]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
powerpc: Add a POWER8 implementation for GET|SET_FLOAT_WORD
authorTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Tue, 18 Oct 2016 17:30:23 +0000 (15:30 -0200)
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Tue, 18 Oct 2016 17:36:59 +0000 (15:36 -0200)
Provides a POWER8 implementation for GET_FLOAT_WORD and SET_FLOAT_WORD
that is able to extract or set a float using only VSR and GPR.

This is a workaround for GCC bug #70568.

ChangeLog
sysdeps/powerpc/powerpc64/power8/fpu/math_private.h [new file with mode: 0644]

index b0c1d93209f5f92c536bd65f1eb80d2c6d76ce2f..7a68f49b4bf904e0755f0952c55f79e51098d237 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-18  Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
+
+       * sysdeps/powerpc/powerpc64/power8/fpu/math_private.h (GET_FLOAT_WORD):
+       (SET_FLOAT_WORD): New macros.
+
 2016-09-19  Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
 
        [BZ #20615]
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/math_private.h b/sysdeps/powerpc/powerpc64/power8/fpu/math_private.h
new file mode 100644 (file)
index 0000000..fe00c73
--- /dev/null
@@ -0,0 +1,49 @@
+/* Private inline math functions for POWER8.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The compiler isn't extracting this without going through memory, so
+   we use some VSX scalar instructions to convert to the 32b format
+   and move to a GPR.  */
+#define GET_FLOAT_WORD(i,d)                    \
+  do {                                         \
+      float tmpd = d;                          \
+      double tmp;                              \
+      long tmpi;                               \
+      __asm__ ("xscvdpspn %x1, %x2\n\t"                \
+              "mfvsrd %0, %x1\n\t"             \
+              : "=wr" (tmpi),                  \
+                "=wa" (tmp)                    \
+              : "wa" (tmpd) );                 \
+      i = tmpi >> 32;                          \
+    } while(0)
+
+/* To ensure that we don't go through memory, we use some VSX scalar
+   instructions to move VSR and to convert to the 32b format.  */
+#define SET_FLOAT_WORD(d,i)            \
+  do {                                 \
+    long tmpi = i;                     \
+    float tmpd;                                \
+    tmpi = tmpi << 32;                 \
+    __asm__ ("mtvsrd %x0, %1\n\t"      \
+            "xscvspdpn %x0, %x0\n\t"   \
+            : "=wa" (tmpd)             \
+            : "wr" (tmpi) );           \
+    d = tmpd;                          \
+  } while(0)
+
+#include_next <math_private.h>