xref: /netbsd-src/external/gpl3/gcc/dist/libgcc/config/riscv/save-restore.S (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1/* Callee-saved register spill and fill routines for RISC-V.
2
3   Copyright (C) 2016-2022 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24<http://www.gnu.org/licenses/>.  */
25
26#include "riscv-asm.h"
27
28  .text
29
30#if __riscv_xlen == 64
31
32FUNC_BEGIN (__riscv_save_12)
33  .cfi_startproc
34  # __riscv_save_* routine use t0/x5 as return address
35  .cfi_return_column 5
36  addi sp, sp, -112
37  .cfi_def_cfa_offset 112
38  li t1, 0
39  sd s11, 8(sp)
40  .cfi_offset 27, -104
41  j .Ls10
42
43FUNC_BEGIN (__riscv_save_11)
44FUNC_BEGIN (__riscv_save_10)
45  .cfi_restore 27
46  addi sp, sp, -112
47  .cfi_def_cfa_offset 112
48  li t1, 1
49.Ls10:
50  sd s10, 16(sp)
51  .cfi_offset 26, -96
52  sd s9, 24(sp)
53  .cfi_offset 25, -88
54  j .Ls8
55
56FUNC_BEGIN (__riscv_save_9)
57FUNC_BEGIN (__riscv_save_8)
58  .cfi_restore 25
59  .cfi_restore 26
60  .cfi_restore 27
61  addi sp, sp, -112
62  .cfi_def_cfa_offset 112
63  li t1, 2
64.Ls8:
65  sd s8, 32(sp)
66  .cfi_offset 24, -80
67  sd s7, 40(sp)
68  .cfi_offset 23, -72
69  j .Ls6
70
71FUNC_BEGIN (__riscv_save_7)
72FUNC_BEGIN (__riscv_save_6)
73  .cfi_restore 23
74  .cfi_restore 24
75  .cfi_restore 25
76  .cfi_restore 26
77  .cfi_restore 27
78  addi sp, sp, -112
79  .cfi_def_cfa_offset 112
80  li t1, 3
81.Ls6:
82  sd s6, 48(sp)
83  .cfi_offset 22, -64
84  sd s5, 56(sp)
85  .cfi_offset 21, -56
86  j .Ls4
87
88FUNC_BEGIN (__riscv_save_5)
89FUNC_BEGIN (__riscv_save_4)
90  .cfi_restore 21
91  .cfi_restore 22
92  .cfi_restore 24
93  .cfi_restore 25
94  .cfi_restore 26
95  .cfi_restore 27
96  .cfi_restore 24
97  .cfi_restore 25
98  .cfi_restore 26
99  .cfi_restore 27
100  addi sp, sp, -112
101  .cfi_def_cfa_offset 112
102  li t1, 4
103.Ls4:
104  sd s4, 64(sp)
105  .cfi_offset 20, -48
106  sd s3, 72(sp)
107  .cfi_offset 19, -40
108  j .Ls2
109
110FUNC_BEGIN (__riscv_save_3)
111FUNC_BEGIN (__riscv_save_2)
112  .cfi_restore 19
113  .cfi_restore 20
114  .cfi_restore 21
115  .cfi_restore 22
116  .cfi_restore 24
117  .cfi_restore 25
118  .cfi_restore 26
119  .cfi_restore 27
120  .cfi_restore 24
121  .cfi_restore 25
122  .cfi_restore 26
123  .cfi_restore 27
124  addi sp, sp, -112
125  .cfi_def_cfa_offset 112
126  li t1, 5
127.Ls2:
128  sd s2, 80(sp)
129  .cfi_offset 18, -32
130  sd s1, 88(sp)
131  .cfi_offset 9, -24
132  sd s0, 96(sp)
133  .cfi_offset 8, -16
134  sd ra, 104(sp)
135  .cfi_offset 1, -8
136  slli t1, t1, 4
137  # CFA info is not correct in next 2 instruction since t1's
138  # value is depend on how may register really save.
139  add sp, sp, t1
140  jr t0
141  .cfi_endproc
142FUNC_END (__riscv_save_12)
143FUNC_END (__riscv_save_11)
144FUNC_END (__riscv_save_10)
145FUNC_END (__riscv_save_9)
146FUNC_END (__riscv_save_8)
147FUNC_END (__riscv_save_7)
148FUNC_END (__riscv_save_6)
149FUNC_END (__riscv_save_5)
150FUNC_END (__riscv_save_4)
151FUNC_END (__riscv_save_3)
152FUNC_END (__riscv_save_2)
153
154FUNC_BEGIN (__riscv_save_1)
155FUNC_BEGIN (__riscv_save_0)
156  .cfi_startproc
157  # __riscv_save_* routine use t0/x5 as return address
158  .cfi_return_column 5
159  addi sp, sp, -16
160  .cfi_def_cfa_offset 16
161  sd s0, 0(sp)
162  .cfi_offset 8, -16
163  sd ra, 8(sp)
164  .cfi_offset 1, -8
165  jr t0
166  .cfi_endproc
167FUNC_END (__riscv_save_1)
168FUNC_END (__riscv_save_0)
169
170FUNC_BEGIN (__riscv_restore_12)
171  .cfi_startproc
172  .cfi_def_cfa_offset 112
173  .cfi_offset 27, -104
174  .cfi_offset 26, -96
175  .cfi_offset 25, -88
176  .cfi_offset 24, -80
177  .cfi_offset 23, -72
178  .cfi_offset 22, -64
179  .cfi_offset 21, -56
180  .cfi_offset 20, -48
181  .cfi_offset 19, -40
182  .cfi_offset 18, -32
183  .cfi_offset 9, -24
184  .cfi_offset 8, -16
185  .cfi_offset 1, -8
186  ld s11, 8(sp)
187  .cfi_restore 27
188  addi sp, sp, 16
189
190FUNC_BEGIN (__riscv_restore_11)
191FUNC_BEGIN (__riscv_restore_10)
192  .cfi_restore 27
193  .cfi_def_cfa_offset 96
194  ld s10, 0(sp)
195  .cfi_restore 26
196  ld s9, 8(sp)
197  .cfi_restore 25
198  addi sp, sp, 16
199
200FUNC_BEGIN (__riscv_restore_9)
201FUNC_BEGIN (__riscv_restore_8)
202  .cfi_restore 25
203  .cfi_restore 26
204  .cfi_restore 27
205  .cfi_def_cfa_offset 80
206  ld s8, 0(sp)
207  .cfi_restore 24
208  ld s7, 8(sp)
209  .cfi_restore 23
210  addi sp, sp, 16
211
212FUNC_BEGIN (__riscv_restore_7)
213FUNC_BEGIN (__riscv_restore_6)
214  .cfi_restore 23
215  .cfi_restore 24
216  .cfi_restore 25
217  .cfi_restore 26
218  .cfi_restore 27
219  .cfi_def_cfa_offset 64
220  ld s6, 0(sp)
221  .cfi_restore 22
222  ld s5, 8(sp)
223  .cfi_restore 21
224  addi sp, sp, 16
225
226FUNC_BEGIN (__riscv_restore_5)
227FUNC_BEGIN (__riscv_restore_4)
228  .cfi_restore 21
229  .cfi_restore 22
230  .cfi_restore 23
231  .cfi_restore 24
232  .cfi_restore 25
233  .cfi_restore 26
234  .cfi_restore 27
235  .cfi_def_cfa_offset 48
236  ld s4, 0(sp)
237  .cfi_restore 20
238  ld s3, 8(sp)
239  .cfi_restore 19
240  addi sp, sp, 16
241
242FUNC_BEGIN (__riscv_restore_3)
243FUNC_BEGIN (__riscv_restore_2)
244  .cfi_restore 19
245  .cfi_restore 20
246  .cfi_restore 21
247  .cfi_restore 22
248  .cfi_restore 23
249  .cfi_restore 24
250  .cfi_restore 25
251  .cfi_restore 26
252  .cfi_restore 27
253  .cfi_def_cfa_offset 32
254  ld s2, 0(sp)
255  .cfi_restore 18
256  ld s1, 8(sp)
257  .cfi_restore 9
258  addi sp, sp, 16
259
260FUNC_BEGIN (__riscv_restore_1)
261FUNC_BEGIN (__riscv_restore_0)
262  .cfi_restore 9
263  .cfi_restore 18
264  .cfi_restore 19
265  .cfi_restore 20
266  .cfi_restore 21
267  .cfi_restore 22
268  .cfi_restore 23
269  .cfi_restore 24
270  .cfi_restore 25
271  .cfi_restore 26
272  .cfi_restore 27
273  .cfi_def_cfa_offset 16
274  ld s0, 0(sp)
275  .cfi_restore 8
276  ld ra, 8(sp)
277  .cfi_restore 1
278  addi sp, sp, 16
279  .cfi_def_cfa_offset 0
280  ret
281  .cfi_endproc
282FUNC_END (__riscv_restore_12)
283FUNC_END (__riscv_restore_11)
284FUNC_END (__riscv_restore_10)
285FUNC_END (__riscv_restore_9)
286FUNC_END (__riscv_restore_8)
287FUNC_END (__riscv_restore_7)
288FUNC_END (__riscv_restore_6)
289FUNC_END (__riscv_restore_5)
290FUNC_END (__riscv_restore_4)
291FUNC_END (__riscv_restore_3)
292FUNC_END (__riscv_restore_2)
293FUNC_END (__riscv_restore_1)
294FUNC_END (__riscv_restore_0)
295
296#else
297
298#ifdef __riscv_32e
299FUNC_BEGIN(__riscv_save_2)
300FUNC_BEGIN(__riscv_save_1)
301FUNC_BEGIN(__riscv_save_0)
302  .cfi_startproc
303  # __riscv_save_* routine use t0/x5 as return address
304  .cfi_return_column 5
305  addi sp, sp, -12
306  .cfi_def_cfa_offset 12
307  sw s1, 0(sp)
308  .cfi_offset 9, -12
309  sw s0, 4(sp)
310  .cfi_offset 8, -8
311  sw ra, 8(sp)
312  .cfi_offset 1, 0
313  jr t0
314  .cfi_endproc
315FUNC_END(__riscv_save_2)
316FUNC_END(__riscv_save_1)
317FUNC_END(__riscv_save_0)
318
319FUNC_BEGIN(__riscv_restore_2)
320FUNC_BEGIN(__riscv_restore_1)
321FUNC_BEGIN(__riscv_restore_0)
322  .cfi_startproc
323  .cfi_def_cfa_offset 14
324  lw s1, 0(sp)
325  .cfi_restore 9
326  lw s0, 4(sp)
327  .cfi_restore 8
328  lw ra, 8(sp)
329  .cfi_restore 1
330  addi sp, sp, 12
331  .cfi_def_cfa_offset 0
332  ret
333  .cfi_endproc
334FUNC_END(__riscv_restore_2)
335FUNC_END(__riscv_restore_1)
336FUNC_END(__riscv_restore_0)
337
338#else
339
340FUNC_BEGIN (__riscv_save_12)
341  .cfi_startproc
342  # __riscv_save_* routine use t0/x5 as return address
343  .cfi_return_column 5
344  addi sp, sp, -64
345  .cfi_def_cfa_offset 64
346  li t1, 0
347  sw s11, 12(sp)
348  .cfi_offset 27, -52
349  j .Ls10
350
351FUNC_BEGIN (__riscv_save_11)
352FUNC_BEGIN (__riscv_save_10)
353FUNC_BEGIN (__riscv_save_9)
354FUNC_BEGIN (__riscv_save_8)
355  .cfi_restore 27
356  addi sp, sp, -64
357  .cfi_def_cfa_offset 64
358  li t1, -16
359.Ls10:
360  sw s10, 16(sp)
361  .cfi_offset 26, -48
362  sw s9, 20(sp)
363  .cfi_offset 25, -44
364  sw s8, 24(sp)
365  .cfi_offset 24, -40
366  sw s7, 28(sp)
367  .cfi_offset 23, -36
368  j .Ls6
369
370FUNC_BEGIN (__riscv_save_7)
371FUNC_BEGIN (__riscv_save_6)
372FUNC_BEGIN (__riscv_save_5)
373FUNC_BEGIN (__riscv_save_4)
374  .cfi_restore 23
375  .cfi_restore 24
376  .cfi_restore 25
377  .cfi_restore 26
378  .cfi_restore 27
379  addi sp, sp, -64
380  .cfi_def_cfa_offset 64
381  li t1, -32
382.Ls6:
383  sw s6, 32(sp)
384  .cfi_offset 22, -32
385  sw s5, 36(sp)
386  .cfi_offset 21, -28
387  sw s4, 40(sp)
388  .cfi_offset 20, -24
389  sw s3, 44(sp)
390  .cfi_offset 19, -20
391  sw s2, 48(sp)
392  .cfi_offset 18, -16
393  sw s1, 52(sp)
394  .cfi_offset 9, -12
395  sw s0, 56(sp)
396  .cfi_offset 8, -8
397  sw ra, 60(sp)
398  .cfi_offset 1, -4
399  # CFA info is not correct in next 2 instruction since t1's
400  # value is depend on how may register really save.
401  sub sp, sp, t1
402  jr t0
403  .cfi_endproc
404FUNC_END (__riscv_save_12)
405FUNC_END (__riscv_save_11)
406FUNC_END (__riscv_save_10)
407FUNC_END (__riscv_save_9)
408FUNC_END (__riscv_save_8)
409FUNC_END (__riscv_save_7)
410FUNC_END (__riscv_save_6)
411FUNC_END (__riscv_save_5)
412FUNC_END (__riscv_save_4)
413
414FUNC_BEGIN (__riscv_save_3)
415FUNC_BEGIN (__riscv_save_2)
416FUNC_BEGIN (__riscv_save_1)
417FUNC_BEGIN (__riscv_save_0)
418  .cfi_startproc
419  # __riscv_save_* routine use t0/x5 as return address
420  .cfi_return_column 5
421  addi sp, sp, -16
422  .cfi_def_cfa_offset 16
423  sw s2, 0(sp)
424  sw s1, 4(sp)
425  .cfi_offset 9, -16
426  sw s0, 8(sp)
427  .cfi_offset 8, -8
428  sw ra, 12(sp)
429  .cfi_offset 1, -4
430  jr t0
431  .cfi_endproc
432FUNC_END (__riscv_save_3)
433FUNC_END (__riscv_save_2)
434FUNC_END (__riscv_save_1)
435FUNC_END (__riscv_save_0)
436
437FUNC_BEGIN (__riscv_restore_12)
438  .cfi_startproc
439  .cfi_def_cfa_offset 64
440  .cfi_offset 27, -52
441  .cfi_offset 26, -48
442  .cfi_offset 25, -44
443  .cfi_offset 24, -40
444  .cfi_offset 23, -36
445  .cfi_offset 22, -32
446  .cfi_offset 21, -28
447  .cfi_offset 20, -24
448  .cfi_offset 19, -20
449  .cfi_offset 18, -16
450  .cfi_offset 9, -12
451  .cfi_offset 8, -8
452  .cfi_offset 1, -4
453  lw s11, 12(sp)
454  .cfi_restore 27
455  addi sp, sp, 16
456
457FUNC_BEGIN (__riscv_restore_11)
458FUNC_BEGIN (__riscv_restore_10)
459FUNC_BEGIN (__riscv_restore_9)
460FUNC_BEGIN (__riscv_restore_8)
461  .cfi_restore 27
462  .cfi_def_cfa_offset 48
463  lw s10, 0(sp)
464  .cfi_restore 26
465  lw s9, 4(sp)
466  .cfi_restore 25
467  lw s8, 8(sp)
468  .cfi_restore 24
469  lw s7, 12(sp)
470  .cfi_restore 23
471  addi sp, sp, 16
472
473FUNC_BEGIN (__riscv_restore_7)
474FUNC_BEGIN (__riscv_restore_6)
475FUNC_BEGIN (__riscv_restore_5)
476FUNC_BEGIN (__riscv_restore_4)
477  .cfi_restore 23
478  .cfi_restore 24
479  .cfi_restore 25
480  .cfi_restore 26
481  .cfi_restore 27
482  .cfi_def_cfa_offset 32
483  lw s6, 0(sp)
484  .cfi_restore 22
485  lw s5, 4(sp)
486  .cfi_restore 21
487  lw s4, 8(sp)
488  .cfi_restore 20
489  lw s3, 12(sp)
490  .cfi_restore 19
491  addi sp, sp, 16
492
493FUNC_BEGIN (__riscv_restore_3)
494FUNC_BEGIN (__riscv_restore_2)
495FUNC_BEGIN (__riscv_restore_1)
496FUNC_BEGIN (__riscv_restore_0)
497  .cfi_restore 19
498  .cfi_restore 20
499  .cfi_restore 21
500  .cfi_restore 22
501  .cfi_restore 24
502  .cfi_restore 25
503  .cfi_restore 26
504  .cfi_restore 27
505  .cfi_def_cfa_offset 16
506  lw s2, 0(sp)
507  .cfi_restore 18
508  lw s1, 4(sp)
509  .cfi_restore 9
510  lw s0, 8(sp)
511  .cfi_restore 8
512  lw ra, 12(sp)
513  .cfi_restore 1
514  addi sp, sp, 16
515  .cfi_def_cfa_offset 0
516  ret
517  .cfi_endproc
518FUNC_END (__riscv_restore_12)
519FUNC_END (__riscv_restore_11)
520FUNC_END (__riscv_restore_10)
521FUNC_END (__riscv_restore_9)
522FUNC_END (__riscv_restore_8)
523FUNC_END (__riscv_restore_7)
524FUNC_END (__riscv_restore_6)
525FUNC_END (__riscv_restore_5)
526FUNC_END (__riscv_restore_4)
527FUNC_END (__riscv_restore_3)
528FUNC_END (__riscv_restore_2)
529FUNC_END (__riscv_restore_1)
530FUNC_END (__riscv_restore_0)
531
532#endif /* __riscv_32e */
533
534#endif /* __riscv_xlen == 64 */
535