summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2016-01-25 13:20:52 +0100
committerRich Felker <dalias@aerifal.cx>2016-03-06 17:03:01 -0500
commit5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb (patch)
treea7a12a71e2a505ed4a5c20c1356fc2d7cf2cb2f1
parent9543656cc32fda48fc463f332ee20e91eed2b768 (diff)
downloadmusl-5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb.tar.gz
musl-5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb.tar.bz2
musl-5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb.tar.xz
musl-5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb.zip
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. Make it possible to run these devices in soft-float mode.
-rw-r--r--arch/powerpc/bits/fenv.h5
-rw-r--r--arch/powerpc/reloc.h8
-rwxr-xr-xconfigure4
-rw-r--r--src/fenv/powerpc/fenv-sf.c3
-rw-r--r--src/fenv/powerpc/fenv.S (renamed from src/fenv/powerpc/fenv.s)42
-rw-r--r--src/setjmp/powerpc/longjmp.S (renamed from src/setjmp/powerpc/longjmp.s)24
-rw-r--r--src/setjmp/powerpc/setjmp.S (renamed from src/setjmp/powerpc/setjmp.s)14
7 files changed, 65 insertions, 35 deletions
diff --git a/arch/powerpc/bits/fenv.h b/arch/powerpc/bits/fenv.h
index 2f722e6b..c5a3e5c5 100644
--- a/arch/powerpc/bits/fenv.h
+++ b/arch/powerpc/bits/fenv.h
@@ -1,3 +1,7 @@
+#ifdef _SOFT_FLOAT
+#define FE_ALL_EXCEPT 0
+#define FE_TONEAREST 0
+#else
#define FE_TONEAREST 0
#define FE_TOWARDZERO 1
#define FE_UPWARD 2
@@ -24,6 +28,7 @@
#define FE_ALL_INVALID 0x01f80700
#endif
+#endif
typedef unsigned fexcept_t;
typedef double fenv_t;
diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h
index b8b6589f..1b4cab36 100644
--- a/arch/powerpc/reloc.h
+++ b/arch/powerpc/reloc.h
@@ -1,4 +1,10 @@
-#define LDSO_ARCH "powerpc"
+#ifdef _SOFT_FLOAT
+#define FP_SUFFIX "-sf"
+#else
+#define FP_SUFFIX ""
+#endif
+
+#define LDSO_ARCH "powerpc" FP_SUFFIX
#define TPOFF_K (-0x7000)
diff --git a/configure b/configure
index 89e0d177..9c0762c9 100755
--- a/configure
+++ b/configure
@@ -621,6 +621,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/fenv-sf.c b/src/fenv/powerpc/fenv-sf.c
new file mode 100644
index 00000000..85bef40f
--- /dev/null
+++ b/src/fenv/powerpc/fenv-sf.c
@@ -0,0 +1,3 @@
+#ifdef _SOFT_FLOAT
+#include "../fenv.c"
+#endif
diff --git a/src/fenv/powerpc/fenv.s b/src/fenv/powerpc/fenv.S
index e34a9990..1516eb5c 100644
--- a/src/fenv/powerpc/fenv.s
+++ b/src/fenv/powerpc/fenv.S
@@ -1,18 +1,21 @@
+#ifndef _SOFT_FLOAT
.global feclearexcept
.type feclearexcept,@function
feclearexcept:
andis. 3,3,0x3e00
- # if (r3 & FE_INVALID) r3 |= all_invalid_flags
+ /* if (r3 & FE_INVALID) r3 |= all_invalid_flags */
andis. 0,3,0x2000
stwu 1,-16(1)
beq- 0,1f
oris 3,3,0x01f8
ori 3,3,0x0700
1:
- # note: fpscr contains various fpu status and control
- # flags and we dont check if r3 may alter other flags
- # than the exception related ones
- # fpscr &= ~r3
+ /*
+ * note: fpscr contains various fpu status and control
+ * flags and we dont check if r3 may alter other flags
+ * than the exception related ones
+ * ufpscr &= ~r3
+ */
mffs 0
stfd 0,8(1)
lwz 9,12(1)
@@ -21,7 +24,7 @@ feclearexcept:
lfd 0,8(1)
mtfsf 255,0
- # return 0
+ /* return 0 */
li 3,0
addi 1,1,16
blr
@@ -30,13 +33,13 @@ feclearexcept:
.type feraiseexcept,@function
feraiseexcept:
andis. 3,3,0x3e00
- # if (r3 & FE_INVALID) r3 |= software_invalid_flag
+ /* if (r3 & FE_INVALID) r3 |= software_invalid_flag */
andis. 0,3,0x2000
stwu 1,-16(1)
beq- 0,1f
ori 3,3,0x0400
1:
- # fpscr |= r3
+ /* fpscr |= r3 */
mffs 0
stfd 0,8(1)
lwz 9,12(1)
@@ -45,7 +48,7 @@ feraiseexcept:
lfd 0,8(1)
mtfsf 255,0
- # return 0
+ /* return 0 */
li 3,0
addi 1,1,16
blr
@@ -54,7 +57,7 @@ feraiseexcept:
.type fetestexcept,@function
fetestexcept:
andis. 3,3,0x3e00
- # return r3 & fpscr
+ /* return r3 & fpscr */
stwu 1,-16(1)
mffs 0
stfd 0,8(1)
@@ -66,7 +69,7 @@ fetestexcept:
.global fegetround
.type fegetround,@function
fegetround:
- # return fpscr & 3
+ /* return fpscr & 3 */
stwu 1,-16(1)
mffs 0
stfd 0,8(1)
@@ -78,8 +81,10 @@ fegetround:
.global __fesetround
.type __fesetround,@function
__fesetround:
- # note: invalid input is not checked, r3 < 4 must hold
- # fpscr = (fpscr & -4U) | r3
+ /*
+ * note: invalid input is not checked, r3 < 4 must hold
+ * fpscr = (fpscr & -4U) | r3
+ */
stwu 1,-16(1)
mffs 0
stfd 0,8(1)
@@ -90,7 +95,7 @@ __fesetround:
lfd 0,8(1)
mtfsf 255,0
- # return 0
+ /* return 0 */
li 3,0
addi 1,1,16
blr
@@ -98,10 +103,10 @@ __fesetround:
.global fegetenv
.type fegetenv,@function
fegetenv:
- # *r3 = fpscr
+ /* *r3 = fpscr */
mffs 0
stfd 0,0(3)
- # return 0
+ /* return 0 */
li 3,0
blr
@@ -115,9 +120,10 @@ fesetenv:
.zero 8
2: mflr 3
mtlr 4
-1: # fpscr = *r3
+1: /* fpscr = *r3 */
lfd 0,0(3)
mtfsf 255,0
- # return 0
+ /* return 0 */
li 3,0
blr
+#endif
diff --git a/src/setjmp/powerpc/longjmp.s b/src/setjmp/powerpc/longjmp.S
index bab17511..e598bd05 100644
--- a/src/setjmp/powerpc/longjmp.s
+++ b/src/setjmp/powerpc/longjmp.S
@@ -4,19 +4,21 @@
.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
+ /*
+ * 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
+ /* 1) put it into link reg */
mtlr 0
- #2 ) restore stack ptr
+ /* 2 ) restore stack ptr */
lwz 1, 4(3)
- #3) restore control reg
+ /* 3) restore control reg */
lwz 0, 8(3)
mtcr 0
- #4) restore r14-r31
+ /* 4) restore r14-r31 */
lwz 14, 12(3)
lwz 15, 16(3)
lwz 16, 20(3)
@@ -35,6 +37,7 @@ longjmp:
lwz 29, 72(3)
lwz 30, 76(3)
lwz 31, 80(3)
+#ifndef _SOFT_FLOAT
lfd 14,88(3)
lfd 15,96(3)
lfd 16,104(3)
@@ -53,10 +56,11 @@ longjmp:
lfd 29,208(3)
lfd 30,216(3)
lfd 31,224(3)
- #5) put val into return reg r3
+#endif
+ /* 5) put val into return reg r3 */
mr 3, 4
- #6) check if return value is 0, make it 1 in that case
+ /* 6) check if return value is 0, make it 1 in that case */
cmpwi cr7, 4, 0
bne cr7, 1f
li 3, 1
diff --git a/src/setjmp/powerpc/setjmp.s b/src/setjmp/powerpc/setjmp.S
index 122177f1..cd91a207 100644
--- a/src/setjmp/powerpc/setjmp.s
+++ b/src/setjmp/powerpc/setjmp.S
@@ -10,15 +10,15 @@ ___setjmp:
__setjmp:
_setjmp:
setjmp:
- # 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg)
+ /* 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)
+ /* 1) store reg1 (SP) */
stw 1, 4(3)
- # 2) store cr
+ /* 2) store cr */
mfcr 0
stw 0, 8(3)
- # 3) store r14-31
+ /* 3) store r14-31 */
stw 14, 12(3)
stw 15, 16(3)
stw 16, 20(3)
@@ -37,6 +37,7 @@ setjmp:
stw 29, 72(3)
stw 30, 76(3)
stw 31, 80(3)
+#ifndef _SOFT_FLOAT
stfd 14,88(3)
stfd 15,96(3)
stfd 16,104(3)
@@ -55,7 +56,8 @@ setjmp:
stfd 29,208(3)
stfd 30,216(3)
stfd 31,224(3)
- # 4) set return value to 0
+#endif
+ /* 4) set return value to 0 */
li 3, 0
- # 5) return
+ /* 5) return */
blr