| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 | #include "picorv32.h"#include "iodevs.h"	// The IRQ dispatch code is written in assembly to make	// better use of the register bank switching: can simply	// use the saved registers here, no saving needed.	// registers need to be	.pushsection ".init.irq","ax"	.balign 4	.globl _irq	.option push	.option norvc	// Alignment matters more here_irq:	addqxi sp,sp,0	// s10 contains the IRQ return address, s11 the mask of	// IRQs to be handled.	// Priority for ABC-bus I/O	andi s0,s11,1 << ABC_IRQ	beqz s0,1f	jal irqhandler_abc	sub s11,s11,s0	beqz s11,.L_done1:	li s1, 0.Lirq_loop:	// ctz would make this more efficient...#if IRQ_VECTORS > 16	slli t0,s11,16	bnez t0,1f	srli s11,s11,16	addi s1,s1,16*41:#endif#if IRQ_VECTORS > 8	zext.b t0,s11	bnez t0,2f	srli s11,s11,8	addi s1,s1,8*42:#endif#if IRQ_VECTORS > 4	andi t0,s11,15	bnez t0,3f	srli s11,s11,4	addi s1,s1,4*43:#endif#if IRQ_VECTORS > 2	andi t0,s11,3	bnez t0,4f	srli s11,s11,2	addi s1,s1,2*44:#endif#if IRQ_VECTORS > 1	andi t0,s11,1	bnez t0,5f	srli s11,s11,1	addi s1,s1,1*45:#endif	// __irq_handler_table must be in the zero page	// However, prevent the linker from incorrectly relaxing	// this instruction.	.option push	.option norelax	lw t0,%lo(__irq_handler_table)(s1)	.option pop	srli a0,s1,2	mv   a1,s10	jalr t0	srli s11,s11,1	addi s1,s1,4*1	bnez s11,.Lirq_loop.L_done:	mret	.type _irq, @function	.size _irq, . - _irq	.option pop
 |