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