This patch adds support for scalar count trailing zeros instruction that is being added to ISA 3.0 (power9).
I have built this patch (along with patches #2 and #4) with a bootstrap build on a power8 little endian system. There were no regressions in the test suite. Is this patch ok to install in the trunk once patch #1 has been installed. [gcc] 2015-11-08 Michael Meissner <meiss...@linux.vnet.ibm.com> * config/rs6000/rs6000.c (rs6000_rtx_costs): Update costs for count trailing zero instruction if we have hardware support. * config/rs6000/rs6000.h (TARGET_CTZ): Add support for count trailing zero instruction in ISA 3.0. * config/rs6000/rs6000.c (ctz<mode>2): Likewise. (ctz<mode>2_h): Likewise. [gcc/testsuite] 2015-11-08 Michael Meissner <meiss...@linux.vnet.ibm.com> * gcc.target/powerpc/ctz-1.c: Add test for count trailing zero instruciton support. * gcc.target/powerpc/ctz-2.c: Likewise. -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 229973) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -31850,6 +31850,9 @@ rs6000_rtx_costs (rtx x, machine_mode mo return false; case CTZ: + *total = COSTS_N_INSNS (TARGET_CTZ ? 1 : 4); + return false; + case FFS: *total = COSTS_N_INSNS (4); return false; Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 229972) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -565,6 +565,7 @@ extern int rs6000_vector_align[]; #define TARGET_FCFIDUS TARGET_POPCNTD #define TARGET_FCTIDUZ TARGET_POPCNTD #define TARGET_FCTIWUZ TARGET_POPCNTD +#define TARGET_CTZ TARGET_MODULO #define TARGET_XSCVDPSPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR) #define TARGET_XSCVSPDPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR) Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 229973) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -2101,12 +2101,25 @@ (define_expand "ctz<mode>2" (clobber (reg:GPR CA_REGNO))])] "" { + if (TARGET_CTZ) + { + emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); + DONE; + } + operands[2] = gen_reg_rtx (<MODE>mode); operands[3] = gen_reg_rtx (<MODE>mode); operands[4] = gen_reg_rtx (<MODE>mode); operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); }) +(define_insn "ctz<mode>2_hw" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] + "TARGET_CTZ" + "cnttz<wd> %0,%1" + [(set_attr "type" "cntlz")]) + (define_expand "ffs<mode>2" [(set (match_dup 2) (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) Index: gcc/testsuite/gcc.target/powerpc/ctz-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/ctz-1.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ctz-1.c (revision 0) @@ -0,0 +1,14 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-options "-mcpu=power9 -O3" } */ + +int i_trailing_zero (int a) { return __builtin_ctz (a); } +int l_trailing_zero (long a) { return __builtin_ctzl (a); } +int ll_trailing_zero (long long a) { return __builtin_ctzll (a); } + +/* { dg-final { scan-assembler "cnttzw " } } */ +/* { dg-final { scan-assembler "cnttzd " } } */ +/* { dg-final { scan-assembler-not "cntlzw " } } */ +/* { dg-final { scan-assembler-not "cntlzd " } } */ Index: gcc/testsuite/gcc.target/powerpc/ctz-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/ctz-2.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ctz-2.c (revision 0) @@ -0,0 +1,10 @@ +/* { dg-do compile { target { powerpc*-*-* && ilp32 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ +/* { dg-options "-mcpu=power9 -O3" } */ + +int i_trailing_zero (int a) { return __builtin_ctz (a); } + +/* { dg-final { scan-assembler "cnttzw " } } */ +/* { dg-final { scan-assembler-not "cntlzw " } } */