diff options
author | Julian Brown <julian@codesourcery.com> | 2021-06-17 11:02:55 -0700 |
---|---|---|
committer | Julian Brown <julian@codesourcery.com> | 2021-06-29 08:19:56 -0700 |
commit | 53b1d1691857a1d3e28566d05bb434fa555c4e8a (patch) | |
tree | 72ff8136806e14e385483cc485a0d43193268b55 | |
parent | 5c127c4cac308429cba483a2ac4e175c2ab26165 (diff) | |
download | gcc-53b1d1691857a1d3e28566d05bb434fa555c4e8a.zip gcc-53b1d1691857a1d3e28566d05bb434fa555c4e8a.tar.gz gcc-53b1d1691857a1d3e28566d05bb434fa555c4e8a.tar.bz2 |
amdgcn: Add [us]mulsi3_highpart SGPR alternatives
This patch splits the <su>mulsi3_highpart pattern into an expander and
register/immediate alternatives (to avoid meaningless sign/zero_extends on
constants), and adds alternatives for SGPR high-part multiply instructions
on GCN5+.
2021-06-29 Julian Brown <julian@codesourcery.com>
gcc/
* config/gcn/gcn.md (<su>mulsi3_highpart): Change to expander.
(<su>mulsi3_highpart_reg, <su>mulsi3_highpart_imm): New patterns.
-rw-r--r-- | gcc/config/gcn/gcn.md | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index cca4552..d1d4998 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -1394,20 +1394,68 @@ (define_code_attr iu [(sign_extend "i") (zero_extend "u")]) (define_code_attr e [(sign_extend "e") (zero_extend "")]) -(define_insn "<su>mulsi3_highpart" - [(set (match_operand:SI 0 "register_operand" "= v") +(define_expand "<su>mulsi3_highpart" + [(set (match_operand:SI 0 "register_operand" "") (truncate:SI (lshiftrt:DI (mult:DI (any_extend:DI - (match_operand:SI 1 "register_operand" "% v")) + (match_operand:SI 1 "register_operand" "")) (any_extend:DI - (match_operand:SI 2 "register_operand" "vSv"))) + (match_operand:SI 2 "gcn_alu_operand" ""))) (const_int 32))))] "" - "v_mul_hi<sgnsuffix>0\t%0, %2, %1" - [(set_attr "type" "vop3a") - (set_attr "length" "8")]) +{ + if (can_create_pseudo_p () + && !TARGET_GCN5 + && !gcn_inline_immediate_operand (operands[2], SImode)) + operands[2] = force_reg (SImode, operands[2]); + + if (REG_P (operands[2])) + emit_insn (gen_<su>mulsi3_highpart_reg (operands[0], operands[1], + operands[2])); + else + emit_insn (gen_<su>mulsi3_highpart_imm (operands[0], operands[1], + operands[2])); + + DONE; +}) + +(define_insn "<su>mulsi3_highpart_reg" + [(set (match_operand:SI 0 "register_operand" "=Sg, v") + (truncate:SI + (lshiftrt:DI + (mult:DI + (any_extend:DI + (match_operand:SI 1 "register_operand" "%Sg, v")) + (any_extend:DI + (match_operand:SI 2 "register_operand" "Sg,vSv"))) + (const_int 32))))] + "" + "@ + s_mul_hi<sgnsuffix>0\t%0, %1, %2 + v_mul_hi<sgnsuffix>0\t%0, %2, %1" + [(set_attr "type" "sop2,vop3a") + (set_attr "length" "4,8") + (set_attr "gcn_version" "gcn5,*")]) + +(define_insn "<su>mulsi3_highpart_imm" + [(set (match_operand:SI 0 "register_operand" "=Sg,Sg,v") + (truncate:SI + (lshiftrt:DI + (mult:DI + (any_extend:DI + (match_operand:SI 1 "register_operand" "Sg,Sg,v")) + (match_operand:DI 2 "gcn_32bit_immediate_operand" "A, B,A")) + (const_int 32))))] + "TARGET_GCN5 || gcn_inline_immediate_operand (operands[2], SImode)" + "@ + s_mul_hi<sgnsuffix>0\t%0, %1, %2 + s_mul_hi<sgnsuffix>0\t%0, %1, %2 + v_mul_hi<sgnsuffix>0\t%0, %2, %1" + [(set_attr "type" "sop2,sop2,vop3a") + (set_attr "length" "4,8,8") + (set_attr "gcn_version" "gcn5,gcn5,*")]) (define_insn "<u>mulhisi3" [(set (match_operand:SI 0 "register_operand" "=v") |