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.
This commit is contained in:
Felix Fietkau 2016-01-25 13:20:52 +01:00 committed by Rich Felker
parent 9543656cc3
commit 5a92dd95c7
7 changed files with 65 additions and 35 deletions

View 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;

View 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)

4
configure vendored
View File

@ -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

View File

@ -0,0 +1,3 @@
#ifdef _SOFT_FLOAT
#include "../fenv.c"
#endif

View 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

View 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

View 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