]> granicus.if.org Git - musl/commitdiff
add powerpc soft-float support
authorFelix Fietkau <nbd@openwrt.org>
Mon, 25 Jan 2016 12:20:52 +0000 (13:20 +0100)
committerRich Felker <dalias@aerifal.cx>
Sun, 6 Mar 2016 22:03:01 +0000 (17:03 -0500)
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.

arch/powerpc/bits/fenv.h
arch/powerpc/reloc.h
configure
src/fenv/powerpc/fenv-sf.c [new file with mode: 0644]
src/fenv/powerpc/fenv.S [moved from src/fenv/powerpc/fenv.s with 68% similarity]
src/setjmp/powerpc/longjmp.S [moved from src/setjmp/powerpc/longjmp.s with 63% similarity]
src/setjmp/powerpc/setjmp.S [moved from src/setjmp/powerpc/setjmp.s with 79% similarity]

index 2f722e6b594acc90f374e4d731aab7a23ead9a4a..c5a3e5c5c70fe850964879b60eedf7616e6ac7e3 100644 (file)
@@ -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;
index b8b6589f988e42519e7e05c3195ad054f0817dc7..1b4cab36a60878c81bb20e06ea1fdc6e22d346df 100644 (file)
@@ -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)
 
index 89e0d177df4a7a8925ff280268c5cee929014fc2..9c0762c95191da4e9bc93fe8735de71e85cbec6e 100755 (executable)
--- 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 (file)
index 0000000..85bef40
--- /dev/null
@@ -0,0 +1,3 @@
+#ifdef _SOFT_FLOAT
+#include "../fenv.c"
+#endif
similarity index 68%
rename from src/fenv/powerpc/fenv.s
rename to src/fenv/powerpc/fenv.S
index e34a999089472214f57112a1083702057790ab14..1516eb5c6ed27ef00d56a3086ac1c797fe668636 100644 (file)
@@ -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
similarity index 63%
rename from src/setjmp/powerpc/longjmp.s
rename to src/setjmp/powerpc/longjmp.S
index bab1751176ecdde88458de482bcb9c04617454d6..e598bd056e6ca240c5ac1a13263f35acce584dcd 100644 (file)
@@ -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
similarity index 79%
rename from src/setjmp/powerpc/setjmp.s
rename to src/setjmp/powerpc/setjmp.S
index 122177f142b670b3452b77b5b5783bc137e4f573..cd91a207f5c7fd82aa2da53b19558a5634189e60 100644 (file)
@@ -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