S/390: Get rid of Y constraint in arithmetic right shift
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Tue, 1 Mar 2016 09:23:41 +0000 (09:23 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Tue, 1 Mar 2016 09:23:41 +0000 (09:23 +0000)
 patterns.

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-03-01  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.
Add ashiftrt to SUBST iterator.

From-SVN: r233845

gcc/ChangeLog
gcc/config/s390/s390.md
gcc/config/s390/subst.md

index aa829f0eb2f449808979386f24562a96a0ee50d8..3178ba110e54f7c5c366d381be7221b9612dfaab 100644 (file)
@@ -1,3 +1,21 @@
+2016-03-01  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.
+       Add ashiftrt to SUBST iterator.
+
 2016-03-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
 
        * config/s390/s390.md ("<shift><mode>3"): Change predicate of
index 771d1e91c22c22ce88bcc089b4812d1707b0605c..dd91383b11be4cafa64324bb2fa08419668b3450 100644 (file)
   [(parallel
     [(set (match_operand:DSI 0 "register_operand" "")
           (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
-                        (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
+                        (match_operand:SI 2 "nonmemory_operand" "")))
      (clobber (reg:CC CC_REGNUM))])]
   ""
   "")
 
-(define_insn "*ashrdi3_cc_31"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
-                 (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_cconly_31"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
-                 (const_int 0)))
-   (clobber (match_scratch:DI 0 "=d"))]
-  "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-(define_insn "*ashrdi3_31"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
-                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
+; FIXME: The number of alternatives is doubled here to match the fix
+; number of 2 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")
+        (ashiftrt:DI (match_operand:DI 1 "register_operand"   "0, 0")
+                     (match_operand:SI 2 "nonmemory_operand" "an,an")))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_ZARCH"
-  "srda\t%0,%Y2"
-  [(set_attr "op_type"  "RS")
-   (set_attr "atype"    "reg")])
-
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cc"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
-                 (const_int 0)))
-   (set (match_operand:GPR 0 "register_operand"                                   "=d,d")
-        (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
-  "s390_match_ccmode(insn, CCSmode)"
   "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
+   srda\t%0,<addr_style_op_cc_ops>
+   srda\t%0,<addr_style_op_cc_ops>"
+  [(set_attr "op_type" "RS")
+   (set_attr "atype"   "reg")])
 
-; sra, srag, srak
-(define_insn "*ashr<mode>3_cconly"
-  [(set (reg CC_REGNUM)
-        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
-                 (const_int 0)))
-   (clobber (match_scratch:GPR 0                                                  "=d,d"))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "@
-   sra<g>\t%0,<1>%Y2
-   sra<gk>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
-   (set_attr "cpu_facility" "*,z196")
-   (set_attr "z10prop" "z10_super_E1,*")])
 
 ; sra, srag
-(define_insn "*ashr<mode>3"
-  [(set (match_operand:GPR 0 "register_operand"                          "=d,d")
-        (ashiftrt:GPR (match_operand:GPR 1 "register_operand"          "<d0>,d")
-                      (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
+(define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
+  [(set (match_operand:GPR 0 "register_operand"                 "=d, d")
+        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
+                      (match_operand:SI 2 "nonmemory_operand"   "an,an")))
    (clobber (reg:CC CC_REGNUM))]
   ""
   "@
-   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,*")])
-
-
-; 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"
+   sra<g>\t%0,<1><addr_style_op_cc_ops>
+   sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
   [(set_attr "op_type"  "RS<E>,RSY")
-   (set_attr "atype"    "reg,reg")
+   (set_attr "atype"    "reg")
    (set_attr "cpu_facility" "*,z196")
    (set_attr "z10prop" "z10_super_E1,*")])
 
index 907676af3969175f7fd27aee35e9327ca0524ab0..3becf2099b6720b721f5624a22f44b4a6087dcec 100644 (file)
@@ -19,7 +19,7 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
-(define_code_iterator SUBST [rotate ashift lshiftrt])
+(define_code_iterator SUBST [rotate ashift lshiftrt ashiftrt])
 
 ; This expands an register/immediate operand to a register+immediate
 ; operand to draw advantage of the address style operand format
 ; 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_ops" "addr_style_op_cc_subst" "%Y2" "%Y3(%2)")
+
+
+; 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"))])
+
+(define_subst_attr "cconly" "cconly_subst" "" "_cconly")