From 5febc7ff25ecdbab6b445286887a4cf3b1083273 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 17 Aug 2013 18:31:05 +0930 Subject: [PATCH] PowerPC floating point little-endian [11 of 15] http://sourceware.org/ml/libc-alpha/2013-07/msg00202.html Another little-endian fix. * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using 64-bit int/double union. (_FPU_SETCW): Likewise. * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise. (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise. --- ChangeLog | 8 ++ sysdeps/powerpc/fpu/tst-setcontext-fpscr.c | 87 +++++++++++----------- sysdeps/powerpc/fpu_control.h | 32 ++++---- 3 files changed, 70 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34cc9c10b4..5327d980b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-10-04 Alan Modra + + * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using + 64-bit int/double union. + (_FPU_SETCW): Likewise. + * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise. + (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise. + 2013-10-04 Alan Modra * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite. diff --git a/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c b/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c index feffa6b4ff..cc9b320bfd 100644 --- a/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c +++ b/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c @@ -83,7 +83,7 @@ ElfW(Addr) query_auxv(int type) return 0; } -typedef unsigned long long di_fpscr_t __attribute__ ((__mode__ (__DI__))); +typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__))); typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__))); #define _FPSCR_RESERVED 0xfffffff8ffffff04ULL @@ -95,50 +95,51 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__))); #define _FPSCR_TEST1_RN 0x0000000000000002ULL /* Macros for accessing the hardware control word on Power6[x]. */ -# define _GET_DI_FPSCR(__fpscr) ({ \ - union { double d; \ - di_fpscr_t fpscr; } \ - tmp __attribute__ ((__aligned__(8))); \ - __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ - (__fpscr)=tmp.fpscr; \ - tmp.fpscr; }) - -/* We make sure to zero fp0 after we use it in order to prevent stale data +#define _GET_DI_FPSCR(__fpscr) \ + ({union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + __asm__ ("mffs %0" : "=f" (fr)); \ + u.d = fr; \ + (__fpscr) = u.fpscr; \ + u.fpscr; \ + }) + +/* We make sure to zero fp after we use it in order to prevent stale data in an fp register from making a test-case pass erroneously. */ -# define _SET_DI_FPSCR(__fpscr) { \ - union { double d; di_fpscr_t fpscr; } \ - tmp __attribute__ ((__aligned__(8))); \ - tmp.fpscr = __fpscr; \ - /* Set the entire 64-bit FPSCR. */ \ - __asm__ ("lfd%U0 0,%0; " \ - ".machine push; " \ - ".machine \"power6\"; " \ - "mtfsf 255,0,1,0; " \ - ".machine pop" : : "m" (tmp.d) : "fr0"); \ - tmp.d = 0; \ - __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \ -} - -# define _GET_SI_FPSCR(__fpscr) ({ \ - union { double d; \ - si_fpscr_t cw[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ - (__fpscr)=tmp.cw[1]; \ - tmp.cw[0]; }) - -/* We make sure to zero fp0 after we use it in order to prevent stale data +# define _SET_DI_FPSCR(__fpscr) \ + { union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + u.fpscr = __fpscr; \ + fr = u.d; \ + /* Set the entire 64-bit FPSCR. */ \ + __asm__ (".machine push; " \ + ".machine \"power6\"; " \ + "mtfsf 255,%0,1,0; " \ + ".machine pop" : : "f" (fr)); \ + fr = 0.0; \ + } + +# define _GET_SI_FPSCR(__fpscr) \ + ({union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + __asm__ ("mffs %0" : "=f" (fr)); \ + u.d = fr; \ + (__fpscr) = (si_fpscr_t) u.fpscr; \ + (si_fpscr_t) u.fpscr; \ + }) + +/* We make sure to zero fp after we use it in order to prevent stale data in an fp register from making a test-case pass erroneously. */ -# define _SET_SI_FPSCR(__fpscr) { \ - union { double d; si_fpscr_t fpscr[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - /* More-or-less arbitrary; this is a QNaN. */ \ - tmp.fpscr[0] = 0xFFF80000; \ - tmp.fpscr[1] = __fpscr; \ - __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \ - tmp.d = 0; \ - __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \ -} +# define _SET_SI_FPSCR(__fpscr) \ + { union { double d; di_fpscr_t fpscr; } u; \ + register double fr; \ + /* More-or-less arbitrary; this is a QNaN. */ \ + u.fpscr = 0xfff80000ULL << 32; \ + u.fpscr |= __fpscr & 0xffffffffULL; \ + fr = u.d; \ + __asm__ ("mtfsf 255,%0" : : "f" (fr)); \ + fr = 0.0; \ + } void prime_special_regs(int which) { diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h index 159543beed..c6c4cb96be 100644 --- a/sysdeps/powerpc/fpu_control.h +++ b/sysdeps/powerpc/fpu_control.h @@ -56,22 +56,26 @@ extern fpu_control_t __fpu_control; # define _FPU_IEEE 0x000000f0 /* Type of the control word. */ -typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); +typedef unsigned int fpu_control_t; /* Macros for accessing the hardware control word. */ -# define _FPU_GETCW(__cw) ( { \ - union { double d; fpu_control_t cw[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ - (__cw)=tmp.cw[1]; \ - tmp.cw[1]; } ) -# define _FPU_SETCW(__cw) { \ - union { double d; fpu_control_t cw[2]; } \ - tmp __attribute__ ((__aligned__(8))); \ - tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \ - tmp.cw[1] = __cw; \ - __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \ -} +# define _FPU_GETCW(cw) \ + ({union { double __d; unsigned long long __ll; } __u; \ + register double __fr; \ + __asm__ ("mffs %0" : "=f" (__fr)); \ + __u.__d = __fr; \ + (cw) = (fpu_control_t) __u.__ll; \ + (fpu_control_t) __u.__ll; \ + }) + +# define _FPU_SETCW(cw) \ + { union { double __d; unsigned long long __ll; } __u; \ + register double __fr; \ + __u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \ + __u.__ll |= (cw) & 0xffffffffLL; \ + __fr = __u.__d; \ + __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \ + } /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -- 2.43.5