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#
30DEFINE_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#
65DEFINE_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#
127DEFINE_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#
236DEFINE_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.
324DEFINE_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//
335DEFINE_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//
566DEFINE_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          SEPARATOR \
655  lwz     %r5, 0(%r4)           SEPARATOR \
656  stw     %r5, _offset(%r3)     SEPARATOR \
657  lwz     %r5, 4(%r4)           SEPARATOR \
658  stw     %r5, _offset+4(%r3)   SEPARATOR \
659  lwz     %r5, 8(%r4)           SEPARATOR \
660  stw     %r5, _offset+8(%r3)   SEPARATOR \
661  lwz     %r5, 12(%r4)          SEPARATOR \
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
710DEFINE_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
770DEFINE_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
811DEFINE_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
825DEFINE_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
839DEFINE_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
862DEFINE_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
891DEFINE_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#
908DEFINE_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#
954DEFINE_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#
1034DEFINE_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
1058NO_EXEC_STACK_DIRECTIVE
1059