vector.md (VEC_L): Add KFmode and TFmode.
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Mon, 3 Aug 2015 17:06:24 +0000 (17:06 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Mon, 3 Aug 2015 17:06:24 +0000 (17:06 +0000)
2015-08-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

* config/rs6000/vector.md (VEC_L): Add KFmode and TFmode.
(VEC_M): Likewise.
(VEC_N): Likewise.
(mov<mode>, VEC_M iterator): Add support for IEEE 128-bit floating
point in VSX registers.

* config/rs6000/constraints.md (wb constraint): Document unused
w<x> constraint.
(we constraint): Likewise.
(wo constraint): Likewise.
(wp constraint): New constraint for IEEE 128-bit floating point in
VSX registers.
(wq constraint): Likewise.

* config/rs6000/predicates.md (easy_fp_constant): Add support for
IEEE 128-bit floating point in VSX registers.
(easy_scalar_constant): Likewise.

* config/rs6000/rs6000.c (rs6000_debug_reg_global): Add new
constraints (wp, wq) for IEEE 128-bit floating point in VSX
registers.
(rs6000_init_hard_regno_mode_ok): Likewise.

* config/rs6000/vsx.md (VSX_LE_128): Add support for IEEE 128-bit
floating point in VSX registers.
(VSX_L): Likewise.
(VSX_M): Likewise.
(VSX_M2): Likewise.
(VSm): Likewise.
(VSs): Likewise.
(VSr): Likewise.
(VSa): Likewise.
(VSv): Likewise.
(vsx_le_permute_<mode>): Add support to properly swap bytes for
IEEE 128-bit floating point in VSX registers on little endian.
(vsx_le_undo_permute_<mode>): Likewise.
(vsx_le_perm_load_<mode>): Likewise.
(vsx_le_perm_store_<mode>): Likewise.
(splitters for IEEE 128-bit fp moves): Likewise.

* config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wp and
wq constraints.

* config/rs6000/altivec.md (VM): Add support for IEEE 128-bit
floating point in VSX registers.
(VM2): Likewise.

* doc/md.text (Machine Constraints): Document wp and wq
constraints on PowerPC.

From-SVN: r226520

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/constraints.md
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/vector.md
gcc/config/rs6000/vsx.md
gcc/doc/md.texi

index 9abde9f912449e8b12e668ee96c155472e53b777..770848af4fa0128e3116b8088634a10cb8fa5c35 100644 (file)
@@ -1,3 +1,55 @@
+2015-08-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * config/rs6000/vector.md (VEC_L): Add KFmode and TFmode.
+       (VEC_M): Likewise.
+       (VEC_N): Likewise.
+       (mov<mode>, VEC_M iterator): Add support for IEEE 128-bit floating
+       point in VSX registers.
+
+       * config/rs6000/constraints.md (wb constraint): Document unused
+       w<x> constraint.
+       (we constraint): Likewise.
+       (wo constraint): Likewise.
+       (wp constraint): New constraint for IEEE 128-bit floating point in
+       VSX registers.
+       (wq constraint): Likewise.
+
+       * config/rs6000/predicates.md (easy_fp_constant): Add support for
+       IEEE 128-bit floating point in VSX registers.
+       (easy_scalar_constant): Likewise.
+
+       * config/rs6000/rs6000.c (rs6000_debug_reg_global): Add new
+       constraints (wp, wq) for IEEE 128-bit floating point in VSX
+       registers.
+       (rs6000_init_hard_regno_mode_ok): Likewise.
+
+       * config/rs6000/vsx.md (VSX_LE_128): Add support for IEEE 128-bit
+       floating point in VSX registers.
+       (VSX_L): Likewise.
+       (VSX_M): Likewise.
+       (VSX_M2): Likewise.
+       (VSm): Likewise.
+       (VSs): Likewise.
+       (VSr): Likewise.
+       (VSa): Likewise.
+       (VSv): Likewise.
+       (vsx_le_permute_<mode>): Add support to properly swap bytes for
+       IEEE 128-bit floating point in VSX registers on little endian.
+       (vsx_le_undo_permute_<mode>): Likewise.
+       (vsx_le_perm_load_<mode>): Likewise.
+       (vsx_le_perm_store_<mode>): Likewise.
+       (splitters for IEEE 128-bit fp moves): Likewise.
+
+       * config/rs6000/rs6000.h (enum r6000_reg_class_enum): Add wp and
+       wq constraints.
+
+       * config/rs6000/altivec.md (VM): Add support for IEEE 128-bit
+       floating point in VSX registers.
+       (VM2): Likewise.
+
+       * doc/md.text (Machine Constraints): Document wp and wq
+       constraints on PowerPC.
+
 2015-08-03  Jeff Law  <law@redhat.com>
 
        PR middle-end/66314
index 5cc0b0359e038ebb5aaae8ea4106ce2821e90642..a8ea0fbdfe146a2fbdc8d84960a885c69901a0ab 100644 (file)
 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
 ;; Vec modes for move/logical/permute ops, include vector types for move not
 ;; otherwise handled by altivec (v2df, v2di, ti)
-(define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI V1TI TI])
+(define_mode_iterator VM [V4SI
+                         V8HI
+                         V16QI
+                         V4SF
+                         V2DF
+                         V2DI
+                         V1TI
+                         TI
+                         (KF "FLOAT128_VECTOR_P (KFmode)")
+                         (TF "FLOAT128_VECTOR_P (TFmode)")])
 
 ;; Like VM, except don't do TImode
-(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI V1TI])
+(define_mode_iterator VM2 [V4SI
+                          V8HI
+                          V16QI
+                          V4SF
+                          V2DF
+                          V2DI
+                          V1TI
+                          (KF "FLOAT128_VECTOR_P (KFmode)")
+                          (TF "FLOAT128_VECTOR_P (TFmode)")])
 
 (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
 (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
index 893a826dcba0ac5eff91809e7204a8698f1daafc..2b8f4bb6066fbe6aed85e03530ad82818b632e8f 100644 (file)
 (define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]"
   "Any VSX register if the -mvsx option was used or NO_REGS.")
 
+;; wb is not currently used
+
 ;; NOTE: For compatibility, "wc" is reserved to represent individual CR bits.
 ;; It is currently used for that purpose in LLVM.
 
 (define_register_constraint "wd" "rs6000_constraints[RS6000_CONSTRAINT_wd]"
   "VSX vector register to hold vector double data or NO_REGS.")
 
+;; we is not currently used
+
 (define_register_constraint "wf" "rs6000_constraints[RS6000_CONSTRAINT_wf]"
   "VSX vector register to hold vector float data or NO_REGS.")
 
 ;; There is a mode_attr that resolves to wm for SDmode and wn for SFmode
 (define_register_constraint "wn" "NO_REGS" "No register (NO_REGS).")
 
+;; wo is not currently used
+
+(define_register_constraint "wp" "rs6000_constraints[RS6000_CONSTRAINT_wp]"
+  "VSX register to use for IEEE 128-bit fp TFmode, or NO_REGS.")
+
+(define_register_constraint "wq" "rs6000_constraints[RS6000_CONSTRAINT_wq]"
+  "VSX register to use for IEEE 128-bit fp KFmode, or NO_REGS.")
+
 (define_register_constraint "wr" "rs6000_constraints[RS6000_CONSTRAINT_wr]"
   "General purpose register if 64-bit instructions are enabled or NO_REGS.")
 
index 2adeee7be31f6fb65787c1f2f59e4bb40313f0a4..5a6bb70c59fbc8c390e11db6533b152ec2ad47a3 100644 (file)
 
   switch (mode)
     {
+    case KFmode:
+    case IFmode:
     case TFmode:
     case DFmode:
     case SFmode:
   if (TARGET_PAIRED_FLOAT)
     return false;
 
+  /* Because IEEE 128-bit floating point is considered a vector type
+     in order to pass it in VSX registers, it might use this function
+     instead of easy_fp_constant.  */
+  if (FLOAT128_VECTOR_P (mode))
+    return easy_fp_constant (op, mode);
+
   if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
     {
       if (zero_constant (op, mode))
index 78de6452feb1a376e981bc96f1b0411734f98d70..bcd0cd074c10b3fc44bcf8aadd4d6ea9b829eb6d 100644 (file)
@@ -2168,6 +2168,8 @@ rs6000_debug_reg_global (void)
           "wk reg_class = %s\n"
           "wl reg_class = %s\n"
           "wm reg_class = %s\n"
+          "wp reg_class = %s\n"
+          "wq reg_class = %s\n"
           "wr reg_class = %s\n"
           "ws reg_class = %s\n"
           "wt reg_class = %s\n"
@@ -2191,6 +2193,8 @@ rs6000_debug_reg_global (void)
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wk]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wm]],
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wp]],
+          reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wq]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]],
           reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wt]],
@@ -2857,6 +2861,13 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   if (TARGET_LFIWZX)
     rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS;     /* DImode  */
 
+  if (TARGET_FLOAT128)
+    {
+      rs6000_constraints[RS6000_CONSTRAINT_wq] = VSX_REGS;     /* KFmode  */
+      if (rs6000_ieeequad)
+       rs6000_constraints[RS6000_CONSTRAINT_wp] = VSX_REGS;    /* TFmode  */
+    }
+
   /* Set up the reload helper and direct move functions.  */
   if (TARGET_VSX || TARGET_ALTIVEC)
     {
index 1518457ad9f1c689120db0cb58aaed3e22e4cff7..102bbce1525a4ccbeb439f3750ab238ab602490f 100644 (file)
@@ -1496,6 +1496,8 @@ enum r6000_reg_class_enum {
   RS6000_CONSTRAINT_wk,                /* FPR/VSX register for DFmode direct moves. */
   RS6000_CONSTRAINT_wl,                /* FPR register for LFIWAX */
   RS6000_CONSTRAINT_wm,                /* VSX register for direct move */
+  RS6000_CONSTRAINT_wp,                /* VSX reg for IEEE 128-bit fp TFmode. */
+  RS6000_CONSTRAINT_wq,                /* VSX reg for IEEE 128-bit fp KFmode.  */
   RS6000_CONSTRAINT_wr,                /* GPR register if 64-bit  */
   RS6000_CONSTRAINT_ws,                /* VSX register for DF */
   RS6000_CONSTRAINT_wt,                /* VSX register for TImode */
index 40d596b43813141b793c03fca6b78ef106bc323c..4a62fbbbdd48ef8274eee91d938312e67a8b871b 100644 (file)
 (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
 
 ;; Vector logical modes
-(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI])
+(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI KF TF])
 
-;; Vector modes for moves.  Don't do TImode here.
-(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI])
+;; Vector modes for moves.  Don't do TImode or TFmode here, since their
+;; moves are handled elsewhere.
+(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI KF])
 
 ;; Vector modes for types that don't need a realignment under VSX
-(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI])
+(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI KF TF])
 
 ;; Vector comparison modes
 (define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF])
 {
   if (can_create_pseudo_p ())
     {
-      if (CONSTANT_P (operands[1])
-         && !easy_vector_constant (operands[1], <MODE>mode))
-       operands[1] = force_const_mem (<MODE>mode, operands[1]);
-
-      else if (!vlogical_operand (operands[0], <MODE>mode)
-              && !vlogical_operand (operands[1], <MODE>mode))
+      if (CONSTANT_P (operands[1]))
+       {
+         if (FLOAT128_VECTOR_P (<MODE>mode))
+           {
+             if (!easy_fp_constant (operands[1], <MODE>mode))
+               operands[1] = force_const_mem (<MODE>mode, operands[1]);
+           }
+         else if (!easy_vector_constant (operands[1], <MODE>mode))
+           operands[1] = force_const_mem (<MODE>mode, operands[1]);
+       }
+
+      if (!vlogical_operand (operands[0], <MODE>mode)
+         && !vlogical_operand (operands[1], <MODE>mode))
        operands[1] = force_reg (<MODE>mode, operands[1]);
     }
   if (!BYTES_BIG_ENDIAN
index b7459a710a5ae90e353ea5fee29acff82d85166e..7f366b8d69a033e9276d146190a42aa668f56b35 100644 (file)
                              V1TI
                              (TI       "VECTOR_MEM_VSX_P (TImode)")])
 
+;; Mode iterator to handle swapping words on little endian for the 128-bit
+;; types that goes in a single vector register.
+(define_mode_iterator VSX_LE_128 [(KF   "FLOAT128_VECTOR_P (KFmode)")
+                                 (TF   "FLOAT128_VECTOR_P (TFmode)")])
+
 ;; Iterator for the 2 32-bit vector types
 (define_mode_iterator VSX_W [V4SF V4SI])
 
 (define_mode_iterator VSX_F [V4SF V2DF])
 
 ;; Iterator for logical types supported by VSX
-(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI])
+;; Note, IFmode won't actually be used since it isn't a VSX type, but it simplifies
+;; the code by using 128-bit iterators for floating point.
+(define_mode_iterator VSX_L [V16QI
+                            V8HI
+                            V4SI
+                            V2DI
+                            V4SF
+                            V2DF
+                            V1TI
+                            TI
+                            (KF        "FLOAT128_VECTOR_P (KFmode)")
+                            (TF        "FLOAT128_VECTOR_P (TFmode)")
+                            (IF        "FLOAT128_VECTOR_P (IFmode)")])
 
 ;; Iterator for memory move.  Handle TImode specially to allow
 ;; it to use gprs as well as vsx registers.
-(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI])
+(define_mode_iterator VSX_M [V16QI
+                            V8HI
+                            V4SI
+                            V2DI
+                            V4SF
+                            V2DF
+                            V1TI
+                            (KF        "FLOAT128_VECTOR_P (KFmode)")
+                            (TF        "FLOAT128_VECTOR_P (TFmode)")])
 
 (define_mode_iterator VSX_M2 [V16QI
                              V8HI
@@ -54,6 +79,8 @@
                              V4SF
                              V2DF
                              V1TI
+                             (KF       "FLOAT128_VECTOR_P (KFmode)")
+                             (TF       "FLOAT128_VECTOR_P (TFmode)")
                              (TI       "TARGET_VSX_TIMODE")])
 
 ;; Map into the appropriate load/store name based on the type
@@ -64,6 +91,8 @@
                        (V2DF  "vd2")
                        (V2DI  "vd2")
                        (DF    "d")
+                       (TF    "vd2")
+                       (KF    "vd2")
                        (V1TI  "vd2")
                        (TI    "vd2")])
 
                         (V2DI  "dp")
                         (DF    "dp")
                         (SF    "sp")
+                        (TF    "dp")
+                        (KF    "dp")
                         (V1TI  "dp")
                         (TI    "dp")])
 
                         (DI    "wi")
                         (DF    "ws")
                         (SF    "ww")
+                        (TF    "wp")
+                        (KF    "wq")
                         (V1TI  "v")
                         (TI    "wt")])
 
                         (DF    "ws")
                         (SF    "ww")
                         (V1TI  "wa")
-                        (TI    "wt")])
+                        (TI    "wt")
+                        (TF    "wp")
+                        (KF    "wq")])
 
 ;; Same size integer type for floating point data
 (define_mode_attr VSi [(V4SF  "v4si")
                         (V2DI  "v")
                         (V2DF  "v")
                         (V1TI  "v")
-                        (DF    "s")])
+                        (DF    "s")
+                        (KF    "v")])
 
 ;; Appropriate type for add ops (and other simple FP ops)
 (define_mode_attr VStype_simple        [(V2DF "vecdouble")
                      (const_int 6) (const_int 7)])))]
   "")
 
+;; Little endian word swapping for 128-bit types that are either scalars or the
+;; special V1TI container class, which it is not appropriate to use vec_select
+;; for the type.
+(define_insn "*vsx_le_permute_<mode>"
+  [(set (match_operand:VSX_LE_128 0 "nonimmediate_operand" "=<VSa>,<VSa>,Z")
+       (rotate:VSX_LE_128
+        (match_operand:VSX_LE_128 1 "input_operand" "<VSa>,Z,<VSa>")
+        (const_int 64)))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX"
+  "@
+   xxpermdi %x0,%x1,%x1,2
+   lxvd2x %x0,%y1
+   stxvd2x %x1,%y0"
+  [(set_attr "length" "4")
+   (set_attr "type" "vecperm,vecload,vecstore")])
+
+(define_insn_and_split "*vsx_le_undo_permute_<mode>"
+  [(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=<VSa>,<VSa>")
+       (rotate:VSX_LE_128
+        (rotate:VSX_LE_128
+         (match_operand:VSX_LE_128 1 "vsx_register_operand" "0,<VSa>")
+         (const_int 64))
+        (const_int 64)))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX"
+  "@
+   #
+   xxlor %x0,%x1"
+  ""
+  [(set (match_dup 0) (match_dup 1))]
+{
+  if (reload_completed && REGNO (operands[0]) == REGNO (operands[1]))
+    {
+      emit_note (NOTE_INSN_DELETED);
+      DONE;
+    }
+}
+  [(set_attr "length" "0,4")
+   (set_attr "type" "vecsimple")])
+
+(define_insn_and_split "*vsx_le_perm_load_<mode>"
+  [(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=<VSa>")
+        (match_operand:VSX_LE_128 1 "memory_operand" "Z"))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX"
+  "#"
+  "!BYTES_BIG_ENDIAN && TARGET_VSX"
+  [(set (match_dup 2)
+       (rotate:VSX_LE_128 (match_dup 1)
+                          (const_int 64)))
+   (set (match_dup 0)
+       (rotate:VSX_LE_128 (match_dup 2)
+                          (const_int 64)))]
+  "
+{
+  operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
+                                       : operands[0];
+}
+  "
+  [(set_attr "type" "vecload")
+   (set_attr "length" "8")])
+
+(define_insn "*vsx_le_perm_store_<mode>"
+  [(set (match_operand:VSX_LE_128 0 "memory_operand" "=Z")
+        (match_operand:VSX_LE_128 1 "vsx_register_operand" "+<VSa>"))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX"
+  "#"
+  [(set_attr "type" "vecstore")
+   (set_attr "length" "12")])
+
+(define_split
+  [(set (match_operand:VSX_LE_128 0 "memory_operand" "")
+        (match_operand:VSX_LE_128 1 "vsx_register_operand" ""))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX && !reload_completed"
+  [(set (match_dup 2)
+       (rotate:VSX_LE_128 (match_dup 1)
+                          (const_int 64)))
+   (set (match_dup 0)
+       (rotate:VSX_LE_128 (match_dup 2)
+                          (const_int 64)))]
+{
+  operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
+                                       : operands[0];
+})
+
+;; The post-reload split requires that we re-permute the source
+;; register in case it is still live.
+(define_split
+  [(set (match_operand:VSX_LE_128 0 "memory_operand" "")
+        (match_operand:VSX_LE_128 1 "vsx_register_operand" ""))]
+  "!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed"
+  [(set (match_dup 1)
+       (rotate:VSX_LE_128 (match_dup 1)
+                          (const_int 64)))
+   (set (match_dup 0)
+       (rotate:VSX_LE_128 (match_dup 1)
+                          (const_int 64)))
+   (set (match_dup 1)
+       (rotate:VSX_LE_128 (match_dup 1)
+                          (const_int 64)))]
+  "")
 
 (define_insn "*vsx_mov<mode>"
   [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?<VSa>,?<VSa>,wQ,?&r,??Y,??r,??r,<VSr>,?<VSa>,*r,v,wZ, v")
index 0ec229ff3818d9c536f7288cc24673f77b4624f9..0bffdc63388a99cc0e9ba81b9a38791c09f3952c 100644 (file)
@@ -3087,12 +3087,13 @@ Any VSX register if the -mvsx option was used or NO_REGS.
 
 When using any of the register constraints (@code{wa}, @code{wd},
 @code{wf}, @code{wg}, @code{wh}, @code{wi}, @code{wj}, @code{wk},
-@code{wl}, @code{wm}, @code{ws}, @code{wt}, @code{wu}, @code{wv},
-@code{ww}, or @code{wy}) that take VSX registers, you must use
-@code{%x<n>} in the template so that the correct register is used.
-Otherwise the register number output in the assembly file will be
-incorrect if an Altivec register is an operand of a VSX instruction
-that expects VSX register numbering.
+@code{wl}, @code{wm}, @code{wp}, @code{wq}, @code{ws}, @code{wt},
+@code{wu}, @code{wv}, @code{ww}, or @code{wy})
+that take VSX registers, you must use @code{%x<n>} in the template so
+that the correct register is used.  Otherwise the register number
+output in the assembly file will be incorrect if an Altivec register
+is an operand of a VSX instruction that expects VSX register
+numbering.
 
 @smallexample
 asm ("xvadddp %x0,%x1,%x2" : "=wa" (v1) : "wa" (v2), "wa" (v3));
@@ -3136,6 +3137,12 @@ VSX register if direct move instructions are enabled, or NO_REGS.
 @item wn
 No register (NO_REGS).
 
+@item wp
+VSX register to use for IEEE 128-bit floating point TFmode, or NO_REGS.
+
+@item wq
+VSX register to use for IEEE 128-bit floating point, or NO_REGS.
+
 @item wr
 General purpose register if 64-bit instructions are enabled or NO_REGS.