aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2016-03-01 09:25:23 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2016-03-01 09:25:23 +0000
commit674a959cd5eac469b63f9e64ab5d11890750451f (patch)
tree613e9ea3bc2d6b2af78ce58229a8e86f7ba11890 /gcc
parenteae48192e4c70b47a2066650a56b12c9198b9b47 (diff)
downloadgcc-674a959cd5eac469b63f9e64ab5d11890750451f.zip
gcc-674a959cd5eac469b63f9e64ab5d11890750451f.tar.gz
gcc-674a959cd5eac469b63f9e64ab5d11890750451f.tar.bz2
S/390: Get rid of Y constraint in vector.md.
This finally removes the Y constraint from the vector patterns while folding some of them using a code iterator. gcc/ChangeLog: 2016-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * config/s390/subst.md (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. From-SVN: r233847
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/s390/subst.md13
-rw-r--r--gcc/config/s390/vector.md125
3 files changed, 100 insertions, 59 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1699e1c..79756c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,26 @@
2016-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+ * config/s390/subst.md (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.
+
+2016-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
* config/s390/s390.md ("*tabort_1"): Change predicate to
nonmemory_operand. Add a second alternative to cover
register as well as const int operands.
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 3becf20..8a1b814 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -20,19 +20,20 @@
;; <http://www.gnu.org/licenses/>.
(define_code_iterator SUBST [rotate ashift lshiftrt 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..5b3cdaf 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -307,47 +307,80 @@
; 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 "nonmemory_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")
+ (unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
+ (match_operand:SI 2 "nonmemory_operand" "an, I,I")
+ (match_operand:V 3 "register_operand" "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
vle<bhfgq>\t%v0,%1,%2
vlei<bhfgq>\t%v0,%1,%2"
[(set_attr "op_type" "VRS,VRX,VRI")])
-; 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")
+(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,%Y4(%2)"
+ [(set_attr "op_type" "VRS")])
+
; 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 "nonmemory_operand" "")]
UNSPEC_VEC_EXTRACT))]
- "TARGET_VX"
+ "TARGET_VX")
+
+(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 "nonmemory_operand" "an, 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,%Y2
vste<bhfgq>\t%v1,%0,%2"
[(set_attr "op_type" "VRS,VRX")])
+(define_insn "*vec_extract<mode>_plus"
+ [(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d")
+ (unspec:<non_vec> [(match_operand:V 1 "register_operand" "v")
+ (plus:SI (match_operand:SI 2 "nonmemory_operand" "a")
+ (match_operand:SI 3 "const_int_operand" "n"))]
+ UNSPEC_VEC_EXTRACT))]
+ "TARGET_VX"
+ "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
+ [(set_attr "op_type" "VRS")])
+
(define_expand "vec_init<V_HW:mode>"
[(match_operand:V_HW 0 "register_operand" "")
(match_operand:V_HW 1 "nonmemory_operand" "")]
@@ -667,17 +700,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,36 +712,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 "nonmemory_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")))]
+(define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
+ [(set (match_operand:VI 0 "register_operand" "=v")
+ (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v")
+ (match_operand:SI 2 "nonmemory_operand" "an")))]
"TARGET_VX"
- "vesrl<bhfgq>\t%v0,%v1,%Y2"
+ "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
[(set_attr "op_type" "VRS")])
-
; Shift each element by corresponding vector element
; veslvb, veslvh, veslvf, veslvg