]> sourceware.org Git - glibc.git/commitdiff
PowerPC floating point little-endian [11 of 15]
authorAlan Modra <amodra@gmail.com>
Sat, 17 Aug 2013 09:01:05 +0000 (18:31 +0930)
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Fri, 15 Nov 2013 17:28:53 +0000 (11:28 -0600)
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
sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
sysdeps/powerpc/fpu_control.h

index 34cc9c10b4c4b2cf7e1bb636c4b01e7d9ccec3c0..5327d980b9de2ddc5a2c857b31c67e36e1c9e6cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2013-10-04  Alan Modra  <amodra@gmail.com>
+
+       * 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  <amodra@gmail.com>
 
        * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
index feffa6b4ffd0a27496c66f161be9f27a1cf27a03..cc9b320bfd25caf6f660e58b7404dc22f8c99e21 100644 (file)
@@ -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)
 {
index 159543beed27116be2d512ab6fe3bcaeba2cafe7..c6c4cb96beb7be70dbd56544760083b96b577c7b 100644 (file)
@@ -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;
This page took 0.119699 seconds and 5 git commands to generate.