From patchwork Fri Sep 14 15:26:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [AArch64] Implement ffs standard pattern Date: Fri, 14 Sep 2012 05:26:12 -0000 From: Ian Bolton X-Patchwork-Id: 183944 Message-Id: <000001cd928d$45eb3960$d1c1ac20$@bolton@arm.com> To: I've implemented the standard pattern ffs, which leads to __builtin_ffs being generated with 4 instructions instead of 5 instructions. Regression tests and my new test pass. OK to commit? Cheers, Ian 2012-09-14 Ian Bolton gcc/ * config/aarch64/aarch64.md (csinc3): Make it into a named pattern. * config/aarch64/aarch64.md (ffs2): New pattern. testsuite/ * gcc.target/aarch64/ffs.c: New test. diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 5278957..dfdba42 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -2021,7 +2021,7 @@ [(set_attr "v8type" "csel") (set_attr "mode" "")]) -(define_insn "*csinc3_insn" +(define_insn "csinc3_insn" [(set (match_operand:GPI 0 "register_operand" "=r") (if_then_else:GPI (match_operator:GPI 1 "aarch64_comparison_operator" @@ -2157,6 +2157,21 @@ } ) +(define_expand "ffs2" + [(match_operand:GPI 0 "register_operand") + (match_operand:GPI 1 "register_operand")] + "" + { + rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx); + rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx); + + emit_insn (gen_rbit2 (operands[0], operands[1])); + emit_insn (gen_clz2 (operands[0], operands[0])); + emit_insn (gen_csinc3_insn (operands[0], x, ccreg, operands[0], const0_rtx)); + DONE; + } +) + (define_insn "*and3nr_compare0" [(set (reg:CC CC_REGNUM) (compare:CC diff --git a/gcc/testsuite/gcc.target/aarch64/ffs.c b/gcc/testsuite/gcc.target/aarch64/ffs.c new file mode 100644 index 0000000..a344761 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ffs.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned int functest(unsigned int x) +{ + return __builtin_ffs(x); +} + +/* { dg-final { scan-assembler "cmp\tw" } } */ +/* { dg-final { scan-assembler "rbit\tw" } } */ +/* { dg-final { scan-assembler "clz\tw" } } */ +/* { dg-final { scan-assembler "csinc\tw" } } */