def int_aarch64_sme_readq_vert : SME_TileToVector_Intrinsic;
def int_aarch64_sme_writeq_horiz : SME_VectorToTile_Intrinsic;
def int_aarch64_sme_writeq_vert : SME_VectorToTile_Intrinsic;
+
+
+ //
+ // Counting elements
+ //
+
+ class AdvSIMD_SME_CNTSB_Intrinsic
+ : DefaultAttrsIntrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+
+ def int_aarch64_sme_cntsb : AdvSIMD_SME_CNTSB_Intrinsic;
+ def int_aarch64_sme_cntsh : AdvSIMD_SME_CNTSB_Intrinsic;
+ def int_aarch64_sme_cntsw : AdvSIMD_SME_CNTSB_Intrinsic;
+ def int_aarch64_sme_cntsd : AdvSIMD_SME_CNTSB_Intrinsic;
}
MAKE_CASE(AArch64ISD::FMINNMV_PRED)
MAKE_CASE(AArch64ISD::FMUL_PRED)
MAKE_CASE(AArch64ISD::FSUB_PRED)
+ MAKE_CASE(AArch64ISD::RDSVL)
MAKE_CASE(AArch64ISD::BIC)
MAKE_CASE(AArch64ISD::BIT)
MAKE_CASE(AArch64ISD::CBZ)
case Intrinsic::aarch64_sve_clz:
return DAG.getNode(AArch64ISD::CTLZ_MERGE_PASSTHRU, dl, Op.getValueType(),
Op.getOperand(2), Op.getOperand(3), Op.getOperand(1));
+ case Intrinsic::aarch64_sme_cntsb:
+ return DAG.getNode(AArch64ISD::RDSVL, dl, Op.getValueType(),
+ DAG.getConstant(1, dl, MVT::i32));
+ case Intrinsic::aarch64_sme_cntsh: {
+ SDValue One = DAG.getConstant(1, dl, MVT::i32);
+ SDValue Bytes = DAG.getNode(AArch64ISD::RDSVL, dl, Op.getValueType(), One);
+ return DAG.getNode(ISD::SRL, dl, Op.getValueType(), Bytes, One);
+ }
+ case Intrinsic::aarch64_sme_cntsw: {
+ SDValue Bytes = DAG.getNode(AArch64ISD::RDSVL, dl, Op.getValueType(),
+ DAG.getConstant(1, dl, MVT::i32));
+ return DAG.getNode(ISD::SRL, dl, Op.getValueType(), Bytes,
+ DAG.getConstant(2, dl, MVT::i32));
+ }
+ case Intrinsic::aarch64_sme_cntsd: {
+ SDValue Bytes = DAG.getNode(AArch64ISD::RDSVL, dl, Op.getValueType(),
+ DAG.getConstant(1, dl, MVT::i32));
+ return DAG.getNode(ISD::SRL, dl, Op.getValueType(), Bytes,
+ DAG.getConstant(3, dl, MVT::i32));
+ }
case Intrinsic::aarch64_sve_cnt: {
SDValue Data = Op.getOperand(3);
// CTPOP only supports integer operands.
SSTNT1_PRED,
SSTNT1_INDEX_PRED,
+ // SME
+ RDSVL,
+
// Asserts that a function argument (i32) is zero-extended to i8 by
// the caller
ASSERT_ZEXT_BOOL,
// Add vector elements horizontally or vertically to ZA tile.
//===----------------------------------------------------------------------===//
+def SDT_AArch64RDSVL : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
+def AArch64rdsvl : SDNode<"AArch64ISD::RDSVL", SDT_AArch64RDSVL>;
+
let Predicates = [HasSME] in {
def RDSVLI_XI : sve_int_read_vl_a<0b0, 0b11111, "rdsvl", /*streaming_sve=*/0b1>;
def ADDSPL_XXI : sve_int_arith_vl<0b1, "addspl", /*streaming_sve=*/0b1>;
def ADDHA_MPPZ_S : sme_add_vector_to_tile_u32<0b0, "addha">;
def ADDVA_MPPZ_S : sme_add_vector_to_tile_u32<0b1, "addva">;
+
+def : Pat<(AArch64rdsvl (i32 simm6_32b:$imm)), (RDSVLI_XI simm6_32b:$imm)>;
}
let Predicates = [HasSMEI64] in {
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -verify-machineinstrs < %s | FileCheck %s
+
+define i64 @sme_cntsb() {
+; CHECK-LABEL: sme_cntsb:
+; CHECK: // %bb.0:
+; CHECK-NEXT: rdsvl x0, #1
+; CHECK-NEXT: ret
+ %v = call i64 @llvm.aarch64.sme.cntsb()
+ ret i64 %v
+}
+
+define i64 @sme_cntsh() {
+; CHECK-LABEL: sme_cntsh:
+; CHECK: // %bb.0:
+; CHECK-NEXT: rdsvl x8, #1
+; CHECK-NEXT: lsr x0, x8, #1
+; CHECK-NEXT: ret
+ %v = call i64 @llvm.aarch64.sme.cntsh()
+ ret i64 %v
+}
+
+define i64 @sme_cntsw() {
+; CHECK-LABEL: sme_cntsw:
+; CHECK: // %bb.0:
+; CHECK-NEXT: rdsvl x8, #1
+; CHECK-NEXT: lsr x0, x8, #2
+; CHECK-NEXT: ret
+ %v = call i64 @llvm.aarch64.sme.cntsw()
+ ret i64 %v
+}
+
+define i64 @sme_cntsd() {
+; CHECK-LABEL: sme_cntsd:
+; CHECK: // %bb.0:
+; CHECK-NEXT: rdsvl x8, #1
+; CHECK-NEXT: lsr x0, x8, #3
+; CHECK-NEXT: ret
+ %v = call i64 @llvm.aarch64.sme.cntsd()
+ ret i64 %v
+}
+
+declare i64 @llvm.aarch64.sme.cntsb()
+declare i64 @llvm.aarch64.sme.cntsh()
+declare i64 @llvm.aarch64.sme.cntsw()
+declare i64 @llvm.aarch64.sme.cntsd()