1349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric#include "assembly.h" 100b57cec5SDimitry Andric 11bdd1243dSDimitry Andric#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 12bdd1243dSDimitry Andric#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 13bdd1243dSDimitry Andric 14bdd1243dSDimitry Andric#define FROM_0_TO_31 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 15bdd1243dSDimitry Andric#define FROM_32_TO_63 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 16bdd1243dSDimitry Andric 1781ad6265SDimitry Andric#if defined(_AIX) 1881ad6265SDimitry Andric .toc 1981ad6265SDimitry Andric#else 200b57cec5SDimitry Andric .text 2181ad6265SDimitry Andric#endif 220b57cec5SDimitry Andric 23*0fca6ea1SDimitry Andric#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric#if defined(__i386__) 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric# 280b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 290b57cec5SDimitry Andric# 300b57cec5SDimitry Andric# On entry: 310b57cec5SDimitry Andric# + + 320b57cec5SDimitry Andric# +-----------------------+ 330b57cec5SDimitry Andric# + thread_state pointer + 340b57cec5SDimitry Andric# +-----------------------+ 350b57cec5SDimitry Andric# + return address + 360b57cec5SDimitry Andric# +-----------------------+ <-- SP 370b57cec5SDimitry Andric# + + 380b57cec5SDimitry Andric# 390b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 40349cc55cSDimitry Andric 41349cc55cSDimitry Andric _LIBUNWIND_CET_ENDBR 420b57cec5SDimitry Andric push %eax 430b57cec5SDimitry Andric movl 8(%esp), %eax 440b57cec5SDimitry Andric movl %ebx, 4(%eax) 450b57cec5SDimitry Andric movl %ecx, 8(%eax) 460b57cec5SDimitry Andric movl %edx, 12(%eax) 470b57cec5SDimitry Andric movl %edi, 16(%eax) 480b57cec5SDimitry Andric movl %esi, 20(%eax) 490b57cec5SDimitry Andric movl %ebp, 24(%eax) 500b57cec5SDimitry Andric movl %esp, %edx 510b57cec5SDimitry Andric addl $8, %edx 520b57cec5SDimitry Andric movl %edx, 28(%eax) # store what sp was at call site as esp 530b57cec5SDimitry Andric # skip ss 540b57cec5SDimitry Andric # skip eflags 550b57cec5SDimitry Andric movl 4(%esp), %edx 560b57cec5SDimitry Andric movl %edx, 40(%eax) # store return address as eip 570b57cec5SDimitry Andric # skip cs 580b57cec5SDimitry Andric # skip ds 590b57cec5SDimitry Andric # skip es 600b57cec5SDimitry Andric # skip fs 610b57cec5SDimitry Andric # skip gs 620b57cec5SDimitry Andric movl (%esp), %edx 630b57cec5SDimitry Andric movl %edx, (%eax) # store original eax 640b57cec5SDimitry Andric popl %eax 650b57cec5SDimitry Andric xorl %eax, %eax # return UNW_ESUCCESS 660b57cec5SDimitry Andric ret 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric#elif defined(__x86_64__) 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric# 710b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 720b57cec5SDimitry Andric# 730b57cec5SDimitry Andric# On entry: 740b57cec5SDimitry Andric# thread_state pointer is in rdi 750b57cec5SDimitry Andric# 760b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 770b57cec5SDimitry Andric#if defined(_WIN64) 780b57cec5SDimitry Andric#define PTR %rcx 790b57cec5SDimitry Andric#define TMP %rdx 800b57cec5SDimitry Andric#else 810b57cec5SDimitry Andric#define PTR %rdi 820b57cec5SDimitry Andric#define TMP %rsi 830b57cec5SDimitry Andric#endif 840b57cec5SDimitry Andric 85349cc55cSDimitry Andric _LIBUNWIND_CET_ENDBR 860b57cec5SDimitry Andric movq %rax, (PTR) 870b57cec5SDimitry Andric movq %rbx, 8(PTR) 880b57cec5SDimitry Andric movq %rcx, 16(PTR) 890b57cec5SDimitry Andric movq %rdx, 24(PTR) 900b57cec5SDimitry Andric movq %rdi, 32(PTR) 910b57cec5SDimitry Andric movq %rsi, 40(PTR) 920b57cec5SDimitry Andric movq %rbp, 48(PTR) 930b57cec5SDimitry Andric movq %rsp, 56(PTR) 940b57cec5SDimitry Andric addq $8, 56(PTR) 950b57cec5SDimitry Andric movq %r8, 64(PTR) 960b57cec5SDimitry Andric movq %r9, 72(PTR) 970b57cec5SDimitry Andric movq %r10, 80(PTR) 980b57cec5SDimitry Andric movq %r11, 88(PTR) 990b57cec5SDimitry Andric movq %r12, 96(PTR) 1000b57cec5SDimitry Andric movq %r13,104(PTR) 1010b57cec5SDimitry Andric movq %r14,112(PTR) 1020b57cec5SDimitry Andric movq %r15,120(PTR) 1030b57cec5SDimitry Andric movq (%rsp),TMP 1040b57cec5SDimitry Andric movq TMP,128(PTR) # store return address as rip 1050b57cec5SDimitry Andric # skip rflags 1060b57cec5SDimitry Andric # skip cs 1070b57cec5SDimitry Andric # skip fs 1080b57cec5SDimitry Andric # skip gs 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric#if defined(_WIN64) 1110b57cec5SDimitry Andric movdqu %xmm0,176(PTR) 1120b57cec5SDimitry Andric movdqu %xmm1,192(PTR) 1130b57cec5SDimitry Andric movdqu %xmm2,208(PTR) 1140b57cec5SDimitry Andric movdqu %xmm3,224(PTR) 1150b57cec5SDimitry Andric movdqu %xmm4,240(PTR) 1160b57cec5SDimitry Andric movdqu %xmm5,256(PTR) 1170b57cec5SDimitry Andric movdqu %xmm6,272(PTR) 1180b57cec5SDimitry Andric movdqu %xmm7,288(PTR) 1190b57cec5SDimitry Andric movdqu %xmm8,304(PTR) 1200b57cec5SDimitry Andric movdqu %xmm9,320(PTR) 1210b57cec5SDimitry Andric movdqu %xmm10,336(PTR) 1220b57cec5SDimitry Andric movdqu %xmm11,352(PTR) 1230b57cec5SDimitry Andric movdqu %xmm12,368(PTR) 1240b57cec5SDimitry Andric movdqu %xmm13,384(PTR) 1250b57cec5SDimitry Andric movdqu %xmm14,400(PTR) 1260b57cec5SDimitry Andric movdqu %xmm15,416(PTR) 1270b57cec5SDimitry Andric#endif 1280b57cec5SDimitry Andric xorl %eax, %eax # return UNW_ESUCCESS 1290b57cec5SDimitry Andric ret 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric# 1340b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 1350b57cec5SDimitry Andric# 1360b57cec5SDimitry Andric# On entry: 1370b57cec5SDimitry Andric# thread_state pointer is in a0 ($4) 1380b57cec5SDimitry Andric# 1390b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1400b57cec5SDimitry Andric .set push 1410b57cec5SDimitry Andric .set noat 1420b57cec5SDimitry Andric .set noreorder 1430b57cec5SDimitry Andric .set nomacro 1440b57cec5SDimitry Andric sw $1, (4 * 1)($4) 1450b57cec5SDimitry Andric sw $2, (4 * 2)($4) 1460b57cec5SDimitry Andric sw $3, (4 * 3)($4) 1470b57cec5SDimitry Andric sw $4, (4 * 4)($4) 1480b57cec5SDimitry Andric sw $5, (4 * 5)($4) 1490b57cec5SDimitry Andric sw $6, (4 * 6)($4) 1500b57cec5SDimitry Andric sw $7, (4 * 7)($4) 1510b57cec5SDimitry Andric sw $8, (4 * 8)($4) 1520b57cec5SDimitry Andric sw $9, (4 * 9)($4) 1530b57cec5SDimitry Andric sw $10, (4 * 10)($4) 1540b57cec5SDimitry Andric sw $11, (4 * 11)($4) 1550b57cec5SDimitry Andric sw $12, (4 * 12)($4) 1560b57cec5SDimitry Andric sw $13, (4 * 13)($4) 1570b57cec5SDimitry Andric sw $14, (4 * 14)($4) 1580b57cec5SDimitry Andric sw $15, (4 * 15)($4) 1590b57cec5SDimitry Andric sw $16, (4 * 16)($4) 1600b57cec5SDimitry Andric sw $17, (4 * 17)($4) 1610b57cec5SDimitry Andric sw $18, (4 * 18)($4) 1620b57cec5SDimitry Andric sw $19, (4 * 19)($4) 1630b57cec5SDimitry Andric sw $20, (4 * 20)($4) 1640b57cec5SDimitry Andric sw $21, (4 * 21)($4) 1650b57cec5SDimitry Andric sw $22, (4 * 22)($4) 1660b57cec5SDimitry Andric sw $23, (4 * 23)($4) 1670b57cec5SDimitry Andric sw $24, (4 * 24)($4) 1680b57cec5SDimitry Andric sw $25, (4 * 25)($4) 1690b57cec5SDimitry Andric sw $26, (4 * 26)($4) 1700b57cec5SDimitry Andric sw $27, (4 * 27)($4) 1710b57cec5SDimitry Andric sw $28, (4 * 28)($4) 1720b57cec5SDimitry Andric sw $29, (4 * 29)($4) 1730b57cec5SDimitry Andric sw $30, (4 * 30)($4) 1740b57cec5SDimitry Andric sw $31, (4 * 31)($4) 1750b57cec5SDimitry Andric # Store return address to pc 1760b57cec5SDimitry Andric sw $31, (4 * 32)($4) 1775f757f3fSDimitry Andric#if __mips_isa_rev < 6 1780b57cec5SDimitry Andric # hi and lo 1790b57cec5SDimitry Andric mfhi $8 1800b57cec5SDimitry Andric sw $8, (4 * 33)($4) 1810b57cec5SDimitry Andric mflo $8 1820b57cec5SDimitry Andric sw $8, (4 * 34)($4) 1835f757f3fSDimitry Andric#endif 1840b57cec5SDimitry Andric#ifdef __mips_hard_float 1850b57cec5SDimitry Andric#if __mips_fpr != 64 1860b57cec5SDimitry Andric sdc1 $f0, (4 * 36 + 8 * 0)($4) 1870b57cec5SDimitry Andric sdc1 $f2, (4 * 36 + 8 * 2)($4) 1880b57cec5SDimitry Andric sdc1 $f4, (4 * 36 + 8 * 4)($4) 1890b57cec5SDimitry Andric sdc1 $f6, (4 * 36 + 8 * 6)($4) 1900b57cec5SDimitry Andric sdc1 $f8, (4 * 36 + 8 * 8)($4) 1910b57cec5SDimitry Andric sdc1 $f10, (4 * 36 + 8 * 10)($4) 1920b57cec5SDimitry Andric sdc1 $f12, (4 * 36 + 8 * 12)($4) 1930b57cec5SDimitry Andric sdc1 $f14, (4 * 36 + 8 * 14)($4) 1940b57cec5SDimitry Andric sdc1 $f16, (4 * 36 + 8 * 16)($4) 1950b57cec5SDimitry Andric sdc1 $f18, (4 * 36 + 8 * 18)($4) 1960b57cec5SDimitry Andric sdc1 $f20, (4 * 36 + 8 * 20)($4) 1970b57cec5SDimitry Andric sdc1 $f22, (4 * 36 + 8 * 22)($4) 1980b57cec5SDimitry Andric sdc1 $f24, (4 * 36 + 8 * 24)($4) 1990b57cec5SDimitry Andric sdc1 $f26, (4 * 36 + 8 * 26)($4) 2000b57cec5SDimitry Andric sdc1 $f28, (4 * 36 + 8 * 28)($4) 2010b57cec5SDimitry Andric sdc1 $f30, (4 * 36 + 8 * 30)($4) 2020b57cec5SDimitry Andric#else 2030b57cec5SDimitry Andric sdc1 $f0, (4 * 36 + 8 * 0)($4) 2040b57cec5SDimitry Andric sdc1 $f1, (4 * 36 + 8 * 1)($4) 2050b57cec5SDimitry Andric sdc1 $f2, (4 * 36 + 8 * 2)($4) 2060b57cec5SDimitry Andric sdc1 $f3, (4 * 36 + 8 * 3)($4) 2070b57cec5SDimitry Andric sdc1 $f4, (4 * 36 + 8 * 4)($4) 2080b57cec5SDimitry Andric sdc1 $f5, (4 * 36 + 8 * 5)($4) 2090b57cec5SDimitry Andric sdc1 $f6, (4 * 36 + 8 * 6)($4) 2100b57cec5SDimitry Andric sdc1 $f7, (4 * 36 + 8 * 7)($4) 2110b57cec5SDimitry Andric sdc1 $f8, (4 * 36 + 8 * 8)($4) 2120b57cec5SDimitry Andric sdc1 $f9, (4 * 36 + 8 * 9)($4) 2130b57cec5SDimitry Andric sdc1 $f10, (4 * 36 + 8 * 10)($4) 2140b57cec5SDimitry Andric sdc1 $f11, (4 * 36 + 8 * 11)($4) 2150b57cec5SDimitry Andric sdc1 $f12, (4 * 36 + 8 * 12)($4) 2160b57cec5SDimitry Andric sdc1 $f13, (4 * 36 + 8 * 13)($4) 2170b57cec5SDimitry Andric sdc1 $f14, (4 * 36 + 8 * 14)($4) 2180b57cec5SDimitry Andric sdc1 $f15, (4 * 36 + 8 * 15)($4) 2190b57cec5SDimitry Andric sdc1 $f16, (4 * 36 + 8 * 16)($4) 2200b57cec5SDimitry Andric sdc1 $f17, (4 * 36 + 8 * 17)($4) 2210b57cec5SDimitry Andric sdc1 $f18, (4 * 36 + 8 * 18)($4) 2220b57cec5SDimitry Andric sdc1 $f19, (4 * 36 + 8 * 19)($4) 2230b57cec5SDimitry Andric sdc1 $f20, (4 * 36 + 8 * 20)($4) 2240b57cec5SDimitry Andric sdc1 $f21, (4 * 36 + 8 * 21)($4) 2250b57cec5SDimitry Andric sdc1 $f22, (4 * 36 + 8 * 22)($4) 2260b57cec5SDimitry Andric sdc1 $f23, (4 * 36 + 8 * 23)($4) 2270b57cec5SDimitry Andric sdc1 $f24, (4 * 36 + 8 * 24)($4) 2280b57cec5SDimitry Andric sdc1 $f25, (4 * 36 + 8 * 25)($4) 2290b57cec5SDimitry Andric sdc1 $f26, (4 * 36 + 8 * 26)($4) 2300b57cec5SDimitry Andric sdc1 $f27, (4 * 36 + 8 * 27)($4) 2310b57cec5SDimitry Andric sdc1 $f28, (4 * 36 + 8 * 28)($4) 2320b57cec5SDimitry Andric sdc1 $f29, (4 * 36 + 8 * 29)($4) 2330b57cec5SDimitry Andric sdc1 $f30, (4 * 36 + 8 * 30)($4) 2340b57cec5SDimitry Andric sdc1 $f31, (4 * 36 + 8 * 31)($4) 2350b57cec5SDimitry Andric#endif 2360b57cec5SDimitry Andric#endif 2370b57cec5SDimitry Andric jr $31 2380b57cec5SDimitry Andric # return UNW_ESUCCESS 2390b57cec5SDimitry Andric or $2, $0, $0 2400b57cec5SDimitry Andric .set pop 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric#elif defined(__mips64) 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric# 2450b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 2460b57cec5SDimitry Andric# 2470b57cec5SDimitry Andric# On entry: 2480b57cec5SDimitry Andric# thread_state pointer is in a0 ($4) 2490b57cec5SDimitry Andric# 2500b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 2510b57cec5SDimitry Andric .set push 2520b57cec5SDimitry Andric .set noat 2530b57cec5SDimitry Andric .set noreorder 2540b57cec5SDimitry Andric .set nomacro 255bdd1243dSDimitry Andric .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 256bdd1243dSDimitry Andric sd $\i, (8 * \i)($4) 257bdd1243dSDimitry Andric .endr 2580b57cec5SDimitry Andric # Store return address to pc 2590b57cec5SDimitry Andric sd $31, (8 * 32)($4) 2605f757f3fSDimitry Andric#if __mips_isa_rev < 6 2610b57cec5SDimitry Andric # hi and lo 2620b57cec5SDimitry Andric mfhi $8 2630b57cec5SDimitry Andric sd $8, (8 * 33)($4) 2640b57cec5SDimitry Andric mflo $8 2650b57cec5SDimitry Andric sd $8, (8 * 34)($4) 2665f757f3fSDimitry Andric#endif 2670b57cec5SDimitry Andric#ifdef __mips_hard_float 268bdd1243dSDimitry Andric .irp i,FROM_0_TO_31 269bdd1243dSDimitry Andric sdc1 $f\i, (280+8*\i)($4) 270bdd1243dSDimitry Andric .endr 2710b57cec5SDimitry Andric#endif 2720b57cec5SDimitry Andric jr $31 2730b57cec5SDimitry Andric # return UNW_ESUCCESS 2740b57cec5SDimitry Andric or $2, $0, $0 2750b57cec5SDimitry Andric .set pop 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric# elif defined(__mips__) 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric# 2800b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 2810b57cec5SDimitry Andric# 2820b57cec5SDimitry Andric# Just trap for the time being. 2830b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 2840b57cec5SDimitry Andric teq $0, $0 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric#elif defined(__powerpc64__) 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric// 2890b57cec5SDimitry Andric// extern int __unw_getcontext(unw_context_t* thread_state) 2900b57cec5SDimitry Andric// 2910b57cec5SDimitry Andric// On entry: 2920b57cec5SDimitry Andric// thread_state pointer is in r3 2930b57cec5SDimitry Andric// 29481ad6265SDimitry Andric#if defined(_AIX) 29581ad6265SDimitry AndricDEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext) 29681ad6265SDimitry Andric#else 2970b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 29881ad6265SDimitry Andric#endif 2990b57cec5SDimitry Andric// store register (GPR) 3000b57cec5SDimitry Andric#define PPC64_STR(n) \ 301fe6060f1SDimitry Andric std n, (8 * (n + 2))(3) 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric // save GPRs 3040b57cec5SDimitry Andric PPC64_STR(0) 305fe6060f1SDimitry Andric mflr 0 306fe6060f1SDimitry Andric std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0 3070b57cec5SDimitry Andric PPC64_STR(1) 3085f757f3fSDimitry Andric PPC64_STR(4) // Save r4 first since it will be used for fixing r2. 3095f757f3fSDimitry Andric#if defined(_AIX) 3105f757f3fSDimitry Andric // The TOC register (r2) was changed by the glue code if unw_getcontext 3115f757f3fSDimitry Andric // is called from a different module. Save the original TOC register 3125f757f3fSDimitry Andric // in the context if this is the case. 3135f757f3fSDimitry Andric mflr 4 3145f757f3fSDimitry Andric lwz 4, 0(4) // Get the first instruction at the return address. 3155f757f3fSDimitry Andric xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"? 3165f757f3fSDimitry Andric cmplwi 0, 0x28 3175f757f3fSDimitry Andric bne 0, LnoR2Fix // No need to fix up r2 if it is not. 3185f757f3fSDimitry Andric ld 2, 40(1) // Use the saved TOC register in the stack. 3195f757f3fSDimitry AndricLnoR2Fix: 3205f757f3fSDimitry Andric#endif 3210b57cec5SDimitry Andric PPC64_STR(2) 3220b57cec5SDimitry Andric PPC64_STR(3) 3230b57cec5SDimitry Andric PPC64_STR(5) 3240b57cec5SDimitry Andric PPC64_STR(6) 3250b57cec5SDimitry Andric PPC64_STR(7) 3260b57cec5SDimitry Andric PPC64_STR(8) 3270b57cec5SDimitry Andric PPC64_STR(9) 3280b57cec5SDimitry Andric PPC64_STR(10) 3290b57cec5SDimitry Andric PPC64_STR(11) 3300b57cec5SDimitry Andric PPC64_STR(12) 3310b57cec5SDimitry Andric PPC64_STR(13) 3320b57cec5SDimitry Andric PPC64_STR(14) 3330b57cec5SDimitry Andric PPC64_STR(15) 3340b57cec5SDimitry Andric PPC64_STR(16) 3350b57cec5SDimitry Andric PPC64_STR(17) 3360b57cec5SDimitry Andric PPC64_STR(18) 3370b57cec5SDimitry Andric PPC64_STR(19) 3380b57cec5SDimitry Andric PPC64_STR(20) 3390b57cec5SDimitry Andric PPC64_STR(21) 3400b57cec5SDimitry Andric PPC64_STR(22) 3410b57cec5SDimitry Andric PPC64_STR(23) 3420b57cec5SDimitry Andric PPC64_STR(24) 3430b57cec5SDimitry Andric PPC64_STR(25) 3440b57cec5SDimitry Andric PPC64_STR(26) 3450b57cec5SDimitry Andric PPC64_STR(27) 3460b57cec5SDimitry Andric PPC64_STR(28) 3470b57cec5SDimitry Andric PPC64_STR(29) 3480b57cec5SDimitry Andric PPC64_STR(30) 3490b57cec5SDimitry Andric PPC64_STR(31) 3500b57cec5SDimitry Andric 351fe6060f1SDimitry Andric mfcr 0 352fe6060f1SDimitry Andric std 0, PPC64_OFFS_CR(3) 353fe6060f1SDimitry Andric mfxer 0 354fe6060f1SDimitry Andric std 0, PPC64_OFFS_XER(3) 3555f757f3fSDimitry Andric#if defined(_AIX) 3565f757f3fSDimitry Andric // LR value saved from the register is not used, initialize it to 0. 3575f757f3fSDimitry Andric li 0, 0 3585f757f3fSDimitry Andric#else 359fe6060f1SDimitry Andric mflr 0 3605f757f3fSDimitry Andric#endif 361fe6060f1SDimitry Andric std 0, PPC64_OFFS_LR(3) 362fe6060f1SDimitry Andric mfctr 0 363fe6060f1SDimitry Andric std 0, PPC64_OFFS_CTR(3) 364fe6060f1SDimitry Andric mfvrsave 0 365fe6060f1SDimitry Andric std 0, PPC64_OFFS_VRSAVE(3) 3660b57cec5SDimitry Andric 367e8d8bef9SDimitry Andric#if defined(__VSX__) 3680b57cec5SDimitry Andric // save VS registers 3690b57cec5SDimitry Andric // (note that this also saves floating point registers and V registers, 3700b57cec5SDimitry Andric // because part of VS is mapped to these registers) 3710b57cec5SDimitry Andric 372fe6060f1SDimitry Andric addi 4, 3, PPC64_OFFS_FP 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric// store VS register 3751ac55f4cSDimitry Andric#ifdef __LITTLE_ENDIAN__ 3761ac55f4cSDimitry Andric// For little-endian targets, we need a swap since stxvd2x will store the 3771ac55f4cSDimitry Andric// register in the incorrect doubleword order. 3781ac55f4cSDimitry Andric// FIXME: when supporting targets older than Power9 on LE is no longer required 3791ac55f4cSDimitry Andric// this can be changed to simply `stxv n, 16 * n(4)`. 3801ac55f4cSDimitry Andric#define PPC64_STVS(n) \ 3811ac55f4cSDimitry Andric xxswapd n, n ;\ 3821ac55f4cSDimitry Andric stxvd2x n, 0, 4 ;\ 3831ac55f4cSDimitry Andric addi 4, 4, 16 3841ac55f4cSDimitry Andric#else 3850b57cec5SDimitry Andric#define PPC64_STVS(n) \ 386fe6060f1SDimitry Andric stxvd2x n, 0, 4 ;\ 387fe6060f1SDimitry Andric addi 4, 4, 16 3881ac55f4cSDimitry Andric#endif 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric PPC64_STVS(0) 3910b57cec5SDimitry Andric PPC64_STVS(1) 3920b57cec5SDimitry Andric PPC64_STVS(2) 3930b57cec5SDimitry Andric PPC64_STVS(3) 3940b57cec5SDimitry Andric PPC64_STVS(4) 3950b57cec5SDimitry Andric PPC64_STVS(5) 3960b57cec5SDimitry Andric PPC64_STVS(6) 3970b57cec5SDimitry Andric PPC64_STVS(7) 3980b57cec5SDimitry Andric PPC64_STVS(8) 3990b57cec5SDimitry Andric PPC64_STVS(9) 4000b57cec5SDimitry Andric PPC64_STVS(10) 4010b57cec5SDimitry Andric PPC64_STVS(11) 4020b57cec5SDimitry Andric PPC64_STVS(12) 4030b57cec5SDimitry Andric PPC64_STVS(13) 4040b57cec5SDimitry Andric PPC64_STVS(14) 4050b57cec5SDimitry Andric PPC64_STVS(15) 4060b57cec5SDimitry Andric PPC64_STVS(16) 4070b57cec5SDimitry Andric PPC64_STVS(17) 4080b57cec5SDimitry Andric PPC64_STVS(18) 4090b57cec5SDimitry Andric PPC64_STVS(19) 4100b57cec5SDimitry Andric PPC64_STVS(20) 4110b57cec5SDimitry Andric PPC64_STVS(21) 4120b57cec5SDimitry Andric PPC64_STVS(22) 4130b57cec5SDimitry Andric PPC64_STVS(23) 4140b57cec5SDimitry Andric PPC64_STVS(24) 4150b57cec5SDimitry Andric PPC64_STVS(25) 4160b57cec5SDimitry Andric PPC64_STVS(26) 4170b57cec5SDimitry Andric PPC64_STVS(27) 4180b57cec5SDimitry Andric PPC64_STVS(28) 4190b57cec5SDimitry Andric PPC64_STVS(29) 4200b57cec5SDimitry Andric PPC64_STVS(30) 4210b57cec5SDimitry Andric PPC64_STVS(31) 4220b57cec5SDimitry Andric PPC64_STVS(32) 4230b57cec5SDimitry Andric PPC64_STVS(33) 4240b57cec5SDimitry Andric PPC64_STVS(34) 4250b57cec5SDimitry Andric PPC64_STVS(35) 4260b57cec5SDimitry Andric PPC64_STVS(36) 4270b57cec5SDimitry Andric PPC64_STVS(37) 4280b57cec5SDimitry Andric PPC64_STVS(38) 4290b57cec5SDimitry Andric PPC64_STVS(39) 4300b57cec5SDimitry Andric PPC64_STVS(40) 4310b57cec5SDimitry Andric PPC64_STVS(41) 4320b57cec5SDimitry Andric PPC64_STVS(42) 4330b57cec5SDimitry Andric PPC64_STVS(43) 4340b57cec5SDimitry Andric PPC64_STVS(44) 4350b57cec5SDimitry Andric PPC64_STVS(45) 4360b57cec5SDimitry Andric PPC64_STVS(46) 4370b57cec5SDimitry Andric PPC64_STVS(47) 4380b57cec5SDimitry Andric PPC64_STVS(48) 4390b57cec5SDimitry Andric PPC64_STVS(49) 4400b57cec5SDimitry Andric PPC64_STVS(50) 4410b57cec5SDimitry Andric PPC64_STVS(51) 4420b57cec5SDimitry Andric PPC64_STVS(52) 4430b57cec5SDimitry Andric PPC64_STVS(53) 4440b57cec5SDimitry Andric PPC64_STVS(54) 4450b57cec5SDimitry Andric PPC64_STVS(55) 4460b57cec5SDimitry Andric PPC64_STVS(56) 4470b57cec5SDimitry Andric PPC64_STVS(57) 4480b57cec5SDimitry Andric PPC64_STVS(58) 4490b57cec5SDimitry Andric PPC64_STVS(59) 4500b57cec5SDimitry Andric PPC64_STVS(60) 4510b57cec5SDimitry Andric PPC64_STVS(61) 4520b57cec5SDimitry Andric PPC64_STVS(62) 4530b57cec5SDimitry Andric PPC64_STVS(63) 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric#else 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric// store FP register 4580b57cec5SDimitry Andric#define PPC64_STF(n) \ 459fe6060f1SDimitry Andric stfd n, (PPC64_OFFS_FP + n * 16)(3) 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // save float registers 4620b57cec5SDimitry Andric PPC64_STF(0) 4630b57cec5SDimitry Andric PPC64_STF(1) 4640b57cec5SDimitry Andric PPC64_STF(2) 4650b57cec5SDimitry Andric PPC64_STF(3) 4660b57cec5SDimitry Andric PPC64_STF(4) 4670b57cec5SDimitry Andric PPC64_STF(5) 4680b57cec5SDimitry Andric PPC64_STF(6) 4690b57cec5SDimitry Andric PPC64_STF(7) 4700b57cec5SDimitry Andric PPC64_STF(8) 4710b57cec5SDimitry Andric PPC64_STF(9) 4720b57cec5SDimitry Andric PPC64_STF(10) 4730b57cec5SDimitry Andric PPC64_STF(11) 4740b57cec5SDimitry Andric PPC64_STF(12) 4750b57cec5SDimitry Andric PPC64_STF(13) 4760b57cec5SDimitry Andric PPC64_STF(14) 4770b57cec5SDimitry Andric PPC64_STF(15) 4780b57cec5SDimitry Andric PPC64_STF(16) 4790b57cec5SDimitry Andric PPC64_STF(17) 4800b57cec5SDimitry Andric PPC64_STF(18) 4810b57cec5SDimitry Andric PPC64_STF(19) 4820b57cec5SDimitry Andric PPC64_STF(20) 4830b57cec5SDimitry Andric PPC64_STF(21) 4840b57cec5SDimitry Andric PPC64_STF(22) 4850b57cec5SDimitry Andric PPC64_STF(23) 4860b57cec5SDimitry Andric PPC64_STF(24) 4870b57cec5SDimitry Andric PPC64_STF(25) 4880b57cec5SDimitry Andric PPC64_STF(26) 4890b57cec5SDimitry Andric PPC64_STF(27) 4900b57cec5SDimitry Andric PPC64_STF(28) 4910b57cec5SDimitry Andric PPC64_STF(29) 4920b57cec5SDimitry Andric PPC64_STF(30) 4930b57cec5SDimitry Andric PPC64_STF(31) 4940b57cec5SDimitry Andric 495e8d8bef9SDimitry Andric#if defined(__ALTIVEC__) 4960b57cec5SDimitry Andric // save vector registers 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric // Use 16-bytes below the stack pointer as an 4990b57cec5SDimitry Andric // aligned buffer to save each vector register. 5000b57cec5SDimitry Andric // Note that the stack pointer is always 16-byte aligned. 501fe6060f1SDimitry Andric subi 4, 1, 16 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric#define PPC64_STV_UNALIGNED(n) \ 504fe6060f1SDimitry Andric stvx n, 0, 4 ;\ 505fe6060f1SDimitry Andric ld 5, 0(4) ;\ 506fe6060f1SDimitry Andric std 5, (PPC64_OFFS_V + n * 16)(3) ;\ 507fe6060f1SDimitry Andric ld 5, 8(4) ;\ 508fe6060f1SDimitry Andric std 5, (PPC64_OFFS_V + n * 16 + 8)(3) 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric PPC64_STV_UNALIGNED(0) 5110b57cec5SDimitry Andric PPC64_STV_UNALIGNED(1) 5120b57cec5SDimitry Andric PPC64_STV_UNALIGNED(2) 5130b57cec5SDimitry Andric PPC64_STV_UNALIGNED(3) 5140b57cec5SDimitry Andric PPC64_STV_UNALIGNED(4) 5150b57cec5SDimitry Andric PPC64_STV_UNALIGNED(5) 5160b57cec5SDimitry Andric PPC64_STV_UNALIGNED(6) 5170b57cec5SDimitry Andric PPC64_STV_UNALIGNED(7) 5180b57cec5SDimitry Andric PPC64_STV_UNALIGNED(8) 5190b57cec5SDimitry Andric PPC64_STV_UNALIGNED(9) 5200b57cec5SDimitry Andric PPC64_STV_UNALIGNED(10) 5210b57cec5SDimitry Andric PPC64_STV_UNALIGNED(11) 5220b57cec5SDimitry Andric PPC64_STV_UNALIGNED(12) 5230b57cec5SDimitry Andric PPC64_STV_UNALIGNED(13) 5240b57cec5SDimitry Andric PPC64_STV_UNALIGNED(14) 5250b57cec5SDimitry Andric PPC64_STV_UNALIGNED(15) 5260b57cec5SDimitry Andric PPC64_STV_UNALIGNED(16) 5270b57cec5SDimitry Andric PPC64_STV_UNALIGNED(17) 5280b57cec5SDimitry Andric PPC64_STV_UNALIGNED(18) 5290b57cec5SDimitry Andric PPC64_STV_UNALIGNED(19) 5300b57cec5SDimitry Andric PPC64_STV_UNALIGNED(20) 5310b57cec5SDimitry Andric PPC64_STV_UNALIGNED(21) 5320b57cec5SDimitry Andric PPC64_STV_UNALIGNED(22) 5330b57cec5SDimitry Andric PPC64_STV_UNALIGNED(23) 5340b57cec5SDimitry Andric PPC64_STV_UNALIGNED(24) 5350b57cec5SDimitry Andric PPC64_STV_UNALIGNED(25) 5360b57cec5SDimitry Andric PPC64_STV_UNALIGNED(26) 5370b57cec5SDimitry Andric PPC64_STV_UNALIGNED(27) 5380b57cec5SDimitry Andric PPC64_STV_UNALIGNED(28) 5390b57cec5SDimitry Andric PPC64_STV_UNALIGNED(29) 5400b57cec5SDimitry Andric PPC64_STV_UNALIGNED(30) 5410b57cec5SDimitry Andric PPC64_STV_UNALIGNED(31) 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric#endif 544e8d8bef9SDimitry Andric#endif 5450b57cec5SDimitry Andric 546fe6060f1SDimitry Andric li 3, 0 // return UNW_ESUCCESS 5470b57cec5SDimitry Andric blr 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric 5501fd87a68SDimitry Andric#elif defined(__powerpc__) 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric// 5534f73ee07SDimitry Andric// extern int unw_getcontext(unw_context_t* thread_state) 5540b57cec5SDimitry Andric// 5550b57cec5SDimitry Andric// On entry: 5560b57cec5SDimitry Andric// thread_state pointer is in r3 5570b57cec5SDimitry Andric// 55881ad6265SDimitry Andric#if defined(_AIX) 55981ad6265SDimitry AndricDEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext) 56081ad6265SDimitry Andric#else 5610b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 56281ad6265SDimitry Andric#endif 563fe6060f1SDimitry Andric stw 0, 8(3) 564fe6060f1SDimitry Andric mflr 0 565fe6060f1SDimitry Andric stw 0, 0(3) // store lr as ssr0 566fe6060f1SDimitry Andric stw 1, 12(3) 5675f757f3fSDimitry Andric stw 4, 24(3) // Save r4 first since it will be used for fixing r2. 5685f757f3fSDimitry Andric#if defined(_AIX) 5695f757f3fSDimitry Andric // The TOC register (r2) was changed by the glue code if unw_getcontext 5705f757f3fSDimitry Andric // is called from a different module. Save the original TOC register 5715f757f3fSDimitry Andric // in the context if this is the case. 5725f757f3fSDimitry Andric mflr 4 5735f757f3fSDimitry Andric lwz 4, 0(4) // Get the instruction at the return address. 5745f757f3fSDimitry Andric xoris 0, 4, 0x8041 // Is it reloading the TOC register "lwz 2,20(1)"? 5755f757f3fSDimitry Andric cmplwi 0, 0x14 5765f757f3fSDimitry Andric bne 0, LnoR2Fix // No need to fix up r2 if it is not. 5775f757f3fSDimitry Andric lwz 2, 20(1) // Use the saved TOC register in the stack. 5785f757f3fSDimitry AndricLnoR2Fix: 5795f757f3fSDimitry Andric#endif 580fe6060f1SDimitry Andric stw 2, 16(3) 581fe6060f1SDimitry Andric stw 3, 20(3) 582fe6060f1SDimitry Andric stw 5, 28(3) 583fe6060f1SDimitry Andric stw 6, 32(3) 584fe6060f1SDimitry Andric stw 7, 36(3) 585fe6060f1SDimitry Andric stw 8, 40(3) 586fe6060f1SDimitry Andric stw 9, 44(3) 587fe6060f1SDimitry Andric stw 10, 48(3) 588fe6060f1SDimitry Andric stw 11, 52(3) 589fe6060f1SDimitry Andric stw 12, 56(3) 590fe6060f1SDimitry Andric stw 13, 60(3) 591fe6060f1SDimitry Andric stw 14, 64(3) 592fe6060f1SDimitry Andric stw 15, 68(3) 593fe6060f1SDimitry Andric stw 16, 72(3) 594fe6060f1SDimitry Andric stw 17, 76(3) 595fe6060f1SDimitry Andric stw 18, 80(3) 596fe6060f1SDimitry Andric stw 19, 84(3) 597fe6060f1SDimitry Andric stw 20, 88(3) 598fe6060f1SDimitry Andric stw 21, 92(3) 599fe6060f1SDimitry Andric stw 22, 96(3) 600fe6060f1SDimitry Andric stw 23,100(3) 601fe6060f1SDimitry Andric stw 24,104(3) 602fe6060f1SDimitry Andric stw 25,108(3) 603fe6060f1SDimitry Andric stw 26,112(3) 604fe6060f1SDimitry Andric stw 27,116(3) 605fe6060f1SDimitry Andric stw 28,120(3) 606fe6060f1SDimitry Andric stw 29,124(3) 607fe6060f1SDimitry Andric stw 30,128(3) 608fe6060f1SDimitry Andric stw 31,132(3) 6090b57cec5SDimitry Andric 610d781ede6SDimitry Andric#if defined(__ALTIVEC__) 6110b57cec5SDimitry Andric // save VRSave register 612fe6060f1SDimitry Andric mfspr 0, 256 613fe6060f1SDimitry Andric stw 0, 156(3) 614d781ede6SDimitry Andric#endif 6150b57cec5SDimitry Andric // save CR registers 616fe6060f1SDimitry Andric mfcr 0 617fe6060f1SDimitry Andric stw 0, 136(3) 6185f757f3fSDimitry Andric#if defined(_AIX) 6195f757f3fSDimitry Andric // LR value from the register is not used, initialize it to 0. 6205f757f3fSDimitry Andric li 0, 0 6215f757f3fSDimitry Andric stw 0, 144(3) 6225f757f3fSDimitry Andric#endif 6230b57cec5SDimitry Andric // save CTR register 624fe6060f1SDimitry Andric mfctr 0 625fe6060f1SDimitry Andric stw 0, 148(3) 6260b57cec5SDimitry Andric 627e8d8bef9SDimitry Andric#if !defined(__NO_FPRS__) 6280b57cec5SDimitry Andric // save float registers 629fe6060f1SDimitry Andric stfd 0, 160(3) 630fe6060f1SDimitry Andric stfd 1, 168(3) 631fe6060f1SDimitry Andric stfd 2, 176(3) 632fe6060f1SDimitry Andric stfd 3, 184(3) 633fe6060f1SDimitry Andric stfd 4, 192(3) 634fe6060f1SDimitry Andric stfd 5, 200(3) 635fe6060f1SDimitry Andric stfd 6, 208(3) 636fe6060f1SDimitry Andric stfd 7, 216(3) 637fe6060f1SDimitry Andric stfd 8, 224(3) 638fe6060f1SDimitry Andric stfd 9, 232(3) 639fe6060f1SDimitry Andric stfd 10,240(3) 640fe6060f1SDimitry Andric stfd 11,248(3) 641fe6060f1SDimitry Andric stfd 12,256(3) 642fe6060f1SDimitry Andric stfd 13,264(3) 643fe6060f1SDimitry Andric stfd 14,272(3) 644fe6060f1SDimitry Andric stfd 15,280(3) 645fe6060f1SDimitry Andric stfd 16,288(3) 646fe6060f1SDimitry Andric stfd 17,296(3) 647fe6060f1SDimitry Andric stfd 18,304(3) 648fe6060f1SDimitry Andric stfd 19,312(3) 649fe6060f1SDimitry Andric stfd 20,320(3) 650fe6060f1SDimitry Andric stfd 21,328(3) 651fe6060f1SDimitry Andric stfd 22,336(3) 652fe6060f1SDimitry Andric stfd 23,344(3) 653fe6060f1SDimitry Andric stfd 24,352(3) 654fe6060f1SDimitry Andric stfd 25,360(3) 655fe6060f1SDimitry Andric stfd 26,368(3) 656fe6060f1SDimitry Andric stfd 27,376(3) 657fe6060f1SDimitry Andric stfd 28,384(3) 658fe6060f1SDimitry Andric stfd 29,392(3) 659fe6060f1SDimitry Andric stfd 30,400(3) 660fe6060f1SDimitry Andric stfd 31,408(3) 661e8d8bef9SDimitry Andric#endif 6620b57cec5SDimitry Andric 663e8d8bef9SDimitry Andric#if defined(__ALTIVEC__) 6640b57cec5SDimitry Andric // save vector registers 6650b57cec5SDimitry Andric 666fe6060f1SDimitry Andric subi 4, 1, 16 667fe6060f1SDimitry Andric rlwinm 4, 4, 0, 0, 27 // mask low 4-bits 6680b57cec5SDimitry Andric // r4 is now a 16-byte aligned pointer into the red zone 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andric#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ 671fe6060f1SDimitry Andric stvx _vec, 0, 4 SEPARATOR \ 672fe6060f1SDimitry Andric lwz 5, 0(4) SEPARATOR \ 673fe6060f1SDimitry Andric stw 5, _offset(3) SEPARATOR \ 674fe6060f1SDimitry Andric lwz 5, 4(4) SEPARATOR \ 675fe6060f1SDimitry Andric stw 5, _offset+4(3) SEPARATOR \ 676fe6060f1SDimitry Andric lwz 5, 8(4) SEPARATOR \ 677fe6060f1SDimitry Andric stw 5, _offset+8(3) SEPARATOR \ 678fe6060f1SDimitry Andric lwz 5, 12(4) SEPARATOR \ 679fe6060f1SDimitry Andric stw 5, _offset+12(3) 6800b57cec5SDimitry Andric 681fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 0, 424+0x000) 682fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 1, 424+0x010) 683fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 2, 424+0x020) 684fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 3, 424+0x030) 685fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 4, 424+0x040) 686fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 5, 424+0x050) 687fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 6, 424+0x060) 688fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 7, 424+0x070) 689fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 8, 424+0x080) 690fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED( 9, 424+0x090) 691fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(10, 424+0x0A0) 692fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(11, 424+0x0B0) 693fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(12, 424+0x0C0) 694fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(13, 424+0x0D0) 695fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(14, 424+0x0E0) 696fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(15, 424+0x0F0) 697fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(16, 424+0x100) 698fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(17, 424+0x110) 699fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(18, 424+0x120) 700fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(19, 424+0x130) 701fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(20, 424+0x140) 702fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(21, 424+0x150) 703fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(22, 424+0x160) 704fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(23, 424+0x170) 705fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(24, 424+0x180) 706fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(25, 424+0x190) 707fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(26, 424+0x1A0) 708fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(27, 424+0x1B0) 709fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(28, 424+0x1C0) 710fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(29, 424+0x1D0) 711fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(30, 424+0x1E0) 712fe6060f1SDimitry Andric SAVE_VECTOR_UNALIGNED(31, 424+0x1F0) 713e8d8bef9SDimitry Andric#endif 7140b57cec5SDimitry Andric 715fe6060f1SDimitry Andric li 3, 0 // return UNW_ESUCCESS 7160b57cec5SDimitry Andric blr 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric 7195ffd83dbSDimitry Andric#elif defined(__aarch64__) 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric// 7220b57cec5SDimitry Andric// extern int __unw_getcontext(unw_context_t* thread_state) 7230b57cec5SDimitry Andric// 7240b57cec5SDimitry Andric// On entry: 7250b57cec5SDimitry Andric// thread_state pointer is in x0 7260b57cec5SDimitry Andric// 7270b57cec5SDimitry Andric .p2align 2 7280b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 7290b57cec5SDimitry Andric stp x0, x1, [x0, #0x000] 7300b57cec5SDimitry Andric stp x2, x3, [x0, #0x010] 7310b57cec5SDimitry Andric stp x4, x5, [x0, #0x020] 7320b57cec5SDimitry Andric stp x6, x7, [x0, #0x030] 7330b57cec5SDimitry Andric stp x8, x9, [x0, #0x040] 7340b57cec5SDimitry Andric stp x10,x11, [x0, #0x050] 7350b57cec5SDimitry Andric stp x12,x13, [x0, #0x060] 7360b57cec5SDimitry Andric stp x14,x15, [x0, #0x070] 7370b57cec5SDimitry Andric stp x16,x17, [x0, #0x080] 7380b57cec5SDimitry Andric stp x18,x19, [x0, #0x090] 7390b57cec5SDimitry Andric stp x20,x21, [x0, #0x0A0] 7400b57cec5SDimitry Andric stp x22,x23, [x0, #0x0B0] 7410b57cec5SDimitry Andric stp x24,x25, [x0, #0x0C0] 7420b57cec5SDimitry Andric stp x26,x27, [x0, #0x0D0] 7430b57cec5SDimitry Andric stp x28,x29, [x0, #0x0E0] 7440b57cec5SDimitry Andric str x30, [x0, #0x0F0] 7450b57cec5SDimitry Andric mov x1,sp 7460b57cec5SDimitry Andric str x1, [x0, #0x0F8] 7470b57cec5SDimitry Andric str x30, [x0, #0x100] // store return address as pc 7480b57cec5SDimitry Andric // skip cpsr 7490b57cec5SDimitry Andric stp d0, d1, [x0, #0x110] 7500b57cec5SDimitry Andric stp d2, d3, [x0, #0x120] 7510b57cec5SDimitry Andric stp d4, d5, [x0, #0x130] 7520b57cec5SDimitry Andric stp d6, d7, [x0, #0x140] 7530b57cec5SDimitry Andric stp d8, d9, [x0, #0x150] 7540b57cec5SDimitry Andric stp d10,d11, [x0, #0x160] 7550b57cec5SDimitry Andric stp d12,d13, [x0, #0x170] 7560b57cec5SDimitry Andric stp d14,d15, [x0, #0x180] 7570b57cec5SDimitry Andric stp d16,d17, [x0, #0x190] 7580b57cec5SDimitry Andric stp d18,d19, [x0, #0x1A0] 7590b57cec5SDimitry Andric stp d20,d21, [x0, #0x1B0] 7600b57cec5SDimitry Andric stp d22,d23, [x0, #0x1C0] 7610b57cec5SDimitry Andric stp d24,d25, [x0, #0x1D0] 7620b57cec5SDimitry Andric stp d26,d27, [x0, #0x1E0] 7630b57cec5SDimitry Andric stp d28,d29, [x0, #0x1F0] 7640b57cec5SDimitry Andric str d30, [x0, #0x200] 7650b57cec5SDimitry Andric str d31, [x0, #0x208] 7660b57cec5SDimitry Andric mov x0, #0 // return UNW_ESUCCESS 7670b57cec5SDimitry Andric ret 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric#elif defined(__arm__) && !defined(__APPLE__) 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric#if !defined(__ARM_ARCH_ISA_ARM) 7720b57cec5SDimitry Andric#if (__ARM_ARCH_ISA_THUMB == 2) 7730b57cec5SDimitry Andric .syntax unified 7740b57cec5SDimitry Andric#endif 7750b57cec5SDimitry Andric .thumb 7760b57cec5SDimitry Andric#endif 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric@ 7790b57cec5SDimitry Andric@ extern int __unw_getcontext(unw_context_t* thread_state) 7800b57cec5SDimitry Andric@ 7810b57cec5SDimitry Andric@ On entry: 7820b57cec5SDimitry Andric@ thread_state pointer is in r0 7830b57cec5SDimitry Andric@ 7840b57cec5SDimitry Andric@ Per EHABI #4.7 this only saves the core integer registers. 7850b57cec5SDimitry Andric@ EHABI #7.4.5 notes that in general all VRS registers should be restored 7860b57cec5SDimitry Andric@ however this is very hard to do for VFP registers because it is unknown 7870b57cec5SDimitry Andric@ to the library how many registers are implemented by the architecture. 7880b57cec5SDimitry Andric@ Instead, VFP registers are demand saved by logic external to __unw_getcontext. 7890b57cec5SDimitry Andric@ 7900b57cec5SDimitry Andric .p2align 2 7910b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 7920b57cec5SDimitry Andric#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1 7930b57cec5SDimitry Andric stm r0!, {r0-r7} 7940b57cec5SDimitry Andric mov r1, r8 7950b57cec5SDimitry Andric mov r2, r9 7960b57cec5SDimitry Andric mov r3, r10 7970b57cec5SDimitry Andric stm r0!, {r1-r3} 7980b57cec5SDimitry Andric mov r1, r11 7990b57cec5SDimitry Andric mov r2, sp 8000b57cec5SDimitry Andric mov r3, lr 8010b57cec5SDimitry Andric str r1, [r0, #0] @ r11 8020b57cec5SDimitry Andric @ r12 does not need storing, it it the intra-procedure-call scratch register 8030b57cec5SDimitry Andric str r2, [r0, #8] @ sp 8040b57cec5SDimitry Andric str r3, [r0, #12] @ lr 8050b57cec5SDimitry Andric str r3, [r0, #16] @ store return address as pc 8060b57cec5SDimitry Andric @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. 8070b57cec5SDimitry Andric @ It is safe to use here though because we are about to return, and cpsr is 8080b57cec5SDimitry Andric @ not expected to be preserved. 8090b57cec5SDimitry Andric movs r0, #0 @ return UNW_ESUCCESS 8100b57cec5SDimitry Andric#else 8110b57cec5SDimitry Andric @ 32bit thumb-2 restrictions for stm: 8120b57cec5SDimitry Andric @ . the sp (r13) cannot be in the list 8130b57cec5SDimitry Andric @ . the pc (r15) cannot be in the list in an STM instruction 8140b57cec5SDimitry Andric stm r0, {r0-r12} 8150b57cec5SDimitry Andric str sp, [r0, #52] 8160b57cec5SDimitry Andric str lr, [r0, #56] 8170b57cec5SDimitry Andric str lr, [r0, #60] @ store return address as pc 8180b57cec5SDimitry Andric mov r0, #0 @ return UNW_ESUCCESS 8190b57cec5SDimitry Andric#endif 8200b57cec5SDimitry Andric JMP(lr) 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric@ 8230b57cec5SDimitry Andric@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) 8240b57cec5SDimitry Andric@ 8250b57cec5SDimitry Andric@ On entry: 8260b57cec5SDimitry Andric@ values pointer is in r0 8270b57cec5SDimitry Andric@ 8280b57cec5SDimitry Andric .p2align 2 8290b57cec5SDimitry Andric#if defined(__ELF__) 8300b57cec5SDimitry Andric .fpu vfpv3-d16 8310b57cec5SDimitry Andric#endif 8320b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv) 8330b57cec5SDimitry Andric vstmia r0, {d0-d15} 8340b57cec5SDimitry Andric JMP(lr) 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric@ 8370b57cec5SDimitry Andric@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) 8380b57cec5SDimitry Andric@ 8390b57cec5SDimitry Andric@ On entry: 8400b57cec5SDimitry Andric@ values pointer is in r0 8410b57cec5SDimitry Andric@ 8420b57cec5SDimitry Andric .p2align 2 8430b57cec5SDimitry Andric#if defined(__ELF__) 8440b57cec5SDimitry Andric .fpu vfpv3-d16 8450b57cec5SDimitry Andric#endif 8460b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv) 8470b57cec5SDimitry Andric vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia 8480b57cec5SDimitry Andric JMP(lr) 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric@ 8510b57cec5SDimitry Andric@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) 8520b57cec5SDimitry Andric@ 8530b57cec5SDimitry Andric@ On entry: 8540b57cec5SDimitry Andric@ values pointer is in r0 8550b57cec5SDimitry Andric@ 8560b57cec5SDimitry Andric .p2align 2 8570b57cec5SDimitry Andric#if defined(__ELF__) 8580b57cec5SDimitry Andric .fpu vfpv3 8590b57cec5SDimitry Andric#endif 8600b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv) 8610b57cec5SDimitry Andric @ VFP and iwMMX instructions are only available when compiling with the flags 8620b57cec5SDimitry Andric @ that enable them. We do not want to do that in the library (because we do not 8630b57cec5SDimitry Andric @ want the compiler to generate instructions that access those) but this is 8640b57cec5SDimitry Andric @ only accessed if the personality routine needs these registers. Use of 8650b57cec5SDimitry Andric @ these registers implies they are, actually, available on the target, so 8660b57cec5SDimitry Andric @ it's ok to execute. 8670b57cec5SDimitry Andric @ So, generate the instructions using the corresponding coprocessor mnemonic. 8680b57cec5SDimitry Andric vstmia r0, {d16-d31} 8690b57cec5SDimitry Andric JMP(lr) 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric#if defined(_LIBUNWIND_ARM_WMMX) 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric@ 8740b57cec5SDimitry Andric@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) 8750b57cec5SDimitry Andric@ 8760b57cec5SDimitry Andric@ On entry: 8770b57cec5SDimitry Andric@ values pointer is in r0 8780b57cec5SDimitry Andric@ 8790b57cec5SDimitry Andric .p2align 2 8800b57cec5SDimitry Andric#if defined(__ELF__) 8810b57cec5SDimitry Andric .arch armv5te 8820b57cec5SDimitry Andric#endif 8830b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv) 8840b57cec5SDimitry Andric stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8 8850b57cec5SDimitry Andric stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8 8860b57cec5SDimitry Andric stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8 8870b57cec5SDimitry Andric stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8 8880b57cec5SDimitry Andric stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8 8890b57cec5SDimitry Andric stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8 8900b57cec5SDimitry Andric stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8 8910b57cec5SDimitry Andric stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8 8920b57cec5SDimitry Andric stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8 8930b57cec5SDimitry Andric stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8 8940b57cec5SDimitry Andric stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8 8950b57cec5SDimitry Andric stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8 8960b57cec5SDimitry Andric stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8 8970b57cec5SDimitry Andric stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8 8980b57cec5SDimitry Andric stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8 8990b57cec5SDimitry Andric stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8 9000b57cec5SDimitry Andric JMP(lr) 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric@ 9030b57cec5SDimitry Andric@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) 9040b57cec5SDimitry Andric@ 9050b57cec5SDimitry Andric@ On entry: 9060b57cec5SDimitry Andric@ values pointer is in r0 9070b57cec5SDimitry Andric@ 9080b57cec5SDimitry Andric .p2align 2 9090b57cec5SDimitry Andric#if defined(__ELF__) 9100b57cec5SDimitry Andric .arch armv5te 9110b57cec5SDimitry Andric#endif 9120b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) 9130b57cec5SDimitry Andric stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4 9140b57cec5SDimitry Andric stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4 9150b57cec5SDimitry Andric stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4 9160b57cec5SDimitry Andric stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 9170b57cec5SDimitry Andric JMP(lr) 9180b57cec5SDimitry Andric 9190b57cec5SDimitry Andric#endif 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric#elif defined(__or1k__) 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric# 9240b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 9250b57cec5SDimitry Andric# 9260b57cec5SDimitry Andric# On entry: 9270b57cec5SDimitry Andric# thread_state pointer is in r3 9280b57cec5SDimitry Andric# 9290b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 9300b57cec5SDimitry Andric l.sw 0(r3), r0 9310b57cec5SDimitry Andric l.sw 4(r3), r1 9320b57cec5SDimitry Andric l.sw 8(r3), r2 9330b57cec5SDimitry Andric l.sw 12(r3), r3 9340b57cec5SDimitry Andric l.sw 16(r3), r4 9350b57cec5SDimitry Andric l.sw 20(r3), r5 9360b57cec5SDimitry Andric l.sw 24(r3), r6 9370b57cec5SDimitry Andric l.sw 28(r3), r7 9380b57cec5SDimitry Andric l.sw 32(r3), r8 9390b57cec5SDimitry Andric l.sw 36(r3), r9 9400b57cec5SDimitry Andric l.sw 40(r3), r10 9410b57cec5SDimitry Andric l.sw 44(r3), r11 9420b57cec5SDimitry Andric l.sw 48(r3), r12 9430b57cec5SDimitry Andric l.sw 52(r3), r13 9440b57cec5SDimitry Andric l.sw 56(r3), r14 9450b57cec5SDimitry Andric l.sw 60(r3), r15 9460b57cec5SDimitry Andric l.sw 64(r3), r16 9470b57cec5SDimitry Andric l.sw 68(r3), r17 9480b57cec5SDimitry Andric l.sw 72(r3), r18 9490b57cec5SDimitry Andric l.sw 76(r3), r19 9500b57cec5SDimitry Andric l.sw 80(r3), r20 9510b57cec5SDimitry Andric l.sw 84(r3), r21 9520b57cec5SDimitry Andric l.sw 88(r3), r22 9530b57cec5SDimitry Andric l.sw 92(r3), r23 9540b57cec5SDimitry Andric l.sw 96(r3), r24 9550b57cec5SDimitry Andric l.sw 100(r3), r25 9560b57cec5SDimitry Andric l.sw 104(r3), r26 9570b57cec5SDimitry Andric l.sw 108(r3), r27 9580b57cec5SDimitry Andric l.sw 112(r3), r28 9590b57cec5SDimitry Andric l.sw 116(r3), r29 9600b57cec5SDimitry Andric l.sw 120(r3), r30 9610b57cec5SDimitry Andric l.sw 124(r3), r31 9620b57cec5SDimitry Andric # store ra to pc 9630b57cec5SDimitry Andric l.sw 128(r3), r9 9640b57cec5SDimitry Andric # zero epcr 9650b57cec5SDimitry Andric l.sw 132(r3), r0 9660b57cec5SDimitry Andric 9675ffd83dbSDimitry Andric#elif defined(__hexagon__) 9685ffd83dbSDimitry Andric# 9695ffd83dbSDimitry Andric# extern int unw_getcontext(unw_context_t* thread_state) 9705ffd83dbSDimitry Andric# 9715ffd83dbSDimitry Andric# On entry: 9725ffd83dbSDimitry Andric# thread_state pointer is in r0 9735ffd83dbSDimitry Andric# 9745ffd83dbSDimitry Andric#define OFFSET(offset) (offset/4) 9755ffd83dbSDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 9765ffd83dbSDimitry Andric memw(r0+#32) = r8 9775ffd83dbSDimitry Andric memw(r0+#36) = r9 9785ffd83dbSDimitry Andric memw(r0+#40) = r10 9795ffd83dbSDimitry Andric memw(r0+#44) = r11 9805ffd83dbSDimitry Andric 9815ffd83dbSDimitry Andric memw(r0+#48) = r12 9825ffd83dbSDimitry Andric memw(r0+#52) = r13 9835ffd83dbSDimitry Andric memw(r0+#56) = r14 9845ffd83dbSDimitry Andric memw(r0+#60) = r15 9855ffd83dbSDimitry Andric 9865ffd83dbSDimitry Andric memw(r0+#64) = r16 9875ffd83dbSDimitry Andric memw(r0+#68) = r17 9885ffd83dbSDimitry Andric memw(r0+#72) = r18 9895ffd83dbSDimitry Andric memw(r0+#76) = r19 9905ffd83dbSDimitry Andric 9915ffd83dbSDimitry Andric memw(r0+#80) = r20 9925ffd83dbSDimitry Andric memw(r0+#84) = r21 9935ffd83dbSDimitry Andric memw(r0+#88) = r22 9945ffd83dbSDimitry Andric memw(r0+#92) = r23 9955ffd83dbSDimitry Andric 9965ffd83dbSDimitry Andric memw(r0+#96) = r24 9975ffd83dbSDimitry Andric memw(r0+#100) = r25 9985ffd83dbSDimitry Andric memw(r0+#104) = r26 9995ffd83dbSDimitry Andric memw(r0+#108) = r27 10005ffd83dbSDimitry Andric 10015ffd83dbSDimitry Andric memw(r0+#112) = r28 10025ffd83dbSDimitry Andric memw(r0+#116) = r29 10035ffd83dbSDimitry Andric memw(r0+#120) = r30 10045ffd83dbSDimitry Andric memw(r0+#124) = r31 10055ffd83dbSDimitry Andric r1 = c4 // Predicate register 10065ffd83dbSDimitry Andric memw(r0+#128) = r1 10075ffd83dbSDimitry Andric r1 = memw(r30) // *FP == Saved FP 10085ffd83dbSDimitry Andric r1 = r31 10095ffd83dbSDimitry Andric memw(r0+#132) = r1 10105ffd83dbSDimitry Andric 10115ffd83dbSDimitry Andric jumpr r31 10125ffd83dbSDimitry Andric 1013d56accc7SDimitry Andric#elif defined(__sparc__) && defined(__arch64__) 1014d56accc7SDimitry Andric 1015d56accc7SDimitry Andric# 1016d56accc7SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 1017d56accc7SDimitry Andric# 1018d56accc7SDimitry Andric# On entry: 1019d56accc7SDimitry Andric# thread_state pointer is in %o0 1020d56accc7SDimitry Andric# 1021d56accc7SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1022d56accc7SDimitry Andric .register %g2, #scratch 1023d56accc7SDimitry Andric .register %g3, #scratch 1024d56accc7SDimitry Andric .register %g6, #scratch 1025d56accc7SDimitry Andric .register %g7, #scratch 1026d56accc7SDimitry Andric stx %g1, [%o0 + 0x08] 1027d56accc7SDimitry Andric stx %g2, [%o0 + 0x10] 1028d56accc7SDimitry Andric stx %g3, [%o0 + 0x18] 1029d56accc7SDimitry Andric stx %g4, [%o0 + 0x20] 1030d56accc7SDimitry Andric stx %g5, [%o0 + 0x28] 1031d56accc7SDimitry Andric stx %g6, [%o0 + 0x30] 1032d56accc7SDimitry Andric stx %g7, [%o0 + 0x38] 1033d56accc7SDimitry Andric stx %o0, [%o0 + 0x40] 1034d56accc7SDimitry Andric stx %o1, [%o0 + 0x48] 1035d56accc7SDimitry Andric stx %o2, [%o0 + 0x50] 1036d56accc7SDimitry Andric stx %o3, [%o0 + 0x58] 1037d56accc7SDimitry Andric stx %o4, [%o0 + 0x60] 1038d56accc7SDimitry Andric stx %o5, [%o0 + 0x68] 1039d56accc7SDimitry Andric stx %o6, [%o0 + 0x70] 1040d56accc7SDimitry Andric stx %o7, [%o0 + 0x78] 1041d56accc7SDimitry Andric stx %l0, [%o0 + 0x80] 1042d56accc7SDimitry Andric stx %l1, [%o0 + 0x88] 1043d56accc7SDimitry Andric stx %l2, [%o0 + 0x90] 1044d56accc7SDimitry Andric stx %l3, [%o0 + 0x98] 1045d56accc7SDimitry Andric stx %l4, [%o0 + 0xa0] 1046d56accc7SDimitry Andric stx %l5, [%o0 + 0xa8] 1047d56accc7SDimitry Andric stx %l6, [%o0 + 0xb0] 1048d56accc7SDimitry Andric stx %l7, [%o0 + 0xb8] 1049d56accc7SDimitry Andric stx %i0, [%o0 + 0xc0] 1050d56accc7SDimitry Andric stx %i1, [%o0 + 0xc8] 1051d56accc7SDimitry Andric stx %i2, [%o0 + 0xd0] 1052d56accc7SDimitry Andric stx %i3, [%o0 + 0xd8] 1053d56accc7SDimitry Andric stx %i4, [%o0 + 0xe0] 1054d56accc7SDimitry Andric stx %i5, [%o0 + 0xe8] 1055d56accc7SDimitry Andric stx %i6, [%o0 + 0xf0] 1056d56accc7SDimitry Andric stx %i7, [%o0 + 0xf8] 1057d56accc7SDimitry Andric 1058d56accc7SDimitry Andric # save StackGhost cookie 1059d56accc7SDimitry Andric mov %i7, %g4 1060d56accc7SDimitry Andric save %sp, -176, %sp 1061d56accc7SDimitry Andric # register window flush necessary even without StackGhost 1062d56accc7SDimitry Andric flushw 1063d56accc7SDimitry Andric restore 1064d56accc7SDimitry Andric ldx [%sp + 2047 + 0x78], %g5 1065d56accc7SDimitry Andric xor %g4, %g5, %g4 1066d56accc7SDimitry Andric stx %g4, [%o0 + 0x100] 1067d56accc7SDimitry Andric retl 1068d56accc7SDimitry Andric # return UNW_ESUCCESS 1069d56accc7SDimitry Andric clr %o0 1070d56accc7SDimitry Andric 10710b57cec5SDimitry Andric#elif defined(__sparc__) 10720b57cec5SDimitry Andric 10730b57cec5SDimitry Andric# 10740b57cec5SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 10750b57cec5SDimitry Andric# 10760b57cec5SDimitry Andric# On entry: 10770b57cec5SDimitry Andric# thread_state pointer is in o0 10780b57cec5SDimitry Andric# 10790b57cec5SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 10800b57cec5SDimitry Andric ta 3 10810b57cec5SDimitry Andric add %o7, 8, %o7 10820b57cec5SDimitry Andric std %g0, [%o0 + 0] 10830b57cec5SDimitry Andric std %g2, [%o0 + 8] 10840b57cec5SDimitry Andric std %g4, [%o0 + 16] 10850b57cec5SDimitry Andric std %g6, [%o0 + 24] 10860b57cec5SDimitry Andric std %o0, [%o0 + 32] 10870b57cec5SDimitry Andric std %o2, [%o0 + 40] 10880b57cec5SDimitry Andric std %o4, [%o0 + 48] 10890b57cec5SDimitry Andric std %o6, [%o0 + 56] 10900b57cec5SDimitry Andric std %l0, [%o0 + 64] 10910b57cec5SDimitry Andric std %l2, [%o0 + 72] 10920b57cec5SDimitry Andric std %l4, [%o0 + 80] 10930b57cec5SDimitry Andric std %l6, [%o0 + 88] 10940b57cec5SDimitry Andric std %i0, [%o0 + 96] 10950b57cec5SDimitry Andric std %i2, [%o0 + 104] 10960b57cec5SDimitry Andric std %i4, [%o0 + 112] 10970b57cec5SDimitry Andric std %i6, [%o0 + 120] 10980b57cec5SDimitry Andric jmp %o7 10990b57cec5SDimitry Andric clr %o0 // return UNW_ESUCCESS 1100480093f4SDimitry Andric 1101fe6060f1SDimitry Andric#elif defined(__riscv) 1102480093f4SDimitry Andric 1103480093f4SDimitry Andric# 1104480093f4SDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 1105480093f4SDimitry Andric# 1106480093f4SDimitry Andric# On entry: 1107480093f4SDimitry Andric# thread_state pointer is in a0 1108480093f4SDimitry Andric# 1109480093f4SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1110fe6060f1SDimitry Andric ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc 1111bdd1243dSDimitry Andric .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 1112bdd1243dSDimitry Andric ISTORE x\i, (RISCV_ISIZE * \i)(a0) 1113bdd1243dSDimitry Andric .endr 1114480093f4SDimitry Andric 1115fe6060f1SDimitry Andric# if defined(__riscv_flen) 1116bdd1243dSDimitry Andric .irp i,FROM_0_TO_31 1117bdd1243dSDimitry Andric FSTORE f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0) 1118bdd1243dSDimitry Andric .endr 1119480093f4SDimitry Andric# endif 1120480093f4SDimitry Andric 1121480093f4SDimitry Andric li a0, 0 // return UNW_ESUCCESS 1122480093f4SDimitry Andric ret // jump to ra 112381ad6265SDimitry Andric 112481ad6265SDimitry Andric#elif defined(__s390x__) 112581ad6265SDimitry Andric 112681ad6265SDimitry Andric// 112781ad6265SDimitry Andric// extern int __unw_getcontext(unw_context_t* thread_state) 112881ad6265SDimitry Andric// 112981ad6265SDimitry Andric// On entry: 113081ad6265SDimitry Andric// thread_state pointer is in r2 113181ad6265SDimitry Andric// 113281ad6265SDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 113381ad6265SDimitry Andric 113481ad6265SDimitry Andric // Save GPRs 113581ad6265SDimitry Andric stmg %r0, %r15, 16(%r2) 113681ad6265SDimitry Andric 113781ad6265SDimitry Andric // Save PSWM 113881ad6265SDimitry Andric epsw %r0, %r1 113981ad6265SDimitry Andric stm %r0, %r1, 0(%r2) 114081ad6265SDimitry Andric 114181ad6265SDimitry Andric // Store return address as PSWA 114281ad6265SDimitry Andric stg %r14, 8(%r2) 114381ad6265SDimitry Andric 114481ad6265SDimitry Andric // Save FPRs 1145bdd1243dSDimitry Andric .irp i,FROM_0_TO_15 1146bdd1243dSDimitry Andric std %f\i, (144+8*\i)(%r2) 1147bdd1243dSDimitry Andric .endr 114881ad6265SDimitry Andric 114981ad6265SDimitry Andric // Return UNW_ESUCCESS 115081ad6265SDimitry Andric lghi %r2, 0 115181ad6265SDimitry Andric br %r14 115281ad6265SDimitry Andric 1153bdd1243dSDimitry Andric#elif defined(__loongarch__) && __loongarch_grlen == 64 1154bdd1243dSDimitry Andric 1155bdd1243dSDimitry Andric# 1156bdd1243dSDimitry Andric# extern int __unw_getcontext(unw_context_t* thread_state) 1157bdd1243dSDimitry Andric# 1158bdd1243dSDimitry Andric# On entry: 1159bdd1243dSDimitry Andric# thread_state pointer is in $a0($r4) 1160bdd1243dSDimitry Andric# 1161bdd1243dSDimitry AndricDEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) 1162bdd1243dSDimitry Andric .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 1163bdd1243dSDimitry Andric st.d $r\i, $a0, (8*\i) 1164bdd1243dSDimitry Andric .endr 1165bdd1243dSDimitry Andric st.d $r1, $a0, (8 * 32) // store $ra to pc 1166bdd1243dSDimitry Andric 1167bdd1243dSDimitry Andric# if __loongarch_frlen == 64 1168bdd1243dSDimitry Andric .irp i,FROM_0_TO_31 1169bdd1243dSDimitry Andric fst.d $f\i, $a0, (8 * 33 + 8 * \i) 1170bdd1243dSDimitry Andric .endr 1171bdd1243dSDimitry Andric# endif 1172bdd1243dSDimitry Andric 1173bdd1243dSDimitry Andric move $a0, $zero // UNW_ESUCCESS 1174bdd1243dSDimitry Andric jr $ra 1175bdd1243dSDimitry Andric 11760b57cec5SDimitry Andric#endif 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric WEAK_ALIAS(__unw_getcontext, unw_getcontext) 11790b57cec5SDimitry Andric 1180*0fca6ea1SDimitry Andric#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */ 11810b57cec5SDimitry Andric 11820b57cec5SDimitry AndricNO_EXEC_STACK_DIRECTIVE 1183