1//===-- save.S - save up to 12 callee-saved 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 save
10//
11//===----------------------------------------------------------------------===//
12
13// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this
14// is the minimum grouping which will maintain the required 16-byte stack
15// alignment.
16
17  .text
18
19#if __riscv_xlen == 32
20
21#ifndef __riscv_32e
22
23  .globl  __riscv_save_12
24  .type   __riscv_save_12,@function
25__riscv_save_12:
26  addi   sp, sp, -64
27  mv     t1, zero
28  sw     s11, 12(sp)
29  j      .Lriscv_save_11_8
30
31  .globl  __riscv_save_11
32  .type   __riscv_save_11,@function
33  .globl  __riscv_save_10
34  .type   __riscv_save_10,@function
35  .globl  __riscv_save_9
36  .type   __riscv_save_9,@function
37  .globl  __riscv_save_8
38  .type   __riscv_save_8,@function
39__riscv_save_11:
40__riscv_save_10:
41__riscv_save_9:
42__riscv_save_8:
43  addi   sp, sp, -64
44  li     t1, 16
45.Lriscv_save_11_8:
46  sw     s10, 16(sp)
47  sw     s9,  20(sp)
48  sw     s8,  24(sp)
49  sw     s7,  28(sp)
50  j      .Lriscv_save_7_4
51
52  .globl  __riscv_save_7
53  .type   __riscv_save_7,@function
54  .globl  __riscv_save_6
55  .type   __riscv_save_6,@function
56  .globl  __riscv_save_5
57  .type   __riscv_save_5,@function
58  .globl  __riscv_save_4
59  .type   __riscv_save_4,@function
60__riscv_save_7:
61__riscv_save_6:
62__riscv_save_5:
63__riscv_save_4:
64  addi   sp, sp, -64
65  li     t1, 32
66.Lriscv_save_7_4:
67  sw     s6, 32(sp)
68  sw     s5, 36(sp)
69  sw     s4, 40(sp)
70  sw     s3, 44(sp)
71  sw     s2, 48(sp)
72  sw     s1, 52(sp)
73  sw     s0, 56(sp)
74  sw     ra, 60(sp)
75  add    sp, sp, t1
76  jr     t0
77
78  .globl  __riscv_save_3
79  .type   __riscv_save_3,@function
80  .globl  __riscv_save_2
81  .type   __riscv_save_2,@function
82  .globl  __riscv_save_1
83  .type   __riscv_save_1,@function
84  .globl  __riscv_save_0
85  .type   __riscv_save_0,@function
86__riscv_save_3:
87__riscv_save_2:
88__riscv_save_1:
89__riscv_save_0:
90  addi    sp, sp, -16
91  sw      s2,  0(sp)
92  sw      s1,  4(sp)
93  sw      s0,  8(sp)
94  sw      ra,  12(sp)
95  jr      t0
96
97#else
98
99  .globl  __riscv_save_2
100  .type   __riscv_save_2,@function
101  .globl  __riscv_save_1
102  .type   __riscv_save_1,@function
103  .globl  __riscv_save_0
104  .type   __riscv_save_0,@function
105__riscv_save_2:
106__riscv_save_1:
107__riscv_save_0:
108  addi    sp, sp, -12
109  sw      s1,  0(sp)
110  sw      s0,  4(sp)
111  sw      ra,  8(sp)
112  jr      t0
113
114#endif
115
116#elif __riscv_xlen == 64
117
118#ifndef __riscv_64e
119
120  .globl  __riscv_save_12
121  .type   __riscv_save_12,@function
122__riscv_save_12:
123  addi   sp, sp, -112
124  mv     t1, zero
125  sd     s11, 8(sp)
126  j      .Lriscv_save_11_10
127
128  .globl  __riscv_save_11
129  .type   __riscv_save_11,@function
130  .globl  __riscv_save_10
131  .type   __riscv_save_10,@function
132__riscv_save_11:
133__riscv_save_10:
134  addi   sp, sp, -112
135  li     t1, 16
136.Lriscv_save_11_10:
137  sd     s10, 16(sp)
138  sd     s9,  24(sp)
139  j      .Lriscv_save_9_8
140
141  .globl  __riscv_save_9
142  .type   __riscv_save_9,@function
143  .globl  __riscv_save_8
144  .type   __riscv_save_8,@function
145__riscv_save_9:
146__riscv_save_8:
147  addi   sp, sp, -112
148  li     t1, 32
149.Lriscv_save_9_8:
150  sd     s8,  32(sp)
151  sd     s7,  40(sp)
152  j      .Lriscv_save_7_6
153
154  .globl  __riscv_save_7
155  .type   __riscv_save_7,@function
156  .globl  __riscv_save_6
157  .type   __riscv_save_6,@function
158__riscv_save_7:
159__riscv_save_6:
160  addi   sp, sp, -112
161  li     t1, 48
162.Lriscv_save_7_6:
163  sd     s6,  48(sp)
164  sd     s5,  56(sp)
165  j      .Lriscv_save_5_4
166
167  .globl  __riscv_save_5
168  .type   __riscv_save_5,@function
169  .globl  __riscv_save_4
170  .type   __riscv_save_4,@function
171__riscv_save_5:
172__riscv_save_4:
173  addi   sp, sp, -112
174  li     t1, 64
175.Lriscv_save_5_4:
176  sd     s4, 64(sp)
177  sd     s3, 72(sp)
178  j      .Lriscv_save_3_2
179
180  .globl  __riscv_save_3
181  .type   __riscv_save_3,@function
182  .globl  __riscv_save_2
183  .type   __riscv_save_2,@function
184__riscv_save_3:
185__riscv_save_2:
186  addi   sp, sp, -112
187  li     t1, 80
188.Lriscv_save_3_2:
189  sd     s2, 80(sp)
190  sd     s1, 88(sp)
191  sd     s0, 96(sp)
192  sd     ra, 104(sp)
193  add    sp, sp, t1
194  jr     t0
195
196  .globl  __riscv_save_1
197  .type   __riscv_save_1,@function
198  .globl  __riscv_save_0
199  .type   __riscv_save_0,@function
200__riscv_save_1:
201__riscv_save_0:
202  addi   sp, sp, -16
203  sd     s0, 0(sp)
204  sd     ra, 8(sp)
205  jr     t0
206
207#else
208
209  .globl  __riscv_save_2
210  .type   __riscv_save_2,@function
211  .globl  __riscv_save_1
212  .type   __riscv_save_1,@function
213  .globl  __riscv_save_0
214  .type   __riscv_save_0,@function
215__riscv_save_2:
216__riscv_save_1:
217__riscv_save_0:
218  addi   sp, sp, -24
219  sd     s1, 0(sp)
220  sd     s0, 8(sp)
221  sd     ra, 16(sp)
222  jr     t0
223
224#endif
225
226#else
227# error "xlen must be 32 or 64 for save-restore implementation
228#endif
229