On 8/4/24 12:35 PM, Mary Bennett wrote:
Spec:
github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md
Contributors:
Mary Bennett <mary.bennett...@gmail.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.
---
@@ -2651,3 +2653,189 @@
}
[(set_attr "type" "branch")
(set_attr "mode" "none")])
+
+;; XCVBITMANIP builtins
+
+(define_insn "riscv_cv_bitmanip_extract"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (sign_extract:SI
+ (match_operand:SI 1 "register_operand" "r,r")
+ (ashiftrt:SI
+ (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")
+ (const_int 5))
+ (plus:SI
+ (and:SI
+ (match_dup 2)
+ (const_int 31))
+ (const_int 1))))]
+
+ "TARGET_XCVBITMANIP && !TARGET_64BIT"
+ "@
+ cv.extract\t%0,%1,%Z2,%W2
+ cv.extractr\t%0,%1,%2"
+ [(set_attr "type" "bitmanip")
+ (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_extractu"
I would combine this with the previous pattern. There's already a code
iterator "any_extract" you can use in the RTL template. And there's a
<u> code attribute that could be extended to handle sign/zero extract so
that you conditionally generate the "u" in the assembly code.
Why aren't the position and size arguments just registers? I didn't see
anything in the spec that would suggest that we'd want to match those
shift and plus expressions in the pos/size arguments to the extraction.
But given the insert/clear/set patterns are using the same basic
structure I think I must be misunderstanding something.
*If* the semantics of the thead extensions are compatible with the Zbs
extension, then we ought to be able to just reuse the existing patterns.
So for example a bclr has two major forms:
(define_insn "*bclr<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(and:X (rotate:X (const_int -2)
(match_operand:QI 2 "register_operand" "r"))
(match_operand:X 1 "register_operand" "r")))]
"TARGET_ZBS"
"bclr\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
(define_insn "*bclri<mode>"
[(set (match_operand:X 0 "register_operand" "=r")
(and:X (match_operand:X 1 "register_operand" "r")
(match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
"TARGET_ZBS"
"bclri\t%0,%1,%T2"
[(set_attr "type" "bitmanip")])
There's other variants and if the semantics are compatible I'd think
we'd want to take advantage of the work that's already been done to
recognize the other forms that combine might generate such as:
;; Yet another form of a bset/bclr that can be created by combine.
(define_insn "*bsetclr_zero_extract"
[(set (zero_extract:X (match_operand:X 0 "register_operand" "+r")
(const_int 1)
(zero_extend:X
(match_operand:QI 1 "register_operand" "r")))
(match_operand 2 "immediate_operand" "n"))]
"TARGET_ZBS
&& (operands[2] == CONST0_RTX (<MODE>mode)
|| operands[2] == CONST1_RTX (<MODE>mode))"
{
return (operands[2] == CONST0_RTX (<MODE>mode)
? "bclr\t%0,%0,%1"
: "bset\t%0,%0,%1");
}
[(set_attr "type" "bitmanip")])
)
+
+(define_predicate "register_UHI_operand"
+ (and (match_code "reg,subreg")
+ (match_test "GET_MODE (op) == HImode")))
Is this really needed? In the places where it's used (via
bit_extract_operand) we already force the operand to be HImode. So
can't we just use "register_operand" instead of "register_UHI_operand"
in bit_extract_operand instead?
Most of the other patterns looked sensible. Though I think it's
possible we might want to combine them with existing standard patterns
as well. Take something like clz/ctz. We've got some bits to recognize
additional variants of those as well. Rotates have Zbb equivalents I
think as well. Happy to entertain thoughts on how we want to manage
this policy-wise going forward (and I'll raise that today in the
patchwork meeting).
jeff