/*
 * Copyright (c) 2020 Intel Corporation
 * SPDX-License-Identifier: Apache-2.0
 */
/*
 * THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT.
 *
 * Functions here are designed to produce efficient code to
 * search an Xtensa bitmask of interrupts, inspecting only those bits
 * declared to be associated with a given interrupt level.  Each
 * dispatcher will handle exactly one flagged interrupt, in numerical
 * order (low bits first) and will return a mask of that bit that can
 * then be cleared by the calling code.  Unrecognized bits for the
 * level will invoke an error handler.
 */

#include <xtensa/config/core-isa.h>
#include <sys/util.h>
#include <sw_isr_table.h>

#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 7
#error core-isa.h interrupt level does not match dispatcher!
#endif

static inline int _xtensa_handle_one_int1(unsigned int mask)
{
	int irq;

	if (mask & 0x3) {
		if (mask & BIT(0)) {
			mask = BIT(0);
			irq = 0;
			goto handle_irq;
		}
		if (mask & BIT(1)) {
			mask = BIT(1);
			irq = 1;
			goto handle_irq;
		}
	} else {
		if (mask & BIT(2)) {
			mask = BIT(2);
			irq = 2;
			goto handle_irq;
		}
		if (mask & BIT(3)) {
			mask = BIT(3);
			irq = 3;
			goto handle_irq;
		}
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int2(unsigned int mask)
{
	int irq;

	if (mask & 0x30) {
		if (mask & BIT(4)) {
			mask = BIT(4);
			irq = 4;
			goto handle_irq;
		}
		if (mask & BIT(5)) {
			mask = BIT(5);
			irq = 5;
			goto handle_irq;
		}
	} else {
		if (mask & BIT(6)) {
			mask = BIT(6);
			irq = 6;
			goto handle_irq;
		}
		if (mask & BIT(7)) {
			mask = BIT(7);
			irq = 7;
			goto handle_irq;
		}
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int3(unsigned int mask)
{
	int irq;

	if (mask & 0x300) {
		if (mask & BIT(8)) {
			mask = BIT(8);
			irq = 8;
			goto handle_irq;
		}
		if (mask & BIT(9)) {
			mask = BIT(9);
			irq = 9;
			goto handle_irq;
		}
	} else {
		if (mask & BIT(10)) {
			mask = BIT(10);
			irq = 10;
			goto handle_irq;
		}
		if (mask & BIT(11)) {
			mask = BIT(11);
			irq = 11;
			goto handle_irq;
		}
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int4(unsigned int mask)
{
	int irq;

	if (mask & BIT(12)) {
		mask = BIT(12);
		irq = 12;
		goto handle_irq;
	}
	if (mask & BIT(13)) {
		mask = BIT(13);
		irq = 13;
		goto handle_irq;
	}
	if (mask & BIT(14)) {
		mask = BIT(14);
		irq = 14;
		goto handle_irq;
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int5(unsigned int mask)
{
	int irq;

	if (mask & 0x18000) {
		if (mask & BIT(15)) {
			mask = BIT(15);
			irq = 15;
			goto handle_irq;
		}
		if (mask & BIT(16)) {
			mask = BIT(16);
			irq = 16;
			goto handle_irq;
		}
	} else {
		if (mask & BIT(17)) {
			mask = BIT(17);
			irq = 17;
			goto handle_irq;
		}
		if (mask & BIT(18)) {
			mask = BIT(18);
			irq = 18;
			goto handle_irq;
		}
		if (mask & BIT(19)) {
			mask = BIT(19);
			irq = 19;
			goto handle_irq;
		}
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int7(unsigned int mask)
{
	int irq;

	if (mask & BIT(20)) {
		mask = BIT(20);
		irq = 20;
		goto handle_irq;
	}
	return 0;
handle_irq:
	_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
	return mask;
}

static inline int _xtensa_handle_one_int0(unsigned int mask)
{
	return 0;
}
static inline int _xtensa_handle_one_int6(unsigned int mask)
{
	return 0;
}
