diff options
Diffstat (limited to 'gcc-4.6')
18 files changed, 164 insertions, 11 deletions
diff --git a/gcc-4.6/gcc/config/i386/i386-c.c b/gcc-4.6/gcc/config/i386/i386-c.c index 149735133..ee9a57699 100644 --- a/gcc-4.6/gcc/config/i386/i386-c.c +++ b/gcc-4.6/gcc/config/i386/i386-c.c @@ -376,6 +376,9 @@ ix86_target_macros (void) builtin_define_std ("i386"); } + if (TARGET_LONG_DOUBLE_64) + cpp_define (parse_in, "__LONG_DOUBLE_64__"); + ix86_target_macros_internal (ix86_isa_flags, ix86_arch, ix86_tune, diff --git a/gcc-4.6/gcc/config/i386/i386.c b/gcc-4.6/gcc/config/i386/i386.c index 6117e7d7b..b99d31150 100644 --- a/gcc-4.6/gcc/config/i386/i386.c +++ b/gcc-4.6/gcc/config/i386/i386.c @@ -3125,6 +3125,7 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune, 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 }, @@ -4292,7 +4293,13 @@ ix86_option_override_internal (bool main_args_p) #endif } - /* Save the initial options in case the user does function specific options */ + /* 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) target_option_default_node = target_option_current_node = build_target_option_node (); @@ -19419,7 +19426,9 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode) parts[2] = gen_int_mode (l[2], SImode); break; case XFmode: - REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); + /* We can't use REAL_VALUE_TO_TARGET_LONG_DOUBLE since + long double may not be 80-bit. */ + real_to_target (l, &r, mode); parts[2] = gen_int_mode (l[2], SImode); break; case DFmode: diff --git a/gcc-4.6/gcc/config/i386/i386.h b/gcc-4.6/gcc/config/i386/i386.h index dcb3f295a..678071f27 100644 --- a/gcc-4.6/gcc/config/i386/i386.h +++ b/gcc-4.6/gcc/config/i386/i386.h @@ -659,9 +659,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 diff --git a/gcc-4.6/gcc/config/i386/i386.opt b/gcc-4.6/gcc/config/i386/i386.opt index dca06e7aa..9deba3e01 100644 --- a/gcc-4.6/gcc/config/i386/i386.opt +++ b/gcc-4.6/gcc/config/i386/i386.opt @@ -73,6 +73,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 diff --git a/gcc-4.6/gcc/doc/invoke.texi b/gcc-4.6/gcc/doc/invoke.texi index 98c270cd4..780f108e0 100644 --- a/gcc-4.6/gcc/doc/invoke.texi +++ b/gcc-4.6/gcc/doc/invoke.texi @@ -626,7 +626,8 @@ Objective-C and Objective-C++ Dialects}. -mthreads -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 @@ -12914,11 +12915,20 @@ its ABI specifies that @code{long double} is to be aligned on 16 byte boundary. Notice that neither of these options enable any extra precision over the x87 standard of 80 bits for a @code{long double}. -@strong{Warning:} if you override the default value for your target ABI, the -structures and arrays containing @code{long double} variables will change -their size as well as function calling convention for function taking -@code{long double} will be modified. Hence they will not be binary -compatible with arrays or structures in 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{number} @opindex mlarge-data-threshold=@var{number} diff --git a/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-1.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-1.c new file mode 100644 index 000000000..cf933796f --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-1.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-64-2.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-2.c new file mode 100644 index 000000000..ddf4fe656 --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-2.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-64-3.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-3.c new file mode 100644 index 000000000..e748fab2e --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-3.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-64-4.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-4.c new file mode 100644 index 000000000..d9c25aaec --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-64-4.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-1.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-1.c new file mode 100644 index 000000000..d3b75a0be --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-1.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-2.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-2.c new file mode 100644 index 000000000..954dfd15d --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-2.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-3.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-3.c new file mode 100644 index 000000000..e0e8365e3 --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-3.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-4.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-4.c new file mode 100644 index 000000000..cac2d55bc --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-4.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-5.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-5.c new file mode 100644 index 000000000..4aa606fd1 --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-5.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-6.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-6.c new file mode 100644 index 000000000..a395a2659 --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-6.c @@ -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-4.6/gcc/testsuite/gcc.target/i386/long-double-80-7.c b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-7.c new file mode 100644 index 000000000..9b30fe885 --- /dev/null +++ b/gcc-4.6/gcc/testsuite/gcc.target/i386/long-double-80-7.c @@ -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 (); +} diff --git a/gcc-4.6/libgcc/config.host b/gcc-4.6/libgcc/config.host index 2516c0a0c..914acb9d2 100644 --- a/gcc-4.6/libgcc/config.host +++ b/gcc-4.6/libgcc/config.host @@ -600,7 +600,7 @@ case ${host} in i[34567]86-*-linux* | x86_64-*-linux* | \ i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | \ i[34567]86-*-gnu*) - tmake_file="${tmake_file} t-tls i386/t-cpuinfo" + tmake_file="${tmake_file} t-tls i386/t-cpuinfo i386/t-linux" if test "$libgcc_cv_cfi" = "yes"; then tmake_file="${tmake_file} t-stack i386/t-stack-i386" fi diff --git a/gcc-4.6/libgcc/config/i386/t-linux b/gcc-4.6/libgcc/config/i386/t-linux new file mode 100644 index 000000000..7595cdeed --- /dev/null +++ b/gcc-4.6/libgcc/config/i386/t-linux @@ -0,0 +1 @@ +HOST_LIBGCC2_CFLAGS += -mlong-double-80 |