2014-05-23 Yvan Roux <yvan.roux@linaro.org>
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Jun 2014 11:48:36 +0000 (11:48 +0000)
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Jun 2014 11:48:36 +0000 (11:48 +0000)
       Backport from trunk r209659.
       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.

git-svn-id: svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@211519 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog.linaro
gcc/config/aarch64/aarch64.md

index bc09e72..4b299ee 100644 (file)
@@ -1,5 +1,19 @@
 2014-05-23  Yvan Roux  <yvan.roux@linaro.org>
 
+       Backport from trunk r209659.
+       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-05-23  Yvan Roux  <yvan.roux@linaro.org>
+
        Backport from trunk r209645.
        2014-04-22  Andrew Pinski  <apinski@cavium.com>
 
index 9871864..365192e 100644 (file)
    (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")
   [(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))
    (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"))
   [(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
   [(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"))
   [(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