Skip to content

Commit 6201bc3

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 6201bc3

File tree

2 files changed

+44
-29
lines changed

2 files changed

+44
-29
lines changed

libunwind/src/UnwindRegistersRestore.S

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ 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+
#define LDP(a,b,r,o,p) ldr a, [r, o] ; ldr b, [r, p]
640+
#endif
641+
636642
//
637643
// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
638644
//
@@ -642,23 +648,24 @@ Lnovec:
642648
.p2align 2
643649
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
644650
// 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]
651+
LDP(x2, x3, x0, #0x010, #0x018)
652+
LDP(x4, x5, x0, #0x020, #0x028)
653+
LDP(x6, x7, x0, #0x030, #0x038)
654+
LDP(x8, x9, x0, #0x040, #0x048)
655+
LDP(x10, x11, x0, #0x050, #0x058)
656+
LDP(x12, x13, x0, #0x060, #0x068)
657+
LDP(x14, x15, x0, #0x070, #0x078)
652658
// x16 and x17 were clobbered by the call into the unwinder, so no point in
653659
// 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]
660+
LDP(x18, x19, x0, #0x090, #0x098)
661+
LDP(x20, x21, x0, #0x0A0, #0x0A8)
662+
LDP(x22, x23, x0, #0x0B0, #0x0B8)
663+
LDP(x24, x25, x0, #0x0C0, #0x0C8)
664+
LDP(x26, x27, x0, #0x0D0, #0x0D8)
665+
LDP(x28, x29, x0, #0x0E0, #0x0E8)
660666
ldr x30, [x0, #0x100] // restore pc into lr
661667

668+
#if defined(__ARM_FP) && __ARM_FP != 0
662669
ldp d0, d1, [x0, #0x110]
663670
ldp d2, d3, [x0, #0x120]
664671
ldp d4, d5, [x0, #0x130]
@@ -676,13 +683,14 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
676683
ldp d28,d29, [x0, #0x1F0]
677684
ldr d30, [x0, #0x200]
678685
ldr d31, [x0, #0x208]
686+
#endif
679687

680688
// Finally, restore sp. This must be done after the last read from the
681689
// context struct, because it is allocated on the stack, and an exception
682690
// could clobber the de-allocated portion of the stack after sp has been
683691
// restored.
684692
ldr x16, [x0, #0x0F8]
685-
ldp x0, x1, [x0, #0x000] // restore x0,x1
693+
LDP(x0, x1, x0, #0x000, #0x008) // restore x0,x1
686694
mov sp,x16 // restore sp
687695
#if defined(__ARM_FEATURE_GCS_DEFAULT)
688696
// If GCS is enabled we need to push the address we're returning to onto the

libunwind/src/UnwindRegistersSave.S

Lines changed: 22 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,21 +732,21 @@ 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]
@@ -763,6 +769,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
763769
stp d28,d29, [x0, #0x1F0]
764770
str d30, [x0, #0x200]
765771
str d31, [x0, #0x208]
772+
#endif
766773
mov x0, #0 // return UNW_ESUCCESS
767774
ret
768775

0 commit comments

Comments
 (0)