aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/riscv/bitmanip.md12
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c17
-rw-r--r--gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c17
3 files changed, 46 insertions, 0 deletions
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 0d126a8..0f45bad 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -215,6 +215,18 @@
[(set_attr "type" "bitmanip")
(set_attr "mode" "<X:MODE>")])
+(define_insn_and_split "*<optab>_not_const<mode>"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
+ (match_operand:X 2 "const_arith_operand" "I")))
+ (clobber (match_scratch:X 3 "=&r"))]
+ "(TARGET_ZBB || TARGET_ZBKB) && !TARGET_ZCB
+ && !optimize_function_for_size_p (cfun)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 2))
+ (set (match_dup 0) (bitmanip_bitwise:X (not:X (match_dup 1)) (match_dup 3)))])
+
;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a
;; bit of extra help for combine (i.e., the below split), we end up emitting
;; not/srai/and instead of combining the not into an andn.
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c
new file mode 100644
index 0000000..f9f3222
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-01.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-g" "-Oz" "-Os" } } */
+
+int foo1(int rs1)
+{
+ return 100 & ~rs1;
+}
+
+int foo2(int rs1)
+{
+ return 100 | ~rs1;
+}
+
+/* { dg-final { scan-assembler-times "andn\t" 1 } } */
+/* { dg-final { scan-assembler-times "orn\t" 1 } } */
+/* { dg-final { scan-assembler-times "li\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c
new file mode 100644
index 0000000..112c0fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb-andn-orn-02.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zbb -mabi=ilp32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-g" "-Oz" "-Os" } } */
+
+int foo1(int rs1)
+{
+ return 100 & ~rs1;
+}
+
+int foo2(int rs1)
+{
+ return 100 | ~rs1;
+}
+
+/* { dg-final { scan-assembler-times "andn\t" 1 } } */
+/* { dg-final { scan-assembler-times "orn\t" 1 } } */
+/* { dg-final { scan-assembler-times "li\t" 2 } } */