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