1//===-- restore.S - restore up to 12 callee-save registers ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Multiple entry points depending on number of registers to restore
10//
11//===----------------------------------------------------------------------===//
12
13// All of the entry points are in the same section since we rely on many of
14// them falling through into each other and don't want the linker to
15// accidentally split them up, garbage collect, or reorder them.
16//
17// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this
18// is the minimum grouping which will maintain the required 16-byte stack
19// alignment.
20
21 .text
22
23#if __riscv_xlen == 32
24
25#ifndef __riscv_32e
26
27 .globl __riscv_restore_12
28 .type __riscv_restore_12,@function
29__riscv_restore_12:
30 lw s11, 12(sp)
31 addi sp, sp, 16
32 // fallthrough into __riscv_restore_11/10/9/8
33
34 .globl __riscv_restore_11
35 .type __riscv_restore_11,@function
36 .globl __riscv_restore_10
37 .type __riscv_restore_10,@function
38 .globl __riscv_restore_9
39 .type __riscv_restore_9,@function
40 .globl __riscv_restore_8
41 .type __riscv_restore_8,@function
42__riscv_restore_11:
43__riscv_restore_10:
44__riscv_restore_9:
45__riscv_restore_8:
46 lw s10, 0(sp)
47 lw s9, 4(sp)
48 lw s8, 8(sp)
49 lw s7, 12(sp)
50 addi sp, sp, 16
51 // fallthrough into __riscv_restore_7/6/5/4
52
53 .globl __riscv_restore_7
54 .type __riscv_restore_7,@function
55 .globl __riscv_restore_6
56 .type __riscv_restore_6,@function
57 .globl __riscv_restore_5
58 .type __riscv_restore_5,@function
59 .globl __riscv_restore_4
60 .type __riscv_restore_4,@function
61__riscv_restore_7:
62__riscv_restore_6:
63__riscv_restore_5:
64__riscv_restore_4:
65 lw s6, 0(sp)
66 lw s5, 4(sp)
67 lw s4, 8(sp)
68 lw s3, 12(sp)
69 addi sp, sp, 16
70 // fallthrough into __riscv_restore_3/2/1/0
71
72 .globl __riscv_restore_3
73 .type __riscv_restore_3,@function
74 .globl __riscv_restore_2
75 .type __riscv_restore_2,@function
76 .globl __riscv_restore_1
77 .type __riscv_restore_1,@function
78 .globl __riscv_restore_0
79 .type __riscv_restore_0,@function
80__riscv_restore_3:
81__riscv_restore_2:
82__riscv_restore_1:
83__riscv_restore_0:
84 lw s2, 0(sp)
85 lw s1, 4(sp)
86 lw s0, 8(sp)
87 lw ra, 12(sp)
88 addi sp, sp, 16
89 ret
90
91#else
92
93 .globl __riscv_restore_2
94 .type __riscv_restore_2,@function
95 .globl __riscv_restore_1
96 .type __riscv_restore_1,@function
97 .globl __riscv_restore_0
98 .type __riscv_restore_0,@function
99__riscv_restore_2:
100__riscv_restore_1:
101__riscv_restore_0:
102 lw s1, 0(sp)
103 lw s0, 4(sp)
104 lw ra, 8(sp)
105 addi sp, sp, 12
106 ret
107
108#endif
109
110#elif __riscv_xlen == 64
111
112#ifndef __riscv_64e
113
114 .globl __riscv_restore_12
115 .type __riscv_restore_12,@function
116__riscv_restore_12:
117 ld s11, 8(sp)
118 addi sp, sp, 16
119 // fallthrough into __riscv_restore_11/10
120
121 .globl __riscv_restore_11
122 .type __riscv_restore_11,@function
123 .globl __riscv_restore_10
124 .type __riscv_restore_10,@function
125__riscv_restore_11:
126__riscv_restore_10:
127 ld s10, 0(sp)
128 ld s9, 8(sp)
129 addi sp, sp, 16
130 // fallthrough into __riscv_restore_9/8
131
132 .globl __riscv_restore_9
133 .type __riscv_restore_9,@function
134 .globl __riscv_restore_8
135 .type __riscv_restore_8,@function
136__riscv_restore_9:
137__riscv_restore_8:
138 ld s8, 0(sp)
139 ld s7, 8(sp)
140 addi sp, sp, 16
141 // fallthrough into __riscv_restore_7/6
142
143 .globl __riscv_restore_7
144 .type __riscv_restore_7,@function
145 .globl __riscv_restore_6
146 .type __riscv_restore_6,@function
147__riscv_restore_7:
148__riscv_restore_6:
149 ld s6, 0(sp)
150 ld s5, 8(sp)
151 addi sp, sp, 16
152 // fallthrough into __riscv_restore_5/4
153
154 .globl __riscv_restore_5
155 .type __riscv_restore_5,@function
156 .globl __riscv_restore_4
157 .type __riscv_restore_4,@function
158__riscv_restore_5:
159__riscv_restore_4:
160 ld s4, 0(sp)
161 ld s3, 8(sp)
162 addi sp, sp, 16
163 // fallthrough into __riscv_restore_3/2
164
165 .globl __riscv_restore_3
166 .type __riscv_restore_3,@function
167 .globl __riscv_restore_2
168 .type __riscv_restore_2,@function
169__riscv_restore_3:
170__riscv_restore_2:
171 ld s2, 0(sp)
172 ld s1, 8(sp)
173 addi sp, sp, 16
174 // fallthrough into __riscv_restore_1/0
175
176 .globl __riscv_restore_1
177 .type __riscv_restore_1,@function
178 .globl __riscv_restore_0
179 .type __riscv_restore_0,@function
180__riscv_restore_1:
181__riscv_restore_0:
182 ld s0, 0(sp)
183 ld ra, 8(sp)
184 addi sp, sp, 16
185 ret
186
187#else
188
189 .globl __riscv_restore_2
190 .type __riscv_restore_2,@function
191 .globl __riscv_restore_1
192 .type __riscv_restore_1,@function
193 .globl __riscv_restore_0
194 .type __riscv_restore_0,@function
195__riscv_restore_2:
196__riscv_restore_1:
197__riscv_restore_0:
198 ld s1, 0(sp)
199 ld s0, 8(sp)
200 ld ra, 16(sp)
201 addi sp, sp, 24
202 ret
203
204#endif
205
206#else
207# error "xlen must be 32 or 64 for save-restore implementation
208#endif
209

source code of compiler-rt/lib/builtins/riscv/restore.S