1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- #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
|