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
This commit is contained in:
parent
eae48192e4
commit
674a959cd5
@ -1,3 +1,24 @@
|
||||
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
|
||||
|
@ -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")
|
||||
|
@ -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")])
|
||||
|
||||
; 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
|
||||
(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")])
|
||||
|
||||
; 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
|
||||
|
Loading…
Reference in New Issue
Block a user