sfp-machine.h (__gcc_CMPtype, [...]): Move ...
authorUros Bizjak <ubizjak@gmail.com>
Sat, 9 Jun 2012 17:32:27 +0000 (19:32 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sat, 9 Jun 2012 17:32:27 +0000 (19:32 +0200)
* config/i386/32/sfp-machine.h (__gcc_CMPtype, CMPtype,
_FP_KEEPNANFRACP, _FP_CHOOSENAN, FP_EX_INVALID, FP_EX_DENORM,
FP_EX_DIVZERO, FP_EX_OVERFLOW, FP_EX_UNDERFLOW, FP_EX_INEXACT,
FP_HANDLE_EXCEPTIONS, FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF,
FP_RND_MINF, _FP_DEXL_EX, FP_INIT_ROUNDMODE, FP_ROUNDMODE,
__LITTLE_ENDIAN, __BIG_ENDIAN, strong_alias): Move ...
* config/i386/64/sfp-machine: ... (delete here) ...
* config/i386/sfp-machine.h: ... to here.
(FP_EX_MASK): New.
(__sfp_handle_exceptions): New function declaration.
(FP_HANDLE_EXCEPTIONS): Use __sfp_handle_exceptions.
* config/i386/sfp-exceptions.c: New.
* config/i386/t-softfp: New.
* config.host (i[34567]86-*-* and x86_64-*-* soft-fp targets): Add
i386/t-softfp to tmake_file.

From-SVN: r188361

libgcc/ChangeLog
libgcc/config.host
libgcc/config/i386/32/sfp-machine.h
libgcc/config/i386/64/sfp-machine.h
libgcc/config/i386/sfp-exceptions.c [new file with mode: 0644]
libgcc/config/i386/sfp-machine.h
libgcc/config/i386/t-softfp [new file with mode: 0644]

index bad8ec08610055b80d688442bed0455a984ecd70..dd1dc5504a5a10f9cbc51f2d0794081d69b640ea 100644 (file)
@@ -1,3 +1,21 @@
+2012-06-09  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/32/sfp-machine.h (__gcc_CMPtype, CMPtype,
+       _FP_KEEPNANFRACP, _FP_CHOOSENAN, FP_EX_INVALID, FP_EX_DENORM,
+       FP_EX_DIVZERO, FP_EX_OVERFLOW, FP_EX_UNDERFLOW, FP_EX_INEXACT,
+       FP_HANDLE_EXCEPTIONS, FP_RND_NEAREST, FP_RND_ZERO, FP_RND_PINF,
+       FP_RND_MINF, _FP_DEXL_EX, FP_INIT_ROUNDMODE, FP_ROUNDMODE,
+       __LITTLE_ENDIAN, __BIG_ENDIAN, strong_alias): Move ...
+       * config/i386/64/sfp-machine: ... (delete here) ...
+       * config/i386/sfp-machine.h: ... to here.
+       (FP_EX_MASK): New.
+       (__sfp_handle_exceptions): New function declaration.
+       (FP_HANDLE_EXCEPTIONS): Use __sfp_handle_exceptions.
+       * config/i386/sfp-exceptions.c: New.
+       * config/i386/t-softfp: New.
+       * config.host (i[34567]86-*-* and x86_64-*-* soft-fp targets): Add
+       i386/t-softfp to tmake_file.
+
 2012-06-03  David S. Miller  <davem@davemloft.net>
 
        * longlong.h [SPARC] (sub_ddmmss): Fix thinko in previous 64-bit
index 14c705b967b3fcb37ce7af37eaedda113815d0a1..d8ad48c5e042f572cee3cd2334a9559f62e35280 100644 (file)
@@ -1153,7 +1153,7 @@ i[34567]86-*-darwin* | x86_64-*-darwin* | \
        if test "${host_address}" = 32; then
                tmake_file="${tmake_file} i386/${host_address}/t-softfp"
        fi
-       tmake_file="${tmake_file} t-softfp"
+       tmake_file="${tmake_file} i386/t-softfp t-softfp"
        ;;
 esac
 
index 1600a7fe2c75840a4f75a9d85630804e05da37fb..6d4e5e17912f79f8b404f903e060e3d757569858 100644 (file)
@@ -3,11 +3,6 @@
 #define _FP_WS_TYPE            signed int
 #define _FP_I_TYPE             int
 
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
 #define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)   \
   __asm__ ("add{l} {%11,%3|%3,%11}\n\t"                                \
           "adc{l} {%9,%2|%2,%9}\n\t"                           \
@@ -85,122 +80,3 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
 #define _FP_NANSIGN_D          1
 #define _FP_NANSIGN_E          1
 #define _FP_NANSIGN_Q          1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if (_FP_FRAC_GT_##wc(X, Y)                                 \
-       || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
-      {                                                                \
-       R##_s = X##_s;                                          \
-        _FP_FRAC_COPY_##wc(R,X);                               \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-        _FP_FRAC_COPY_##wc(R,Y);                               \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-#define FP_EX_INVALID          0x01
-#define FP_EX_DENORM           0x02
-#define FP_EX_DIVZERO          0x04
-#define FP_EX_OVERFLOW         0x08
-#define FP_EX_UNDERFLOW                0x10
-#define FP_EX_INEXACT          0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS                                           \
-  do {                                                                 \
-    if (_fex & FP_EX_INVALID)                                          \
-      {                                                                        \
-       float f = 0.0;                                                  \
-       __asm__ __volatile__ ("fdiv {%y0, %0|%0, %y0}" : "+t" (f));     \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_DIVZERO)                                          \
-      {                                                                        \
-       float f = 1.0, g = 0.0;                                         \
-       __asm__ __volatile__ ("fdivp {%0, %y1|%y1, %0}"                 \
-                                     : "+t" (f) : "u" (g)              \
-                                     : "st(1)");                       \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_OVERFLOW)                                         \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_OVERFLOW;                           \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_UNDERFLOW)                                                \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_UNDERFLOW;                          \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_INEXACT)                                          \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_INEXACT;                            \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-  } while (0)
-
-#define FP_RND_NEAREST         0
-#define FP_RND_ZERO            0xc00
-#define FP_RND_PINF            0x800
-#define FP_RND_MINF            0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE                      \
-  do {                                         \
-    __asm__ ("fnstcw %0" : "=m" (_fcw));       \
-  } while (0)
-
-#define FP_ROUNDMODE           (_fcw & 0xc00)
-
-#define        __LITTLE_ENDIAN 1234
-#define        __BIG_ENDIAN    4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
-#else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
-#endif
index 7a2a4beaaaf416ef9c70da01e4b5e408ca0f8a06..469c28cfbc3963d4db9ae59ad2de29107dc5e29b 100644 (file)
@@ -1,5 +1,4 @@
 #define _FP_W_TYPE_SIZE                64
-
 #define _FP_W_TYPE             unsigned long long
 #define _FP_WS_TYPE            signed long long
 #define _FP_I_TYPE             long long
@@ -9,11 +8,6 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
 
 #define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
 
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
 #define _FP_MUL_MEAT_Q(R,X,Y)                           \
   _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
 
@@ -27,126 +21,3 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
 #define _FP_NANSIGN_D          1
 #define _FP_NANSIGN_E          1
 #define _FP_NANSIGN_Q          1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
-  do {                                                         \
-    if (_FP_FRAC_GT_##wc(X, Y)                                 \
-       || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
-      {                                                                \
-       R##_s = X##_s;                                          \
-        _FP_FRAC_COPY_##wc(R,X);                               \
-      }                                                                \
-    else                                                       \
-      {                                                                \
-       R##_s = Y##_s;                                          \
-        _FP_FRAC_COPY_##wc(R,Y);                               \
-      }                                                                \
-    R##_c = FP_CLS_NAN;                                                \
-  } while (0)
-
-#define FP_EX_INVALID          0x01
-#define FP_EX_DENORM           0x02
-#define FP_EX_DIVZERO          0x04
-#define FP_EX_OVERFLOW         0x08
-#define FP_EX_UNDERFLOW                0x10
-#define FP_EX_INEXACT          0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#ifdef __AVX__
- #define ASM_INVALID "vdivss %0, %0, %0"
- #define ASM_DIVZERO "vdivss %1, %0, %0"
-#else
- #define ASM_INVALID "divss %0, %0"
- #define ASM_DIVZERO "divss %1, %0"
-#endif
-
-#define FP_HANDLE_EXCEPTIONS                                           \
-  do {                                                                 \
-    if (_fex & FP_EX_INVALID)                                          \
-      {                                                                        \
-       float f = 0.0;                                                  \
-       __asm__ __volatile__ (ASM_INVALID : : "x" (f));                 \
-      }                                                                        \
-    if (_fex & FP_EX_DIVZERO)                                          \
-      {                                                                        \
-       float f = 1.0, g = 0.0;                                         \
-       __asm__ __volatile__ (ASM_DIVZERO : : "x" (f), "x" (g));        \
-      }                                                                        \
-    if (_fex & FP_EX_OVERFLOW)                                         \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_OVERFLOW;                           \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_UNDERFLOW)                                                \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_UNDERFLOW;                          \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-    if (_fex & FP_EX_INEXACT)                                          \
-      {                                                                        \
-       struct fenv temp;                                               \
-       __asm__ __volatile__ ("fnstenv %0" : "=m" (temp));              \
-       temp.__status_word |= FP_EX_INEXACT;                            \
-       __asm__ __volatile__ ("fldenv %0" : : "m" (temp));              \
-       __asm__ __volatile__ ("fwait");                                 \
-      }                                                                        \
-  } while (0)
-
-#define FP_RND_NEAREST         0
-#define FP_RND_ZERO            0xc00
-#define FP_RND_PINF            0x800
-#define FP_RND_MINF            0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE                      \
-  do {                                         \
-    __asm__ ("fnstcw %0" : "=m" (_fcw));       \
-  } while (0)
-
-#define FP_ROUNDMODE           (_fcw & 0xc00)
-
-#define        __LITTLE_ENDIAN 1234
-#define        __BIG_ENDIAN    4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
-#else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
-#endif
diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c
new file mode 100644 (file)
index 0000000..14b5ca1
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 3, or (at your option) any
+ * later version.
+ * 
+ * This file 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
+ * General Public License for more details.
+ * 
+ * Under Section 7 of GPL version 3, you are granted additional
+ * permissions described in the GCC Runtime Library Exception, version
+ * 3.1, as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License and
+ * a copy of the GCC Runtime Library Exception along with this program;
+ * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sfp-machine.h"
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+void
+__sfp_handle_exceptions (int _fex)
+{
+  if (_fex & FP_EX_INVALID)
+    {
+      float f = 0.0f;
+#ifdef __SSE__
+      asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
+#else
+      asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
+      asm volatile ("fwait");
+#endif
+    }
+  if (_fex & FP_EX_DIVZERO)
+    {
+      float f = 1.0f, g = 0.0f;
+#ifdef __SSE__
+      asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
+#else
+      asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
+      asm volatile ("fwait");
+#endif
+    }
+  if (_fex & FP_EX_OVERFLOW)
+    {
+      struct fenv temp;
+      asm volatile ("fnstenv\t%0" : "=m" (temp));
+      temp.__status_word |= FP_EX_OVERFLOW;
+      asm volatile ("fldenv\t%0" : : "m" (temp));
+      asm volatile ("fwait");
+    }
+  if (_fex & FP_EX_UNDERFLOW)
+    {
+      struct fenv temp;
+      asm volatile ("fnstenv\t%0" : "=m" (temp));
+      temp.__status_word |= FP_EX_UNDERFLOW;
+      asm volatile ("fldenv\t%0" : : "m" (temp));
+      asm volatile ("fwait");
+    }
+  if (_fex & FP_EX_INEXACT)
+    {
+      struct fenv temp;
+      asm volatile ("fnstenv\t%0" : "=m" (temp));
+      temp.__status_word |= FP_EX_INEXACT;
+      asm volatile ("fldenv\t%0" : : "m" (temp));
+      asm volatile ("fwait");
+    }
+};
index eb4b8bfb5fd87459f239313e4c3b63d613776a68..f84a368ebd1ebdba61d19e67fbeee02c76d73d80 100644 (file)
@@ -3,8 +3,83 @@
 #define _FP_STRUCT_LAYOUT  __attribute__ ((gcc_struct))
 #endif
 
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
 #ifdef __x86_64__
 #include "config/i386/64/sfp-machine.h"
 #else
 #include "config/i386/32/sfp-machine.h"
 #endif
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if (_FP_FRAC_GT_##wc(X, Y)                                 \
+       || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+      {                                                                \
+       R##_s = X##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,X);                               \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,Y);                               \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+#define FP_EX_INVALID          0x01
+#define FP_EX_DENORM           0x02
+#define FP_EX_DIVZERO          0x04
+#define FP_EX_OVERFLOW         0x08
+#define FP_EX_UNDERFLOW                0x10
+#define FP_EX_INEXACT          0x20
+
+#define FP_EX_MASK             0x3f
+
+void __sfp_handle_exceptions (int);
+
+#define FP_HANDLE_EXCEPTIONS                   \
+  do {                                         \
+    if (_fex & FP_EX_MASK)                     \
+      __sfp_handle_exceptions (_fex);          \
+  } while (0);
+
+#define FP_RND_NEAREST         0
+#define FP_RND_ZERO            0xc00
+#define FP_RND_PINF            0x800
+#define FP_RND_MINF            0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE                      \
+  do {                                         \
+    __asm__ ("fnstcw %0" : "=m" (_fcw));       \
+  } while (0)
+
+#define FP_ROUNDMODE           (_fcw & 0xc00)
+
+#define        __LITTLE_ENDIAN 1234
+#define        __BIG_ENDIAN    4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
diff --git a/libgcc/config/i386/t-softfp b/libgcc/config/i386/t-softfp
new file mode 100644 (file)
index 0000000..685d9cf
--- /dev/null
@@ -0,0 +1 @@
+LIB2ADD += $(srcdir)/config/i386/sfp-exceptions.c