Some implementations have a higher cost for the csel insn
(and its specializations) than they do for adc/sbc.

        * config/aarch64/aarch64.md (*cstore<ALLI>_carry): New.
        (*cstoresi_carry_uxtw): New.
        (*cstore<ALLI>_borrow): New.
        (*cstoresi_borrow_uxtw): New.
        (*csinc2<GPI>_carry): New.
---
 gcc/testsuite/gcc.target/aarch64/asm-flag-1.c |  3 +-
 gcc/config/aarch64/aarch64.md                 | 51 ++++++++++++++++++-
 2 files changed, 51 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c 
b/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
index 49901e59c38..b6c21fee306 100644
--- a/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/asm-flag-1.c
@@ -21,7 +21,8 @@ void f(char *out)
 
 /* { dg-final { scan-assembler "cset.*, ne" } } */
 /* { dg-final { scan-assembler "cset.*, eq" } } */
-/* { dg-final { scan-assembler "cset.*, cs" } } */
+/* { dg-final { scan-assembler-not "cset.*, cs" } } */
+/* { dg-final { scan-assembler "adc.*, .zr, .zr" } } */
 /* { dg-final { scan-assembler "cset.*, cc" } } */
 /* { dg-final { scan-assembler "cset.*, mi" } } */
 /* { dg-final { scan-assembler "cset.*, pl" } } */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index e65f46f0f74..d266a1edd64 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4086,6 +4086,15 @@
   "
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than adc.
+(define_insn "*cstore<mode>_carry"
+  [(set (match_operand:ALLI 0 "register_operand" "=r")
+       (match_operand:ALLI 1 "aarch64_carry_operation"))]
+  ""
+  "adc\\t%<w>0, <w>zr, <w>zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "aarch64_cstore<mode>"
   [(set (match_operand:ALLI 0 "register_operand" "=r")
        (match_operator:ALLI 1 "aarch64_comparison_operator_mode"
@@ -4130,7 +4139,16 @@
   [(set_attr "type" "csel")]
 )
 
-;; zero_extend version of the above
+;; zero_extend versions of the above
+
+(define_insn "*cstoresi_carry_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI (match_operand:SI 1 "aarch64_carry_operation")))]
+  ""
+  "adc\\t%w0, wzr, wzr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*cstoresi_insn_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
@@ -4141,6 +4159,15 @@
   [(set_attr "type" "csel")]
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than sbc.
+(define_insn "*cstore<mode>_borrow"
+  [(set (match_operand:ALLI 0 "register_operand" "=r")
+       (neg:ALLI (match_operand:ALLI 1 "aarch64_borrow_operation")))]
+  ""
+  "sbc\\t%<w>0, <w>zr, <w>zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "cstore<mode>_neg"
   [(set (match_operand:ALLI 0 "register_operand" "=r")
        (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator_mode"
@@ -4150,7 +4177,17 @@
   [(set_attr "type" "csel")]
 )
 
-;; zero_extend version of the above
+;; zero_extend versions of the above
+
+(define_insn "*cstoresi_borrow_uxtw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (neg:SI (match_operand:SI 1 "aarch64_borrow_operation"))))]
+  ""
+  "sbc\\t%w0, wzr, wzr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*cstoresi_neg_uxtw"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI
@@ -4353,6 +4390,16 @@
   [(set_attr "type" "crc")]
 )
 
+;; On some implementations (e.g. tx1) csel is more expensive than adc.
+(define_insn "*csinc2<mode>_carry"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (plus:GPI (match_operand 2 "aarch64_carry_operation")
+                  (match_operand:GPI 1 "register_operand" "r")))]
+  ""
+  "adc\\t%<w>0, %<w>1, <w>zr"
+  [(set_attr "type" "adc_reg")]
+)
+
 (define_insn "*csinc2<mode>_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
-- 
2.20.1

Reply via email to