aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2014-04-22 13:31:29 -0700
committerRichard Henderson <rth@gcc.gnu.org>2014-04-22 13:31:29 -0700
commit2195867f1d6cdc9e8d36aeeefc3c0f000bccbda3 (patch)
tree84bee9aaafc38cd54f126b2eef638988f1bcc8cc /gcc
parentb1dc55ad71a5b75889e1675b01bfa13d494797eb (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/aarch64/aarch64.md89
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