This patch is the second part to allow TFmode to be IBM extended double or IEEE
128-bit floating point depending on switches.

I have built the compiler with this patch and the previous subpatches (1-12).
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 (FP iterator): Allow TFmode to be IEEE
        128-bit floating point.
        (extenddftf2): Rework 128-bit floating point conversions to
        properly handle -mabi=ieeelongdouble. Merge IFmode, TFmode, and
        KFmode expanders into one function.
        (extenddf<mode>2): Likewise.
        (extenddftf2_fprs): Likewise.
        (extenddf<mode>2_fprs): Likewise.
        (extenddftf2_vsx): Likewise.
        (extenddf<mode>2_vsx): Likewise.
        (extendsftf2): Likewise.
        (extendsf<mode>2): Likewise.
        (trunctfdf2): Likewise.
        (trunc<mode>df2): Likewise.
        (trunctfdf2_internal1): Likewise.
        (trunc<mode>df2_internal1): Likewise.
        (trunctfdf2_internal2): Likewise.
        (trunc<mode>df2_internal2): Likewise.
        (trunctfsf2): Likewise.
        (trunc<mode>sf2): Likewise.
        (trunctfsf2_fprs): Likewise.
        (trunc<mode>sf2_fprs): Likewise.
        (floatsit2f): Likewise.
        (floatsi<mode>2): Likewise.
        (fix_trunc_helper): Likewise.
        (fix_trunc_helper<mode>): Likewise.
        (fix_trunctfsi2): Likewise.
        (fix_trunc<mode>si2): Likewise.
        (fix_trunctfsi2_fprs): Likewise.
        (fix_trunc<mode>si2_fprs): Likewise.
        (fix_trunctfsi2_internal): Likewise.
        (fix_trunc<mode>si2_internal): Likewise.
        (fix_trunctfdi2): Likewise.
        (fix_trunc<mode>di2): Likewise.
        (fixuns_trunctf<mode>2): Likewise.
        (fixuns_trunc<IEEE128:mode><SDI:mode>2): Likewise.
        (floatditf2): Likewise.
        (floatdi<mode>2): Likewise.
        (floatuns<mode>tf2): Likewise.
        (floatuns<SDI:mode><IEEE128:mode>): 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 229198)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -347,8 +347,7 @@ (define_mode_iterator FP [
    && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)")
   (DF "TARGET_HARD_FLOAT 
    && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)")
-  (TF "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT
+  (TF "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128")
   (IF "TARGET_FLOAT128")
@@ -6463,34 +6462,51 @@ (define_insn_and_split "*mov<mode>_softf
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
   [(set_attr "length" "20,20,16")])
 
-(define_expand "extenddftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-       (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "")))]
+(define_expand "extenddf<mode>2"
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
+       (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128"
 {
-  if (TARGET_IEEEQUAD)
+  if (FLOAT128_IEEE_P (<MODE>mode))
     rs6000_expand_float128_convert (operands[0], operands[1], false);
   else if (TARGET_E500_DOUBLE)
-    emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
+    {
+      gcc_assert (<MODE>mode == TFmode);
+      emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
+    }
   else if (TARGET_VSX)
-    emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
-  else
+    {
+      if (<MODE>mode == TFmode)
+       emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
+      else if (<MODE>mode == IFmode)
+       emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
+      else
+       gcc_unreachable ();
+    }
+   else
     {
       rtx zero = gen_reg_rtx (DFmode);
       rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
-      emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
+
+      if (<MODE>mode == TFmode)
+       emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
+      else if (<MODE>mode == IFmode)
+       emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
+      else
+       gcc_unreachable ();
     }
   DONE;
 })
 
 ;; Allow memory operands for the source to be created by the combiner.
-(define_insn_and_split "extenddftf2_fprs"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d,&d")
-       (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
+(define_insn_and_split "extenddf<mode>2_fprs"
+  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
+       (float_extend:IBM128
+        (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
    (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
   "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
-   && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD"
+   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 1))
@@ -6499,14 +6515,15 @@ (define_insn_and_split "extenddftf2_fprs
   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
 
-  operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
-  operands[4] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
+  operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
 })
 
-(define_insn_and_split "extenddftf2_vsx"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "=d,d")
-       (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
-  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && !TARGET_IEEEQUAD"
+(define_insn_and_split "extenddf<mode>2_vsx"
+  [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
+       (float_extend:IBM128
+        (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
+  "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 2) (match_dup 1))
@@ -6515,47 +6532,48 @@ (define_insn_and_split "extenddftf2_vsx"
   const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
 
-  operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
-  operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+  operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
+  operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
   operands[4] = CONST0_RTX (DFmode);
 })
 
-(define_expand "extendsftf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-       (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
+(define_expand "extendsf<mode>2"
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
+       (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128"
 {
-  if (TARGET_IEEEQUAD)
+  if (FLOAT128_IEEE_P (<MODE>mode))
     rs6000_expand_float128_convert (operands[0], operands[1], false);
   else
     {
       rtx tmp = gen_reg_rtx (DFmode);
       emit_insn (gen_extendsfdf2 (tmp, operands[1]));
-      emit_insn (gen_extenddftf2 (operands[0], tmp));
+      emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
     }
   DONE;
 })
 
-(define_expand "trunctfdf2"
+(define_expand "trunc<mode>df2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
-       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
+       (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128"
 {
-  if (TARGET_IEEEQUAD)
+  if (FLOAT128_IEEE_P (<MODE>mode))
     {
       rs6000_expand_float128_convert (operands[0], operands[1], false);
       DONE;
     }
 })
 
-(define_insn_and_split "trunctfdf2_internal1"
+(define_insn_and_split "trunc<mode>df2_internal1"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
-       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
-  "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
+       (float_truncate:DF
+        (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
+  "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "@
    #
@@ -6568,39 +6586,44 @@ (define_insn_and_split "trunctfdf2_inter
 }
   [(set_attr "type" "fp")])
 
-(define_insn "trunctfdf2_internal2"
+(define_insn "trunc<mode>df2_internal2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
-  "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 
-   && TARGET_LONG_DOUBLE_128"
+       (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
+  "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
+   && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
   "fadd %0,%1,%L1"
   [(set_attr "type" "fp")
    (set_attr "fp_type" "fp_addsub_d")])
 
-(define_expand "trunctfsf2"
+(define_expand "trunc<mode>sf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
-       (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
+       (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128"
 {
-  if (TARGET_IEEEQUAD)
+  if (FLOAT128_IEEE_P (<MODE>mode))
     rs6000_expand_float128_convert (operands[0], operands[1], false);
   else if (TARGET_E500_DOUBLE)
-    emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
-  else
+    {
+      gcc_assert (<MODE>mode == TFmode);
+      emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
+    }
+  else if (<MODE>mode == TFmode)
     emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
+  else if (<MODE>mode == IFmode)
+    emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
+  else
+    gcc_unreachable ();
   DONE;
 })
 
-(define_insn_and_split "trunctfsf2_fprs"
+(define_insn_and_split "trunc<mode>sf2_fprs"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-       (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
+       (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
    (clobber (match_scratch:DF 2 "=d"))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
-   && TARGET_LONG_DOUBLE_128"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 
+   && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 2)
@@ -6609,56 +6632,69 @@ (define_insn_and_split "trunctfsf2_fprs"
        (float_truncate:SF (match_dup 2)))]
   "")
 
-(define_expand "floatsitf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-        (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT
+(define_expand "floatsi<mode>2"
+  [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
+        (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128"
 {
-  rtx tmp = gen_reg_rtx (DFmode);
-  expand_float (tmp, operands[1], false);
-  emit_insn (gen_extenddftf2 (operands[0], tmp));
+  if (FLOAT128_IEEE_P (<MODE>mode))
+    rs6000_expand_float128_convert (operands[0], operands[1], false);
+  else
+    {
+      rtx tmp = gen_reg_rtx (DFmode);
+      expand_float (tmp, operands[1], false);
+      if (<MODE>mode == TFmode)
+       emit_insn (gen_extenddftf2 (operands[0], tmp));
+      else if (<MODE>mode == IFmode)
+       emit_insn (gen_extenddfif2 (operands[0], tmp));
+      else
+       gcc_unreachable ();
+    }
   DONE;
 })
 
 ; fadd, but rounding towards zero.
 ; This is probably not the optimal code sequence.
-(define_insn "fix_trunc_helper"
+(define_insn "fix_trunc_helper<mode>"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
-       (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
+       (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
                   UNSPEC_FIX_TRUNC_TF))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && FLOAT128_IBM_P (<MODE>mode)"
   "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
   [(set_attr "type" "fp")
    (set_attr "length" "20")])
 
-(define_expand "fix_trunctfsi2"
+(define_expand "fix_trunc<mode>si2"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
-       (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
+       (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128"
 {
-  if (TARGET_IEEEQUAD)
+  if (FLOAT128_IEEE_P (<MODE>mode))
     rs6000_expand_float128_convert (operands[0], operands[1], false);
-  else if (TARGET_E500_DOUBLE)
+  else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode)
     emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
-  else
+  else if (<MODE>mode == TFmode)
     emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
+  else if (<MODE>mode == IFmode)
+    emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1]));
+  else
+    gcc_unreachable ();
   DONE;
 })
 
-(define_expand "fix_trunctfsi2_fprs"
+(define_expand "fix_trunc<mode>si2_fprs"
   [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
-                  (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
+                  (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
              (clobber (match_dup 2))
              (clobber (match_dup 3))
              (clobber (match_dup 4))
              (clobber (match_dup 5))])]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
 {
   operands[2] = gen_reg_rtx (DFmode);
   operands[3] = gen_reg_rtx (DFmode);
@@ -6666,21 +6702,21 @@ (define_expand "fix_trunctfsi2_fprs"
   operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
 })
 
-(define_insn_and_split "*fix_trunctfsi2_internal"
+(define_insn_and_split "*fix_trunc<mode>si2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
+        (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
    (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
   ""
   [(pc)]
 {
   rtx lowword;
-  emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
+  emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
+                                        operands[3]));
 
   gcc_assert (MEM_P (operands[5]));
   lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
@@ -6691,37 +6727,37 @@ (define_insn_and_split "*fix_trunctfsi2_
   DONE;
 })
 
-(define_expand "fix_trunctfdi2"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "")
-       (fix:DI (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
+(define_expand "fix_trunc<mode>di2"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "")
+       (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
+  "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "fixuns_trunctf<mode>2"
-  [(set (match_operand:SDI 0 "nonimmediate_operand" "")
-       (unsigned_fix:SDI (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
+(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
+  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
+       (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
+  "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], true);
   DONE;
 })
 
-(define_expand "floatditf2"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "")
-       (float:TF (match_operand:DI 1 "gpc_reg_operand" "")))]
-  "TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
+(define_expand "floatdi<mode>2"
+  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
+       (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
+  "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], false);
   DONE;
 })
 
-(define_expand "floatuns<mode>tf2"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "")
-       (unsigned_float:TF (match_operand:SDI 1 "gpc_reg_operand" "")))]
-  "TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
+(define_expand "floatuns<SDI:mode><IEEE128:mode>2"
+  [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
+       (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))]
+  "TARGET_FLOAT128"
 {
   rs6000_expand_float128_convert (operands[0], operands[1], true);
   DONE;

Reply via email to