]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / powerpc / fpu / tst-setcontext-fpscr.c
index 973fb3f77ad397dc166e319e6d32a37530de6089..222aea442ea6c4896f1e2625243a96932bfa1caa 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001,2002,2004,2006,2007,2008 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ryan S. Arnold <rsa@us.ibm.com>
                   Sean Curry <spcurry@us.ibm.com>
@@ -14,9 +14,8 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
 
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <ucontext.h>
 #include <unistd.h>
-#include <malloc.h>
 #include <link.h>
 #include <elf.h>
-#include <sysdep.h>
 #include <fpu_control.h>
+#include <sys/auxv.h>
+#include <support/support.h>
 
 static ucontext_t ctx[3];
 
@@ -60,11 +59,11 @@ ElfW(Addr) query_auxv(int type)
          perror("Error opening file for reading");
          return 0;
        }
-      auxv = (ElfW(auxv_t) *)malloc(getpagesize());
+      auxv = xmalloc (getpagesize ());
 
       do
        {
-         fread(&auxv_struct, sizeof(ElfW(auxv_t)), 1, auxv_f);
+         fread (&auxv_struct, sizeof (ElfW(auxv_t)), 1, auxv_f);
          auxv[i] = auxv_struct;
          i++;
        } while(auxv_struct.a_type != AT_NULL);
@@ -84,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
@@ -96,38 +95,47 @@ 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; })
-
-# 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; mtfsf 255,0,1,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]; })
-
-# 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");                     \
-}
+#define _GET_DI_FPSCR(__fpscr)                                         \
+  ({union { double d; di_fpscr_t fpscr; } u;                           \
+    u.d = __builtin_mffs ();                                           \
+    (__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; } 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;                           \
+    u.d = __builtin_mffs ();                                           \
+    (__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; 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;                                                          \
+    __builtin_mtfsf (255, fr);                                         \
+    fr = 0.0;                                                          \
+  }
 
 void prime_special_regs(int which)
 {