about summary refs log tree commit diff
path: root/src/setjmp/arm/longjmp.S
diff options
context:
space:
mode:
authorSzabolcs Nagy <nsz@port70.net>2019-09-25 19:34:25 +0100
committerRich Felker <dalias@aerifal.cx>2019-09-26 00:34:15 -0400
commitb678f7b46a614ca8985b3ef662d96036e06e8810 (patch)
treedc35054552afd0fbccc7f78258cef15080a78994 /src/setjmp/arm/longjmp.S
parent29bad49d72e5aeedb97d2bb2af44838d934026a0 (diff)
downloadmusl-b678f7b46a614ca8985b3ef662d96036e06e8810.tar.gz
musl-b678f7b46a614ca8985b3ef662d96036e06e8810.tar.xz
musl-b678f7b46a614ca8985b3ef662d96036e06e8810.zip
arm: fix setjmp and longjmp asm for armv8-a
armv8 removed the coprocessor instructions other than cp14, so
on an armv8 system the related hwcaps should never be set.

new llvm complains about the use of coprocessor instructions in
armv8-a mode (even though they are never executed at runtime),
so ifdef them out when musl is built for armv8.
Diffstat (limited to 'src/setjmp/arm/longjmp.S')
-rw-r--r--src/setjmp/arm/longjmp.S50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/setjmp/arm/longjmp.S b/src/setjmp/arm/longjmp.S
new file mode 100644
index 00000000..8df0b819
--- /dev/null
+++ b/src/setjmp/arm/longjmp.S
@@ -0,0 +1,50 @@
+.syntax unified
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	mov ip,r0
+	movs r0,r1
+	moveq r0,#1
+	ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
+	ldmia ip!, {r2,lr}
+	mov sp,r2
+
+	adr r1,1f
+	ldr r2,1f
+	ldr r1,[r1,r2]
+
+#if __ARM_ARCH < 8
+	tst r1,#0x260
+	beq 3f
+	// HWCAP_ARM_FPA
+	tst r1,#0x20
+	beq 2f
+	ldc p2, cr4, [ip], #48
+#endif
+2:	tst r1,#0x40
+	beq 2f
+	.fpu vfp
+	vldmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
+#if __ARM_ARCH < 8
+	// HWCAP_ARM_IWMMXT
+2:	tst r1,#0x200
+	beq 3f
+	ldcl p1, cr10, [ip], #8
+	ldcl p1, cr11, [ip], #8
+	ldcl p1, cr12, [ip], #8
+	ldcl p1, cr13, [ip], #8
+	ldcl p1, cr14, [ip], #8
+	ldcl p1, cr15, [ip], #8
+#endif
+2:
+3:	bx lr
+
+.hidden __hwcap
+.align 2
+1:	.word __hwcap-1b