Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Wed,  8 Jul 2015 13:59:58 +0200
From: Felix Fietkau <nbd@...nwrt.org>
To: musl@...ts.openwall.com
Subject: [PATCH] Add PowerPC soft-float support

Some PowerPC CPUs (e.g. Freescale MPC85xx) have a completely different
instruction set for floating point operations (SPE).
Executing regular PowerPC floating point instructions results in
"Illegal instruction" errors.

Until support for SPE FPU is added, make it possible to run these
devices in soft-float mode.

Signed-off-by: Felix Fietkau <nbd@...nwrt.org>
---
 configure                         |  4 ++++
 src/fenv/powerpc-sf/fenv.sub      |  1 +
 src/setjmp/powerpc-sf/longjmp.s   | 47 +++++++++++++++++++++++++++++++++++++++
 src/setjmp/powerpc-sf/longjmp.sub |  1 +
 src/setjmp/powerpc-sf/setjmp.s    | 43 +++++++++++++++++++++++++++++++++++
 src/setjmp/powerpc-sf/setjmp.sub  |  1 +
 6 files changed, 97 insertions(+)
 create mode 100644 src/fenv/powerpc-sf/fenv.sub
 create mode 100644 src/setjmp/powerpc-sf/longjmp.s
 create mode 100644 src/setjmp/powerpc-sf/longjmp.sub
 create mode 100644 src/setjmp/powerpc-sf/setjmp.s
 create mode 100644 src/setjmp/powerpc-sf/setjmp.sub

diff --git a/configure b/configure
index beed406..1e94f06 100755
--- a/configure
+++ b/configure
@@ -522,6 +522,10 @@ trycppif "_MIPSEL || __MIPSEL || __MIPSEL__" "$t" && SUBARCH=${SUBARCH}el
 trycppif __mips_soft_float "$t" && SUBARCH=${SUBARCH}-sf
 fi
 
+if test "$ARCH" = "powerpc" ; then
+trycppif _SOFT_FLOAT "$t" && SUBARCH=${SUBARCH}-sf
+fi
+
 test "$ARCH" = "microblaze" && trycppif __MICROBLAZEEL__ "$t" \
 && SUBARCH=${SUBARCH}el
 
diff --git a/src/fenv/powerpc-sf/fenv.sub b/src/fenv/powerpc-sf/fenv.sub
new file mode 100644
index 0000000..9cafca5
--- /dev/null
+++ b/src/fenv/powerpc-sf/fenv.sub
@@ -0,0 +1 @@
+../fenv.c
diff --git a/src/setjmp/powerpc-sf/longjmp.s b/src/setjmp/powerpc-sf/longjmp.s
new file mode 100644
index 0000000..fd61ae7
--- /dev/null
+++ b/src/setjmp/powerpc-sf/longjmp.s
@@ -0,0 +1,47 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+# void longjmp(jmp_buf env, int val);
+# put val into return register and restore the env saved in setjmp
+# if val(r4) is 0, put 1 there.
+	# 0) move old return address into r0
+	lwz 0, 0(3)
+	# 1) put it into link reg
+	mtlr 0
+	#2 ) restore stack ptr
+	lwz 1, 4(3)
+	#3) restore control reg
+	lwz 0, 8(3)
+	mtcr 0
+	#4) restore r14-r31
+	lwz 14, 12(3)
+	lwz 15, 16(3)
+	lwz 16, 20(3)
+	lwz 17, 24(3)
+	lwz 18, 28(3)
+	lwz 19, 32(3)
+	lwz 20, 36(3)
+	lwz 21, 40(3)
+	lwz 22, 44(3)
+	lwz 23, 48(3)
+	lwz 24, 52(3)
+	lwz 25, 56(3)
+	lwz 26, 60(3)
+	lwz 27, 64(3)
+	lwz 28, 68(3)
+	lwz 29, 72(3)
+	lwz 30, 76(3)
+	lwz 31, 80(3)
+	#5) put val into return reg r3
+	mr 3, 4
+
+	#6) check if return value is 0, make it 1 in that case
+	cmpwi cr7, 4, 0
+	bne cr7, 1f
+	li 3, 1
+1:
+	blr
+
diff --git a/src/setjmp/powerpc-sf/longjmp.sub b/src/setjmp/powerpc-sf/longjmp.sub
new file mode 100644
index 0000000..e80331b
--- /dev/null
+++ b/src/setjmp/powerpc-sf/longjmp.sub
@@ -0,0 +1 @@
+longjmp.s
diff --git a/src/setjmp/powerpc-sf/setjmp.s b/src/setjmp/powerpc-sf/setjmp.s
new file mode 100644
index 0000000..17c2663
--- /dev/null
+++ b/src/setjmp/powerpc-sf/setjmp.s
@@ -0,0 +1,43 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	# 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg)
+	mflr 0
+	stw 0, 0(3)
+	# 1) store reg1 (SP)
+	stw 1, 4(3)
+	# 2) store cr
+	mfcr 0
+	stw 0, 8(3)
+	# 3) store r14-31
+	stw 14, 12(3)
+	stw 15, 16(3)
+	stw 16, 20(3)
+	stw 17, 24(3)
+	stw 18, 28(3)
+	stw 19, 32(3)
+	stw 20, 36(3)
+	stw 21, 40(3)
+	stw 22, 44(3)
+	stw 23, 48(3)
+	stw 24, 52(3)
+	stw 25, 56(3)
+	stw 26, 60(3)
+	stw 27, 64(3)
+	stw 28, 68(3)
+	stw 29, 72(3)
+	stw 30, 76(3)
+	stw 31, 80(3)
+	# 4) set return value to 0
+	li 3, 0
+	# 5) return
+	blr
diff --git a/src/setjmp/powerpc-sf/setjmp.sub b/src/setjmp/powerpc-sf/setjmp.sub
new file mode 100644
index 0000000..b7ad221
--- /dev/null
+++ b/src/setjmp/powerpc-sf/setjmp.sub
@@ -0,0 +1 @@
+setjmp.s
-- 
2.2.2

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.