* config/aarch64/aarch64.md (multi3): New expander. (madd<GPI>): Remove leading * from name. --- gcc/config/aarch64/aarch64.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 0b3943d..0f76cd1 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1968,7 +1968,7 @@ [(set_attr "type" "mul")] ) -(define_insn "*madd<mode>" +(define_insn "madd<mode>" [(set (match_operand:GPI 0 "register_operand" "=r") (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand:GPI 2 "register_operand" "r")) @@ -2095,6 +2095,31 @@ DONE; }) +;; The default expansion of multi3 using umuldi3_highpart will perform +;; the additions in an order that fails to combine into two madd insns. +(define_expand "multi3" + [(set (match_operand:TI 0 "register_operand") + (mult:TI (match_operand:TI 1 "register_operand") + (match_operand:TI 2 "register_operand")))] + "" +{ + rtx l0 = gen_reg_rtx (DImode); + rtx l1 = gen_lowpart (DImode, operands[1]); + rtx l2 = gen_lowpart (DImode, operands[2]); + rtx h0 = gen_reg_rtx (DImode); + rtx h1 = gen_highpart (DImode, operands[1]); + rtx h2 = gen_highpart (DImode, operands[2]); + + emit_insn (gen_muldi3 (l0, l1, l2)); + emit_insn (gen_umuldi3_highpart (h0, l1, l2)); + emit_insn (gen_madddi (h0, h1, l2, h0)); + emit_insn (gen_madddi (h0, l1, h2, h0)); + + emit_move_insn (gen_lowpart (DImode, operands[0]), l0); + emit_move_insn (gen_highpart (DImode, operands[0]), h0); + DONE; +}) + (define_insn "<su>muldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=r") (truncate:DI -- 1.8.4.2