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