]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S
Merge LLVM libunwind trunk r351319, from just before upstream's
[FreeBSD/FreeBSD.git] / contrib / llvm / projects / libunwind / src / UnwindRegistersSave.S
1 //===------------------------ UnwindRegistersSave.S -----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "assembly.h"
11
12     .text
13
14 #if !defined(__USING_SJLJ_EXCEPTIONS__)
15
16 #if defined(__i386__)
17
18 #
19 # extern int unw_getcontext(unw_context_t* thread_state)
20 #
21 # On entry:
22 #   +                       +
23 #   +-----------------------+
24 #   + thread_state pointer  +
25 #   +-----------------------+
26 #   + return address        +
27 #   +-----------------------+   <-- SP
28 #   +                       +
29 #
30 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
31   push  %eax
32   movl  8(%esp), %eax
33   movl  %ebx,  4(%eax)
34   movl  %ecx,  8(%eax)
35   movl  %edx, 12(%eax)
36   movl  %edi, 16(%eax)
37   movl  %esi, 20(%eax)
38   movl  %ebp, 24(%eax)
39   movl  %esp, %edx
40   addl  $8, %edx
41   movl  %edx, 28(%eax)  # store what sp was at call site as esp
42   # skip ss
43   # skip eflags
44   movl  4(%esp), %edx
45   movl  %edx, 40(%eax)  # store return address as eip
46   # skip cs
47   # skip ds
48   # skip es
49   # skip fs
50   # skip gs
51   movl  (%esp), %edx
52   movl  %edx, (%eax)  # store original eax
53   popl  %eax
54   xorl  %eax, %eax    # return UNW_ESUCCESS
55   ret
56
57 #elif defined(__x86_64__)
58
59 #
60 # extern int unw_getcontext(unw_context_t* thread_state)
61 #
62 # On entry:
63 #  thread_state pointer is in rdi
64 #
65 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
66 #if defined(_WIN64)
67 #define PTR %rcx
68 #define TMP %rdx
69 #else
70 #define PTR %rdi
71 #define TMP %rsi
72 #endif
73
74   movq  %rax,   (PTR)
75   movq  %rbx,  8(PTR)
76   movq  %rcx, 16(PTR)
77   movq  %rdx, 24(PTR)
78   movq  %rdi, 32(PTR)
79   movq  %rsi, 40(PTR)
80   movq  %rbp, 48(PTR)
81   movq  %rsp, 56(PTR)
82   addq  $8,   56(PTR)
83   movq  %r8,  64(PTR)
84   movq  %r9,  72(PTR)
85   movq  %r10, 80(PTR)
86   movq  %r11, 88(PTR)
87   movq  %r12, 96(PTR)
88   movq  %r13,104(PTR)
89   movq  %r14,112(PTR)
90   movq  %r15,120(PTR)
91   movq  (%rsp),TMP
92   movq  TMP,128(PTR) # store return address as rip
93   # skip rflags
94   # skip cs
95   # skip fs
96   # skip gs
97
98 #if defined(_WIN64)
99   movdqu %xmm0,176(PTR)
100   movdqu %xmm1,192(PTR)
101   movdqu %xmm2,208(PTR)
102   movdqu %xmm3,224(PTR)
103   movdqu %xmm4,240(PTR)
104   movdqu %xmm5,256(PTR)
105   movdqu %xmm6,272(PTR)
106   movdqu %xmm7,288(PTR)
107   movdqu %xmm8,304(PTR)
108   movdqu %xmm9,320(PTR)
109   movdqu %xmm10,336(PTR)
110   movdqu %xmm11,352(PTR)
111   movdqu %xmm12,368(PTR)
112   movdqu %xmm13,384(PTR)
113   movdqu %xmm14,400(PTR)
114   movdqu %xmm15,416(PTR)
115 #endif
116   xorl  %eax, %eax    # return UNW_ESUCCESS
117   ret
118
119 #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
120
121 #
122 # extern int unw_getcontext(unw_context_t* thread_state)
123 #
124 # On entry:
125 #  thread_state pointer is in a0 ($4)
126 #
127 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
128   .set push
129   .set noat
130   .set noreorder
131   .set nomacro
132   sw    $1, (4 * 1)($4)
133   sw    $2, (4 * 2)($4)
134   sw    $3, (4 * 3)($4)
135   sw    $4, (4 * 4)($4)
136   sw    $5, (4 * 5)($4)
137   sw    $6, (4 * 6)($4)
138   sw    $7, (4 * 7)($4)
139   sw    $8, (4 * 8)($4)
140   sw    $9, (4 * 9)($4)
141   sw    $10, (4 * 10)($4)
142   sw    $11, (4 * 11)($4)
143   sw    $12, (4 * 12)($4)
144   sw    $13, (4 * 13)($4)
145   sw    $14, (4 * 14)($4)
146   sw    $15, (4 * 15)($4)
147   sw    $16, (4 * 16)($4)
148   sw    $17, (4 * 17)($4)
149   sw    $18, (4 * 18)($4)
150   sw    $19, (4 * 19)($4)
151   sw    $20, (4 * 20)($4)
152   sw    $21, (4 * 21)($4)
153   sw    $22, (4 * 22)($4)
154   sw    $23, (4 * 23)($4)
155   sw    $24, (4 * 24)($4)
156   sw    $25, (4 * 25)($4)
157   sw    $26, (4 * 26)($4)
158   sw    $27, (4 * 27)($4)
159   sw    $28, (4 * 28)($4)
160   sw    $29, (4 * 29)($4)
161   sw    $30, (4 * 30)($4)
162   sw    $31, (4 * 31)($4)
163   # Store return address to pc
164   sw    $31, (4 * 32)($4)
165   # hi and lo
166   mfhi  $8
167   sw    $8,  (4 * 33)($4)
168   mflo  $8
169   sw    $8,  (4 * 34)($4)
170 #ifdef __mips_hard_float
171 #if __mips_fpr != 64
172   sdc1  $f0, (4 * 36 + 8 * 0)($4)
173   sdc1  $f2, (4 * 36 + 8 * 2)($4)
174   sdc1  $f4, (4 * 36 + 8 * 4)($4)
175   sdc1  $f6, (4 * 36 + 8 * 6)($4)
176   sdc1  $f8, (4 * 36 + 8 * 8)($4)
177   sdc1  $f10, (4 * 36 + 8 * 10)($4)
178   sdc1  $f12, (4 * 36 + 8 * 12)($4)
179   sdc1  $f14, (4 * 36 + 8 * 14)($4)
180   sdc1  $f16, (4 * 36 + 8 * 16)($4)
181   sdc1  $f18, (4 * 36 + 8 * 18)($4)
182   sdc1  $f20, (4 * 36 + 8 * 20)($4)
183   sdc1  $f22, (4 * 36 + 8 * 22)($4)
184   sdc1  $f24, (4 * 36 + 8 * 24)($4)
185   sdc1  $f26, (4 * 36 + 8 * 26)($4)
186   sdc1  $f28, (4 * 36 + 8 * 28)($4)
187   sdc1  $f30, (4 * 36 + 8 * 30)($4)
188 #else
189   sdc1  $f0, (4 * 36 + 8 * 0)($4)
190   sdc1  $f1, (4 * 36 + 8 * 1)($4)
191   sdc1  $f2, (4 * 36 + 8 * 2)($4)
192   sdc1  $f3, (4 * 36 + 8 * 3)($4)
193   sdc1  $f4, (4 * 36 + 8 * 4)($4)
194   sdc1  $f5, (4 * 36 + 8 * 5)($4)
195   sdc1  $f6, (4 * 36 + 8 * 6)($4)
196   sdc1  $f7, (4 * 36 + 8 * 7)($4)
197   sdc1  $f8, (4 * 36 + 8 * 8)($4)
198   sdc1  $f9, (4 * 36 + 8 * 9)($4)
199   sdc1  $f10, (4 * 36 + 8 * 10)($4)
200   sdc1  $f11, (4 * 36 + 8 * 11)($4)
201   sdc1  $f12, (4 * 36 + 8 * 12)($4)
202   sdc1  $f13, (4 * 36 + 8 * 13)($4)
203   sdc1  $f14, (4 * 36 + 8 * 14)($4)
204   sdc1  $f15, (4 * 36 + 8 * 15)($4)
205   sdc1  $f16, (4 * 36 + 8 * 16)($4)
206   sdc1  $f17, (4 * 36 + 8 * 17)($4)
207   sdc1  $f18, (4 * 36 + 8 * 18)($4)
208   sdc1  $f19, (4 * 36 + 8 * 19)($4)
209   sdc1  $f20, (4 * 36 + 8 * 20)($4)
210   sdc1  $f21, (4 * 36 + 8 * 21)($4)
211   sdc1  $f22, (4 * 36 + 8 * 22)($4)
212   sdc1  $f23, (4 * 36 + 8 * 23)($4)
213   sdc1  $f24, (4 * 36 + 8 * 24)($4)
214   sdc1  $f25, (4 * 36 + 8 * 25)($4)
215   sdc1  $f26, (4 * 36 + 8 * 26)($4)
216   sdc1  $f27, (4 * 36 + 8 * 27)($4)
217   sdc1  $f28, (4 * 36 + 8 * 28)($4)
218   sdc1  $f29, (4 * 36 + 8 * 29)($4)
219   sdc1  $f30, (4 * 36 + 8 * 30)($4)
220   sdc1  $f31, (4 * 36 + 8 * 31)($4)
221 #endif
222 #endif
223   jr    $31
224   # return UNW_ESUCCESS
225   or    $2, $0, $0
226   .set pop
227
228 #elif defined(__mips64)
229
230 #
231 # extern int unw_getcontext(unw_context_t* thread_state)
232 #
233 # On entry:
234 #  thread_state pointer is in a0 ($4)
235 #
236 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
237   .set push
238   .set noat
239   .set noreorder
240   .set nomacro
241   sd    $1, (8 * 1)($4)
242   sd    $2, (8 * 2)($4)
243   sd    $3, (8 * 3)($4)
244   sd    $4, (8 * 4)($4)
245   sd    $5, (8 * 5)($4)
246   sd    $6, (8 * 6)($4)
247   sd    $7, (8 * 7)($4)
248   sd    $8, (8 * 8)($4)
249   sd    $9, (8 * 9)($4)
250   sd    $10, (8 * 10)($4)
251   sd    $11, (8 * 11)($4)
252   sd    $12, (8 * 12)($4)
253   sd    $13, (8 * 13)($4)
254   sd    $14, (8 * 14)($4)
255   sd    $15, (8 * 15)($4)
256   sd    $16, (8 * 16)($4)
257   sd    $17, (8 * 17)($4)
258   sd    $18, (8 * 18)($4)
259   sd    $19, (8 * 19)($4)
260   sd    $20, (8 * 20)($4)
261   sd    $21, (8 * 21)($4)
262   sd    $22, (8 * 22)($4)
263   sd    $23, (8 * 23)($4)
264   sd    $24, (8 * 24)($4)
265   sd    $25, (8 * 25)($4)
266   sd    $26, (8 * 26)($4)
267   sd    $27, (8 * 27)($4)
268   sd    $28, (8 * 28)($4)
269   sd    $29, (8 * 29)($4)
270   sd    $30, (8 * 30)($4)
271   sd    $31, (8 * 31)($4)
272   # Store return address to pc
273   sd    $31, (8 * 32)($4)
274   # hi and lo
275   mfhi  $8
276   sd    $8,  (8 * 33)($4)
277   mflo  $8
278   sd    $8,  (8 * 34)($4)
279 #ifdef __mips_hard_float
280   sdc1  $f0, (8 * 35)($4)
281   sdc1  $f1, (8 * 36)($4)
282   sdc1  $f2, (8 * 37)($4)
283   sdc1  $f3, (8 * 38)($4)
284   sdc1  $f4, (8 * 39)($4)
285   sdc1  $f5, (8 * 40)($4)
286   sdc1  $f6, (8 * 41)($4)
287   sdc1  $f7, (8 * 42)($4)
288   sdc1  $f8, (8 * 43)($4)
289   sdc1  $f9, (8 * 44)($4)
290   sdc1  $f10, (8 * 45)($4)
291   sdc1  $f11, (8 * 46)($4)
292   sdc1  $f12, (8 * 47)($4)
293   sdc1  $f13, (8 * 48)($4)
294   sdc1  $f14, (8 * 49)($4)
295   sdc1  $f15, (8 * 50)($4)
296   sdc1  $f16, (8 * 51)($4)
297   sdc1  $f17, (8 * 52)($4)
298   sdc1  $f18, (8 * 53)($4)
299   sdc1  $f19, (8 * 54)($4)
300   sdc1  $f20, (8 * 55)($4)
301   sdc1  $f21, (8 * 56)($4)
302   sdc1  $f22, (8 * 57)($4)
303   sdc1  $f23, (8 * 58)($4)
304   sdc1  $f24, (8 * 59)($4)
305   sdc1  $f25, (8 * 60)($4)
306   sdc1  $f26, (8 * 61)($4)
307   sdc1  $f27, (8 * 62)($4)
308   sdc1  $f28, (8 * 63)($4)
309   sdc1  $f29, (8 * 64)($4)
310   sdc1  $f30, (8 * 65)($4)
311   sdc1  $f31, (8 * 66)($4)
312 #endif
313   jr    $31
314   # return UNW_ESUCCESS
315   or    $2, $0, $0
316   .set pop
317
318 # elif defined(__mips__)
319
320 #
321 # extern int unw_getcontext(unw_context_t* thread_state)
322 #
323 # Just trap for the time being.
324 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
325   teq $0, $0
326
327 #elif defined(__powerpc64__)
328
329 //
330 // extern int unw_getcontext(unw_context_t* thread_state)
331 //
332 // On entry:
333 //  thread_state pointer is in r3
334 //
335 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
336
337 // store register (GPR)
338 #define PPC64_STR(n) \
339   std   %r##n, (8 * (n + 2))(%r3)
340
341   // save GPRs
342   PPC64_STR(0)
343   mflr  %r0
344   std   %r0, PPC64_OFFS_SRR0(%r3) // store lr as ssr0
345   PPC64_STR(1)
346   PPC64_STR(2)
347   PPC64_STR(3)
348   PPC64_STR(4)
349   PPC64_STR(5)
350   PPC64_STR(6)
351   PPC64_STR(7)
352   PPC64_STR(8)
353   PPC64_STR(9)
354   PPC64_STR(10)
355   PPC64_STR(11)
356   PPC64_STR(12)
357   PPC64_STR(13)
358   PPC64_STR(14)
359   PPC64_STR(15)
360   PPC64_STR(16)
361   PPC64_STR(17)
362   PPC64_STR(18)
363   PPC64_STR(19)
364   PPC64_STR(20)
365   PPC64_STR(21)
366   PPC64_STR(22)
367   PPC64_STR(23)
368   PPC64_STR(24)
369   PPC64_STR(25)
370   PPC64_STR(26)
371   PPC64_STR(27)
372   PPC64_STR(28)
373   PPC64_STR(29)
374   PPC64_STR(30)
375   PPC64_STR(31)
376
377   mfcr  %r0
378   std   %r0,  PPC64_OFFS_CR(%r3)
379   mfxer %r0
380   std   %r0,  PPC64_OFFS_XER(%r3)
381   mflr  %r0
382   std   %r0,  PPC64_OFFS_LR(%r3)
383   mfctr %r0
384   std   %r0,  PPC64_OFFS_CTR(%r3)
385   mfvrsave    %r0
386   std   %r0,  PPC64_OFFS_VRSAVE(%r3)
387
388 #ifdef PPC64_HAS_VMX
389   // save VS registers
390   // (note that this also saves floating point registers and V registers,
391   // because part of VS is mapped to these registers)
392
393   addi  %r4, %r3, PPC64_OFFS_FP
394
395 // store VS register
396 #define PPC64_STVS(n)      \
397   stxvd2x %vs##n, 0, %r4  ;\
398   addi    %r4, %r4, 16
399
400   PPC64_STVS(0)
401   PPC64_STVS(1)
402   PPC64_STVS(2)
403   PPC64_STVS(3)
404   PPC64_STVS(4)
405   PPC64_STVS(5)
406   PPC64_STVS(6)
407   PPC64_STVS(7)
408   PPC64_STVS(8)
409   PPC64_STVS(9)
410   PPC64_STVS(10)
411   PPC64_STVS(11)
412   PPC64_STVS(12)
413   PPC64_STVS(13)
414   PPC64_STVS(14)
415   PPC64_STVS(15)
416   PPC64_STVS(16)
417   PPC64_STVS(17)
418   PPC64_STVS(18)
419   PPC64_STVS(19)
420   PPC64_STVS(20)
421   PPC64_STVS(21)
422   PPC64_STVS(22)
423   PPC64_STVS(23)
424   PPC64_STVS(24)
425   PPC64_STVS(25)
426   PPC64_STVS(26)
427   PPC64_STVS(27)
428   PPC64_STVS(28)
429   PPC64_STVS(29)
430   PPC64_STVS(30)
431   PPC64_STVS(31)
432   PPC64_STVS(32)
433   PPC64_STVS(33)
434   PPC64_STVS(34)
435   PPC64_STVS(35)
436   PPC64_STVS(36)
437   PPC64_STVS(37)
438   PPC64_STVS(38)
439   PPC64_STVS(39)
440   PPC64_STVS(40)
441   PPC64_STVS(41)
442   PPC64_STVS(42)
443   PPC64_STVS(43)
444   PPC64_STVS(44)
445   PPC64_STVS(45)
446   PPC64_STVS(46)
447   PPC64_STVS(47)
448   PPC64_STVS(48)
449   PPC64_STVS(49)
450   PPC64_STVS(50)
451   PPC64_STVS(51)
452   PPC64_STVS(52)
453   PPC64_STVS(53)
454   PPC64_STVS(54)
455   PPC64_STVS(55)
456   PPC64_STVS(56)
457   PPC64_STVS(57)
458   PPC64_STVS(58)
459   PPC64_STVS(59)
460   PPC64_STVS(60)
461   PPC64_STVS(61)
462   PPC64_STVS(62)
463   PPC64_STVS(63)
464
465 #else
466
467 // store FP register
468 #define PPC64_STF(n) \
469   stfd  %f##n, (PPC64_OFFS_FP + n * 16)(%r3)
470
471   // save float registers
472   PPC64_STF(0)
473   PPC64_STF(1)
474   PPC64_STF(2)
475   PPC64_STF(3)
476   PPC64_STF(4)
477   PPC64_STF(5)
478   PPC64_STF(6)
479   PPC64_STF(7)
480   PPC64_STF(8)
481   PPC64_STF(9)
482   PPC64_STF(10)
483   PPC64_STF(11)
484   PPC64_STF(12)
485   PPC64_STF(13)
486   PPC64_STF(14)
487   PPC64_STF(15)
488   PPC64_STF(16)
489   PPC64_STF(17)
490   PPC64_STF(18)
491   PPC64_STF(19)
492   PPC64_STF(20)
493   PPC64_STF(21)
494   PPC64_STF(22)
495   PPC64_STF(23)
496   PPC64_STF(24)
497   PPC64_STF(25)
498   PPC64_STF(26)
499   PPC64_STF(27)
500   PPC64_STF(28)
501   PPC64_STF(29)
502   PPC64_STF(30)
503   PPC64_STF(31)
504
505   // save vector registers
506
507   // Use 16-bytes below the stack pointer as an
508   // aligned buffer to save each vector register.
509   // Note that the stack pointer is always 16-byte aligned.
510   subi  %r4, %r1, 16
511
512 #define PPC64_STV_UNALIGNED(n)                 \
513   stvx  %v##n, 0, %r4                         ;\
514   ld    %r5, 0(%r4)                           ;\
515   std   %r5, (PPC64_OFFS_V + n * 16)(%r3)     ;\
516   ld    %r5, 8(%r4)                           ;\
517   std   %r5, (PPC64_OFFS_V + n * 16 + 8)(%r3)
518
519   PPC64_STV_UNALIGNED(0)
520   PPC64_STV_UNALIGNED(1)
521   PPC64_STV_UNALIGNED(2)
522   PPC64_STV_UNALIGNED(3)
523   PPC64_STV_UNALIGNED(4)
524   PPC64_STV_UNALIGNED(5)
525   PPC64_STV_UNALIGNED(6)
526   PPC64_STV_UNALIGNED(7)
527   PPC64_STV_UNALIGNED(8)
528   PPC64_STV_UNALIGNED(9)
529   PPC64_STV_UNALIGNED(10)
530   PPC64_STV_UNALIGNED(11)
531   PPC64_STV_UNALIGNED(12)
532   PPC64_STV_UNALIGNED(13)
533   PPC64_STV_UNALIGNED(14)
534   PPC64_STV_UNALIGNED(15)
535   PPC64_STV_UNALIGNED(16)
536   PPC64_STV_UNALIGNED(17)
537   PPC64_STV_UNALIGNED(18)
538   PPC64_STV_UNALIGNED(19)
539   PPC64_STV_UNALIGNED(20)
540   PPC64_STV_UNALIGNED(21)
541   PPC64_STV_UNALIGNED(22)
542   PPC64_STV_UNALIGNED(23)
543   PPC64_STV_UNALIGNED(24)
544   PPC64_STV_UNALIGNED(25)
545   PPC64_STV_UNALIGNED(26)
546   PPC64_STV_UNALIGNED(27)
547   PPC64_STV_UNALIGNED(28)
548   PPC64_STV_UNALIGNED(29)
549   PPC64_STV_UNALIGNED(30)
550   PPC64_STV_UNALIGNED(31)
551
552 #endif
553
554   li    %r3,  0   // return UNW_ESUCCESS
555   blr
556
557
558 #elif defined(__ppc__)
559
560 ;
561 ; extern int unw_getcontext(unw_context_t* thread_state)
562 ;
563 ; On entry:
564 ;  thread_state pointer is in r3
565 ;
566 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
567   stw    r0,  8(r3)
568   mflr  r0
569   stw    r0,  0(r3)  ; store lr as ssr0
570   stw    r1, 12(r3)
571   stw    r2, 16(r3)
572   stw    r3, 20(r3)
573   stw    r4, 24(r3)
574   stw    r5, 28(r3)
575   stw    r6, 32(r3)
576   stw    r7, 36(r3)
577   stw    r8, 40(r3)
578   stw    r9, 44(r3)
579   stw     r10, 48(r3)
580   stw     r11, 52(r3)
581   stw     r12, 56(r3)
582   stw     r13, 60(r3)
583   stw     r14, 64(r3)
584   stw     r15, 68(r3)
585   stw     r16, 72(r3)
586   stw     r17, 76(r3)
587   stw     r18, 80(r3)
588   stw     r19, 84(r3)
589   stw     r20, 88(r3)
590   stw     r21, 92(r3)
591   stw     r22, 96(r3)
592   stw     r23,100(r3)
593   stw     r24,104(r3)
594   stw     r25,108(r3)
595   stw     r26,112(r3)
596   stw     r27,116(r3)
597   stw     r28,120(r3)
598   stw     r29,124(r3)
599   stw     r30,128(r3)
600   stw     r31,132(r3)
601
602   ; save VRSave register
603   mfspr  r0,256
604   stw    r0,156(r3)
605   ; save CR registers
606   mfcr  r0
607   stw    r0,136(r3)
608   ; save CTR register
609   mfctr  r0
610   stw    r0,148(r3)
611
612   ; save float registers
613   stfd    f0, 160(r3)
614   stfd    f1, 168(r3)
615   stfd    f2, 176(r3)
616   stfd    f3, 184(r3)
617   stfd    f4, 192(r3)
618   stfd    f5, 200(r3)
619   stfd    f6, 208(r3)
620   stfd    f7, 216(r3)
621   stfd    f8, 224(r3)
622   stfd    f9, 232(r3)
623   stfd    f10,240(r3)
624   stfd    f11,248(r3)
625   stfd    f12,256(r3)
626   stfd    f13,264(r3)
627   stfd    f14,272(r3)
628   stfd    f15,280(r3)
629   stfd    f16,288(r3)
630   stfd    f17,296(r3)
631   stfd    f18,304(r3)
632   stfd    f19,312(r3)
633   stfd    f20,320(r3)
634   stfd    f21,328(r3)
635   stfd    f22,336(r3)
636   stfd    f23,344(r3)
637   stfd    f24,352(r3)
638   stfd    f25,360(r3)
639   stfd    f26,368(r3)
640   stfd    f27,376(r3)
641   stfd    f28,384(r3)
642   stfd    f29,392(r3)
643   stfd    f30,400(r3)
644   stfd    f31,408(r3)
645
646
647   ; save vector registers
648
649   subi  r4,r1,16
650   rlwinm  r4,r4,0,0,27  ; mask low 4-bits
651   ; r4 is now a 16-byte aligned pointer into the red zone
652
653 #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
654   stvx  _vec,0,r4           @\
655   lwz    r5, 0(r4)          @\
656   stw    r5, _offset(r3)    @\
657   lwz    r5, 4(r4)          @\
658   stw    r5, _offset+4(r3)  @\
659   lwz    r5, 8(r4)          @\
660   stw    r5, _offset+8(r3)  @\
661   lwz    r5, 12(r4)         @\
662   stw    r5, _offset+12(r3)
663
664   SAVE_VECTOR_UNALIGNED( v0, 424+0x000)
665   SAVE_VECTOR_UNALIGNED( v1, 424+0x010)
666   SAVE_VECTOR_UNALIGNED( v2, 424+0x020)
667   SAVE_VECTOR_UNALIGNED( v3, 424+0x030)
668   SAVE_VECTOR_UNALIGNED( v4, 424+0x040)
669   SAVE_VECTOR_UNALIGNED( v5, 424+0x050)
670   SAVE_VECTOR_UNALIGNED( v6, 424+0x060)
671   SAVE_VECTOR_UNALIGNED( v7, 424+0x070)
672   SAVE_VECTOR_UNALIGNED( v8, 424+0x080)
673   SAVE_VECTOR_UNALIGNED( v9, 424+0x090)
674   SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0)
675   SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0)
676   SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0)
677   SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0)
678   SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0)
679   SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0)
680   SAVE_VECTOR_UNALIGNED(v16, 424+0x100)
681   SAVE_VECTOR_UNALIGNED(v17, 424+0x110)
682   SAVE_VECTOR_UNALIGNED(v18, 424+0x120)
683   SAVE_VECTOR_UNALIGNED(v19, 424+0x130)
684   SAVE_VECTOR_UNALIGNED(v20, 424+0x140)
685   SAVE_VECTOR_UNALIGNED(v21, 424+0x150)
686   SAVE_VECTOR_UNALIGNED(v22, 424+0x160)
687   SAVE_VECTOR_UNALIGNED(v23, 424+0x170)
688   SAVE_VECTOR_UNALIGNED(v24, 424+0x180)
689   SAVE_VECTOR_UNALIGNED(v25, 424+0x190)
690   SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0)
691   SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0)
692   SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0)
693   SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0)
694   SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0)
695   SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0)
696
697   li  r3, 0    ; return UNW_ESUCCESS
698   blr
699
700
701 #elif defined(__arm64__) || defined(__aarch64__)
702
703 //
704 // extern int unw_getcontext(unw_context_t* thread_state)
705 //
706 // On entry:
707 //  thread_state pointer is in x0
708 //
709   .p2align 2
710 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
711   stp    x0, x1,  [x0, #0x000]
712   stp    x2, x3,  [x0, #0x010]
713   stp    x4, x5,  [x0, #0x020]
714   stp    x6, x7,  [x0, #0x030]
715   stp    x8, x9,  [x0, #0x040]
716   stp    x10,x11, [x0, #0x050]
717   stp    x12,x13, [x0, #0x060]
718   stp    x14,x15, [x0, #0x070]
719   stp    x16,x17, [x0, #0x080]
720   stp    x18,x19, [x0, #0x090]
721   stp    x20,x21, [x0, #0x0A0]
722   stp    x22,x23, [x0, #0x0B0]
723   stp    x24,x25, [x0, #0x0C0]
724   stp    x26,x27, [x0, #0x0D0]
725   stp    x28,x29, [x0, #0x0E0]
726   str    x30,     [x0, #0x0F0]
727   mov    x1,sp
728   str    x1,      [x0, #0x0F8]
729   str    x30,     [x0, #0x100]    // store return address as pc
730   // skip cpsr
731   stp    d0, d1,  [x0, #0x110]
732   stp    d2, d3,  [x0, #0x120]
733   stp    d4, d5,  [x0, #0x130]
734   stp    d6, d7,  [x0, #0x140]
735   stp    d8, d9,  [x0, #0x150]
736   stp    d10,d11, [x0, #0x160]
737   stp    d12,d13, [x0, #0x170]
738   stp    d14,d15, [x0, #0x180]
739   stp    d16,d17, [x0, #0x190]
740   stp    d18,d19, [x0, #0x1A0]
741   stp    d20,d21, [x0, #0x1B0]
742   stp    d22,d23, [x0, #0x1C0]
743   stp    d24,d25, [x0, #0x1D0]
744   stp    d26,d27, [x0, #0x1E0]
745   stp    d28,d29, [x0, #0x1F0]
746   str    d30,     [x0, #0x200]
747   str    d31,     [x0, #0x208]
748   mov    x0, #0                   // return UNW_ESUCCESS
749   ret
750
751 #elif defined(__arm__) && !defined(__APPLE__)
752
753 #if !defined(__ARM_ARCH_ISA_ARM)
754   .thumb
755 #endif
756
757 @
758 @ extern int unw_getcontext(unw_context_t* thread_state)
759 @
760 @ On entry:
761 @  thread_state pointer is in r0
762
763 @ Per EHABI #4.7 this only saves the core integer registers.
764 @ EHABI #7.4.5 notes that in general all VRS registers should be restored
765 @ however this is very hard to do for VFP registers because it is unknown
766 @ to the library how many registers are implemented by the architecture.
767 @ Instead, VFP registers are demand saved by logic external to unw_getcontext.
768 @
769   .p2align 2
770 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
771 #if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1
772   stm r0!, {r0-r7}
773   mov r1, r8
774   mov r2, r9
775   mov r3, r10
776   stm r0!, {r1-r3}
777   mov r1, r11
778   mov r2, sp
779   mov r3, lr
780   str r1, [r0, #0]   @ r11
781   @ r12 does not need storing, it it the intra-procedure-call scratch register
782   str r2, [r0, #8]   @ sp
783   str r3, [r0, #12]  @ lr
784   str r3, [r0, #16]  @ store return address as pc
785   @ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
786   @ It is safe to use here though because we are about to return, and cpsr is
787   @ not expected to be preserved.
788   movs r0, #0        @ return UNW_ESUCCESS
789 #else
790   @ 32bit thumb-2 restrictions for stm:
791   @ . the sp (r13) cannot be in the list
792   @ . the pc (r15) cannot be in the list in an STM instruction
793   stm r0, {r0-r12}
794   str sp, [r0, #52]
795   str lr, [r0, #56]
796   str lr, [r0, #60]  @ store return address as pc
797   mov r0, #0         @ return UNW_ESUCCESS
798 #endif
799   JMP(lr)
800
801 @
802 @ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
803 @
804 @ On entry:
805 @  values pointer is in r0
806 @
807   .p2align 2
808 #if defined(__ELF__)
809   .fpu vfpv3-d16
810 #endif
811 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy)
812   vstmia r0, {d0-d15}
813   JMP(lr)
814
815 @
816 @ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
817 @
818 @ On entry:
819 @  values pointer is in r0
820 @
821   .p2align 2
822 #if defined(__ELF__)
823   .fpu vfpv3-d16
824 #endif
825 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy)
826   vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
827   JMP(lr)
828
829 @
830 @ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
831 @
832 @ On entry:
833 @  values pointer is in r0
834 @
835   .p2align 2
836 #if defined(__ELF__)
837   .fpu vfpv3
838 #endif
839 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy)
840   @ VFP and iwMMX instructions are only available when compiling with the flags
841   @ that enable them. We do not want to do that in the library (because we do not
842   @ want the compiler to generate instructions that access those) but this is
843   @ only accessed if the personality routine needs these registers. Use of
844   @ these registers implies they are, actually, available on the target, so
845   @ it's ok to execute.
846   @ So, generate the instructions using the corresponding coprocessor mnemonic.
847   vstmia r0, {d16-d31}
848   JMP(lr)
849
850 #if defined(_LIBUNWIND_ARM_WMMX)
851
852 @
853 @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
854 @
855 @ On entry:
856 @  values pointer is in r0
857 @
858   .p2align 2
859 #if defined(__ELF__)
860   .arch armv5te
861 #endif
862 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy)
863   stcl p1, cr0, [r0], #8  @ wstrd wR0, [r0], #8
864   stcl p1, cr1, [r0], #8  @ wstrd wR1, [r0], #8
865   stcl p1, cr2, [r0], #8  @ wstrd wR2, [r0], #8
866   stcl p1, cr3, [r0], #8  @ wstrd wR3, [r0], #8
867   stcl p1, cr4, [r0], #8  @ wstrd wR4, [r0], #8
868   stcl p1, cr5, [r0], #8  @ wstrd wR5, [r0], #8
869   stcl p1, cr6, [r0], #8  @ wstrd wR6, [r0], #8
870   stcl p1, cr7, [r0], #8  @ wstrd wR7, [r0], #8
871   stcl p1, cr8, [r0], #8  @ wstrd wR8, [r0], #8
872   stcl p1, cr9, [r0], #8  @ wstrd wR9, [r0], #8
873   stcl p1, cr10, [r0], #8  @ wstrd wR10, [r0], #8
874   stcl p1, cr11, [r0], #8  @ wstrd wR11, [r0], #8
875   stcl p1, cr12, [r0], #8  @ wstrd wR12, [r0], #8
876   stcl p1, cr13, [r0], #8  @ wstrd wR13, [r0], #8
877   stcl p1, cr14, [r0], #8  @ wstrd wR14, [r0], #8
878   stcl p1, cr15, [r0], #8  @ wstrd wR15, [r0], #8
879   JMP(lr)
880
881 @
882 @ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
883 @
884 @ On entry:
885 @  values pointer is in r0
886 @
887   .p2align 2
888 #if defined(__ELF__)
889   .arch armv5te
890 #endif
891 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
892   stc2 p1, cr8, [r0], #4  @ wstrw wCGR0, [r0], #4
893   stc2 p1, cr9, [r0], #4  @ wstrw wCGR1, [r0], #4
894   stc2 p1, cr10, [r0], #4  @ wstrw wCGR2, [r0], #4
895   stc2 p1, cr11, [r0], #4  @ wstrw wCGR3, [r0], #4
896   JMP(lr)
897
898 #endif
899
900 #elif defined(__or1k__)
901
902 #
903 # extern int unw_getcontext(unw_context_t* thread_state)
904 #
905 # On entry:
906 #  thread_state pointer is in r3
907 #
908 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
909   l.sw       0(r3), r0
910   l.sw       4(r3), r1
911   l.sw       8(r3), r2
912   l.sw      12(r3), r3
913   l.sw      16(r3), r4
914   l.sw      20(r3), r5
915   l.sw      24(r3), r6
916   l.sw      28(r3), r7
917   l.sw      32(r3), r8
918   l.sw      36(r3), r9
919   l.sw      40(r3), r10
920   l.sw      44(r3), r11
921   l.sw      48(r3), r12
922   l.sw      52(r3), r13
923   l.sw      56(r3), r14
924   l.sw      60(r3), r15
925   l.sw      64(r3), r16
926   l.sw      68(r3), r17
927   l.sw      72(r3), r18
928   l.sw      76(r3), r19
929   l.sw      80(r3), r20
930   l.sw      84(r3), r21
931   l.sw      88(r3), r22
932   l.sw      92(r3), r23
933   l.sw      96(r3), r24
934   l.sw     100(r3), r25
935   l.sw     104(r3), r26
936   l.sw     108(r3), r27
937   l.sw     112(r3), r28
938   l.sw     116(r3), r29
939   l.sw     120(r3), r30
940   l.sw     124(r3), r31
941   # store ra to pc
942   l.sw     128(r3), r9
943   # zero epcr
944   l.sw     132(r3), r0
945
946 #elif defined(__riscv)
947
948 #
949 # extern int unw_getcontext(unw_context_t* thread_state)
950 #
951 # On entry:
952 #  thread_state pointer is in a0
953 #
954 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
955   // x0 is zero
956   sd    x1, (8 * 1)(a0)
957   sd    x2, (8 * 2)(a0)
958   sd    x3, (8 * 3)(a0)
959   sd    x4, (8 * 4)(a0)
960   sd    x5, (8 * 5)(a0)
961   sd    x6, (8 * 6)(a0)
962   sd    x7, (8 * 7)(a0)
963   sd    x8, (8 * 8)(a0)
964   sd    x9, (8 * 9)(a0)
965   sd    x10, (8 * 10)(a0)
966   sd    x11, (8 * 11)(a0)
967   sd    x12, (8 * 12)(a0)
968   sd    x13, (8 * 13)(a0)
969   sd    x14, (8 * 14)(a0)
970   sd    x15, (8 * 15)(a0)
971   sd    x16, (8 * 16)(a0)
972   sd    x17, (8 * 17)(a0)
973   sd    x18, (8 * 18)(a0)
974   sd    x19, (8 * 19)(a0)
975   sd    x20, (8 * 20)(a0)
976   sd    x21, (8 * 21)(a0)
977   sd    x22, (8 * 22)(a0)
978   sd    x23, (8 * 23)(a0)
979   sd    x24, (8 * 24)(a0)
980   sd    x25, (8 * 25)(a0)
981   sd    x26, (8 * 26)(a0)
982   sd    x27, (8 * 27)(a0)
983   sd    x28, (8 * 28)(a0)
984   sd    x29, (8 * 29)(a0)
985   sd    x30, (8 * 30)(a0)
986   sd    x31, (8 * 31)(a0)
987
988 #ifdef __riscv_float_abi_double
989   fsd    f0, (8 * 32 + 8 * 0)(a0)
990   fsd    f1, (8 * 32 + 8 * 1)(a0)
991   fsd    f2, (8 * 32 + 8 * 2)(a0)
992   fsd    f3, (8 * 32 + 8 * 3)(a0)
993   fsd    f4, (8 * 32 + 8 * 4)(a0)
994   fsd    f5, (8 * 32 + 8 * 5)(a0)
995   fsd    f6, (8 * 32 + 8 * 6)(a0)
996   fsd    f7, (8 * 32 + 8 * 7)(a0)
997   fsd    f8, (8 * 32 + 8 * 8)(a0)
998   fsd    f9, (8 * 32 + 8 * 9)(a0)
999   fsd    f10, (8 * 32 + 8 * 10)(a0)
1000   fsd    f11, (8 * 32 + 8 * 11)(a0)
1001   fsd    f12, (8 * 32 + 8 * 12)(a0)
1002   fsd    f13, (8 * 32 + 8 * 13)(a0)
1003   fsd    f14, (8 * 32 + 8 * 14)(a0)
1004   fsd    f15, (8 * 32 + 8 * 15)(a0)
1005   fsd    f16, (8 * 32 + 8 * 16)(a0)
1006   fsd    f17, (8 * 32 + 8 * 17)(a0)
1007   fsd    f18, (8 * 32 + 8 * 18)(a0)
1008   fsd    f19, (8 * 32 + 8 * 19)(a0)
1009   fsd    f20, (8 * 32 + 8 * 20)(a0)
1010   fsd    f21, (8 * 32 + 8 * 21)(a0)
1011   fsd    f22, (8 * 32 + 8 * 22)(a0)
1012   fsd    f23, (8 * 32 + 8 * 23)(a0)
1013   fsd    f24, (8 * 32 + 8 * 24)(a0)
1014   fsd    f25, (8 * 32 + 8 * 25)(a0)
1015   fsd    f26, (8 * 32 + 8 * 26)(a0)
1016   fsd    f27, (8 * 32 + 8 * 27)(a0)
1017   fsd    f28, (8 * 32 + 8 * 28)(a0)
1018   fsd    f29, (8 * 32 + 8 * 29)(a0)
1019   fsd    f30, (8 * 32 + 8 * 30)(a0)
1020   fsd    f31, (8 * 32 + 8 * 31)(a0)
1021 #endif
1022
1023   li     a0, 0  // return UNW_ESUCCESS
1024   ret           // jump to ra
1025
1026 #elif defined(__sparc__)
1027
1028 #
1029 # extern int unw_getcontext(unw_context_t* thread_state)
1030 #
1031 # On entry:
1032 #  thread_state pointer is in o0
1033 #
1034 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
1035   ta 3
1036   add %o7, 8, %o7
1037   std %g0, [%o0 +   0]
1038   std %g2, [%o0 +   8]
1039   std %g4, [%o0 +  16]
1040   std %g6, [%o0 +  24]
1041   std %o0, [%o0 +  32]
1042   std %o2, [%o0 +  40]
1043   std %o4, [%o0 +  48]
1044   std %o6, [%o0 +  56]
1045   std %l0, [%o0 +  64]
1046   std %l2, [%o0 +  72]
1047   std %l4, [%o0 +  80]
1048   std %l6, [%o0 +  88]
1049   std %i0, [%o0 +  96]
1050   std %i2, [%o0 + 104]
1051   std %i4, [%o0 + 112]
1052   std %i6, [%o0 + 120]
1053   jmp %o7
1054    clr %o0                   // return UNW_ESUCCESS
1055 #endif
1056 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
1057
1058 NO_EXEC_STACK_DIRECTIVE