Index: src/Unwind/UnwindRegistersRestore.S =================================================================== --- src/Unwind/UnwindRegistersRestore.S +++ src/Unwind/UnwindRegistersRestore.S @@ -310,6 +310,10 @@ #elif __arm__ && !__APPLE__ +#if !defined(__ARM_ARCH_ISA_ARM) + .thumb +#endif + @ @ void libunwind::Registers_arm::restoreCoreAndJumpTo() @ @@ -318,6 +322,13 @@ @ .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: @@ -326,11 +337,8 @@ ldm lr, {r0-r12} ldr sp, [lr, #52] ldr lr, [lr, #60] @ restore pc into lr -#if __ARM_ARCH > 4 - bx lr -#else - mov pc, lr #endif + JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPWithFLDMD(unw_fpreg_t* values) @@ -340,8 +348,9 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMDEPy) +#if defined(__ARM_FP) @ VFP and iwMMX instructions are only available when compiling with the flags - @ that enable them. We don't want to do that in the library (because we don't + @ 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 @@ -352,7 +361,8 @@ #else vldmia r0, {d0-d15} #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPWithFLDMX(unw_fpreg_t* values) @@ -362,12 +372,14 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreVFPWithFLDMXEPy) +#if defined(__ARM_FP) #if __ARM_ARCH < 7 ldc p11, cr0, [r0], {0x21} @ fldmiax r0, {d0-d15} #else vldmia r0, {d0-d15} @ fldmiax is deprecated in ARMv7+ and now behaves like vldmia #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::restoreVFPv3(unw_fpreg_t* values) @@ -377,12 +389,14 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreVFPv3EPy) +#if defined(__ARM_FP) #if __ARM_ARCH < 7 ldcl p11, cr0, [r0], {0x20} @ vldm r0, {d16-d31} #else vldmia r0, {d16-d31} #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::restoreiWMMX(unw_fpreg_t* values) @@ -392,6 +406,7 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm12restoreiWMMXEPy) +#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __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 @@ -408,7 +423,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 - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::restoreiWMMXControl(unw_uint32_t* values) @@ -418,10 +434,12 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXControlEPj) +#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __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 - mov pc, lr +#endif + JMP(lr) #endif Index: src/Unwind/UnwindRegistersSave.S =================================================================== --- src/Unwind/UnwindRegistersSave.S +++ src/Unwind/UnwindRegistersSave.S @@ -282,6 +282,10 @@ #elif __arm__ && !__APPLE__ +#if !defined(__ARM_ARCH_ISA_ARM) + .thumb +#endif + @ @ extern int unw_getcontext(unw_context_t* thread_state) @ @@ -296,6 +300,14 @@ @ .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 @@ -303,12 +315,9 @@ str sp, [r0, #52] str lr, [r0, #56] str lr, [r0, #60] @ store return address as pc - mov r0, #0 @ return UNW_ESUCCESS -#if __ARM_ARCH > 4 - bx lr -#else - mov pc, lr #endif + mov r0, #0 @ return UNW_ESUCCESS + JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPWithFSTMD(unw_fpreg_t* values) @@ -318,12 +327,14 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMDEPy) +#if defined(__ARM_FP) #if __ARM_ARCH < 7 stc p11, cr0, [r0], {0x20} @ fstmiad r0, {d0-d15} #else vstmia r0, {d0-d15} #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPWithFSTMX(unw_fpreg_t* values) @@ -333,12 +344,14 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveVFPWithFSTMXEPy) +#if defined(__ARM_FP) #if __ARM_ARCH < 7 stc p11, cr0, [r0], {0x21} @ fstmiax r0, {d0-d15} #else vstmia r0, {d0-d15} @ fstmiax is deprecated in ARMv7+ and now behaves like vstmia #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::saveVFPv3(unw_fpreg_t* values) @@ -348,8 +361,9 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveVFPv3EPy) +#if defined(__ARM_FP) @ VFP and iwMMX instructions are only available when compiling with the flags - @ that enable them. We don't want to do that in the library (because we don't + @ 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 @@ -360,7 +374,8 @@ #else vstmia r0, {d16-d31} #endif - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::saveiWMMX(unw_fpreg_t* values) @@ -370,6 +385,7 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm9saveiWMMXEPy) +#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __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 @@ -386,7 +402,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 - mov pc, lr +#endif + JMP(lr) @ @ static void libunwind::Registers_arm::saveiWMMXControl(unw_uint32_t* values) @@ -396,10 +413,12 @@ @ .p2align 2 DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControlEPj) +#if (!defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_6SM__)) || __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 - mov pc, lr +#endif + JMP(lr) #endif Index: src/Unwind/assembly.h =================================================================== --- src/Unwind/assembly.h +++ src/Unwind/assembly.h @@ -61,4 +61,17 @@ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ SYMBOL_NAME(name): +#if defined(__arm__) +#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 +#define ARM_HAS_BX +#endif + +#ifdef ARM_HAS_BX +#define JMP(r) bx r +#else +#define JMP(r) mov pc, r +#endif +#endif +#endif /* __arm__ */ + #endif /* UNWIND_ASSEMBLY_H */