From: Andreas Krebbel Date: Fri, 3 Feb 2006 07:52:57 +0000 (+0000) Subject: re PR target/25864 (Enable IBM long double format in 32-bit PowerPC Linux) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f61a2c7da855928032ffe9293483c5c9584f7ceb;p=gcc.git re PR target/25864 (Enable IBM long double format in 32-bit PowerPC Linux) 2006-02-03 Andreas Krebbel Ulrich Weigand PR target/25864 * config/s390/2084.md ("x_fsimptf", "x_fmultf", "x_fdivtf", "x_floadtf", "x_ftrunctf", "x_ftruncdf"): New insn reservations. * config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): New functions. * config/s390/s390.c (struct processor_costs): Add mxbr, sqxbr, dxbr and dxr fields. (z900_cost, z990_cost, z9_109_cost): Values for the new fields added. (s390_rtx_costs): Use the new fields to calculate rtx costs. (s390_secondary_input_reload_class, s390_secondary_output_reload_class): Define secondary reloads for TFmode moves. (constant_modes): Add TFmode. (NR_C_MODES): Set to 8. * config/s390/s390.h (TARGET_CPU_CPP_BUILTINS): Add __LONG_DOUBLE_128__ builtin define. (LONG_DOUBLE_TYPE_SIZE): Set to 128 or 64. (LIBGCC2_LONG_DOUBLE_TYPE_SIZE, WIDEST_HARDWARE_FP_SIZE): Define. (HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, CLASS_MAX_NREGS, CANNOT_CHANGE_MODE_CLASS): Consider TFmode. * config/s390/s390.md ("type" attribute): Add fsimptf, floadtf, fmultf, fdivtf, fsqrttf, ftrunctf, ftruncdf as possible values. (FPR mode macro): Add TFmode. (DSF mode macro): New. (, mode attributes): Removed. (, , , , mode attributes): New. ("*cmp_ccs_0", "*cmp_ccs_0_ibm", "*cmp_ccs", "*cmp_ccs_ibm", "fix_trunc2_ieee", "floatdi2", "floatsi2_ieee", "*add3", "*add3_cc", "*add3_cconly", "*add3_ibm", "*sub3", "*sub3_cc", "*sub3_cconly", "*sub3_ibm", "*mul3_ibm", "*fmadd", "*fmsub", "*div3", "*div3_ibm", "*neg2_cc", "*neg2_cconly", "*neg2", "*neg2_ibm", "*abs2_cc", "*abs2_cconly", "*abs2", "*abs2_ibm", "*negabs2_cc", "*negabs2_cconly", "*negabs2", "sqrt2"): Changed to . R constraint replaced by . ("*mul3"): Changed to . R constraint replaced by . ("fix_truncdi2"): 'FPR:' removed. ("*fmadd", "*fmsub"): FPR mode replaced by DSF. ("*movtf_64", "*movtf_31"): New insn definitions followed by 5 splitters. ("movtf", "reload_outtf", "reload_intf", "trunctfdf2", "trunctfsf2", "extenddftf2", "extendsftf2"): New expanders. ("*trunctfdf2_ieee", "*trunctfdf2_ibm", "*trunctfsf2_ieee", "*trunctfsf2_ibm", "*extenddftf2_ieee", "*extenddftf2_ibm", "*extendsftf2_ieee", "*extendsftf2_ibm"): New insn patterns. * config/s390/s390.opt (mlong-double-128, mlong-double-64): New options. * config/s390/t-crtstuff (TARGET_LIBGCC2_CFLAGS): Macro defined. * config/s390/libgcc-glibc.ver (__divtc3, __multc3, __powitf2, __fixtfti, __fixunstfti, __floattitf, __fixtfdi, __fixunstfdi, __floatditf): Add a GCC_4.1.0 symbol version tag. * doc/invoke.texi (-mlong-double-128, -mlong-double-64): Document the new options. Co-Authored-By: Ulrich Weigand From-SVN: r110539 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 83d13e78b22..2a8be97e735 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,62 @@ +2006-02-03 Andreas Krebbel + Ulrich Weigand + + PR target/25864 + * config/s390/2084.md ("x_fsimptf", "x_fmultf", "x_fdivtf", + "x_floadtf", "x_ftrunctf", "x_ftruncdf"): New insn reservations. + * config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): New functions. + * config/s390/s390.c (struct processor_costs): Add mxbr, sqxbr, dxbr + and dxr fields. + (z900_cost, z990_cost, z9_109_cost): Values for the new fields added. + (s390_rtx_costs): Use the new fields to calculate rtx costs. + (s390_secondary_input_reload_class, s390_secondary_output_reload_class): + Define secondary reloads for TFmode moves. + (constant_modes): Add TFmode. + (NR_C_MODES): Set to 8. + * config/s390/s390.h (TARGET_CPU_CPP_BUILTINS): Add __LONG_DOUBLE_128__ + builtin define. + (LONG_DOUBLE_TYPE_SIZE): Set to 128 or 64. + (LIBGCC2_LONG_DOUBLE_TYPE_SIZE, WIDEST_HARDWARE_FP_SIZE): Define. + (HARD_REGNO_NREGS, HARD_REGNO_MODE_OK, CLASS_MAX_NREGS, + CANNOT_CHANGE_MODE_CLASS): Consider TFmode. + * config/s390/s390.md ("type" attribute): Add fsimptf, floadtf, fmultf, + fdivtf, fsqrttf, ftrunctf, ftruncdf as possible values. + (FPR mode macro): Add TFmode. + (DSF mode macro): New. + (, mode attributes): Removed. + (, , , , mode attributes): New. + ("*cmp_ccs_0", "*cmp_ccs_0_ibm", "*cmp_ccs", + "*cmp_ccs_ibm", "fix_trunc2_ieee", + "floatdi2", "floatsi2_ieee", "*add3", + "*add3_cc", "*add3_cconly", "*add3_ibm", + "*sub3", "*sub3_cc", "*sub3_cconly", + "*sub3_ibm", "*mul3_ibm", "*fmadd", "*fmsub", + "*div3", "*div3_ibm", "*neg2_cc", + "*neg2_cconly", "*neg2", "*neg2_ibm", + "*abs2_cc", "*abs2_cconly", "*abs2", + "*abs2_ibm", "*negabs2_cc", "*negabs2_cconly", + "*negabs2", "sqrt2"): + Changed to . R constraint replaced by . + ("*mul3"): Changed to . R constraint replaced by + . + ("fix_truncdi2"): 'FPR:' removed. + ("*fmadd", "*fmsub"): FPR mode replaced by DSF. + ("*movtf_64", "*movtf_31"): New insn definitions followed by 5 + splitters. + ("movtf", "reload_outtf", "reload_intf", "trunctfdf2", "trunctfsf2", + "extenddftf2", "extendsftf2"): New expanders. + ("*trunctfdf2_ieee", "*trunctfdf2_ibm", "*trunctfsf2_ieee", + "*trunctfsf2_ibm", "*extenddftf2_ieee", "*extenddftf2_ibm", + "*extendsftf2_ieee", "*extendsftf2_ibm"): New insn patterns. + * config/s390/s390.opt (mlong-double-128, mlong-double-64): + New options. + * config/s390/t-crtstuff (TARGET_LIBGCC2_CFLAGS): Macro defined. + * config/s390/libgcc-glibc.ver (__divtc3, __multc3, __powitf2, + __fixtfti, __fixunstfti, __floattitf, __fixtfdi, __fixunstfdi, + __floatditf): Add a GCC_4.1.0 symbol version tag. + * doc/invoke.texi (-mlong-double-128, -mlong-double-64): Document + the new options. + 2006-02-02 Andrew Pinski PR target/25377 diff --git a/gcc/config/s390/2084.md b/gcc/config/s390/2084.md index be56f76ad14..3a4479a2937 100644 --- a/gcc/config/s390/2084.md +++ b/gcc/config/s390/2084.md @@ -1,5 +1,5 @@ ;; Scheduling description for z990 (cpu 2084). -;; Copyright (C) 2003,2004, 2005 Free Software Foundation, Inc. +;; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com). @@ -161,6 +161,11 @@ ;; Floating point insns ;; +(define_insn_reservation "x_fsimptf" 7 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "fsimptf")) + "x_e1_t*2,x-wr-fp") + (define_insn_reservation "x_fsimpdf" 6 (and (eq_attr "cpu" "z990,z9_109") (eq_attr "type" "fsimpdf,fmuldf")) @@ -171,6 +176,18 @@ (eq_attr "type" "fsimpsf,fmulsf")) "x_e1_t,x-wr-fp") + +(define_insn_reservation "x_fmultf" 33 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "fmultf")) + "x_e1_t*27,x-wr-fp") + + +(define_insn_reservation "x_fdivtf" 82 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "fdivtf,fsqrttf")) + "x_e1_t*76,x-wr-fp") + (define_insn_reservation "x_fdivdf" 36 (and (eq_attr "cpu" "z990,z9_109") (eq_attr "type" "fdivdf,fsqrtdf")) @@ -181,6 +198,12 @@ (eq_attr "type" "fdivsf,fsqrtsf")) "x_e1_t*30,x-wr-fp") + +(define_insn_reservation "x_floadtf" 6 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "floadtf")) + "x_e1_t,x-wr-fp") + (define_insn_reservation "x_floaddf" 6 (and (eq_attr "cpu" "z990,z9_109") (eq_attr "type" "floaddf")) @@ -191,6 +214,7 @@ (eq_attr "type" "floadsf")) "x_e1_t,x-wr-fp") + (define_insn_reservation "x_fstoredf" 1 (and (eq_attr "cpu" "z990,z9_109") (eq_attr "type" "fstoredf")) @@ -201,6 +225,18 @@ (eq_attr "type" "fstoresf")) "x_e1_t,x-wr-fp") + +(define_insn_reservation "x_ftrunctf" 16 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "ftrunctf")) + "x_e1_t*10,x-wr-fp") + +(define_insn_reservation "x_ftruncdf" 11 + (and (eq_attr "cpu" "z990,z9_109") + (eq_attr "type" "ftruncdf")) + "x_e1_t*5,x-wr-fp") + + (define_insn_reservation "x_ftoi" 1 (and (eq_attr "cpu" "z990,z9_109") (eq_attr "type" "ftoi")) @@ -234,7 +270,7 @@ "s390_agen_dep_p") (define_bypass 9 "x_int,x_agen,x_lr" - "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ + "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf" "s390_agen_dep_p") ;; @@ -247,7 +283,7 @@ "s390_agen_dep_p") (define_bypass 5 "x_load" - "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ + "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf" "s390_agen_dep_p") @@ -261,7 +297,7 @@ "s390_agen_dep_p") (define_bypass 5 "x_larl, x_la" - "x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ + "x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\ x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf" "s390_agen_dep_p") diff --git a/gcc/config/s390/fixdfdi.h b/gcc/config/s390/fixdfdi.h index 4802a59c5a0..fd12243a381 100644 --- a/gcc/config/s390/fixdfdi.h +++ b/gcc/config/s390/fixdfdi.h @@ -20,6 +20,156 @@ along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#ifdef L_fixunstfdi + +#define EXPD(fp) (((fp.l.i[0]) >> 16) & 0x7FFF) +#define EXPONENT_BIAS 16383 +#define MANTISSA_BITS 112 +#define PRECISION (MANTISSA_BITS + 1) +#define SIGNBIT 0x80000000 +#define SIGND(fp) ((fp.l.i[0]) & SIGNBIT) +#define MANTD_HIGH_LL(fp) ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT) +#define MANTD_LOW_LL(fp) (fp.ll[1]) +#define FRACD_ZERO_P(fp) (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK)) +#define HIGH_LL_FRAC_BITS 48 +#define HIGH_LL_UNIT_BIT ((UDItype_x)1 << HIGH_LL_FRAC_BITS) +#define HIGH_LL_FRAC_MASK (HIGH_LL_UNIT_BIT - 1) + +typedef int DItype_x __attribute__ ((mode (DI))); +typedef unsigned int UDItype_x __attribute__ ((mode (DI))); +typedef int SItype_x __attribute__ ((mode (SI))); +typedef unsigned int USItype_x __attribute__ ((mode (SI))); + +union double_long { + long double d; + struct { + SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */ + } l; + UDItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ +}; + +UDItype_x __fixunstfdi (long double a1); + +/* convert double to unsigned int */ +UDItype_x +__fixunstfdi (long double a1) +{ + register union double_long dl1; + register int exp; + register UDItype_x l; + + dl1.d = a1; + + /* +/- 0, denormalized, negative */ + if (!EXPD (dl1) || SIGND(dl1)) + return 0; + + /* The exponent - considered the binary point at the right end of + the mantissa. */ + exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS; + + /* number < 1: If the mantissa would need to be right-shifted more bits than + its size (plus the implied one bit on the left) the result would be + zero. */ + if (exp <= -PRECISION) + return 0; + + /* NaN: All exponent bits set and a non-zero fraction. */ + if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) + return 0x0ULL; + + /* If the upper ll part of the mantissa isn't + zeroed out after shifting the number would be to large. */ + if (exp >= -HIGH_LL_FRAC_BITS) + return 0xFFFFFFFFFFFFFFFFULL; + + exp += HIGH_LL_FRAC_BITS + 1; + + l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1) + | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1)); + + return l >> -exp; +} +#define __fixunstfdi ___fixunstfdi +#endif +#undef L_fixunstfdi + +#ifdef L_fixtfdi +#define EXPD(fp) (((fp.l.i[0]) >> 16) & 0x7FFF) +#define EXPONENT_BIAS 16383 +#define MANTISSA_BITS 112 +#define PRECISION (MANTISSA_BITS + 1) +#define SIGNBIT 0x80000000 +#define SIGND(fp) ((fp.l.i[0]) & SIGNBIT) +#define MANTD_HIGH_LL(fp) ((fp.ll[0] & HIGH_LL_FRAC_MASK) | HIGH_LL_UNIT_BIT) +#define MANTD_LOW_LL(fp) (fp.ll[1]) +#define FRACD_ZERO_P(fp) (!fp.ll[1] && !(fp.ll[0] & HIGH_LL_FRAC_MASK)) +#define HIGH_LL_FRAC_BITS 48 +#define HIGH_LL_UNIT_BIT ((UDItype_x)1 << HIGH_LL_FRAC_BITS) +#define HIGH_LL_FRAC_MASK (HIGH_LL_UNIT_BIT - 1) + +typedef int DItype_x __attribute__ ((mode (DI))); +typedef unsigned int UDItype_x __attribute__ ((mode (DI))); +typedef int SItype_x __attribute__ ((mode (SI))); +typedef unsigned int USItype_x __attribute__ ((mode (SI))); + +union double_long { + long double d; + struct { + SItype_x i[4]; /* 32 bit parts: 0 upper ... 3 lowest */ + } l; + DItype_x ll[2]; /* 64 bit parts: 0 upper, 1 lower */ +}; + +DItype_x __fixtfdi (long double a1); + +/* convert double to unsigned int */ +DItype_x +__fixtfdi (long double a1) +{ + register union double_long dl1; + register int exp; + register UDItype_x l; + + dl1.d = a1; + + /* +/- 0, denormalized */ + if (!EXPD (dl1)) + return 0; + + /* The exponent - considered the binary point at the right end of + the mantissa. */ + exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS; + + /* number < 1: If the mantissa would need to be right-shifted more bits than + its size the result would be zero. */ + if (exp <= -PRECISION) + return 0; + + /* NaN: All exponent bits set and a non-zero fraction. */ + if ((EXPD(dl1) == 0x7fff) && !FRACD_ZERO_P (dl1)) + return 0x8000000000000000ULL; + + /* If the upper ll part of the mantissa isn't + zeroed out after shifting the number would be to large. */ + if (exp >= -HIGH_LL_FRAC_BITS) + { + l = (long long)1 << 63; /* long int min */ + return SIGND (dl1) ? l : l - 1; + } + + /* The extra bit is needed for the sign bit. */ + exp += HIGH_LL_FRAC_BITS + 1; + + l = MANTD_LOW_LL (dl1) >> (HIGH_LL_FRAC_BITS + 1) + | MANTD_HIGH_LL (dl1) << (64 - (HIGH_LL_FRAC_BITS + 1)); + + return SIGND (dl1) ? -(l >> -exp) : l >> -exp; +} +#define __fixtfdi ___fixtfdi +#endif +#undef L_fixtfdi + #ifdef L_fixunsdfdi #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) #define EXCESSD 1022 @@ -305,4 +455,3 @@ __fixsfdi (float a1) #define __fixsfdi ___fixsfdi #endif #undef L_fixsfdi - diff --git a/gcc/config/s390/libgcc-glibc.ver b/gcc/config/s390/libgcc-glibc.ver index 1d9e2290413..e9413d0fff1 100644 --- a/gcc/config/s390/libgcc-glibc.ver +++ b/gcc/config/s390/libgcc-glibc.ver @@ -39,3 +39,36 @@ GLIBC_2.2 { } %endif +# With GCC 4.1.0 long double 128 bit support was introduced. The +# following symbols coming from libgcc are enabled when -mlong-double-128 +# is specified. These lines make the symbols to get a @@GCC_4.1.0 attached. + +%exclude { + __divtc3 + __multc3 + __powitf2 + __fixtfti + __fixunstfti + __floattitf + + __fixtfdi + __fixunstfdi + __floatditf +} + +GCC_4.1.0 { + __divtc3 + __multc3 + __powitf2 + +%ifdef __s390x__ + __fixtfti + __fixunstfti + __floattitf + +%else + __fixtfdi + __fixunstfdi + __floatditf +%endif +} diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 5d80d50383f..dfefaca21fc 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on IBM S/390 and zSeries - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Hartmut Penner (hpenner@de.ibm.com) and Ulrich Weigand (uweigand@de.ibm.com). @@ -71,13 +71,17 @@ struct processor_costs const int msgr; /* cost of an MSGR instruction. */ const int msr; /* cost of an MSR instruction. */ const int mult_df; /* cost of multiplication in DFmode. */ + const int mxbr; /* square root */ + const int sqxbr; /* cost of square root in TFmode. */ const int sqdbr; /* cost of square root in DFmode. */ const int sqebr; /* cost of square root in SFmode. */ /* multiply and add */ const int madbr; /* cost of multiply and add in DFmode. */ const int maebr; /* cost of multiply and add in SFmode. */ /* division */ + const int dxbr; + const int dxr; const int ddbr; const int ddr; const int debr; @@ -107,10 +111,14 @@ struct processor_costs z900_cost = COSTS_N_INSNS (10), /* MSGR */ COSTS_N_INSNS (4), /* MSR */ COSTS_N_INSNS (7), /* multiplication in DFmode */ + COSTS_N_INSNS (13), /* MXBR */ + COSTS_N_INSNS (136), /* SQXBR */ COSTS_N_INSNS (44), /* SQDBR */ COSTS_N_INSNS (35), /* SQEBR */ COSTS_N_INSNS (18), /* MADBR */ COSTS_N_INSNS (13), /* MAEBR */ + COSTS_N_INSNS (134), /* DXBR */ + COSTS_N_INSNS (135), /* DXR */ COSTS_N_INSNS (30), /* DDBR */ COSTS_N_INSNS (30), /* DDR */ COSTS_N_INSNS (27), /* DEBR */ @@ -138,10 +146,14 @@ struct processor_costs z990_cost = COSTS_N_INSNS (4), /* MSGR */ COSTS_N_INSNS (4), /* MSR */ COSTS_N_INSNS (1), /* multiplication in DFmode */ + COSTS_N_INSNS (28), /* MXBR */ + COSTS_N_INSNS (130), /* SQXBR */ COSTS_N_INSNS (66), /* SQDBR */ COSTS_N_INSNS (38), /* SQEBR */ COSTS_N_INSNS (1), /* MADBR */ COSTS_N_INSNS (1), /* MAEBR */ + COSTS_N_INSNS (60), /* DXBR */ + COSTS_N_INSNS (72), /* DXR */ COSTS_N_INSNS (40), /* DDBR */ COSTS_N_INSNS (44), /* DDR */ COSTS_N_INSNS (26), /* DDBR */ @@ -169,10 +181,14 @@ struct processor_costs z9_109_cost = COSTS_N_INSNS (4), /* MSGR */ COSTS_N_INSNS (4), /* MSR */ COSTS_N_INSNS (1), /* multiplication in DFmode */ + COSTS_N_INSNS (28), /* MXBR */ + COSTS_N_INSNS (130), /* SQXBR */ COSTS_N_INSNS (66), /* SQDBR */ COSTS_N_INSNS (38), /* SQEBR */ COSTS_N_INSNS (1), /* MADBR */ COSTS_N_INSNS (1), /* MAEBR */ + COSTS_N_INSNS (60), /* DXBR */ + COSTS_N_INSNS (72), /* DXR */ COSTS_N_INSNS (40), /* DDBR */ COSTS_N_INSNS (37), /* DDR */ COSTS_N_INSNS (26), /* DDBR */ @@ -2159,6 +2175,9 @@ s390_rtx_costs (rtx x, int code, int outer_code, int *total) case DFmode: *total = s390_cost->mult_df; break; + case TFmode: + *total = s390_cost->mxbr; + break; default: return false; } @@ -2209,13 +2228,22 @@ s390_rtx_costs (rtx x, int code, int outer_code, int *total) else /* TARGET_IBM_FLOAT */ *total = s390_cost->ddr; } + else if (GET_MODE (x) == TFmode) + { + if (TARGET_IEEE_FLOAT) + *total = s390_cost->dxbr; + else /* TARGET_IBM_FLOAT */ + *total = s390_cost->dxr; + } return false; case SQRT: if (GET_MODE (x) == SFmode) *total = s390_cost->sqebr; - else /* DFmode */ + else if (GET_MODE (x) == DFmode) *total = s390_cost->sqdbr; + else /* TFmode */ + *total = s390_cost->sqxbr; return false; case SIGN_EXTEND: @@ -2570,6 +2598,15 @@ s390_secondary_input_reload_class (enum reg_class class, if (s390_plus_operand (in, mode)) return ADDR_REGS; + if (reg_classes_intersect_p (FP_REGS, class) + && mode == TFmode + && GET_CODE (in) == MEM + && GET_CODE (XEXP (in, 0)) == PLUS + && GET_CODE (XEXP (XEXP (in, 0), 1)) == CONST_INT + && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (in, 0), 1)) + + GET_MODE_SIZE (mode) - 1)) + return ADDR_REGS; + if (reg_classes_intersect_p (CC_REGS, class)) return GENERAL_REGS; @@ -2586,7 +2623,7 @@ enum reg_class s390_secondary_output_reload_class (enum reg_class class, enum machine_mode mode, rtx out) { - if ((TARGET_64BIT ? mode == TImode + if ((TARGET_64BIT ? (mode == TImode || mode == TFmode) : (mode == DImode || mode == DFmode)) && reg_classes_intersect_p (GENERAL_REGS, class) && GET_CODE (out) == MEM @@ -2597,6 +2634,15 @@ s390_secondary_output_reload_class (enum reg_class class, + GET_MODE_SIZE (mode) - 1)) return ADDR_REGS; + if (reg_classes_intersect_p (FP_REGS, class) + && mode == TFmode + && GET_CODE (out) == MEM + && GET_CODE (XEXP (out, 0)) == PLUS + && GET_CODE (XEXP (XEXP (out, 0), 1)) == CONST_INT + && !DISP_IN_RANGE (INTVAL (XEXP (XEXP (out, 0), 1)) + + GET_MODE_SIZE (mode) - 1)) + return ADDR_REGS; + if (reg_classes_intersect_p (CC_REGS, class)) return GENERAL_REGS; @@ -5169,10 +5215,10 @@ replace_ltrel_base (rtx *x) /* We keep a list of constants which we have to add to internal constant tables in the middle of large functions. */ -#define NR_C_MODES 7 +#define NR_C_MODES 8 enum machine_mode constant_modes[NR_C_MODES] = { - TImode, + TFmode, TImode, DFmode, DImode, SFmode, SImode, HImode, diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index d8d1d1990d0..1a61158ba04 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for IBM S/390 - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Contributed by Hartmut Penner (hpenner@de.ibm.com) and Ulrich Weigand (uweigand@de.ibm.com). @@ -93,6 +93,8 @@ extern enum processor_flags s390_arch_flags; builtin_define ("__s390__"); \ if (TARGET_64BIT) \ builtin_define ("__s390x__"); \ + if (TARGET_LONG_DOUBLE_128) \ + builtin_define ("__LONG_DOUBLE_128__"); \ } \ while (0) @@ -216,7 +218,18 @@ if (INTEGRAL_MODE_P (MODE) && \ #define LONG_LONG_TYPE_SIZE 64 #define FLOAT_TYPE_SIZE 32 #define DOUBLE_TYPE_SIZE 64 -#define LONG_DOUBLE_TYPE_SIZE 64 /* ??? Should support extended format. */ +#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64) + +/* Define this to set long double type size to use in libgcc2.c, which can + not depend on target_flags. */ +#ifdef __LONG_DOUBLE_128__ +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 +#else +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +#endif + +/* Work around target_flags dependency in ada/targtyps.c. */ +#define WIDEST_HARDWARE_FP_SIZE 64 /* We use "unsigned char" as default. */ #define DEFAULT_SIGNED_CHAR 0 @@ -334,28 +347,34 @@ if (INTEGRAL_MODE_P (MODE) && \ Floating point modes <= word size fit into any FPR or GPR. Floating point modes > word size (i.e. DFmode on 32-bit) fit into any FPR, or an even-odd GPR pair. + TFmode fits only into an even-odd FPR pair. Complex floating point modes fit either into two FPRs, or into successive GPRs (again starting with an even number). + TCmode fits only into two successive even-odd FPR pairs. Condition code modes fit only into the CC register. */ #define HARD_REGNO_NREGS(REGNO, MODE) \ (FP_REGNO_P(REGNO)? \ - (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \ + (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? \ + 2 * ((GET_MODE_SIZE(MODE) / 2 + 8 - 1) / 8) : \ + ((GET_MODE_SIZE(MODE) + 8 - 1) / 8)) : \ GENERAL_REGNO_P(REGNO)? \ ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \ ACCESS_REGNO_P(REGNO)? \ - ((GET_MODE_SIZE(MODE)+4-1) / 4) : \ + ((GET_MODE_SIZE(MODE) + 4 - 1) / 4) : \ 1) #define HARD_REGNO_MODE_OK(REGNO, MODE) \ (FP_REGNO_P(REGNO)? \ - ((MODE) == SImode || (MODE) == DImode || \ - GET_MODE_CLASS(MODE) == MODE_FLOAT || \ - GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) : \ + (((MODE) == SImode || (MODE) == DImode \ + || GET_MODE_CLASS(MODE) == MODE_FLOAT \ + || GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) \ + && (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \ GENERAL_REGNO_P(REGNO)? \ - (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) : \ + ((HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) \ + && (((MODE) != TFmode && (MODE) != TCmode) || TARGET_64BIT)) : \ CC_REGNO_P(REGNO)? \ GET_MODE_CLASS (MODE) == MODE_CC : \ FRAME_REGNO_P(REGNO)? \ @@ -376,7 +395,9 @@ if (INTEGRAL_MODE_P (MODE) && \ in a register of class CLASS. */ #define CLASS_MAX_NREGS(CLASS, MODE) \ ((CLASS) == FP_REGS ? \ - (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \ + (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? \ + 2 * (GET_MODE_SIZE (MODE) / 2 + 8 - 1) / 8 : \ + (GET_MODE_SIZE (MODE) + 8 - 1) / 8) : \ (CLASS) == ACCESS_REGS ? \ (GET_MODE_SIZE (MODE) + 4 - 1) / 4 : \ (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) @@ -386,10 +407,11 @@ if (INTEGRAL_MODE_P (MODE) && \ cannot use SUBREGs to switch between modes in FP registers. Likewise for access registers, since they have only half the word size on 64-bit. */ -#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ - (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ - ? reg_classes_intersect_p (FP_REGS, CLASS) \ - || reg_classes_intersect_p (ACCESS_REGS, CLASS) : 0) +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ + ? ((reg_classes_intersect_p (FP_REGS, CLASS) \ + && (GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8)) \ + || reg_classes_intersect_p (ACCESS_REGS, CLASS)) : 0) /* Register classes. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 40a32d4508f..0f3e562be20 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler -- S/390 / zSeries version. -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ;; Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com). @@ -199,11 +199,11 @@ (define_attr "type" "none,integer,load,lr,la,larl,lm,stm, cs,vs,store,sem,idiv, imulhi,imulsi,imuldi, - branch,jsr,fsimpdf,fsimpsf, - floaddf,floadsf,fstoredf,fstoresf, - fmuldf,fmulsf,fdivdf,fdivsf, - ftoi,itof,fsqrtdf,fsqrtsf, - other" + branch,jsr,fsimptf,fsimpdf,fsimpsf, + floadtf,floaddf,floadsf,fstoredf,fstoresf, + fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf, + ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf, + ftrunctf,ftruncdf,other" (cond [(eq_attr "op_type" "NN") (const_string "other") (eq_attr "op_type" "SS") (const_string "cs")] (const_string "integer"))) @@ -248,9 +248,10 @@ ;; Macros -;; This mode macro allows DF and SF patterns to be generated from the +;; This mode macro allows floating point patterns to be generated from the ;; same template. -(define_mode_macro FPR [DF SF]) +(define_mode_macro FPR [TF DF SF]) +(define_mode_macro DSF [DF SF]) ;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated ;; from the same template. @@ -291,13 +292,22 @@ (plus "add") (minus "sub") (mult "nand")]) -;; In FPR templates, a string like "ltbr" will expand to "ltdbr" in DFmode -;; and "ltebr" in SFmode. -(define_mode_attr de [(DF "d") (SF "e")]) +;; In FPR templates, a string like "ltbr" will expand to "ltxbr" in TFmode, +;; "ltdbr" in DFmode, and "ltebr" in SFmode. +(define_mode_attr xde [(TF "x") (DF "d") (SF "e")]) -;; In FPR templates, a string like "mbr" will expand to "mdbr" in DFmode -;; and "meebr" in SFmode. This is needed for the 'mul3' pattern. -(define_mode_attr dee [(DF "d") (SF "ee")]) +;; In FPR templates, a string like "mbr" will expand to "mxbr" in TFmode, +;; "mdbr" in DFmode, and "meebr" in SFmode. +(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")]) + +;; In FPR templates, "" will expand to "RRE" in TFmode and "RR" otherwise. +;; Likewise for "". +(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")]) +(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")]) + +;; In FPR templates, "" will expand to "f" in TFmode and "R" otherwise. +;; This is used to disable the memory alternative in TFmode patterns. +(define_mode_attr Rf [(TF "f") (DF "R") (SF "R")]) ;; In GPR and P templates, a constraint like "" will expand to "d" in DImode ;; and "0" in SImode. This allows to combine instructions of which the 31bit @@ -769,7 +779,7 @@ (compare (match_operand:FPR 0 "register_operand" "f") (match_operand:FPR 1 "const0_operand" "")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "ltbr\t%0,%0" + "ltbr\t%0,%0" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -778,30 +788,30 @@ (compare (match_operand:FPR 0 "register_operand" "f") (match_operand:FPR 1 "const0_operand" "")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "ltr\t%0,%0" - [(set_attr "op_type" "RR") + "ltr\t%0,%0" + [(set_attr "op_type" "") (set_attr "type" "fsimp")]) (define_insn "*cmp_ccs" [(set (reg CC_REGNUM) (compare (match_operand:FPR 0 "register_operand" "f,f") - (match_operand:FPR 1 "general_operand" "f,R")))] + (match_operand:FPR 1 "general_operand" "f,")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - cbr\t%0,%1 - cb\t%0,%1" + cbr\t%0,%1 + cb\t%0,%1" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*cmp_ccs_ibm" [(set (reg CC_REGNUM) (compare (match_operand:FPR 0 "register_operand" "f,f") - (match_operand:FPR 1 "general_operand" "f,R")))] + (match_operand:FPR 1 "general_operand" "f,")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - cr\t%0,%1 - c\t%0,%1" - [(set_attr "op_type" "RR,RX") + cr\t%0,%1 + c\t%0,%1" + [(set_attr "op_type" ",") (set_attr "type" "fsimp")]) @@ -1435,6 +1445,149 @@ [(set_attr "op_type" "RR,RX,RXY,RRE") (set_attr "type" "lr,load,load,*")]) +; +; movtf instruction pattern(s). +; + +(define_expand "movtf" + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "" + "") + +(define_insn "*movtf_64" + [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q") + (match_operand:TF 1 "general_operand" "G,f,o,f,QS,d,dm,d,Q"))] + "TARGET_64BIT" + "@ + lzxr\t%0 + lxr\t%0,%1 + # + # + lmg\t%0,%N0,%S1 + stmg\t%1,%N1,%S0 + # + # + #" + [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*,*")]) + +(define_insn "*movtf_31" + [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q") + (match_operand:TF 1 "general_operand" "G,f,o,f,Q"))] + "!TARGET_64BIT" + "@ + lzxr\t%0 + lxr\t%0,%1 + # + # + #" + [(set_attr "op_type" "RRE,RRE,*,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,*")]) + +; TFmode in GPRs splitters + +(define_split + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], TFmode, 0)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 0, 0, TFmode); + operands[3] = operand_subword (operands[0], 1, 0, TFmode); + operands[4] = operand_subword (operands[1], 0, 0, TFmode); + operands[5] = operand_subword (operands[1], 1, 0, TFmode); +}) + +(define_split + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], TFmode, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, TFmode); + operands[3] = operand_subword (operands[0], 0, 0, TFmode); + operands[4] = operand_subword (operands[1], 1, 0, TFmode); + operands[5] = operand_subword (operands[1], 0, 0, TFmode); +}) + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "memory_operand" ""))] + "TARGET_64BIT && reload_completed + && !FP_REG_P (operands[0]) + && !s_operand (operands[1], VOIDmode)" + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = operand_subword (operands[0], 1, 0, DFmode); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +; TFmode in FPRs splitters + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "memory_operand" ""))] + "reload_completed && offsettable_memref_p (operands[1]) + && FP_REG_P (operands[0])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0); + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8); + operands[4] = adjust_address_nv (operands[1], DFmode, 0); + operands[5] = adjust_address_nv (operands[1], DFmode, 8); +}) + +(define_split + [(set (match_operand:TF 0 "memory_operand" "") + (match_operand:TF 1 "register_operand" ""))] + "reload_completed && offsettable_memref_p (operands[0]) + && FP_REG_P (operands[1])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = adjust_address_nv (operands[0], DFmode, 0); + operands[3] = adjust_address_nv (operands[0], DFmode, 8); + operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0); + operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8); +}) + +(define_expand "reload_outtf" + [(parallel [(match_operand:TF 0 "" "") + (match_operand:TF 1 "register_operand" "f") + (match_operand:SI 2 "register_operand" "=&a")])] + "" +{ + rtx addr = gen_lowpart (Pmode, operands[2]); + + gcc_assert (MEM_P (operands[0])); + s390_load_address (addr, find_replacement (&XEXP (operands[0], 0))); + operands[0] = replace_equiv_address (operands[0], addr); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_expand "reload_intf" + [(parallel [(match_operand:TF 0 "register_operand" "=f") + (match_operand:TF 1 "" "") + (match_operand:SI 2 "register_operand" "=&a")])] + "" +{ + rtx addr = gen_lowpart (Pmode, operands[2]); + + gcc_assert (MEM_P (operands[1])); + s390_load_address (addr, find_replacement (&XEXP (operands[1], 0))); + operands[1] = replace_equiv_address (operands[1], addr); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + ; ; movdf instruction pattern(s). ; @@ -2972,13 +3125,13 @@ DONE; }) -(define_expand "fix_truncdi2" +(define_expand "fix_truncdi2" [(set (match_operand:DI 0 "register_operand" "") - (fix:DI (match_operand:FPR 1 "nonimmediate_operand" "")))] + (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))] "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" { - operands[1] = force_reg (mode, operands[1]); - emit_insn (gen_fix_truncdi2_ieee (operands[0], operands[1], + operands[1] = force_reg (mode, operands[1]); + emit_insn (gen_fix_truncdi2_ieee (operands[0], operands[1], GEN_INT(5))); DONE; }) @@ -2989,10 +3142,22 @@ (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cbr\t%0,%h2,%1" + "cbr\t%0,%h2,%1" [(set_attr "op_type" "RRE") (set_attr "type" "ftoi")]) +; +; fix_trunctf(si|di)2 instruction pattern(s). +; + +(define_expand "fix_trunctf2" + [(parallel [(set (match_operand:GPR 0 "register_operand" "") + (fix:GPR (match_operand:TF 1 "register_operand" ""))) + (unspec:GPR [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "") + ; ; fix_truncdfsi2 instruction pattern(s). ; @@ -3066,21 +3231,36 @@ }) ; -; floatdi(df|sf)2 instruction pattern(s). +; float(si|di)(tf|df|sf)2 instruction pattern(s). ; (define_insn "floatdi2" [(set (match_operand:FPR 0 "register_operand" "=f") (float:FPR (match_operand:DI 1 "register_operand" "d")))] "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cgbr\t%0,%1" + "cgbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "itof" )]) +(define_insn "floatsi2_ieee" + [(set (match_operand:FPR 0 "register_operand" "=f") + (float:FPR (match_operand:SI 1 "register_operand" "d")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "cfbr\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "itof" )]) + + ; -; floatsidf2 instruction pattern(s). +; floatsi(tf|df)2 instruction pattern(s). ; +(define_expand "floatsitf2" + [(set (match_operand:TF 0 "register_operand" "") + (float:TF (match_operand:SI 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "") + (define_expand "floatsidf2" [(set (match_operand:DF 0 "register_operand" "") (float:DF (match_operand:SI 1 "register_operand" "")))] @@ -3098,14 +3278,6 @@ } }) -(define_insn "floatsidf2_ieee" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cdfbr\t%0,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "itof" )]) - (define_insn "floatsidf2_ibm" [(set (match_operand:DF 0 "register_operand" "=f") (float:DF (match_operand:SI 1 "register_operand" "d"))) @@ -3141,14 +3313,6 @@ } }) -(define_insn "floatsisf2_ieee" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cefbr\t%0,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "itof" )]) - ; ; truncdfsf2 instruction pattern(s). ; @@ -3164,7 +3328,8 @@ (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "ledbr\t%0,%1" - [(set_attr "op_type" "RRE")]) + [(set_attr "op_type" "RRE") + (set_attr "type" "ftruncdf")]) (define_insn "truncdfsf2_ibm" [(set (match_operand:SF 0 "register_operand" "=f,f") @@ -3176,6 +3341,66 @@ [(set_attr "op_type" "RR,RX") (set_attr "type" "floadsf")]) +; +; trunctfdf2 instruction pattern(s). +; + +(define_expand "trunctfdf2" + [(parallel + [(set (match_operand:DF 0 "register_operand" "") + (float_truncate:DF (match_operand:TF 1 "register_operand" ""))) + (clobber (match_scratch:TF 2 "=f"))])] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*trunctfdf2_ieee" + [(set (match_operand:DF 0 "register_operand" "=f") + (float_truncate:DF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "ldxbr\t%2,%1\;ldr\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + +(define_insn "*trunctfdf2_ibm" + [(set (match_operand:DF 0 "register_operand" "=f") + (float_truncate:DF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "ldxr\t%2,%1\;ldr\t%0,%2" + [(set_attr "length" "4") + (set_attr "type" "ftrunctf")]) + +; +; trunctfsf2 instruction pattern(s). +; + +(define_expand "trunctfsf2" + [(parallel + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))])] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*trunctfsf2_ieee" + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "lexbr\t%2,%1\;ler\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + +(define_insn "*trunctfsf2_ibm" + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "lexr\t%2,%1\;ler\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + ; ; extendsfdf2 instruction pattern(s). ; @@ -3200,7 +3425,7 @@ ldebr\t%0,%1 ldeb\t%0,%1" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "floadsf")]) + (set_attr "type" "fsimpsf, floadsf")]) (define_insn "extendsfdf2_ibm" [(set (match_operand:DF 0 "register_operand" "=f,f") @@ -3213,6 +3438,66 @@ [(set_attr "length" "4,6") (set_attr "type" "floadsf")]) +; +; extenddftf2 instruction pattern(s). +; + +(define_expand "extenddftf2" + [(set (match_operand:TF 0 "register_operand" "") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*extenddftf2_ieee" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "@ + lxdbr\t%0,%1 + lxdb\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +(define_insn "*extenddftf2_ibm" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "@ + lxdr\t%0,%1 + lxd\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +; +; extendsftf2 instruction pattern(s). +; + +(define_expand "extendsftf2" + [(set (match_operand:TF 0 "register_operand" "") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*extendsftf2_ieee" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "@ + lxebr\t%0,%1 + lxeb\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +(define_insn "*extendsftf2_ibm" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "@ + lxer\t%0,%1 + lxe\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + ;; ;; ARITHMETIC OPERATIONS @@ -3535,7 +3820,7 @@ [(parallel [(set (match_operand:FPR 0 "register_operand" "=f,f") (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) + (match_operand:FPR 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" "") @@ -3543,52 +3828,52 @@ (define_insn "*add3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) + (match_operand:FPR 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - abr\t%0,%2 - ab\t%0,%2" + abr\t%0,%2 + ab\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*add3_cc" [(set (reg CC_REGNUM) (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")) + (match_operand:FPR 2 "general_operand" "f,")) (match_operand:FPR 3 "const0_operand" ""))) (set (match_operand:FPR 0 "register_operand" "=f,f") (plus:FPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - abr\t%0,%2 - ab\t%0,%2" + abr\t%0,%2 + ab\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*add3_cconly" [(set (reg CC_REGNUM) (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")) + (match_operand:FPR 2 "general_operand" "f,")) (match_operand:FPR 3 "const0_operand" ""))) (clobber (match_scratch:FPR 0 "=f,f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - abr\t%0,%2 - ab\t%0,%2" + abr\t%0,%2 + ab\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*add3_ibm" [(set (match_operand:FPR 0 "register_operand" "=f,f") (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) + (match_operand:FPR 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - ar\t%0,%2 - a\t%0,%2" - [(set_attr "op_type" "RR,RX") + ar\t%0,%2 + a\t%0,%2" + [(set_attr "op_type" ",") (set_attr "type" "fsimp")]) @@ -3875,52 +4160,52 @@ (define_insn "*sub3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (minus:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) + (match_operand:FPR 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sbr\t%0,%2 - sb\t%0,%2" + sbr\t%0,%2 + sb\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*sub3_cc" [(set (reg CC_REGNUM) (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")) + (match_operand:FPR 2 "general_operand" "f,")) (match_operand:FPR 3 "const0_operand" ""))) (set (match_operand:FPR 0 "register_operand" "=f,f") (minus:FPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sbr\t%0,%2 - sb\t%0,%2" + sbr\t%0,%2 + sb\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*sub3_cconly" [(set (reg CC_REGNUM) (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")) + (match_operand:FPR 2 "general_operand" "f,")) (match_operand:FPR 3 "const0_operand" ""))) (clobber (match_scratch:FPR 0 "=f,f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sbr\t%0,%2 - sb\t%0,%2" + sbr\t%0,%2 + sb\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsimp")]) (define_insn "*sub3_ibm" [(set (match_operand:FPR 0 "register_operand" "=f,f") (minus:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) + (match_operand:FPR 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - sr\t%0,%2 - s\t%0,%2" - [(set_attr "op_type" "RR,RX") + sr\t%0,%2 + s\t%0,%2" + [(set_attr "op_type" ",") (set_attr "type" "fsimp")]) @@ -4168,53 +4453,53 @@ (define_expand "mul3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT" "") (define_insn "*mul3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - mbr\t%0,%2 - mb\t%0,%2" + mbr\t%0,%2 + mb\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fmul")]) (define_insn "*mul3_ibm" [(set (match_operand:FPR 0 "register_operand" "=f,f") (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - mr\t%0,%2 - m\t%0,%2" - [(set_attr "op_type" "RR,RX") + mr\t%0,%2 + m\t%0,%2" + [(set_attr "op_type" ",") (set_attr "type" "fmul")]) (define_insn "*fmadd" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "%f,f") - (match_operand:FPR 2 "nonimmediate_operand" "f,R")) - (match_operand:FPR 3 "register_operand" "0,0")))] + [(set (match_operand:DSF 0 "register_operand" "=f,f") + (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f") + (match_operand:DSF 2 "nonimmediate_operand" "f,R")) + (match_operand:DSF 3 "register_operand" "0,0")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" "@ - mabr\t%0,%1,%2 - mab\t%0,%1,%2" + mabr\t%0,%1,%2 + mab\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fmul")]) (define_insn "*fmsub" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "f,f") - (match_operand:FPR 2 "nonimmediate_operand" "f,R")) - (match_operand:FPR 3 "register_operand" "0,0")))] + [(set (match_operand:DSF 0 "register_operand" "=f,f") + (minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f") + (match_operand:DSF 2 "nonimmediate_operand" "f,R")) + (match_operand:DSF 3 "register_operand" "0,0")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" "@ - msbr\t%0,%1,%2 - msb\t%0,%1,%2" + msbr\t%0,%1,%2 + msb\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fmul")]) @@ -4661,30 +4946,30 @@ (define_expand "div3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT" "") (define_insn "*div3" [(set (match_operand:FPR 0 "register_operand" "=f,f") (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - dbr\t%0,%2 - db\t%0,%2" + dbr\t%0,%2 + db\t%0,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fdiv")]) (define_insn "*div3_ibm" [(set (match_operand:FPR 0 "register_operand" "=f,f") (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] + (match_operand:FPR 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - dr\t%0,%2 - d\t%0,%2" - [(set_attr "op_type" "RR,RX") + dr\t%0,%2 + d\t%0,%2" + [(set_attr "op_type" ",") (set_attr "type" "fdiv")]) @@ -5667,7 +5952,7 @@ (set (match_operand:FPR 0 "register_operand" "=f") (neg:FPR (match_dup 1)))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + "lcbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5677,7 +5962,7 @@ (match_operand:FPR 2 "const0_operand" ""))) (clobber (match_scratch:FPR 0 "=f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + "lcbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5686,7 +5971,7 @@ (neg:FPR (match_operand:FPR 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + "lcbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5695,8 +5980,8 @@ (neg:FPR (match_operand:FPR 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lcr\t%0,%1" - [(set_attr "op_type" "RR") + "lcr\t%0,%1" + [(set_attr "op_type" "") (set_attr "type" "fsimp")]) @@ -5774,7 +6059,7 @@ (set (match_operand:FPR 0 "register_operand" "=f") (abs:FPR (match_dup 1)))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5784,7 +6069,7 @@ (match_operand:FPR 2 "const0_operand" ""))) (clobber (match_scratch:FPR 0 "=f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5793,7 +6078,7 @@ (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5802,8 +6087,8 @@ (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lpr\t%0,%1" - [(set_attr "op_type" "RR") + "lpr\t%0,%1" + [(set_attr "op_type" "") (set_attr "type" "fsimp")]) ;; @@ -5873,7 +6158,7 @@ (set (match_operand:FPR 0 "register_operand" "=f") (neg:FPR (abs:FPR (match_dup 1))))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5883,7 +6168,7 @@ (match_operand:FPR 2 "const0_operand" ""))) (clobber (match_scratch:FPR 0 "=f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5892,7 +6177,7 @@ (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))) (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5906,11 +6191,11 @@ (define_insn "sqrt2" [(set (match_operand:FPR 0 "register_operand" "=f,f") - (sqrt:FPR (match_operand:FPR 1 "general_operand" "f,R")))] + (sqrt:FPR (match_operand:FPR 1 "general_operand" "f,")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sqbr\t%0,%1 - sqb\t%0,%1" + sqbr\t%0,%1 + sqb\t%0,%1" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsqrt")]) diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt index d6567860115..21ef4f31065 100644 --- a/gcc/config/s390/s390.opt +++ b/gcc/config/s390/s390.opt @@ -1,6 +1,6 @@ ; Options for the S/390 / zSeries port of the compiler. -; Copyright (C) 2005 Free Software Foundation, Inc. +; Copyright (C) 2005, 2006 Free Software Foundation, Inc. ; ; This file is part of GCC. ; @@ -51,6 +51,14 @@ mhard-float Target Report RejectNegative Mask(HARD_FLOAT) Use hardware fp +mlong-double-128 +Target Report RejectNegative Mask(LONG_DOUBLE_128) +Use 128-bit long double + +mlong-double-64 +Target Report RejectNegative InverseMask(LONG_DOUBLE_128) +Use 64-bit long double + mpacked-stack Target Report Mask(PACKED_STACK) Use packed stack layout diff --git a/gcc/config/s390/t-crtstuff b/gcc/config/s390/t-crtstuff index 5572e6bf54e..39b0eba6b97 100644 --- a/gcc/config/s390/t-crtstuff +++ b/gcc/config/s390/t-crtstuff @@ -2,3 +2,4 @@ # because then __FRAME_END__ might not be the last thing in .eh_frame # section. CRTSTUFF_T_CFLAGS = -fno-asynchronous-unwind-tables +TARGET_LIBGCC2_CFLAGS += -mlong-double-128 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8edff2a4267..b4927d9f890 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -674,8 +674,8 @@ See RS/6000 and PowerPC Options. @emph{S/390 and zSeries Options} @gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol --mhard-float -msoft-float -mbackchain -mno-backchain @gol --mpacked-stack -mno-packed-stack @gol +-mhard-float -msoft-float -mlong-double-64 -mlong-double-128 @gol +-mbackchain -mno-backchain -mpacked-stack -mno-packed-stack @gol -msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol -m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol -mtpf-trace -mno-tpf-trace -mfused-madd -mno-fused-madd @gol @@ -11711,6 +11711,14 @@ functions in @file{libgcc.a} will be used to perform floating-point operations. When @option{-mhard-float} is specified, the compiler generates IEEE floating-point instructions. This is the default. +@item -mlong-double-64 +@itemx -mlong-double-128 +@opindex mlong-double-64 +@opindex mlong-double-128 +These switches control the size of @code{long double} type. A size +of 64bit makes the @code{long double} type equivalent to the @code{double} +type. This is the default. + @item -mbackchain @itemx -mno-backchain @opindex mbackchain