This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 7/9] S/390: Get rid of Y constraint in vector.md.


This finally removes the Y constraint from the vector patterns while
folding some of them using a code iterator.

gcc/ChangeLog:

2016-02-29  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* config/s390/subst.md (DSI_VI): New mode iterator.
	("addr_style_op_subst"): Use DSI_VI instead of DSI.
	* config/s390/vector.md ("vec_set<mode>"): Move expander before
	the insn definition.
	("*vec_set<mode>"): Change predicate and add alternative to
	support only either register or const_int operands as element
	selector.
	("*vec_set<mode>_plus"): New pattern to support reg + const_int
	operands.
	("vec_extract<mode>"): New expander.
	("*vec_extract<mode>"): New insn definition supporting reg and
	const_int element selectors.
	("*vec_extract<mode>_plus"): New insn definition supporting
	reg+const_int element selectors.
	("rotl<mode>3", "ashl<mode>3", "ashr<mode>3"): Merge into the
	following expander+insn definition.
	("<vec_shifts_name><mode>3"): New expander.
	("*<vec_shifts_name><mode>3<addr_style_op>"): New insn definition.
---
 gcc/config/s390/subst.md  |  13 ++---
 gcc/config/s390/vector.md | 127 +++++++++++++++++++++++++++-------------------
 2 files changed, 81 insertions(+), 59 deletions(-)

diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 3becf20..8a1b814 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -20,19 +20,20 @@
 ;; <http://www.gnu.org/licenses/>.
 
 (define_code_iterator SUBST [rotate ashift lshiftrt ashiftrt])
+(define_mode_iterator DSI_VI [SI DI V2QI V4QI V8QI V16QI V2HI V4HI V8HI V2SI V4SI V2DI])
 
 ; This expands an register/immediate operand to a register+immediate
 ; operand to draw advantage of the address style operand format
 ; providing a addition for free.
 (define_subst "addr_style_op_subst"
-  [(set (match_operand:DSI 0 "" "")
-        (SUBST:DSI (match_operand:DSI 1 "" "")
-		   (match_operand:SI 2 "" "")))]
+  [(set (match_operand:DSI_VI 0 "" "")
+        (SUBST:DSI_VI (match_operand:DSI_VI 1 "" "")
+		      (match_operand:SI 2 "" "")))]
   ""
   [(set (match_dup 0)
-        (SUBST:DSI (match_dup 1)
-		   (plus:SI (match_operand:SI 2 "register_operand" "a")
-			    (match_operand 3 "const_int_operand"   "n"))))])
+        (SUBST:DSI_VI (match_dup 1)
+		      (plus:SI (match_operand:SI 2 "register_operand" "a")
+			       (match_operand 3 "const_int_operand"   "n"))))])
 
 ; Use this in the insn name.
 (define_subst_attr "addr_style_op"     "addr_style_op_subst" "" "_plus")
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index cc3287c..2b8e9bf 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -307,47 +307,82 @@
 
 ; vec_store_lanes?
 
+; vec_set is supposed to *modify* an existing vector so operand 0 is
+; duplicated as input operand.
+(define_expand "vec_set<mode>"
+  [(set (match_operand:V                    0 "register_operand"              "")
+	(unspec:V [(match_operand:<non_vec> 1 "general_operand"               "")
+		   (match_operand:SI        2 "shift_count_or_setmem_operand" "")
+		   (match_dup 0)]
+		   UNSPEC_VEC_SET))]
+  "TARGET_VX")
+
 ; FIXME: Support also vector mode operands for 1
 ; FIXME: A target memory operand seems to be useful otherwise we end
 ; up with vl vlvgg vst.  Shouldn't the middle-end be able to handle
 ; that itself?
 (define_insn "*vec_set<mode>"
-  [(set (match_operand:V                    0 "register_operand"             "=v, v,v")
-	(unspec:V [(match_operand:<non_vec> 1 "general_operand"               "d,QR,K")
-		   (match_operand:SI        2 "shift_count_or_setmem_operand" "Y, I,I")
-		   (match_operand:V         3 "register_operand"              "0, 0,0")]
+  [(set (match_operand:V                    0 "register_operand"  "=v, v,v")
+	(unspec:V [(match_operand:<non_vec> 1 "general_operand"    "d,QR,K")
+		   (match_operand:SI        2 "nonmemory_operand" "an, I,I")
+		   (match_operand:V         3 "register_operand"   "0, 0,0")]
 		  UNSPEC_VEC_SET))]
-  "TARGET_VX"
+  "TARGET_VX
+   && (!CONST_INT_P (operands[2])
+       || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
   "@
    vlvg<bhfgq>\t%v0,%1,%Y2
    vle<bhfgq>\t%v0,%1,%2
    vlei<bhfgq>\t%v0,%1,%2"
   [(set_attr "op_type" "VRS,VRX,VRI")])
 
-; vec_set is supposed to *modify* an existing vector so operand 0 is
-; duplicated as input operand.
-(define_expand "vec_set<mode>"
-  [(set (match_operand:V                    0 "register_operand"              "")
-	(unspec:V [(match_operand:<non_vec> 1 "general_operand"               "")
-		   (match_operand:SI        2 "shift_count_or_setmem_operand" "")
-		   (match_dup 0)]
-		   UNSPEC_VEC_SET))]
-  "TARGET_VX")
+(define_insn "*vec_set<mode>_plus"
+  [(set (match_operand:V                      0 "register_operand" "=v")
+	(unspec:V [(match_operand:<non_vec>   1 "general_operand"   "d")
+		   (plus:SI (match_operand:SI 2 "register_operand"  "a")
+			    (match_operand:SI 4 "const_int_operand" "n"))
+		   (match_operand:V           3 "register_operand"  "0")]
+		  UNSPEC_VEC_SET))]
+  "TARGET_VX"
+  "vlvg<bhfgq>\t%v0,%1,%4(%2)"
+  [(set_attr "op_type" "VRS")])
+
 
 ; FIXME: Support also vector mode operands for 0
 ; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
 ; This is used via RTL standard name as well as for expanding the builtin
-(define_insn "vec_extract<mode>"
-  [(set (match_operand:<non_vec> 0 "nonimmediate_operand"                        "=d,QR")
-	(unspec:<non_vec> [(match_operand:V  1 "register_operand"                " v, v")
-			   (match_operand:SI 2 "shift_count_or_setmem_operand"   " Y, I")]
+(define_expand "vec_extract<mode>"
+  [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
+	(unspec:<non_vec> [(match_operand:V  1 "register_operand" "")
+			   (match_operand:SI 2 "shift_count_or_setmem_operand" "")]
 			  UNSPEC_VEC_EXTRACT))]
-  "TARGET_VX"
+  "TARGET_VX")
+
+(define_insn "*vec_extract<mode>"
+  [(set (match_operand:<non_vec> 0 "nonimmediate_operand"          "=d,QR")
+	(unspec:<non_vec> [(match_operand:V  1 "register_operand"   "v, v")
+			   (match_operand:SI 2 "nonmemory_operand" "an, I")]
+			  UNSPEC_VEC_EXTRACT))]
+  "TARGET_VX
+   && (!CONST_INT_P (operands[2])
+       || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
   "@
    vlgv<bhfgq>\t%0,%v1,%Y2
    vste<bhfgq>\t%v1,%0,%2"
   [(set_attr "op_type" "VRS,VRX")])
 
+(define_insn "*vec_extract<mode>_plus"
+  [(set (match_operand:<non_vec>                      0 "nonimmediate_operand" "=d,QR")
+	(unspec:<non_vec> [(match_operand:V           1 "register_operand"      "v, v")
+			   (plus:SI (match_operand:SI 2 "nonmemory_operand"     "a, I")
+				    (match_operand:SI 3 "const_int_operand"     "n, I"))]
+			   UNSPEC_VEC_EXTRACT))]
+  "TARGET_VX"
+  "@
+   vlgv<bhfgq>\t%0,%v1,%3(%2)
+   vste<bhfgq>\t%v1,%0,%2"
+  [(set_attr "op_type" "VRS,VRX")])
+
 (define_expand "vec_init<V_HW:mode>"
   [(match_operand:V_HW 0 "register_operand" "")
    (match_operand:V_HW 1 "nonmemory_operand" "")]
@@ -667,17 +702,6 @@
   [(set_attr "op_type" "VRR")])
 
 
-; Vector rotate instructions
-
-; Each vector element rotated by a scalar
-; verllb, verllh, verllf, verllg
-(define_insn "rotl<mode>3"
-  [(set (match_operand:VI            0 "register_operand"             "=v")
-	(rotate:VI (match_operand:VI 1 "register_operand"              "v")
-		   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
-  "TARGET_VX"
-  "verll<bhfgq>\t%v0,%v1,%Y2"
-  [(set_attr "op_type" "VRS")])
 
 ; Each vector element rotated by the corresponding vector element
 ; verllvb, verllvh, verllvf, verllvg
@@ -690,36 +714,33 @@
   [(set_attr "op_type" "VRR")])
 
 
-; Shift each element by scalar value
+; Vector rotate and shift by scalar instructions
 
-; veslb, veslh, veslf, veslg
-(define_insn "ashl<mode>3"
-  [(set (match_operand:VI            0 "register_operand"             "=v")
-	(ashift:VI (match_operand:VI 1 "register_operand"              "v")
-		   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
-  "TARGET_VX"
-  "vesl<bhfgq>\t%v0,%v1,%Y2"
-  [(set_attr "op_type" "VRS")])
+(define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
+(define_code_attr vec_shifts_name [(ashift "ashl")    (ashiftrt "ashr")
+				   (lshiftrt "lshr")  (rotate "rotl")])
+(define_code_attr vec_shifts_mnem [(ashift "vesl")    (ashiftrt "vesra")
+				   (lshiftrt "vesrl") (rotate "verll")])
 
-; vesrab, vesrah, vesraf, vesrag
-(define_insn "ashr<mode>3"
-  [(set (match_operand:VI              0 "register_operand"             "=v")
-	(ashiftrt:VI (match_operand:VI 1 "register_operand"              "v")
-		     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
-  "TARGET_VX"
-  "vesra<bhfgq>\t%v0,%v1,%Y2"
-  [(set_attr "op_type" "VRS")])
+; Each vector element rotated by a scalar
+(define_expand "<vec_shifts_name><mode>3"
+  [(set (match_operand:VI 0 "register_operand" "")
+	(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
+		       (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
+  "TARGET_VX")
 
+; verllb, verllh, verllf, verllg
+; veslb,  veslh,  veslf,  veslg
+; vesrab, vesrah, vesraf, vesrag
 ; vesrlb, vesrlh, vesrlf, vesrlg
-(define_insn "lshr<mode>3"
-  [(set (match_operand:VI              0 "register_operand"             "=v")
-	(lshiftrt:VI (match_operand:VI 1 "register_operand"              "v")
-		     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
+  [(set (match_operand:VI                0 "register_operand"  "=v")
+	(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand"   "v")
+		       (match_operand:SI 2 "nonmemory_operand" "an")))]
   "TARGET_VX"
-  "vesrl<bhfgq>\t%v0,%v1,%Y2"
+  "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
   [(set_attr "op_type" "VRS")])
 
-
 ; Shift each element by corresponding vector element
 
 ; veslvb, veslvh, veslvf, veslvg
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]