This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 7/9] S/390: Get rid of Y constraint in vector.md.
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 23 Feb 2016 15:33:22 +0100
- Subject: [PATCH 7/9] S/390: Get rid of Y constraint in vector.md.
- Authentication-results: sourceware.org; auth=none
- References: <1456238004-21150-1-git-send-email-krebbel at linux dot vnet dot ibm dot com>
This finally removes the Y constraint from the vector patterns while
folding some of them using a code iterator.
gcc/ChangeLog:
* config/s390/subst.md (SUBST mode iterator): Add ashiftrt.
(DSI_VI): New mode iterator.
("addr_style_op_subst"): Use DSI_VI instead of DSI.
* config/s390/vector.md ("vec_set<mode>"): Move expander before
the insn definition.
("*vec_set<mode>"): Change predicate and add alternative to
support only either register or const_int operands as element
selector.
("*vec_set<mode>_plus"): New pattern to support reg + const_int
operands.
("vec_extract<mode>"): New expander.
("*vec_extract<mode>"): New insn definition supporting reg and
const_int element selectors.
("*vec_extract<mode>_plus"): New insn definition supporting
reg+const_int element selectors.
("rotl<mode>3", "ashl<mode>3", "ashr<mode>3"): Merge into the
following expander+insn definition.
("<vec_shifts_name><mode>3"): New expander.
("*<vec_shifts_name><mode>3<addr_style_op>"): New insn definition.
---
gcc/config/s390/subst.md | 15 ++---
gcc/config/s390/vector.md | 138 +++++++++++++++++++++++++++-------------------
2 files changed, 89 insertions(+), 64 deletions(-)
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 1e2b1ba..08704c2 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -19,20 +19,21 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
-(define_code_iterator SUBST [ashift lshiftrt rotate])
+(define_code_iterator SUBST [ashift lshiftrt rotate ashiftrt])
+(define_mode_iterator DSI_VI [SI DI V2QI V4QI V8QI V16QI V2HI V4HI V8HI V2SI V4SI V2DI])
; This expands an register/immediate operand to a register+immediate
; operand to draw advantage of the address style operand format
; providing a addition for free.
(define_subst "addr_style_op_subst"
- [(set (match_operand:DSI 0 "" "")
- (SUBST:DSI (match_operand:DSI 1 "" "")
- (match_operand:SI 2 "" "")))]
+ [(set (match_operand:DSI_VI 0 "" "")
+ (SUBST:DSI_VI (match_operand:DSI_VI 1 "" "")
+ (match_operand:SI 2 "" "")))]
""
[(set (match_dup 0)
- (SUBST:DSI (match_dup 1)
- (plus:SI (match_operand:SI 2 "register_operand" "a")
- (match_operand 3 "const_int_operand" "n"))))])
+ (SUBST:DSI_VI (match_dup 1)
+ (plus:SI (match_operand:SI 2 "register_operand" "a")
+ (match_operand 3 "const_int_operand" "n"))))])
; Use this in the insn name.
(define_subst_attr "addr_style_op" "addr_style_op_subst" "" "_plus")
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index cc3287c..a1b208c 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -307,44 +307,81 @@
; vec_store_lanes?
+; vec_set is supposed to *modify* an existing vector so operand 0 is
+; duplicated as input operand.
+(define_expand "vec_set<mode>"
+ [(set (match_operand:V 0 "register_operand" "")
+ (unspec:V [(match_operand:<non_vec> 1 "general_operand" "")
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "")
+ (match_dup 0)]
+ UNSPEC_VEC_SET))]
+ "TARGET_VX")
+
; FIXME: Support also vector mode operands for 1
; FIXME: A target memory operand seems to be useful otherwise we end
; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
; that itself?
(define_insn "*vec_set<mode>"
- [(set (match_operand:V 0 "register_operand" "=v, v,v")
- (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "Y, I,I")
- (match_operand:V 3 "register_operand" "0, 0,0")]
+ [(set (match_operand:V 0 "register_operand" "=v,v,v,v")
+ (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,d,QR,K")
+ (match_operand:SI 2 "nonmemory_operand" "a,n,I,I")
+ (match_operand:V 3 "register_operand" "0,0,0,0")]
UNSPEC_VEC_SET))]
- "TARGET_VX"
+ "TARGET_VX
+ && (!CONST_INT_P (operands[2])
+ || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
"@
- vlvg<bhfgq>\t%v0,%1,%Y2
+ vlvg<bhfgq>\t%v0,%1,0(%2)
+ vlvg<bhfgq>\t%v0,%1,%2
vle<bhfgq>\t%v0,%1,%2
vlei<bhfgq>\t%v0,%1,%2"
- [(set_attr "op_type" "VRS,VRX,VRI")])
+ [(set_attr "op_type" "VRS,VRS,VRX,VRI")])
+
+(define_insn "*vec_set<mode>_plus"
+ [(set (match_operand:V 0 "register_operand" "=v")
+ (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d")
+ (plus:SI (match_operand:SI 2 "register_operand" "a")
+ (match_operand:SI 4 "const_int_operand" "n"))
+ (match_operand:V 3 "register_operand" "0")]
+ UNSPEC_VEC_SET))]
+ "TARGET_VX"
+ "vlvg<bhfgq>\t%v0,%1,%4(%2)"
+ [(set_attr "op_type" "VRS")])
-; vec_set is supposed to *modify* an existing vector so operand 0 is
-; duplicated as input operand.
-(define_expand "vec_set<mode>"
- [(set (match_operand:V 0 "register_operand" "")
- (unspec:V [(match_operand:<non_vec> 1 "general_operand" "")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "")
- (match_dup 0)]
- UNSPEC_VEC_SET))]
- "TARGET_VX")
; FIXME: Support also vector mode operands for 0
; FIXME: This should be (vec_select ..) or something but it does only allow constant selectors :(
; This is used via RTL standard name as well as for expanding the builtin
-(define_insn "vec_extract<mode>"
- [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
- (unspec:<non_vec> [(match_operand:V 1 "register_operand" " v, v")
- (match_operand:SI 2 "shift_count_or_setmem_operand" " Y, I")]
+(define_expand "vec_extract<mode>"
+ [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "")
+ (unspec:<non_vec> [(match_operand:V 1 "register_operand" "")
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "")]
UNSPEC_VEC_EXTRACT))]
+ "TARGET_VX")
+
+(define_insn "*vec_extract<mode>"
+ [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,d,QR")
+ (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v, v")
+ (match_operand:SI 2 "nonmemory_operand" "a,n, I")]
+ UNSPEC_VEC_EXTRACT))]
+ "TARGET_VX
+ && (!CONST_INT_P (operands[2])
+ || UINTVAL (operands[2]) < GET_MODE_NUNITS (<V:MODE>mode))"
+ "@
+ vlgv<bhfgq>\t%0,%v1,0(%2)
+ vlgv<bhfgq>\t%0,%v1,%2
+ vste<bhfgq>\t%v1,%0,%2"
+ [(set_attr "op_type" "VRS,VRS,VRX")])
+
+(define_insn "*vec_extract<mode>_plus"
+ [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
+ (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v, v")
+ (plus:SI (match_operand:SI 2 "nonmemory_operand" "a, I")
+ (match_operand:SI 3 "const_int_operand" "n, I"))]
+ UNSPEC_VEC_EXTRACT))]
"TARGET_VX"
"@
- vlgv<bhfgq>\t%0,%v1,%Y2
+ vlgv<bhfgq>\t%0,%v1,%3(%2)
vste<bhfgq>\t%v1,%0,%2"
[(set_attr "op_type" "VRS,VRX")])
@@ -667,17 +704,6 @@
[(set_attr "op_type" "VRR")])
-; Vector rotate instructions
-
-; Each vector element rotated by a scalar
-; verllb, verllh, verllf, verllg
-(define_insn "rotl<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (rotate:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
- "TARGET_VX"
- "verll<bhfgq>\t%v0,%v1,%Y2"
- [(set_attr "op_type" "VRS")])
; Each vector element rotated by the corresponding vector element
; verllvb, verllvh, verllvf, verllvg
@@ -690,35 +716,33 @@
[(set_attr "op_type" "VRR")])
-; Shift each element by scalar value
+; Vector rotate and shift by scalar instructions
-; veslb, veslh, veslf, veslg
-(define_insn "ashl<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (ashift:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
- "TARGET_VX"
- "vesl<bhfgq>\t%v0,%v1,%Y2"
- [(set_attr "op_type" "VRS")])
+(define_code_iterator VEC_SHIFTS [ashift ashiftrt lshiftrt rotate])
+(define_code_attr vec_shifts_name [(ashift "ashl") (ashiftrt "ashr")
+ (lshiftrt "lshr") (rotate "rotl")])
+(define_code_attr vec_shifts_mnem [(ashift "vesl") (ashiftrt "vesra")
+ (lshiftrt "vesrl") (rotate "verll")])
-; vesrab, vesrah, vesraf, vesrag
-(define_insn "ashr<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
- "TARGET_VX"
- "vesra<bhfgq>\t%v0,%v1,%Y2"
- [(set_attr "op_type" "VRS")])
+; Each vector element rotated by a scalar
+(define_expand "<vec_shifts_name><mode>3"
+ [(set (match_operand:VI 0 "register_operand" "")
+ (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
+ (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
+ "TARGET_VX")
+; verllb, verllh, verllf, verllg
+; veslb, veslh, veslf, veslg
+; vesrab, vesrah, vesraf, vesrag
; vesrlb, vesrlh, vesrlf, vesrlg
-(define_insn "lshr<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
- "TARGET_VX"
- "vesrl<bhfgq>\t%v0,%v1,%Y2"
- [(set_attr "op_type" "VRS")])
-
+(define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
+ [(set (match_operand:VI 0 "register_operand" "=v,v")
+ (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v,v")
+ (match_operand:SI 2 "nonmemory_operand" "a,n")))]
+ "TARGET_VX"
+ "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
+ [(set_attr "enabled" "*,<addr_style_op_enabled>")
+ (set_attr "op_type" "VRS")])
; Shift each element by corresponding vector element
--
1.9.1