#include "picorv32.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" .globl _irq _irq: addqxi sp,sp,0 // s10 contains the IRQ return address, s11 the mask of // IRQs to be handled. lui s0, %hi(__irq_handler_table) li s1, 0 .Lirq_loop: // ctz would make this more efficient... slli t0,s11,16 bnez t0,1f srli s11,s11,16 addi s1,s1,16*4 1: zext.b t0,s11 bnez t0,2f srli s11,s11,8 addi s1,s1,8*4 2: andi t0,s11,15 bnez t0,3f srli s11,s11,4 addi s1,s1,4*4 3: andi t0,s11,3 bnez t0,4f srli s11,s11,2 addi s1,s1,2*4 4: andi t0,s11,1 bnez t0,5f srli s11,s11,1 addi s1,s1,1*4 5: add t0,s0,s1 lw t0,%lo(__irq_handler_table)(t0) srli a0,s1,2 jalr t0 srli s11,s11,1 addi s1,s1,4*1 bnez s11,.Lirq_loop mret .type _irq, @function .size _irq, . - _irq