5de29b
# commit 9c008155b7d5d1bd81d909497850a2ece28aec50
5de29b
# Author: Alan Modra <amodra@gmail.com>
5de29b
# Date:   Sat Aug 17 18:31:05 2013 +0930
5de29b
# 
5de29b
#     PowerPC floating point little-endian [11 of 15]
5de29b
#     http://sourceware.org/ml/libc-alpha/2013-07/msg00202.html
5de29b
#     
5de29b
#     Another little-endian fix.
5de29b
#     
5de29b
#         * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using
5de29b
#         64-bit int/double union.
5de29b
#         (_FPU_SETCW): Likewise.
5de29b
#         * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise.
5de29b
#         (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise.
5de29b
# 
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h	2014-05-27 22:40:18.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h	2014-05-27 22:43:40.000000000 -0500
5de29b
@@ -45,22 +45,26 @@
5de29b
 #define _FPU_IEEE     0x000000f0
5de29b
 
5de29b
 /* Type of the control word.  */
5de29b
-typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
5de29b
+typedef unsigned int fpu_control_t;
5de29b
 
5de29b
 /* Macros for accessing the hardware control word.  */
5de29b
-#define _FPU_GETCW(__cw) ( { \
5de29b
-  union { double d; fpu_control_t cw[2]; } \
5de29b
-    tmp __attribute__ ((__aligned__(8))); \
5de29b
-  __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \
5de29b
-  (__cw)=tmp.cw[1]; \
5de29b
-  tmp.cw[1]; } )
5de29b
-#define _FPU_SETCW(__cw) { \
5de29b
-  union { double d; fpu_control_t cw[2]; } \
5de29b
-    tmp __attribute__ ((__aligned__(8))); \
5de29b
-  tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \
5de29b
-  tmp.cw[1] = __cw; \
5de29b
-  __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \
5de29b
-}
5de29b
+#define _FPU_GETCW(cw)						\
5de29b
+  ({union { double __d; unsigned long long __ll; } __u;		\
5de29b
+    register double __fr;					\
5de29b
+    __asm__ ("mffs %0" : "=f" (__fr));				\
5de29b
+    __u.__d = __fr;						\
5de29b
+    (cw) = (fpu_control_t) __u.__ll;				\
5de29b
+    (fpu_control_t) __u.__ll;					\
5de29b
+  })
5de29b
+
5de29b
+#define _FPU_SETCW(cw)						\
5de29b
+  { union { double __d; unsigned long long __ll; } __u;		\
5de29b
+    register double __fr;					\
5de29b
+    __u.__ll = 0xfff80000LL << 32; /* This is a QNaN.  */	\
5de29b
+    __u.__ll |= (cw) & 0xffffffffLL;				\
5de29b
+    __fr = __u.__d;						\
5de29b
+    __asm__ ("mtfsf 255,%0" : : "f" (__fr));			\
5de29b
+  }
5de29b
 
5de29b
 /* Default control word set at startup.  */
5de29b
 extern fpu_control_t __fpu_control;
12745e
diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
12745e
--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c	2014-05-27 22:40:18.000000000 -0500
12745e
+++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c	2014-05-27 22:40:21.000000000 -0500
5de29b
@@ -83,7 +83,7 @@
5de29b
   return 0;
5de29b
 }
5de29b
 
5de29b
-typedef unsigned long long di_fpscr_t __attribute__ ((__mode__ (__DI__)));
5de29b
+typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__)));
5de29b
 typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
5de29b
 
5de29b
 #define _FPSCR_RESERVED 0xfffffff8ffffff04ULL
5de29b
@@ -95,50 +95,51 @@
5de29b
 #define _FPSCR_TEST1_RN  0x0000000000000002ULL
5de29b
 
5de29b
 /* Macros for accessing the hardware control word on Power6[x].  */
5de29b
-# define _GET_DI_FPSCR(__fpscr) ({					     \
5de29b
-   union { double d;							     \
5de29b
-           di_fpscr_t fpscr; }						     \
5de29b
-     tmp __attribute__ ((__aligned__(8)));				     \
5de29b
-   __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0");		     \
5de29b
-   (__fpscr)=tmp.fpscr;							     \
5de29b
-   tmp.fpscr; })
5de29b
+#define _GET_DI_FPSCR(__fpscr)						\
5de29b
+  ({union { double d; di_fpscr_t fpscr; } u;				\
5de29b
+    register double fr;							\
5de29b
+    __asm__ ("mffs %0" : "=f" (fr));					\
5de29b
+    u.d = fr;								\
5de29b
+    (__fpscr) = u.fpscr;						\
5de29b
+    u.fpscr;								\
5de29b
+  })
5de29b
 
5de29b
-/* We make sure to zero fp0 after we use it in order to prevent stale data
5de29b
+/* We make sure to zero fp after we use it in order to prevent stale data
5de29b
    in an fp register from making a test-case pass erroneously.  */
5de29b
-# define _SET_DI_FPSCR(__fpscr) {					     \
5de29b
-  union { double d; di_fpscr_t fpscr; }					     \
5de29b
-    tmp __attribute__ ((__aligned__(8)));				     \
5de29b
-  tmp.fpscr = __fpscr;							     \
5de29b
-  /* Set the entire 64-bit FPSCR.  */					     \
5de29b
-  __asm__ ("lfd%U0 0,%0; "						     \
5de29b
-	   ".machine push; "						     \
5de29b
-	   ".machine \"power6\"; "					     \
5de29b
-	   "mtfsf 255,0,1,0; "						     \
5de29b
-	   ".machine pop" : : "m" (tmp.d) : "fr0");			     \
5de29b
-  tmp.d = 0;								     \
5de29b
-  __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0");			     \
5de29b
-}
5de29b
-
5de29b
-# define _GET_SI_FPSCR(__fpscr) ({					     \
5de29b
-   union { double d;							     \
5de29b
-           si_fpscr_t cw[2]; }						     \
5de29b
-     tmp __attribute__ ((__aligned__(8)));				     \
5de29b
-   __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0");		     \
5de29b
-   (__fpscr)=tmp.cw[1];							     \
5de29b
-   tmp.cw[0]; })
5de29b
+# define _SET_DI_FPSCR(__fpscr)						\
5de29b
+  { union { double d; di_fpscr_t fpscr; } u;				\
5de29b
+    register double fr;							\
5de29b
+    u.fpscr = __fpscr;							\
5de29b
+    fr = u.d;								\
5de29b
+    /* Set the entire 64-bit FPSCR.  */					\
5de29b
+    __asm__ (".machine push; "						\
5de29b
+	     ".machine \"power6\"; "					\
5de29b
+	     "mtfsf 255,%0,1,0; "					\
5de29b
+	     ".machine pop" : : "f" (fr));				\
5de29b
+    fr = 0.0;								\
5de29b
+  }
5de29b
+
5de29b
+# define _GET_SI_FPSCR(__fpscr)						\
5de29b
+  ({union { double d; di_fpscr_t fpscr; } u;				\
5de29b
+    register double fr;							\
5de29b
+    __asm__ ("mffs %0" : "=f" (fr));					\
5de29b
+    u.d = fr;								\
5de29b
+    (__fpscr) = (si_fpscr_t) u.fpscr;					\
5de29b
+    (si_fpscr_t) u.fpscr;						\
5de29b
+  })
5de29b
 
5de29b
-/* We make sure to zero fp0 after we use it in order to prevent stale data
5de29b
+/* We make sure to zero fp after we use it in order to prevent stale data
5de29b
    in an fp register from making a test-case pass erroneously.  */
5de29b
-# define _SET_SI_FPSCR(__fpscr) {					     \
5de29b
-  union { double d; si_fpscr_t fpscr[2]; }				     \
5de29b
-    tmp __attribute__ ((__aligned__(8)));				     \
5de29b
-  /* More-or-less arbitrary; this is a QNaN. */				     \
5de29b
-  tmp.fpscr[0] = 0xFFF80000;						     \
5de29b
-  tmp.fpscr[1] = __fpscr;						     \
5de29b
-  __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0");		     \
5de29b
-  tmp.d = 0;								     \
5de29b
-  __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0");			     \
5de29b
-}
5de29b
+# define _SET_SI_FPSCR(__fpscr)						\
5de29b
+  { union { double d; di_fpscr_t fpscr; } u;				\
5de29b
+    register double fr;							\
5de29b
+    /* More-or-less arbitrary; this is a QNaN. */			\
5de29b
+    u.fpscr = 0xfff80000ULL << 32;					\
5de29b
+    u.fpscr |= __fpscr & 0xffffffffULL;					\
5de29b
+    fr = u.d;								\
5de29b
+    __asm__ ("mtfsf 255,%0" : : "f" (fr));				\
5de29b
+    fr = 0.0;								\
5de29b
+  }
5de29b
 
5de29b
 void prime_special_regs(int which)
5de29b
 {