OSDN Git Service

2006-02-03 Andreas Krebbel <krebbel1@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Feb 2006 07:52:57 +0000 (07:52 +0000)
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Feb 2006 07:52:57 +0000 (07:52 +0000)
            Ulrich Weigand  <uweigand@de.ibm.com>

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.
(<de>, <dee> mode attributes): Removed.
(<xde>, <xdee>, <RRe>, <RXe>, <Rf> mode attributes): New.
("*cmp<mode>_ccs_0", "*cmp<mode>_ccs_0_ibm", "*cmp<mode>_ccs",
"*cmp<mode>_ccs_ibm", "fix_trunc<FPR:mode><GPR:mode>2_ieee",
"floatdi<mode>2", "floatsi<mode>2_ieee", "*add<mode>3",
"*add<mode>3_cc", "*add<mode>3_cconly", "*add<mode>3_ibm",
"*sub<mode>3", "*sub<mode>3_cc", "*sub<mode>3_cconly",
"*sub<mode>3_ibm", "*mul<mode>3_ibm", "*fmadd<mode>", "*fmsub<mode>",
"*div<mode>3", "*div<mode>3_ibm", "*neg<mode>2_cc",
"*neg<mode>2_cconly", "*neg<mode>2", "*neg<mode>2_ibm",
"*abs<mode>2_cc", "*abs<mode>2_cconly", "*abs<mode>2",
"*abs<mode>2_ibm", "*negabs<mode>2_cc", "*negabs<mode>2_cconly",
"*negabs<mode>2", "sqrt<mode>2"):
Changed <de> to <xde>. R constraint replaced by <Rf>.
("*mul<mode>3"): Changed <dee> to <xdee>. R constraint replaced by
<Rf>.
("fix_trunc<FPR:mode>di2"): 'FPR:' removed.
        ("*fmadd<mode>", "*fmsub<mode>"): 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.

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

gcc/ChangeLog
gcc/config/s390/2084.md
gcc/config/s390/fixdfdi.h
gcc/config/s390/libgcc-glibc.ver
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md
gcc/config/s390/s390.opt
gcc/config/s390/t-crtstuff
gcc/doc/invoke.texi

index 83d13e7..2a8be97 100644 (file)
@@ -1,3 +1,62 @@
+2006-02-03  Andreas Krebbel  <krebbel1@de.ibm.com>
+            Ulrich Weigand  <uweigand@de.ibm.com>
+
+       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.
+       (<de>, <dee> mode attributes): Removed.
+       (<xde>, <xdee>, <RRe>, <RXe>, <Rf> mode attributes): New.
+       ("*cmp<mode>_ccs_0", "*cmp<mode>_ccs_0_ibm", "*cmp<mode>_ccs", 
+       "*cmp<mode>_ccs_ibm", "fix_trunc<FPR:mode><GPR:mode>2_ieee", 
+       "floatdi<mode>2", "floatsi<mode>2_ieee", "*add<mode>3", 
+       "*add<mode>3_cc", "*add<mode>3_cconly", "*add<mode>3_ibm", 
+       "*sub<mode>3", "*sub<mode>3_cc", "*sub<mode>3_cconly", 
+       "*sub<mode>3_ibm", "*mul<mode>3_ibm", "*fmadd<mode>", "*fmsub<mode>",
+       "*div<mode>3", "*div<mode>3_ibm", "*neg<mode>2_cc", 
+       "*neg<mode>2_cconly", "*neg<mode>2", "*neg<mode>2_ibm", 
+       "*abs<mode>2_cc", "*abs<mode>2_cconly", "*abs<mode>2",
+       "*abs<mode>2_ibm", "*negabs<mode>2_cc", "*negabs<mode>2_cconly", 
+       "*negabs<mode>2", "sqrt<mode>2"):
+       Changed <de> to <xde>. R constraint replaced by <Rf>.
+       ("*mul<mode>3"): Changed <dee> to <xdee>. R constraint replaced by 
+       <Rf>.
+       ("fix_trunc<FPR:mode>di2"): 'FPR:' removed.
+        ("*fmadd<mode>", "*fmsub<mode>"): 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  <pinskia@physics.uc.edu>
 
        PR target/25377
index be56f76..3a4479a 100644 (file)
@@ -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).
 
 ;; 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"))
        (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"))
        (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"))
        (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"))
        (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"))
                 "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")
 ;;
                 "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")
 
                 "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")
 
index 4802a59..fd12243 100644 (file)
@@ -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
-
index 1d9e229..e9413d0 100644 (file)
@@ -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
+}
index 5d80d50..dfefaca 100644 (file)
@@ -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,
index d8d1d19..1a61158 100644 (file)
@@ -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.  */
 
index 40a32d4..0f3e562 100644 (file)
@@ -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).
 (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")))
 
 ;; 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.
                          (plus "add") (minus "sub") (mult "nand")])
 
 
-;; In FPR templates, a string like "lt<de>br" will expand to "ltdbr" in DFmode
-;; and "ltebr" in SFmode.
-(define_mode_attr de [(DF "d") (SF "e")])
+;; In FPR templates, a string like "lt<de>br" 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 "m<dee>br" will expand to "mdbr" in DFmode
-;; and "meebr" in SFmode.  This is needed for the 'mul<mode>3' pattern. 
-(define_mode_attr dee [(DF "d") (SF "ee")])
+;; In FPR templates, a string like "m<dee>br" 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, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
+;; Likewise for "<RXe>".
+(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
+(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
+
+;; In FPR templates, "<Rf>" 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 "<d0>" will expand to "d" in DImode
 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
         (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"
-  "lt<de>br\t%0,%0"
+  "lt<xde>br\t%0,%0"
    [(set_attr "op_type" "RRE")
     (set_attr "type"  "fsimp<mode>")])
 
         (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"
-  "lt<de>r\t%0,%0"
-   [(set_attr "op_type" "RR")
+  "lt<xde>r\t%0,%0"
+   [(set_attr "op_type" "<RRe>")
     (set_attr "type"  "fsimp<mode>")])
 
 (define_insn "*cmp<mode>_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,<Rf>")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   c<de>br\t%0,%1
-   c<de>b\t%0,%1"
+   c<xde>br\t%0,%1
+   c<xde>b\t%0,%1"
    [(set_attr "op_type" "RRE,RXE")
     (set_attr "type"  "fsimp<mode>")])
 
 (define_insn "*cmp<mode>_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,<Rf>")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   c<de>r\t%0,%1
-   c<de>\t%0,%1"
-   [(set_attr "op_type" "RR,RX")
+   c<xde>r\t%0,%1
+   c<xde>\t%0,%1"
+   [(set_attr "op_type" "<RRe>,<RXe>")
     (set_attr "type"  "fsimp<mode>")])
 
 
    (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).
 ;
 
   DONE;
 })
 
-(define_expand "fix_trunc<FPR:mode>di2"
+(define_expand "fix_trunc<mode>di2"
   [(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 (<FPR:MODE>mode, operands[1]);
-  emit_insn (gen_fix_trunc<FPR:mode>di2_ieee (operands[0], operands[1],
+  operands[1] = force_reg (<MODE>mode, operands[1]);
+  emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1],
       GEN_INT(5)));
   DONE;
 })
    (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "c<GPR:gf><FPR:de>br\t%0,%h2,%1"
+  "c<GPR:gf><FPR:xde>br\t%0,%h2,%1"
   [(set_attr "op_type" "RRE")
    (set_attr "type"    "ftoi")])
 
 ;
+; fix_trunctf(si|di)2 instruction pattern(s).
+;
+
+(define_expand "fix_trunctf<mode>2"
+  [(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).
 ;
 
 })
 
 ;
-; floatdi(df|sf)2 instruction pattern(s).
+; float(si|di)(tf|df|sf)2 instruction pattern(s).
 ;
 
 (define_insn "floatdi<mode>2"
   [(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"
-  "c<de>gbr\t%0,%1"
+  "c<xde>gbr\t%0,%1"
   [(set_attr "op_type" "RRE")
    (set_attr "type"    "itof" )])
 
+(define_insn "floatsi<mode>2_ieee"
+  [(set (match_operand:FPR 0 "register_operand" "=f")
+        (float:FPR (match_operand:SI 1 "register_operand" "d")))]
+  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+  "c<xde>fbr\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" "")))]
     }
 })
 
-(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")))
     }
 })
 
-(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).
 ;
         (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")
    (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).
 ;
 
    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")
   [(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
   [(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,<Rf>")))
      (clobber (reg:CC CC_REGNUM))])]
   "TARGET_HARD_FLOAT"
   "")
 (define_insn "*add<mode>3"
   [(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,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_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,<Rf>"))
                 (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"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_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,<Rf>"))
                 (match_operand:FPR 3 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   a<de>br\t%0,%2
-   a<de>b\t%0,%2"
+   a<xde>br\t%0,%2
+   a<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*add<mode>3_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,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   a<de>r\t%0,%2
-   a<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   a<xde>r\t%0,%2
+   a<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
 (define_insn "*sub<mode>3"
   [(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,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_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,<Rf>"))
                 (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"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_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,<Rf>"))
                 (match_operand:FPR 3 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   s<de>br\t%0,%2
-   s<de>b\t%0,%2"
+   s<xde>br\t%0,%2
+   s<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
 (define_insn "*sub<mode>3_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,<Rf>")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   s<de>r\t%0,%2
-   s<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   s<xde>r\t%0,%2
+   s<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
 (define_expand "mul<mode>3"
   [(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,<Rf>")))]
   "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*mul<mode>3"
   [(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,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   m<dee>br\t%0,%2
-   m<dee>b\t%0,%2"
+   m<xdee>br\t%0,%2
+   m<xdee>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*mul<mode>3_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,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   m<de>r\t%0,%2
-   m<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   m<xde>r\t%0,%2
+   m<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*fmadd<mode>"
-  [(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"
   "@
-   ma<de>br\t%0,%1,%2
-   ma<de>b\t%0,%1,%2"
+   ma<xde>br\t%0,%1,%2
+   ma<xde>b\t%0,%1,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
 (define_insn "*fmsub<mode>"
-  [(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"
   "@
-   ms<de>br\t%0,%1,%2
-   ms<de>b\t%0,%1,%2"
+   ms<xde>br\t%0,%1,%2
+   ms<xde>b\t%0,%1,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fmul<mode>")])
 
 (define_expand "div<mode>3"
   [(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,<Rf>")))]
   "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*div<mode>3"
   [(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,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   d<de>br\t%0,%2
-   d<de>b\t%0,%2"
+   d<xde>br\t%0,%2
+   d<xde>b\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
    (set_attr "type"     "fdiv<mode>")])
 
 (define_insn "*div<mode>3_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,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "@
-   d<de>r\t%0,%2
-   d<de>\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
+   d<xde>r\t%0,%2
+   d<xde>\t%0,%2"
+  [(set_attr "op_type"  "<RRe>,<RXe>")
    (set_attr "type"     "fdiv<mode>")])
 
 
    (set (match_operand:FPR 0 "register_operand" "=f")
         (neg:FPR (match_dup 1)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
         (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lc<de>br\t%0,%1"
+  "lc<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
         (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
-  "lc<de>r\t%0,%1"
-  [(set_attr "op_type"  "RR")
+  "lc<xde>r\t%0,%1"
+  [(set_attr "op_type"  "<RRe>")
    (set_attr "type"     "fsimp<mode>")])
 
 
    (set (match_operand:FPR 0 "register_operand" "=f")
         (abs:FPR (match_dup 1)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
         (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "lp<de>br\t%0,%1"
+  "lp<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
         (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
-  "lp<de>r\t%0,%1"
-  [(set_attr "op_type"  "RR")
+  "lp<xde>r\t%0,%1"
+  [(set_attr "op_type"  "<RRe>")
    (set_attr "type"     "fsimp<mode>")])
 
 ;;
    (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"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
                  (match_operand:FPR 2 "const0_operand" "")))
    (clobber (match_scratch:FPR 0 "=f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
   
         (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
-  "ln<de>br\t%0,%1"
+  "ln<xde>br\t%0,%1"
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
 
 (define_insn "sqrt<mode>2"
   [(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,<Rf>")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
-   sq<de>br\t%0,%1
-   sq<de>b\t%0,%1"
+   sq<xde>br\t%0,%1
+   sq<xde>b\t%0,%1"
   [(set_attr "op_type" "RRE,RXE")
    (set_attr "type" "fsqrt<mode>")])
 
index d656786..21ef4f3 100644 (file)
@@ -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
index 5572e6b..39b0eba 100644 (file)
@@ -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
index 8edff2a..b4927d9 100644 (file)
@@ -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