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

Reply via email to