Index: head/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S =================================================================== --- head/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S (revision 335369) +++ head/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S (revision 335370) @@ -1,731 +1,764 @@ //===-------------------- UnwindRegistersRestore.S ------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "assembly.h" .text #if defined(__i386__) DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv) # # void libunwind::Registers_x86::jumpto() # # On entry: # + + # +-----------------------+ # + thread_state pointer + # +-----------------------+ # + return address + # +-----------------------+ <-- SP # + + movl 4(%esp), %eax # set up eax and ret on new stack location movl 28(%eax), %edx # edx holds new stack pointer subl $8,%edx movl %edx, 28(%eax) movl 0(%eax), %ebx movl %ebx, 0(%edx) movl 40(%eax), %ebx movl %ebx, 4(%edx) # we now have ret and eax pushed onto where new stack will be # restore all registers movl 4(%eax), %ebx movl 8(%eax), %ecx movl 12(%eax), %edx movl 16(%eax), %edi movl 20(%eax), %esi movl 24(%eax), %ebp movl 28(%eax), %esp # skip ss # skip eflags pop %eax # eax was already pushed on new stack ret # eip was already pushed on new stack # skip cs # skip ds # skip es # skip fs # skip gs #elif defined(__x86_64__) DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv) # # void libunwind::Registers_x86_64::jumpto() # # On entry, thread_state pointer is in rdi movq 56(%rdi), %rax # rax holds new stack pointer subq $16, %rax movq %rax, 56(%rdi) movq 32(%rdi), %rbx # store new rdi on new stack movq %rbx, 0(%rax) movq 128(%rdi), %rbx # store new rip on new stack movq %rbx, 8(%rax) # restore all registers movq 0(%rdi), %rax movq 8(%rdi), %rbx movq 16(%rdi), %rcx movq 24(%rdi), %rdx # restore rdi later movq 40(%rdi), %rsi movq 48(%rdi), %rbp # restore rsp later movq 64(%rdi), %r8 movq 72(%rdi), %r9 movq 80(%rdi), %r10 movq 88(%rdi), %r11 movq 96(%rdi), %r12 movq 104(%rdi), %r13 movq 112(%rdi), %r14 movq 120(%rdi), %r15 # skip rflags # skip cs # skip fs # skip gs movq 56(%rdi), %rsp # cut back rsp to new location pop %rdi # rdi was saved here earlier ret # rip was saved here #elif defined(__ppc__) DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv) ; ; void libunwind::Registers_ppc::jumpto() ; ; On entry: ; thread_state pointer is in r3 ; ; restore integral registerrs ; skip r0 for now ; skip r1 for now lwz r2, 16(r3) ; skip r3 for now ; skip r4 for now ; skip r5 for now lwz r6, 32(r3) lwz r7, 36(r3) lwz r8, 40(r3) lwz r9, 44(r3) lwz r10, 48(r3) lwz r11, 52(r3) lwz r12, 56(r3) lwz r13, 60(r3) lwz r14, 64(r3) lwz r15, 68(r3) lwz r16, 72(r3) lwz r17, 76(r3) lwz r18, 80(r3) lwz r19, 84(r3) lwz r20, 88(r3) lwz r21, 92(r3) lwz r22, 96(r3) lwz r23,100(r3) lwz r24,104(r3) lwz r25,108(r3) lwz r26,112(r3) lwz r27,116(r3) lwz r28,120(r3) lwz r29,124(r3) lwz r30,128(r3) lwz r31,132(r3) ; restore float registers lfd f0, 160(r3) lfd f1, 168(r3) lfd f2, 176(r3) lfd f3, 184(r3) lfd f4, 192(r3) lfd f5, 200(r3) lfd f6, 208(r3) lfd f7, 216(r3) lfd f8, 224(r3) lfd f9, 232(r3) lfd f10,240(r3) lfd f11,248(r3) lfd f12,256(r3) lfd f13,264(r3) lfd f14,272(r3) lfd f15,280(r3) lfd f16,288(r3) lfd f17,296(r3) lfd f18,304(r3) lfd f19,312(r3) lfd f20,320(r3) lfd f21,328(r3) lfd f22,336(r3) lfd f23,344(r3) lfd f24,352(r3) lfd f25,360(r3) lfd f26,368(r3) lfd f27,376(r3) lfd f28,384(r3) lfd f29,392(r3) lfd f30,400(r3) lfd f31,408(r3) ; restore vector registers if any are in use lwz r5,156(r3) ; test VRsave cmpwi r5,0 beq Lnovec subi r4,r1,16 rlwinm r4,r4,0,0,27 ; mask low 4-bits ; r4 is now a 16-byte aligned pointer into the red zone ; the _vectorRegisters may not be 16-byte aligned so copy via red zone temp buffer #define LOAD_VECTOR_UNALIGNEDl(_index) \ andis. r0,r5,(1<<(15-_index)) @\ beq Ldone ## _index @\ lwz r0, 424+_index*16(r3) @\ stw r0, 0(r4) @\ lwz r0, 424+_index*16+4(r3) @\ stw r0, 4(r4) @\ lwz r0, 424+_index*16+8(r3) @\ stw r0, 8(r4) @\ lwz r0, 424+_index*16+12(r3)@\ stw r0, 12(r4) @\ lvx v ## _index,0,r4 @\ Ldone ## _index: #define LOAD_VECTOR_UNALIGNEDh(_index) \ andi. r0,r5,(1<<(31-_index)) @\ beq Ldone ## _index @\ lwz r0, 424+_index*16(r3) @\ stw r0, 0(r4) @\ lwz r0, 424+_index*16+4(r3) @\ stw r0, 4(r4) @\ lwz r0, 424+_index*16+8(r3) @\ stw r0, 8(r4) @\ lwz r0, 424+_index*16+12(r3)@\ stw r0, 12(r4) @\ lvx v ## _index,0,r4 @\ Ldone ## _index: LOAD_VECTOR_UNALIGNEDl(0) LOAD_VECTOR_UNALIGNEDl(1) LOAD_VECTOR_UNALIGNEDl(2) LOAD_VECTOR_UNALIGNEDl(3) LOAD_VECTOR_UNALIGNEDl(4) LOAD_VECTOR_UNALIGNEDl(5) LOAD_VECTOR_UNALIGNEDl(6) LOAD_VECTOR_UNALIGNEDl(7) LOAD_VECTOR_UNALIGNEDl(8) LOAD_VECTOR_UNALIGNEDl(9) LOAD_VECTOR_UNALIGNEDl(10) LOAD_VECTOR_UNALIGNEDl(11) LOAD_VECTOR_UNALIGNEDl(12) LOAD_VECTOR_UNALIGNEDl(13) LOAD_VECTOR_UNALIGNEDl(14) LOAD_VECTOR_UNALIGNEDl(15) LOAD_VECTOR_UNALIGNEDh(16) LOAD_VECTOR_UNALIGNEDh(17) LOAD_VECTOR_UNALIGNEDh(18) LOAD_VECTOR_UNALIGNEDh(19) LOAD_VECTOR_UNALIGNEDh(20) LOAD_VECTOR_UNALIGNEDh(21) LOAD_VECTOR_UNALIGNEDh(22) LOAD_VECTOR_UNALIGNEDh(23) LOAD_VECTOR_UNALIGNEDh(24) LOAD_VECTOR_UNALIGNEDh(25) LOAD_VECTOR_UNALIGNEDh(26) LOAD_VECTOR_UNALIGNEDh(27) LOAD_VECTOR_UNALIGNEDh(28) LOAD_VECTOR_UNALIGNEDh(29) LOAD_VECTOR_UNALIGNEDh(30) LOAD_VECTOR_UNALIGNEDh(31) Lnovec: lwz r0, 136(r3) ; __cr mtocrf 255,r0 lwz r0, 148(r3) ; __ctr mtctr r0 lwz r0, 0(r3) ; __ssr0 mtctr r0 lwz r0, 8(r3) ; do r0 now lwz r5,28(r3) ; do r5 now lwz r4,24(r3) ; do r4 now lwz r1,12(r3) ; do sp now lwz r3,20(r3) ; do r3 last bctr #elif defined(__arm64__) || defined(__aarch64__) // // void libunwind::Registers_arm64::jumpto() // // On entry: // thread_state pointer is in x0 // .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv) // skip restore of x0,x1 for now ldp x2, x3, [x0, #0x010] ldp x4, x5, [x0, #0x020] ldp x6, x7, [x0, #0x030] ldp x8, x9, [x0, #0x040] ldp x10,x11, [x0, #0x050] ldp x12,x13, [x0, #0x060] ldp x14,x15, [x0, #0x070] ldp x16,x17, [x0, #0x080] ldp x18,x19, [x0, #0x090] ldp x20,x21, [x0, #0x0A0] ldp x22,x23, [x0, #0x0B0] ldp x24,x25, [x0, #0x0C0] ldp x26,x27, [x0, #0x0D0] ldp x28,x29, [x0, #0x0E0] ldr x30, [x0, #0x100] // restore pc into lr ldr x1, [x0, #0x0F8] mov sp,x1 // restore sp ldp d0, d1, [x0, #0x110] ldp d2, d3, [x0, #0x120] ldp d4, d5, [x0, #0x130] ldp d6, d7, [x0, #0x140] ldp d8, d9, [x0, #0x150] ldp d10,d11, [x0, #0x160] ldp d12,d13, [x0, #0x170] ldp d14,d15, [x0, #0x180] ldp d16,d17, [x0, #0x190] ldp d18,d19, [x0, #0x1A0] ldp d20,d21, [x0, #0x1B0] ldp d22,d23, [x0, #0x1C0] ldp d24,d25, [x0, #0x1D0] ldp d26,d27, [x0, #0x1E0] ldp d28,d29, [x0, #0x1F0] ldr d30, [x0, #0x200] ldr d31, [x0, #0x208] ldp x0, x1, [x0, #0x000] // restore x0,x1 ret x30 // jump to pc #elif defined(__arm__) && !defined(__APPLE__) #if !defined(__ARM_ARCH_ISA_ARM) .thumb #endif @ @ void libunwind::Registers_arm::restoreCoreAndJumpTo() @ @ On entry: @ thread_state pointer is in r0 @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm20restoreCoreAndJumpToEv) #if !defined(__ARM_ARCH_ISA_ARM) ldr r2, [r0, #52] ldr r3, [r0, #60] mov sp, r2 mov lr, r3 @ restore pc into lr ldm r0, {r0-r7} #else @ Use lr as base so that r0 can be restored. mov lr, r0 @ 32bit thumb-2 restrictions for ldm: @ . the sp (r13) cannot be in the list @ . the pc (r15) and lr (r14) cannot both be in the list in an LDM instruction ldm lr, {r0-r12} ldr sp, [lr, #52] ldr lr, [lr, #60] @ restore pc into lr #endif JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3-d16 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy) @ VFP and iwMMX instructions are only available when compiling with the flags @ that enable them. We do not want to do that in the library (because we do not @ want the compiler to generate instructions that access those) but this is @ only accessed if the personality routine needs these registers. Use of @ these registers implies they are, actually, available on the target, so @ it's ok to execute. @ So, generate the instruction using the corresponding coprocessor mnemonic. vldmia r0, {d0-d15} JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3-d16 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy) vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy) vldmia r0, {d16-d31} JMP(lr) @ @ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy) #if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX) ldcl p1, cr0, [r0], #8 @ wldrd wR0, [r0], #8 ldcl p1, cr1, [r0], #8 @ wldrd wR1, [r0], #8 ldcl p1, cr2, [r0], #8 @ wldrd wR2, [r0], #8 ldcl p1, cr3, [r0], #8 @ wldrd wR3, [r0], #8 ldcl p1, cr4, [r0], #8 @ wldrd wR4, [r0], #8 ldcl p1, cr5, [r0], #8 @ wldrd wR5, [r0], #8 ldcl p1, cr6, [r0], #8 @ wldrd wR6, [r0], #8 ldcl p1, cr7, [r0], #8 @ wldrd wR7, [r0], #8 ldcl p1, cr8, [r0], #8 @ wldrd wR8, [r0], #8 ldcl p1, cr9, [r0], #8 @ wldrd wR9, [r0], #8 ldcl p1, cr10, [r0], #8 @ wldrd wR10, [r0], #8 ldcl p1, cr11, [r0], #8 @ wldrd wR11, [r0], #8 ldcl p1, cr12, [r0], #8 @ wldrd wR12, [r0], #8 ldcl p1, cr13, [r0], #8 @ wldrd wR13, [r0], #8 ldcl p1, cr14, [r0], #8 @ wldrd wR14, [r0], #8 ldcl p1, cr15, [r0], #8 @ wldrd wR15, [r0], #8 #endif JMP(lr) @ @ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) #if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX) ldc2 p1, cr8, [r0], #4 @ wldrw wCGR0, [r0], #4 ldc2 p1, cr9, [r0], #4 @ wldrw wCGR1, [r0], #4 ldc2 p1, cr10, [r0], #4 @ wldrw wCGR2, [r0], #4 ldc2 p1, cr11, [r0], #4 @ wldrw wCGR3, [r0], #4 #endif JMP(lr) #elif defined(__or1k__) DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # # void libunwind::Registers_or1k::jumpto() # # On entry: # thread_state pointer is in r3 # # restore integral registerrs l.lwz r0, 0(r3) l.lwz r1, 4(r3) l.lwz r2, 8(r3) # skip r3 for now l.lwz r4, 16(r3) l.lwz r5, 20(r3) l.lwz r6, 24(r3) l.lwz r7, 28(r3) l.lwz r8, 32(r3) l.lwz r9, 36(r3) l.lwz r10, 40(r3) l.lwz r11, 44(r3) l.lwz r12, 48(r3) l.lwz r13, 52(r3) l.lwz r14, 56(r3) l.lwz r15, 60(r3) l.lwz r16, 64(r3) l.lwz r17, 68(r3) l.lwz r18, 72(r3) l.lwz r19, 76(r3) l.lwz r20, 80(r3) l.lwz r21, 84(r3) l.lwz r22, 88(r3) l.lwz r23, 92(r3) l.lwz r24, 96(r3) l.lwz r25,100(r3) l.lwz r26,104(r3) l.lwz r27,108(r3) l.lwz r28,112(r3) l.lwz r29,116(r3) l.lwz r30,120(r3) l.lwz r31,124(r3) # at last, restore r3 l.lwz r3, 12(r3) # jump to pc l.jr r9 l.nop #elif defined(__riscv) // // void libunwind::Registers_riscv::jumpto() // // On entry: // thread_state pointer is in a0 // .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) +#ifdef __riscv_float_abi_double + fld f0, (8 * 32 + 8 * 0)(a0) + fld f1, (8 * 32 + 8 * 1)(a0) + fld f2, (8 * 32 + 8 * 2)(a0) + fld f3, (8 * 32 + 8 * 3)(a0) + fld f4, (8 * 32 + 8 * 4)(a0) + fld f5, (8 * 32 + 8 * 5)(a0) + fld f6, (8 * 32 + 8 * 6)(a0) + fld f7, (8 * 32 + 8 * 7)(a0) + fld f8, (8 * 32 + 8 * 8)(a0) + fld f9, (8 * 32 + 8 * 9)(a0) + fld f10, (8 * 32 + 8 * 10)(a0) + fld f11, (8 * 32 + 8 * 11)(a0) + fld f12, (8 * 32 + 8 * 12)(a0) + fld f13, (8 * 32 + 8 * 13)(a0) + fld f14, (8 * 32 + 8 * 14)(a0) + fld f15, (8 * 32 + 8 * 15)(a0) + fld f16, (8 * 32 + 8 * 16)(a0) + fld f17, (8 * 32 + 8 * 17)(a0) + fld f18, (8 * 32 + 8 * 18)(a0) + fld f19, (8 * 32 + 8 * 19)(a0) + fld f20, (8 * 32 + 8 * 20)(a0) + fld f21, (8 * 32 + 8 * 21)(a0) + fld f22, (8 * 32 + 8 * 22)(a0) + fld f23, (8 * 32 + 8 * 23)(a0) + fld f24, (8 * 32 + 8 * 24)(a0) + fld f25, (8 * 32 + 8 * 25)(a0) + fld f26, (8 * 32 + 8 * 26)(a0) + fld f27, (8 * 32 + 8 * 27)(a0) + fld f28, (8 * 32 + 8 * 28)(a0) + fld f29, (8 * 32 + 8 * 29)(a0) + fld f30, (8 * 32 + 8 * 30)(a0) + fld f31, (8 * 32 + 8 * 31)(a0) +#endif + // x0 is zero ld x1, (8 * 1)(a0) ld x2, (8 * 2)(a0) ld x3, (8 * 3)(a0) ld x4, (8 * 4)(a0) ld x5, (8 * 5)(a0) ld x6, (8 * 6)(a0) ld x7, (8 * 7)(a0) ld x8, (8 * 8)(a0) ld x9, (8 * 9)(a0) // skip a0 for now ld x11, (8 * 11)(a0) ld x12, (8 * 12)(a0) ld x13, (8 * 13)(a0) ld x14, (8 * 14)(a0) ld x15, (8 * 15)(a0) ld x16, (8 * 16)(a0) ld x17, (8 * 17)(a0) ld x18, (8 * 18)(a0) ld x19, (8 * 19)(a0) ld x20, (8 * 20)(a0) ld x21, (8 * 21)(a0) ld x22, (8 * 22)(a0) ld x23, (8 * 23)(a0) ld x24, (8 * 24)(a0) ld x25, (8 * 25)(a0) ld x26, (8 * 26)(a0) ld x27, (8 * 27)(a0) ld x28, (8 * 28)(a0) ld x29, (8 * 29)(a0) ld x30, (8 * 30)(a0) ld x31, (8 * 31)(a0) ld x10, (8 * 10)(a0) // restore a0 - - /* RISCVTODO: restore FPU registers */ ret // jump to ra #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 // // void libunwind::Registers_mips_o32::jumpto() // // On entry: // thread state pointer is in a0 ($4) // DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) .set push .set noat .set noreorder .set nomacro #ifdef __mips_hard_float #if __mips_fpr == 32 ldc1 $f0, (4 * 36 + 8 * 0)($4) ldc1 $f2, (4 * 36 + 8 * 2)($4) ldc1 $f4, (4 * 36 + 8 * 4)($4) ldc1 $f6, (4 * 36 + 8 * 6)($4) ldc1 $f8, (4 * 36 + 8 * 8)($4) ldc1 $f10, (4 * 36 + 8 * 10)($4) ldc1 $f12, (4 * 36 + 8 * 12)($4) ldc1 $f14, (4 * 36 + 8 * 14)($4) ldc1 $f16, (4 * 36 + 8 * 16)($4) ldc1 $f18, (4 * 36 + 8 * 18)($4) ldc1 $f20, (4 * 36 + 8 * 20)($4) ldc1 $f22, (4 * 36 + 8 * 22)($4) ldc1 $f24, (4 * 36 + 8 * 24)($4) ldc1 $f26, (4 * 36 + 8 * 26)($4) ldc1 $f28, (4 * 36 + 8 * 28)($4) ldc1 $f30, (4 * 36 + 8 * 30)($4) #else ldc1 $f0, (4 * 36 + 8 * 0)($4) ldc1 $f1, (4 * 36 + 8 * 1)($4) ldc1 $f2, (4 * 36 + 8 * 2)($4) ldc1 $f3, (4 * 36 + 8 * 3)($4) ldc1 $f4, (4 * 36 + 8 * 4)($4) ldc1 $f5, (4 * 36 + 8 * 5)($4) ldc1 $f6, (4 * 36 + 8 * 6)($4) ldc1 $f7, (4 * 36 + 8 * 7)($4) ldc1 $f8, (4 * 36 + 8 * 8)($4) ldc1 $f9, (4 * 36 + 8 * 9)($4) ldc1 $f10, (4 * 36 + 8 * 10)($4) ldc1 $f11, (4 * 36 + 8 * 11)($4) ldc1 $f12, (4 * 36 + 8 * 12)($4) ldc1 $f13, (4 * 36 + 8 * 13)($4) ldc1 $f14, (4 * 36 + 8 * 14)($4) ldc1 $f15, (4 * 36 + 8 * 15)($4) ldc1 $f16, (4 * 36 + 8 * 16)($4) ldc1 $f17, (4 * 36 + 8 * 17)($4) ldc1 $f18, (4 * 36 + 8 * 18)($4) ldc1 $f19, (4 * 36 + 8 * 19)($4) ldc1 $f20, (4 * 36 + 8 * 20)($4) ldc1 $f21, (4 * 36 + 8 * 21)($4) ldc1 $f22, (4 * 36 + 8 * 22)($4) ldc1 $f23, (4 * 36 + 8 * 23)($4) ldc1 $f24, (4 * 36 + 8 * 24)($4) ldc1 $f25, (4 * 36 + 8 * 25)($4) ldc1 $f26, (4 * 36 + 8 * 26)($4) ldc1 $f27, (4 * 36 + 8 * 27)($4) ldc1 $f28, (4 * 36 + 8 * 28)($4) ldc1 $f29, (4 * 36 + 8 * 29)($4) ldc1 $f30, (4 * 36 + 8 * 30)($4) ldc1 $f31, (4 * 36 + 8 * 31)($4) #endif #endif // restore hi and lo lw $8, (4 * 33)($4) mthi $8 lw $8, (4 * 34)($4) mtlo $8 // r0 is zero lw $1, (4 * 1)($4) lw $2, (4 * 2)($4) lw $3, (4 * 3)($4) // skip a0 for now lw $5, (4 * 5)($4) lw $6, (4 * 6)($4) lw $7, (4 * 7)($4) lw $8, (4 * 8)($4) lw $9, (4 * 9)($4) lw $10, (4 * 10)($4) lw $11, (4 * 11)($4) lw $12, (4 * 12)($4) lw $13, (4 * 13)($4) lw $14, (4 * 14)($4) lw $15, (4 * 15)($4) lw $16, (4 * 16)($4) lw $17, (4 * 17)($4) lw $18, (4 * 18)($4) lw $19, (4 * 19)($4) lw $20, (4 * 20)($4) lw $21, (4 * 21)($4) lw $22, (4 * 22)($4) lw $23, (4 * 23)($4) lw $24, (4 * 24)($4) lw $25, (4 * 25)($4) lw $26, (4 * 26)($4) lw $27, (4 * 27)($4) lw $28, (4 * 28)($4) lw $29, (4 * 29)($4) lw $30, (4 * 30)($4) // load new pc into ra lw $31, (4 * 32)($4) // jump to ra, load a0 in the delay slot jr $31 lw $4, (4 * 4)($4) .set pop #elif defined(__mips64) // // void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder .set nomacro #ifdef __mips_hard_float ldc1 $f0, (8 * 35)($4) ldc1 $f1, (8 * 36)($4) ldc1 $f2, (8 * 37)($4) ldc1 $f3, (8 * 38)($4) ldc1 $f4, (8 * 39)($4) ldc1 $f5, (8 * 40)($4) ldc1 $f6, (8 * 41)($4) ldc1 $f7, (8 * 42)($4) ldc1 $f8, (8 * 43)($4) ldc1 $f9, (8 * 44)($4) ldc1 $f10, (8 * 45)($4) ldc1 $f11, (8 * 46)($4) ldc1 $f12, (8 * 47)($4) ldc1 $f13, (8 * 48)($4) ldc1 $f14, (8 * 49)($4) ldc1 $f15, (8 * 50)($4) ldc1 $f16, (8 * 51)($4) ldc1 $f17, (8 * 52)($4) ldc1 $f18, (8 * 53)($4) ldc1 $f19, (8 * 54)($4) ldc1 $f20, (8 * 55)($4) ldc1 $f21, (8 * 56)($4) ldc1 $f22, (8 * 57)($4) ldc1 $f23, (8 * 58)($4) ldc1 $f24, (8 * 59)($4) ldc1 $f25, (8 * 60)($4) ldc1 $f26, (8 * 61)($4) ldc1 $f27, (8 * 62)($4) ldc1 $f28, (8 * 63)($4) ldc1 $f29, (8 * 64)($4) ldc1 $f30, (8 * 65)($4) ldc1 $f31, (8 * 66)($4) #endif // restore hi and lo ld $8, (8 * 33)($4) mthi $8 ld $8, (8 * 34)($4) mtlo $8 // r0 is zero ld $1, (8 * 1)($4) ld $2, (8 * 2)($4) ld $3, (8 * 3)($4) // skip a0 for now ld $5, (8 * 5)($4) ld $6, (8 * 6)($4) ld $7, (8 * 7)($4) ld $8, (8 * 8)($4) ld $9, (8 * 9)($4) ld $10, (8 * 10)($4) ld $11, (8 * 11)($4) ld $12, (8 * 12)($4) ld $13, (8 * 13)($4) ld $14, (8 * 14)($4) ld $15, (8 * 15)($4) ld $16, (8 * 16)($4) ld $17, (8 * 17)($4) ld $18, (8 * 18)($4) ld $19, (8 * 19)($4) ld $20, (8 * 20)($4) ld $21, (8 * 21)($4) ld $22, (8 * 22)($4) ld $23, (8 * 23)($4) ld $24, (8 * 24)($4) ld $25, (8 * 25)($4) ld $26, (8 * 26)($4) ld $27, (8 * 27)($4) ld $28, (8 * 28)($4) ld $29, (8 * 29)($4) ld $30, (8 * 30)($4) // load new pc into ra ld $31, (8 * 32)($4) // jump to ra, load a0 in the delay slot jr $31 ld $4, (8 * 4)($4) .set pop #endif NO_EXEC_STACK_DIRECTIVE Index: head/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S =================================================================== --- head/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S (revision 335369) +++ head/contrib/llvm/projects/libunwind/src/UnwindRegistersSave.S (revision 335370) @@ -1,673 +1,748 @@ //===------------------------ UnwindRegistersSave.S -----------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "assembly.h" .text #if defined(__i386__) # # extern int unw_getcontext(unw_context_t* thread_state) # # On entry: # + + # +-----------------------+ # + thread_state pointer + # +-----------------------+ # + return address + # +-----------------------+ <-- SP # + + # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) push %eax movl 8(%esp), %eax movl %ebx, 4(%eax) movl %ecx, 8(%eax) movl %edx, 12(%eax) movl %edi, 16(%eax) movl %esi, 20(%eax) movl %ebp, 24(%eax) movl %esp, %edx addl $8, %edx movl %edx, 28(%eax) # store what sp was at call site as esp # skip ss # skip eflags movl 4(%esp), %edx movl %edx, 40(%eax) # store return address as eip # skip cs # skip ds # skip es # skip fs # skip gs movl (%esp), %edx movl %edx, (%eax) # store original eax popl %eax xorl %eax, %eax # return UNW_ESUCCESS ret #elif defined(__x86_64__) # # extern int unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in rdi # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) movq %rax, (%rdi) movq %rbx, 8(%rdi) movq %rcx, 16(%rdi) movq %rdx, 24(%rdi) movq %rdi, 32(%rdi) movq %rsi, 40(%rdi) movq %rbp, 48(%rdi) movq %rsp, 56(%rdi) addq $8, 56(%rdi) movq %r8, 64(%rdi) movq %r9, 72(%rdi) movq %r10, 80(%rdi) movq %r11, 88(%rdi) movq %r12, 96(%rdi) movq %r13,104(%rdi) movq %r14,112(%rdi) movq %r15,120(%rdi) movq (%rsp),%rsi movq %rsi,128(%rdi) # store return address as rip # skip rflags # skip cs # skip fs # skip gs xorl %eax, %eax # return UNW_ESUCCESS ret #elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 # # extern int unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in a0 ($4) # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) .set push .set noat .set noreorder .set nomacro sw $1, (4 * 1)($4) sw $2, (4 * 2)($4) sw $3, (4 * 3)($4) sw $4, (4 * 4)($4) sw $5, (4 * 5)($4) sw $6, (4 * 6)($4) sw $7, (4 * 7)($4) sw $8, (4 * 8)($4) sw $9, (4 * 9)($4) sw $10, (4 * 10)($4) sw $11, (4 * 11)($4) sw $12, (4 * 12)($4) sw $13, (4 * 13)($4) sw $14, (4 * 14)($4) sw $15, (4 * 15)($4) sw $16, (4 * 16)($4) sw $17, (4 * 17)($4) sw $18, (4 * 18)($4) sw $19, (4 * 19)($4) sw $20, (4 * 20)($4) sw $21, (4 * 21)($4) sw $22, (4 * 22)($4) sw $23, (4 * 23)($4) sw $24, (4 * 24)($4) sw $25, (4 * 25)($4) sw $26, (4 * 26)($4) sw $27, (4 * 27)($4) sw $28, (4 * 28)($4) sw $29, (4 * 29)($4) sw $30, (4 * 30)($4) sw $31, (4 * 31)($4) # Store return address to pc sw $31, (4 * 32)($4) # hi and lo mfhi $8 sw $8, (4 * 33)($4) mflo $8 sw $8, (4 * 34)($4) #ifdef __mips_hard_float #if __mips_fpr == 32 sdc1 $f0, (4 * 36 + 8 * 0)($4) sdc1 $f2, (4 * 36 + 8 * 2)($4) sdc1 $f4, (4 * 36 + 8 * 4)($4) sdc1 $f6, (4 * 36 + 8 * 6)($4) sdc1 $f8, (4 * 36 + 8 * 8)($4) sdc1 $f10, (4 * 36 + 8 * 10)($4) sdc1 $f12, (4 * 36 + 8 * 12)($4) sdc1 $f14, (4 * 36 + 8 * 14)($4) sdc1 $f16, (4 * 36 + 8 * 16)($4) sdc1 $f18, (4 * 36 + 8 * 18)($4) sdc1 $f20, (4 * 36 + 8 * 20)($4) sdc1 $f22, (4 * 36 + 8 * 22)($4) sdc1 $f24, (4 * 36 + 8 * 24)($4) sdc1 $f26, (4 * 36 + 8 * 26)($4) sdc1 $f28, (4 * 36 + 8 * 28)($4) sdc1 $f30, (4 * 36 + 8 * 30)($4) #else sdc1 $f0, (4 * 36 + 8 * 0)($4) sdc1 $f1, (4 * 36 + 8 * 1)($4) sdc1 $f2, (4 * 36 + 8 * 2)($4) sdc1 $f3, (4 * 36 + 8 * 3)($4) sdc1 $f4, (4 * 36 + 8 * 4)($4) sdc1 $f5, (4 * 36 + 8 * 5)($4) sdc1 $f6, (4 * 36 + 8 * 6)($4) sdc1 $f7, (4 * 36 + 8 * 7)($4) sdc1 $f8, (4 * 36 + 8 * 8)($4) sdc1 $f9, (4 * 36 + 8 * 9)($4) sdc1 $f10, (4 * 36 + 8 * 10)($4) sdc1 $f11, (4 * 36 + 8 * 11)($4) sdc1 $f12, (4 * 36 + 8 * 12)($4) sdc1 $f13, (4 * 36 + 8 * 13)($4) sdc1 $f14, (4 * 36 + 8 * 14)($4) sdc1 $f15, (4 * 36 + 8 * 15)($4) sdc1 $f16, (4 * 36 + 8 * 16)($4) sdc1 $f17, (4 * 36 + 8 * 17)($4) sdc1 $f18, (4 * 36 + 8 * 18)($4) sdc1 $f19, (4 * 36 + 8 * 19)($4) sdc1 $f20, (4 * 36 + 8 * 20)($4) sdc1 $f21, (4 * 36 + 8 * 21)($4) sdc1 $f22, (4 * 36 + 8 * 22)($4) sdc1 $f23, (4 * 36 + 8 * 23)($4) sdc1 $f24, (4 * 36 + 8 * 24)($4) sdc1 $f25, (4 * 36 + 8 * 25)($4) sdc1 $f26, (4 * 36 + 8 * 26)($4) sdc1 $f27, (4 * 36 + 8 * 27)($4) sdc1 $f28, (4 * 36 + 8 * 28)($4) sdc1 $f29, (4 * 36 + 8 * 29)($4) sdc1 $f30, (4 * 36 + 8 * 30)($4) sdc1 $f31, (4 * 36 + 8 * 31)($4) #endif #endif jr $31 # return UNW_ESUCCESS or $2, $0, $0 .set pop #elif defined(__mips64) # # extern int unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in a0 ($4) # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) .set push .set noat .set noreorder .set nomacro sd $1, (8 * 1)($4) sd $2, (8 * 2)($4) sd $3, (8 * 3)($4) sd $4, (8 * 4)($4) sd $5, (8 * 5)($4) sd $6, (8 * 6)($4) sd $7, (8 * 7)($4) sd $8, (8 * 8)($4) sd $9, (8 * 9)($4) sd $10, (8 * 10)($4) sd $11, (8 * 11)($4) sd $12, (8 * 12)($4) sd $13, (8 * 13)($4) sd $14, (8 * 14)($4) sd $15, (8 * 15)($4) sd $16, (8 * 16)($4) sd $17, (8 * 17)($4) sd $18, (8 * 18)($4) sd $19, (8 * 19)($4) sd $20, (8 * 20)($4) sd $21, (8 * 21)($4) sd $22, (8 * 22)($4) sd $23, (8 * 23)($4) sd $24, (8 * 24)($4) sd $25, (8 * 25)($4) sd $26, (8 * 26)($4) sd $27, (8 * 27)($4) sd $28, (8 * 28)($4) sd $29, (8 * 29)($4) sd $30, (8 * 30)($4) sd $31, (8 * 31)($4) # Store return address to pc sd $31, (8 * 32)($4) # hi and lo mfhi $8 sd $8, (8 * 33)($4) mflo $8 sd $8, (8 * 34)($4) #ifdef __mips_hard_float sdc1 $f0, (8 * 35)($4) sdc1 $f1, (8 * 36)($4) sdc1 $f2, (8 * 37)($4) sdc1 $f3, (8 * 38)($4) sdc1 $f4, (8 * 39)($4) sdc1 $f5, (8 * 40)($4) sdc1 $f6, (8 * 41)($4) sdc1 $f7, (8 * 42)($4) sdc1 $f8, (8 * 43)($4) sdc1 $f9, (8 * 44)($4) sdc1 $f10, (8 * 45)($4) sdc1 $f11, (8 * 46)($4) sdc1 $f12, (8 * 47)($4) sdc1 $f13, (8 * 48)($4) sdc1 $f14, (8 * 49)($4) sdc1 $f15, (8 * 50)($4) sdc1 $f16, (8 * 51)($4) sdc1 $f17, (8 * 52)($4) sdc1 $f18, (8 * 53)($4) sdc1 $f19, (8 * 54)($4) sdc1 $f20, (8 * 55)($4) sdc1 $f21, (8 * 56)($4) sdc1 $f22, (8 * 57)($4) sdc1 $f23, (8 * 58)($4) sdc1 $f24, (8 * 59)($4) sdc1 $f25, (8 * 60)($4) sdc1 $f26, (8 * 61)($4) sdc1 $f27, (8 * 62)($4) sdc1 $f28, (8 * 63)($4) sdc1 $f29, (8 * 64)($4) sdc1 $f30, (8 * 65)($4) sdc1 $f31, (8 * 66)($4) #endif jr $31 # return UNW_ESUCCESS or $2, $0, $0 .set pop # elif defined(__mips__) # # extern int unw_getcontext(unw_context_t* thread_state) # # Just trap for the time being. DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) teq $0, $0 #elif defined(__ppc__) ; ; extern int unw_getcontext(unw_context_t* thread_state) ; ; On entry: ; thread_state pointer is in r3 ; DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) stw r0, 8(r3) mflr r0 stw r0, 0(r3) ; store lr as ssr0 stw r1, 12(r3) stw r2, 16(r3) stw r3, 20(r3) stw r4, 24(r3) stw r5, 28(r3) stw r6, 32(r3) stw r7, 36(r3) stw r8, 40(r3) stw r9, 44(r3) stw r10, 48(r3) stw r11, 52(r3) stw r12, 56(r3) stw r13, 60(r3) stw r14, 64(r3) stw r15, 68(r3) stw r16, 72(r3) stw r17, 76(r3) stw r18, 80(r3) stw r19, 84(r3) stw r20, 88(r3) stw r21, 92(r3) stw r22, 96(r3) stw r23,100(r3) stw r24,104(r3) stw r25,108(r3) stw r26,112(r3) stw r27,116(r3) stw r28,120(r3) stw r29,124(r3) stw r30,128(r3) stw r31,132(r3) ; save VRSave register mfspr r0,256 stw r0,156(r3) ; save CR registers mfcr r0 stw r0,136(r3) ; save CTR register mfctr r0 stw r0,148(r3) ; save float registers stfd f0, 160(r3) stfd f1, 168(r3) stfd f2, 176(r3) stfd f3, 184(r3) stfd f4, 192(r3) stfd f5, 200(r3) stfd f6, 208(r3) stfd f7, 216(r3) stfd f8, 224(r3) stfd f9, 232(r3) stfd f10,240(r3) stfd f11,248(r3) stfd f12,256(r3) stfd f13,264(r3) stfd f14,272(r3) stfd f15,280(r3) stfd f16,288(r3) stfd f17,296(r3) stfd f18,304(r3) stfd f19,312(r3) stfd f20,320(r3) stfd f21,328(r3) stfd f22,336(r3) stfd f23,344(r3) stfd f24,352(r3) stfd f25,360(r3) stfd f26,368(r3) stfd f27,376(r3) stfd f28,384(r3) stfd f29,392(r3) stfd f30,400(r3) stfd f31,408(r3) ; save vector registers subi r4,r1,16 rlwinm r4,r4,0,0,27 ; mask low 4-bits ; r4 is now a 16-byte aligned pointer into the red zone #define SAVE_VECTOR_UNALIGNED(_vec, _offset) \ stvx _vec,0,r4 @\ lwz r5, 0(r4) @\ stw r5, _offset(r3) @\ lwz r5, 4(r4) @\ stw r5, _offset+4(r3) @\ lwz r5, 8(r4) @\ stw r5, _offset+8(r3) @\ lwz r5, 12(r4) @\ stw r5, _offset+12(r3) SAVE_VECTOR_UNALIGNED( v0, 424+0x000) SAVE_VECTOR_UNALIGNED( v1, 424+0x010) SAVE_VECTOR_UNALIGNED( v2, 424+0x020) SAVE_VECTOR_UNALIGNED( v3, 424+0x030) SAVE_VECTOR_UNALIGNED( v4, 424+0x040) SAVE_VECTOR_UNALIGNED( v5, 424+0x050) SAVE_VECTOR_UNALIGNED( v6, 424+0x060) SAVE_VECTOR_UNALIGNED( v7, 424+0x070) SAVE_VECTOR_UNALIGNED( v8, 424+0x080) SAVE_VECTOR_UNALIGNED( v9, 424+0x090) SAVE_VECTOR_UNALIGNED(v10, 424+0x0A0) SAVE_VECTOR_UNALIGNED(v11, 424+0x0B0) SAVE_VECTOR_UNALIGNED(v12, 424+0x0C0) SAVE_VECTOR_UNALIGNED(v13, 424+0x0D0) SAVE_VECTOR_UNALIGNED(v14, 424+0x0E0) SAVE_VECTOR_UNALIGNED(v15, 424+0x0F0) SAVE_VECTOR_UNALIGNED(v16, 424+0x100) SAVE_VECTOR_UNALIGNED(v17, 424+0x110) SAVE_VECTOR_UNALIGNED(v18, 424+0x120) SAVE_VECTOR_UNALIGNED(v19, 424+0x130) SAVE_VECTOR_UNALIGNED(v20, 424+0x140) SAVE_VECTOR_UNALIGNED(v21, 424+0x150) SAVE_VECTOR_UNALIGNED(v22, 424+0x160) SAVE_VECTOR_UNALIGNED(v23, 424+0x170) SAVE_VECTOR_UNALIGNED(v24, 424+0x180) SAVE_VECTOR_UNALIGNED(v25, 424+0x190) SAVE_VECTOR_UNALIGNED(v26, 424+0x1A0) SAVE_VECTOR_UNALIGNED(v27, 424+0x1B0) SAVE_VECTOR_UNALIGNED(v28, 424+0x1C0) SAVE_VECTOR_UNALIGNED(v29, 424+0x1D0) SAVE_VECTOR_UNALIGNED(v30, 424+0x1E0) SAVE_VECTOR_UNALIGNED(v31, 424+0x1F0) li r3, 0 ; return UNW_ESUCCESS blr #elif defined(__arm64__) || defined(__aarch64__) // // extern int unw_getcontext(unw_context_t* thread_state) // // On entry: // thread_state pointer is in x0 // .p2align 2 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) stp x0, x1, [x0, #0x000] stp x2, x3, [x0, #0x010] stp x4, x5, [x0, #0x020] stp x6, x7, [x0, #0x030] stp x8, x9, [x0, #0x040] stp x10,x11, [x0, #0x050] stp x12,x13, [x0, #0x060] stp x14,x15, [x0, #0x070] stp x16,x17, [x0, #0x080] stp x18,x19, [x0, #0x090] stp x20,x21, [x0, #0x0A0] stp x22,x23, [x0, #0x0B0] stp x24,x25, [x0, #0x0C0] stp x26,x27, [x0, #0x0D0] stp x28,x29, [x0, #0x0E0] str x30, [x0, #0x0F0] mov x1,sp str x1, [x0, #0x0F8] str x30, [x0, #0x100] // store return address as pc // skip cpsr stp d0, d1, [x0, #0x110] stp d2, d3, [x0, #0x120] stp d4, d5, [x0, #0x130] stp d6, d7, [x0, #0x140] stp d8, d9, [x0, #0x150] stp d10,d11, [x0, #0x160] stp d12,d13, [x0, #0x170] stp d14,d15, [x0, #0x180] stp d16,d17, [x0, #0x190] stp d18,d19, [x0, #0x1A0] stp d20,d21, [x0, #0x1B0] stp d22,d23, [x0, #0x1C0] stp d24,d25, [x0, #0x1D0] stp d26,d27, [x0, #0x1E0] stp d28,d29, [x0, #0x1F0] str d30, [x0, #0x200] str d31, [x0, #0x208] mov x0, #0 // return UNW_ESUCCESS ret #elif defined(__arm__) && !defined(__APPLE__) #if !defined(__ARM_ARCH_ISA_ARM) .thumb #endif @ @ extern int unw_getcontext(unw_context_t* thread_state) @ @ On entry: @ thread_state pointer is in r0 @ @ Per EHABI #4.7 this only saves the core integer registers. @ EHABI #7.4.5 notes that in general all VRS registers should be restored @ however this is very hard to do for VFP registers because it is unknown @ to the library how many registers are implemented by the architecture. @ Instead, VFP registers are demand saved by logic external to unw_getcontext. @ .p2align 2 DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) #if !defined(__ARM_ARCH_ISA_ARM) stm r0, {r0-r7} mov r2, sp mov r3, lr str r2, [r0, #52] str r3, [r0, #56] str r3, [r0, #60] @ store return address as pc #else @ 32bit thumb-2 restrictions for stm: @ . the sp (r13) cannot be in the list @ . the pc (r15) cannot be in the list in an STM instruction stm r0, {r0-r12} str sp, [r0, #52] str lr, [r0, #56] str lr, [r0, #60] @ store return address as pc #endif #if __ARM_ARCH_ISA_THUMB == 1 @ T1 does not have a non-cpsr-clobbering register-zeroing instruction. @ It is safe to use here though because we are about to return, and cpsr is @ not expected to be preserved. movs r0, #0 @ return UNW_ESUCCESS #else mov r0, #0 @ return UNW_ESUCCESS #endif JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3-d16 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy) vstmia r0, {d0-d15} JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3-d16 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy) vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 .fpu vfpv3 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy) @ VFP and iwMMX instructions are only available when compiling with the flags @ that enable them. We do not want to do that in the library (because we do not @ want the compiler to generate instructions that access those) but this is @ only accessed if the personality routine needs these registers. Use of @ these registers implies they are, actually, available on the target, so @ it's ok to execute. @ So, generate the instructions using the corresponding coprocessor mnemonic. vstmia r0, {d16-d31} JMP(lr) @ @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy) #if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX) stcl p1, cr0, [r0], #8 @ wstrd wR0, [r0], #8 stcl p1, cr1, [r0], #8 @ wstrd wR1, [r0], #8 stcl p1, cr2, [r0], #8 @ wstrd wR2, [r0], #8 stcl p1, cr3, [r0], #8 @ wstrd wR3, [r0], #8 stcl p1, cr4, [r0], #8 @ wstrd wR4, [r0], #8 stcl p1, cr5, [r0], #8 @ wstrd wR5, [r0], #8 stcl p1, cr6, [r0], #8 @ wstrd wR6, [r0], #8 stcl p1, cr7, [r0], #8 @ wstrd wR7, [r0], #8 stcl p1, cr8, [r0], #8 @ wstrd wR8, [r0], #8 stcl p1, cr9, [r0], #8 @ wstrd wR9, [r0], #8 stcl p1, cr10, [r0], #8 @ wstrd wR10, [r0], #8 stcl p1, cr11, [r0], #8 @ wstrd wR11, [r0], #8 stcl p1, cr12, [r0], #8 @ wstrd wR12, [r0], #8 stcl p1, cr13, [r0], #8 @ wstrd wR13, [r0], #8 stcl p1, cr14, [r0], #8 @ wstrd wR14, [r0], #8 stcl p1, cr15, [r0], #8 @ wstrd wR15, [r0], #8 #endif JMP(lr) @ @ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) @ @ On entry: @ values pointer is in r0 @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) #if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || defined(__ARM_WMMX) stc2 p1, cr8, [r0], #4 @ wstrw wCGR0, [r0], #4 stc2 p1, cr9, [r0], #4 @ wstrw wCGR1, [r0], #4 stc2 p1, cr10, [r0], #4 @ wstrw wCGR2, [r0], #4 stc2 p1, cr11, [r0], #4 @ wstrw wCGR3, [r0], #4 #endif JMP(lr) #elif defined(__or1k__) # # extern int unw_getcontext(unw_context_t* thread_state) # # On entry: # thread_state pointer is in r3 # DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) l.sw 0(r3), r0 l.sw 4(r3), r1 l.sw 8(r3), r2 l.sw 12(r3), r3 l.sw 16(r3), r4 l.sw 20(r3), r5 l.sw 24(r3), r6 l.sw 28(r3), r7 l.sw 32(r3), r8 l.sw 36(r3), r9 l.sw 40(r3), r10 l.sw 44(r3), r11 l.sw 48(r3), r12 l.sw 52(r3), r13 l.sw 56(r3), r14 l.sw 60(r3), r15 l.sw 64(r3), r16 l.sw 68(r3), r17 l.sw 72(r3), r18 l.sw 76(r3), r19 l.sw 80(r3), r20 l.sw 84(r3), r21 l.sw 88(r3), r22 l.sw 92(r3), r23 l.sw 96(r3), r24 l.sw 100(r3), r25 l.sw 104(r3), r26 l.sw 108(r3), r27 l.sw 112(r3), r28 l.sw 116(r3), r29 l.sw 120(r3), r30 l.sw 124(r3), r31 #elif defined(__riscv) -/* RISCVTODO */ +# +# extern int unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in a0 +# +DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) + // x0 is zero + sd x1, (8 * 1)(a0) + sd x2, (8 * 2)(a0) + sd x3, (8 * 3)(a0) + sd x4, (8 * 4)(a0) + sd x5, (8 * 5)(a0) + sd x6, (8 * 6)(a0) + sd x7, (8 * 7)(a0) + sd x8, (8 * 8)(a0) + sd x9, (8 * 9)(a0) + sd x10, (8 * 10)(a0) + sd x11, (8 * 11)(a0) + sd x12, (8 * 12)(a0) + sd x13, (8 * 13)(a0) + sd x14, (8 * 14)(a0) + sd x15, (8 * 15)(a0) + sd x16, (8 * 16)(a0) + sd x17, (8 * 17)(a0) + sd x18, (8 * 18)(a0) + sd x19, (8 * 19)(a0) + sd x20, (8 * 20)(a0) + sd x21, (8 * 21)(a0) + sd x22, (8 * 22)(a0) + sd x23, (8 * 23)(a0) + sd x24, (8 * 24)(a0) + sd x25, (8 * 25)(a0) + sd x26, (8 * 26)(a0) + sd x27, (8 * 27)(a0) + sd x28, (8 * 28)(a0) + sd x29, (8 * 29)(a0) + sd x30, (8 * 30)(a0) + sd x31, (8 * 31)(a0) +#ifdef __riscv_float_abi_double + fsd f0, (8 * 32 + 8 * 0)(a0) + fsd f1, (8 * 32 + 8 * 1)(a0) + fsd f2, (8 * 32 + 8 * 2)(a0) + fsd f3, (8 * 32 + 8 * 3)(a0) + fsd f4, (8 * 32 + 8 * 4)(a0) + fsd f5, (8 * 32 + 8 * 5)(a0) + fsd f6, (8 * 32 + 8 * 6)(a0) + fsd f7, (8 * 32 + 8 * 7)(a0) + fsd f8, (8 * 32 + 8 * 8)(a0) + fsd f9, (8 * 32 + 8 * 9)(a0) + fsd f10, (8 * 32 + 8 * 10)(a0) + fsd f11, (8 * 32 + 8 * 11)(a0) + fsd f12, (8 * 32 + 8 * 12)(a0) + fsd f13, (8 * 32 + 8 * 13)(a0) + fsd f14, (8 * 32 + 8 * 14)(a0) + fsd f15, (8 * 32 + 8 * 15)(a0) + fsd f16, (8 * 32 + 8 * 16)(a0) + fsd f17, (8 * 32 + 8 * 17)(a0) + fsd f18, (8 * 32 + 8 * 18)(a0) + fsd f19, (8 * 32 + 8 * 19)(a0) + fsd f20, (8 * 32 + 8 * 20)(a0) + fsd f21, (8 * 32 + 8 * 21)(a0) + fsd f22, (8 * 32 + 8 * 22)(a0) + fsd f23, (8 * 32 + 8 * 23)(a0) + fsd f24, (8 * 32 + 8 * 24)(a0) + fsd f25, (8 * 32 + 8 * 25)(a0) + fsd f26, (8 * 32 + 8 * 26)(a0) + fsd f27, (8 * 32 + 8 * 27)(a0) + fsd f28, (8 * 32 + 8 * 28)(a0) + fsd f29, (8 * 32 + 8 * 29)(a0) + fsd f30, (8 * 32 + 8 * 30)(a0) + fsd f31, (8 * 32 + 8 * 31)(a0) +#endif + + li a0, 0 // return UNW_ESUCCESS + ret // jump to ra #endif NO_EXEC_STACK_DIRECTIVE