irqasm.S 955 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #include "picorv32.h"
  2. // The IRQ dispatch code is written in assembly to make
  3. // better use of the register bank switching: can simply
  4. // use the saved registers here, no saving needed.
  5. // registers need to be
  6. .pushsection ".init.irq","ax"
  7. .globl _irq
  8. _irq:
  9. addqxi sp,sp,0
  10. // s10 contains the IRQ return address, s11 the mask of
  11. // IRQs to be handled.
  12. lui s0, %hi(__irq_handler_table)
  13. li s1, 0
  14. .Lirq_loop:
  15. // ctz would make this more efficient...
  16. slli t0,s11,16
  17. bnez t0,1f
  18. srli s11,s11,16
  19. addi s1,s1,16*4
  20. 1:
  21. zext.b t0,s11
  22. bnez t0,2f
  23. srli s11,s11,8
  24. addi s1,s1,8*4
  25. 2:
  26. andi t0,s11,15
  27. bnez t0,3f
  28. srli s11,s11,4
  29. addi s1,s1,4*4
  30. 3:
  31. andi t0,s11,3
  32. bnez t0,4f
  33. srli s11,s11,2
  34. addi s1,s1,2*4
  35. 4:
  36. andi t0,s11,1
  37. bnez t0,5f
  38. srli s11,s11,1
  39. addi s1,s1,1*4
  40. 5:
  41. add t0,s0,s1
  42. lw t0,%lo(__irq_handler_table)(t0)
  43. srli a0,s1,2
  44. jalr t0
  45. srli s11,s11,1
  46. addi s1,s1,4*1
  47. bnez s11,.Lirq_loop
  48. mret
  49. .type _irq, @function
  50. .size _irq, . - _irq