From 674a959cd5eac469b63f9e64ab5d11890750451f Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Tue, 1 Mar 2016 09:25:23 +0000 Subject: [PATCH] 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 * 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"): Move expander before the insn definition. ("*vec_set"): Change predicate and add alternative to support only either register or const_int operands as element selector. ("*vec_set_plus"): New pattern to support reg + const_int operands. ("vec_extract"): New expander. ("*vec_extract"): New insn definition supporting reg and const_int element selectors. ("*vec_extract_plus"): New insn definition supporting reg+const_int element selectors. ("rotl3", "ashl3", "ashr3"): Merge into the following expander+insn definition. ("3"): New expander. ("*3"): New insn definition. From-SVN: r233847 --- gcc/ChangeLog | 21 ++++++++ gcc/config/s390/subst.md | 13 ++--- gcc/config/s390/vector.md | 125 ++++++++++++++++++++++++++-------------------- 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 + * 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"): Move expander before + the insn definition. + ("*vec_set"): Change predicate and add alternative to + support only either register or const_int operands as element + selector. + ("*vec_set_plus"): New pattern to support reg + const_int + operands. + ("vec_extract"): New expander. + ("*vec_extract"): New insn definition supporting reg and + const_int element selectors. + ("*vec_extract_plus"): New insn definition supporting + reg+const_int element selectors. + ("rotl3", "ashl3", "ashr3"): Merge into the + following expander+insn definition. + ("3"): New expander. + ("*3"): New insn definition. + +2016-03-01 Andreas Krebbel + * 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 @@ ;; . (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" + [(set (match_operand:V 0 "register_operand" "") + (unspec:V [(match_operand: 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" - [(set (match_operand:V 0 "register_operand" "=v, v,v") - (unspec:V [(match_operand: 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: 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 (mode))" "@ vlvg\t%v0,%1,%Y2 vle\t%v0,%1,%2 vlei\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" - [(set (match_operand:V 0 "register_operand" "") - (unspec:V [(match_operand: 1 "general_operand" "") - (match_operand:SI 2 "shift_count_or_setmem_operand" "") - (match_dup 0)] - UNSPEC_VEC_SET))] - "TARGET_VX") +(define_insn "*vec_set_plus" + [(set (match_operand:V 0 "register_operand" "=v") + (unspec:V [(match_operand: 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\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" - [(set (match_operand: 0 "nonimmediate_operand" "=d,QR") - (unspec: [(match_operand:V 1 "register_operand" " v, v") - (match_operand:SI 2 "shift_count_or_setmem_operand" " Y, I")] +(define_expand "vec_extract" + [(set (match_operand: 0 "nonimmediate_operand" "") + (unspec: [(match_operand:V 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")] UNSPEC_VEC_EXTRACT))] - "TARGET_VX" + "TARGET_VX") + +(define_insn "*vec_extract" + [(set (match_operand: 0 "nonimmediate_operand" "=d,QR") + (unspec: [(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 (mode))" "@ vlgv\t%0,%v1,%Y2 vste\t%v1,%0,%2" [(set_attr "op_type" "VRS,VRX")]) +(define_insn "*vec_extract_plus" + [(set (match_operand: 0 "nonimmediate_operand" "=d") + (unspec: [(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\t%0,%v1,%Y3(%2)" + [(set_attr "op_type" "VRS")]) + (define_expand "vec_init" [(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 "rotl3" - [(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\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 "ashl3" - [(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\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 "ashr3" - [(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\t%v0,%v1,%Y2" - [(set_attr "op_type" "VRS")]) +; Each vector element rotated by a scalar +(define_expand "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 "lshr3" - [(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 "*3" + [(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\t%v0,%v1,%Y2" + "\t%v0,%v1,%Y2" [(set_attr "op_type" "VRS")]) - ; Shift each element by corresponding vector element ; veslvb, veslvh, veslvf, veslvg -- 2.7.4