diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 48c249f2a68d38d30d2748c2723a4387ce770e44..86cc85001c35c9fa64c6c77fef946002ca10f9b4 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -394,6 +394,18 @@ "bext\t%0,%1,%2" [(set_attr "type" "bitmanip")]) +;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner +;; usually has the `bitno` typed as X-mode (i.e. no further +;; zero-extension is performed around the bitno). +(define_insn "*bext<mode>" + [(set (match_operand:X 0 "register_operand" "=r") + (zero_extract:X (match_operand:X 1 "register_operand" "r") + (const_int 1) + (match_operand:X 2 "register_operand" "r")))] + "TARGET_ZBS" + "bext\t%0,%1,%2" + [(set_attr "type" "bitmanip")]) + (define_insn "*bexti" [(set (match_operand:X 0 "register_operand" "=r") (zero_extract:X (match_operand:X 1 "register_operand" "r") diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bext.c b/gcc/testsuite/gcc.target/riscv/zbs-bext.c index 4798239611909e0be30b3502ec6ccc8e201fb745..8de9c5a167c6b5b75c50551cce7f61f01a111afd 100644 --- a/gcc/testsuite/gcc.target/riscv/zbs-bext.c +++ b/gcc/testsuite/gcc.target/riscv/zbs-bext.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */ -/* { dg-skip-if "" { *-*-* } { "-O0" } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ /* bext */ long @@ -16,6 +16,23 @@ foo1 (long i) return 1L & (i >> 20); } +long bext64_1(long a, char bitno) +{ + return (a & (1UL << bitno)) ? 1 : 0; +} + +long bext64_2(long a, char bitno) +{ + return (a & (1UL << bitno)) ? 0 : -1; +} + +long bext64_3(long a, char bitno) +{ + return (a & (1UL << bitno)) ? -1 : 0; +} + /* { dg-final { scan-assembler-times "bexti\t" 1 } } */ -/* { dg-final { scan-assembler-times "bext\t" 1 } } */ -/* { dg-final { scan-assembler-not "andi" } } */ +/* { dg-final { scan-assembler-times "bext\t" 4 } } */ +/* { dg-final { scan-assembler-times "addi\t" 1 } } */ +/* { dg-final { scan-assembler-times "neg\t" 1 } } */ +/* { dg-final { scan-assembler-not "andi" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/riscv/zbs-bexti.c b/gcc/testsuite/gcc.target/riscv/zbs-bexti.c new file mode 100644 index 0000000000000000000000000000000000000000..30b69c9bc3e531ba94c941994291430770dee447 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-bexti.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +/* bexti */ +#define BIT_NO 21 + +long bexti64_1(long a, char bitno) +{ + return (a & (1UL << BIT_NO)) ? 1 : 0; +} + +long bexti64_2(long a, char bitno) +{ + return (a & (1UL << BIT_NO)) ? 0 : -1; +} + +long bexti64_3(long a, char bitno) +{ + return (a & (1UL << BIT_NO)) ? -1 : 0; +} + +/* { dg-final { scan-assembler-times "bexti\t" 3 } } */ +/* { dg-final { scan-assembler-times "addi\t" 1 } } */ +/* { dg-final { scan-assembler-times "neg\t" 1 } } */