UnwindRegistersSave.S revision 360784
1100966Siwasaki//===------------------------ UnwindRegistersSave.S -----------------------===//
2100966Siwasaki//
3100966Siwasaki// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4100966Siwasaki// See https://llvm.org/LICENSE.txt for license information.
5167802Sjkim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6100966Siwasaki//
7100966Siwasaki//===----------------------------------------------------------------------===//
8100966Siwasaki
9100966Siwasaki#include "assembly.h"
10100966Siwasaki
11100966Siwasaki    .text
12100966Siwasaki
13167802Sjkim#if !defined(__USING_SJLJ_EXCEPTIONS__)
14100966Siwasaki
15100966Siwasaki#if defined(__i386__)
16100966Siwasaki
17100966Siwasaki#
18100966Siwasaki# extern int __unw_getcontext(unw_context_t* thread_state)
19100966Siwasaki#
20100966Siwasaki# On entry:
21100966Siwasaki#   +                       +
22100966Siwasaki#   +-----------------------+
23100966Siwasaki#   + thread_state pointer  +
24100966Siwasaki#   +-----------------------+
25100966Siwasaki#   + return address        +
26100966Siwasaki#   +-----------------------+   <-- SP
27100966Siwasaki#   +                       +
28100966Siwasaki#
29100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
30100966Siwasaki  push  %eax
31100966Siwasaki  movl  8(%esp), %eax
32100966Siwasaki  movl  %ebx,  4(%eax)
33100966Siwasaki  movl  %ecx,  8(%eax)
34100966Siwasaki  movl  %edx, 12(%eax)
35100966Siwasaki  movl  %edi, 16(%eax)
36100966Siwasaki  movl  %esi, 20(%eax)
37100966Siwasaki  movl  %ebp, 24(%eax)
38100966Siwasaki  movl  %esp, %edx
39100966Siwasaki  addl  $8, %edx
40100966Siwasaki  movl  %edx, 28(%eax)  # store what sp was at call site as esp
41100966Siwasaki  # skip ss
42100966Siwasaki  # skip eflags
43100966Siwasaki  movl  4(%esp), %edx
44100966Siwasaki  movl  %edx, 40(%eax)  # store return address as eip
45100966Siwasaki  # skip cs
46100966Siwasaki  # skip ds
47100966Siwasaki  # skip es
48100966Siwasaki  # skip fs
49100966Siwasaki  # skip gs
50100966Siwasaki  movl  (%esp), %edx
51100966Siwasaki  movl  %edx, (%eax)  # store original eax
52100966Siwasaki  popl  %eax
53100966Siwasaki  xorl  %eax, %eax    # return UNW_ESUCCESS
54100966Siwasaki  ret
55100966Siwasaki
56100966Siwasaki#elif defined(__x86_64__)
57100966Siwasaki
58100966Siwasaki#
59100966Siwasaki# extern int __unw_getcontext(unw_context_t* thread_state)
60100966Siwasaki#
61100966Siwasaki# On entry:
62100966Siwasaki#  thread_state pointer is in rdi
63100966Siwasaki#
64100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
65100966Siwasaki#if defined(_WIN64)
66100966Siwasaki#define PTR %rcx
67100966Siwasaki#define TMP %rdx
68100966Siwasaki#else
69100966Siwasaki#define PTR %rdi
70100966Siwasaki#define TMP %rsi
71100966Siwasaki#endif
72100966Siwasaki
73100966Siwasaki  movq  %rax,   (PTR)
74100966Siwasaki  movq  %rbx,  8(PTR)
75100966Siwasaki  movq  %rcx, 16(PTR)
76100966Siwasaki  movq  %rdx, 24(PTR)
77100966Siwasaki  movq  %rdi, 32(PTR)
78100966Siwasaki  movq  %rsi, 40(PTR)
79100966Siwasaki  movq  %rbp, 48(PTR)
80100966Siwasaki  movq  %rsp, 56(PTR)
81100966Siwasaki  addq  $8,   56(PTR)
82100966Siwasaki  movq  %r8,  64(PTR)
83100966Siwasaki  movq  %r9,  72(PTR)
84100966Siwasaki  movq  %r10, 80(PTR)
85100966Siwasaki  movq  %r11, 88(PTR)
86100966Siwasaki  movq  %r12, 96(PTR)
87100966Siwasaki  movq  %r13,104(PTR)
88100966Siwasaki  movq  %r14,112(PTR)
89100966Siwasaki  movq  %r15,120(PTR)
90100966Siwasaki  movq  (%rsp),TMP
91100966Siwasaki  movq  TMP,128(PTR) # store return address as rip
92100966Siwasaki  # skip rflags
93100966Siwasaki  # skip cs
94100966Siwasaki  # skip fs
95100966Siwasaki  # skip gs
96100966Siwasaki
97100966Siwasaki#if defined(_WIN64)
98100966Siwasaki  movdqu %xmm0,176(PTR)
99100966Siwasaki  movdqu %xmm1,192(PTR)
100100966Siwasaki  movdqu %xmm2,208(PTR)
101100966Siwasaki  movdqu %xmm3,224(PTR)
102100966Siwasaki  movdqu %xmm4,240(PTR)
103100966Siwasaki  movdqu %xmm5,256(PTR)
104100966Siwasaki  movdqu %xmm6,272(PTR)
105100966Siwasaki  movdqu %xmm7,288(PTR)
106100966Siwasaki  movdqu %xmm8,304(PTR)
107100966Siwasaki  movdqu %xmm9,320(PTR)
108100966Siwasaki  movdqu %xmm10,336(PTR)
109100966Siwasaki  movdqu %xmm11,352(PTR)
110100966Siwasaki  movdqu %xmm12,368(PTR)
111100966Siwasaki  movdqu %xmm13,384(PTR)
112100966Siwasaki  movdqu %xmm14,400(PTR)
113100966Siwasaki  movdqu %xmm15,416(PTR)
114100966Siwasaki#endif
115100966Siwasaki  xorl  %eax, %eax    # return UNW_ESUCCESS
116100966Siwasaki  ret
117100966Siwasaki
118100966Siwasaki#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
119100966Siwasaki
120100966Siwasaki#
121151600Sobrien# extern int __unw_getcontext(unw_context_t* thread_state)
122151600Sobrien#
123151600Sobrien# On entry:
124100966Siwasaki#  thread_state pointer is in a0 ($4)
125100966Siwasaki#
126100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
127100966Siwasaki  .set push
128100966Siwasaki  .set noat
129100966Siwasaki  .set noreorder
130100966Siwasaki  .set nomacro
131100966Siwasaki  sw    $1, (4 * 1)($4)
132100966Siwasaki  sw    $2, (4 * 2)($4)
133100966Siwasaki  sw    $3, (4 * 3)($4)
134100966Siwasaki  sw    $4, (4 * 4)($4)
135151937Sjkim  sw    $5, (4 * 5)($4)
136151937Sjkim  sw    $6, (4 * 6)($4)
137100966Siwasaki  sw    $7, (4 * 7)($4)
138100966Siwasaki  sw    $8, (4 * 8)($4)
139151937Sjkim  sw    $9, (4 * 9)($4)
140100966Siwasaki  sw    $10, (4 * 10)($4)
141100966Siwasaki  sw    $11, (4 * 11)($4)
142100966Siwasaki  sw    $12, (4 * 12)($4)
143100966Siwasaki  sw    $13, (4 * 13)($4)
144100966Siwasaki  sw    $14, (4 * 14)($4)
145100966Siwasaki  sw    $15, (4 * 15)($4)
146100966Siwasaki  sw    $16, (4 * 16)($4)
147100966Siwasaki  sw    $17, (4 * 17)($4)
148100966Siwasaki  sw    $18, (4 * 18)($4)
149100966Siwasaki  sw    $19, (4 * 19)($4)
150100966Siwasaki  sw    $20, (4 * 20)($4)
151100966Siwasaki  sw    $21, (4 * 21)($4)
152100966Siwasaki  sw    $22, (4 * 22)($4)
153100966Siwasaki  sw    $23, (4 * 23)($4)
154100966Siwasaki  sw    $24, (4 * 24)($4)
155100966Siwasaki  sw    $25, (4 * 25)($4)
156100966Siwasaki  sw    $26, (4 * 26)($4)
157100966Siwasaki  sw    $27, (4 * 27)($4)
158100966Siwasaki  sw    $28, (4 * 28)($4)
159100966Siwasaki  sw    $29, (4 * 29)($4)
160100966Siwasaki  sw    $30, (4 * 30)($4)
161100966Siwasaki  sw    $31, (4 * 31)($4)
162100966Siwasaki  # Store return address to pc
163167802Sjkim  sw    $31, (4 * 32)($4)
164100966Siwasaki  # hi and lo
165100966Siwasaki  mfhi  $8
166100966Siwasaki  sw    $8,  (4 * 33)($4)
167100966Siwasaki  mflo  $8
168100966Siwasaki  sw    $8,  (4 * 34)($4)
169100966Siwasaki#ifdef __mips_hard_float
170100966Siwasaki#if __mips_fpr != 64
171100966Siwasaki  sdc1  $f0, (4 * 36 + 8 * 0)($4)
172100966Siwasaki  sdc1  $f2, (4 * 36 + 8 * 2)($4)
173100966Siwasaki  sdc1  $f4, (4 * 36 + 8 * 4)($4)
174100966Siwasaki  sdc1  $f6, (4 * 36 + 8 * 6)($4)
175100966Siwasaki  sdc1  $f8, (4 * 36 + 8 * 8)($4)
176100966Siwasaki  sdc1  $f10, (4 * 36 + 8 * 10)($4)
177100966Siwasaki  sdc1  $f12, (4 * 36 + 8 * 12)($4)
178100966Siwasaki  sdc1  $f14, (4 * 36 + 8 * 14)($4)
179100966Siwasaki  sdc1  $f16, (4 * 36 + 8 * 16)($4)
180100966Siwasaki  sdc1  $f18, (4 * 36 + 8 * 18)($4)
181100966Siwasaki  sdc1  $f20, (4 * 36 + 8 * 20)($4)
182100966Siwasaki  sdc1  $f22, (4 * 36 + 8 * 22)($4)
183100966Siwasaki  sdc1  $f24, (4 * 36 + 8 * 24)($4)
184100966Siwasaki  sdc1  $f26, (4 * 36 + 8 * 26)($4)
185100966Siwasaki  sdc1  $f28, (4 * 36 + 8 * 28)($4)
186100966Siwasaki  sdc1  $f30, (4 * 36 + 8 * 30)($4)
187100966Siwasaki#else
188100966Siwasaki  sdc1  $f0, (4 * 36 + 8 * 0)($4)
189100966Siwasaki  sdc1  $f1, (4 * 36 + 8 * 1)($4)
190100966Siwasaki  sdc1  $f2, (4 * 36 + 8 * 2)($4)
191100966Siwasaki  sdc1  $f3, (4 * 36 + 8 * 3)($4)
192100966Siwasaki  sdc1  $f4, (4 * 36 + 8 * 4)($4)
193100966Siwasaki  sdc1  $f5, (4 * 36 + 8 * 5)($4)
194100966Siwasaki  sdc1  $f6, (4 * 36 + 8 * 6)($4)
195100966Siwasaki  sdc1  $f7, (4 * 36 + 8 * 7)($4)
196100966Siwasaki  sdc1  $f8, (4 * 36 + 8 * 8)($4)
197167802Sjkim  sdc1  $f9, (4 * 36 + 8 * 9)($4)
198100966Siwasaki  sdc1  $f10, (4 * 36 + 8 * 10)($4)
199100966Siwasaki  sdc1  $f11, (4 * 36 + 8 * 11)($4)
200100966Siwasaki  sdc1  $f12, (4 * 36 + 8 * 12)($4)
201100966Siwasaki  sdc1  $f13, (4 * 36 + 8 * 13)($4)
202100966Siwasaki  sdc1  $f14, (4 * 36 + 8 * 14)($4)
203100966Siwasaki  sdc1  $f15, (4 * 36 + 8 * 15)($4)
204100966Siwasaki  sdc1  $f16, (4 * 36 + 8 * 16)($4)
205100966Siwasaki  sdc1  $f17, (4 * 36 + 8 * 17)($4)
206100966Siwasaki  sdc1  $f18, (4 * 36 + 8 * 18)($4)
207100966Siwasaki  sdc1  $f19, (4 * 36 + 8 * 19)($4)
208100966Siwasaki  sdc1  $f20, (4 * 36 + 8 * 20)($4)
209100966Siwasaki  sdc1  $f21, (4 * 36 + 8 * 21)($4)
210167802Sjkim  sdc1  $f22, (4 * 36 + 8 * 22)($4)
211167802Sjkim  sdc1  $f23, (4 * 36 + 8 * 23)($4)
212100966Siwasaki  sdc1  $f24, (4 * 36 + 8 * 24)($4)
213100966Siwasaki  sdc1  $f25, (4 * 36 + 8 * 25)($4)
214100966Siwasaki  sdc1  $f26, (4 * 36 + 8 * 26)($4)
215100966Siwasaki  sdc1  $f27, (4 * 36 + 8 * 27)($4)
216100966Siwasaki  sdc1  $f28, (4 * 36 + 8 * 28)($4)
217100966Siwasaki  sdc1  $f29, (4 * 36 + 8 * 29)($4)
218100966Siwasaki  sdc1  $f30, (4 * 36 + 8 * 30)($4)
219100966Siwasaki  sdc1  $f31, (4 * 36 + 8 * 31)($4)
220100966Siwasaki#endif
221100966Siwasaki#endif
222100966Siwasaki  jr	$31
223100966Siwasaki  # return UNW_ESUCCESS
224100966Siwasaki  or    $2, $0, $0
225100966Siwasaki  .set pop
226100966Siwasaki
227167802Sjkim#elif defined(__mips64)
228100966Siwasaki
229167802Sjkim#
230100966Siwasaki# extern int __unw_getcontext(unw_context_t* thread_state)
231100966Siwasaki#
232100966Siwasaki# On entry:
233100966Siwasaki#  thread_state pointer is in a0 ($4)
234100966Siwasaki#
235128212SnjlDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
236128212Snjl  .set push
237100966Siwasaki  .set noat
238100966Siwasaki  .set noreorder
239128212Snjl  .set nomacro
240100966Siwasaki  sd    $1, (8 * 1)($4)
241100966Siwasaki  sd    $2, (8 * 2)($4)
242100966Siwasaki  sd    $3, (8 * 3)($4)
243100966Siwasaki  sd    $4, (8 * 4)($4)
244100966Siwasaki  sd    $5, (8 * 5)($4)
245100966Siwasaki  sd    $6, (8 * 6)($4)
246100966Siwasaki  sd    $7, (8 * 7)($4)
247100966Siwasaki  sd    $8, (8 * 8)($4)
248100966Siwasaki  sd    $9, (8 * 9)($4)
249100966Siwasaki  sd    $10, (8 * 10)($4)
250100966Siwasaki  sd    $11, (8 * 11)($4)
251100966Siwasaki  sd    $12, (8 * 12)($4)
252100966Siwasaki  sd    $13, (8 * 13)($4)
253100966Siwasaki  sd    $14, (8 * 14)($4)
254100966Siwasaki  sd    $15, (8 * 15)($4)
255100966Siwasaki  sd    $16, (8 * 16)($4)
256100966Siwasaki  sd    $17, (8 * 17)($4)
257100966Siwasaki  sd    $18, (8 * 18)($4)
258167802Sjkim  sd    $19, (8 * 19)($4)
259100966Siwasaki  sd    $20, (8 * 20)($4)
260100966Siwasaki  sd    $21, (8 * 21)($4)
261100966Siwasaki  sd    $22, (8 * 22)($4)
262100966Siwasaki  sd    $23, (8 * 23)($4)
263167802Sjkim  sd    $24, (8 * 24)($4)
264100966Siwasaki  sd    $25, (8 * 25)($4)
265100966Siwasaki  sd    $26, (8 * 26)($4)
266167802Sjkim  sd    $27, (8 * 27)($4)
267129684Snjl  sd    $28, (8 * 28)($4)
268167802Sjkim  sd    $29, (8 * 29)($4)
269167802Sjkim  sd    $30, (8 * 30)($4)
270167802Sjkim  sd    $31, (8 * 31)($4)
271167802Sjkim  # Store return address to pc
272167802Sjkim  sd    $31, (8 * 32)($4)
273167802Sjkim  # hi and lo
274167802Sjkim  mfhi  $8
275167802Sjkim  sd    $8,  (8 * 33)($4)
276167802Sjkim  mflo  $8
277167802Sjkim  sd    $8,  (8 * 34)($4)
278167802Sjkim#ifdef __mips_hard_float
279167802Sjkim  sdc1  $f0, (8 * 35)($4)
280167802Sjkim  sdc1  $f1, (8 * 36)($4)
281167802Sjkim  sdc1  $f2, (8 * 37)($4)
282167802Sjkim  sdc1  $f3, (8 * 38)($4)
283167802Sjkim  sdc1  $f4, (8 * 39)($4)
284167802Sjkim  sdc1  $f5, (8 * 40)($4)
285167802Sjkim  sdc1  $f6, (8 * 41)($4)
286100966Siwasaki  sdc1  $f7, (8 * 42)($4)
287167802Sjkim  sdc1  $f8, (8 * 43)($4)
288167802Sjkim  sdc1  $f9, (8 * 44)($4)
289100966Siwasaki  sdc1  $f10, (8 * 45)($4)
290100966Siwasaki  sdc1  $f11, (8 * 46)($4)
291100966Siwasaki  sdc1  $f12, (8 * 47)($4)
292100966Siwasaki  sdc1  $f13, (8 * 48)($4)
293100966Siwasaki  sdc1  $f14, (8 * 49)($4)
294100966Siwasaki  sdc1  $f15, (8 * 50)($4)
295100966Siwasaki  sdc1  $f16, (8 * 51)($4)
296167802Sjkim  sdc1  $f17, (8 * 52)($4)
297167802Sjkim  sdc1  $f18, (8 * 53)($4)
298167802Sjkim  sdc1  $f19, (8 * 54)($4)
299100966Siwasaki  sdc1  $f20, (8 * 55)($4)
300167802Sjkim  sdc1  $f21, (8 * 56)($4)
301167802Sjkim  sdc1  $f22, (8 * 57)($4)
302100966Siwasaki  sdc1  $f23, (8 * 58)($4)
303100966Siwasaki  sdc1  $f24, (8 * 59)($4)
304167802Sjkim  sdc1  $f25, (8 * 60)($4)
305167802Sjkim  sdc1  $f26, (8 * 61)($4)
306100966Siwasaki  sdc1  $f27, (8 * 62)($4)
307100966Siwasaki  sdc1  $f28, (8 * 63)($4)
308167802Sjkim  sdc1  $f29, (8 * 64)($4)
309167802Sjkim  sdc1  $f30, (8 * 65)($4)
310100966Siwasaki  sdc1  $f31, (8 * 66)($4)
311100966Siwasaki#endif
312167802Sjkim  jr	$31
313100966Siwasaki  # return UNW_ESUCCESS
314100966Siwasaki  or    $2, $0, $0
315167802Sjkim  .set pop
316100966Siwasaki
317100966Siwasaki# elif defined(__mips__)
318100966Siwasaki
319100966Siwasaki#
320100966Siwasaki# extern int __unw_getcontext(unw_context_t* thread_state)
321100966Siwasaki#
322100966Siwasaki# Just trap for the time being.
323100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
324100966Siwasaki  teq $0, $0
325100966Siwasaki
326100966Siwasaki#elif defined(__powerpc64__)
327167802Sjkim
328167802Sjkim//
329167802Sjkim// extern int __unw_getcontext(unw_context_t* thread_state)
330167802Sjkim//
331100966Siwasaki// On entry:
332100966Siwasaki//  thread_state pointer is in r3
333100966Siwasaki//
334100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
335167802Sjkim
336167802Sjkim// store register (GPR)
337167802Sjkim#define PPC64_STR(n) \
338100966Siwasaki  std   %r##n, (8 * (n + 2))(%r3)
339100966Siwasaki
340100966Siwasaki  // save GPRs
341167802Sjkim  PPC64_STR(0)
342167802Sjkim  mflr  %r0
343100966Siwasaki  std   %r0, PPC64_OFFS_SRR0(%r3) // store lr as ssr0
344100966Siwasaki  PPC64_STR(1)
345100966Siwasaki  PPC64_STR(2)
346167802Sjkim  PPC64_STR(3)
347167802Sjkim  PPC64_STR(4)
348100966Siwasaki  PPC64_STR(5)
349100966Siwasaki  PPC64_STR(6)
350100966Siwasaki  PPC64_STR(7)
351100966Siwasaki  PPC64_STR(8)
352100966Siwasaki  PPC64_STR(9)
353100966Siwasaki  PPC64_STR(10)
354167802Sjkim  PPC64_STR(11)
355167802Sjkim  PPC64_STR(12)
356167802Sjkim  PPC64_STR(13)
357100966Siwasaki  PPC64_STR(14)
358100966Siwasaki  PPC64_STR(15)
359100966Siwasaki  PPC64_STR(16)
360100966Siwasaki  PPC64_STR(17)
361100966Siwasaki  PPC64_STR(18)
362100966Siwasaki  PPC64_STR(19)
363100966Siwasaki  PPC64_STR(20)
364100966Siwasaki  PPC64_STR(21)
365167802Sjkim  PPC64_STR(22)
366100966Siwasaki  PPC64_STR(23)
367100966Siwasaki  PPC64_STR(24)
368100966Siwasaki  PPC64_STR(25)
369100966Siwasaki  PPC64_STR(26)
370100966Siwasaki  PPC64_STR(27)
371167802Sjkim  PPC64_STR(28)
372167802Sjkim  PPC64_STR(29)
373100966Siwasaki  PPC64_STR(30)
374100966Siwasaki  PPC64_STR(31)
375100966Siwasaki
376100966Siwasaki  mfcr  %r0
377100966Siwasaki  std   %r0,  PPC64_OFFS_CR(%r3)
378100966Siwasaki  mfxer %r0
379100966Siwasaki  std   %r0,  PPC64_OFFS_XER(%r3)
380100966Siwasaki  mflr  %r0
381100966Siwasaki  std   %r0,  PPC64_OFFS_LR(%r3)
382100966Siwasaki  mfctr %r0
383167802Sjkim  std   %r0,  PPC64_OFFS_CTR(%r3)
384100966Siwasaki  mfvrsave    %r0
385100966Siwasaki  std   %r0,  PPC64_OFFS_VRSAVE(%r3)
386100966Siwasaki
387100966Siwasaki#ifdef PPC64_HAS_VMX
388100966Siwasaki  // save VS registers
389167802Sjkim  // (note that this also saves floating point registers and V registers,
390167802Sjkim  // because part of VS is mapped to these registers)
391167802Sjkim
392167802Sjkim  addi  %r4, %r3, PPC64_OFFS_FP
393100966Siwasaki
394100966Siwasaki// store VS register
395100966Siwasaki#define PPC64_STVS(n)      \
396100966Siwasaki  stxvd2x %vs##n, 0, %r4  ;\
397151937Sjkim  addi    %r4, %r4, 16
398167802Sjkim
399100966Siwasaki  PPC64_STVS(0)
400100966Siwasaki  PPC64_STVS(1)
401100966Siwasaki  PPC64_STVS(2)
402167802Sjkim  PPC64_STVS(3)
403167802Sjkim  PPC64_STVS(4)
404100966Siwasaki  PPC64_STVS(5)
405100966Siwasaki  PPC64_STVS(6)
406100966Siwasaki  PPC64_STVS(7)
407129684Snjl  PPC64_STVS(8)
408129684Snjl  PPC64_STVS(9)
409100966Siwasaki  PPC64_STVS(10)
410100966Siwasaki  PPC64_STVS(11)
411100966Siwasaki  PPC64_STVS(12)
412167802Sjkim  PPC64_STVS(13)
413167802Sjkim  PPC64_STVS(14)
414167802Sjkim  PPC64_STVS(15)
415167802Sjkim  PPC64_STVS(16)
416100966Siwasaki  PPC64_STVS(17)
417100966Siwasaki  PPC64_STVS(18)
418100966Siwasaki  PPC64_STVS(19)
419100966Siwasaki  PPC64_STVS(20)
420100966Siwasaki  PPC64_STVS(21)
421100966Siwasaki  PPC64_STVS(22)
422167802Sjkim  PPC64_STVS(23)
423100966Siwasaki  PPC64_STVS(24)
424129684Snjl  PPC64_STVS(25)
425167802Sjkim  PPC64_STVS(26)
426167802Sjkim  PPC64_STVS(27)
427100966Siwasaki  PPC64_STVS(28)
428167802Sjkim  PPC64_STVS(29)
429167802Sjkim  PPC64_STVS(30)
430167802Sjkim  PPC64_STVS(31)
431167802Sjkim  PPC64_STVS(32)
432167802Sjkim  PPC64_STVS(33)
433167802Sjkim  PPC64_STVS(34)
434100966Siwasaki  PPC64_STVS(35)
435100966Siwasaki  PPC64_STVS(36)
436167802Sjkim  PPC64_STVS(37)
437167802Sjkim  PPC64_STVS(38)
438167802Sjkim  PPC64_STVS(39)
439167802Sjkim  PPC64_STVS(40)
440167802Sjkim  PPC64_STVS(41)
441167802Sjkim  PPC64_STVS(42)
442100966Siwasaki  PPC64_STVS(43)
443100966Siwasaki  PPC64_STVS(44)
444100966Siwasaki  PPC64_STVS(45)
445167802Sjkim  PPC64_STVS(46)
446100966Siwasaki  PPC64_STVS(47)
447100966Siwasaki  PPC64_STVS(48)
448167802Sjkim  PPC64_STVS(49)
449100966Siwasaki  PPC64_STVS(50)
450100966Siwasaki  PPC64_STVS(51)
451100966Siwasaki  PPC64_STVS(52)
452167802Sjkim  PPC64_STVS(53)
453100966Siwasaki  PPC64_STVS(54)
454167802Sjkim  PPC64_STVS(55)
455100966Siwasaki  PPC64_STVS(56)
456100966Siwasaki  PPC64_STVS(57)
457100966Siwasaki  PPC64_STVS(58)
458100966Siwasaki  PPC64_STVS(59)
459100966Siwasaki  PPC64_STVS(60)
460100966Siwasaki  PPC64_STVS(61)
461100966Siwasaki  PPC64_STVS(62)
462100966Siwasaki  PPC64_STVS(63)
463100966Siwasaki
464100966Siwasaki#else
465100966Siwasaki
466100966Siwasaki// store FP register
467100966Siwasaki#define PPC64_STF(n) \
468100966Siwasaki  stfd  %f##n, (PPC64_OFFS_FP + n * 16)(%r3)
469100966Siwasaki
470100966Siwasaki  // save float registers
471100966Siwasaki  PPC64_STF(0)
472100966Siwasaki  PPC64_STF(1)
473100966Siwasaki  PPC64_STF(2)
474100966Siwasaki  PPC64_STF(3)
475100966Siwasaki  PPC64_STF(4)
476100966Siwasaki  PPC64_STF(5)
477100966Siwasaki  PPC64_STF(6)
478100966Siwasaki  PPC64_STF(7)
479100966Siwasaki  PPC64_STF(8)
480100966Siwasaki  PPC64_STF(9)
481100966Siwasaki  PPC64_STF(10)
482100966Siwasaki  PPC64_STF(11)
483100966Siwasaki  PPC64_STF(12)
484100966Siwasaki  PPC64_STF(13)
485100966Siwasaki  PPC64_STF(14)
486100966Siwasaki  PPC64_STF(15)
487100966Siwasaki  PPC64_STF(16)
488100966Siwasaki  PPC64_STF(17)
489100966Siwasaki  PPC64_STF(18)
490100966Siwasaki  PPC64_STF(19)
491100966Siwasaki  PPC64_STF(20)
492100966Siwasaki  PPC64_STF(21)
493100966Siwasaki  PPC64_STF(22)
494100966Siwasaki  PPC64_STF(23)
495100966Siwasaki  PPC64_STF(24)
496100966Siwasaki  PPC64_STF(25)
497167802Sjkim  PPC64_STF(26)
498100966Siwasaki  PPC64_STF(27)
499100966Siwasaki  PPC64_STF(28)
500100966Siwasaki  PPC64_STF(29)
501100966Siwasaki  PPC64_STF(30)
502167802Sjkim  PPC64_STF(31)
503167802Sjkim
504100966Siwasaki  // save vector registers
505100966Siwasaki
506100966Siwasaki  // Use 16-bytes below the stack pointer as an
507100966Siwasaki  // aligned buffer to save each vector register.
508100966Siwasaki  // Note that the stack pointer is always 16-byte aligned.
509100966Siwasaki  subi  %r4, %r1, 16
510100966Siwasaki
511100966Siwasaki#define PPC64_STV_UNALIGNED(n)                 \
512100966Siwasaki  stvx  %v##n, 0, %r4                         ;\
513100966Siwasaki  ld    %r5, 0(%r4)                           ;\
514100966Siwasaki  std   %r5, (PPC64_OFFS_V + n * 16)(%r3)     ;\
515100966Siwasaki  ld    %r5, 8(%r4)                           ;\
516100966Siwasaki  std   %r5, (PPC64_OFFS_V + n * 16 + 8)(%r3)
517100966Siwasaki
518100966Siwasaki  PPC64_STV_UNALIGNED(0)
519100966Siwasaki  PPC64_STV_UNALIGNED(1)
520100966Siwasaki  PPC64_STV_UNALIGNED(2)
521151937Sjkim  PPC64_STV_UNALIGNED(3)
522151937Sjkim  PPC64_STV_UNALIGNED(4)
523100966Siwasaki  PPC64_STV_UNALIGNED(5)
524100966Siwasaki  PPC64_STV_UNALIGNED(6)
525100966Siwasaki  PPC64_STV_UNALIGNED(7)
526100966Siwasaki  PPC64_STV_UNALIGNED(8)
527100966Siwasaki  PPC64_STV_UNALIGNED(9)
528100966Siwasaki  PPC64_STV_UNALIGNED(10)
529167802Sjkim  PPC64_STV_UNALIGNED(11)
530100966Siwasaki  PPC64_STV_UNALIGNED(12)
531167802Sjkim  PPC64_STV_UNALIGNED(13)
532100966Siwasaki  PPC64_STV_UNALIGNED(14)
533100966Siwasaki  PPC64_STV_UNALIGNED(15)
534100966Siwasaki  PPC64_STV_UNALIGNED(16)
535100966Siwasaki  PPC64_STV_UNALIGNED(17)
536100966Siwasaki  PPC64_STV_UNALIGNED(18)
537100966Siwasaki  PPC64_STV_UNALIGNED(19)
538100966Siwasaki  PPC64_STV_UNALIGNED(20)
539100966Siwasaki  PPC64_STV_UNALIGNED(21)
540100966Siwasaki  PPC64_STV_UNALIGNED(22)
541100966Siwasaki  PPC64_STV_UNALIGNED(23)
542100966Siwasaki  PPC64_STV_UNALIGNED(24)
543100966Siwasaki  PPC64_STV_UNALIGNED(25)
544100966Siwasaki  PPC64_STV_UNALIGNED(26)
545100966Siwasaki  PPC64_STV_UNALIGNED(27)
546100966Siwasaki  PPC64_STV_UNALIGNED(28)
547100966Siwasaki  PPC64_STV_UNALIGNED(29)
548100966Siwasaki  PPC64_STV_UNALIGNED(30)
549100966Siwasaki  PPC64_STV_UNALIGNED(31)
550100966Siwasaki
551100966Siwasaki#endif
552100966Siwasaki
553117521Snjl  li    %r3,  0   // return UNW_ESUCCESS
554100966Siwasaki  blr
555100966Siwasaki
556100966Siwasaki
557100966Siwasaki#elif defined(__ppc__)
558117521Snjl
559117521Snjl//
560100966Siwasaki// extern int unw_getcontext(unw_context_t* thread_state)
561100966Siwasaki//
562100966Siwasaki// On entry:
563100966Siwasaki//  thread_state pointer is in r3
564100966Siwasaki//
565100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
566100966Siwasaki  stw     %r0,   8(%r3)
567100966Siwasaki  mflr    %r0
568100966Siwasaki  stw     %r0,   0(%r3) // store lr as ssr0
569100966Siwasaki  stw     %r1,  12(%r3)
570100966Siwasaki  stw     %r2,  16(%r3)
571100966Siwasaki  stw     %r3,  20(%r3)
572100966Siwasaki  stw     %r4,  24(%r3)
573100966Siwasaki  stw     %r5,  28(%r3)
574100966Siwasaki  stw     %r6,  32(%r3)
575100966Siwasaki  stw     %r7,  36(%r3)
576100966Siwasaki  stw     %r8,  40(%r3)
577100966Siwasaki  stw     %r9,  44(%r3)
578100966Siwasaki  stw     %r10, 48(%r3)
579100966Siwasaki  stw     %r11, 52(%r3)
580117521Snjl  stw     %r12, 56(%r3)
581117521Snjl  stw     %r13, 60(%r3)
582100966Siwasaki  stw     %r14, 64(%r3)
583100966Siwasaki  stw     %r15, 68(%r3)
584100966Siwasaki  stw     %r16, 72(%r3)
585100966Siwasaki  stw     %r17, 76(%r3)
586100966Siwasaki  stw     %r18, 80(%r3)
587100966Siwasaki  stw     %r19, 84(%r3)
588167802Sjkim  stw     %r20, 88(%r3)
589100966Siwasaki  stw     %r21, 92(%r3)
590167802Sjkim  stw     %r22, 96(%r3)
591117521Snjl  stw     %r23,100(%r3)
592100966Siwasaki  stw     %r24,104(%r3)
593100966Siwasaki  stw     %r25,108(%r3)
594100966Siwasaki  stw     %r26,112(%r3)
595117521Snjl  stw     %r27,116(%r3)
596117521Snjl  stw     %r28,120(%r3)
597100966Siwasaki  stw     %r29,124(%r3)
598100966Siwasaki  stw     %r30,128(%r3)
599100966Siwasaki  stw     %r31,132(%r3)
600100966Siwasaki
601100966Siwasaki  // save VRSave register
602100966Siwasaki  mfspr   %r0, 256
603100966Siwasaki  stw     %r0, 156(%r3)
604100966Siwasaki  // save CR registers
605100966Siwasaki  mfcr    %r0
606100966Siwasaki  stw     %r0, 136(%r3)
607100966Siwasaki  // save CTR register
608100966Siwasaki  mfctr   %r0
609117521Snjl  stw     %r0, 148(%r3)
610100966Siwasaki
611117521Snjl  // save float registers
612117521Snjl  stfd    %f0, 160(%r3)
613100966Siwasaki  stfd    %f1, 168(%r3)
614100966Siwasaki  stfd    %f2, 176(%r3)
615100966Siwasaki  stfd    %f3, 184(%r3)
616100966Siwasaki  stfd    %f4, 192(%r3)
617100966Siwasaki  stfd    %f5, 200(%r3)
618100966Siwasaki  stfd    %f6, 208(%r3)
619100966Siwasaki  stfd    %f7, 216(%r3)
620100966Siwasaki  stfd    %f8, 224(%r3)
621100966Siwasaki  stfd    %f9, 232(%r3)
622100966Siwasaki  stfd    %f10,240(%r3)
623117521Snjl  stfd    %f11,248(%r3)
624100966Siwasaki  stfd    %f12,256(%r3)
625117521Snjl  stfd    %f13,264(%r3)
626100966Siwasaki  stfd    %f14,272(%r3)
627117521Snjl  stfd    %f15,280(%r3)
628117521Snjl  stfd    %f16,288(%r3)
629117521Snjl  stfd    %f17,296(%r3)
630167802Sjkim  stfd    %f18,304(%r3)
631117521Snjl  stfd    %f19,312(%r3)
632117521Snjl  stfd    %f20,320(%r3)
633100966Siwasaki  stfd    %f21,328(%r3)
634167802Sjkim  stfd    %f22,336(%r3)
635100966Siwasaki  stfd    %f23,344(%r3)
636100966Siwasaki  stfd    %f24,352(%r3)
637100966Siwasaki  stfd    %f25,360(%r3)
638151937Sjkim  stfd    %f26,368(%r3)
639151937Sjkim  stfd    %f27,376(%r3)
640100966Siwasaki  stfd    %f28,384(%r3)
641100966Siwasaki  stfd    %f29,392(%r3)
642100966Siwasaki  stfd    %f30,400(%r3)
643100966Siwasaki  stfd    %f31,408(%r3)
644100966Siwasaki
645100966Siwasaki
646100966Siwasaki  // save vector registers
647100966Siwasaki
648100966Siwasaki  subi    %r4, %r1, 16
649100966Siwasaki  rlwinm  %r4, %r4, 0, 0, 27  // mask low 4-bits
650100966Siwasaki  // r4 is now a 16-byte aligned pointer into the red zone
651100966Siwasaki
652100966Siwasaki#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \
653100966Siwasaki  stvx    _vec, 0, %r4          SEPARATOR \
654100966Siwasaki  lwz     %r5, 0(%r4)           SEPARATOR \
655100966Siwasaki  stw     %r5, _offset(%r3)     SEPARATOR \
656100966Siwasaki  lwz     %r5, 4(%r4)           SEPARATOR \
657100966Siwasaki  stw     %r5, _offset+4(%r3)   SEPARATOR \
658100966Siwasaki  lwz     %r5, 8(%r4)           SEPARATOR \
659117521Snjl  stw     %r5, _offset+8(%r3)   SEPARATOR \
660117521Snjl  lwz     %r5, 12(%r4)          SEPARATOR \
661100966Siwasaki  stw     %r5, _offset+12(%r3)
662100966Siwasaki
663100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v0, 424+0x000)
664100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v1, 424+0x010)
665100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v2, 424+0x020)
666100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v3, 424+0x030)
667100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v4, 424+0x040)
668100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v5, 424+0x050)
669100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v6, 424+0x060)
670100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v7, 424+0x070)
671114237Snjl  SAVE_VECTOR_UNALIGNED( %v8, 424+0x080)
672100966Siwasaki  SAVE_VECTOR_UNALIGNED( %v9, 424+0x090)
673100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v10, 424+0x0A0)
674100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v11, 424+0x0B0)
675100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v12, 424+0x0C0)
676100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v13, 424+0x0D0)
677100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v14, 424+0x0E0)
678100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v15, 424+0x0F0)
679100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v16, 424+0x100)
680167802Sjkim  SAVE_VECTOR_UNALIGNED(%v17, 424+0x110)
681100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v18, 424+0x120)
682100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v19, 424+0x130)
683100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v20, 424+0x140)
684100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v21, 424+0x150)
685100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v22, 424+0x160)
686100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v23, 424+0x170)
687100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v24, 424+0x180)
688100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v25, 424+0x190)
689100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v26, 424+0x1A0)
690100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v27, 424+0x1B0)
691100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v28, 424+0x1C0)
692100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v29, 424+0x1D0)
693100966Siwasaki  SAVE_VECTOR_UNALIGNED(%v30, 424+0x1E0)
694167802Sjkim  SAVE_VECTOR_UNALIGNED(%v31, 424+0x1F0)
695100966Siwasaki
696100966Siwasaki  li      %r3, 0  // return UNW_ESUCCESS
697100966Siwasaki  blr
698100966Siwasaki
699100966Siwasaki
700100966Siwasaki#elif defined(__arm64__) || defined(__aarch64__)
701100966Siwasaki
702100966Siwasaki//
703100966Siwasaki// extern int __unw_getcontext(unw_context_t* thread_state)
704100966Siwasaki//
705100966Siwasaki// On entry:
706100966Siwasaki//  thread_state pointer is in x0
707100966Siwasaki//
708100966Siwasaki  .p2align 2
709100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
710167802Sjkim  stp    x0, x1,  [x0, #0x000]
711167802Sjkim  stp    x2, x3,  [x0, #0x010]
712167802Sjkim  stp    x4, x5,  [x0, #0x020]
713100966Siwasaki  stp    x6, x7,  [x0, #0x030]
714100966Siwasaki  stp    x8, x9,  [x0, #0x040]
715100966Siwasaki  stp    x10,x11, [x0, #0x050]
716100966Siwasaki  stp    x12,x13, [x0, #0x060]
717100966Siwasaki  stp    x14,x15, [x0, #0x070]
718167802Sjkim  stp    x16,x17, [x0, #0x080]
719100966Siwasaki  stp    x18,x19, [x0, #0x090]
720167802Sjkim  stp    x20,x21, [x0, #0x0A0]
721100966Siwasaki  stp    x22,x23, [x0, #0x0B0]
722100966Siwasaki  stp    x24,x25, [x0, #0x0C0]
723100966Siwasaki  stp    x26,x27, [x0, #0x0D0]
724100966Siwasaki  stp    x28,x29, [x0, #0x0E0]
725114237Snjl  str    x30,     [x0, #0x0F0]
726107325Siwasaki  mov    x1,sp
727107325Siwasaki  str    x1,      [x0, #0x0F8]
728100966Siwasaki  str    x30,     [x0, #0x100]    // store return address as pc
729100966Siwasaki  // skip cpsr
730100966Siwasaki  stp    d0, d1,  [x0, #0x110]
731107325Siwasaki  stp    d2, d3,  [x0, #0x120]
732100966Siwasaki  stp    d4, d5,  [x0, #0x130]
733100966Siwasaki  stp    d6, d7,  [x0, #0x140]
734100966Siwasaki  stp    d8, d9,  [x0, #0x150]
735100966Siwasaki  stp    d10,d11, [x0, #0x160]
736100966Siwasaki  stp    d12,d13, [x0, #0x170]
737100966Siwasaki  stp    d14,d15, [x0, #0x180]
738100966Siwasaki  stp    d16,d17, [x0, #0x190]
739100966Siwasaki  stp    d18,d19, [x0, #0x1A0]
740100966Siwasaki  stp    d20,d21, [x0, #0x1B0]
741100966Siwasaki  stp    d22,d23, [x0, #0x1C0]
742100966Siwasaki  stp    d24,d25, [x0, #0x1D0]
743100966Siwasaki  stp    d26,d27, [x0, #0x1E0]
744100966Siwasaki  stp    d28,d29, [x0, #0x1F0]
745100966Siwasaki  str    d30,     [x0, #0x200]
746100966Siwasaki  str    d31,     [x0, #0x208]
747100966Siwasaki  mov    x0, #0                   // return UNW_ESUCCESS
748100966Siwasaki  ret
749100966Siwasaki
750100966Siwasaki#elif defined(__arm__) && !defined(__APPLE__)
751100966Siwasaki
752100966Siwasaki#if !defined(__ARM_ARCH_ISA_ARM)
753100966Siwasaki#if (__ARM_ARCH_ISA_THUMB == 2)
754100966Siwasaki  .syntax unified
755100966Siwasaki#endif
756100966Siwasaki  .thumb
757100966Siwasaki#endif
758100966Siwasaki
759100966Siwasaki@
760100966Siwasaki@ extern int __unw_getcontext(unw_context_t* thread_state)
761100966Siwasaki@
762100966Siwasaki@ On entry:
763100966Siwasaki@  thread_state pointer is in r0
764100966Siwasaki@
765100966Siwasaki@ Per EHABI #4.7 this only saves the core integer registers.
766100966Siwasaki@ EHABI #7.4.5 notes that in general all VRS registers should be restored
767100966Siwasaki@ however this is very hard to do for VFP registers because it is unknown
768100966Siwasaki@ to the library how many registers are implemented by the architecture.
769100966Siwasaki@ Instead, VFP registers are demand saved by logic external to __unw_getcontext.
770100966Siwasaki@
771100966Siwasaki  .p2align 2
772100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
773100966Siwasaki#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1
774100966Siwasaki  stm r0!, {r0-r7}
775100966Siwasaki  mov r1, r8
776167802Sjkim  mov r2, r9
777100966Siwasaki  mov r3, r10
778167802Sjkim  stm r0!, {r1-r3}
779100966Siwasaki  mov r1, r11
780100966Siwasaki  mov r2, sp
781100966Siwasaki  mov r3, lr
782100966Siwasaki  str r1, [r0, #0]   @ r11
783107325Siwasaki  @ r12 does not need storing, it it the intra-procedure-call scratch register
784107325Siwasaki  str r2, [r0, #8]   @ sp
785100966Siwasaki  str r3, [r0, #12]  @ lr
786100966Siwasaki  str r3, [r0, #16]  @ store return address as pc
787100966Siwasaki  @ T1 does not have a non-cpsr-clobbering register-zeroing instruction.
788107325Siwasaki  @ It is safe to use here though because we are about to return, and cpsr is
789100966Siwasaki  @ not expected to be preserved.
790100966Siwasaki  movs r0, #0        @ return UNW_ESUCCESS
791100966Siwasaki#else
792100966Siwasaki  @ 32bit thumb-2 restrictions for stm:
793100966Siwasaki  @ . the sp (r13) cannot be in the list
794100966Siwasaki  @ . the pc (r15) cannot be in the list in an STM instruction
795100966Siwasaki  stm r0, {r0-r12}
796100966Siwasaki  str sp, [r0, #52]
797100966Siwasaki  str lr, [r0, #56]
798100966Siwasaki  str lr, [r0, #60]  @ store return address as pc
799100966Siwasaki  mov r0, #0         @ return UNW_ESUCCESS
800100966Siwasaki#endif
801100966Siwasaki  JMP(lr)
802100966Siwasaki
803100966Siwasaki@
804100966Siwasaki@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)
805100966Siwasaki@
806100966Siwasaki@ On entry:
807100966Siwasaki@  values pointer is in r0
808100966Siwasaki@
809100966Siwasaki  .p2align 2
810100966Siwasaki#if defined(__ELF__)
811100966Siwasaki  .fpu vfpv3-d16
812100966Siwasaki#endif
813100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv)
814100966Siwasaki  vstmia r0, {d0-d15}
815100966Siwasaki  JMP(lr)
816100966Siwasaki
817100966Siwasaki@
818100966Siwasaki@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)
819100966Siwasaki@
820100966Siwasaki@ On entry:
821100966Siwasaki@  values pointer is in r0
822100966Siwasaki@
823100966Siwasaki  .p2align 2
824100966Siwasaki#if defined(__ELF__)
825100966Siwasaki  .fpu vfpv3-d16
826100966Siwasaki#endif
827100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv)
828100966Siwasaki  vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia
829100966Siwasaki  JMP(lr)
830100966Siwasaki
831167802Sjkim@
832100966Siwasaki@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)
833167802Sjkim@
834100966Siwasaki@ On entry:
835100966Siwasaki@  values pointer is in r0
836100966Siwasaki@
837100966Siwasaki  .p2align 2
838107325Siwasaki#if defined(__ELF__)
839107325Siwasaki  .fpu vfpv3
840107325Siwasaki#endif
841100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv)
842100966Siwasaki  @ VFP and iwMMX instructions are only available when compiling with the flags
843100966Siwasaki  @ that enable them. We do not want to do that in the library (because we do not
844107325Siwasaki  @ want the compiler to generate instructions that access those) but this is
845100966Siwasaki  @ only accessed if the personality routine needs these registers. Use of
846100966Siwasaki  @ these registers implies they are, actually, available on the target, so
847100966Siwasaki  @ it's ok to execute.
848100966Siwasaki  @ So, generate the instructions using the corresponding coprocessor mnemonic.
849100966Siwasaki  vstmia r0, {d16-d31}
850100966Siwasaki  JMP(lr)
851100966Siwasaki
852100966Siwasaki#if defined(_LIBUNWIND_ARM_WMMX)
853100966Siwasaki
854100966Siwasaki@
855100966Siwasaki@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)
856100966Siwasaki@
857100966Siwasaki@ On entry:
858100966Siwasaki@  values pointer is in r0
859100966Siwasaki@
860100966Siwasaki  .p2align 2
861100966Siwasaki#if defined(__ELF__)
862100966Siwasaki  .arch armv5te
863100966Siwasaki#endif
864100966SiwasakiDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv)
865100966Siwasaki  stcl p1, cr0, [r0], #8  @ wstrd wR0, [r0], #8
866100966Siwasaki  stcl p1, cr1, [r0], #8  @ wstrd wR1, [r0], #8
867100966Siwasaki  stcl p1, cr2, [r0], #8  @ wstrd wR2, [r0], #8
868100966Siwasaki  stcl p1, cr3, [r0], #8  @ wstrd wR3, [r0], #8
869100966Siwasaki  stcl p1, cr4, [r0], #8  @ wstrd wR4, [r0], #8
870100966Siwasaki  stcl p1, cr5, [r0], #8  @ wstrd wR5, [r0], #8
871100966Siwasaki  stcl p1, cr6, [r0], #8  @ wstrd wR6, [r0], #8
872100966Siwasaki  stcl p1, cr7, [r0], #8  @ wstrd wR7, [r0], #8
873100966Siwasaki  stcl p1, cr8, [r0], #8  @ wstrd wR8, [r0], #8
874100966Siwasaki  stcl p1, cr9, [r0], #8  @ wstrd wR9, [r0], #8
875100966Siwasaki  stcl p1, cr10, [r0], #8  @ wstrd wR10, [r0], #8
876100966Siwasaki  stcl p1, cr11, [r0], #8  @ wstrd wR11, [r0], #8
877100966Siwasaki  stcl p1, cr12, [r0], #8  @ wstrd wR12, [r0], #8
878100966Siwasaki  stcl p1, cr13, [r0], #8  @ wstrd wR13, [r0], #8
879100966Siwasaki  stcl p1, cr14, [r0], #8  @ wstrd wR14, [r0], #8
880100966Siwasaki  stcl p1, cr15, [r0], #8  @ wstrd wR15, [r0], #8
881100966Siwasaki  JMP(lr)
882100966Siwasaki
883100966Siwasaki@
884100966Siwasaki@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)
885100966Siwasaki@
886100966Siwasaki@ On entry:
887100966Siwasaki@  values pointer is in r0
888100966Siwasaki@
889167802Sjkim  .p2align 2
890100966Siwasaki#if defined(__ELF__)
891167802Sjkim  .arch armv5te
892#endif
893DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)
894  stc2 p1, cr8, [r0], #4  @ wstrw wCGR0, [r0], #4
895  stc2 p1, cr9, [r0], #4  @ wstrw wCGR1, [r0], #4
896  stc2 p1, cr10, [r0], #4  @ wstrw wCGR2, [r0], #4
897  stc2 p1, cr11, [r0], #4  @ wstrw wCGR3, [r0], #4
898  JMP(lr)
899
900#endif
901
902#elif defined(__or1k__)
903
904#
905# extern int __unw_getcontext(unw_context_t* thread_state)
906#
907# On entry:
908#  thread_state pointer is in r3
909#
910DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
911  l.sw       0(r3), r0
912  l.sw       4(r3), r1
913  l.sw       8(r3), r2
914  l.sw      12(r3), r3
915  l.sw      16(r3), r4
916  l.sw      20(r3), r5
917  l.sw      24(r3), r6
918  l.sw      28(r3), r7
919  l.sw      32(r3), r8
920  l.sw      36(r3), r9
921  l.sw      40(r3), r10
922  l.sw      44(r3), r11
923  l.sw      48(r3), r12
924  l.sw      52(r3), r13
925  l.sw      56(r3), r14
926  l.sw      60(r3), r15
927  l.sw      64(r3), r16
928  l.sw      68(r3), r17
929  l.sw      72(r3), r18
930  l.sw      76(r3), r19
931  l.sw      80(r3), r20
932  l.sw      84(r3), r21
933  l.sw      88(r3), r22
934  l.sw      92(r3), r23
935  l.sw      96(r3), r24
936  l.sw     100(r3), r25
937  l.sw     104(r3), r26
938  l.sw     108(r3), r27
939  l.sw     112(r3), r28
940  l.sw     116(r3), r29
941  l.sw     120(r3), r30
942  l.sw     124(r3), r31
943  # store ra to pc
944  l.sw     128(r3), r9
945  # zero epcr
946  l.sw     132(r3), r0
947
948#elif defined(__sparc__)
949
950#
951# extern int __unw_getcontext(unw_context_t* thread_state)
952#
953# On entry:
954#  thread_state pointer is in o0
955#
956DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
957  ta 3
958  add %o7, 8, %o7
959  std %g0, [%o0 +   0]
960  std %g2, [%o0 +   8]
961  std %g4, [%o0 +  16]
962  std %g6, [%o0 +  24]
963  std %o0, [%o0 +  32]
964  std %o2, [%o0 +  40]
965  std %o4, [%o0 +  48]
966  std %o6, [%o0 +  56]
967  std %l0, [%o0 +  64]
968  std %l2, [%o0 +  72]
969  std %l4, [%o0 +  80]
970  std %l6, [%o0 +  88]
971  std %i0, [%o0 +  96]
972  std %i2, [%o0 + 104]
973  std %i4, [%o0 + 112]
974  std %i6, [%o0 + 120]
975  jmp %o7
976   clr %o0                   // return UNW_ESUCCESS
977
978#elif defined(__riscv) && __riscv_xlen == 64
979
980#
981# extern int __unw_getcontext(unw_context_t* thread_state)
982#
983# On entry:
984#  thread_state pointer is in a0
985#
986DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
987  // x0 is zero
988  sd    x1, (8 * 1)(a0)
989  sd    x2, (8 * 2)(a0)
990  sd    x3, (8 * 3)(a0)
991  sd    x4, (8 * 4)(a0)
992  sd    x5, (8 * 5)(a0)
993  sd    x6, (8 * 6)(a0)
994  sd    x7, (8 * 7)(a0)
995  sd    x8, (8 * 8)(a0)
996  sd    x9, (8 * 9)(a0)
997  sd    x10, (8 * 10)(a0)
998  sd    x11, (8 * 11)(a0)
999  sd    x12, (8 * 12)(a0)
1000  sd    x13, (8 * 13)(a0)
1001  sd    x14, (8 * 14)(a0)
1002  sd    x15, (8 * 15)(a0)
1003  sd    x16, (8 * 16)(a0)
1004  sd    x17, (8 * 17)(a0)
1005  sd    x18, (8 * 18)(a0)
1006  sd    x19, (8 * 19)(a0)
1007  sd    x20, (8 * 20)(a0)
1008  sd    x21, (8 * 21)(a0)
1009  sd    x22, (8 * 22)(a0)
1010  sd    x23, (8 * 23)(a0)
1011  sd    x24, (8 * 24)(a0)
1012  sd    x25, (8 * 25)(a0)
1013  sd    x26, (8 * 26)(a0)
1014  sd    x27, (8 * 27)(a0)
1015  sd    x28, (8 * 28)(a0)
1016  sd    x29, (8 * 29)(a0)
1017  sd    x30, (8 * 30)(a0)
1018  sd    x31, (8 * 31)(a0)
1019
1020#if defined(__riscv_flen) && __riscv_flen == 64
1021  fsd    f0, (8 * 32 + 8 * 0)(a0)
1022  fsd    f1, (8 * 32 + 8 * 1)(a0)
1023  fsd    f2, (8 * 32 + 8 * 2)(a0)
1024  fsd    f3, (8 * 32 + 8 * 3)(a0)
1025  fsd    f4, (8 * 32 + 8 * 4)(a0)
1026  fsd    f5, (8 * 32 + 8 * 5)(a0)
1027  fsd    f6, (8 * 32 + 8 * 6)(a0)
1028  fsd    f7, (8 * 32 + 8 * 7)(a0)
1029  fsd    f8, (8 * 32 + 8 * 8)(a0)
1030  fsd    f9, (8 * 32 + 8 * 9)(a0)
1031  fsd    f10, (8 * 32 + 8 * 10)(a0)
1032  fsd    f11, (8 * 32 + 8 * 11)(a0)
1033  fsd    f12, (8 * 32 + 8 * 12)(a0)
1034  fsd    f13, (8 * 32 + 8 * 13)(a0)
1035  fsd    f14, (8 * 32 + 8 * 14)(a0)
1036  fsd    f15, (8 * 32 + 8 * 15)(a0)
1037  fsd    f16, (8 * 32 + 8 * 16)(a0)
1038  fsd    f17, (8 * 32 + 8 * 17)(a0)
1039  fsd    f18, (8 * 32 + 8 * 18)(a0)
1040  fsd    f19, (8 * 32 + 8 * 19)(a0)
1041  fsd    f20, (8 * 32 + 8 * 20)(a0)
1042  fsd    f21, (8 * 32 + 8 * 21)(a0)
1043  fsd    f22, (8 * 32 + 8 * 22)(a0)
1044  fsd    f23, (8 * 32 + 8 * 23)(a0)
1045  fsd    f24, (8 * 32 + 8 * 24)(a0)
1046  fsd    f25, (8 * 32 + 8 * 25)(a0)
1047  fsd    f26, (8 * 32 + 8 * 26)(a0)
1048  fsd    f27, (8 * 32 + 8 * 27)(a0)
1049  fsd    f28, (8 * 32 + 8 * 28)(a0)
1050  fsd    f29, (8 * 32 + 8 * 29)(a0)
1051  fsd    f30, (8 * 32 + 8 * 30)(a0)
1052  fsd    f31, (8 * 32 + 8 * 31)(a0)
1053#endif
1054
1055  li     a0, 0  // return UNW_ESUCCESS
1056  ret           // jump to ra
1057#endif
1058
1059  WEAK_ALIAS(__unw_getcontext, unw_getcontext)
1060
1061#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
1062
1063NO_EXEC_STACK_DIRECTIVE
1064