[NFC][Py Reformat] Reformat python files in llvm
[llvm-project.git] / libunwind / src / UnwindRegistersSave.S
blob79f5696a9888f5e491c3c51cc3f785d546a0f40a
1 //===----------------------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #include "assembly.h"
11 #define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
12 #define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
14 #define FROM_0_TO_31 0,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
15 #define FROM_32_TO_63 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
17 #if defined(_AIX)
18     .toc
19 #else
20     .text
21 #endif
23 #if !defined(__USING_SJLJ_EXCEPTIONS__)
25 #if defined(__i386__)
28 # extern int __unw_getcontext(unw_context_t* thread_state)
30 # On entry:
31 #   +                       +
32 #   +-----------------------+
33 #   + thread_state pointer  +
34 #   +-----------------------+
35 #   + return address        +
36 #   +-----------------------+   <-- SP
37 #   +                       +
39 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
41   _LIBUNWIND_CET_ENDBR
42   push  %eax
43   movl  8(%esp), %eax
44   movl  %ebx,  4(%eax)
45   movl  %ecx,  8(%eax)
46   movl  %edx, 12(%eax)
47   movl  %edi, 16(%eax)
48   movl  %esi, 20(%eax)
49   movl  %ebp, 24(%eax)
50   movl  %esp, %edx
51   addl  $8, %edx
52   movl  %edx, 28(%eax)  # store what sp was at call site as esp
53   # skip ss
54   # skip eflags
55   movl  4(%esp), %edx
56   movl  %edx, 40(%eax)  # store return address as eip
57   # skip cs
58   # skip ds
59   # skip es
60   # skip fs
61   # skip gs
62   movl  (%esp), %edx
63   movl  %edx, (%eax)  # store original eax
64   popl  %eax
65   xorl  %eax, %eax    # return UNW_ESUCCESS
66   ret
68 #elif defined(__x86_64__)
71 # extern int __unw_getcontext(unw_context_t* thread_state)
73 # On entry:
74 #  thread_state pointer is in rdi
76 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
77 #if defined(_WIN64)
78 #define PTR %rcx
79 #define TMP %rdx
80 #else
81 #define PTR %rdi
82 #define TMP %rsi
83 #endif
85   _LIBUNWIND_CET_ENDBR
86   movq  %rax,   (PTR)
87   movq  %rbx,  8(PTR)
88   movq  %rcx, 16(PTR)
89   movq  %rdx, 24(PTR)
90   movq  %rdi, 32(PTR)
91   movq  %rsi, 40(PTR)
92   movq  %rbp, 48(PTR)
93   movq  %rsp, 56(PTR)
94   addq  $8,   56(PTR)
95   movq  %r8,  64(PTR)
96   movq  %r9,  72(PTR)
97   movq  %r10, 80(PTR)
98   movq  %r11, 88(PTR)
99   movq  %r12, 96(PTR)
100   movq  %r13,104(PTR)
101   movq  %r14,112(PTR)
102   movq  %r15,120(PTR)
103   movq  (%rsp),TMP
104   movq  TMP,128(PTR) # store return address as rip
105   # skip rflags
106   # skip cs
107   # skip fs
108   # skip gs
110 #if defined(_WIN64)
111   movdqu %xmm0,176(PTR)
112   movdqu %xmm1,192(PTR)
113   movdqu %xmm2,208(PTR)
114   movdqu %xmm3,224(PTR)
115   movdqu %xmm4,240(PTR)
116   movdqu %xmm5,256(PTR)
117   movdqu %xmm6,272(PTR)
118   movdqu %xmm7,288(PTR)
119   movdqu %xmm8,304(PTR)
120   movdqu %xmm9,320(PTR)
121   movdqu %xmm10,336(PTR)
122   movdqu %xmm11,352(PTR)
123   movdqu %xmm12,368(PTR)
124   movdqu %xmm13,384(PTR)
125   movdqu %xmm14,400(PTR)
126   movdqu %xmm15,416(PTR)
127 #endif
128   xorl  %eax, %eax    # return UNW_ESUCCESS
129   ret
131 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
134 # extern int __unw_getcontext(unw_context_t* thread_state)
136 # On entry:
137 #  thread_state pointer is in a0 ($4)
139 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
140   .set push
141   .set noat
142   .set noreorder
143   .set nomacro
144   sw    $1, (4 * 1)($4)
145   sw    $2, (4 * 2)($4)
146   sw    $3, (4 * 3)($4)
147   sw    $4, (4 * 4)($4)
148   sw    $5, (4 * 5)($4)
149   sw    $6, (4 * 6)($4)
150   sw    $7, (4 * 7)($4)
151   sw    $8, (4 * 8)($4)
152   sw    $9, (4 * 9)($4)
153   sw    $10, (4 * 10)($4)
154   sw    $11, (4 * 11)($4)
155   sw    $12, (4 * 12)($4)
156   sw    $13, (4 * 13)($4)
157   sw    $14, (4 * 14)($4)
158   sw    $15, (4 * 15)($4)
159   sw    $16, (4 * 16)($4)
160   sw    $17, (4 * 17)($4)
161   sw    $18, (4 * 18)($4)
162   sw    $19, (4 * 19)($4)
163   sw    $20, (4 * 20)($4)
164   sw    $21, (4 * 21)($4)
165   sw    $22, (4 * 22)($4)
166   sw    $23, (4 * 23)($4)
167   sw    $24, (4 * 24)($4)
168   sw    $25, (4 * 25)($4)
169   sw    $26, (4 * 26)($4)
170   sw    $27, (4 * 27)($4)
171   sw    $28, (4 * 28)($4)
172   sw    $29, (4 * 29)($4)
173   sw    $30, (4 * 30)($4)
174   sw    $31, (4 * 31)($4)
175   # Store return address to pc
176   sw    $31, (4 * 32)($4)
177   # hi and lo
178   mfhi  $8
179   sw    $8,  (4 * 33)($4)
180   mflo  $8
181   sw    $8,  (4 * 34)($4)
182 #ifdef __mips_hard_float
183 #if __mips_fpr != 64
184   sdc1  $f0, (4 * 36 + 8 * 0)($4)
185   sdc1  $f2, (4 * 36 + 8 * 2)($4)
186   sdc1  $f4, (4 * 36 + 8 * 4)($4)
187   sdc1  $f6, (4 * 36 + 8 * 6)($4)
188   sdc1  $f8, (4 * 36 + 8 * 8)($4)
189   sdc1  $f10, (4 * 36 + 8 * 10)($4)
190   sdc1  $f12, (4 * 36 + 8 * 12)($4)
191   sdc1  $f14, (4 * 36 + 8 * 14)($4)
192   sdc1  $f16, (4 * 36 + 8 * 16)($4)
193   sdc1  $f18, (4 * 36 + 8 * 18)($4)
194   sdc1  $f20, (4 * 36 + 8 * 20)($4)
195   sdc1  $f22, (4 * 36 + 8 * 22)($4)
196   sdc1  $f24, (4 * 36 + 8 * 24)($4)
197   sdc1  $f26, (4 * 36 + 8 * 26)($4)
198   sdc1  $f28, (4 * 36 + 8 * 28)($4)
199   sdc1  $f30, (4 * 36 + 8 * 30)($4)
200 #else
201   sdc1  $f0, (4 * 36 + 8 * 0)($4)
202   sdc1  $f1, (4 * 36 + 8 * 1)($4)
203   sdc1  $f2, (4 * 36 + 8 * 2)($4)
204   sdc1  $f3, (4 * 36 + 8 * 3)($4)
205   sdc1  $f4, (4 * 36 + 8 * 4)($4)
206   sdc1  $f5, (4 * 36 + 8 * 5)($4)
207   sdc1  $f6, (4 * 36 + 8 * 6)($4)
208   sdc1  $f7, (4 * 36 + 8 * 7)($4)
209   sdc1  $f8, (4 * 36 + 8 * 8)($4)
210   sdc1  $f9, (4 * 36 + 8 * 9)($4)
211   sdc1  $f10, (4 * 36 + 8 * 10)($4)
212   sdc1  $f11, (4 * 36 + 8 * 11)($4)
213   sdc1  $f12, (4 * 36 + 8 * 12)($4)
214   sdc1  $f13, (4 * 36 + 8 * 13)($4)
215   sdc1  $f14, (4 * 36 + 8 * 14)($4)
216   sdc1  $f15, (4 * 36 + 8 * 15)($4)
217   sdc1  $f16, (4 * 36 + 8 * 16)($4)
218   sdc1  $f17, (4 * 36 + 8 * 17)($4)
219   sdc1  $f18, (4 * 36 + 8 * 18)($4)
220   sdc1  $f19, (4 * 36 + 8 * 19)($4)
221   sdc1  $f20, (4 * 36 + 8 * 20)($4)
222   sdc1  $f21, (4 * 36 + 8 * 21)($4)
223   sdc1  $f22, (4 * 36 + 8 * 22)($4)
224   sdc1  $f23, (4 * 36 + 8 * 23)($4)
225   sdc1  $f24, (4 * 36 + 8 * 24)($4)
226   sdc1  $f25, (4 * 36 + 8 * 25)($4)
227   sdc1  $f26, (4 * 36 + 8 * 26)($4)
228   sdc1  $f27, (4 * 36 + 8 * 27)($4)
229   sdc1  $f28, (4 * 36 + 8 * 28)($4)
230   sdc1  $f29, (4 * 36 + 8 * 29)($4)
231   sdc1  $f30, (4 * 36 + 8 * 30)($4)
232   sdc1  $f31, (4 * 36 + 8 * 31)($4)
233 #endif
234 #endif
235   jr    $31
236   # return UNW_ESUCCESS
237   or    $2, $0, $0
238   .set pop
240 #elif defined(__mips64)
243 # extern int __unw_getcontext(unw_context_t* thread_state)
245 # On entry:
246 #  thread_state pointer is in a0 ($4)
248 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
249   .set push
250   .set noat
251   .set noreorder
252   .set nomacro
253   .irp i,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
254     sd $\i, (8 * \i)($4)
255   .endr
256   # Store return address to pc
257   sd    $31, (8 * 32)($4)
258   # hi and lo
259   mfhi  $8
260   sd    $8,  (8 * 33)($4)
261   mflo  $8
262   sd    $8,  (8 * 34)($4)
263 #ifdef __mips_hard_float
264   .irp i,FROM_0_TO_31
265     sdc1 $f\i, (280+8*\i)($4)
266   .endr
267 #endif
268   jr    $31
269   # return UNW_ESUCCESS
270   or    $2, $0, $0
271   .set pop
273 # elif defined(__mips__)
276 # extern int __unw_getcontext(unw_context_t* thread_state)
278 # Just trap for the time being.
279 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
280   teq $0, $0
282 #elif defined(__powerpc64__)
285 // extern int __unw_getcontext(unw_context_t* thread_state)
287 // On entry:
288 //  thread_state pointer is in r3
290 #if defined(_AIX)
291 DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
292 #else
293 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
294 #endif
295 // store register (GPR)
296 #define PPC64_STR(n) \
297   std   n, (8 * (n + 2))(3)
299   // save GPRs
300   PPC64_STR(0)
301   mflr  0
302   std   0, PPC64_OFFS_SRR0(3) // store lr as ssr0
303   PPC64_STR(1)
304   PPC64_STR(2)
305   PPC64_STR(3)
306   PPC64_STR(4)
307   PPC64_STR(5)
308   PPC64_STR(6)
309   PPC64_STR(7)
310   PPC64_STR(8)
311   PPC64_STR(9)
312   PPC64_STR(10)
313   PPC64_STR(11)
314   PPC64_STR(12)
315   PPC64_STR(13)
316   PPC64_STR(14)
317   PPC64_STR(15)
318   PPC64_STR(16)
319   PPC64_STR(17)
320   PPC64_STR(18)
321   PPC64_STR(19)
322   PPC64_STR(20)
323   PPC64_STR(21)
324   PPC64_STR(22)
325   PPC64_STR(23)
326   PPC64_STR(24)
327   PPC64_STR(25)
328   PPC64_STR(26)
329   PPC64_STR(27)
330   PPC64_STR(28)
331   PPC64_STR(29)
332   PPC64_STR(30)
333   PPC64_STR(31)
335   mfcr  0
336   std   0,  PPC64_OFFS_CR(3)
337   mfxer 0
338   std   0,  PPC64_OFFS_XER(3)
339   mflr  0
340   std   0,  PPC64_OFFS_LR(3)
341   mfctr 0
342   std   0,  PPC64_OFFS_CTR(3)
343   mfvrsave    0
344   std   0,  PPC64_OFFS_VRSAVE(3)
346 #if defined(__VSX__)
347   // save VS registers
348   // (note that this also saves floating point registers and V registers,
349   // because part of VS is mapped to these registers)
351   addi  4, 3, PPC64_OFFS_FP
353 // store VS register
354 #ifdef __LITTLE_ENDIAN__
355 // For little-endian targets, we need a swap since stxvd2x will store the
356 // register in the incorrect doubleword order.
357 // FIXME: when supporting targets older than Power9 on LE is no longer required
358 //        this can be changed to simply `stxv n, 16 * n(4)`.
359 #define PPC64_STVS(n)      \
360   xxswapd n, n            ;\
361   stxvd2x n, 0, 4         ;\
362   addi    4, 4, 16
363 #else
364 #define PPC64_STVS(n)      \
365   stxvd2x n, 0, 4         ;\
366   addi    4, 4, 16
367 #endif
369   PPC64_STVS(0)
370   PPC64_STVS(1)
371   PPC64_STVS(2)
372   PPC64_STVS(3)
373   PPC64_STVS(4)
374   PPC64_STVS(5)
375   PPC64_STVS(6)
376   PPC64_STVS(7)
377   PPC64_STVS(8)
378   PPC64_STVS(9)
379   PPC64_STVS(10)
380   PPC64_STVS(11)
381   PPC64_STVS(12)
382   PPC64_STVS(13)
383   PPC64_STVS(14)
384   PPC64_STVS(15)
385   PPC64_STVS(16)
386   PPC64_STVS(17)
387   PPC64_STVS(18)
388   PPC64_STVS(19)
389   PPC64_STVS(20)
390   PPC64_STVS(21)
391   PPC64_STVS(22)
392   PPC64_STVS(23)
393   PPC64_STVS(24)
394   PPC64_STVS(25)
395   PPC64_STVS(26)
396   PPC64_STVS(27)
397   PPC64_STVS(28)
398   PPC64_STVS(29)
399   PPC64_STVS(30)
400   PPC64_STVS(31)
401   PPC64_STVS(32)
402   PPC64_STVS(33)
403   PPC64_STVS(34)
404   PPC64_STVS(35)
405   PPC64_STVS(36)
406   PPC64_STVS(37)
407   PPC64_STVS(38)
408   PPC64_STVS(39)
409   PPC64_STVS(40)
410   PPC64_STVS(41)
411   PPC64_STVS(42)
412   PPC64_STVS(43)
413   PPC64_STVS(44)
414   PPC64_STVS(45)
415   PPC64_STVS(46)
416   PPC64_STVS(47)
417   PPC64_STVS(48)
418   PPC64_STVS(49)
419   PPC64_STVS(50)
420   PPC64_STVS(51)
421   PPC64_STVS(52)
422   PPC64_STVS(53)
423   PPC64_STVS(54)
424   PPC64_STVS(55)
425   PPC64_STVS(56)
426   PPC64_STVS(57)
427   PPC64_STVS(58)
428   PPC64_STVS(59)
429   PPC64_STVS(60)
430   PPC64_STVS(61)
431   PPC64_STVS(62)
432   PPC64_STVS(63)
434 #else
436 // store FP register
437 #define PPC64_STF(n) \
438   stfd  n, (PPC64_OFFS_FP + n * 16)(3)
440   // save float registers
441   PPC64_STF(0)
442   PPC64_STF(1)
443   PPC64_STF(2)
444   PPC64_STF(3)
445   PPC64_STF(4)
446   PPC64_STF(5)
447   PPC64_STF(6)
448   PPC64_STF(7)
449   PPC64_STF(8)
450   PPC64_STF(9)
451   PPC64_STF(10)
452   PPC64_STF(11)
453   PPC64_STF(12)
454   PPC64_STF(13)
455   PPC64_STF(14)
456   PPC64_STF(15)
457   PPC64_STF(16)
458   PPC64_STF(17)
459   PPC64_STF(18)
460   PPC64_STF(19)
461   PPC64_STF(20)
462   PPC64_STF(21)
463   PPC64_STF(22)
464   PPC64_STF(23)
465   PPC64_STF(24)
466   PPC64_STF(25)
467   PPC64_STF(26)
468   PPC64_STF(27)
469   PPC64_STF(28)
470   PPC64_STF(29)
471   PPC64_STF(30)
472   PPC64_STF(31)
474 #if defined(__ALTIVEC__)
475   // save vector registers
477   // Use 16-bytes below the stack pointer as an
478   // aligned buffer to save each vector register.
479   // Note that the stack pointer is always 16-byte aligned.
480   subi  4, 1, 16
482 #define PPC64_STV_UNALIGNED(n)             \
483   stvx  n, 0, 4                           ;\
484   ld    5, 0(4)                           ;\
485   std   5, (PPC64_OFFS_V + n * 16)(3)     ;\
486   ld    5, 8(4)                           ;\
487   std   5, (PPC64_OFFS_V + n * 16 + 8)(3)
489   PPC64_STV_UNALIGNED(0)
490   PPC64_STV_UNALIGNED(1)
491   PPC64_STV_UNALIGNED(2)
492   PPC64_STV_UNALIGNED(3)
493   PPC64_STV_UNALIGNED(4)
494   PPC64_STV_UNALIGNED(5)
495   PPC64_STV_UNALIGNED(6)
496   PPC64_STV_UNALIGNED(7)
497   PPC64_STV_UNALIGNED(8)
498   PPC64_STV_UNALIGNED(9)
499   PPC64_STV_UNALIGNED(10)
500   PPC64_STV_UNALIGNED(11)
501   PPC64_STV_UNALIGNED(12)
502   PPC64_STV_UNALIGNED(13)
503   PPC64_STV_UNALIGNED(14)
504   PPC64_STV_UNALIGNED(15)
505   PPC64_STV_UNALIGNED(16)
506   PPC64_STV_UNALIGNED(17)
507   PPC64_STV_UNALIGNED(18)
508   PPC64_STV_UNALIGNED(19)
509   PPC64_STV_UNALIGNED(20)
510   PPC64_STV_UNALIGNED(21)
511   PPC64_STV_UNALIGNED(22)
512   PPC64_STV_UNALIGNED(23)
513   PPC64_STV_UNALIGNED(24)
514   PPC64_STV_UNALIGNED(25)
515   PPC64_STV_UNALIGNED(26)
516   PPC64_STV_UNALIGNED(27)
517   PPC64_STV_UNALIGNED(28)
518   PPC64_STV_UNALIGNED(29)
519   PPC64_STV_UNALIGNED(30)
520   PPC64_STV_UNALIGNED(31)
522 #endif
523 #endif
525   li    3,  0   // return UNW_ESUCCESS
526   blr
529 #elif defined(__powerpc__)
532 // extern int unw_getcontext(unw_context_t* thread_state)
534 // On entry:
535 //  thread_state pointer is in r3
537 #if defined(_AIX)
538 DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)
539 #else
540 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
541 #endif
542   stw     0,   8(3)
543   mflr    0
544   stw     0,   0(3) // store lr as ssr0
545   stw     1,  12(3)
546   stw     2,  16(3)
547   stw     3,  20(3)
548   stw     4,  24(3)
549   stw     5,  28(3)
550   stw     6,  32(3)
551   stw     7,  36(3)
552   stw     8,  40(3)
553   stw     9,  44(3)
554   stw     10, 48(3)
555   stw     11, 52(3)
556   stw     12, 56(3)
557   stw     13, 60(3)
558   stw     14, 64(3)
559   stw     15, 68(3)
560   stw     16, 72(3)
561   stw     17, 76(3)
562   stw     18, 80(3)
563   stw     19, 84(3)
564   stw     20, 88(3)
565   stw     21, 92(3)
566   stw     22, 96(3)
567   stw     23,100(3)
568   stw     24,104(3)
569   stw     25,108(3)
570   stw     26,112(3)
571   stw     27,116(3)
572   stw     28,120(3)
573   stw     29,124(3)
574   stw     30,128(3)
575   stw     31,132(3)
577 #if defined(__ALTIVEC__)
578   // save VRSave register
579   mfspr   0, 256
580   stw     0, 156(3)
581 #endif
582   // save CR registers
583   mfcr    0
584   stw     0, 136(3)
585   // save CTR register
586   mfctr   0
587   stw     0, 148(3)
589 #if !defined(__NO_FPRS__)
590   // save float registers
591   stfd    0, 160(3)
592   stfd    1, 168(3)
593   stfd    2, 176(3)
594   stfd    3, 184(3)
595   stfd    4, 192(3)
596   stfd    5, 200(3)
597   stfd    6, 208(3)
598   stfd    7, 216(3)
599   stfd    8, 224(3)
600   stfd    9, 232(3)
601   stfd    10,240(3)
602   stfd    11,248(3)
603   stfd    12,256(3)
604   stfd    13,264(3)
605   stfd    14,272(3)
606   stfd    15,280(3)
607   stfd    16,288(3)
608   stfd    17,296(3)
609   stfd    18,304(3)
610   stfd    19,312(3)
611   stfd    20,320(3)
612   stfd    21,328(3)
613   stfd    22,336(3)
614   stfd    23,344(3)
615   stfd    24,352(3)
616   stfd    25,360(3)
617   stfd    26,368(3)
618   stfd    27,376(3)
619   stfd    28,384(3)
620   stfd    29,392(3)
621   stfd    30,400(3)
622   stfd    31,408(3)
623 #endif
625 #if defined(__ALTIVEC__)
626   // save vector registers
628   subi    4, 1, 16
629   rlwinm  4, 4, 0, 0, 27  // mask low 4-bits
630   // r4 is now a 16-byte aligned pointer into the red zone
632 #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
633   stvx    _vec, 0, 4               SEPARATOR \
634   lwz     5, 0(4)                  SEPARATOR \
635   stw     5, _offset(3)            SEPARATOR \
636   lwz     5, 4(4)                  SEPARATOR \
637   stw     5, _offset+4(3)          SEPARATOR \
638   lwz     5, 8(4)                  SEPARATOR \
639   stw     5, _offset+8(3)          SEPARATOR \
640   lwz     5, 12(4)                 SEPARATOR \
641   stw     5, _offset+12(3)
643   SAVE_VECTOR_UNALIGNED( 0, 424+0x000)
644   SAVE_VECTOR_UNALIGNED( 1, 424+0x010)
645   SAVE_VECTOR_UNALIGNED( 2, 424+0x020)
646   SAVE_VECTOR_UNALIGNED( 3, 424+0x030)
647   SAVE_VECTOR_UNALIGNED( 4, 424+0x040)
648   SAVE_VECTOR_UNALIGNED( 5, 424+0x050)
649   SAVE_VECTOR_UNALIGNED( 6, 424+0x060)
650   SAVE_VECTOR_UNALIGNED( 7, 424+0x070)
651   SAVE_VECTOR_UNALIGNED( 8, 424+0x080)
652   SAVE_VECTOR_UNALIGNED( 9, 424+0x090)
653   SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)
654   SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)
655   SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)
656   SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)
657   SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)
658   SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)
659   SAVE_VECTOR_UNALIGNED(16, 424+0x100)
660   SAVE_VECTOR_UNALIGNED(17, 424+0x110)
661   SAVE_VECTOR_UNALIGNED(18, 424+0x120)
662   SAVE_VECTOR_UNALIGNED(19, 424+0x130)
663   SAVE_VECTOR_UNALIGNED(20, 424+0x140)
664   SAVE_VECTOR_UNALIGNED(21, 424+0x150)
665   SAVE_VECTOR_UNALIGNED(22, 424+0x160)
666   SAVE_VECTOR_UNALIGNED(23, 424+0x170)
667   SAVE_VECTOR_UNALIGNED(24, 424+0x180)
668   SAVE_VECTOR_UNALIGNED(25, 424+0x190)
669   SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)
670   SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)
671   SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)
672   SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)
673   SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)
674   SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)
675 #endif
677   li      3, 0  // return UNW_ESUCCESS
678   blr
681 #elif defined(__aarch64__)
684 // extern int __unw_getcontext(unw_context_t* thread_state)
686 // On entry:
687 //  thread_state pointer is in x0
689   .p2align 2
690 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
691   stp    x0, x1,  [x0, #0x000]
692   stp    x2, x3,  [x0, #0x010]
693   stp    x4, x5,  [x0, #0x020]
694   stp    x6, x7,  [x0, #0x030]
695   stp    x8, x9,  [x0, #0x040]
696   stp    x10,x11, [x0, #0x050]
697   stp    x12,x13, [x0, #0x060]
698   stp    x14,x15, [x0, #0x070]
699   stp    x16,x17, [x0, #0x080]
700   stp    x18,x19, [x0, #0x090]
701   stp    x20,x21, [x0, #0x0A0]
702   stp    x22,x23, [x0, #0x0B0]
703   stp    x24,x25, [x0, #0x0C0]
704   stp    x26,x27, [x0, #0x0D0]
705   stp    x28,x29, [x0, #0x0E0]
706   str    x30,     [x0, #0x0F0]
707   mov    x1,sp
708   str    x1,      [x0, #0x0F8]
709   str    x30,     [x0, #0x100]    // store return address as pc
710   // skip cpsr
711   stp    d0, d1,  [x0, #0x110]
712   stp    d2, d3,  [x0, #0x120]
713   stp    d4, d5,  [x0, #0x130]
714   stp    d6, d7,  [x0, #0x140]
715   stp    d8, d9,  [x0, #0x150]
716   stp    d10,d11, [x0, #0x160]
717   stp    d12,d13, [x0, #0x170]
718   stp    d14,d15, [x0, #0x180]
719   stp    d16,d17, [x0, #0x190]
720   stp    d18,d19, [x0, #0x1A0]
721   stp    d20,d21, [x0, #0x1B0]
722   stp    d22,d23, [x0, #0x1C0]
723   stp    d24,d25, [x0, #0x1D0]
724   stp    d26,d27, [x0, #0x1E0]
725   stp    d28,d29, [x0, #0x1F0]
726   str    d30,     [x0, #0x200]
727   str    d31,     [x0, #0x208]
728   mov    x0, #0                   // return UNW_ESUCCESS
729   ret
731 #elif defined(__arm__) && !defined(__APPLE__)
733 #if !defined(__ARM_ARCH_ISA_ARM)
734 #if (__ARM_ARCH_ISA_THUMB == 2)
735   .syntax unified
736 #endif
737   .thumb
738 #endif
741 @ extern int __unw_getcontext(unw_context_t* thread_state)
743 @ On entry:
744 @  thread_state pointer is in r0
746 @ Per EHABI #4.7 this only saves the core integer registers.
747 @ EHABI #7.4.5 notes that in general all VRS registers should be restored
748 @ however this is very hard to do for VFP registers because it is unknown
749 @ to the library how many registers are implemented by the architecture.
750 @ Instead, VFP registers are demand saved by logic external to __unw_getcontext.
752   .p2align 2
753 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
754 #if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1
755   stm r0!, {r0-r7}
756   mov r1, r8
757   mov r2, r9
758   mov r3, r10
759   stm r0!, {r1-r3}
760   mov r1, r11
761   mov r2, sp
762   mov r3, lr
763   str r1, [r0, #0]   @ r11
764   @ r12 does not need storing, it it the intra-procedure-call scratch register
765   str r2, [r0, #8]   @ sp
766   str r3, [r0, #12]  @ lr
767   str r3, [r0, #16]  @ store return address as pc
768   @ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
769   @ It is safe to use here though because we are about to return, and cpsr is
770   @ not expected to be preserved.
771   movs r0, #0        @ return UNW_ESUCCESS
772 #else
773   @ 32bit thumb-2 restrictions for stm:
774   @ . the sp (r13) cannot be in the list
775   @ . the pc (r15) cannot be in the list in an STM instruction
776   stm r0, {r0-r12}
777   str sp, [r0, #52]
778   str lr, [r0, #56]
779   str lr, [r0, #60]  @ store return address as pc
780   mov r0, #0         @ return UNW_ESUCCESS
781 #endif
782   JMP(lr)
785 @ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
787 @ On entry:
788 @  values pointer is in r0
790   .p2align 2
791 #if defined(__ELF__)
792   .fpu vfpv3-d16
793 #endif
794 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv)
795   vstmia r0, {d0-d15}
796   JMP(lr)
799 @ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
801 @ On entry:
802 @  values pointer is in r0
804   .p2align 2
805 #if defined(__ELF__)
806   .fpu vfpv3-d16
807 #endif
808 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv)
809   vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
810   JMP(lr)
813 @ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
815 @ On entry:
816 @  values pointer is in r0
818   .p2align 2
819 #if defined(__ELF__)
820   .fpu vfpv3
821 #endif
822 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv)
823   @ VFP and iwMMX instructions are only available when compiling with the flags
824   @ that enable them. We do not want to do that in the library (because we do not
825   @ want the compiler to generate instructions that access those) but this is
826   @ only accessed if the personality routine needs these registers. Use of
827   @ these registers implies they are, actually, available on the target, so
828   @ it's ok to execute.
829   @ So, generate the instructions using the corresponding coprocessor mnemonic.
830   vstmia r0, {d16-d31}
831   JMP(lr)
833 #if defined(_LIBUNWIND_ARM_WMMX)
836 @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
838 @ On entry:
839 @  values pointer is in r0
841   .p2align 2
842 #if defined(__ELF__)
843   .arch armv5te
844 #endif
845 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv)
846   stcl p1, cr0, [r0], #8  @ wstrd wR0, [r0], #8
847   stcl p1, cr1, [r0], #8  @ wstrd wR1, [r0], #8
848   stcl p1, cr2, [r0], #8  @ wstrd wR2, [r0], #8
849   stcl p1, cr3, [r0], #8  @ wstrd wR3, [r0], #8
850   stcl p1, cr4, [r0], #8  @ wstrd wR4, [r0], #8
851   stcl p1, cr5, [r0], #8  @ wstrd wR5, [r0], #8
852   stcl p1, cr6, [r0], #8  @ wstrd wR6, [r0], #8
853   stcl p1, cr7, [r0], #8  @ wstrd wR7, [r0], #8
854   stcl p1, cr8, [r0], #8  @ wstrd wR8, [r0], #8
855   stcl p1, cr9, [r0], #8  @ wstrd wR9, [r0], #8
856   stcl p1, cr10, [r0], #8  @ wstrd wR10, [r0], #8
857   stcl p1, cr11, [r0], #8  @ wstrd wR11, [r0], #8
858   stcl p1, cr12, [r0], #8  @ wstrd wR12, [r0], #8
859   stcl p1, cr13, [r0], #8  @ wstrd wR13, [r0], #8
860   stcl p1, cr14, [r0], #8  @ wstrd wR14, [r0], #8
861   stcl p1, cr15, [r0], #8  @ wstrd wR15, [r0], #8
862   JMP(lr)
865 @ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
867 @ On entry:
868 @  values pointer is in r0
870   .p2align 2
871 #if defined(__ELF__)
872   .arch armv5te
873 #endif
874 DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
875   stc2 p1, cr8, [r0], #4  @ wstrw wCGR0, [r0], #4
876   stc2 p1, cr9, [r0], #4  @ wstrw wCGR1, [r0], #4
877   stc2 p1, cr10, [r0], #4  @ wstrw wCGR2, [r0], #4
878   stc2 p1, cr11, [r0], #4  @ wstrw wCGR3, [r0], #4
879   JMP(lr)
881 #endif
883 #elif defined(__or1k__)
886 # extern int __unw_getcontext(unw_context_t* thread_state)
888 # On entry:
889 #  thread_state pointer is in r3
891 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
892   l.sw       0(r3), r0
893   l.sw       4(r3), r1
894   l.sw       8(r3), r2
895   l.sw      12(r3), r3
896   l.sw      16(r3), r4
897   l.sw      20(r3), r5
898   l.sw      24(r3), r6
899   l.sw      28(r3), r7
900   l.sw      32(r3), r8
901   l.sw      36(r3), r9
902   l.sw      40(r3), r10
903   l.sw      44(r3), r11
904   l.sw      48(r3), r12
905   l.sw      52(r3), r13
906   l.sw      56(r3), r14
907   l.sw      60(r3), r15
908   l.sw      64(r3), r16
909   l.sw      68(r3), r17
910   l.sw      72(r3), r18
911   l.sw      76(r3), r19
912   l.sw      80(r3), r20
913   l.sw      84(r3), r21
914   l.sw      88(r3), r22
915   l.sw      92(r3), r23
916   l.sw      96(r3), r24
917   l.sw     100(r3), r25
918   l.sw     104(r3), r26
919   l.sw     108(r3), r27
920   l.sw     112(r3), r28
921   l.sw     116(r3), r29
922   l.sw     120(r3), r30
923   l.sw     124(r3), r31
924   # store ra to pc
925   l.sw     128(r3), r9
926   # zero epcr
927   l.sw     132(r3), r0
929 #elif defined(__hexagon__)
931 # extern int unw_getcontext(unw_context_t* thread_state)
933 # On entry:
934 #  thread_state pointer is in r0
936 #define OFFSET(offset) (offset/4)
937 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
938   memw(r0+#32) = r8
939   memw(r0+#36) = r9
940   memw(r0+#40) = r10
941   memw(r0+#44) = r11
943   memw(r0+#48) = r12
944   memw(r0+#52) = r13
945   memw(r0+#56) = r14
946   memw(r0+#60) = r15
948   memw(r0+#64) = r16
949   memw(r0+#68) = r17
950   memw(r0+#72) = r18
951   memw(r0+#76) = r19
953   memw(r0+#80) = r20
954   memw(r0+#84) = r21
955   memw(r0+#88) = r22
956   memw(r0+#92) = r23
958   memw(r0+#96) = r24
959   memw(r0+#100) = r25
960   memw(r0+#104) = r26
961   memw(r0+#108) = r27
963   memw(r0+#112) = r28
964   memw(r0+#116) = r29
965   memw(r0+#120) = r30
966   memw(r0+#124) = r31
967   r1 = c4   // Predicate register
968   memw(r0+#128) = r1
969   r1 = memw(r30)           // *FP == Saved FP
970   r1 = r31
971   memw(r0+#132) = r1
973   jumpr r31
975 #elif defined(__sparc__) && defined(__arch64__)
978 # extern int __unw_getcontext(unw_context_t* thread_state)
980 # On entry:
981 #  thread_state pointer is in %o0
983 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
984   .register %g2, #scratch
985   .register %g3, #scratch
986   .register %g6, #scratch
987   .register %g7, #scratch
988   stx  %g1, [%o0 + 0x08]
989   stx  %g2, [%o0 + 0x10]
990   stx  %g3, [%o0 + 0x18]
991   stx  %g4, [%o0 + 0x20]
992   stx  %g5, [%o0 + 0x28]
993   stx  %g6, [%o0 + 0x30]
994   stx  %g7, [%o0 + 0x38]
995   stx  %o0, [%o0 + 0x40]
996   stx  %o1, [%o0 + 0x48]
997   stx  %o2, [%o0 + 0x50]
998   stx  %o3, [%o0 + 0x58]
999   stx  %o4, [%o0 + 0x60]
1000   stx  %o5, [%o0 + 0x68]
1001   stx  %o6, [%o0 + 0x70]
1002   stx  %o7, [%o0 + 0x78]
1003   stx  %l0, [%o0 + 0x80]
1004   stx  %l1, [%o0 + 0x88]
1005   stx  %l2, [%o0 + 0x90]
1006   stx  %l3, [%o0 + 0x98]
1007   stx  %l4, [%o0 + 0xa0]
1008   stx  %l5, [%o0 + 0xa8]
1009   stx  %l6, [%o0 + 0xb0]
1010   stx  %l7, [%o0 + 0xb8]
1011   stx  %i0, [%o0 + 0xc0]
1012   stx  %i1, [%o0 + 0xc8]
1013   stx  %i2, [%o0 + 0xd0]
1014   stx  %i3, [%o0 + 0xd8]
1015   stx  %i4, [%o0 + 0xe0]
1016   stx  %i5, [%o0 + 0xe8]
1017   stx  %i6, [%o0 + 0xf0]
1018   stx  %i7, [%o0 + 0xf8]
1020   # save StackGhost cookie
1021   mov  %i7, %g4
1022   save %sp, -176, %sp
1023   # register window flush necessary even without StackGhost
1024   flushw
1025   restore
1026   ldx  [%sp + 2047 + 0x78], %g5
1027   xor  %g4, %g5, %g4
1028   stx  %g4, [%o0 + 0x100]
1029   retl
1030   # return UNW_ESUCCESS
1031    clr %o0
1033 #elif defined(__sparc__)
1036 # extern int __unw_getcontext(unw_context_t* thread_state)
1038 # On entry:
1039 #  thread_state pointer is in o0
1041 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1042   ta 3
1043   add %o7, 8, %o7
1044   std %g0, [%o0 +   0]
1045   std %g2, [%o0 +   8]
1046   std %g4, [%o0 +  16]
1047   std %g6, [%o0 +  24]
1048   std %o0, [%o0 +  32]
1049   std %o2, [%o0 +  40]
1050   std %o4, [%o0 +  48]
1051   std %o6, [%o0 +  56]
1052   std %l0, [%o0 +  64]
1053   std %l2, [%o0 +  72]
1054   std %l4, [%o0 +  80]
1055   std %l6, [%o0 +  88]
1056   std %i0, [%o0 +  96]
1057   std %i2, [%o0 + 104]
1058   std %i4, [%o0 + 112]
1059   std %i6, [%o0 + 120]
1060   jmp %o7
1061    clr %o0                   // return UNW_ESUCCESS
1063 #elif defined(__riscv)
1066 # extern int __unw_getcontext(unw_context_t* thread_state)
1068 # On entry:
1069 #  thread_state pointer is in a0
1071 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1072   ISTORE    x1, (RISCV_ISIZE * 0)(a0) // store ra as pc
1073   .irp i,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
1074     ISTORE x\i, (RISCV_ISIZE * \i)(a0)
1075   .endr
1077 # if defined(__riscv_flen)
1078   .irp i,FROM_0_TO_31
1079     FSTORE f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0)
1080   .endr
1081 # endif
1083   li     a0, 0  // return UNW_ESUCCESS
1084   ret           // jump to ra
1086 #elif defined(__s390x__)
1089 // extern int __unw_getcontext(unw_context_t* thread_state)
1091 // On entry:
1092 //  thread_state pointer is in r2
1094 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1096   // Save GPRs
1097   stmg %r0, %r15, 16(%r2)
1099   // Save PSWM
1100   epsw %r0, %r1
1101   stm %r0, %r1, 0(%r2)
1103   // Store return address as PSWA
1104   stg %r14, 8(%r2)
1106   // Save FPRs
1107   .irp i,FROM_0_TO_15
1108     std %f\i, (144+8*\i)(%r2)
1109   .endr
1111   // Return UNW_ESUCCESS
1112   lghi %r2, 0
1113   br %r14
1115 #elif defined(__loongarch__) && __loongarch_grlen == 64
1118 # extern int __unw_getcontext(unw_context_t* thread_state)
1120 # On entry:
1121 #  thread_state pointer is in $a0($r4)
1123 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
1124   .irp i,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
1125     st.d $r\i, $a0, (8*\i)
1126   .endr
1127   st.d    $r1,  $a0, (8 * 32) // store $ra to pc
1129 # if __loongarch_frlen == 64
1130   .irp i,FROM_0_TO_31
1131     fst.d $f\i, $a0, (8 * 33 + 8 * \i)
1132   .endr
1133 # endif
1135   move     $a0, $zero  // UNW_ESUCCESS
1136   jr       $ra
1138 #endif
1140   WEAK_ALIAS(__unw_getcontext, unw_getcontext)
1142 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
1144 NO_EXEC_STACK_DIRECTIVE