AArch64 add, sub, mul in TImode

* config/aarch64/aarch64.md (multi3): New expander.
	(madd<GPI>): Remove leading * from name.

	* config/aarch64/aarch64.md (<su_optab>mulditi3): New expander.

	* config/aarch64/aarch64 (addti3, subti3): New expanders.
	(add<GPI>3_compare0): Remove leading * from name.
	(add<GPI>3_carryin): Likewise.
	(sub<GPI>3_compare0): Likewise.
	(sub<GPI>3_carryin): Likewise.

From-SVN: r209659
This commit is contained in:
Richard Henderson 2014-04-22 13:31:29 -07:00 committed by Richard Henderson
parent b1dc55ad71
commit 2195867f1d
2 changed files with 95 additions and 5 deletions

View File

@ -1,3 +1,14 @@
2014-04-22 Richard Henderson <rth@redhat.com>
* config/aarch64/aarch64 (addti3, subti3): New expanders.
(add<GPI>3_compare0): Remove leading * from name.
(add<GPI>3_carryin): Likewise.
(sub<GPI>3_compare0): Likewise.
(sub<GPI>3_carryin): Likewise.
(<su_optab>mulditi3): New expander.
(multi3): New expander.
(madd<GPI>): Remove leading * from name.
2014-04-22 Martin Jambor <mjambor@suse.cz>
* cgraphclones.c (cgraph_function_versioning): Copy

View File

@ -1106,7 +1106,26 @@
(set_attr "simd" "*,*,*,yes")]
)
(define_insn "*add<mode>3_compare0"
(define_expand "addti3"
[(set (match_operand:TI 0 "register_operand" "")
(plus:TI (match_operand:TI 1 "register_operand" "")
(match_operand:TI 2 "register_operand" "")))]
""
{
rtx low = gen_reg_rtx (DImode);
emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
gen_lowpart (DImode, operands[2])));
rtx high = gen_reg_rtx (DImode);
emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
gen_highpart (DImode, operands[2])));
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
emit_move_insn (gen_highpart (DImode, operands[0]), high);
DONE;
})
(define_insn "add<mode>3_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ
(plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
@ -1390,7 +1409,7 @@
[(set_attr "type" "alu_ext")]
)
(define_insn "*add<mode>3_carryin"
(define_insn "add<mode>3_carryin"
[(set
(match_operand:GPI 0 "register_operand" "=r")
(plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
@ -1558,8 +1577,26 @@
(set_attr "simd" "*,yes")]
)
(define_expand "subti3"
[(set (match_operand:TI 0 "register_operand" "")
(minus:TI (match_operand:TI 1 "register_operand" "")
(match_operand:TI 2 "register_operand" "")))]
""
{
rtx low = gen_reg_rtx (DImode);
emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
gen_lowpart (DImode, operands[2])));
(define_insn "*sub<mode>3_compare0"
rtx high = gen_reg_rtx (DImode);
emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
gen_highpart (DImode, operands[2])));
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
emit_move_insn (gen_highpart (DImode, operands[0]), high);
DONE;
})
(define_insn "sub<mode>3_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
(match_operand:GPI 2 "register_operand" "r"))
@ -1706,7 +1743,7 @@
[(set_attr "type" "alu_ext")]
)
(define_insn "*sub<mode>3_carryin"
(define_insn "sub<mode>3_carryin"
[(set
(match_operand:GPI 0 "register_operand" "=r")
(minus:GPI (minus:GPI
@ -1935,7 +1972,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"))
@ -2045,6 +2082,48 @@
[(set_attr "type" "<su>mull")]
)
(define_expand "<su_optab>mulditi3"
[(set (match_operand:TI 0 "register_operand")
(mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
(ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
""
{
rtx low = gen_reg_rtx (DImode);
emit_insn (gen_muldi3 (low, operands[1], operands[2]));
rtx high = gen_reg_rtx (DImode);
emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
emit_move_insn (gen_highpart (DImode, operands[0]), high);
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