mirror of https://git.musl-libc.org/git/musl
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:
parent
9543656cc3
commit
5a92dd95c7
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#ifdef _SOFT_FLOAT
|
||||
#include "../fenv.c"
|
||||
#endif
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue