This patch is the first of two rs6000.md patches to straighten out the IFmode,
KFmode, and TFmode support.  Part of the change is to change the iterator names
to be easier to understand, using IEEE128, IBM128, and FLOAT128 as the
iterators.  This change, and the next change go through and have parallel insns
for handling IFmode and TFmode (when -mabi=ibmlongdouble) for IBM extended
double, and for handling KFmode and TFmode (when -mabi=ieeelongdouble).  The
idea is to prepare the way in GCC 7.0 to change the default for long double.

I have built the compiler with this patch and the previous subpatches (1-11).
I have bootstrapped the compiler with all 16 subpatches installed, and there
were no regressions.  Is it ok to install in the trunk?

2015-10-22  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * config/rs6000/rs6000.md (FLOAT128_SFDFTF): Delete iterator,
        rework IEEE 128-bit floating point insns to deal with TFmode being
        either IBM extended double or IEEE 128-bit floating point.
        (IFKF): Likewise.
        (IBM128): Update iterator to add condition that the mode is IBM
        extended double.
        (IEEE128): New iterator for IEEE 128-bit floating point.
        (TFIFKF): Rename TFIFKF iterator to FLOAT128.
        (FLOAT128): Likewise.
        (signbit<mode>2): FLOAT128_IBM_P condition test moved into IBM128
        iterator.
        (neg<mode>2): Replace TFIFKF iterator with FLOAT128. Add support
        for TFmode being IEEE 128-bit floating point. Use IEEE128 iterator
        instead of hard coding TFmode or KFmode.
        (negtf2_internal): Likewise.
        (neg<mode>2_internal): Likewise.
        (abs<mode>2): Likewise.
        (abstf2_internal): Likewise.
        (abs<mode>2_internal): Likewise.
        (ieee_128bit_neg<mode>2): Likewise.
        (ieee_128bit_neg<mode>2_internal): Likewise.
        (ieee_128bit_abs<mode>2): Likewise.
        (ieee_128bit_abs<mode>2_internal): Likewise.
        (ieee_128bit_nabs<mode>2): Likewise.
        (ieee_128bit_nabs<mode>2_internal): Likewise.
        (extendiftf2): Add explicit conversions between 128-bit floating
        point types. Drop the old conversions that had become unwieldy.
        (extend<FLOAT128_SFDFTF:mode><IFKF:mode>2): Likewise.
        (extendifkf2): Likewise.
        (trunc<IFKF:mode><FLOAT128_SFDFTF:mode>2): Likewise.
        (extendtfkf2): Likewise.
        (fix_trunc<IFKF:mode><SDI:mode>2): Likewise.
        (trunciftf2): Likewise.
        (fixuns_trunc<IFKF:mode><SDI:mode>2): Likewise.
        (truncifkf2): Likewise.
        (float<SDI:mode><IFKF:mode>2): Likewise.
        (trunckftf2): Likewise.
        (floatuns<SDI:mode><IFKF:mode>2): Likewise.
        (trunctfif2): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 229182)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -448,24 +448,18 @@ (define_mode_iterator RECIPF [SF DF V4SF
 ; Iterator for just SF/DF
 (define_mode_iterator SFDF [SF DF])
 
-; Iterator for float128 floating conversions
-(define_mode_iterator FLOAT128_SFDFTF [
-    (SF "TARGET_FLOAT128")
-    (DF "TARGET_FLOAT128")
-    (TF "FLOAT128_IBM_P (TFmode)")
-    (IF "TARGET_FLOAT128")])
-
-; Iterator for special 128-bit floating point.  This is for non-default
-; conversions, so TFmode is not used here.
-(define_mode_iterator IFKF [IF KF])
-
 ; Iterator for 128-bit floating point that uses the IBM double-double format
-(define_mode_iterator IBM128 [IF TF])
+(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
+                             (TF "FLOAT128_IBM_P (TFmode)")])
+
+; Iterator for 128-bit floating point that uses IEEE 128-bit float
+(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
+                              (TF "FLOAT128_IEEE_P (TFmode)")])
 
 ; Iterator for 128-bit floating point
-(define_mode_iterator TFIFKF [(KF "TARGET_FLOAT128")
-                             (IF "TARGET_FLOAT128")
-                             (TF "TARGET_LONG_DOUBLE_128")])
+(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128")
+                               (IF "TARGET_FLOAT128")
+                               (TF "TARGET_LONG_DOUBLE_128")])
 
 ; SF/DF suffix for traditional floating instructions
 (define_mode_attr Ftrad                [(SF "s") (DF "")])
@@ -4248,8 +4242,7 @@ (define_expand "signbit<mode>2"
        (match_dup 5))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
        (match_dup 6))]
-  "FLOAT128_IBM_P (<MODE>mode)
-   && TARGET_HARD_FLOAT
+  "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)"
 {
   operands[2] = gen_reg_rtx (DFmode);
@@ -6735,8 +6728,8 @@ (define_expand "floatuns<mode>tf2"
 })
 
 (define_expand "neg<mode>2"
-  [(set (match_operand:TFIFKF 0 "gpc_reg_operand" "")
-       (neg:TFIFKF (match_operand:TFIFKF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
+       (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
   "FLOAT128_IEEE_P (<MODE>mode)
    || (FLOAT128_IBM_P (<MODE>mode)
        && TARGET_HARD_FLOAT
@@ -6746,7 +6739,14 @@ (define_expand "neg<mode>2"
   if (FLOAT128_IEEE_P (<MODE>mode))
     {
       if (TARGET_FLOAT128)
-       emit_insn (gen_ieee_128bit_vsx_neg<mode>2 (operands[0], operands[1]));
+       {
+         if (<MODE>mode == TFmode)
+           emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
+         else if (<MODE>mode == KFmode)
+           emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
+         else
+           gcc_unreachable ();
+       }
       else
        {
          rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
@@ -6761,9 +6761,9 @@ (define_expand "neg<mode>2"
     }
 }")
 
-(define_insn "negtf2_internal"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
-       (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
+(define_insn "neg<mode>2_internal"
+  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
+       (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
   "*
 {
@@ -6776,8 +6776,8 @@ (define_insn "negtf2_internal"
    (set_attr "length" "8")])
 
 (define_expand "abs<mode>2"
-  [(set (match_operand:TFIFKF 0 "gpc_reg_operand" "")
-       (abs:TFIFKF (match_operand:TFIFKF 1 "gpc_reg_operand" "")))]
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
+       (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
   "FLOAT128_IEEE_P (<MODE>mode)
    || (FLOAT128_IBM_P (<MODE>mode)
        && TARGET_HARD_FLOAT
@@ -6790,7 +6790,12 @@ (define_expand "abs<mode>2"
     {
       if (TARGET_FLOAT128)
        {
-         emit_insn (gen_ieee_128bit_vsx_abs<mode>2 (operands[0], operands[1]));
+         if (<MODE>mode == TFmode)
+           emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
+         else if (<MODE>mode == KFmode)
+           emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
+         else
+           FAIL;
          DONE;
        }
       else
@@ -6798,22 +6803,26 @@ (define_expand "abs<mode>2"
     }
 
   label = gen_label_rtx ();
-  if (TARGET_E500_DOUBLE)
+  if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
     {
       if (flag_finite_math_only && !flag_trapping_math)
        emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
       else
        emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
     }
-  else
+  else if (<MODE>mode == TFmode)
     emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
+  else if (<MODE>mode == TFmode)
+    emit_insn (gen_absif2_internal (operands[0], operands[1], label));
+  else
+    FAIL;
   emit_label (label);
   DONE;
 }")
 
-(define_expand "abstf2_internal"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-       (match_operand:TF 1 "gpc_reg_operand" ""))
+(define_expand "abs<mode>2_internal"
+  [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
+       (match_operand:IBM128 1 "gpc_reg_operand" ""))
    (set (match_dup 3) (match_dup 5))
    (set (match_dup 5) (abs:DF (match_dup 5)))
    (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
@@ -6821,8 +6830,7 @@ (define_expand "abstf2_internal"
                           (label_ref (match_operand 2 "" ""))
                           (pc)))
    (set (match_dup 6) (neg:DF (match_dup 6)))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
    && TARGET_LONG_DOUBLE_128"
   "
 {
@@ -6830,8 +6838,8 @@ (define_expand "abstf2_internal"
   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = gen_reg_rtx (CCFPmode);
-  operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
-  operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+  operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
+  operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
 }")
 
 
@@ -6864,14 +6872,14 @@ (define_expand "ieee_128bit_negative_zer
 ;; neg/abs to create the constant just once.
 
 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (clobber (match_scratch:V16QI 2 "=v"))]
-  "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
+  "TARGET_FLOAT128"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
-                  (neg:TFIFKF (match_dup 1)))
+                  (neg:IEEE128 (match_dup 1)))
              (use (match_dup 2))])]
 {
   if (GET_CODE (operands[2]) == SCRATCH)
@@ -6884,8 +6892,8 @@ (define_insn_and_split "ieee_128bit_vsx_
    (set_attr "type" "vecsimple")])
 
 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (use (match_operand:V16QI 2 "register_operand" "=v"))]
   "TARGET_FLOAT128"
   "xxlxor %x0,%x1,%x2"
@@ -6893,14 +6901,14 @@ (define_insn "*ieee_128bit_vsx_neg<mode>
 
 ;; IEEE 128-bit absolute value
 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (abs:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (clobber (match_scratch:V16QI 2 "=v"))]
   "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
-                  (abs:TFIFKF (match_dup 1)))
+                  (abs:IEEE128 (match_dup 1)))
              (use (match_dup 2))])]
 {
   if (GET_CODE (operands[2]) == SCRATCH)
@@ -6913,8 +6921,8 @@ (define_insn_and_split "ieee_128bit_vsx_
    (set_attr "type" "vecsimple")])
 
 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (abs:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
    (use (match_operand:V16QI 2 "register_operand" "=v"))]
   "TARGET_FLOAT128"
   "xxlandc %x0,%x1,%x2"
@@ -6922,16 +6930,16 @@ (define_insn "*ieee_128bit_vsx_abs<mode>
 
 ;; IEEE 128-bit negative absolute value
 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (neg:TFIFKF
-        (abs:TFIFKF
-         (match_operand:TFIFKF 1 "register_operand" "wa"))))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (neg:IEEE128
+        (abs:IEEE128
+         (match_operand:IEEE128 1 "register_operand" "wa"))))
    (clobber (match_scratch:V16QI 2 "=v"))]
   "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
   "#"
   "&& 1"
   [(parallel [(set (match_dup 0)
-                  (abs:TFIFKF (match_dup 1)))
+                  (abs:IEEE128 (match_dup 1)))
              (use (match_dup 2))])]
 {
   if (GET_CODE (operands[2]) == SCRATCH)
@@ -6944,70 +6952,78 @@ (define_insn_and_split "*ieee_128bit_vsx
    (set_attr "type" "vecsimple")])
 
 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
-  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
-       (neg:TFIFKF
-        (abs:TFIFKF
-         (match_operand:TFIFKF 1 "register_operand" "wa"))))
+  [(set (match_operand:IEEE128 0 "register_operand" "=wa")
+       (neg:IEEE128
+        (abs:IEEE128
+         (match_operand:IEEE128 1 "register_operand" "wa"))))
    (use (match_operand:V16QI 2 "register_operand" "=v"))]
   "TARGET_FLOAT128"
   "xxlor %x0,%x1,%x2"
   [(set_attr "type" "vecsimple")])
 
 ;; Float128 conversion functions.  These expand to library function calls.
+;; We use expand to convert from IBM double double to IEEE 128-bit
+;; and trunc for the opposite.
+(define_expand "extendiftf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
+  "TARGET_FLOAT128"
+{
+  rs6000_expand_float128_convert (operands[0], operands[1], false);
+  DONE;
+})
 
-(define_expand "extend<FLOAT128_SFDFTF:mode><IFKF:mode>2"
-  [(set (match_operand:IFKF 0 "nonimmediate_operand" "")
-       (float_extend:IFKF
-        (match_operand:FLOAT128_SFDFTF 1 "gpc_reg_operand" "")))]
+(define_expand "extendifkf2"
+  [(set (match_operand:KF 0 "gpc_reg_operand" "")
+       (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "trunc<IFKF:mode><FLOAT128_SFDFTF:mode>2"
-  [(set (match_operand:FLOAT128_SFDFTF 0 "nonimmediate_operand" "")
-       (float_truncate:FLOAT128_SFDFTF
-        (match_operand:IFKF 1 "gpc_reg_operand" "")))]
+(define_expand "extendtfkf2"
+  [(set (match_operand:KF 0 "gpc_reg_operand" "")
+       (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "fix_trunc<IFKF:mode><SDI:mode>2"
-  [(set (match_operand:SDI 0 "nonimmediate_operand" "")
-       (fix:SDI (match_operand:IFKF 1 "gpc_reg_operand" "")))]
+(define_expand "trunciftf2"
+  [(set (match_operand:IF 0 "gpc_reg_operand" "")
+       (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "fixuns_trunc<IFKF:mode><SDI:mode>2"
-  [(set (match_operand:SDI 0 "nonimmediate_operand" "")
-       (unsigned_fix:SDI (match_operand:IFKF 1 "gpc_reg_operand" "")))]
+(define_expand "truncifkf2"
+  [(set (match_operand:IF 0 "gpc_reg_operand" "")
+       (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
-  rs6000_expand_float128_convert (operands[0], operands[1], true);
+  rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "float<SDI:mode><IFKF:mode>2"
-  [(set (match_operand:IFKF 0 "nonimmediate_operand" "")
-       (float:KF (match_operand:SDI 1 "gpc_reg_operand" "")))]
+(define_expand "trunckftf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "floatuns<SDI:mode><IFKF:mode>2"
-  [(set (match_operand:IFKF 0 "nonimmediate_operand" "")
-       (unsigned_float:IFKF (match_operand:SDI 1 "gpc_reg_operand" "")))]
+(define_expand "trunctfif2"
+  [(set (match_operand:IF 0 "gpc_reg_operand" "")
+       (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
   "TARGET_FLOAT128"
 {
-  rs6000_expand_float128_convert (operands[0], operands[1], true);
+  rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 

Reply via email to