public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/9] S/390 rework shift count handling
@ 2016-01-14 16:34 Andreas Krebbel
  2016-01-14 16:36 ` [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns Andreas Krebbel
                   ` (10 more replies)
  0 siblings, 11 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:34 UTC (permalink / raw)
  To: gcc-patches

On S/390 we have address style shift counts.  So it is possible to
have a reg + const_int shift count.  To address this it appeared to be
convenient to really handle this as address operand.  For that reason
the "Y" constraint used for shift counts is an extra memory
constraint.  Unfortunately a shift count is not necessarily Pmode.  So
even when compiling for 64 bit we had to allow SImode addresses for Y.
Since all extra memory constraints go through s390_decompose_address
we had to unconditionally enable SImode addresses everywhere:

https://gcc.gnu.org/ml/gcc-patches/2006-03/msg01495.html

Unfortunately this seems to cause some trouble in situations not
entirely clear to me yet:

https://gcc.gnu.org/ml/gcc/2015-05/msg00305.html

This patchset fixes this by getting rid of SImode - "Y" combinations
in our machine description.  To prevent us from losing performance in
situations where an reg + const_int can really be used as shift count
we have to make it explicit in the RTL patterns.  This unfortunately
requires us to duplicate a lot of patterns.  To compensate for that
I'm using the define_subst mechanism to keep the overhead limited.  In
fact the patchset reduces the number of lines in the md files.

I've tested the whole patchset with various CPU levels on s390 and
s390x.  No regressions.

Patch 1 is the only common code change which fixes a problem with the
renumbering of operands when performing substitutions.

While I only need a formal approval for patch 1 comments regarding the
other patches are welcome as well.

Ok to apply?

Bye,

-Andreas-

Andreas Krebbel (9):
  gensupport: Fix define_subst operand renumbering.
  S/390: Add disabled insn attribute
  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 |  31 +++
 gcc/config/s390/s390.c        |   8 +-
 gcc/config/s390/s390.md       | 581 +++++++++++++++---------------------------
 gcc/config/s390/subst.md      | 180 +++++++++++++
 gcc/config/s390/vector.md     | 138 +++++-----
 gcc/gensupport.c              |  41 +--
 6 files changed, 520 insertions(+), 459 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

-- 
1.9.1

^ permalink raw reply	[flat|nested] 31+ 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
  2016-01-14 16:36 ` [PATCH 2/9] S/390: Add disabled insn attribute Andreas Krebbel
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 31+ 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] 31+ messages in thread

* [PATCH 2/9] S/390: Add disabled insn attribute
  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-01-14 16:36 ` Andreas Krebbel
  2016-02-01 13:45   ` Ulrich Weigand
  2016-01-14 16:38 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:36 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 a `disabled' attribute is defined which can be used to
explicitly disable an alternative.  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:

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

	* config/s390/s390.md ("op_type", "atype", "length" attributes):
	Remove RRR type.  It doesn't really exist.
	("disabled"): New attribute definition.
	("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"): Use the new
	disabled attribute.
---
 gcc/config/s390/s390.md | 227 ++++++++++++++++++++++++++----------------------
 1 file changed, 122 insertions(+), 105 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index d6097c1..39467ad 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -357,7 +357,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.
@@ -384,7 +384,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")))
 
@@ -425,8 +425,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)))
 
 
@@ -442,8 +442,18 @@
   "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vec"
   (const_string "standard"))
 
+; Insn attribute with boolean value
+;  1 to disable an insn alternative
+;  0 or * for an active insn alternative
+;  an active alternative can still be disabled due to lacking cpu
+;  facility support
+(define_attr "disabled" "" (const_int 0))
+
 (define_attr "enabled" ""
-  (cond [(eq_attr "cpu_facility" "standard")
+  (cond [(eq_attr "disabled" "1")
+	 (const_int 0)
+
+	 (eq_attr "cpu_facility" "standard")
 	 (const_int 1)
 
          (and (eq_attr "cpu_facility" "ieee")
@@ -606,27 +616,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 `disabled' insn
+;; attribute to disable certain alternatives for certain modes.
+(define_mode_attr BFP [(TF "1") (DF "1") (SF "1") (TD "0") (DD "0") (DD "0")])
+(define_mode_attr DFP [(TF "0") (DF "0") (SF "0") (TD "1") (DD "1") (DD "1")])
+(define_mode_attr nDSF [(TF "1") (DF "0") (SF "0") (TD "1") (DD "1") (SD "1")])
+(define_mode_attr nDFDI [(TF "1") (DF "0") (SF "1")
+			 (TD "1") (DD "1") (DD "1")
+			 (TI "1") (DI "0") (SI "1")])
 
 ;; This attribute is used in the operand constraint list
 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
@@ -636,10 +633,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")])
@@ -1248,13 +1241,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 "disabled" "0,<nDSF>")])
 
 ; wfcedbs, wfchdbs, wfchedbs
 (define_insn "*vec_cmp<insn_cmp>df_cconly"
@@ -4695,15 +4689,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 "disabled"     "0,<nDFDI>")])
 
 ; cxfbr, cdfbr, cefbr
 (define_insn "floatsi<mode>2"
@@ -5462,47 +5457,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 "disabled"     "<BFP>,<DFP>,<nDSF>,<nDFDI>")])
 
 ; 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 "disabled" "<BFP>,<DFP>,<nDSF>")])
 
 ; 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 "disabled" "<BFP>,<DFP>,<nDSF>")])
 
 ;
 ; Pointer add instruction patterns
@@ -5886,47 +5887,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 "disabled"     "<BFP>,<DFP>,<nDSF>,<nDFDI>")])
 
 ; 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 "disabled" "<BFP>,<DFP>,<nDSF>")])
 
 ; 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 "disabled" "<BFP>,<DFP>,<nDSF>")])
 
 
 ;;
@@ -6308,24 +6315,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 "disabled"     "<BFP>,<DFP>,<nDSF>,<nDFDI>")])
 
 ; 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
@@ -6333,14 +6342,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 "disabled"     "0,0,<nDFDI>")])
 
 ; 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
@@ -6348,7 +6358,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 "disabled"     "0,0,<nDFDI>")])
 
 ;;
 ;;- Divide and modulo instructions.
@@ -6774,17 +6785,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 "disabled"     "<BFP>,<DFP>,<nDSF>,<nDFDI>")])
 
 
 ;;
@@ -7995,8 +8008,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"
   "@
@@ -8004,7 +8017,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 "disabled"     "0,<nDFDI>")])
 
 
 ;;
@@ -8117,8 +8131,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"
   "@
@@ -8126,7 +8140,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 "disabled"     "0,<nDFDI>")])
 
 
 ;;
@@ -8232,8 +8247,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"
   "@
@@ -8241,7 +8256,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 "disabled"     "0,<nDFDI>")])
 
 ;;
 ;;- Square root instructions.
@@ -8253,8 +8269,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
@@ -8262,7 +8278,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 "disabled"     "0,<nDSF>,<nDFDI>")])
 
 
 ;;
-- 
1.9.1

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

* [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns.
  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-01-14 16:36 ` [PATCH 2/9] S/390: Add disabled insn attribute Andreas Krebbel
@ 2016-01-14 16:38 ` Andreas Krebbel
  2016-02-01 13:35   ` Ulrich Weigand
  2016-01-14 16:39 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:38 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.

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

	* 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  | 185 +++++++----------------------------------------
 gcc/config/s390/subst.md |  61 ++++++++++++++++
 2 files changed, 86 insertions(+), 160 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 8a99cd1..f91c92d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8436,178 +8436,43 @@
   ""
   "")
 
-(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 "addrreg_or_constint_operand" "a,n,a,n")))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_ZARCH"
-  "srda\t%0,%Y2"
+  "@
+   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 "disabled" "0,<addr_style_op_cc_disable>,0,<addr_style_op_cc_disable>")
    (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,*")])
-
-; 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 "addrreg_or_constint_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 "disabled" "0,<addr_style_op_cc_disable>,0,<addr_style_op_cc_disable>")
+   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 481f33e..8983120 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -64,3 +64,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_disable" "addr_style_op_cc_subst" "0" "1")
+(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] 31+ messages in thread

* [PATCH 6/9] S/390: Get rid of Y constraint in tabort.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (2 preceding siblings ...)
  2016-01-14 16:38 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
@ 2016-01-14 16:39 ` Andreas Krebbel
  2016-02-01 13:36   ` Ulrich Weigand
  2016-01-14 16:40 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:39 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:

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

	* config/s390/s390.md ("*tabort_1"): Change predicate to
	addrreg_or_constint_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 | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index f91c92d..389b523 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -10697,10 +10697,20 @@
 })
 
 (define_insn "*tabort_1"
-  [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
+  [(unspec_volatile [(match_operand:SI 0 "addrreg_or_constint_operand" "a,n")]
 		    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"
+  "tabort\t%1(%0)"
   [(set_attr "op_type" "S")])
 
 ; Transaction extract nesting depth
-- 
1.9.1

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

* [PATCH 7/9] S/390: Get rid of Y constraint in vector.md.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (3 preceding siblings ...)
  2016-01-14 16:39 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
@ 2016-01-14 16:40 ` Andreas Krebbel
  2016-02-01 13:38   ` Ulrich Weigand
  2016-01-14 16:41 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:40 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:

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

	* 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 8983120..ccff40e 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 "" "")))]
   "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"))))])
+        (SUBST:DSI_VI (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")
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 2302a8f..abdc8c3 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 "addrreg_or_constint_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 "addrreg_or_constint_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 "register_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 "addrreg_or_constint_operand" "a,n")))]
+  "TARGET_VX"
+  "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
+  [(set_attr "disabled" "0,<addr_style_op_disable>")
+   (set_attr "op_type" "VRS")])
 
 ; Shift each element by corresponding vector element
 
-- 
1.9.1

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

* [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (4 preceding siblings ...)
  2016-01-14 16:40 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
@ 2016-01-14 16:41 ` Andreas Krebbel
  2016-02-01 13:46   ` Ulrich Weigand
  2016-01-14 16:44 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:41 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:

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

	* 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 21a5687..e0226a1 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2795,9 +2795,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
@@ -2843,9 +2841,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] 31+ messages in thread

* [PATCH 1/9] gensupport: Fix define_subst operand renumbering.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (5 preceding siblings ...)
  2016-01-14 16:41 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
@ 2016-01-14 16:44 ` Andreas Krebbel
  2016-01-18 14:46   ` Bernd Schmidt
  2016-01-14 19:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 16:44 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 to record
the operand numbers already in use.  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 recorded already when assigning new
numbers.

Bootstrapped and regtested on s390, s390x, and x86_64.

Ok for mainline?

Bye,

-Andreas-

gcc/ChangeLog:

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

	* 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 | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 596b885..8ace425 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
@@ -1843,7 +1846,15 @@ 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);
+
+	  renumerate_operands_in_pattern (subst_pattern);
 
 	  /* Substitute match_dup and match_op_dup in the new pattern and
 	     duplicate constraints.  */
@@ -1856,7 +1867,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;
 
@@ -1976,6 +1986,14 @@ find_first_unused_number_of_operand ()
    It visits all expressions in PATTERN and assigns not-occupied
    operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
    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 void
 renumerate_operands_in_pattern (rtx pattern)
 {
@@ -2010,23 +2028,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] 31+ messages in thread

* [PATCH 8/9] S/390: Use define_subst for the setmem patterns.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (6 preceding siblings ...)
  2016-01-14 16:44 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
@ 2016-01-14 19:33 ` Andreas Krebbel
  2016-02-01 13:43   ` Ulrich Weigand
  2016-01-14 19:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 19: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:

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

	* config/s390/predicates.md ("const_int_8bitset_operand"): New predicate.
	* config/s390/s390.md ("*setmem_long", "*setmem_long_and")
	("*setmem_long_31z", "*setmem_long_and_31z"): Merge into ...
	("*setmem_long<setmem_31z><setmem_and>"): New pattern definition.
	* 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       | 60 +++++--------------------------------------
 gcc/config/s390/subst.md      | 52 +++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 53 deletions(-)

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index b58cb22..bc25773 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -140,6 +140,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 389b523..350ed36 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3313,62 +3313,16 @@
 
 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
 
-(define_insn "*setmem_long"
+(define_insn "*setmem_long<setmem_31z><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")
-		     (subreg:P (match_dup 3) <modesize>)]
+   (set (mem:BLK (subreg:P (match_operand:<DBL> 1 "register_operand" "0") 0))
+        (unspec:BLK [(match_operand:P 3 "shift_count_or_setmem_operand" "Y")
+		     (subreg:P (match_operand:<DBL> 2 "register_operand" "0") <modesize>)]
 		     UNSPEC_REPLICATE_BYTE))
-   (use (match_operand:<DBL> 1 "register_operand" "d"))
+   (use (match_operand:<DBL> 4 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
-  "TARGET_64BIT || !TARGET_ZARCH"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(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"
-  [(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")
-		     (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"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(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"
+  "<setmem_31z_cond>"
+  "mvcle\t%0,%4,%Y3\;jo\t.-4"
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index ccff40e..a633f3f 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -126,3 +126,55 @@
    (clobber (match_scratch:DSI 0 "=d,d,d,d"))])
 
 (define_subst_attr "cconly" "cconly_subst" "" "_cconly")
+
+
+;; setmem substitution patterns
+
+
+; Turn the DImode in the 31 bit pattern into TImode to enforce
+; register pair usage even with -mzarch.
+; The subreg offset is adjusted accordingly.
+(define_subst "setmem_31z_subst"
+  [(clobber (match_operand:DI                      0 "register_operand" ""))
+   (set (mem:BLK (subreg:SI (match_operand:DI      3 "register_operand" "") 0))
+        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
+		     (subreg:SI (match_operand:DI  4 "register_operand" "")
+				0)]
+		     UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:DI                          1 "register_operand" ""))
+   (clobber (reg:CC CC_REGNUM))]
+""
+  [(clobber (match_operand:TI                      0 "register_operand" ""))
+   (set (mem:BLK (subreg:SI (match_operand:TI      3 "register_operand" "") 4))
+        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
+		     (subreg:SI (match_operand:TI  4 "register_operand" "")
+				12)]
+		    UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:TI                          1 "register_operand" ""))
+   (clobber (reg:CC CC_REGNUM))])
+
+(define_subst_attr "setmem_31z"      "setmem_31z_subst" "" "_31z")
+(define_subst_attr "setmem_31z_cond" "setmem_31z_subst" "TARGET_64BIT || !TARGET_ZARCH"
+                                                        "!TARGET_64BIT && TARGET_ZARCH")
+
+; 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:SI (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] 31+ messages in thread

* [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (7 preceding siblings ...)
  2016-01-14 19:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
@ 2016-01-14 19:33 ` Andreas Krebbel
  2016-01-14 20:44 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
  2016-01-14 21:06 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
  10 siblings, 0 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 19: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.

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

	* config/s390/s390.md ("*<shift>di3_31", "*<shift><mode>3")
	("*<shift>di3_31_and", "*<shift><mode>3_and"): Merge into single
	pattern definition ...
	("*<shift>di3_31<addr_style_op><masked_op>"): New pattern.
---
 gcc/config/s390/s390.md | 61 ++++++++++++++++++-------------------------------
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3ed10f4..8a99cd1 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8389,56 +8389,39 @@
   ""
   "")
 
+; 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 "addrreg_or_constint_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 "disabled" "0,<addr_style_op_disable>")
    (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 "addrreg_or_constint_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 "disabled" "0,<addr_style_op_disable>,0,<addr_style_op_disable>")
+   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
 
 ;
 ; ashr(di|si)3 instruction pattern(s).
-- 
1.9.1

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

* [PATCH 8/9] S/390: Use define_subst for the setmem patterns.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (8 preceding siblings ...)
  2016-01-14 19:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
@ 2016-01-14 20:44 ` Andreas Krebbel
  2016-01-14 21:06 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
  10 siblings, 0 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 20:44 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:

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

	* config/s390/predicates.md ("const_int_8bitset_operand"): New predicate.
	* config/s390/s390.md ("*setmem_long", "*setmem_long_and")
	("*setmem_long_31z", "*setmem_long_and_31z"): Merge into ...
	("*setmem_long<setmem_31z><setmem_and>"): New pattern definition.
	* 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       | 60 +++++--------------------------------------
 gcc/config/s390/subst.md      | 52 +++++++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 53 deletions(-)

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index b58cb22..bc25773 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -140,6 +140,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 389b523..350ed36 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3313,62 +3313,16 @@
 
 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
 
-(define_insn "*setmem_long"
+(define_insn "*setmem_long<setmem_31z><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")
-		     (subreg:P (match_dup 3) <modesize>)]
+   (set (mem:BLK (subreg:P (match_operand:<DBL> 1 "register_operand" "0") 0))
+        (unspec:BLK [(match_operand:P 3 "shift_count_or_setmem_operand" "Y")
+		     (subreg:P (match_operand:<DBL> 2 "register_operand" "0") <modesize>)]
 		     UNSPEC_REPLICATE_BYTE))
-   (use (match_operand:<DBL> 1 "register_operand" "d"))
+   (use (match_operand:<DBL> 4 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
-  "TARGET_64BIT || !TARGET_ZARCH"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(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"
-  [(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")
-		     (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"
-  "mvcle\t%0,%1,%Y2\;jo\t.-4"
-  [(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"
+  "<setmem_31z_cond>"
+  "mvcle\t%0,%4,%Y3\;jo\t.-4"
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index ccff40e..a633f3f 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -126,3 +126,55 @@
    (clobber (match_scratch:DSI 0 "=d,d,d,d"))])
 
 (define_subst_attr "cconly" "cconly_subst" "" "_cconly")
+
+
+;; setmem substitution patterns
+
+
+; Turn the DImode in the 31 bit pattern into TImode to enforce
+; register pair usage even with -mzarch.
+; The subreg offset is adjusted accordingly.
+(define_subst "setmem_31z_subst"
+  [(clobber (match_operand:DI                      0 "register_operand" ""))
+   (set (mem:BLK (subreg:SI (match_operand:DI      3 "register_operand" "") 0))
+        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
+		     (subreg:SI (match_operand:DI  4 "register_operand" "")
+				0)]
+		     UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:DI                          1 "register_operand" ""))
+   (clobber (reg:CC CC_REGNUM))]
+""
+  [(clobber (match_operand:TI                      0 "register_operand" ""))
+   (set (mem:BLK (subreg:SI (match_operand:TI      3 "register_operand" "") 4))
+        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
+		     (subreg:SI (match_operand:TI  4 "register_operand" "")
+				12)]
+		    UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:TI                          1 "register_operand" ""))
+   (clobber (reg:CC CC_REGNUM))])
+
+(define_subst_attr "setmem_31z"      "setmem_31z_subst" "" "_31z")
+(define_subst_attr "setmem_31z_cond" "setmem_31z_subst" "TARGET_64BIT || !TARGET_ZARCH"
+                                                        "!TARGET_64BIT && TARGET_ZARCH")
+
+; 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:SI (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] 31+ messages in thread

* [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns.
  2016-01-14 16:34 [PATCH 0/9] S/390 rework shift count handling Andreas Krebbel
                   ` (9 preceding siblings ...)
  2016-01-14 20:44 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
@ 2016-01-14 21:06 ` Andreas Krebbel
  10 siblings, 0 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-01-14 21:06 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.

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

	* config/s390/s390.md ("*<shift>di3_31", "*<shift><mode>3")
	("*<shift>di3_31_and", "*<shift><mode>3_and"): Merge into single
	pattern definition ...
	("*<shift>di3_31<addr_style_op><masked_op>"): New pattern.
---
 gcc/config/s390/s390.md | 61 ++++++++++++++++++-------------------------------
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 3ed10f4..8a99cd1 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8389,56 +8389,39 @@
   ""
   "")
 
+; 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 "addrreg_or_constint_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 "disabled" "0,<addr_style_op_disable>")
    (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 "addrreg_or_constint_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 "disabled" "0,<addr_style_op_disable>,0,<addr_style_op_disable>")
+   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
 
 ;
 ; ashr(di|si)3 instruction pattern(s).
-- 
1.9.1

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

* Re: [PATCH 1/9] gensupport: Fix define_subst operand renumbering.
  2016-01-14 16:44 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
@ 2016-01-18 14:46   ` Bernd Schmidt
  0 siblings, 0 replies; 31+ messages in thread
From: Bernd Schmidt @ 2016-01-18 14:46 UTC (permalink / raw)
  To: Andreas Krebbel, gcc-patches

On 01/14/2016 05:33 PM, Andreas Krebbel wrote:
> When processing substitutions the operands are renumbered.  To find a
> free operand number the array used_operands_numbers is used to record
> the operand numbers already in use.  Currently this array is used to
> assign new numbers *before* all the RTXes in the vector have been
> processed.

> 	* 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.

Mostly ok, I think. As an aside, all the define_subst stuff in 
gensupport looks rather suspiciously clunky and the comments are in 
broken English. We should fix this stuff at some point.

> @@ -1976,6 +1986,14 @@ find_first_unused_number_of_operand ()
>      It visits all expressions in PATTERN and assigns not-occupied
>      operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
>      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 void
>   renumerate_operands_in_pattern (rtx pattern)
>   {

If you want to keep this comment, you might want to move it inside the 
function (or into the caller). Ok with or without any such change - this 
looks a bit weird but I don't know what's best.


Bernd

^ permalink raw reply	[flat|nested] 31+ 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; 31+ 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] 31+ messages in thread

* Re: [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns.
  2016-01-14 16:38 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
@ 2016-02-01 13:35   ` Ulrich Weigand
  2016-02-23 14:25     ` Andreas Krebbel
  0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:35 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> +; This is like the addr_style_op substitution above but with a CC clobber.
> +(define_subst "addr_style_op_cc_subst"

> +; This is like the masked_op substitution but with a CC clobber.
> +(define_subst "masked_op_cc_subst"

A bit unfortunate that these need to be duplicated.  Does the subst always
have to match the full pattern, or can it match and operate on just one
element of a PARALLEL?

> +; This adds an explicit CC reg set to an operation while keeping the
> +; set for the operation result as well.
> +(define_subst "setcc_subst"

> +; This adds an explicit CC reg set to an operation while dropping the
> +; result of the operation.
> +(define_subst "cconly_subst"

These are nice!  It would seem they could be applied to simplify many
of the non-shift patterns too, right?

Bye,
Ulrich

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

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

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

Andreas Krebbel wrote:

>  (define_insn "*tabort_1"
> -  [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
> +  [(unspec_volatile [(match_operand:SI 0 "addrreg_or_constint_operand" "a,n")]
>  		    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"
> +  "tabort\t%1(%0)"

This seems dangerous: const_int_operand may match a constant that does
not fit into the "J" constraint, which would lead to an abort in reload.

What is the semantics for the abort code anyway?  It is supposed to be
automatically truncated or not?

Bye,
Ulrich

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

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

* Re: [PATCH 7/9] S/390: Get rid of Y constraint in vector.md.
  2016-01-14 16:40 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
@ 2016-02-01 13:38   ` Ulrich Weigand
  0 siblings, 0 replies; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:38 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> +(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 "register_operand"      "a, I")

The second alternative can never match here, can it?

Bye,
Ulrich

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

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

* Re: [PATCH 8/9] S/390: Use define_subst for the setmem patterns.
  2016-01-14 19:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
@ 2016-02-01 13:43   ` Ulrich Weigand
  0 siblings, 0 replies; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:43 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebel:

> 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.

Hmm, I'm wondering whether it's worth it to use a subst pattern that
is only ever used in one single instance?  (Specifically I'm wondering
about the 31z subst.  The and subst is used multiple times.)


> +; Turn the DImode in the 31 bit pattern into TImode to enforce
> +; register pair usage even with -mzarch.
> +; The subreg offset is adjusted accordingly.
> +(define_subst "setmem_31z_subst"
> +  [(clobber (match_operand:DI                      0 "register_operand" ""))
> +   (set (mem:BLK (subreg:SI (match_operand:DI      3 "register_operand" "") 0))
> +        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
> +		     (subreg:SI (match_operand:DI  4 "register_operand" "")
> +				0)]

Is this right?  Shouldn't it be subreg offset 4 originally?

> +		     UNSPEC_REPLICATE_BYTE))
> +   (use (match_operand:DI                          1 "register_operand" ""))
> +   (clobber (reg:CC CC_REGNUM))]
> +""
> +  [(clobber (match_operand:TI                      0 "register_operand" ""))
> +   (set (mem:BLK (subreg:SI (match_operand:TI      3 "register_operand" "") 4))
> +        (unspec:BLK [(match_operand:SI             2 "shift_count_or_setmem_operand" "")
> +		     (subreg:SI (match_operand:TI  4 "register_operand" "")
> +				12)]
> +		    UNSPEC_REPLICATE_BYTE))
> +   (use (match_operand:TI                          1 "register_operand" ""))
> +   (clobber (reg:CC CC_REGNUM))])

Bye,
Ulrich

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

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

* Re: [PATCH 2/9] S/390: Add disabled insn attribute
  2016-01-14 16:36 ` [PATCH 2/9] S/390: Add disabled insn attribute Andreas Krebbel
@ 2016-02-01 13:45   ` Ulrich Weigand
  2016-02-01 17:14     ` Andreas Krebbel
  0 siblings, 1 reply; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:45 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> With this patch a `disabled' attribute is defined which can be used to
> explicitly disable an alternative.  This comes handy when defining the
> substitutions later and while adding it anyway I've used it for the
> existing cases as well.

> +; Insn attribute with boolean value
> +;  1 to disable an insn alternative
> +;  0 or * for an active insn alternative
> +;  an active alternative can still be disabled due to lacking cpu
> +;  facility support
> +(define_attr "disabled" "" (const_int 0))
> +
>  (define_attr "enabled" ""
> -  (cond [(eq_attr "cpu_facility" "standard")
> +  (cond [(eq_attr "disabled" "1")
> +	 (const_int 0)
> +
> +	 (eq_attr "cpu_facility" "standard")
>  	 (const_int 1)
>  
>           (and (eq_attr "cpu_facility" "ieee")

So I'm wondering what the difference is between this and simply
overriding the default implementation of "enabled" per-insn?

So instead of adding
    (set_attr "disabled" "0,1")])
to an insn, you might simply add instead:
    (set_attr "enabled" "*,0")])

Bye,
Ulrich

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

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

* Re: [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address
  2016-01-14 16:41 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
@ 2016-02-01 13:46   ` Ulrich Weigand
  0 siblings, 0 replies; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 13:46 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:

> 	* config/s390/s390.c (s390_decompose_address): Don't accept SImode
> 	anymore.

Great!  Very nice to finally get rid of this.

Thanks,
Ulrich

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

^ permalink raw reply	[flat|nested] 31+ 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; 31+ 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] 31+ 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; 31+ 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] 31+ 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; 31+ 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] 31+ 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; 31+ 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] 31+ messages in thread

* Re: [PATCH 2/9] S/390: Add disabled insn attribute
  2016-02-01 13:45   ` Ulrich Weigand
@ 2016-02-01 17:14     ` Andreas Krebbel
  2016-02-01 17:22       ` Ulrich Weigand
  0 siblings, 1 reply; 31+ messages in thread
From: Andreas Krebbel @ 2016-02-01 17:14 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On 02/01/2016 02:45 PM, Ulrich Weigand wrote:
> Andreas Krebbel wrote:
> 
>> With this patch a `disabled' attribute is defined which can be used to
>> explicitly disable an alternative.  This comes handy when defining the
>> substitutions later and while adding it anyway I've used it for the
>> existing cases as well.
> 
>> +; Insn attribute with boolean value
>> +;  1 to disable an insn alternative
>> +;  0 or * for an active insn alternative
>> +;  an active alternative can still be disabled due to lacking cpu
>> +;  facility support
>> +(define_attr "disabled" "" (const_int 0))
>> +
>>  (define_attr "enabled" ""
>> -  (cond [(eq_attr "cpu_facility" "standard")
>> +  (cond [(eq_attr "disabled" "1")
>> +	 (const_int 0)
>> +
>> +	 (eq_attr "cpu_facility" "standard")
>>  	 (const_int 1)
>>  
>>           (and (eq_attr "cpu_facility" "ieee")
> 
> So I'm wondering what the difference is between this and simply
> overriding the default implementation of "enabled" per-insn?
> 
> So instead of adding
>     (set_attr "disabled" "0,1")])
> to an insn, you might simply add instead:
>     (set_attr "enabled" "*,0")])
Not sure but wouldn't this mean that the value of the enabled attribute would then depend on the
order of the set_attr for "enabled" and "cpu_facility" since one is defined on the value of the other?!

-Andreas-

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

* Re: [PATCH 2/9] S/390: Add disabled insn attribute
  2016-02-01 17:14     ` Andreas Krebbel
@ 2016-02-01 17:22       ` Ulrich Weigand
  0 siblings, 0 replies; 31+ messages in thread
From: Ulrich Weigand @ 2016-02-01 17:22 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Andreas Krebbel wrote:
> On 02/01/2016 02:45 PM, Ulrich Weigand wrote:
> > So I'm wondering what the difference is between this and simply
> > overriding the default implementation of "enabled" per-insn?
> > 
> > So instead of adding
> >     (set_attr "disabled" "0,1")])
> > to an insn, you might simply add instead:
> >     (set_attr "enabled" "*,0")])
> Not sure but wouldn't this mean that the value of the enabled attribute would then depend on the
> order of the set_attr for "enabled" and "cpu_facility" since one is defined on the value of the other?!

I don't think the order matches; genattrtab seems to first read in all .md
files and only then optimize and then emit definitions of all the get_attr_...
functions.  The eq_attr uses in the "enabled" definition would only be
evaluated at that point.

Bye,
Ulrich

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

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

* Re: [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns.
  2016-02-01 13:35   ` Ulrich Weigand
@ 2016-02-23 14:25     ` Andreas Krebbel
  0 siblings, 0 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:25 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On 02/01/2016 02:35 PM, Ulrich Weigand wrote:
> Andreas Krebbel wrote:
> 
>> +; This is like the addr_style_op substitution above but with a CC clobber.
>> +(define_subst "addr_style_op_cc_subst"
> 
>> +; This is like the masked_op substitution but with a CC clobber.
>> +(define_subst "masked_op_cc_subst"
> 
> A bit unfortunate that these need to be duplicated.  Does the subst always
> have to match the full pattern, or can it match and operate on just one
> element of a PARALLEL?

Yes. The match is always on the full pattern.

-Andreas-


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

* Re: [PATCH 6/9] S/390: Get rid of Y constraint in tabort.
  2016-02-01 13:36   ` Ulrich Weigand
@ 2016-02-23 14:28     ` Andreas Krebbel
  0 siblings, 0 replies; 31+ messages in thread
From: Andreas Krebbel @ 2016-02-23 14:28 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc-patches

On 02/01/2016 02:36 PM, Ulrich Weigand wrote:
> Andreas Krebbel wrote:
> 
>>  (define_insn "*tabort_1"
>> -  [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
>> +  [(unspec_volatile [(match_operand:SI 0 "addrreg_or_constint_operand" "a,n")]
>>  		    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"
>> +  "tabort\t%1(%0)"
> 
> This seems dangerous: const_int_operand may match a constant that does
> not fit into the "J" constraint, which would lead to an abort in reload.

Right. The insn condition should make sure it fits already when matching the insn.

> What is the semantics for the abort code anyway?  It is supposed to be
> automatically truncated or not?

Not to my knowledge.  There seem to be a full 64 bit slot in the transaction diagnostic buffer where
this value will be copied to.

-Andreas-

^ permalink raw reply	[flat|nested] 31+ 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; 31+ 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] 31+ 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; 31+ 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] 31+ 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
@ 2016-02-23 14:33 ` Andreas Krebbel
  2016-02-25 17:14   ` Ulrich Weigand
  0 siblings, 1 reply; 31+ 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] 31+ messages in thread

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

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2016-01-14 16:36 ` [PATCH 2/9] S/390: Add disabled insn attribute Andreas Krebbel
2016-02-01 13:45   ` Ulrich Weigand
2016-02-01 17:14     ` Andreas Krebbel
2016-02-01 17:22       ` Ulrich Weigand
2016-01-14 16:38 ` [PATCH 5/9] S/390: Get rid of Y constraint in arithmetic right shift patterns Andreas Krebbel
2016-02-01 13:35   ` Ulrich Weigand
2016-02-23 14:25     ` Andreas Krebbel
2016-01-14 16:39 ` [PATCH 6/9] S/390: Get rid of Y constraint in tabort Andreas Krebbel
2016-02-01 13:36   ` Ulrich Weigand
2016-02-23 14:28     ` Andreas Krebbel
2016-01-14 16:40 ` [PATCH 7/9] S/390: Get rid of Y constraint in vector.md Andreas Krebbel
2016-02-01 13:38   ` Ulrich Weigand
2016-01-14 16:41 ` [PATCH 9/9] S/390: Disallow SImode in s390_decompose_address Andreas Krebbel
2016-02-01 13:46   ` Ulrich Weigand
2016-01-14 16:44 ` [PATCH 1/9] gensupport: Fix define_subst operand renumbering Andreas Krebbel
2016-01-18 14:46   ` Bernd Schmidt
2016-01-14 19:33 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
2016-02-01 13:43   ` Ulrich Weigand
2016-01-14 19:33 ` [PATCH 4/9] S/390: Get rid of Y constraint in left and logical right shift patterns Andreas Krebbel
2016-01-14 20:44 ` [PATCH 8/9] S/390: Use define_subst for the setmem patterns Andreas Krebbel
2016-01-14 21:06 ` [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 0/9] S/390 rework shift count handling - v2 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-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

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).