Add -mlong-double-64/-mlong-double-80 to i386
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2012 19:46:28 +0000 (19:46 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2012 19:46:28 +0000 (19:46 +0000)
gcc/

* doc/invoke.texi: Document -mlong-double-64/-mlong-double-80.

* config/i386/i386.c (flag_opts): Add -mlong-double-64.
(TARGET_HAS_BIONIC): Default long double to 64-bit for Bionic.

* config/i386/i386.h (LONG_DOUBLE_TYPE_SIZE): Use 64 if
TARGET_LONG_DOUBLE_64 is true.
(LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New macro.
(WIDEST_HARDWARE_FP_SIZE): Defined to 80.

* config/i386/i386.opt (mlong-double-80): New option.
(mlong-double-64): Likewise.

* config/i386/i386-c.c (ix86_target_macros): Define
__LONG_DOUBLE_64__ for TARGET_LONG_DOUBLE_64.

gcc/testsuite/

* gcc.target/i386/long-double-64-1.c: New file.
* gcc.target/i386/long-double-64-2.c: Likewise.
* gcc.target/i386/long-double-64-3.c: Likewise.
* gcc.target/i386/long-double-64-4.c: Likewise.
* gcc.target/i386/long-double-80-1.c: Likewise.
* gcc.target/i386/long-double-80-2.c: Likewise.
* gcc.target/i386/long-double-80-3.c: Likewise.
* gcc.target/i386/long-double-80-4.c: Likewise.
* gcc.target/i386/long-double-80-5.c: Likewise.
* gcc.target/i386/long-double-80-6.c: Likewise.
* gcc.target/i386/long-double-80-7.c: Likewise.

libgcc/

* config/i386/t-linux (HOST_LIBGCC2_CFLAGS): New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190599 138bc75d-0d04-0410-961f-82ee72b054a4

20 files changed:
gcc/ChangeLog
gcc/config/i386/i386-c.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/long-double-64-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-64-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-64-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-64-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/long-double-80-7.c [new file with mode: 0644]
libgcc/ChangeLog
libgcc/config/i386/t-linux

index 085bef1..f67c4ac 100644 (file)
@@ -1,5 +1,23 @@
 2012-08-22  H.J. Lu  <hongjiu.lu@intel.com>
 
+       * doc/invoke.texi: Document -mlong-double-64/-mlong-double-80.
+
+       * config/i386/i386.c (flag_opts): Add -mlong-double-64.
+       (TARGET_HAS_BIONIC): Default long double to 64-bit for Bionic.
+
+       * config/i386/i386.h (LONG_DOUBLE_TYPE_SIZE): Use 64 if
+       TARGET_LONG_DOUBLE_64 is true.
+       (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New macro.
+       (WIDEST_HARDWARE_FP_SIZE): Defined to 80.
+
+       * config/i386/i386.opt (mlong-double-80): New option.
+       (mlong-double-64): Likewise.
+
+       * config/i386/i386-c.c (ix86_target_macros): Define
+       __LONG_DOUBLE_64__ for TARGET_LONG_DOUBLE_64.
+
+2012-08-22  H.J. Lu  <hongjiu.lu@intel.com>
+
        PR target/54347
        * config/i386/i386.c (ix86_split_to_parts): Replace
        REAL_VALUE_TO_TARGET_LONG_DOUBLE with real_to_target.
index d00e0ba..edd64ff 100644 (file)
@@ -409,6 +409,9 @@ ix86_target_macros (void)
       builtin_define_std ("i386");
     }
 
+  if (TARGET_LONG_DOUBLE_64)
+    cpp_define (parse_in, "__LONG_DOUBLE_64__");
+
   cpp_define_formatted (parse_in, "__ATOMIC_HLE_ACQUIRE=%d", IX86_HLE_ACQUIRE);
   cpp_define_formatted (parse_in, "__ATOMIC_HLE_RELEASE=%d", IX86_HLE_RELEASE);
 
index a6fc45b..da931ee 100644 (file)
@@ -2786,6 +2786,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
   static struct ix86_target_opts flag_opts[] =
   {
     { "-m128bit-long-double",          MASK_128BIT_LONG_DOUBLE },
+    { "-mlong-double-64",              MASK_LONG_DOUBLE_64 },
     { "-m80387",                       MASK_80387 },
     { "-maccumulate-outgoing-args",    MASK_ACCUMULATE_OUTGOING_ARGS },
     { "-malign-double",                        MASK_ALIGN_DOUBLE },
@@ -4084,6 +4085,11 @@ ix86_option_override_internal (bool main_args_p)
   else if (target_flags_explicit & MASK_RECIP)
     recip_mask &= ~(RECIP_MASK_ALL & ~recip_mask_explicit);
 
+  /* Default long double to 64-bit for Bionic.  */
+  if (TARGET_HAS_BIONIC
+      && !(target_flags_explicit & MASK_LONG_DOUBLE_64))
+    target_flags |= MASK_LONG_DOUBLE_64;
+
   /* Save the initial options in case the user does function specific
      options.  */
   if (main_args_p)
index 11f79e3..3a41a43 100644 (file)
@@ -671,9 +671,17 @@ enum target_cpu_default
 #define LONG_LONG_TYPE_SIZE 64
 #define FLOAT_TYPE_SIZE 32
 #define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 80
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_64 ? 64 : 80)
 
-#define WIDEST_HARDWARE_FP_SIZE LONG_DOUBLE_TYPE_SIZE
+/* Define this to set long double type size to use in libgcc2.c, which can
+   not depend on target_flags.  */
+#ifdef __LONG_DOUBLE_64__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80
+#endif
+
+#define WIDEST_HARDWARE_FP_SIZE 80
 
 #if defined (TARGET_BI_ARCH) || TARGET_64BIT_DEFAULT
 #define MAX_BITS_PER_WORD 64
index e4f78f3..6a38994 100644 (file)
@@ -86,6 +86,14 @@ m96bit-long-double
 Target RejectNegative Report InverseMask(128BIT_LONG_DOUBLE) Save
 sizeof(long double) is 12
 
+mlong-double-80
+Target Report RejectNegative InverseMask(LONG_DOUBLE_64) Save
+Use 80-bit long double
+
+mlong-double-64
+Target Report RejectNegative Mask(LONG_DOUBLE_64) Save
+Use 64-bit long double
+
 maccumulate-outgoing-args
 Target Report Mask(ACCUMULATE_OUTGOING_ARGS) Save
 Reserve space for outgoing arguments in the function prologue
index 599b0f6..5404a3c 100644 (file)
@@ -636,7 +636,8 @@ Objective-C and Objective-C++ Dialects}.
 -mno-align-stringops  -minline-all-stringops @gol
 -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
 -mpush-args  -maccumulate-outgoing-args  -m128bit-long-double @gol
--m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
+-m96bit-long-double -mlong-double-64 -mlong-double-80 @gol
+-mregparm=@var{num}  -msseregparm @gol
 -mveclibabi=@var{type} -mvect8-ret-in-mem @gol
 -mpc32 -mpc64 -mpc80 -mstackrealign @gol
 -momit-leaf-frame-pointer  -mno-red-zone -mno-tls-direct-seg-refs @gol
@@ -13517,6 +13518,21 @@ as well as modifying the function calling convention for functions taking
 @code{long double}.  Hence they are not binary-compatible
 with code compiled without that switch.
 
+@item -mlong-double-64
+@itemx -mlong-double-80
+@opindex mlong-double-64
+@opindex mlong-double-80
+These switches control the size of @code{long double} type. A size
+of 64 bits makes the @code{long double} type equivalent to the @code{double}
+type. This is the default for Bionic C library.
+
+@strong{Warning:} if you override the default value for your target ABI, this
+changes the size of
+structures and arrays containing @code{long double} variables,
+as well as modifying the function calling convention for functions taking
+@code{long double}.  Hence they are not binary-compatible
+with code compiled without that switch.
+
 @item -mlarge-data-threshold=@var{threshold}
 @opindex mlarge-data-threshold
 When @option{-mcmodel=medium} is specified, data objects larger than
index 049e2d1..ed45fc0 100644 (file)
@@ -1,3 +1,17 @@
+2012-08-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gcc.target/i386/long-double-64-1.c: New file.
+       * gcc.target/i386/long-double-64-2.c: Likewise.
+       * gcc.target/i386/long-double-64-3.c: Likewise.
+       * gcc.target/i386/long-double-64-4.c: Likewise.
+       * gcc.target/i386/long-double-80-1.c: Likewise.
+       * gcc.target/i386/long-double-80-2.c: Likewise.
+       * gcc.target/i386/long-double-80-3.c: Likewise.
+       * gcc.target/i386/long-double-80-4.c: Likewise.
+       * gcc.target/i386/long-double-80-5.c: Likewise.
+       * gcc.target/i386/long-double-80-6.c: Likewise.
+       * gcc.target/i386/long-double-80-7.c: Likewise.
+
 2012-08-22  Marc Glisse  <marc.glisse@inria.fr>
 
        PR tree-optimization/54317
diff --git a/gcc/testsuite/gcc.target/i386/long-double-64-1.c b/gcc/testsuite/gcc.target/i386/long-double-64-1.c
new file mode 100644 (file)
index 0000000..cf93379
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlong-double-64" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler-not "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-64-2.c b/gcc/testsuite/gcc.target/i386/long-double-64-2.c
new file mode 100644 (file)
index 0000000..ddf4fe6
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -mbionic" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler-not "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-64-3.c b/gcc/testsuite/gcc.target/i386/long-double-64-3.c
new file mode 100644 (file)
index 0000000..e748fab
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -mandroid" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler-not "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-64-4.c b/gcc/testsuite/gcc.target/i386/long-double-64-4.c
new file mode 100644 (file)
index 0000000..d9c25aa
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlong-double-80 -mlong-double-64" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler-not "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-1.c b/gcc/testsuite/gcc.target/i386/long-double-80-1.c
new file mode 100644 (file)
index 0000000..d3b75a0
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlong-double-80" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-2.c b/gcc/testsuite/gcc.target/i386/long-double-80-2.c
new file mode 100644 (file)
index 0000000..954dfd1
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -mlong-double-80 -mbionic" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-3.c b/gcc/testsuite/gcc.target/i386/long-double-80-3.c
new file mode 100644 (file)
index 0000000..e0e8365
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -mlong-double-80 -mandroid" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-4.c b/gcc/testsuite/gcc.target/i386/long-double-80-4.c
new file mode 100644 (file)
index 0000000..cac2d55
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlong-double-64 -mlong-double-80" } */
+
+long double
+foo (long double x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-5.c b/gcc/testsuite/gcc.target/i386/long-double-80-5.c
new file mode 100644 (file)
index 0000000..4aa606f
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mlong-double-64" } */
+
+__float80
+foo (__float80 x)
+{
+  return x * x;
+}
+
+/* { dg-final { scan-assembler "fldt" } } */
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-6.c b/gcc/testsuite/gcc.target/i386/long-double-80-6.c
new file mode 100644 (file)
index 0000000..a395a26
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-O0 -mlong-double-64 -mfpmath=387" } */
+
+int
+main ()
+{
+  __float80 a = -0.23456789;
+  if ((double) a >= 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/long-double-80-7.c b/gcc/testsuite/gcc.target/i386/long-double-80-7.c
new file mode 100644 (file)
index 0000000..9b30fe8
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-O0 -mlong-double-64 -mfpmath=sse" } */
+/* { dg-require-effective-target sse2 } */
+
+#include "sse2-check.h"
+
+static void
+sse2_test (void)
+{
+  __float80 a = -0.23456789;
+  if ((double) a >= 0)
+    __builtin_abort ();
+}
index 0d4d78d..d59a455 100644 (file)
@@ -1,3 +1,7 @@
+2012-08-22  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/i386/t-linux (HOST_LIBGCC2_CFLAGS): New.
+
 2012-08-22  Joseph Myers  <joseph@codesourcery.com>
 
        * Makefile.in (vis_hide, gen-hide-list): Do not make definitions
index 29b4c22..4f47f7b 100644 (file)
@@ -2,3 +2,5 @@
 # Need to support TImode for x86.  Override the settings from
 # t-slibgcc-elf-ver and t-linux
 SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-glibc.ver
+
+HOST_LIBGCC2_CFLAGS += -mlong-double-80