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  <ian.bol...@arm.com>
 
gcc/
        * config/aarch64/aarch64.md (csinc3<mode>): Make it into a
        named pattern.
        * config/aarch64/aarch64.md (ffs<mode>2): 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" "<MODE>")])
 
-(define_insn "*csinc3<mode>_insn"
+(define_insn "csinc3<mode>_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 "ffs<mode>2"
+  [(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_rbit<mode>2 (operands[0], operands[1]));
+    emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
+    emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], 
const0_rtx));
+    DONE;
+  }
+)
+
 (define_insn "*and<mode>3nr_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" } } */

Reply via email to