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

Reply via email to