Skip to content

Commit 048cb1b

Browse files
committed
[libunwind] Support aarch64 without FPU
ldp and stp instructions both require an FPU. Use pairs of ldr or str instructions when the target doesn't have one. Signed-off-by: Keith Packard <[email protected]>
1 parent 9e862ae commit 048cb1b

File tree

2 files changed

+46
-29
lines changed

2 files changed

+46
-29
lines changed

libunwind/src/UnwindRegistersRestore.S

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,13 @@ Lnovec:
633633
.arch_extension gcs
634634
#endif
635635

636+
#if defined(__ARM_FP) && __ARM_FP != 0
637+
#define LDP(a,b,r,o,p) stp a, b, [r, o]
638+
#else
639+
/* In reverse order so that the last LDP(x0,x1,x0) works. */
640+
#define LDP(a,b,r,o,p) ldr b, [r, p] ; ldr a, [r, o]
641+
#endif
642+
636643
//
637644
// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
638645
//
@@ -642,23 +649,24 @@ Lnovec:
642649
.p2align 2
643650
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
644651
// skip restore of x0,x1 for now
645-
ldp x2, x3, [x0, #0x010]
646-
ldp x4, x5, [x0, #0x020]
647-
ldp x6, x7, [x0, #0x030]
648-
ldp x8, x9, [x0, #0x040]
649-
ldp x10,x11, [x0, #0x050]
650-
ldp x12,x13, [x0, #0x060]
651-
ldp x14,x15, [x0, #0x070]
652+
LDP(x2, x3, x0, #0x010, #0x018)
653+
LDP(x4, x5, x0, #0x020, #0x028)
654+
LDP(x6, x7, x0, #0x030, #0x038)
655+
LDP(x8, x9, x0, #0x040, #0x048)
656+
LDP(x10, x11, x0, #0x050, #0x058)
657+
LDP(x12, x13, x0, #0x060, #0x068)
658+
LDP(x14, x15, x0, #0x070, #0x078)
652659
// x16 and x17 were clobbered by the call into the unwinder, so no point in
653660
// restoring them.
654-
ldp x18,x19, [x0, #0x090]
655-
ldp x20,x21, [x0, #0x0A0]
656-
ldp x22,x23, [x0, #0x0B0]
657-
ldp x24,x25, [x0, #0x0C0]
658-
ldp x26,x27, [x0, #0x0D0]
659-
ldp x28,x29, [x0, #0x0E0]
661+
LDP(x18, x19, x0, #0x090, #0x098)
662+
LDP(x20, x21, x0, #0x0A0, #0x0A8)
663+
LDP(x22, x23, x0, #0x0B0, #0x0B8)
664+
LDP(x24, x25, x0, #0x0C0, #0x0C8)
665+
LDP(x26, x27, x0, #0x0D0, #0x0D8)
666+
LDP(x28, x29, x0, #0x0E0, #0x0E8)
660667
ldr x30, [x0, #0x100] // restore pc into lr
661668

669+
#if defined(__ARM_FP) && __ARM_FP != 0
662670
ldp d0, d1, [x0, #0x110]
663671
ldp d2, d3, [x0, #0x120]
664672
ldp d4, d5, [x0, #0x130]
@@ -676,13 +684,14 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
676684
ldp d28,d29, [x0, #0x1F0]
677685
ldr d30, [x0, #0x200]
678686
ldr d31, [x0, #0x208]
687+
#endif
679688

680689
// Finally, restore sp. This must be done after the last read from the
681690
// context struct, because it is allocated on the stack, and an exception
682691
// could clobber the de-allocated portion of the stack after sp has been
683692
// restored.
684693
ldr x16, [x0, #0x0F8]
685-
ldp x0, x1, [x0, #0x000] // restore x0,x1
694+
LDP(x0, x1, x0, #0x000, #0x008) // restore x0,x1
686695
mov sp,x16 // restore sp
687696
#if defined(__ARM_FEATURE_GCS_DEFAULT)
688697
// If GCS is enabled we need to push the address we're returning to onto the

libunwind/src/UnwindRegistersSave.S

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,12 @@ LnoR2Fix:
718718

719719
#elif defined(__aarch64__)
720720

721+
#if defined(__ARM_FP) && __ARM_FP != 0
722+
#define STP(a,b,r,o,p) stp a, b, [r, o]
723+
#else
724+
#define STP(a,b,r,o,p) str a, [r, o] ; str b, [r, p]
725+
#endif
726+
721727
//
722728
// extern int __unw_getcontext(unw_context_t* thread_state)
723729
//
@@ -726,26 +732,27 @@ LnoR2Fix:
726732
//
727733
.p2align 2
728734
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
729-
stp x0, x1, [x0, #0x000]
730-
stp x2, x3, [x0, #0x010]
731-
stp x4, x5, [x0, #0x020]
732-
stp x6, x7, [x0, #0x030]
733-
stp x8, x9, [x0, #0x040]
734-
stp x10,x11, [x0, #0x050]
735-
stp x12,x13, [x0, #0x060]
736-
stp x14,x15, [x0, #0x070]
737-
stp x16,x17, [x0, #0x080]
738-
stp x18,x19, [x0, #0x090]
739-
stp x20,x21, [x0, #0x0A0]
740-
stp x22,x23, [x0, #0x0B0]
741-
stp x24,x25, [x0, #0x0C0]
742-
stp x26,x27, [x0, #0x0D0]
743-
stp x28,x29, [x0, #0x0E0]
735+
STP(x0, x1, x0, #0x000, #0x008)
736+
STP(x2, x3, x0, #0x010, #0x018)
737+
STP(x4, x5, x0, #0x020, #0x028)
738+
STP(x6, x7, x0, #0x030, #0x038)
739+
STP(x8, x9, x0, #0x040, #0x048)
740+
STP(x10, x11, x0, #0x050, #0x058)
741+
STP(x12, x13, x0, #0x060, #0x068)
742+
STP(x14, x15, x0, #0x070, #0x078)
743+
STP(x16, x17, x0, #0x080, #0x088)
744+
STP(x18, x19, x0, #0x090, #0x098)
745+
STP(x20, x21, x0, #0x0A0, #0x0A8)
746+
STP(x22, x23, x0, #0x0B0, #0x0B8)
747+
STP(x24, x25, x0, #0x0C0, #0x0C8)
748+
STP(x26, x27, x0, #0x0D0, #0x0D8)
749+
STP(x28, x29, x0, #0x0E0, #0x0E8)
744750
str x30, [x0, #0x0F0]
745751
mov x1,sp
746752
str x1, [x0, #0x0F8]
747753
str x30, [x0, #0x100] // store return address as pc
748754
// skip cpsr
755+
#if defined(__ARM_FP) && __ARM_FP != 0
749756
stp d0, d1, [x0, #0x110]
750757
stp d2, d3, [x0, #0x120]
751758
stp d4, d5, [x0, #0x130]
@@ -763,6 +770,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
763770
stp d28,d29, [x0, #0x1F0]
764771
str d30, [x0, #0x200]
765772
str d31, [x0, #0x208]
773+
#endif
766774
mov x0, #0 // return UNW_ESUCCESS
767775
ret
768776

0 commit comments

Comments
 (0)