On 1/16/24 09:25, Mary Bennett wrote:
Spec:
github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md
Contributors:
Mary Bennett <mary.benn...@embecosm.com>
Nandni Jamnadas <nandni.jamna...@embecosm.com>
Pietra Ferreira <pietra.ferre...@embecosm.com>
Charlie Keaney
Jessica Mills
Craig Blackmore <craig.blackm...@embecosm.com>
Simon Cook <simon.c...@embecosm.com>
Jeremy Bennett <jeremy.benn...@embecosm.com>
Helene Chelin <helene.che...@embecosm.com>
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc: Add XCVbitmanip.
* config/riscv/constraints.md: Likewise.
* config/riscv/corev.def: Likewise.
* config/riscv/corev.md: Likewise.
* config/riscv/predicates.md: Likewise.
* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
* config/riscv/riscv-ftypes.def: Likewise.
* config/riscv/riscv.opt: Likewise.
* doc/extend.texi: Add XCVbitmanip builtin documentation.
* doc/sourcebuild.texi: Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/cv-bitmanip-compile-bclr.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-bclrr.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-bitrev.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-bset.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-bsetr.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-clb.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-cnt.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-extract.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-extractr.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-extractu.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-extractur.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-ff1.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-fl1.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-insert.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-insertr.c: New test.
* gcc.target/riscv/cv-bitmanip-compile-ror.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-bset.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-extract.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c: New test.
* gcc.target/riscv/cv-bitmanip-fail-compile-insert.c: New test.
* lib/target-supports.exp: Add proc for the XCVbitmanip extension.
---
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index adad2409fb6..9afd69ec080 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -706,3 +710,163 @@
[(set_attr "type" "load")
(set_attr "mode" "SI")])
+
+;; XCVBITMANIP builtins
+
+(define_insn "riscv_cv_bitmanip_extract"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (sign_extend:SI (and:SI (rotate:SI (ashift:SI (const_int 1)
+ (ashiftrt:HI
+ (match_operand:HI 2 "bit_extract_operand"
"CV_bit_si10,r")
+ (const_int 5)))
+ (and:HI (match_dup 2)
+ (const_int 31)))
+ (match_operand:SI 1 "register_operand" "r,r"))))]
So it looks like the you've got an ashift:SI where the shift amount of
the result of an ashiftrt:HI -- note the difference in the modes. That
doesn't seem right. It also looks like the indentation on the RTL
pattern is wrong -- that ashiftrt is an argument of the ashift:SI, so it
should line up with the (const_int 1) argument.
It looks like the same issue is repeated on the extractu pattern. Which
leads to a second comment. I think the two patterns can be combined.
There'a an "any_extend" iterator that you could use in place of the
sign_extend/zero_extend. And there's a "u" iterator that you can use in
the output template to conditionally emit a "u".
The insertion, bclr, and bset patterns seem to be goofy on their modes
in a similar way.
+
+(define_insn "riscv_cv_bitmanip_ff1"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (if_then_else (eq:SI (match_operand:SI 1 "register_operand" "r")
(const_int 0))
+ (const_int 32)
+ (minus:SI (ffs:SI (match_dup 1))
+ (const_int 1))))]
Presumably this is an if-then-else to deal with the case when the input
value is zero? Is there any way to use ctz/clz in combination with
C[LT]Z_DEFINED_VALUE_AT_ZERO instead of ffs with a conditional?
More generally, can we avoid the UNSPECs in here by defining these
operations in terms of ffs, clz, ctz?
+
+(define_insn "riscv_cv_bitmanip_cnt"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (truncate:QI (popcount:SI (match_operand:SI 1 "register_operand"
"r"))))]
+
+ "TARGET_XCVBITMANIP && !TARGET_64BIT"
+ "cv.cnt\t%0,%1"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "SI")])
Interesting truncation here? Does the cv.cnt instruction really just
write the result in QImode? Or are you trying to express that the
number of bits must be in the range 0..32 inclusive? The former would
make your code correct, the latter is better left to the generic VRP
optimizer to discover.
+
+(define_insn "riscv_cv_bitmanip_bitrev"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_csr_operand" "K")
+ (match_operand:QI 3 "const_int2_operand" "D03")]
+ UNSPEC_CV_BITMANIP_BITREV))]
Note I think there's a bitreverse opcode now.
Jeff