Path: blob/main/contrib/llvm-project/libunwind/src/UnwindRegistersSave.S
96309 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "assembly.h"910#define FROM_0_TO_15 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,1511#define FROM_16_TO_31 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,311213#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,3114#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,631516#if defined(_AIX)17.toc18#else19.text20#endif2122#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__)2324#if defined(__i386__)2526#27# extern int __unw_getcontext(unw_context_t* thread_state)28#29# On entry:30# + +31# +-----------------------+32# + thread_state pointer +33# +-----------------------+34# + return address +35# +-----------------------+ <-- SP36# + +37#38DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)3940_LIBUNWIND_CET_ENDBR41push %eax42movl 8(%esp), %eax43movl %ebx, 4(%eax)44movl %ecx, 8(%eax)45movl %edx, 12(%eax)46movl %edi, 16(%eax)47movl %esi, 20(%eax)48movl %ebp, 24(%eax)49movl %esp, %edx50addl $8, %edx51movl %edx, 28(%eax) # store what sp was at call site as esp52# skip ss53# skip eflags54movl 4(%esp), %edx55movl %edx, 40(%eax) # store return address as eip56# skip cs57# skip ds58# skip es59# skip fs60# skip gs61movl (%esp), %edx62movl %edx, (%eax) # store original eax63popl %eax64xorl %eax, %eax # return UNW_ESUCCESS65ret6667#elif defined(__x86_64__)6869#70# extern int __unw_getcontext(unw_context_t* thread_state)71#72# On entry:73# thread_state pointer is in rdi74#75DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)76#if defined(_WIN64)77#define PTR %rcx78#define TMP %rdx79#else80#define PTR %rdi81#define TMP %rsi82#endif8384_LIBUNWIND_CET_ENDBR85movq %rax, (PTR)86movq %rbx, 8(PTR)87movq %rcx, 16(PTR)88movq %rdx, 24(PTR)89movq %rdi, 32(PTR)90movq %rsi, 40(PTR)91movq %rbp, 48(PTR)92movq %rsp, 56(PTR)93addq $8, 56(PTR)94movq %r8, 64(PTR)95movq %r9, 72(PTR)96movq %r10, 80(PTR)97movq %r11, 88(PTR)98movq %r12, 96(PTR)99movq %r13,104(PTR)100movq %r14,112(PTR)101movq %r15,120(PTR)102movq (%rsp),TMP103movq TMP,128(PTR) # store return address as rip104# skip rflags105# skip cs106# skip fs107# skip gs108109#if defined(_WIN64)110movdqu %xmm0,176(PTR)111movdqu %xmm1,192(PTR)112movdqu %xmm2,208(PTR)113movdqu %xmm3,224(PTR)114movdqu %xmm4,240(PTR)115movdqu %xmm5,256(PTR)116movdqu %xmm6,272(PTR)117movdqu %xmm7,288(PTR)118movdqu %xmm8,304(PTR)119movdqu %xmm9,320(PTR)120movdqu %xmm10,336(PTR)121movdqu %xmm11,352(PTR)122movdqu %xmm12,368(PTR)123movdqu %xmm13,384(PTR)124movdqu %xmm14,400(PTR)125movdqu %xmm15,416(PTR)126#endif127xorl %eax, %eax # return UNW_ESUCCESS128ret129130#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32131132#133# extern int __unw_getcontext(unw_context_t* thread_state)134#135# On entry:136# thread_state pointer is in a0 ($4)137#138DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)139.set push140.set noat141.set noreorder142.set nomacro143sw $1, (4 * 1)($4)144sw $2, (4 * 2)($4)145sw $3, (4 * 3)($4)146sw $4, (4 * 4)($4)147sw $5, (4 * 5)($4)148sw $6, (4 * 6)($4)149sw $7, (4 * 7)($4)150sw $8, (4 * 8)($4)151sw $9, (4 * 9)($4)152sw $10, (4 * 10)($4)153sw $11, (4 * 11)($4)154sw $12, (4 * 12)($4)155sw $13, (4 * 13)($4)156sw $14, (4 * 14)($4)157sw $15, (4 * 15)($4)158sw $16, (4 * 16)($4)159sw $17, (4 * 17)($4)160sw $18, (4 * 18)($4)161sw $19, (4 * 19)($4)162sw $20, (4 * 20)($4)163sw $21, (4 * 21)($4)164sw $22, (4 * 22)($4)165sw $23, (4 * 23)($4)166sw $24, (4 * 24)($4)167sw $25, (4 * 25)($4)168sw $26, (4 * 26)($4)169sw $27, (4 * 27)($4)170sw $28, (4 * 28)($4)171sw $29, (4 * 29)($4)172sw $30, (4 * 30)($4)173sw $31, (4 * 31)($4)174# Store return address to pc175sw $31, (4 * 32)($4)176#if __mips_isa_rev < 6177# hi and lo178mfhi $8179sw $8, (4 * 33)($4)180mflo $8181sw $8, (4 * 34)($4)182#endif183#ifdef __mips_hard_float184#if __mips_fpr != 64185sdc1 $f0, (4 * 36 + 8 * 0)($4)186sdc1 $f2, (4 * 36 + 8 * 2)($4)187sdc1 $f4, (4 * 36 + 8 * 4)($4)188sdc1 $f6, (4 * 36 + 8 * 6)($4)189sdc1 $f8, (4 * 36 + 8 * 8)($4)190sdc1 $f10, (4 * 36 + 8 * 10)($4)191sdc1 $f12, (4 * 36 + 8 * 12)($4)192sdc1 $f14, (4 * 36 + 8 * 14)($4)193sdc1 $f16, (4 * 36 + 8 * 16)($4)194sdc1 $f18, (4 * 36 + 8 * 18)($4)195sdc1 $f20, (4 * 36 + 8 * 20)($4)196sdc1 $f22, (4 * 36 + 8 * 22)($4)197sdc1 $f24, (4 * 36 + 8 * 24)($4)198sdc1 $f26, (4 * 36 + 8 * 26)($4)199sdc1 $f28, (4 * 36 + 8 * 28)($4)200sdc1 $f30, (4 * 36 + 8 * 30)($4)201#else202sdc1 $f0, (4 * 36 + 8 * 0)($4)203sdc1 $f1, (4 * 36 + 8 * 1)($4)204sdc1 $f2, (4 * 36 + 8 * 2)($4)205sdc1 $f3, (4 * 36 + 8 * 3)($4)206sdc1 $f4, (4 * 36 + 8 * 4)($4)207sdc1 $f5, (4 * 36 + 8 * 5)($4)208sdc1 $f6, (4 * 36 + 8 * 6)($4)209sdc1 $f7, (4 * 36 + 8 * 7)($4)210sdc1 $f8, (4 * 36 + 8 * 8)($4)211sdc1 $f9, (4 * 36 + 8 * 9)($4)212sdc1 $f10, (4 * 36 + 8 * 10)($4)213sdc1 $f11, (4 * 36 + 8 * 11)($4)214sdc1 $f12, (4 * 36 + 8 * 12)($4)215sdc1 $f13, (4 * 36 + 8 * 13)($4)216sdc1 $f14, (4 * 36 + 8 * 14)($4)217sdc1 $f15, (4 * 36 + 8 * 15)($4)218sdc1 $f16, (4 * 36 + 8 * 16)($4)219sdc1 $f17, (4 * 36 + 8 * 17)($4)220sdc1 $f18, (4 * 36 + 8 * 18)($4)221sdc1 $f19, (4 * 36 + 8 * 19)($4)222sdc1 $f20, (4 * 36 + 8 * 20)($4)223sdc1 $f21, (4 * 36 + 8 * 21)($4)224sdc1 $f22, (4 * 36 + 8 * 22)($4)225sdc1 $f23, (4 * 36 + 8 * 23)($4)226sdc1 $f24, (4 * 36 + 8 * 24)($4)227sdc1 $f25, (4 * 36 + 8 * 25)($4)228sdc1 $f26, (4 * 36 + 8 * 26)($4)229sdc1 $f27, (4 * 36 + 8 * 27)($4)230sdc1 $f28, (4 * 36 + 8 * 28)($4)231sdc1 $f29, (4 * 36 + 8 * 29)($4)232sdc1 $f30, (4 * 36 + 8 * 30)($4)233sdc1 $f31, (4 * 36 + 8 * 31)($4)234#endif235#endif236jr $31237# return UNW_ESUCCESS238or $2, $0, $0239.set pop240241#elif defined(__mips64)242243#244# extern int __unw_getcontext(unw_context_t* thread_state)245#246# On entry:247# thread_state pointer is in a0 ($4)248#249DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)250.set push251.set noat252.set noreorder253.set nomacro254.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,31255sd $\i, (8 * \i)($4)256.endr257# Store return address to pc258sd $31, (8 * 32)($4)259#if __mips_isa_rev < 6260# hi and lo261mfhi $8262sd $8, (8 * 33)($4)263mflo $8264sd $8, (8 * 34)($4)265#endif266#ifdef __mips_hard_float267.irp i,FROM_0_TO_31268sdc1 $f\i, (280+8*\i)($4)269.endr270#endif271jr $31272# return UNW_ESUCCESS273or $2, $0, $0274.set pop275276# elif defined(__mips__)277278#279# extern int __unw_getcontext(unw_context_t* thread_state)280#281# Just trap for the time being.282DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)283teq $0, $0284285#elif defined(__powerpc64__)286287//288// extern int __unw_getcontext(unw_context_t* thread_state)289//290// On entry:291// thread_state pointer is in r3292//293#if defined(_AIX)294DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)295#else296DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)297#endif298// store register (GPR)299#define PPC64_STR(n) \300std n, (8 * (n + 2))(3)301302// save GPRs303PPC64_STR(0)304mflr 0305std 0, PPC64_OFFS_SRR0(3) // store lr as ssr0306PPC64_STR(1)307PPC64_STR(4) // Save r4 first since it will be used for fixing r2.308#if defined(_AIX)309// The TOC register (r2) was changed by the glue code if unw_getcontext310// is called from a different module. Save the original TOC register311// in the context if this is the case.312mflr 4313lwz 4, 0(4) // Get the first instruction at the return address.314xoris 0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?315cmplwi 0, 0x28316bne 0, LnoR2Fix // No need to fix up r2 if it is not.317ld 2, 40(1) // Use the saved TOC register in the stack.318LnoR2Fix:319#endif320PPC64_STR(2)321PPC64_STR(3)322PPC64_STR(5)323PPC64_STR(6)324PPC64_STR(7)325PPC64_STR(8)326PPC64_STR(9)327PPC64_STR(10)328PPC64_STR(11)329PPC64_STR(12)330PPC64_STR(13)331PPC64_STR(14)332PPC64_STR(15)333PPC64_STR(16)334PPC64_STR(17)335PPC64_STR(18)336PPC64_STR(19)337PPC64_STR(20)338PPC64_STR(21)339PPC64_STR(22)340PPC64_STR(23)341PPC64_STR(24)342PPC64_STR(25)343PPC64_STR(26)344PPC64_STR(27)345PPC64_STR(28)346PPC64_STR(29)347PPC64_STR(30)348PPC64_STR(31)349350mfcr 0351std 0, PPC64_OFFS_CR(3)352mfxer 0353std 0, PPC64_OFFS_XER(3)354#if defined(_AIX)355// LR value saved from the register is not used, initialize it to 0.356li 0, 0357#else358mflr 0359#endif360std 0, PPC64_OFFS_LR(3)361mfctr 0362std 0, PPC64_OFFS_CTR(3)363mfvrsave 0364std 0, PPC64_OFFS_VRSAVE(3)365366#if defined(__VSX__)367// save VS registers368// (note that this also saves floating point registers and V registers,369// because part of VS is mapped to these registers)370371addi 4, 3, PPC64_OFFS_FP372373// store VS register374#ifdef __LITTLE_ENDIAN__375// For little-endian targets, we need a swap since stxvd2x will store the376// register in the incorrect doubleword order.377// FIXME: when supporting targets older than Power9 on LE is no longer required378// this can be changed to simply `stxv n, 16 * n(4)`.379#define PPC64_STVS(n) \380xxswapd n, n ;\381stxvd2x n, 0, 4 ;\382addi 4, 4, 16383#else384#define PPC64_STVS(n) \385stxvd2x n, 0, 4 ;\386addi 4, 4, 16387#endif388389PPC64_STVS(0)390PPC64_STVS(1)391PPC64_STVS(2)392PPC64_STVS(3)393PPC64_STVS(4)394PPC64_STVS(5)395PPC64_STVS(6)396PPC64_STVS(7)397PPC64_STVS(8)398PPC64_STVS(9)399PPC64_STVS(10)400PPC64_STVS(11)401PPC64_STVS(12)402PPC64_STVS(13)403PPC64_STVS(14)404PPC64_STVS(15)405PPC64_STVS(16)406PPC64_STVS(17)407PPC64_STVS(18)408PPC64_STVS(19)409PPC64_STVS(20)410PPC64_STVS(21)411PPC64_STVS(22)412PPC64_STVS(23)413PPC64_STVS(24)414PPC64_STVS(25)415PPC64_STVS(26)416PPC64_STVS(27)417PPC64_STVS(28)418PPC64_STVS(29)419PPC64_STVS(30)420PPC64_STVS(31)421PPC64_STVS(32)422PPC64_STVS(33)423PPC64_STVS(34)424PPC64_STVS(35)425PPC64_STVS(36)426PPC64_STVS(37)427PPC64_STVS(38)428PPC64_STVS(39)429PPC64_STVS(40)430PPC64_STVS(41)431PPC64_STVS(42)432PPC64_STVS(43)433PPC64_STVS(44)434PPC64_STVS(45)435PPC64_STVS(46)436PPC64_STVS(47)437PPC64_STVS(48)438PPC64_STVS(49)439PPC64_STVS(50)440PPC64_STVS(51)441PPC64_STVS(52)442PPC64_STVS(53)443PPC64_STVS(54)444PPC64_STVS(55)445PPC64_STVS(56)446PPC64_STVS(57)447PPC64_STVS(58)448PPC64_STVS(59)449PPC64_STVS(60)450PPC64_STVS(61)451PPC64_STVS(62)452PPC64_STVS(63)453454#else455456// store FP register457#define PPC64_STF(n) \458stfd n, (PPC64_OFFS_FP + n * 16)(3)459460// save float registers461PPC64_STF(0)462PPC64_STF(1)463PPC64_STF(2)464PPC64_STF(3)465PPC64_STF(4)466PPC64_STF(5)467PPC64_STF(6)468PPC64_STF(7)469PPC64_STF(8)470PPC64_STF(9)471PPC64_STF(10)472PPC64_STF(11)473PPC64_STF(12)474PPC64_STF(13)475PPC64_STF(14)476PPC64_STF(15)477PPC64_STF(16)478PPC64_STF(17)479PPC64_STF(18)480PPC64_STF(19)481PPC64_STF(20)482PPC64_STF(21)483PPC64_STF(22)484PPC64_STF(23)485PPC64_STF(24)486PPC64_STF(25)487PPC64_STF(26)488PPC64_STF(27)489PPC64_STF(28)490PPC64_STF(29)491PPC64_STF(30)492PPC64_STF(31)493494#if defined(__ALTIVEC__)495// save vector registers496497// Use 16-bytes below the stack pointer as an498// aligned buffer to save each vector register.499// Note that the stack pointer is always 16-byte aligned.500subi 4, 1, 16501502#define PPC64_STV_UNALIGNED(n) \503stvx n, 0, 4 ;\504ld 5, 0(4) ;\505std 5, (PPC64_OFFS_V + n * 16)(3) ;\506ld 5, 8(4) ;\507std 5, (PPC64_OFFS_V + n * 16 + 8)(3)508509PPC64_STV_UNALIGNED(0)510PPC64_STV_UNALIGNED(1)511PPC64_STV_UNALIGNED(2)512PPC64_STV_UNALIGNED(3)513PPC64_STV_UNALIGNED(4)514PPC64_STV_UNALIGNED(5)515PPC64_STV_UNALIGNED(6)516PPC64_STV_UNALIGNED(7)517PPC64_STV_UNALIGNED(8)518PPC64_STV_UNALIGNED(9)519PPC64_STV_UNALIGNED(10)520PPC64_STV_UNALIGNED(11)521PPC64_STV_UNALIGNED(12)522PPC64_STV_UNALIGNED(13)523PPC64_STV_UNALIGNED(14)524PPC64_STV_UNALIGNED(15)525PPC64_STV_UNALIGNED(16)526PPC64_STV_UNALIGNED(17)527PPC64_STV_UNALIGNED(18)528PPC64_STV_UNALIGNED(19)529PPC64_STV_UNALIGNED(20)530PPC64_STV_UNALIGNED(21)531PPC64_STV_UNALIGNED(22)532PPC64_STV_UNALIGNED(23)533PPC64_STV_UNALIGNED(24)534PPC64_STV_UNALIGNED(25)535PPC64_STV_UNALIGNED(26)536PPC64_STV_UNALIGNED(27)537PPC64_STV_UNALIGNED(28)538PPC64_STV_UNALIGNED(29)539PPC64_STV_UNALIGNED(30)540PPC64_STV_UNALIGNED(31)541542#endif543#endif544545li 3, 0 // return UNW_ESUCCESS546blr547548549#elif defined(__powerpc__)550551//552// extern int unw_getcontext(unw_context_t* thread_state)553//554// On entry:555// thread_state pointer is in r3556//557#if defined(_AIX)558DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(__unw_getcontext, unw_getcontext)559#else560DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)561#endif562stw 0, 8(3)563mflr 0564stw 0, 0(3) // store lr as ssr0565stw 1, 12(3)566stw 4, 24(3) // Save r4 first since it will be used for fixing r2.567#if defined(_AIX)568// The TOC register (r2) was changed by the glue code if unw_getcontext569// is called from a different module. Save the original TOC register570// in the context if this is the case.571mflr 4572lwz 4, 0(4) // Get the instruction at the return address.573xoris 0, 4, 0x8041 // Is it reloading the TOC register "lwz 2,20(1)"?574cmplwi 0, 0x14575bne 0, LnoR2Fix // No need to fix up r2 if it is not.576lwz 2, 20(1) // Use the saved TOC register in the stack.577LnoR2Fix:578#endif579stw 2, 16(3)580stw 3, 20(3)581stw 5, 28(3)582stw 6, 32(3)583stw 7, 36(3)584stw 8, 40(3)585stw 9, 44(3)586stw 10, 48(3)587stw 11, 52(3)588stw 12, 56(3)589stw 13, 60(3)590stw 14, 64(3)591stw 15, 68(3)592stw 16, 72(3)593stw 17, 76(3)594stw 18, 80(3)595stw 19, 84(3)596stw 20, 88(3)597stw 21, 92(3)598stw 22, 96(3)599stw 23,100(3)600stw 24,104(3)601stw 25,108(3)602stw 26,112(3)603stw 27,116(3)604stw 28,120(3)605stw 29,124(3)606stw 30,128(3)607stw 31,132(3)608609#if defined(__ALTIVEC__)610// save VRSave register611mfspr 0, 256612stw 0, 156(3)613#endif614// save CR registers615mfcr 0616stw 0, 136(3)617#if defined(_AIX)618// LR value from the register is not used, initialize it to 0.619li 0, 0620stw 0, 144(3)621#endif622// save CTR register623mfctr 0624stw 0, 148(3)625626#if !defined(__NO_FPRS__)627// save float registers628stfd 0, 160(3)629stfd 1, 168(3)630stfd 2, 176(3)631stfd 3, 184(3)632stfd 4, 192(3)633stfd 5, 200(3)634stfd 6, 208(3)635stfd 7, 216(3)636stfd 8, 224(3)637stfd 9, 232(3)638stfd 10,240(3)639stfd 11,248(3)640stfd 12,256(3)641stfd 13,264(3)642stfd 14,272(3)643stfd 15,280(3)644stfd 16,288(3)645stfd 17,296(3)646stfd 18,304(3)647stfd 19,312(3)648stfd 20,320(3)649stfd 21,328(3)650stfd 22,336(3)651stfd 23,344(3)652stfd 24,352(3)653stfd 25,360(3)654stfd 26,368(3)655stfd 27,376(3)656stfd 28,384(3)657stfd 29,392(3)658stfd 30,400(3)659stfd 31,408(3)660#endif661662#if defined(__ALTIVEC__)663// save vector registers664665subi 4, 1, 16666rlwinm 4, 4, 0, 0, 27 // mask low 4-bits667// r4 is now a 16-byte aligned pointer into the red zone668669#define SAVE_VECTOR_UNALIGNED(_vec, _offset) \670stvx _vec, 0, 4 SEPARATOR \671lwz 5, 0(4) SEPARATOR \672stw 5, _offset(3) SEPARATOR \673lwz 5, 4(4) SEPARATOR \674stw 5, _offset+4(3) SEPARATOR \675lwz 5, 8(4) SEPARATOR \676stw 5, _offset+8(3) SEPARATOR \677lwz 5, 12(4) SEPARATOR \678stw 5, _offset+12(3)679680SAVE_VECTOR_UNALIGNED( 0, 424+0x000)681SAVE_VECTOR_UNALIGNED( 1, 424+0x010)682SAVE_VECTOR_UNALIGNED( 2, 424+0x020)683SAVE_VECTOR_UNALIGNED( 3, 424+0x030)684SAVE_VECTOR_UNALIGNED( 4, 424+0x040)685SAVE_VECTOR_UNALIGNED( 5, 424+0x050)686SAVE_VECTOR_UNALIGNED( 6, 424+0x060)687SAVE_VECTOR_UNALIGNED( 7, 424+0x070)688SAVE_VECTOR_UNALIGNED( 8, 424+0x080)689SAVE_VECTOR_UNALIGNED( 9, 424+0x090)690SAVE_VECTOR_UNALIGNED(10, 424+0x0A0)691SAVE_VECTOR_UNALIGNED(11, 424+0x0B0)692SAVE_VECTOR_UNALIGNED(12, 424+0x0C0)693SAVE_VECTOR_UNALIGNED(13, 424+0x0D0)694SAVE_VECTOR_UNALIGNED(14, 424+0x0E0)695SAVE_VECTOR_UNALIGNED(15, 424+0x0F0)696SAVE_VECTOR_UNALIGNED(16, 424+0x100)697SAVE_VECTOR_UNALIGNED(17, 424+0x110)698SAVE_VECTOR_UNALIGNED(18, 424+0x120)699SAVE_VECTOR_UNALIGNED(19, 424+0x130)700SAVE_VECTOR_UNALIGNED(20, 424+0x140)701SAVE_VECTOR_UNALIGNED(21, 424+0x150)702SAVE_VECTOR_UNALIGNED(22, 424+0x160)703SAVE_VECTOR_UNALIGNED(23, 424+0x170)704SAVE_VECTOR_UNALIGNED(24, 424+0x180)705SAVE_VECTOR_UNALIGNED(25, 424+0x190)706SAVE_VECTOR_UNALIGNED(26, 424+0x1A0)707SAVE_VECTOR_UNALIGNED(27, 424+0x1B0)708SAVE_VECTOR_UNALIGNED(28, 424+0x1C0)709SAVE_VECTOR_UNALIGNED(29, 424+0x1D0)710SAVE_VECTOR_UNALIGNED(30, 424+0x1E0)711SAVE_VECTOR_UNALIGNED(31, 424+0x1F0)712#endif713714li 3, 0 // return UNW_ESUCCESS715blr716717718#elif defined(__aarch64__)719720//721// extern int __unw_getcontext(unw_context_t* thread_state)722//723// On entry:724// thread_state pointer is in x0725//726.p2align 2727DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)728stp x0, x1, [x0, #0x000]729stp x2, x3, [x0, #0x010]730stp x4, x5, [x0, #0x020]731stp x6, x7, [x0, #0x030]732stp x8, x9, [x0, #0x040]733stp x10,x11, [x0, #0x050]734stp x12,x13, [x0, #0x060]735stp x14,x15, [x0, #0x070]736stp x16,x17, [x0, #0x080]737stp x18,x19, [x0, #0x090]738stp x20,x21, [x0, #0x0A0]739stp x22,x23, [x0, #0x0B0]740stp x24,x25, [x0, #0x0C0]741stp x26,x27, [x0, #0x0D0]742stp x28,x29, [x0, #0x0E0]743str x30, [x0, #0x0F0]744mov x1,sp745str x1, [x0, #0x0F8]746str x30, [x0, #0x100] // store return address as pc747// skip cpsr748stp d0, d1, [x0, #0x110]749stp d2, d3, [x0, #0x120]750stp d4, d5, [x0, #0x130]751stp d6, d7, [x0, #0x140]752stp d8, d9, [x0, #0x150]753stp d10,d11, [x0, #0x160]754stp d12,d13, [x0, #0x170]755stp d14,d15, [x0, #0x180]756stp d16,d17, [x0, #0x190]757stp d18,d19, [x0, #0x1A0]758stp d20,d21, [x0, #0x1B0]759stp d22,d23, [x0, #0x1C0]760stp d24,d25, [x0, #0x1D0]761stp d26,d27, [x0, #0x1E0]762stp d28,d29, [x0, #0x1F0]763str d30, [x0, #0x200]764str d31, [x0, #0x208]765mov x0, #0 // return UNW_ESUCCESS766ret767768#elif defined(__arm__) && !defined(__APPLE__)769770#if !defined(__ARM_ARCH_ISA_ARM)771#if (__ARM_ARCH_ISA_THUMB == 2)772.syntax unified773#endif774.thumb775#endif776777@778@ extern int __unw_getcontext(unw_context_t* thread_state)779@780@ On entry:781@ thread_state pointer is in r0782@783@ Per EHABI #4.7 this only saves the core integer registers.784@ EHABI #7.4.5 notes that in general all VRS registers should be restored785@ however this is very hard to do for VFP registers because it is unknown786@ to the library how many registers are implemented by the architecture.787@ Instead, VFP registers are demand saved by logic external to __unw_getcontext.788@789.p2align 2790DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)791#if !defined(__ARM_ARCH_ISA_ARM) && __ARM_ARCH_ISA_THUMB == 1792stm r0!, {r0-r7}793mov r1, r8794mov r2, r9795mov r3, r10796stm r0!, {r1-r3}797mov r1, r11798mov r2, sp799mov r3, lr800str r1, [r0, #0] @ r11801@ r12 does not need storing, it it the intra-procedure-call scratch register802str r2, [r0, #8] @ sp803str r3, [r0, #12] @ lr804str r3, [r0, #16] @ store return address as pc805@ T1 does not have a non-cpsr-clobbering register-zeroing instruction.806@ It is safe to use here though because we are about to return, and cpsr is807@ not expected to be preserved.808movs r0, #0 @ return UNW_ESUCCESS809#else810@ 32bit thumb-2 restrictions for stm:811@ . the sp (r13) cannot be in the list812@ . the pc (r15) cannot be in the list in an STM instruction813stm r0, {r0-r12}814str sp, [r0, #52]815str lr, [r0, #56]816str lr, [r0, #60] @ store return address as pc817mov r0, #0 @ return UNW_ESUCCESS818#endif819JMP(lr)820821@822@ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values)823@824@ On entry:825@ values pointer is in r0826@827.p2align 2828#if defined(__ELF__)829.fpu vfpv3-d16830#endif831DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPv)832vstmia r0, {d0-d15}833JMP(lr)834835@836@ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values)837@838@ On entry:839@ values pointer is in r0840@841.p2align 2842#if defined(__ELF__)843.fpu vfpv3-d16844#endif845DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPv)846vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia847JMP(lr)848849@850@ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values)851@852@ On entry:853@ values pointer is in r0854@855.p2align 2856#if defined(__ELF__)857.fpu vfpv3858#endif859DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPv)860@ VFP and iwMMX instructions are only available when compiling with the flags861@ that enable them. We do not want to do that in the library (because we do not862@ want the compiler to generate instructions that access those) but this is863@ only accessed if the personality routine needs these registers. Use of864@ these registers implies they are, actually, available on the target, so865@ it's ok to execute.866@ So, generate the instructions using the corresponding coprocessor mnemonic.867vstmia r0, {d16-d31}868JMP(lr)869870#if defined(_LIBUNWIND_ARM_WMMX)871872@873@ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values)874@875@ On entry:876@ values pointer is in r0877@878.p2align 2879#if defined(__ELF__)880.arch armv5te881#endif882DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPv)883stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8884stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8885stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8886stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8887stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8888stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8889stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8890stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8891stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8892stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8893stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8894stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8895stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8896stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8897stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8898stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8899JMP(lr)900901@902@ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values)903@904@ On entry:905@ values pointer is in r0906@907.p2align 2908#if defined(__ELF__)909.arch armv5te910#endif911DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj)912stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4913stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4914stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4915stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4916JMP(lr)917918#endif919920#elif defined(__or1k__)921922#923# extern int __unw_getcontext(unw_context_t* thread_state)924#925# On entry:926# thread_state pointer is in r3927#928DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)929l.sw 0(r3), r0930l.sw 4(r3), r1931l.sw 8(r3), r2932l.sw 12(r3), r3933l.sw 16(r3), r4934l.sw 20(r3), r5935l.sw 24(r3), r6936l.sw 28(r3), r7937l.sw 32(r3), r8938l.sw 36(r3), r9939l.sw 40(r3), r10940l.sw 44(r3), r11941l.sw 48(r3), r12942l.sw 52(r3), r13943l.sw 56(r3), r14944l.sw 60(r3), r15945l.sw 64(r3), r16946l.sw 68(r3), r17947l.sw 72(r3), r18948l.sw 76(r3), r19949l.sw 80(r3), r20950l.sw 84(r3), r21951l.sw 88(r3), r22952l.sw 92(r3), r23953l.sw 96(r3), r24954l.sw 100(r3), r25955l.sw 104(r3), r26956l.sw 108(r3), r27957l.sw 112(r3), r28958l.sw 116(r3), r29959l.sw 120(r3), r30960l.sw 124(r3), r31961# store ra to pc962l.sw 128(r3), r9963# zero epcr964l.sw 132(r3), r0965966#elif defined(__hexagon__)967#968# extern int unw_getcontext(unw_context_t* thread_state)969#970# On entry:971# thread_state pointer is in r0972#973#define OFFSET(offset) (offset/4)974DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)975memw(r0+#32) = r8976memw(r0+#36) = r9977memw(r0+#40) = r10978memw(r0+#44) = r11979980memw(r0+#48) = r12981memw(r0+#52) = r13982memw(r0+#56) = r14983memw(r0+#60) = r15984985memw(r0+#64) = r16986memw(r0+#68) = r17987memw(r0+#72) = r18988memw(r0+#76) = r19989990memw(r0+#80) = r20991memw(r0+#84) = r21992memw(r0+#88) = r22993memw(r0+#92) = r23994995memw(r0+#96) = r24996memw(r0+#100) = r25997memw(r0+#104) = r26998memw(r0+#108) = r279991000memw(r0+#112) = r281001memw(r0+#116) = r291002memw(r0+#120) = r301003memw(r0+#124) = r311004r1 = c4 // Predicate register1005memw(r0+#128) = r11006r1 = memw(r30) // *FP == Saved FP1007r1 = r311008memw(r0+#132) = r110091010jumpr r3110111012#elif defined(__sparc__) && defined(__arch64__)10131014#1015# extern int __unw_getcontext(unw_context_t* thread_state)1016#1017# On entry:1018# thread_state pointer is in %o01019#1020DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)1021.register %g2, #scratch1022.register %g3, #scratch1023.register %g6, #scratch1024.register %g7, #scratch1025stx %g1, [%o0 + 0x08]1026stx %g2, [%o0 + 0x10]1027stx %g3, [%o0 + 0x18]1028stx %g4, [%o0 + 0x20]1029stx %g5, [%o0 + 0x28]1030stx %g6, [%o0 + 0x30]1031stx %g7, [%o0 + 0x38]1032stx %o0, [%o0 + 0x40]1033stx %o1, [%o0 + 0x48]1034stx %o2, [%o0 + 0x50]1035stx %o3, [%o0 + 0x58]1036stx %o4, [%o0 + 0x60]1037stx %o5, [%o0 + 0x68]1038stx %o6, [%o0 + 0x70]1039stx %o7, [%o0 + 0x78]1040stx %l0, [%o0 + 0x80]1041stx %l1, [%o0 + 0x88]1042stx %l2, [%o0 + 0x90]1043stx %l3, [%o0 + 0x98]1044stx %l4, [%o0 + 0xa0]1045stx %l5, [%o0 + 0xa8]1046stx %l6, [%o0 + 0xb0]1047stx %l7, [%o0 + 0xb8]1048stx %i0, [%o0 + 0xc0]1049stx %i1, [%o0 + 0xc8]1050stx %i2, [%o0 + 0xd0]1051stx %i3, [%o0 + 0xd8]1052stx %i4, [%o0 + 0xe0]1053stx %i5, [%o0 + 0xe8]1054stx %i6, [%o0 + 0xf0]1055stx %i7, [%o0 + 0xf8]10561057# save StackGhost cookie1058mov %i7, %g41059save %sp, -176, %sp1060# register window flush necessary even without StackGhost1061flushw1062restore1063ldx [%sp + 2047 + 0x78], %g51064xor %g4, %g5, %g41065stx %g4, [%o0 + 0x100]1066retl1067# return UNW_ESUCCESS1068clr %o010691070#elif defined(__sparc__)10711072#1073# extern int __unw_getcontext(unw_context_t* thread_state)1074#1075# On entry:1076# thread_state pointer is in o01077#1078DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)1079ta 31080add %o7, 8, %o71081std %g0, [%o0 + 0]1082std %g2, [%o0 + 8]1083std %g4, [%o0 + 16]1084std %g6, [%o0 + 24]1085std %o0, [%o0 + 32]1086std %o2, [%o0 + 40]1087std %o4, [%o0 + 48]1088std %o6, [%o0 + 56]1089std %l0, [%o0 + 64]1090std %l2, [%o0 + 72]1091std %l4, [%o0 + 80]1092std %l6, [%o0 + 88]1093std %i0, [%o0 + 96]1094std %i2, [%o0 + 104]1095std %i4, [%o0 + 112]1096std %i6, [%o0 + 120]1097jmp %o71098clr %o0 // return UNW_ESUCCESS10991100#elif defined(__riscv)11011102#1103# extern int __unw_getcontext(unw_context_t* thread_state)1104#1105# On entry:1106# thread_state pointer is in a01107#1108DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)1109ISTORE x1, (RISCV_ISIZE * 0)(a0) // store ra as pc1110.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,311111ISTORE x\i, (RISCV_ISIZE * \i)(a0)1112.endr11131114# if defined(__riscv_flen)1115.irp i,FROM_0_TO_311116FSTORE f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0)1117.endr1118# endif11191120li a0, 0 // return UNW_ESUCCESS1121ret // jump to ra11221123#elif defined(__s390x__)11241125//1126// extern int __unw_getcontext(unw_context_t* thread_state)1127//1128// On entry:1129// thread_state pointer is in r21130//1131DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)11321133// Save GPRs1134stmg %r0, %r15, 16(%r2)11351136// Save PSWM1137epsw %r0, %r11138stm %r0, %r1, 0(%r2)11391140// Store return address as PSWA1141stg %r14, 8(%r2)11421143// Save FPRs1144.irp i,FROM_0_TO_151145std %f\i, (144+8*\i)(%r2)1146.endr11471148// Return UNW_ESUCCESS1149lghi %r2, 01150br %r1411511152#elif defined(__loongarch__) && __loongarch_grlen == 6411531154#1155# extern int __unw_getcontext(unw_context_t* thread_state)1156#1157# On entry:1158# thread_state pointer is in $a0($r4)1159#1160DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)1161.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,311162st.d $r\i, $a0, (8*\i)1163.endr1164st.d $r1, $a0, (8 * 32) // store $ra to pc11651166# if __loongarch_frlen == 641167.irp i,FROM_0_TO_311168fst.d $f\i, $a0, (8 * 33 + 8 * \i)1169.endr1170# endif11711172move $a0, $zero // UNW_ESUCCESS1173jr $ra11741175#endif11761177WEAK_ALIAS(__unw_getcontext, unw_getcontext)11781179#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__wasm__) */11801181NO_EXEC_STACK_DIRECTIVE118211831184