github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/device/riscv/handleinterrupt.S (about) 1 #ifdef __riscv_flen 2 #define NREG 48 3 #define LFREG flw 4 #define SFREG fsw 5 #else 6 #define NREG 16 7 #endif 8 9 #if __riscv_xlen==64 10 #define REGSIZE 8 11 #define SREG sd 12 #define LREG ld 13 #else 14 #define REGSIZE 4 15 #define SREG sw 16 #define LREG lw 17 #endif 18 19 .section .text.handleInterruptASM 20 .global handleInterruptASM 21 .type handleInterruptASM,@function 22 handleInterruptASM: 23 // Save and restore all registers, because the hardware only saves/restores 24 // the pc. 25 // Note: we have to do this in assembly because the "interrupt"="machine" 26 // attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984 27 addi sp, sp, -NREG*REGSIZE 28 SREG ra, 0*REGSIZE(sp) 29 SREG t0, 1*REGSIZE(sp) 30 SREG t1, 2*REGSIZE(sp) 31 SREG t2, 3*REGSIZE(sp) 32 SREG a0, 4*REGSIZE(sp) 33 SREG a1, 5*REGSIZE(sp) 34 SREG a2, 6*REGSIZE(sp) 35 SREG a3, 7*REGSIZE(sp) 36 SREG a4, 8*REGSIZE(sp) 37 SREG a5, 9*REGSIZE(sp) 38 SREG a6, 10*REGSIZE(sp) 39 SREG a7, 11*REGSIZE(sp) 40 SREG t3, 12*REGSIZE(sp) 41 SREG t4, 13*REGSIZE(sp) 42 SREG t5, 14*REGSIZE(sp) 43 SREG t6, 15*REGSIZE(sp) 44 #ifdef __riscv_flen 45 SFREG f0, (0 + 16)*REGSIZE(sp) 46 SFREG f1, (1 + 16)*REGSIZE(sp) 47 SFREG f2, (2 + 16)*REGSIZE(sp) 48 SFREG f3, (3 + 16)*REGSIZE(sp) 49 SFREG f4, (4 + 16)*REGSIZE(sp) 50 SFREG f5, (5 + 16)*REGSIZE(sp) 51 SFREG f6, (6 + 16)*REGSIZE(sp) 52 SFREG f7, (7 + 16)*REGSIZE(sp) 53 SFREG f8, (8 + 16)*REGSIZE(sp) 54 SFREG f9, (9 + 16)*REGSIZE(sp) 55 SFREG f10,(10 + 16)*REGSIZE(sp) 56 SFREG f11,(11 + 16)*REGSIZE(sp) 57 SFREG f12,(12 + 16)*REGSIZE(sp) 58 SFREG f13,(13 + 16)*REGSIZE(sp) 59 SFREG f14,(14 + 16)*REGSIZE(sp) 60 SFREG f15,(15 + 16)*REGSIZE(sp) 61 SFREG f16,(16 + 16)*REGSIZE(sp) 62 SFREG f17,(17 + 16)*REGSIZE(sp) 63 SFREG f18,(18 + 16)*REGSIZE(sp) 64 SFREG f19,(19 + 16)*REGSIZE(sp) 65 SFREG f20,(20 + 16)*REGSIZE(sp) 66 SFREG f21,(21 + 16)*REGSIZE(sp) 67 SFREG f22,(22 + 16)*REGSIZE(sp) 68 SFREG f23,(23 + 16)*REGSIZE(sp) 69 SFREG f24,(24 + 16)*REGSIZE(sp) 70 SFREG f25,(25 + 16)*REGSIZE(sp) 71 SFREG f26,(26 + 16)*REGSIZE(sp) 72 SFREG f27,(27 + 16)*REGSIZE(sp) 73 SFREG f28,(28 + 16)*REGSIZE(sp) 74 SFREG f29,(29 + 16)*REGSIZE(sp) 75 SFREG f30,(30 + 16)*REGSIZE(sp) 76 SFREG f31,(31 + 16)*REGSIZE(sp) 77 #endif 78 call handleInterrupt 79 #ifdef __riscv_flen 80 LFREG f0, (31 + 16)*REGSIZE(sp) 81 LFREG f1, (30 + 16)*REGSIZE(sp) 82 LFREG f2, (29 + 16)*REGSIZE(sp) 83 LFREG f3, (28 + 16)*REGSIZE(sp) 84 LFREG f4, (27 + 16)*REGSIZE(sp) 85 LFREG f5, (26 + 16)*REGSIZE(sp) 86 LFREG f6, (25 + 16)*REGSIZE(sp) 87 LFREG f7, (24 + 16)*REGSIZE(sp) 88 LFREG f8, (23 + 16)*REGSIZE(sp) 89 LFREG f9, (22 + 16)*REGSIZE(sp) 90 LFREG f10,(21 + 16)*REGSIZE(sp) 91 LFREG f11,(20 + 16)*REGSIZE(sp) 92 LFREG f12,(19 + 16)*REGSIZE(sp) 93 LFREG f13,(18 + 16)*REGSIZE(sp) 94 LFREG f14,(17 + 16)*REGSIZE(sp) 95 LFREG f15,(16 + 16)*REGSIZE(sp) 96 LFREG f16,(15 + 16)*REGSIZE(sp) 97 LFREG f17,(14 + 16)*REGSIZE(sp) 98 LFREG f18,(13 + 16)*REGSIZE(sp) 99 LFREG f19,(12 + 16)*REGSIZE(sp) 100 LFREG f20,(11 + 16)*REGSIZE(sp) 101 LFREG f21,(10 + 16)*REGSIZE(sp) 102 LFREG f22,(9 + 16)*REGSIZE(sp) 103 LFREG f23,(8 + 16)*REGSIZE(sp) 104 LFREG f24,(7 + 16)*REGSIZE(sp) 105 LFREG f25,(6 + 16)*REGSIZE(sp) 106 LFREG f26,(5 + 16)*REGSIZE(sp) 107 LFREG f27,(4 + 16)*REGSIZE(sp) 108 LFREG f28,(3 + 16)*REGSIZE(sp) 109 LFREG f29,(2 + 16)*REGSIZE(sp) 110 LFREG f30,(1 + 16)*REGSIZE(sp) 111 LFREG f31,(0 + 16)*REGSIZE(sp) 112 #endif 113 LREG t6, 15*REGSIZE(sp) 114 LREG t5, 14*REGSIZE(sp) 115 LREG t4, 13*REGSIZE(sp) 116 LREG t3, 12*REGSIZE(sp) 117 LREG a7, 11*REGSIZE(sp) 118 LREG a6, 10*REGSIZE(sp) 119 LREG a5, 9*REGSIZE(sp) 120 LREG a4, 8*REGSIZE(sp) 121 LREG a3, 7*REGSIZE(sp) 122 LREG a2, 6*REGSIZE(sp) 123 LREG a1, 5*REGSIZE(sp) 124 LREG a0, 4*REGSIZE(sp) 125 LREG t2, 3*REGSIZE(sp) 126 LREG t1, 2*REGSIZE(sp) 127 LREG t0, 1*REGSIZE(sp) 128 LREG ra, 0*REGSIZE(sp) 129 addi sp, sp, NREG*REGSIZE 130 mret