public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 7/9] S/390: Get rid of Y constraint in vector.md.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (6 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 2/9] S/390: Use enabled attribute overrides to disable alternatives Andreas Krebbel
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

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

gcc/ChangeLog:

	* config/s390/subst.md (SUBST mode iterator): Add ashiftrt.
	(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  |  15 ++---
 gcc/config/s390/vector.md | 138 +++++++++++++++++++++++++++-------------------
 2 files changed, 89 insertions(+), 64 deletions(-)

diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 1e2b1ba..08704c2 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -19,20 +19,21 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
-(define_code_iterator SUBST [ashift lshiftrt rotate])
+(define_code_iterator SUBST [ashift lshiftrt rotate 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..a1b208c 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -307,44 +307,81 @@
 
 ; 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,v")
+	(unspec:V [(match_operand:<non_vec> 1 "general_operand"   "d,d,QR,K")
+		   (match_operand:SI        2 "nonmemory_operand" "a,n,I,I")
+		   (match_operand:V         3 "register_operand"  "0,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
+   vlvg<bhfgq>\t%v0,%1,0(%2)
+   vlvg<bhfgq>\t%v0,%1,%2
    vle<bhfgq>\t%v0,%1,%2
    vlei<bhfgq>\t%v0,%1,%2"
-  [(set_attr "op_type" "VRS,VRX,VRI")])
+  [(set_attr "op_type" "VRS,VRS,VRX,VRI")])
+
+(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")])
 
-; 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 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")
+
+(define_insn "*vec_extract<mode>"
+  [(set (match_operand:<non_vec> 0 "nonimmediate_operand"         "=d,d,QR")
+	(unspec:<non_vec> [(match_operand:V  1 "register_operand"  "v,v, v")
+			   (match_operand:SI 2 "nonmemory_operand" "a,n, 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,0(%2)
+   vlgv<bhfgq>\t%0,%v1,%2
+   vste<bhfgq>\t%v1,%0,%2"
+  [(set_attr "op_type" "VRS,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,%Y2
+   vlgv<bhfgq>\t%0,%v1,%3(%2)
    vste<bhfgq>\t%v1,%0,%2"
   [(set_attr "op_type" "VRS,VRX")])
 
@@ -667,17 +704,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,35 +716,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")))]
-  "TARGET_VX"
-  "vesrl<bhfgq>\t%v0,%v1,%Y2"
-  [(set_attr "op_type" "VRS")])
-
+(define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
+  [(set (match_operand:VI                0 "register_operand" "=v,v")
+	(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand"  "v,v")
+		       (match_operand:SI 2 "nonmemory_operand" "a,n")))]
+  "TARGET_VX"
+  "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
+  [(set_attr "enabled" "*,<addr_style_op_enabled>")
+   (set_attr "op_type" "VRS")])
 
 ; Shift each element by corresponding vector element
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

With this patch the substitution patterns added earlier are used for
the logical right shift and all the left shift patterns.

	* config/s390/s390.md ("<shift><mode>3"): Change predicate of
	op2 to nonmemory_operand.
	("*<shift>di3_31", "*<shift>di3_31_and"):
	Merge into single pattern definition ...
	("*<shift>di3_31<addr_style_op><masked_op>"): New pattern.
	("*<shift><mode>3", "*<shift><mode>3_and"): Merge into single
	pattern definition ...
	("*<shift><mode>3<addr_style_op><masked_op>"): New pattern.
---
 gcc/config/s390/s390.md | 63 ++++++++++++++++++-------------------------------
 1 file changed, 23 insertions(+), 40 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 9703a30..b4983cd 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8395,60 +8395,43 @@
 (define_expand "<shift><mode>3"
   [(set (match_operand:DSI 0 "register_operand" "")
         (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
-                   (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
+                   (match_operand:SI 2 "nonmemory_operand" "")))]
   ""
   "")
 
+; ESA 64 bit register pair shift with reg or imm shift count
 ; sldl, srdl
-(define_insn "*<shift>di3_31"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
-                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_insn "*<shift>di3_31<addr_style_op><masked_op>"
+  [(set (match_operand:DI 0 "register_operand"           "=d,d")
+        (SHIFT:DI (match_operand:DI 1 "register_operand"  "0,0")
+                  (match_operand:SI 2 "nonmemory_operand" "a,n")))]
   "!TARGET_ZARCH"
-  "s<lr>dl\t%0,%Y2"
+  "@
+   s<lr>dl\t%0,<addr_style_op_op3>(%2)
+   s<lr>dl\t%0,%Y2"
   [(set_attr "op_type"  "RS")
    (set_attr "atype"    "reg")
+   (set_attr "enabled"  "*,<addr_style_op_enabled>")
    (set_attr "z196prop" "z196_cracked")])
 
-; sll, srl, sllg, srlg, sllk, srlk
-(define_insn "*<shift><mode>3"
-  [(set (match_operand:GPR 0 "register_operand"                          "=d,d")
-        (SHIFT:GPR (match_operand:GPR 1 "register_operand"             "<d0>,d")
-                   (match_operand:SI 2 "shift_count_or_setmem_operand"    "Y,Y")))]
-  ""
-  "@
-   s<lr>l<g>\t%0,<1>%Y2
-   s<lr>l<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
-
-; sldl, srdl
-(define_insn "*<shift>di3_31_and"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
-                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			  (match_operand:SI 3 "const_int_operand"   "n"))))]
-  "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "s<lr>dl\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
 
+; 64 bit register shift with reg or imm shift count
 ; sll, srl, sllg, srlg, sllk, srlk
-(define_insn "*<shift><mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand"                                 "=d,d")
-        (SHIFT:GPR (match_operand:GPR 1 "register_operand"                    "<d0>,d")
-                   (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand"   "Y,Y")
-			   (match_operand:SI 3 "const_int_operand"               "n,n"))))]
-  "(INTVAL (operands[3]) & 63) == 63"
+(define_insn "*<shift><mode>3<addr_style_op><masked_op>"
+  [(set (match_operand:GPR 0 "register_operand"              "=d,   d,d,d")
+        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,<d0>,d,d")
+                   (match_operand:SI 2 "nonmemory_operand"    "a,   n,a,n")))]
+  ""
   "@
+   s<lr>l<g>\t%0,<1><addr_style_op_op3>(%2)
    s<lr>l<g>\t%0,<1>%Y2
+   s<lr>l<gk>\t%0,%1,<addr_style_op_op3>(%2)
    s<lr>l<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
+  [(set_attr "op_type"  "RS<E>,RS<E>,RSY,RSY")
+   (set_attr "atype"    "reg,reg,reg,reg")
+   (set_attr "cpu_facility" "*,*,z196,z196")
+   (set_attr "enabled"  "*,<addr_style_op_enabled>,*,<addr_style_op_enabled>")
+   (set_attr "z10prop"  "z10_super_E1,z10_super_E1,*,*")])
 
 ;
 ; ashr(di|si)3 instruction pattern(s).
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 6/9] S/390: Get rid of Y constraint in tabort.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (2 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

This removes the Y constraint from the tabort pattern definition.  In
this case it is easier without using substitutions.

gcc/ChangeLog:

	* config/s390/s390.md ("*tabort_1"): Change predicate to
	nonmemory_operand.  Add a second alternative to cover
	register as well as const int operands.
	("*tabort_1_plus"): New pattern definition.
---
 gcc/config/s390/s390.md | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index a058f58..3ce687c 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -10697,7 +10697,7 @@
 ; Transaction abort
 
 (define_expand "tabort"
-  [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "")]
+  [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
 		    UNSPECV_TABORT)]
   "TARGET_HTM && operands != NULL"
 {
@@ -10712,10 +10712,21 @@
 })
 
 (define_insn "*tabort_1"
-  [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
+  [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "a,J")]
 		    UNSPECV_TABORT)]
   "TARGET_HTM && operands != NULL"
-  "tabort\t%Y0"
+  "@
+   tabort\t0(%0)
+   tabort\t%0"
+  [(set_attr "op_type" "S")])
+
+(define_insn "*tabort_1_plus"
+  [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand"  "a")
+			      (match_operand:SI 1 "const_int_operand" "J"))]
+		    UNSPECV_TABORT)]
+  "TARGET_HTM && operands != NULL
+   && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
+  "tabort\t%1(%0)"
   [(set_attr "op_type" "S")])
 
 ; Transaction extract nesting depth
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (5 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 2/9] S/390: Use enabled attribute overrides to disable alternatives Andreas Krebbel
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

The arithmetic shift patterns set also the condition code.  This adds
more substitution potential.  Depending on whether the actual result
or the CC output will be used 3 different variants of each of these
patterns are needed.  This multiplied with the PLUS and the AND
operands from the earlier substitutions enables a lot of folding.

	* config/s390/s390.md ("*ashrdi3_cc_31")
	("*ashrdi3_cconly_31""*ashrdi3_cc_31_and")
	("*ashrdi3_cconly_31_and", "*ashrdi3_31_and", "*ashrdi3_31"):
	Merge insn definitions into ...
	("*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"):
	New pattern definition.
	("*ashr<mode>3_cc", "*ashr<mode>3_cconly", "ashr<mode>3", )
	("*ashr<mode>3_cc_and", "*ashr<mode>3_cconly_and")
	("*ashr<mode>3_and"): Merge insn definitions into ...
	("*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"):
	New pattern definition.
	* config/s390/subst.md ("addr_style_op_cc_subst")
	("masked_op_cc_subst", "setcc_subst", "cconly_subst"): New
	substitutions patterns plus attributes.
---
 gcc/config/s390/s390.md  | 189 +++++++----------------------------------------
 gcc/config/s390/subst.md |  61 +++++++++++++++
 2 files changed, 88 insertions(+), 162 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index b4983cd..a058f58 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8441,183 +8441,48 @@
   [(parallel
     [(set (match_operand:DSI 0 "register_operand" "")
           (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
-                        (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
+                        (match_operand:SI 2 "nonmemory_operand" "")))
      (clobber (reg:CC CC_REGNUM))])]
   ""
   "")
 
-(define_insn "*ashrdi3_cc_31"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
-                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_cconly_31"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
-                 (const_int 0)))
-   (clobber (match_scratch:DI 0 "=d"))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_31"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
+; FIXME: The number of alternatives is doubled here to match the fix
+; number of 4 in the subst pattern for the (clobber (match_scratch...
+; The right fix should be to support match_scratch in the output
+; pattern of a define_subst.
+(define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
+  [(set (match_operand:DI 0 "register_operand"              "=d,d,d,d")
+        (ashiftrt:DI (match_operand:DI 1 "register_operand"  "0,0,0,0")
+                     (match_operand:SI 2 "nonmemory_operand" "a,n,a,n")))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_ZARCH"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cc"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
-                 (const_int 0)))
-   (set (match_operand:GPR 0 "register_operand"                                   "=d,d")
-        (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
-  "s390_match_ccmode(insn, CCSmode)"
   "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
+   srda\t%0,<addr_style_op_cc_op3>(%2)
+   srda\t%0,%Y2
+   srda\t%0,<addr_style_op_cc_op3>(%2)
+   srda\t%0,%Y2"
+  [(set_attr "op_type" "RS")
+   (set_attr "enabled" "*,<addr_style_op_cc_enabled>,*,<addr_style_op_cc_enabled>")
+   (set_attr "atype"   "reg")])
 
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cconly"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
-                 (const_int 0)))
-   (clobber (match_scratch:GPR 0                                                  "=d,d"))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
 
 ; sra, srag
-(define_insn "*ashr<mode>3"
-  [(set (match_operand:GPR 0 "register_operand"                          "=d,d")
-        (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                      (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
+(define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
+  [(set (match_operand:GPR 0 "register_operand"                 "=d,   d,d,d")
+        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,<d0>,d,d")
+                      (match_operand:SI 2 "nonmemory_operand"    "a,   n,a,n")))
    (clobber (reg:CC CC_REGNUM))]
   ""
   "@
+   sra<g>\t%0,<1><addr_style_op_cc_op3>(%2)
    sra<g>\t%0,<1>%Y2
+   sra<gk>\t%0,%1,<addr_style_op_cc_op3>(%2)
    sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
-
-
-; shift pattern with implicit ANDs
-
-(define_insn "*ashrdi3_cc_31_and"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-				      (match_operand:SI 3 "const_int_operand"   "n")))
-		 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
-   && (INTVAL (operands[3]) & 63) == 63"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_cconly_31_and"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-				      (match_operand:SI 3 "const_int_operand"   "n")))
-                 (const_int 0)))
-   (clobber (match_scratch:DI 0 "=d"))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
-   && (INTVAL (operands[3]) & 63) == 63"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_31_and"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			     (match_operand:SI 3 "const_int_operand"   "n"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cc_and"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"                  "<d0>,d")
-                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
-				       (match_operand:SI 3 "const_int_operand"             "n,n")))
-		 (const_int 0)))
-   (set (match_operand:GPR 0 "register_operand"                                           "=d,d")
-        (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
-  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
-  "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
-
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cconly_and"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"                  "<d0>,d")
-                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
-				       (match_operand:SI 3 "const_int_operand"             "n,n")))
-                 (const_int 0)))
-   (clobber (match_scratch:GPR 0                                                          "=d,d"))]
-  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
-  "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
-
-; sra, srag, srak
-(define_insn "*ashr<mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand"                                  "=d,d")
-        (ashiftrt:GPR (match_operand:GPR 1 "register_operand"                  "<d0>,d")
-                      (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
-			      (match_operand:SI 3 "const_int_operand"             "n,n"))))
-   (clobber (reg:CC CC_REGNUM))]
-  "(INTVAL (operands[3]) & 63) == 63"
-  "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
+  [(set_attr "op_type"  "RS<E>,RS<E>,RSY,RSY")
+   (set_attr "atype"    "reg")
+   (set_attr "cpu_facility" "*,*,z196,z196")
+   (set_attr "enabled" "*,<addr_style_op_cc_enabled>,*,<addr_style_op_cc_enabled>")
+   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 8443c69..1e2b1ba 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -65,3 +65,64 @@
 ; Use this in the insn name.
 (define_subst_attr "masked_op" "masked_op_subst" "" "_and")
 
+
+
+; This is like the addr_style_op substitution above but with a CC clobber.
+(define_subst "addr_style_op_cc_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (ashiftrt:DSI (match_operand:DSI 1 "" "")
+		      (match_operand:SI 2 "" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "REG_P (operands[2])"
+  [(set (match_dup 0)
+        (ashiftrt:DSI (match_dup 1)
+		      (plus:SI (match_dup 2)
+			       (match_operand 3 "const_int_operand" "n"))))
+   (clobber (reg:CC CC_REGNUM))])
+
+(define_subst_attr "addr_style_op_cc"     "addr_style_op_cc_subst" "" "_plus")
+(define_subst_attr "addr_style_op_cc_enabled" "addr_style_op_cc_subst" "*" "0")
+(define_subst_attr "addr_style_op_cc_op3" "addr_style_op_cc_subst" "0" "%Y3")
+
+
+; This is like the masked_op substitution but with a CC clobber.
+(define_subst "masked_op_cc_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (ashiftrt:DSI (match_operand:DSI 1 "" "")
+		      (match_operand:SI  2 "" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  ""
+  [(set (match_dup 0)
+        (ashiftrt:DSI (match_dup 1)
+		      (and:SI (match_dup 2)
+			      (match_operand:SI 3 "const_int_6bitset_operand" ""))))
+   (clobber (reg:CC CC_REGNUM))])
+(define_subst_attr "masked_op_cc" "masked_op_cc_subst" "" "_and")
+
+
+; This adds an explicit CC reg set to an operation while keeping the
+; set for the operation result as well.
+(define_subst "setcc_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (match_operand:DSI 1 "" ""))
+   (clobber (reg:CC CC_REGNUM))]
+  "s390_match_ccmode(insn, CCSmode)"
+  [(set (reg CC_REGNUM)
+	(compare (match_dup 1) (const_int 0)))
+   (set (match_dup 0) (match_dup 1))])
+
+; Use this in the insn name.
+(define_subst_attr "setcc" "setcc_subst" "" "_cc")
+
+; This adds an explicit CC reg set to an operation while dropping the
+; result of the operation.
+(define_subst "cconly_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (match_operand:DSI 1 "" ""))
+   (clobber (reg:CC CC_REGNUM))]
+  "s390_match_ccmode(insn, CCSmode)"
+  [(set (reg CC_REGNUM)
+	(compare (match_dup 1) (const_int 0)))
+   (clobber (match_scratch:DSI 0 "=d,d,d,d"))])
+
+(define_subst_attr "cconly" "cconly_subst" "" "_cconly")
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

After Y is never used anymore with SImode operands we can finally
disallow SImode (if != Pmode) in s390_decompose_address.  In fact that
was the whole point of the patch series.

gcc/ChangeLog:

	* config/s390/s390.c (s390_decompose_address): Don't accept SImode
	anymore.
---
 gcc/config/s390/s390.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 43219dd..8924367 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2817,9 +2817,7 @@ s390_decompose_address (rtx addr, struct s390_address *out)
 	    return false;
 	  }
 
-      if (!REG_P (base)
-	  || (GET_MODE (base) != SImode
-	      && GET_MODE (base) != Pmode))
+      if (!REG_P (base) || GET_MODE (base) != Pmode)
 	return false;
 
       if (REGNO (base) == STACK_POINTER_REGNUM
@@ -2865,9 +2863,7 @@ s390_decompose_address (rtx addr, struct s390_address *out)
 	    return false;
 	  }
 
-      if (!REG_P (indx)
-	  || (GET_MODE (indx) != SImode
-	      && GET_MODE (indx) != Pmode))
+      if (!REG_P (indx) || GET_MODE (indx) != Pmode)
 	return false;
 
       if (REGNO (indx) == STACK_POINTER_REGNUM
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/9] S/390: Use enabled attribute overrides to disable alternatives.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (7 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

So far whenever we wanted to disable an alternative we have used mode
attributes emitting constraints matching an earlier alternative
assuming that due to this the later alternative will never be chosen.

With this patch the `enabled' attribute, which so far is only set from
`cpu_facility', is overridden to 0 to disable certain alternatives.
This comes handy when defining the substitutions later and while
adding it anyway I've used it for the existing cases as well.

gcc/ChangeLog:

	* config/s390/s390.md ("op_type", "atype", "length" attributes):
	Remove RRR type.  It doesn't really exist.
	("RRer", "f0", "v0", "vf", "vd", "op1", "Rf"): Remove mode
	attributes.
	("BFP", "DFP", "nDSF", "nDFDI"): Add mode attributes.
	("*cmp<mode>_ccs", "floatdi<mode>2", "add<mode>3")
	("*add<mode>3_cc", "*add<mode>3_cconly", "sub<mode>3")
	("*sub<mode>3_cc", "*sub<mode>3_cconly", "mul<mode>3")
	("fma<mode>4", "fms<mode>4", "div<mode>3", "*neg<mode>2")
	("*abs<mode>2", "*negabs<mode>2", "sqrt<mode>2"): Override
	`enabled' attribute.
---
 gcc/config/s390/s390.md | 215 +++++++++++++++++++++++++-----------------------
 1 file changed, 111 insertions(+), 104 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 2c90eae..b878ec2 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -366,7 +366,7 @@
 ;; Used to determine defaults for length and other attribute values.
 
 (define_attr "op_type"
-  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX"
+  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX"
   (const_string "NN"))
 
 ;; Instruction type attribute used for scheduling.
@@ -393,7 +393,7 @@
 ;;   reg: Instruction does not use the agen unit
 
 (define_attr "atype" "agen,reg"
-  (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF,RRR")
+  (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
 		(const_string "reg")
 		(const_string "agen")))
 
@@ -434,8 +434,8 @@
 ;; Length in bytes.
 
 (define_attr "length" ""
-  (cond [(eq_attr "op_type" "E,RR")		              (const_int 2)
-         (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR")  (const_int 4)]
+  (cond [(eq_attr "op_type" "E,RR")		          (const_int 2)
+         (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF")  (const_int 4)]
     (const_int 6)))
 
 
@@ -618,27 +618,14 @@
 ;; fp register operands.  The following attributes allow to merge the bfp and
 ;; dfp variants in a single insn definition.
 
-;; This attribute is used to set op_type accordingly.
-(define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
-                        (DD "RRR") (SD "RRR")])
-
-;; This attribute is used in the operand constraint list in order to have the
-;; first and the second operand match for bfp modes.
-(define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
-
-;; This attribute is used to merge the scalar vector instructions into
-;; the FP patterns.  For non-supported modes (all but DF) it expands
-;; to constraints which are supposed to be matched by an earlier
-;; variant.
-(define_mode_attr v0      [(TF "0") (DF "v") (SF "0") (TD "0") (DD "0") (DD "0") (TI "0") (DI "v") (SI "0")])
-(define_mode_attr vf      [(TF "f") (DF "v") (SF "f") (TD "f") (DD "f") (DD "f") (TI "f") (DI "v") (SI "f")])
-(define_mode_attr vd      [(TF "d") (DF "v") (SF "d") (TD "d") (DD "d") (DD "d") (TI "d") (DI "v") (SI "d")])
-
-;; This attribute is used in the operand list of the instruction to have an
-;; additional operand for the dfp instructions.
-(define_mode_attr op1 [(TF "") (DF "") (SF "")
-                       (TD "%1,") (DD "%1,") (SD "%1,")])
-
+;; These mode attributes are supposed to be used in the `enabled' insn
+;; attribute to disable certain alternatives for certain modes.
+(define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
+(define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
+(define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
+(define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
+			(TD "0") (DD "0") (DD "0")
+			(TI "0") (DI "*") (SI "0")])
 
 ;; This attribute is used in the operand constraint list
 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
@@ -648,10 +635,6 @@
 ;; target operand uses the same fp register.
 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
 
-;; In FP 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") (TD "f") (DD "f") (SD "f")])
-
 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
 ;; within instruction mnemonics.
 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
@@ -1260,13 +1243,14 @@
 (define_insn "*cmp<mode>_ccs"
   [(set (reg CC_REGNUM)
         (compare (match_operand:FP 0 "register_operand" "f,f")
-                 (match_operand:FP 1 "general_operand"  "f,<Rf>")))]
+                 (match_operand:FP 1 "general_operand"  "f,R")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
   "@
    c<xde><bt>r\t%0,%1
    c<xde>b\t%0,%1"
    [(set_attr "op_type" "RRE,RXE")
-    (set_attr "type"  "fsimp<mode>")])
+    (set_attr "type"  "fsimp<mode>")
+    (set_attr "enabled" "*,<DSF>")])
 
 ; wfcedbs, wfchdbs, wfchedbs
 (define_insn "*vec_cmp<insn_cmp>df_cconly"
@@ -4715,15 +4699,16 @@
 
 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
 (define_insn "floatdi<mode>2"
-  [(set (match_operand:FP           0 "register_operand" "=f,<vf>")
-        (float:FP (match_operand:DI 1 "register_operand"  "d,<vd>")))]
+  [(set (match_operand:FP           0 "register_operand" "=f,v")
+        (float:FP (match_operand:DI 1 "register_operand"  "d,v")))]
   "TARGET_ZARCH && TARGET_HARD_FLOAT"
   "@
    c<xde>g<bt>r\t%0,%1
    wcdgb\t%v0,%v1,0,0"
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "type"         "itof<mode>" )
-   (set_attr "cpu_facility" "*,vec")])
+   (set_attr "cpu_facility" "*,vec")
+   (set_attr "enabled"      "*,<DFDI>")])
 
 ; cxfbr, cdfbr, cefbr
 (define_insn "floatsi<mode>2"
@@ -5482,47 +5467,53 @@
 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
 ; FIXME: wfadb does not clobber cc
 (define_insn "add<mode>3"
-  [(set (match_operand:FP 0 "register_operand"                 "=f,   f,<vf>")
-        (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,   0,<v0>")
-		 (match_operand:FP 2 "general_operand"          "f,<Rf>,<vf>")))
+  [(set (match_operand:FP 0 "register_operand"              "=f,f,f,v")
+        (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
+		 (match_operand:FP 2 "general_operand"       "f,f,R,v")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT"
   "@
-   a<xde><bt>r\t%0,<op1>%2
+   a<xde>tr\t%0,%1,%2
+   a<xde>br\t%0,%2
    a<xde>b\t%0,%2
    wfadb\t%v0,%v1,%v2"
-  [(set_attr "op_type"      "<RRer>,RXE,VRR")
+  [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fsimp<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
 (define_insn "*add<mode>3_cc"
   [(set (reg CC_REGNUM)
-	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
-			  (match_operand:FP 2 "general_operand"      " f,<Rf>"))
+	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
+			  (match_operand:FP 2 "general_operand"       "f,f,R"))
 		 (match_operand:FP 3 "const0_operand" "")))
-   (set (match_operand:FP 0 "register_operand" "=f,f")
+   (set (match_operand:FP 0 "register_operand" "=f,f,f")
 	(plus:FP (match_dup 1) (match_dup 2)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
   "@
-   a<xde><bt>r\t%0,<op1>%2
+   a<xde>tr\t%0,%1,%2
+   a<xde>br\t%0,%2
    a<xde>b\t%0,%2"
-  [(set_attr "op_type"  "<RRer>,RXE")
-   (set_attr "type"     "fsimp<mode>")])
+  [(set_attr "op_type"  "RRF,RRE,RXE")
+   (set_attr "type"     "fsimp<mode>")
+   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
 
 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
 (define_insn "*add<mode>3_cconly"
   [(set (reg CC_REGNUM)
-	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
-			   (match_operand:FP 2 "general_operand"      " f,<Rf>"))
+	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
+			  (match_operand:FP 2 "general_operand"       "f,f,R"))
 		 (match_operand:FP 3 "const0_operand" "")))
-   (clobber (match_scratch:FP 0 "=f,f"))]
+   (clobber (match_scratch:FP 0 "=f,f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
   "@
-   a<xde><bt>r\t%0,<op1>%2
+   a<xde>tr\t%0,%1,%2
+   a<xde>br\t%0,%2
    a<xde>b\t%0,%2"
-  [(set_attr "op_type"  "<RRer>,RXE")
-   (set_attr "type"     "fsimp<mode>")])
+  [(set_attr "op_type"  "RRF,RRE,RXE")
+   (set_attr "type"     "fsimp<mode>")
+   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
 
 ;
 ; Pointer add instruction patterns
@@ -5906,47 +5897,53 @@
 
 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
 (define_insn "sub<mode>3"
-  [(set (match_operand:FP           0 "register_operand"   "=f,   f,<vf>")
-        (minus:FP (match_operand:FP 1 "register_operand" "<f0>,   0,<v0>")
-                  (match_operand:FP 2 "general_operand"     "f,<Rf>,<vf>")))
+  [(set (match_operand:FP           0 "register_operand" "=f,f,f,v")
+        (minus:FP (match_operand:FP 1 "register_operand"  "f,0,0,v")
+                  (match_operand:FP 2 "general_operand"   "f,f,R,v")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT"
   "@
-   s<xde><bt>r\t%0,<op1>%2
+   s<xde>tr\t%0,%1,%2
+   s<xde>br\t%0,%2
    s<xde>b\t%0,%2
    wfsdb\t%v0,%v1,%v2"
-  [(set_attr "op_type"      "<RRer>,RXE,VRR")
+  [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fsimp<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
 (define_insn "*sub<mode>3_cc"
   [(set (reg CC_REGNUM)
-	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
-                           (match_operand:FP 2 "general_operand"      "f,<Rf>"))
+	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
+                           (match_operand:FP 2 "general_operand"      "f,f,R"))
 		 (match_operand:FP 3 "const0_operand" "")))
-   (set (match_operand:FP 0 "register_operand" "=f,f")
+   (set (match_operand:FP 0 "register_operand" "=f,f,f")
 	(minus:FP (match_dup 1) (match_dup 2)))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
   "@
-   s<xde><bt>r\t%0,<op1>%2
+   s<xde>tr\t%0,%1,%2
+   s<xde>br\t%0,%2
    s<xde>b\t%0,%2"
-  [(set_attr "op_type"  "<RRer>,RXE")
-   (set_attr "type"     "fsimp<mode>")])
+  [(set_attr "op_type"  "RRF,RRE,RXE")
+   (set_attr "type"     "fsimp<mode>")
+   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
 
 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
 (define_insn "*sub<mode>3_cconly"
   [(set (reg CC_REGNUM)
-	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
-			   (match_operand:FP 2 "general_operand"      "f,<Rf>"))
+	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
+			   (match_operand:FP 2 "general_operand"      "f,f,R"))
 		 (match_operand:FP 3 "const0_operand" "")))
-   (clobber (match_scratch:FP 0 "=f,f"))]
+   (clobber (match_scratch:FP 0 "=f,f,f"))]
   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
   "@
-   s<xde><bt>r\t%0,<op1>%2
+   s<xde>tr\t%0,%1,%2
+   s<xde>br\t%0,%2
    s<xde>b\t%0,%2"
-  [(set_attr "op_type"  "<RRer>,RXE")
-   (set_attr "type"     "fsimp<mode>")])
+  [(set_attr "op_type"  "RRF,RRE,RXE")
+   (set_attr "type"     "fsimp<mode>")
+   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
 
 
 ;;
@@ -6328,24 +6325,26 @@
 
 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
 (define_insn "mul<mode>3"
-  [(set (match_operand:FP          0 "register_operand"        "=f,   f,<vf>")
-        (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,   0,<v0>")
-                 (match_operand:FP 2 "general_operand"          "f,<Rf>,<vf>")))]
+  [(set (match_operand:FP          0 "register_operand"     "=f,f,f,v")
+        (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
+                 (match_operand:FP 2 "general_operand"       "f,f,R,v")))]
   "TARGET_HARD_FLOAT"
   "@
-   m<xdee><bt>r\t%0,<op1>%2
+   m<xdee>tr\t%0,%1,%2
+   m<xdee>br\t%0,%2
    m<xdee>b\t%0,%2
    wfmdb\t%v0,%v1,%v2"
-  [(set_attr "op_type"      "<RRer>,RXE,VRR")
+  [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fmul<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 ; madbr, maebr, maxb, madb, maeb
 (define_insn "fma<mode>4"
-  [(set (match_operand:DSF          0 "register_operand"     "=f,f,<vf>")
-	(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
-		 (match_operand:DSF 2 "nonimmediate_operand"  "f,R,<vf>")
-		 (match_operand:DSF 3 "register_operand"      "0,0,<v0>")))]
+  [(set (match_operand:DSF          0 "register_operand"     "=f,f,v")
+	(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
+		 (match_operand:DSF 2 "nonimmediate_operand"  "f,R,v")
+		 (match_operand:DSF 3 "register_operand"      "0,0,v")))]
   "TARGET_HARD_FLOAT"
   "@
    ma<xde>br\t%0,%1,%2
@@ -6353,14 +6352,15 @@
    wfmadb\t%v0,%v1,%v2,%v3"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fmadd<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "enabled"      "*,*,<DFDI>")])
 
 ; msxbr, msdbr, msebr, msxb, msdb, mseb
 (define_insn "fms<mode>4"
-  [(set (match_operand:DSF                   0 "register_operand"     "=f,f,<vf>")
-	(fma:DSF (match_operand:DSF          1 "nonimmediate_operand" "%f,f,<vf>")
-		 (match_operand:DSF          2 "nonimmediate_operand"  "f,R,<vf>")
-		 (neg:DSF (match_operand:DSF 3 "register_operand"      "0,0,<v0>"))))]
+  [(set (match_operand:DSF                   0 "register_operand"     "=f,f,v")
+	(fma:DSF (match_operand:DSF          1 "nonimmediate_operand" "%f,f,v")
+		 (match_operand:DSF          2 "nonimmediate_operand"  "f,R,v")
+		 (neg:DSF (match_operand:DSF 3 "register_operand"      "0,0,v"))))]
   "TARGET_HARD_FLOAT"
   "@
    ms<xde>br\t%0,%1,%2
@@ -6368,7 +6368,8 @@
    wfmsdb\t%v0,%v1,%v2,%v3"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fmadd<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "enabled"      "*,*,<DFDI>")])
 
 ;;
 ;;- Divide and modulo instructions.
@@ -6794,17 +6795,19 @@
 
 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
 (define_insn "div<mode>3"
-  [(set (match_operand:FP         0 "register_operand"   "=f,   f,<vf>")
-        (div:FP (match_operand:FP 1 "register_operand" "<f0>,   0,<v0>")
-		(match_operand:FP 2 "general_operand"     "f,<Rf>,<vf>")))]
+  [(set (match_operand:FP         0 "register_operand" "=f,f,f,v")
+        (div:FP (match_operand:FP 1 "register_operand"  "f,0,0,v")
+		(match_operand:FP 2 "general_operand"   "f,f,R,v")))]
   "TARGET_HARD_FLOAT"
   "@
-   d<xde><bt>r\t%0,<op1>%2
+   d<xde>tr\t%0,%1,%2
+   d<xde>br\t%0,%2
    d<xde>b\t%0,%2
    wfddb\t%v0,%v1,%v2"
-  [(set_attr "op_type"      "<RRer>,RXE,VRR")
+  [(set_attr "op_type"      "RRF,RRE,RXE,VRR")
    (set_attr "type"         "fdiv<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,*,vec")
+   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
 
 
 ;;
@@ -8015,8 +8018,8 @@
 ; lcxbr, lcdbr, lcebr
 ; FIXME: wflcdb does not clobber cc
 (define_insn "*neg<mode>2"
-  [(set (match_operand:BFP          0 "register_operand" "=f,<vf>")
-        (neg:BFP (match_operand:BFP 1 "register_operand"  "f,<vf>")))
+  [(set (match_operand:BFP          0 "register_operand" "=f,v")
+        (neg:BFP (match_operand:BFP 1 "register_operand"  "f,v")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT"
   "@
@@ -8024,7 +8027,8 @@
    wflcdb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "cpu_facility" "*,vec")
-   (set_attr "type"         "fsimp<mode>,*")])
+   (set_attr "type"         "fsimp<mode>,*")
+   (set_attr "enabled"      "*,<DFDI>")])
 
 
 ;;
@@ -8137,8 +8141,8 @@
 ; lpxbr, lpdbr, lpebr
 ; FIXME: wflpdb does not clobber cc
 (define_insn "*abs<mode>2"
-  [(set (match_operand:BFP          0 "register_operand" "=f,<vf>")
-        (abs:BFP (match_operand:BFP 1 "register_operand"  "f,<vf>")))
+  [(set (match_operand:BFP          0 "register_operand" "=f,v")
+        (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT"
   "@
@@ -8146,7 +8150,8 @@
     wflpdb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "cpu_facility" "*,vec")
-   (set_attr "type"         "fsimp<mode>,*")])
+   (set_attr "type"         "fsimp<mode>,*")
+   (set_attr "enabled"      "*,<DFDI>")])
 
 
 ;;
@@ -8252,8 +8257,8 @@
 ; lnxbr, lndbr, lnebr
 ; FIXME: wflndb does not clobber cc
 (define_insn "*negabs<mode>2"
-  [(set (match_operand:BFP                   0 "register_operand" "=f,<vf>")
-        (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand"  "f,<vf>"))))
+  [(set (match_operand:BFP                   0 "register_operand" "=f,v")
+        (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_HARD_FLOAT"
   "@
@@ -8261,7 +8266,8 @@
    wflndb\t%0,%1"
   [(set_attr "op_type"      "RRE,VRR")
    (set_attr "cpu_facility" "*,vec")
-   (set_attr "type"         "fsimp<mode>,*")])
+   (set_attr "type"         "fsimp<mode>,*")
+   (set_attr "enabled"      "*,<DFDI>")])
 
 ;;
 ;;- Square root instructions.
@@ -8273,8 +8279,8 @@
 
 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
 (define_insn "sqrt<mode>2"
-  [(set (match_operand:BFP           0 "register_operand" "=f,   f,<vf>")
-	(sqrt:BFP (match_operand:BFP 1 "general_operand"   "f,<Rf>,<vf>")))]
+  [(set (match_operand:BFP           0 "register_operand" "=f,f,v")
+	(sqrt:BFP (match_operand:BFP 1 "general_operand"   "f,R,v")))]
   "TARGET_HARD_FLOAT"
   "@
    sq<xde>br\t%0,%1
@@ -8282,7 +8288,8 @@
    wfsqdb\t%v0,%v1"
   [(set_attr "op_type"      "RRE,RXE,VRR")
    (set_attr "type"         "fsqrt<mode>")
-   (set_attr "cpu_facility" "*,*,vec")])
+   (set_attr "cpu_facility" "*,*,vec")
+   (set_attr "enabled"      "*,<DSF>,<DFDI>")])
 
 
 ;;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/9] gensupport: Fix define_subst operand renumbering.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

When processing substitutions the operands are renumbered.  To find a
free operand number the array used_operands_numbers is used.
Currently this array is used to assign new numbers before all the
RTXes in the vector have been processed.  I did run into problems with
this for insns where a match_dup occurred in a later (use ...) operand
referring to an earlier operand (e.g. s390.md "setmem_long").

The patch splits the loop doing the processing into two in order to
have all the operand numbers collected already when assigning new
numbers.

Bootstrapped and regtested on s390, s390x, and x86_64.

Ok for mainline?

Bye,

-Andreas-

gcc/ChangeLog:

	* gensupport.c (process_substs_on_one_elem): Split loop to
	complete mark_operands_used_in_match_dup on all expressions in the
	vector first.
	(adjust_operands_numbers): Inline into process_substs_on_one_elem
	and remove function.
---
 gcc/gensupport.c | 45 ++++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 8c5a1ab..de29579 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -126,7 +126,10 @@ static const char * duplicate_each_alternative (const char * str, int n_dup);
 
 typedef const char * (*constraints_handler_t) (const char *, int);
 static rtx alter_constraints (rtx, int, constraints_handler_t);
-static rtx adjust_operands_numbers (rtx);
+
+static void mark_operands_used_in_match_dup (rtx);
+static void renumerate_operands_in_pattern (rtx);
+
 static rtx replace_duplicating_operands_in_pattern (rtx);
 \f
 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
@@ -1844,7 +1847,18 @@ process_substs_on_one_elem (struct queue_elem *elem,
 	  subst_pattern = alter_constraints (subst_pattern, alternatives,
 					     duplicate_each_alternative);
 
-	  subst_pattern = adjust_operands_numbers (subst_pattern);
+	  mark_operands_used_in_match_dup (subst_pattern);
+	  RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
+	}
+
+      for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
+	{
+	  subst_pattern = RTVEC_ELT (subst_pattern_vec, j);
+
+	  /* The number of MATCH_OPERANDs in the output pattern might
+	     change.  This routine assigns new numbers to the
+	     MATCH_OPERAND expressions to avoid collisions.  */
+	  renumerate_operands_in_pattern (subst_pattern);
 
 	  /* Substitute match_dup and match_op_dup in the new pattern and
 	     duplicate constraints.  */
@@ -1857,7 +1871,6 @@ process_substs_on_one_elem (struct queue_elem *elem,
 	  if (GET_CODE (elem->data) == DEFINE_EXPAND)
 	    remove_constraints (subst_pattern);
 
-	  RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
 	}
       XVEC (elem->data, 1) = subst_pattern_vec;
 
@@ -1927,7 +1940,7 @@ mark_operands_from_match_dup (rtx pattern)
     }
 }
 
-/* This is a subroutine of adjust_operands_numbers.
+/* This is a subroutine of process_substs_on_one_elem.
    It goes through all expressions in PATTERN and when MATCH_DUP is
    met, all MATCH_OPERANDs inside it is marked as occupied.  The
    process of marking is done by routin mark_operands_from_match_dup.  */
@@ -1973,10 +1986,9 @@ find_first_unused_number_of_operand ()
   return MAX_OPERANDS;
 }
 
-/* This is subroutine of adjust_operands_numbers.
-   It visits all expressions in PATTERN and assigns not-occupied
-   operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
-   PATTERN.  */
+/* This is a subroutine of process_substs_on_one_elem.  It visits all
+   expressions in PATTERN and assigns not-occupied operand indexes to
+   MATCH_OPERANDs and MATCH_OPERATORs of this PATTERN.  */
 static void
 renumerate_operands_in_pattern (rtx pattern)
 {
@@ -2011,23 +2023,6 @@ renumerate_operands_in_pattern (rtx pattern)
     }
 }
 
-/* If output pattern of define_subst contains MATCH_DUP, then this
-   expression would be replaced with the pattern, matched with
-   MATCH_OPERAND from input pattern.  This pattern could contain any
-   number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
-   that a MATCH_OPERAND from output_pattern (if any) would have the
-   same number, as MATCH_OPERAND from copied pattern.  To avoid such
-   indexes overlapping, we assign new indexes to MATCH_OPERANDs,
-   laying in the output pattern outside of MATCH_DUPs.  */
-static rtx
-adjust_operands_numbers (rtx pattern)
-{
-  mark_operands_used_in_match_dup (pattern);
-
-  renumerate_operands_in_pattern (pattern);
-
-  return pattern;
-}
 
 /* Generate RTL expression
    (match_dup OPNO)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 8/9] S/390: Use define_subst for the setmem patterns.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (3 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

While trying to get rid of the Y constraint in the setmem patterns I
noticed that for these patterns it isn't even a problem since these
always only use the constraint with a Pmode match_operand.  But while
being at it I've tried to fold some of the patterns a bit.

gcc/ChangeLog:

	* config/s390/predicates.md ("const_int_8bitset_operand"): New predicate.
	* config/s390/s390.md ("*setmem_long", "*setmem_long_and"): Merge
	into ...
	("*setmem_long<setmem_and>"): New pattern.
	("*setmem_long_31z", "*setmem_long_and_31z"): Merge
	into ...
	("*setmem_long_31z<setmem_and>"): New pattern.
	* config/s390/subst.md ("setmem_31z_subst", "setmem_and_subst"):
	New substitution rules with the required attributes.
---
 gcc/config/s390/predicates.md |  6 ++++++
 gcc/config/s390/s390.md       | 35 ++---------------------------------
 gcc/config/s390/subst.md      | 25 +++++++++++++++++++++++++
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 9e91b5c..9585b1f 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -119,6 +119,12 @@
 (define_predicate "const_int_6bitset_operand"
  (and (match_code "const_int")
       (match_test "(INTVAL (op) & 63) == 63")))
+
+; An integer operand with the lowest order 8 bit all ones.
+(define_predicate "const_int_8bitset_operand"
+ (and (match_code "const_int")
+      (match_test "(INTVAL (op) & 255) == 255")))
+
 (define_predicate "nonzero_shift_count_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3ce687c..49784b3 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3323,7 +3323,7 @@
 
 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
 
-(define_insn "*setmem_long"
+(define_insn "*setmem_long<setmem_and>"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
         (unspec:BLK [(match_operand:P 2 "shift_count_or_setmem_operand" "Y")
@@ -3336,26 +3336,10 @@
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
-(define_insn "*setmem_long_and"
-  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
-   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (unspec:BLK [(and:P
-		      (match_operand:P 2 "shift_count_or_setmem_operand" "Y")
-		      (match_operand:P 4 "const_int_operand"             "n"))
-		    (subreg:P (match_dup 3) <modesize>)]
-		    UNSPEC_REPLICATE_BYTE))
-   (use (match_operand:<DBL> 1 "register_operand" "d"))
-   (clobber (reg:CC CC_REGNUM))]
-  "(TARGET_64BIT || !TARGET_ZARCH) &&
-   (INTVAL (operands[4]) & 255) == 255"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(set_attr "length" "8")
-   (set_attr "type" "vs")])
-
 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
 ; of the SImode subregs.
 
-(define_insn "*setmem_long_31z"
+(define_insn "*setmem_long_31z<setmem_and>"
   [(clobber (match_operand:TI 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
         (unspec:BLK [(match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
@@ -3367,21 +3351,6 @@
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
-(define_insn "*setmem_long_and_31z"
-  [(clobber (match_operand:TI 0 "register_operand" "=d"))
-   (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
-        (unspec:BLK [(and:SI
-		      (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-		      (match_operand:SI 4 "const_int_operand"             "n"))
-		    (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
-   (use (match_operand:TI 1 "register_operand" "d"))
-   (clobber (reg:CC CC_REGNUM))]
-  "(!TARGET_64BIT && TARGET_ZARCH) &&
-   (INTVAL (operands[4]) & 255) == 255"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(set_attr "length" "8")
-   (set_attr "type" "vs")])
-
 ;
 ; cmpmemM instruction pattern(s).
 ;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 08704c2..f03e678 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -127,3 +127,28 @@
    (clobber (match_scratch:DSI 0 "=d,d,d,d"))])
 
 (define_subst_attr "cconly" "cconly_subst" "" "_cconly")
+
+
+;; setmem substitution patterns
+
+; Add an AND operation on the padding byte operand.  Only the lowest 8
+; bit are used and the rest is ignored.
+(define_subst "setmem_and_subst"
+  [(clobber (match_operand:TDI                  0 "register_operand" ""))
+   (set (mem:BLK (subreg:DSI (match_operand:TDI 1 "register_operand" "") 0))
+        (unspec:BLK [(match_operand:DSI         2 "shift_count_or_setmem_operand" "")
+		     (match_operand:DSI         3 "register_operand" "")]
+		     UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:TDI                      4 "register_operand" ""))
+   (clobber (reg:CC CC_REGNUM))]
+""
+  [(clobber (match_dup 0))
+   (set (mem:BLK (subreg:DSI (match_dup 1) 0))
+	(unspec:BLK [(and:DSI (match_dup 2)
+			      (match_operand:DSI 5 "const_int_8bitset_operand" ""))
+		     (match_dup 3)]
+		    UNSPEC_REPLICATE_BYTE))
+   (use (match_dup 4))
+   (clobber (reg:CC CC_REGNUM))])
+
+(define_subst_attr "setmem_and"      "setmem_and_subst" "" "_and")
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
                   ` (4 preceding siblings ...)
  2016-02-23 14:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-25 17:14   ` Ulrich Weigand
  2016-02-23 14:33 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

This patch introduces substitution patterns to add PLUS const_int, and
AND operands to patterns and uses this to rewrite the existing rotate
pattern.

gcc/ChangeLog:

	* config/s390/predicates.md (const_int_6bitset_operand): New
        predicates.
	* config/s390/s390.md: Include subst.md.
	("rotl<mode>3"): New expander.
	("rotl<mode>3", "*rotl<mode>3_and"): Merge insn definitions into
	...
	("*rotl<mode>3<addr_style_op><masked_op>"): New insn definition.
	* config/s390/subst.md: New file.
---
 gcc/config/s390/predicates.md |  4 +++
 gcc/config/s390/s390.c        | 23 +++++++++++----
 gcc/config/s390/s390.md       | 34 +++++++++++-----------
 gcc/config/s390/subst.md      | 67 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+), 23 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index cbc8092..9e91b5c 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -115,6 +115,10 @@
   return true;
 })
 
+; An integer operand with the lowest order 6 bit all ones.
+(define_predicate "const_int_6bitset_operand"
+ (and (match_code "const_int")
+      (match_test "(INTVAL (op) & 63) == 63")))
 (define_predicate "nonzero_shift_count_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index cd53b15..43219dd 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2994,18 +2994,18 @@ s390_decompose_address (rtx addr, struct s390_address *out)
 bool
 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
 {
-  HOST_WIDE_INT off = 0;
+  rtx off = NULL_RTX;
 
   /* We can have an integer constant, an address register,
      or a sum of the two.  */
-  if (GET_CODE (op) == CONST_INT)
+  if (CONST_SCALAR_INT_P (op))
     {
-      off = INTVAL (op);
+      off = op;
       op = NULL_RTX;
     }
-  if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+  if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
     {
-      off = INTVAL (XEXP (op, 1));
+      off = XEXP (op, 1);
       op = XEXP (op, 0);
     }
   while (op && GET_CODE (op) == SUBREG)
@@ -3015,7 +3015,18 @@ s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
     return false;
 
   if (offset)
-    *offset = off;
+    {
+      if (off == NULL_RTX)
+	*offset = 0;
+      else if (CONST_INT_P (off))
+	*offset = INTVAL (off);
+      else if (CONST_WIDE_INT_P (off))
+	/* The offset will anyway be cut down to 12 bits so take just
+	   the lowest order chunk of the wide int.  */
+	*offset = CONST_WIDE_INT_ELT (off, 0);
+      else
+	gcc_unreachable ();
+    }
   if (base)
     *base = op;
 
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index b878ec2..9703a30 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -741,6 +741,8 @@
 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
 
+;; Subst pattern definitions
+(include "subst.md")
 
 (include "vector.md")
 
@@ -8360,28 +8362,26 @@
 ; rotl(di|si)3 instruction pattern(s).
 ;
 
-; rll, rllg
-(define_insn "rotl<mode>3"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_expand "rotl<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "")
+        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
+		    (match_operand:SI 2 "nonmemory_operand" "")))]
   "TARGET_CPU_ZARCH"
-  "rll<g>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RSE")
-   (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+  "")
 
 ; rll, rllg
-(define_insn "*rotl<mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			    (match_operand:SI 3 "const_int_operand"   "n"))))]
-  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "rll<g>\t%0,%1,%Y2"
+(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
+  [(set (match_operand:GPR             0 "register_operand" "=d,d")
+	(rotate:GPR (match_operand:GPR 1 "register_operand"  "d,d")
+		    (match_operand:SI  2 "nonmemory_operand" "a,n")))]
+  "TARGET_CPU_ZARCH"
+  "@
+   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
+   rll<g>\t%0,%1,%Y2"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+   (set_attr "enabled"  "*,<addr_style_op_enabled>")
+   (set_attr "z10prop"  "z10_super_E1")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
new file mode 100644
index 0000000..8443c69
--- /dev/null
+++ b/gcc/config/s390/subst.md
@@ -0,0 +1,67 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;;  Subst patterns.
+;;  Copyright (C) 2016 Free Software Foundation, Inc.
+;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 3, or (at your option) any later
+;; version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_code_iterator SUBST [ashift lshiftrt rotate])
+
+; 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_dup 0)
+        (SUBST:DSI (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")
+
+; In the subst pattern the additional const int operand will be used
+; as displacement.  In the normal version the displacements stays just
+; 0.
+(define_subst_attr "addr_style_op_op3" "addr_style_op_subst" "0" "%Y3")
+
+; The constraints for the second alternative are ok.  However, the
+; output template is not.  We simply disable the alternative.
+; Alternatively we could also adjust the output template with a
+; subst_attr.
+(define_subst_attr "addr_style_op_enabled" "addr_style_op_subst" "*" "0")
+
+
+; This substitution adds an explicit AND operation to the second
+; operand.  This way previous operations on the now masked out bits
+; might get optimized away.
+(define_subst "masked_op_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (SUBST:DSI (match_operand:DSI 1 "" "")
+		   (match_operand:SI  2 "" "")))]
+  ""
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (and:SI (match_dup 2)
+			   (match_operand:SI 3 "const_int_6bitset_operand" ""))))])
+
+; Use this in the insn name.
+(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
+
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 0/9] S/390 rework shift count handling - v2
@ 2016-02-23 14:33 Andreas Krebbel
  2016-02-23 14:33 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:33 UTC (permalink / raw)
  To: gcc-patches

This is an updated version of the shift count rework in the S/390
backend.  I think I've addressed most of the feedback from Ulrich and
Bernd (gensupport patch).

https://gcc.gnu.org/ml/gcc-patches/2016-01/msg00940.html

Andreas Krebbel (9):
  gensupport: Fix define_subst operand renumbering.
  S/390: Use enabled attribute overrides to disable alternatives.
  S/390: Get rid of Y constraint in rotate patterns.
  S/390: Get rid of Y constraint in left and logical right shift
    patterns.
  S/390: Get rid of Y constraint in arithmetic right shift patterns.
  S/390: Get rid of Y constraint in tabort.
  S/390: Get rid of Y constraint in vector.md.
  S/390: Use define_subst for the setmem patterns.
  S/390: Disallow SImode in s390_decompose_address

 gcc/config/s390/predicates.md |  10 +
 gcc/config/s390/s390.c        |  31 ++-
 gcc/config/s390/s390.md       | 553 +++++++++++++++---------------------------
 gcc/config/s390/subst.md      | 154 ++++++++++++
 gcc/config/s390/vector.md     | 138 ++++++-----
 gcc/gensupport.c              |  45 ++--
 6 files changed, 478 insertions(+), 453 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-23 14:33 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
@ 2016-02-25 17:14   ` Ulrich Weigand
  0 siblings, 0 replies; 18+ messages in thread
From: Ulrich Weigand @ 2016-02-25 17:14 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> 	* config/s390/predicates.md (const_int_6bitset_operand): New
>         predicates.
> 	* config/s390/s390.md: Include subst.md.
> 	("rotl<mode>3"): New expander.
> 	("rotl<mode>3", "*rotl<mode>3_and"): Merge insn definitions into
> 	...
> 	("*rotl<mode>3<addr_style_op><masked_op>"): New insn definition.
> 	* config/s390/subst.md: New file.

This already looks much nicer (and shorter) :-)

In fact, I'm now wondering whether it couldn't be even shorter.  Would it
be possible to use instead of:

(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
  [(set (match_operand:GPR             0 "register_operand" "=d,d")
	(rotate:GPR (match_operand:GPR 1 "register_operand"  "d,d")
		    (match_operand:SI  2 "nonmemory_operand" "a,n")))]
  "TARGET_CPU_ZARCH"
  "@
   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
   rll<g>\t%0,%1,%Y2"
  [(set_attr "op_type"  "RSE")
   (set_attr "atype"    "reg")
   (set_attr "enabled"  "*,<addr_style_op_enabled>")
   (set_attr "z10prop"  "z10_super_E1")])

simply something like:

(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
  [(set (match_operand:GPR             0 "register_operand" "=d")
	(rotate:GPR (match_operand:GPR 1 "register_operand"  "d")
		    (match_operand:SI  2 "nonmemory_operand" "an")))]
  "TARGET_CPU_ZARCH"
  "rll<g>\t%0,%1,<addr_style_op_ops>
  [(set_attr "op_type"  "RSE")
   (set_attr "atype"    "reg")
   (set_attr "z10prop"  "z10_super_E1")])


where addr_style_op_ops is defined like:

(define_subst_attr "addr_style_op_ops" "addr_style_op_subst" "%Y2" "%Y3(%2)")

and we don't need addr_style_op_enabled any more?   %Y would continue
to emit both simple constants and register operands (and full address
operands e.g. for setmem) as before.


> +(define_subst "masked_op_subst"
> +  [(set (match_operand:DSI 0 ""           "")
> +        (SUBST:DSI (match_operand:DSI 1 "" "")
> +		   (match_operand:SI  2 "" "")))]
> +  ""
> +  [(set (match_dup 0)
> +        (SUBST:DSI (match_dup 1)
> +		   (and:SI (match_dup 2)
> +			   (match_operand:SI 3 "const_int_6bitset_operand" ""))))])

Do we need a constraint letter here?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-29  8:47 [PATCH 0/9] S/390 rework shift count handling - v3 Andreas Krebbel
@ 2016-02-29  8:46 ` Andreas Krebbel
  0 siblings, 0 replies; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-29  8:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: uweigand

This patch introduces substitution patterns to add PLUS const_int, and
AND operands to patterns and uses this to rewrite the existing rotate
pattern.

gcc/ChangeLog:

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

	* config/s390/predicates.md (const_int_6bitset_operand): New
        predicates.
	* config/s390/s390.md: Include subst.md.
	("rotl<mode>3"): New expander.
	("rotl<mode>3", "*rotl<mode>3_and"): Merge insn definitions into
	...
	("*rotl<mode>3<addr_style_op><masked_op>"): New insn definition.
	* config/s390/subst.md: New file.
---
 gcc/config/s390/constraints.md |  4 +++
 gcc/config/s390/predicates.md  |  4 +++
 gcc/config/s390/s390.c         | 23 +++++++++++-----
 gcc/config/s390/s390.md        | 31 ++++++++++-----------
 gcc/config/s390/subst.md       | 61 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 100 insertions(+), 23 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index c1d2c8e..60a7edf 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -36,6 +36,7 @@
 ;;         jyy: constant consisting of byte chunks being either 0 or 0xff
 ;;         jKK: constant vector with all elements having the same value and
 ;;              matching K constraint
+;;         jm6: An integer operand with the lowest order 6 bits all ones.
 ;;    t -- Access registers 36 and 37.
 ;;    v -- Vector registers v0-v31.
 ;;    C -- A signed 8-bit constant (-128..127)
@@ -415,6 +416,9 @@
 	    (match_test "const_vec_duplicate_p (op)"))
        (match_test "satisfies_constraint_K (XVECEXP (op, 0, 0))")))
 
+(define_constraint "jm6"
+  "@internal An integer operand with the lowest order 6 bits all ones."
+  (match_operand 0 "const_int_6bitset_operand"))
 
 ;;
 ;; Memory constraints follow.
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index cbc8092..fefefb3 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -115,6 +115,10 @@
   return true;
 })
 
+; An integer operand with the lowest order 6 bits all ones.
+(define_predicate "const_int_6bitset_operand"
+ (and (match_code "const_int")
+      (match_test "(INTVAL (op) & 63) == 63")))
 (define_predicate "nonzero_shift_count_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index cd53b15..43219dd 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2994,18 +2994,18 @@ s390_decompose_address (rtx addr, struct s390_address *out)
 bool
 s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
 {
-  HOST_WIDE_INT off = 0;
+  rtx off = NULL_RTX;
 
   /* We can have an integer constant, an address register,
      or a sum of the two.  */
-  if (GET_CODE (op) == CONST_INT)
+  if (CONST_SCALAR_INT_P (op))
     {
-      off = INTVAL (op);
+      off = op;
       op = NULL_RTX;
     }
-  if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+  if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
     {
-      off = INTVAL (XEXP (op, 1));
+      off = XEXP (op, 1);
       op = XEXP (op, 0);
     }
   while (op && GET_CODE (op) == SUBREG)
@@ -3015,7 +3015,18 @@ s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
     return false;
 
   if (offset)
-    *offset = off;
+    {
+      if (off == NULL_RTX)
+	*offset = 0;
+      else if (CONST_INT_P (off))
+	*offset = INTVAL (off);
+      else if (CONST_WIDE_INT_P (off))
+	/* The offset will anyway be cut down to 12 bits so take just
+	   the lowest order chunk of the wide int.  */
+	*offset = CONST_WIDE_INT_ELT (off, 0);
+      else
+	gcc_unreachable ();
+    }
   if (base)
     *base = op;
 
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 65b6ce9..b7c037a 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -741,6 +741,8 @@
 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
 
+;; Subst pattern definitions
+(include "subst.md")
 
 (include "vector.md")
 
@@ -8376,28 +8378,23 @@
 ; rotl(di|si)3 instruction pattern(s).
 ;
 
-; rll, rllg
-(define_insn "rotl<mode>3"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_expand "rotl<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "")
+        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
+		    (match_operand:SI 2 "nonmemory_operand" "")))]
   "TARGET_CPU_ZARCH"
-  "rll<g>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RSE")
-   (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+  "")
 
 ; rll, rllg
-(define_insn "*rotl<mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			    (match_operand:SI 3 "const_int_operand"   "n"))))]
-  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "rll<g>\t%0,%1,%Y2"
+(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
+  [(set (match_operand:GPR             0 "register_operand"  "=d")
+	(rotate:GPR (match_operand:GPR 1 "register_operand"   "d")
+		    (match_operand:SI  2 "nonmemory_operand" "an")))]
+  "TARGET_CPU_ZARCH"
+  "rll<g>\t%0,%1,<addr_style_op_ops>"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+   (set_attr "z10prop"  "z10_super_E1")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
new file mode 100644
index 0000000..c3761a9
--- /dev/null
+++ b/gcc/config/s390/subst.md
@@ -0,0 +1,61 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;;  Subst patterns.
+;;  Copyright (C) 2016 Free Software Foundation, Inc.
+;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 3, or (at your option) any later
+;; version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_code_iterator SUBST [rotate])
+
+; 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_dup 0)
+        (SUBST:DSI (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")
+
+; In the subst pattern the additional const int operand will be used
+; as displacement.  In the normal version %Y is able to print the
+; operand either as displacement or as base register.
+(define_subst_attr "addr_style_op_ops" "addr_style_op_subst" "%Y2" "%Y3(%2)")
+
+
+; This substitution adds an explicit AND operation to the second
+; operand.  This way previous operations on the now masked out bits
+; might get optimized away.
+(define_subst "masked_op_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (SUBST:DSI (match_operand:DSI 1 "" "")
+		   (match_operand:SI  2 "" "")))]
+  ""
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (and:SI (match_dup 2)
+			   (match_operand:SI 3 "const_int_6bitset_operand" "jm6"))))])
+
+; Use this in the insn name.
+(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
+
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-01 17:04         ` Andreas Krebbel
@ 2016-02-01 17:11           ` Ulrich Weigand
  0 siblings, 0 replies; 18+ messages in thread
From: Ulrich Weigand @ 2016-02-01 17:11 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:
> > Hmm.  In theory reload should always respect both constraints and predicates.
> > But I guess it can't hurt to disable the alternative just to be safe; it is
> > indeed an uncommon case to have the constraint accept more than the predicate.
> > (Also a PLUS with two CONST_INT operands is not canonical RTL anyway.)
> 
> Does this mean you would prefer to convert the insn condition into a predicate and change it with
> subst_attr or should I leave it in the insn condition?

If we can transform the operand predicate, that would certainly be the best.
I.e. where the original pattern has:
  (match_operand:SI 2 "nonmemory_operand" "a,n")
have the replaced pattern use instead:
  (plus:SI (match_operand:SI 2 "register_operand" "a")
           (match_operand 3 "const_int_operand" "n"))

if that is possible via the subst mechanism ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-01 16:58       ` Ulrich Weigand
@ 2016-02-01 17:04         ` Andreas Krebbel
  2016-02-01 17:11           ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-01 17:04 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On 02/01/2016 05:58 PM, Ulrich Weigand wrote:
> Andreas Krebbel wrote:
>> On 02/01/2016 02:30 PM, Ulrich Weigand wrote:
>>> This seems to add just a single alternative.  Is that OK if it gets
>>> substituted into a pattern that used multiple alternatives otherwise?
>> Yes.  This is supposed to work.  The new constraint will be duplicated until it matches the number
>> of alternatives in the original insn.
> 
> OK, that makes sense.   But now I'm wondering about this bit of
> the ashiftrt patch:
> 
> +; FIXME: The number of alternatives is doubled here to match the fix
> +; number of 4 in the subst pattern for the (clobber (match_scratch...
> +; The right fix should be to support match_scratch in the output
> +; pattern of a define_subst.
> 
> +(define_subst "cconly_subst"
> +  [(set (match_operand:DSI 0 ""           "")
> +        (match_operand:DSI 1 "" ""))
> +   (clobber (reg:CC CC_REGNUM))]
> +  "s390_match_ccmode(insn, CCSmode)"
> +  [(set (reg CC_REGNUM)
> +	(compare (match_dup 1) (const_int 0)))
> +   (clobber (match_scratch:DSI 0 "=d,d,d,d"))])
> 
> I guess this is where the number 4 comes from?  But if the alternatives
> are duplicated, shouldn't it then work to simply use:
>    (clobber (match_scratch:DSI 0 "=d"))])

As the comment tries (and fails) to say the duplication of constraints currently does not seem to
work for match_scratch - only for match_operand.  This is just an ugly way to work around this for
now. The real fix is to enable match_scratch as well.

>>>> +; In the subst pattern we have to disable the alternative where op2 is
>>>> +; already a constant.  This attribute is supposed to be used in the
>>>> +; "disabled" insn attribute to achieve this.
>>>> +(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")
>>>
>>> Is this necessary given that the subst adds a REG_P (operands[2])
>>> condition?
>> I wasn't sure about this.  How does reload/lra behave when the constraints allow more than the insn
>> condition? I expected that reload might remember that one of the alternatives might take a constant
>> as well and then tries as part of reload inheritance and such things to actually exploit this?! Just
>> disabling the alternative in order to prevent reload from recording stuff for that alternative
>> appeared safer to me.
>>
>> On the other hand it is not ideal to have an operands[x] check in the insn condition in the first
>> place. Especially when using define_substs where the operands get renumbered this might add hard to
>> find bugs. Perhaps I should try replacing the insn predicate with a subst_attr instead? Is having a
>> constraint which allows more than a predicate any better than having the same with the insn condition?
> 
> Hmm.  In theory reload should always respect both constraints and predicates.
> But I guess it can't hurt to disable the alternative just to be safe; it is
> indeed an uncommon case to have the constraint accept more than the predicate.
> (Also a PLUS with two CONST_INT operands is not canonical RTL anyway.)

Does this mean you would prefer to convert the insn condition into a predicate and change it with
subst_attr or should I leave it in the insn condition?

-Andreas-

> 
> Bye,
> Ulrich
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-01 16:47     ` Andreas Krebbel
@ 2016-02-01 16:58       ` Ulrich Weigand
  2016-02-01 17:04         ` Andreas Krebbel
  0 siblings, 1 reply; 18+ messages in thread
From: Ulrich Weigand @ 2016-02-01 16:58 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:
> On 02/01/2016 02:30 PM, Ulrich Weigand wrote:
> > This seems to add just a single alternative.  Is that OK if it gets
> > substituted into a pattern that used multiple alternatives otherwise?
> Yes.  This is supposed to work.  The new constraint will be duplicated until it matches the number
> of alternatives in the original insn.

OK, that makes sense.   But now I'm wondering about this bit of
the ashiftrt patch:

+; FIXME: The number of alternatives is doubled here to match the fix
+; number of 4 in the subst pattern for the (clobber (match_scratch...
+; The right fix should be to support match_scratch in the output
+; pattern of a define_subst.

+(define_subst "cconly_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (match_operand:DSI 1 "" ""))
+   (clobber (reg:CC CC_REGNUM))]
+  "s390_match_ccmode(insn, CCSmode)"
+  [(set (reg CC_REGNUM)
+	(compare (match_dup 1) (const_int 0)))
+   (clobber (match_scratch:DSI 0 "=d,d,d,d"))])

I guess this is where the number 4 comes from?  But if the alternatives
are duplicated, shouldn't it then work to simply use:
   (clobber (match_scratch:DSI 0 "=d"))])


> >> +; In the subst pattern we have to disable the alternative where op2 is
> >> +; already a constant.  This attribute is supposed to be used in the
> >> +; "disabled" insn attribute to achieve this.
> >> +(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")
> > 
> > Is this necessary given that the subst adds a REG_P (operands[2])
> > condition?
> I wasn't sure about this.  How does reload/lra behave when the constraints allow more than the insn
> condition? I expected that reload might remember that one of the alternatives might take a constant
> as well and then tries as part of reload inheritance and such things to actually exploit this?! Just
> disabling the alternative in order to prevent reload from recording stuff for that alternative
> appeared safer to me.
> 
> On the other hand it is not ideal to have an operands[x] check in the insn condition in the first
> place. Especially when using define_substs where the operands get renumbered this might add hard to
> find bugs. Perhaps I should try replacing the insn predicate with a subst_attr instead? Is having a
> constraint which allows more than a predicate any better than having the same with the insn condition?

Hmm.  In theory reload should always respect both constraints and predicates.
But I guess it can't hurt to disable the alternative just to be safe; it is
indeed an uncommon case to have the constraint accept more than the predicate.
(Also a PLUS with two CONST_INT operands is not canonical RTL anyway.)

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-02-01 13:30   ` Ulrich Weigand
@ 2016-02-01 16:47     ` Andreas Krebbel
  2016-02-01 16:58       ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: Andreas Krebbel @ 2016-02-01 16:47 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On 02/01/2016 02:30 PM, Ulrich Weigand wrote:
> Andreas Krebbel wrote:
> 
>> +; Accept single register and immediate operands usable as shift
>> +; counts.
>> +(define_predicate "addrreg_or_constint_operand"
>> +  (match_code "reg, subreg, const_int")
> 
> I'm wondering whether this is even necessary.
> 
>> +{
>> +  if (GET_MODE (op) != VOIDmode
>> +      && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
>> +    return false;
> 
> The predicate always seems to be used with a mode, so any extra
> mode checks here seem redundant.
> 
>> +  while (op && GET_CODE (op) == SUBREG)
>> +    op = SUBREG_REG (op);
>> +
>> +  if (REG_P (op)
>> +      && (REGNO (op) >= FIRST_PSEUDO_REGISTER || ADDR_REG_P (op)))
>> +    return true;
>> +
>> +  if (CONST_INT_P (op))
>> +    return true;
> 
> This looks somewhat copied from shift_count_or_setmem_operand, where
> we have a comment:
>   /* Don't allow any non-base hard registers.  Doing so without
>      confusing reload and/or regrename would be tricky, and doesn't
>      buy us much anyway.  */
> 
> With the new set up, I don't believe there is any issue with confusing
> reload -- it's no more complex than any other pattern now.  So it
> should be fine to just accept any register.
> 
> In fact, I'm starting to wonder whether it wouldn't be just fine to
> simply using nonmemory_operand instead of this special predicate
> (the only issue might be that we could get CONST_WIDE_INT, but it
> should be simple to handle those).
> 
>> +(define_expand "rotl<mode>3"
>> +  [(set (match_operand:GPR 0 "register_operand" "")
>> +        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
>> +		    (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
> 
> Similarly, I think the expander no longer needs to use the special predicate
> shift_count_or_setmem_operandm but could just use nonmemory_operand.
> [ This will reject the PLUS that shift_count_or_setmem_operand accepted,
> but I don't believe you ever *could* get the PLUS in the expander anyway.
> It will only be moved in by combine, so as long as the insn accepts it,
> everything should be good.  ]
Ok. I'll try to get rid of the special predicates.

>> +(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
>> +  [(set (match_operand:GPR             0 "register_operand"           "=d,d")
>> +	(rotate:GPR (match_operand:GPR 1 "register_operand"            "d,d")
>> +		    (match_operand:SI  2 "addrreg_or_constint_operand" "a,n")))]
>> +  "TARGET_CPU_ZARCH"
>> +  "@
>> +   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
>> +   rll<g>\t%0,%1,%Y2"
> 
> So it looks like %Y is now always used for just a constant.  Maybe the
> implementation of %Y should be adjusted (once the patch series is complete)?
> Also, if we use just nonmemory_operand, %Y should be updated to accept
> CONST_WIDE_INT just like e.g. %x does.
Ok.

> 
>> +; 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 "" "")))]
>> +  "REG_P (operands[2])"
>> +  [(set (match_dup 0)
>> +        (SUBST:DSI (match_dup 1)
>> +		   (plus:SI (match_dup 2)
>> +			    (match_operand 3 "const_int_operand" "n"))))])
> 
> This seems to add just a single alternative.  Is that OK if it gets
> substituted into a pattern that used multiple alternatives otherwise?
Yes.  This is supposed to work.  The new constraint will be duplicated until it matches the number
of alternatives in the original insn.

>> +; In the subst pattern we have to disable the alternative where op2 is
>> +; already a constant.  This attribute is supposed to be used in the
>> +; "disabled" insn attribute to achieve this.
>> +(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")
> 
> Is this necessary given that the subst adds a REG_P (operands[2])
> condition?
I wasn't sure about this.  How does reload/lra behave when the constraints allow more than the insn
condition? I expected that reload might remember that one of the alternatives might take a constant
as well and then tries as part of reload inheritance and such things to actually exploit this?! Just
disabling the alternative in order to prevent reload from recording stuff for that alternative
appeared safer to me.

On the other hand it is not ideal to have an operands[x] check in the insn condition in the first
place. Especially when using define_substs where the operands get renumbered this might add hard to
find bugs. Perhaps I should try replacing the insn predicate with a subst_attr instead? Is having a
constraint which allows more than a predicate any better than having the same with the insn condition?

-Andreas-

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-01-14 16:36 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
@ 2016-02-01 13:30   ` Ulrich Weigand
  2016-02-01 16:47     ` Andreas Krebbel
  0 siblings, 1 reply; 18+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:30 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> +; Accept single register and immediate operands usable as shift
> +; counts.
> +(define_predicate "addrreg_or_constint_operand"
> +  (match_code "reg, subreg, const_int")

I'm wondering whether this is even necessary.

> +{
> +  if (GET_MODE (op) != VOIDmode
> +      && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
> +    return false;

The predicate always seems to be used with a mode, so any extra
mode checks here seem redundant.

> +  while (op && GET_CODE (op) == SUBREG)
> +    op = SUBREG_REG (op);
> +
> +  if (REG_P (op)
> +      && (REGNO (op) >= FIRST_PSEUDO_REGISTER || ADDR_REG_P (op)))
> +    return true;
> +
> +  if (CONST_INT_P (op))
> +    return true;

This looks somewhat copied from shift_count_or_setmem_operand, where
we have a comment:
  /* Don't allow any non-base hard registers.  Doing so without
     confusing reload and/or regrename would be tricky, and doesn't
     buy us much anyway.  */

With the new set up, I don't believe there is any issue with confusing
reload -- it's no more complex than any other pattern now.  So it
should be fine to just accept any register.

In fact, I'm starting to wonder whether it wouldn't be just fine to
simply using nonmemory_operand instead of this special predicate
(the only issue might be that we could get CONST_WIDE_INT, but it
should be simple to handle those).

> +(define_expand "rotl<mode>3"
> +  [(set (match_operand:GPR 0 "register_operand" "")
> +        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
> +		    (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]

Similarly, I think the expander no longer needs to use the special predicate
shift_count_or_setmem_operandm but could just use nonmemory_operand.
[ This will reject the PLUS that shift_count_or_setmem_operand accepted,
but I don't believe you ever *could* get the PLUS in the expander anyway.
It will only be moved in by combine, so as long as the insn accepts it,
everything should be good.  ]

> +(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
> +  [(set (match_operand:GPR             0 "register_operand"           "=d,d")
> +	(rotate:GPR (match_operand:GPR 1 "register_operand"            "d,d")
> +		    (match_operand:SI  2 "addrreg_or_constint_operand" "a,n")))]
> +  "TARGET_CPU_ZARCH"
> +  "@
> +   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
> +   rll<g>\t%0,%1,%Y2"

So it looks like %Y is now always used for just a constant.  Maybe the
implementation of %Y should be adjusted (once the patch series is complete)?
Also, if we use just nonmemory_operand, %Y should be updated to accept
CONST_WIDE_INT just like e.g. %x does.

> +; 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 "" "")))]
> +  "REG_P (operands[2])"
> +  [(set (match_dup 0)
> +        (SUBST:DSI (match_dup 1)
> +		   (plus:SI (match_dup 2)
> +			    (match_operand 3 "const_int_operand" "n"))))])

This seems to add just a single alternative.  Is that OK if it gets
substituted into a pattern that used multiple alternatives otherwise?

> +; In the subst pattern we have to disable the alternative where op2 is
> +; already a constant.  This attribute is supposed to be used in the
> +; "disabled" insn attribute to achieve this.
> +(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")

Is this necessary given that the subst adds a REG_P (operands[2])
condition?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
@ 2016-01-14 16:36 ` Andreas Krebbel
  2016-02-01 13:30   ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:36 UTC (permalink / raw)
  To: gcc-patches

This patch introduces substitution patterns to add PLUS const_int, and
AND operands to patterns and uses this to rewrite the existing rotate
pattern.

gcc/ChangeLog:

2016-01-14  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* config/s390/predicates.md (addrreg_or_constint_operand)
	(const_int_6bitset_operand): New predicates.
	* config/s390/s390.md: Include subst.md.
	("rotl<mode>3"): New expander.
	("rotl<mode>3", "*rotl<mode>3_and"): Merge insn definitions into
	...
	("*rotl<mode>3<addr_style_op><masked_op>"): New insn definition.
	* config/s390/subst.md: New file.
---
 gcc/config/s390/predicates.md | 25 ++++++++++++++++
 gcc/config/s390/s390.md       | 34 +++++++++++-----------
 gcc/config/s390/subst.md      | 66 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+), 17 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index cbc8092..b58cb22 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -115,6 +115,31 @@
   return true;
 })
 
+; Accept single register and immediate operands usable as shift
+; counts.
+(define_predicate "addrreg_or_constint_operand"
+  (match_code "reg, subreg, const_int")
+{
+  if (GET_MODE (op) != VOIDmode
+      && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
+    return false;
+
+  while (op && GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (REG_P (op)
+      && (REGNO (op) >= FIRST_PSEUDO_REGISTER || ADDR_REG_P (op)))
+    return true;
+
+  if (CONST_INT_P (op))
+    return true;
+
+  return false;
+})
+; An integer operand with the lowest order 6 bit all ones.
+(define_predicate "const_int_6bitset_operand"
+ (and (match_code "const_int")
+      (match_test "(INTVAL (op) & 63) == 63")))
 (define_predicate "nonzero_shift_count_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 39467ad..3ed10f4 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -739,6 +739,8 @@
 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
 
+;; Subst pattern definitions
+(include "subst.md")
 
 (include "vector.md")
 
@@ -8350,28 +8352,26 @@
 ; rotl(di|si)3 instruction pattern(s).
 ;
 
-; rll, rllg
-(define_insn "rotl<mode>3"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_expand "rotl<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "")
+        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
+		    (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
   "TARGET_CPU_ZARCH"
-  "rll<g>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RSE")
-   (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+  "")
 
 ; rll, rllg
-(define_insn "*rotl<mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			    (match_operand:SI 3 "const_int_operand"   "n"))))]
-  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "rll<g>\t%0,%1,%Y2"
+(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
+  [(set (match_operand:GPR             0 "register_operand"           "=d,d")
+	(rotate:GPR (match_operand:GPR 1 "register_operand"            "d,d")
+		    (match_operand:SI  2 "addrreg_or_constint_operand" "a,n")))]
+  "TARGET_CPU_ZARCH"
+  "@
+   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
+   rll<g>\t%0,%1,%Y2"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+   (set_attr "disabled" "0,<addr_style_op_disable>")
+   (set_attr "z10prop"  "z10_super_E1")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
new file mode 100644
index 0000000..481f33e
--- /dev/null
+++ b/gcc/config/s390/subst.md
@@ -0,0 +1,66 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;;  Subst patterns.
+;;  Copyright (C) 2016 Free Software Foundation, Inc.
+;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 3, or (at your option) any later
+;; version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_code_iterator SUBST [ashift lshiftrt rotate])
+
+; 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 "" "")))]
+  "REG_P (operands[2])"
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (plus:SI (match_dup 2)
+			    (match_operand 3 "const_int_operand" "n"))))])
+
+; Use this in the insn name.
+(define_subst_attr "addr_style_op"     "addr_style_op_subst" "" "_plus")
+
+; In the subst pattern the additional const int operand will be used
+; as displacement.  In the normal version the displacements stays just
+; 0.
+(define_subst_attr "addr_style_op_op3" "addr_style_op_subst" "0" "%Y3")
+
+; In the subst pattern we have to disable the alternative where op2 is
+; already a constant.  This attribute is supposed to be used in the
+; "disabled" insn attribute to achieve this.
+(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")
+
+
+; This substitution adds an explicit AND operation to the second
+; operand.  This way previous operations on the now masked out bits
+; might get optimized away.
+(define_subst "masked_op_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (SUBST:DSI (match_operand:DSI 1 "" "")
+		   (match_operand:SI  2 "" "")))]
+  ""
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (and:SI (match_dup 2)
+			   (match_operand:SI 3 "const_int_6bitset_operand" ""))))])
+
+; Use this in the insn name.
+(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
+
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-02-29  8:46 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-23 14:33 [PATCH 0/9] S/390 rework shift count handling - v2 Andreas Krebbel
2016-02-23 14:33 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
2016-02-23 14:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
2016-02-23 14:33 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
2016-02-23 14:33 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
2016-02-23 14:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
2016-02-23 14:33 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
2016-02-25 17:14   ` Ulrich Weigand
2016-02-23 14:33 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
2016-02-23 14:33 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
2016-02-23 14:33 ` [PATCH 2/9] S/390: Use enabled attribute overrides to disable alternatives Andreas Krebbel
  -- strict thread matches above, loose matches on Subject: below --
2016-02-29  8:47 [PATCH 0/9] S/390 rework shift count handling - v3 Andreas Krebbel
2016-02-29  8:46 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
2016-01-14 16:36 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
2016-02-01 13:30   ` Ulrich Weigand
2016-02-01 16:47     ` Andreas Krebbel
2016-02-01 16:58       ` Ulrich Weigand
2016-02-01 17:04         ` Andreas Krebbel
2016-02-01 17:11           ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).