Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150806224749.GA32423@port70.net>
Date: Fri, 7 Aug 2015 00:47:50 +0200
From: Szabolcs Nagy <nsz@...t70.net>
To: musl@...ts.openwall.com
Subject: Re: [PATCH v2] Add PowerPC soft-float support

* Felix Fietkau <nbd@...nwrt.org> [2015-07-10 13:02:51 +0200]:
> 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.
> 

thanks, this looks good

i used

#define MUSL_DYNAMIC_LINKER \
  "/lib/ld-musl-powerpc" MUSL_DYNAMIC_LINKER_E "%{msoft-float:-sf}.so.1"

in gcc to get a soft float toolchain.
(MUSL_DYNAMIC_LINKER_E is "le" on little endian).
but i'm not yet sure if -msoft-float is always passed
down by gcc for soft float targets.

(the gcc config files are rather messy, there might be more
ppc abi variants lurking there)

> Signed-off-by: Felix Fietkau <nbd@...nwrt.org>
> ---
>  arch/powerpc/reloc.h              |  8 ++++++-
>  configure                         |  4 ++++
>  src/fenv/powerpc-sf/fenv.sub      |  1 +

this is not enough for fenv.

unsupported FE_* macros must be hidden in arch/powerpc/bits/fenv.h
(see e.g. how arm does it), exceptions and non-nearest rounding
are not supported for soft float.

the rest looks ok to me.

>  src/setjmp/powerpc-sf/longjmp.s   | 47 +++++++++++++++++++++++++++++++++++++++
>  src/setjmp/powerpc-sf/longjmp.sub |  1 +
>  src/setjmp/powerpc-sf/setjmp.s    | 43 +++++++++++++++++++++++++++++++++++
>  src/setjmp/powerpc-sf/setjmp.sub  |  1 +
>  7 files changed, 104 insertions(+), 1 deletion(-)
>  create mode 100644 src/fenv/powerpc-sf/fenv.sub
>  create mode 100644 src/setjmp/powerpc-sf/longjmp.s
>  create mode 100644 src/setjmp/powerpc-sf/longjmp.sub
>  create mode 100644 src/setjmp/powerpc-sf/setjmp.s
>  create mode 100644 src/setjmp/powerpc-sf/setjmp.sub
> 
> diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h
> index aa5f8c9..7880fb5 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 beed406..1e94f06 100755
> --- a/configure
> +++ b/configure
> @@ -522,6 +522,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-sf/fenv.sub b/src/fenv/powerpc-sf/fenv.sub
> new file mode 100644
> index 0000000..9cafca5
> --- /dev/null
> +++ b/src/fenv/powerpc-sf/fenv.sub
> @@ -0,0 +1 @@
> +../fenv.c
> diff --git a/src/setjmp/powerpc-sf/longjmp.s b/src/setjmp/powerpc-sf/longjmp.s
> new file mode 100644
> index 0000000..fd61ae7
> --- /dev/null
> +++ b/src/setjmp/powerpc-sf/longjmp.s
> @@ -0,0 +1,47 @@
> +	.global _longjmp
> +	.global longjmp
> +	.type   _longjmp,@function
> +	.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
> +	lwz 0, 0(3)
> +	# 1) put it into link reg
> +	mtlr 0
> +	#2 ) restore stack ptr
> +	lwz 1, 4(3)
> +	#3) restore control reg
> +	lwz 0, 8(3)
> +	mtcr 0
> +	#4) restore r14-r31
> +	lwz 14, 12(3)
> +	lwz 15, 16(3)
> +	lwz 16, 20(3)
> +	lwz 17, 24(3)
> +	lwz 18, 28(3)
> +	lwz 19, 32(3)
> +	lwz 20, 36(3)
> +	lwz 21, 40(3)
> +	lwz 22, 44(3)
> +	lwz 23, 48(3)
> +	lwz 24, 52(3)
> +	lwz 25, 56(3)
> +	lwz 26, 60(3)
> +	lwz 27, 64(3)
> +	lwz 28, 68(3)
> +	lwz 29, 72(3)
> +	lwz 30, 76(3)
> +	lwz 31, 80(3)
> +	#5) put val into return reg r3
> +	mr 3, 4
> +
> +	#6) check if return value is 0, make it 1 in that case
> +	cmpwi cr7, 4, 0
> +	bne cr7, 1f
> +	li 3, 1
> +1:
> +	blr
> +
> diff --git a/src/setjmp/powerpc-sf/longjmp.sub b/src/setjmp/powerpc-sf/longjmp.sub
> new file mode 100644
> index 0000000..e80331b
> --- /dev/null
> +++ b/src/setjmp/powerpc-sf/longjmp.sub
> @@ -0,0 +1 @@
> +longjmp.s
> diff --git a/src/setjmp/powerpc-sf/setjmp.s b/src/setjmp/powerpc-sf/setjmp.s
> new file mode 100644
> index 0000000..17c2663
> --- /dev/null
> +++ b/src/setjmp/powerpc-sf/setjmp.s
> @@ -0,0 +1,43 @@
> +	.global ___setjmp
> +	.hidden ___setjmp
> +	.global __setjmp
> +	.global _setjmp
> +	.global setjmp
> +	.type   __setjmp,@function
> +	.type   _setjmp,@function
> +	.type   setjmp,@function
> +___setjmp:
> +__setjmp:
> +_setjmp:
> +setjmp:
> +	# 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)
> +	stw 1, 4(3)
> +	# 2) store cr
> +	mfcr 0
> +	stw 0, 8(3)
> +	# 3) store r14-31
> +	stw 14, 12(3)
> +	stw 15, 16(3)
> +	stw 16, 20(3)
> +	stw 17, 24(3)
> +	stw 18, 28(3)
> +	stw 19, 32(3)
> +	stw 20, 36(3)
> +	stw 21, 40(3)
> +	stw 22, 44(3)
> +	stw 23, 48(3)
> +	stw 24, 52(3)
> +	stw 25, 56(3)
> +	stw 26, 60(3)
> +	stw 27, 64(3)
> +	stw 28, 68(3)
> +	stw 29, 72(3)
> +	stw 30, 76(3)
> +	stw 31, 80(3)
> +	# 4) set return value to 0
> +	li 3, 0
> +	# 5) return
> +	blr
> diff --git a/src/setjmp/powerpc-sf/setjmp.sub b/src/setjmp/powerpc-sf/setjmp.sub
> new file mode 100644
> index 0000000..b7ad221
> --- /dev/null
> +++ b/src/setjmp/powerpc-sf/setjmp.sub
> @@ -0,0 +1 @@
> +setjmp.s
> -- 
> 2.2.2

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.