diff options
| author | Felix Fietkau <nbd@openwrt.org> | 2016-01-25 13:20:52 +0100 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2016-03-06 17:03:01 -0500 | 
| commit | 5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb (patch) | |
| tree | a7a12a71e2a505ed4a5c20c1356fc2d7cf2cb2f1 | |
| parent | 9543656cc32fda48fc463f332ee20e91eed2b768 (diff) | |
| download | musl-5a92dd95c77cee81755f1a441ae0b71e3ae2bcdb.tar.gz | |
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.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/reloc.h | 8 | ||||
| -rwxr-xr-x | configure | 4 | ||||
| -rw-r--r-- | src/fenv/powerpc/fenv-sf.c | 3 | ||||
| -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) @@ -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 | 
