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