diff options
author | Richard Henderson <rth@redhat.com> | 2014-04-22 13:31:29 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2014-04-22 13:31:29 -0700 |
commit | 2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3 (patch) | |
tree | 84bee9aaafc38cd54f126b2eef638988f1bcc8cc | |
parent | b1dc55ad71a5b75889e1675b01bfa13d494797eb (diff) | |
download | gcc-2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3.zip gcc-2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3.tar.gz gcc-2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 89 |
2 files changed, 95 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e63f9d..8f84b6a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f0d1d18..ee32b6c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -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]))); + + 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" +(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 |