[clang] [llvm] [RISCV] Support spacemit vsmtvdotii extensions (PR #202533)
Mark Zhuang via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 12 09:32:47 PDT 2026
https://github.com/zqb-all updated https://github.com/llvm/llvm-project/pull/202533
>From 3b8fbe9759f73107a33ec18a778988255945a15b Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Tue, 9 Jun 2026 16:06:46 +0800
Subject: [PATCH 1/8] [RISCV] Support spacemit vsmtvdotii externsions
SPEC: https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md
---
.../Driver/print-supported-extensions-riscv.c | 1 +
clang/test/Driver/riscv-cpus.c | 1 +
llvm/docs/RISCVUsage.rst | 4 +
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 81 ++++++-
.../RISCV/Disassembler/RISCVDisassembler.cpp | 32 ++-
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 62 ++++++
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 10 +
.../RISCV/MCTargetDesc/RISCVInstPrinter.h | 2 +
llvm/lib/Target/RISCV/RISCVFeatures.td | 8 +
llvm/lib/Target/RISCV/RISCVInstrFormats.td | 1 +
.../RISCV/RISCVInstrFormatsSpacemitV.td | 202 +++++++++++++++++-
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 6 +
.../Target/RISCV/RISCVInstrInfoXSpacemiT.td | 62 ++++++
llvm/lib/Target/RISCV/RISCVProcessors.td | 3 +-
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 4 +
llvm/test/CodeGen/RISCV/features-info.ll | 1 +
llvm/test/MC/RISCV/xsmtvdot-valid.s | 32 +--
.../TargetParser/RISCVISAInfoTest.cpp | 1 +
18 files changed, 491 insertions(+), 22 deletions(-)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 34c651891538d..10ac35a77df89 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -228,6 +228,7 @@
// CHECK-NEXT: xsifivecdiscarddlone 1.0 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)
// CHECK-NEXT: xsifivecflushdlone 1.0 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)
// CHECK-NEXT: xsmtvdot 1.0 'XSMTVDot' (SpacemiT Vector Dot Product Extension)
+// CHECK-NEXT: xsmtvdotii 1.0 'XSMTVDotII' (SpacemiT Vector Dot Product 2.0 Extension)
// CHECK-NEXT: xtheadba 1.0 'XTHeadBa' (T-Head address calculation instructions)
// CHECK-NEXT: xtheadbb 1.0 'XTHeadBb' (T-Head basic bit-manipulation instructions)
// CHECK-NEXT: xtheadbs 1.0 'XTHeadBs' (T-Head single-bit instructions)
diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index 99a4c0601b41b..dffdf8dbda9a6 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -106,6 +106,7 @@
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=spacemit-a100 | FileCheck -check-prefix=MCPU-SPACEMIT-A100 %s
// MCPU-SPACEMIT-A100: "-target-cpu" "spacemit-a100"
// COM: The list of extensions are tested in `test/Driver/print-enabled-extensions/riscv-spacemit-a100.c`
+// MCPU-SPACEMIT-A100-SAME: "-target-feature" "+xsmtvdotii"
// MCPU-SPACEMIT-A100-SAME: "-target-abi" "lp64d"
// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=spacemit-a100 | FileCheck -check-prefix=MTUNE-SPACEMIT-A100 %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 7cfbd967eee77..d3dc8e3657466 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -588,6 +588,10 @@ The current vendor extensions supported are:
SpacemiT defines `Integrated Matrix Extension (IME) specification <https://github.com/spacemit-com/riscv-ime-extension-spec/releases/tag/v1.0>`__.
LLVM implement the hardware-adapted subset for SpacemiT X60, defined in the `feature document <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the implementation guide. Note that this implemented subset is `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification`, which is strictly a subset of the full IME specification to reflect the capabilities of SpacemiT X60 hardware correctly.
+``XSMTVDotII``
+ SpacemiT defines `https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md`.
+ LLVM implement the hardware-adapted subset for SpacemiT A100
+
Experimental C Intrinsics
=========================
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 2e287b5386d10..d534a789af18e 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -231,6 +231,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
template <bool IsRV64Inst> ParseStatus parseGPRPair(OperandVector &Operands);
ParseStatus parseGPRPair(OperandVector &Operands, bool IsRV64Inst);
ParseStatus parseFRMArg(OperandVector &Operands);
+ ParseStatus parseSMTVType(OperandVector &Operands);
ParseStatus parseFenceArg(OperandVector &Operands);
ParseStatus parseRegList(OperandVector &Operands, bool MustIncludeS0 = false);
ParseStatus parseRegListS0(OperandVector &Operands) {
@@ -305,6 +306,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
std::unique_ptr<RISCVOperand> defaultFRMArgOp() const;
std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp() const;
+ std::unique_ptr<RISCVOperand> defaultSMTVType();
public:
enum RISCVMatchResultTy : unsigned {
@@ -363,6 +365,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
FPImmediate,
SystemRegister,
VType,
+ SMTVType,
FRM,
Fence,
RegList,
@@ -396,6 +399,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
unsigned Val;
};
+ struct SMTVTypeOp {
+ XSMTVTypeMode::SMTVTypeMode SMTVType;
+ };
+
struct FRMOp {
RISCVFPRndMode::RoundingMode FRM;
};
@@ -425,6 +432,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
FPImmOp FPImm;
SysRegOp SysReg;
VTypeOp VType;
+ SMTVTypeOp SMTVType;
FRMOp FRM;
FenceOp Fence;
RegListOp RegList;
@@ -458,6 +466,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
case KindTy::VType:
VType = o.VType;
break;
+ case KindTy::SMTVType:
+ SMTVType = o.SMTVType;
+ break;
case KindTy::FRM:
FRM = o.FRM;
break;
@@ -683,6 +694,22 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }
bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }
+ // Return true if the operand is a SpacemiT AI Inst support i4/i8
+ bool isSMTVType0() const {
+ return Kind == KindTy::SMTVType &&
+ XSMTVTypeMode::isValidSMTVTypeInt(SMTVType.SMTVType);
+ }
+
+ // Return true if the operand is a SpacemiT AI Inst support bfp16/fp16
+ bool isSMTVType1() const {
+ return Kind == KindTy::SMTVType &&
+ XSMTVTypeMode::isValidSMTVTypeFP(SMTVType.SMTVType);
+ }
+
+ bool isSMTI8() const {
+ return isSMTVType0() && SMTVType.SMTVType == XSMTVTypeMode::SMT_I8;
+ }
+
/// Return true if the operand is a valid fli.s floating-point immediate.
bool isLoadFPImm() const {
if (isExpr())
@@ -1099,6 +1126,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return Fence.Val;
}
+ XSMTVTypeMode::SMTVTypeMode getSMTVType() const {
+ assert(Kind == KindTy::SMTVType && "Invalid type access!");
+ return SMTVType.SMTVType;
+ }
+
void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
auto RegName = [](MCRegister Reg) {
if (Reg)
@@ -1136,6 +1168,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
OS << roundingModeToString(getFRM());
OS << '>';
break;
+ case KindTy::SMTVType:
+ OS << "<smt: ";
+ SMTVTypeModeToString(getSMTVType());
+ OS << '>';
+ break;
case KindTy::Fence:
OS << "<fence: ";
OS << getFence();
@@ -1214,6 +1251,15 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return Op;
}
+ static std::unique_ptr<RISCVOperand>
+ createSMTVType(XSMTVTypeMode::SMTVTypeMode VType, SMLoc S) {
+ auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
+ Op->SMTVType.SMTVType = VType;
+ Op->StartLoc = S;
+ Op->EndLoc = S;
+ return Op;
+ }
+
static std::unique_ptr<RISCVOperand> createFenceArg(unsigned Val, SMLoc S) {
auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
Op->Fence.Val = Val;
@@ -1345,6 +1391,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createImm(getFRM()));
}
+
+ void addSMTVTypeOperand(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(getSMTVType()));
+ }
};
} // end anonymous namespace.
@@ -1379,6 +1430,8 @@ static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
unsigned RegClassID;
if (Kind == MCK_VRM2)
RegClassID = RISCV::VRM2RegClassID;
+ else if (Kind == MCK_VRM2NoV0)
+ RegClassID = RISCV::VRM2NoV0RegClassID;
else if (Kind == MCK_VRM4)
RegClassID = RISCV::VRM4RegClassID;
else if (Kind == MCK_VRM8)
@@ -1453,7 +1506,8 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
// As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
// the register from VR to VRM2/VRM4/VRM8 if necessary.
- if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
+ if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM2NoV0 ||
+ Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
Op.Reg.Reg = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind);
if (!Op.Reg.Reg)
return Match_InvalidOperand;
@@ -2748,6 +2802,26 @@ ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands,
return ParseStatus::Success;
}
+ParseStatus RISCVAsmParser::parseSMTVType(OperandVector &Operands) {
+ if (getLexer().isNot(AsmToken::Identifier))
+ return TokError("operand must be a valid SpacemiT VType mnemonic");
+
+ StringRef Str = getLexer().getTok().getIdentifier();
+ XSMTVTypeMode::SMTVTypeMode VType = XSMTVTypeMode::stringToSMTVTypeMode(Str);
+
+ if (!isValidSMTVTypeMode(VType))
+ return TokError("SpacemiT AI only support [i4|i8|bfp16|fp16] Mode");
+
+ // bfp16 and fp16 has the same encoding in SpacemiT AI
+ // In AsmParse, need conside bfp16 as fp16
+ if (VType == XSMTVTypeMode::SMTVTypeMode::SMT_BFP16) {
+ VType = XSMTVTypeMode::SMTVTypeMode::SMT_FP16;
+ }
+ Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
+ Lex(); // Eat identifier token.
+ return ParseStatus::Success;
+}
+
ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
return TokError(
@@ -2765,6 +2839,11 @@ ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
return ParseStatus::Success;
}
+std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
+ return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
+ llvm::SMLoc());
+}
+
ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {
const AsmToken &Tok = getLexer().getTok();
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index cf1f8edf16976..b3c80835e5df7 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -217,6 +217,35 @@ static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeVRV0V1RegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo >= 2)
+ return MCDisassembler::Fail;
+
+ return DecodeSimpleRegisterClass<RISCV::V0, 2>(Inst, RegNo, Address, Decoder);
+}
+
+static DecodeStatus DecodeVRNoV0V1RegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo == 0 || RegNo == 1)
+ return MCDisassembler::Fail;
+
+ return DecodeSimpleRegisterClass<RISCV::V0, 32>(Inst, RegNo, Address,
+ Decoder);
+}
+
+static DecodeStatus DecodeVRM2NoV0RegisterClass(MCInst &Inst, uint32_t RegNo,
+ uint64_t Address,
+ const MCDisassembler *Decoder) {
+ if (RegNo == 0)
+ return MCDisassembler::Fail;
+
+ return DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>(
+ Inst, RegNo, Address, Decoder);
+}
+
static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
@@ -531,7 +560,8 @@ static constexpr FeatureBitset XAndesGroup = {
RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,
RISCV::FeatureVendorXAndesVDot};
-static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot};
+static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot,
+ RISCV::FeatureVendorXSMTVDotII};
static constexpr FeatureBitset XAIFGroup = {RISCV::FeatureVendorXAIFET};
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index adf5d5d8b3759..ee1966700acee 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -144,6 +144,8 @@ enum OperandType : unsigned {
OPERAND_BCC_OPCODE,
OPERAND_VMASK,
+ OPERAND_SMTVType,
+ OPERAND_SMTI8,
};
} // namespace RISCVOp
@@ -553,6 +555,66 @@ inline static bool isValidRoundingMode(unsigned Mode) {
}
} // namespace RISCVFPRndMode
+namespace XSMTVTypeMode {
+enum SMTVTypeMode {
+ // Define the different SMT VType modes here
+ SMT_FP16 = 0,
+ SMT_BFP16 = 1,
+ SMT_I4 = 2,
+ SMT_I8 = 3,
+ Invalid
+};
+
+inline static StringRef SMTVTypeModeToString(SMTVTypeMode TypeMode) {
+ switch (TypeMode) {
+ default:
+ llvm_unreachable("Unknown SpacemiT AI VType's mode");
+ case XSMTVTypeMode::SMT_BFP16:
+ return "bfp16";
+ case XSMTVTypeMode::SMT_FP16:
+ return "fp16";
+ case XSMTVTypeMode::SMT_I4:
+ return "i4";
+ case XSMTVTypeMode::SMT_I8:
+ return "i8";
+ }
+}
+
+inline static SMTVTypeMode stringToSMTVTypeMode(StringRef Str) {
+ return StringSwitch<SMTVTypeMode>(Str)
+ .Case("bfp16", XSMTVTypeMode::SMT_BFP16)
+ .Case("fp16", XSMTVTypeMode::SMT_FP16)
+ .Case("i4", XSMTVTypeMode::SMT_I4)
+ .Case("i8", XSMTVTypeMode::SMT_I8)
+ .Default(XSMTVTypeMode::Invalid);
+}
+
+inline static bool isValidSMTVTypeInt(unsigned Mode) {
+ switch (Mode) {
+ default:
+ return false;
+ case XSMTVTypeMode::SMT_I4:
+ case XSMTVTypeMode::SMT_I8:
+ return true;
+ }
+}
+
+inline static bool isValidSMTVTypeFP(unsigned Mode) {
+ switch (Mode) {
+ default:
+ return false;
+ case XSMTVTypeMode::SMT_BFP16:
+ case XSMTVTypeMode::SMT_FP16:
+ return true;
+ }
+}
+
+inline static bool isValidSMTVTypeMode(unsigned Mode) {
+ return isValidSMTVTypeInt(Mode) || isValidSMTVTypeFP(Mode);
+}
+
+} // namespace XSMTVTypeMode
+
namespace RISCVVXRndMode {
enum RoundingMode {
RNU = 0,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 475ffb44f4931..d6012006bbc09 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -162,6 +162,16 @@ void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo,
O << "0";
}
+void RISCVInstPrinter::printSMTVType(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ auto VType =
+ static_cast<XSMTVTypeMode::SMTVTypeMode>(MI->getOperand(OpNo).getImm());
+ assert(XSMTVTypeMode::isValidSMTVTypeMode(VType) &&
+ "SpacemiT AI only support [i4|i8|fp16|bfp16] Mode");
+ O << ", " << XSMTVTypeMode::SMTVTypeModeToString(VType);
+}
+
void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O) {
auto FRMArg =
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index 587eb41803a45..a9cfdbdf99503 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -38,6 +38,8 @@ class RISCVInstPrinter : public MCInstPrinter {
const MCSubtargetInfo &STI, raw_ostream &O);
void printFenceArg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
+ void printSMTVType(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
void printFRMArgLegacy(const MCInst *MI, unsigned OpNo,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 361be64352499..ecab0f66214c4 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1856,6 +1856,14 @@ def HasVendorXSMTVDot
AssemblerPredicate<(all_of FeatureVendorXSMTVDot),
"'XSMTVDot' (SpacemiT Vector Dot Product Extension)">;
+def FeatureVendorXSMTVDotII
+ : RISCVExtension<1, 0, "SpacemiT Vector Dot Product 2.0 Extension",
+ [FeatureStdExtZve32f]>;
+def HasVendorXSMTVDotII
+ : Predicate<"Subtarget->hasVendorXSMTVDotII()">,
+ AssemblerPredicate<(all_of FeatureVendorXSMTVDotII),
+ "'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))">;
+
def FeatureVendorXAIFET
: RISCVExtension<1, 0, "AI Foundry ET Extension", [FeatureStdExtF]>;
def HasXAIFET : Predicate<"Subtarget->hasXAIFET()">,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index e3c93dc93a686..d48de5cc0f394 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -58,6 +58,7 @@ def InstFormatQC_EB : InstFormat<24>;
def InstFormatQC_EJ : InstFormat<25>;
def InstFormatQC_ES : InstFormat<26>;
def InstFormatNDS_BRANCH_10 : InstFormat<27>;
+def InstFormatSMT : InstFormat<28>;
def InstFormatOther : InstFormat<31>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
index 66535c4e77f4a..aa3e515a8a464 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -54,6 +54,60 @@ defvar SlideEncodes = [SlideEncode<0b00, "1">,
SlideEncode<0b01, "2">,
SlideEncode<0b10, "3">];
+class HPEncode<bits<3> encoding, string name> {
+ bits<3> Encoding = encoding;
+ string Name = name;
+}
+defvar HPEncodes = [HPEncode<0b011, "u">,
+ HPEncode<0b110, "us">,
+ HPEncode<0b101, "su">,
+ HPEncode<0b100, "">];
+
+// The SpacemiT support element Type
+class SMTVType<bit isFP> : AsmOperandClass {
+ let Name = "SMTVType"#isFP;
+ let RenderMethod = "addSMTVTypeOperand";
+ let ParserMethod = "parseSMTVType";
+ let DiagnosticType = "InvalidSMTType"#isFP;
+ let DiagnosticString = !if(isFP,
+ "This Inst only supports bfp16 and fp16",
+ "This Inst only supports i4 and i8, i8 is defuat type"
+ );
+ let IsOptional = 1;
+ let DefaultMethod = "defaultSMTVType";
+}
+
+class SMT_VTYPE<bit isFP> : Operand<XLenVT> {
+ let ParserMatchClass = SMTVType<isFP>;
+ let PrintMethod = "printSMTVType";
+ let DecoderMethod = "decodeUImmOperand<2>";
+ let OperandType = "OPERAND_SMTVType";
+ let OperandNamespace = "RISCVOp";
+}
+
+// Supports i4 and i8
+def SMT_INT : SMT_VTYPE<0>;
+// Supports bfp16 and fp16
+def SMT_FP : SMT_VTYPE<1>;
+
+def SMTI8 : AsmOperandClass {
+ let Name = "SMTI8";
+ let RenderMethod = "addSMTVTypeOperand";
+ let DiagnosticType = "InvalidSMTI8";
+ let DiagnosticString = "smt.vmadot with slide only support i8 type";
+ let ParserMethod = "parseSMTVType";
+ let IsOptional = 1;
+ let DefaultMethod = "defaultSMTVType";
+}
+
+def SMT_I8 : Operand<XLenVT> {
+ let ParserMatchClass = SMTI8;
+ let PrintMethod = "printSMTVType";
+ let DecoderMethod = "decodeUImmOperand<2>";
+ let OperandType = "OPERAND_SMTI8";
+ let OperandNamespace = "RISCVOp";
+}
+
//===----------------------------------------------------------------------===//
// Instruction formats
//===----------------------------------------------------------------------===//
@@ -62,7 +116,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
class SMTVMADot<bits<2> sign, string opcodestr, bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb), (ins VRM2:$vd, VR:$vs1, VR:$vs2),
- opcodestr, "$vd, $vs1, $vs2", [], InstFormatR> {
+ opcodestr, "$vd, $vs1, $vs2", [], InstFormatSMT> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -83,7 +137,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVMADotSlide<bits<2> funct2, bits<2> sign, string opcodestr,
bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb), (ins VRM2:$vd, VRM2:$vs1, VR:$vs2),
- opcodestr, "$vd, $vs1, $vs2", [], InstFormatR> {
+ opcodestr, "$vd, $vs1, $vs2", [], InstFormatSMT> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -99,5 +153,147 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
!if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
let UseNamedOperandTable = true;
}
-}
+ class SMTVMADotII<bits<2> sign, string opcodestr, bit EarlyClobber = 0>
+ : RVInst<(outs VRM2:$vd_wb),
+ (ins VRM2:$vd, VR:$vs1, VR:$vs2, SMT_INT:$vtype), opcodestr,
+ "$vd, $vs1, $vs2$vtype", [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> vtype;
+
+ let Inst{31} = 0b1;
+ let Inst{30-29} = vtype;
+ let Inst{28-25} = 0b0001;
+ let Inst{24-20} = vs2;
+ let Inst{19-15} = vs1;
+ let Inst{14} = 0b0;
+ let Inst{13-12} = sign;
+ let Inst{11-7} = vd;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let Constraints =
+ !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
+ let UseNamedOperandTable = true;
+ }
+
+ // Now only support element type i8 for sliding-window dot-product
+ // instructions
+ class SMTVMADotSlideII<bits<2> slide, bits<2> sign, string opcodestr,
+ bit EarlyClobber = 0>
+ : RVInst<(outs VRM2:$vd_wb),
+ (ins VRM2:$vd, VRM2:$vs1, VR:$vs2, SMT_I8:$vtype), opcodestr,
+ "$vd, $vs1, $vs2$vtype", [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> vtype;
+
+ let Inst{31} = 1;
+ let Inst{30-29} = vtype;
+ let Inst{28-25} = 0b0011;
+ let Inst{24-20} = vs2;
+ let Inst{19-16} = vs1{4-1};
+ let Inst{15-14} = slide;
+ let Inst{13-12} = sign;
+ let Inst{11-7} = vd;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let Constraints =
+ !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
+ let UseNamedOperandTable = true;
+ }
+
+ class SMTVMADOTSP<bits<2> sign, string opcodestr, string argstr,
+ bit EarlyClobber = 0>
+ : RVInst<(outs VRM2NoV0:$vd_wb),
+ (ins VRM2NoV0:$vd, VRM2NoV0:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm2:$imm2,
+ SMT_INT:$vtype),
+ opcodestr, argstr, [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> vtype;
+ bit vmask;
+ bits<2> imm2;
+
+ let Inst{31} = 0b1;
+ let Inst{30-29} = vtype;
+ let Inst{28-26} = 0b010;
+ let Inst{25} = vmask;
+ let Inst{24-20} = vs2;
+ let Inst{19-16} = vs1{4-1};
+ let Inst{15} = imm2{1};
+ let Inst{14} = 0b0;
+ let Inst{13-12} = sign;
+ let Inst{11-8} = vd{4-1};
+ let Inst{7} = imm2{0};
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let Constraints =
+ !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
+ let UseNamedOperandTable = true;
+ }
+
+ class SMTVMADOTHP<bits<3> funct3, string opcodestr, string argstr,
+ bit EarlyClobber = 0>
+ : RVInst<(outs VRNoV0V1:$vd_wb),
+ (ins VRNoV0V1:$vd, VRNoV0V1:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm3:$imm3,
+ SMT_INT:$vtype),
+ opcodestr, argstr, [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> vtype;
+ bit vmask;
+ bits<3> imm3;
+
+ let Inst{31} = 0b1;
+ let Inst{30-29} = vtype;
+ let Inst{28-26} = funct3;
+ let Inst{25} = vmask;
+ let Inst{24-20} = vs2;
+ let Inst{19-15} = vs1;
+ let Inst{14-12} = imm3;
+ let Inst{11-7} = vd;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let Constraints =
+ !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
+ let UseNamedOperandTable = true;
+ }
+
+ class SMTVFWMADOT<bits<3> funct3, dag outs, dag ins, string opcodestr,
+ string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> vtype;
+
+ let Inst{31} = 0b1;
+ let Inst{30-29} = vtype;
+ let Inst{28-25} = 0b1111;
+ let Inst{24-20} = vs2;
+ let Inst{19-15} = vs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = vd;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let UseNamedOperandTable = true;
+ }
+
+ class SMTVPACK<bits<7> funct7, bit funct1, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatSMT> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+ bits<2> imm2;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-20} = vs2;
+ let Inst{19-15} = vs1;
+ let Inst{14} = funct1;
+ let Inst{13-12} = imm2;
+ let Inst{11-7} = vd;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let UseNamedOperandTable = true;
+ }
+}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 4de0a27790eca..6512dde8fde23 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3140,6 +3140,12 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_RTZARG:
Ok = Imm == RISCVFPRndMode::RTZ;
break;
+ case RISCVOp::OPERAND_SMTVType:
+ Ok = XSMTVTypeMode::isValidSMTVTypeMode(Imm);
+ break;
+ case RISCVOp::OPERAND_SMTI8:
+ Ok = Imm == XSMTVTypeMode::SMT_I8;
+ break;
case RISCVOp::OPERAND_COND_CODE:
Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID;
break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index 41a0f0b73c1fc..d28ce0b505675 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -46,4 +46,66 @@ let DecoderNamespace = "XSMT" in {
def SMT_VMADOT#!toupper(a.Name)#!toupper(b.Name) :
SMTVMADotSlide<a.Encoding, b.Encoding, "smt.vmadot"#a.Name#b.Name>, Sched<[]>;
}
+
+ class VFWMADTSLIDE_INSN<bits<3> funct3, string opcodestr>
+ : SMTVFWMADOT<funct3, (outs VRM2:$vd_wb),
+ (ins VRM2:$vd, VRM2:$vs1, VR:$vs2, SMT_FP:$vtype),
+ opcodestr, "$vd, $vs1, $vs2$vtype">, Sched<[]>;
+
+ class VNPACK_INSN<bits<7> funct7, bit funct1, string opcodestr>
+ : SMTVPACK<funct7, funct1, (outs VR:$vd),
+ (ins VR:$vs1, VR:$vs2, uimm2:$imm2), opcodestr,
+ "$vd, $vs1, $vs2, $imm2">, Sched<[]>;
+
+ class VPACK_INSN<bits<7> funct7, bit funct1, string opcodestr>
+ : SMTVPACK<funct7, funct1, (outs VRM2:$vd),
+ (ins VR:$vs1, VR:$vs2, uimm2:$imm2), opcodestr,
+ "$vd, $vs1, $vs2, $imm2">, Sched<[]>;
+
+ let Predicates = [HasVendorXSMTVDotII, IsRV64], ElementsDependOn = EltDepsNone in {
+ let VS1VS2Constraint = WidenV in {
+ // Base VMADOT II instructions
+ // Support smt.vmadot/smt.vmadotu/smt.vmadotus/smt.vmadotsu
+ foreach a = VTypeEncodes in
+ def VMADOT#!toupper(a.Name) :
+ SMTVMADotII<a.Encoding, "smt.vmadot"#a.Name>, Sched<[]>;
+
+ // VMADOT Slide
+ foreach a = SlideEncodes in
+ foreach b = VTypeEncodes in
+ def VMADOT#!toupper(a.Name)#!toupper(b.Name):
+ SMTVMADotSlideII<a.Encoding, b.Encoding, "smt.vmadot"#a.Name#b.Name>, Sched<[]>;
+
+ // Support smt.vmadot.sp/smt.vmadotu.sp/smt.vmadotus.sp/smt.vmadotsu.sp
+ foreach a = VTypeEncodes in
+ def VMADOT#!toupper(a.Name)#_SP :
+ SMTVMADOTSP<a.Encoding, "smt.vmadot"#a.Name#".sp",
+ "$vd, $vs1, $vs2, $vmask, $imm2$vtype">, Sched<[]>;
+
+ // Support smt.vmadot.hp/smt.vmadotu.hp/smt.vmadotus.hp/smt.vmadotsu.hp
+ foreach c = HPEncodes in
+ def VMADOT#!toupper(c.Name)#_HP :
+ SMTVMADOTHP<c.Encoding, "smt.vmadot"#c.Name#".hp",
+ "$vd, $vs1, $vs2, $vmask, $imm3$vtype">, Sched<[]>;
+
+ let DestEEW = EEWSEWx2, Constraints = "$vd = $vd_wb"in {
+ // VFWMADOT
+ def VFWMADOT :
+ SMTVFWMADOT<0b100, (outs VRM2:$vd_wb),
+ (ins VRM2:$vd, VR:$vs1, VR:$vs2, SMT_FP:$vtype),
+ "smt.vfwmadot", "$vd, $vs1, $vs2$vtype">, Sched<[]>;
+ // VFWMADOT Slide
+ def VFWMADOT1 : VFWMADTSLIDE_INSN<0b101, "smt.vfwmadot1">;
+ def VFWMADOT2 : VFWMADTSLIDE_INSN<0b110, "smt.vfwmadot2">;
+ def VFWMADOT3 : VFWMADTSLIDE_INSN<0b111, "smt.vfwmadot3">;
+ }
+
+ def VNPACK_VV : VNPACK_INSN<0b0110001, 0b0, "smt.vnpack.vv">;
+ def VNSPACK_VV : VNPACK_INSN<0b0110001, 0b1, "smt.vnspack.vv">;
+ def VNPACK4_VV : VNPACK_INSN<0b0100001, 0b0, "smt.vnpack4.vv">;
+ def VNSPACK4_VV : VNPACK_INSN<0b0100001, 0b1, "smt.vnspack4.vv">;
+ def VPACK_VV : VPACK_INSN<0b0110011, 0b0, "smt.vpack.vv">;
+ def VUPACK_VV : VPACK_INSN<0b0110011, 0b1, "smt.vupack.vv">;
+ }
+ }
} // DecoderNamespace = "XSMT"
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td
index daf7bcd0aad82..431f213f24afe 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -873,7 +873,8 @@ def SPACEMIT_A100 : RISCVProcessorModel<"spacemit-a100",
FeatureStdExtZvksc,
FeatureStdExtZvksg,
FeatureStdExtZvl1024b,
- FeatureUnalignedScalarMem]),
+ FeatureUnalignedScalarMem,
+ FeatureVendorXSMTVDotII]),
[TuneDLenFactor2,
TuneOptimizedNF2SegmentLoadStore,
TuneOptimizedNF3SegmentLoadStore,
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index a3f968b5ab76f..a31eb9ad1fb6e 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -867,8 +867,12 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
let DecoderMethod = "DecodeSimpleRegisterClass<RISCV::V0, 32>";
}
+def VRV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (add V0, V1), 1>;
+
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
+def VRNoV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0, V1), 1>;
+
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2> {
let DecoderMethod = "DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>";
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 8abe64b8ecda4..9a70ecfc6e3ce 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -265,6 +265,7 @@
; CHECK-NEXT: xsifivecdiscarddlone - 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction).
; CHECK-NEXT: xsifivecflushdlone - 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction).
; CHECK-NEXT: xsmtvdot - 'XSMTVDot' (SpacemiT Vector Dot Product Extension).
+; CHECK-NEXT: xsmtvdotII - 'XSMTVDot' (SpacemiT Vector Dot Product 2.0 Extension).
; CHECK-NEXT: xtheadba - 'XTHeadBa' (T-Head address calculation instructions).
; CHECK-NEXT: xtheadbb - 'XTHeadBb' (T-Head basic bit-manipulation instructions).
; CHECK-NEXT: xtheadbs - 'XTHeadBs' (T-Head single-bit instructions).
diff --git a/llvm/test/MC/RISCV/xsmtvdot-valid.s b/llvm/test/MC/RISCV/xsmtvdot-valid.s
index 4f402236099d6..bde8a42403c1b 100644
--- a/llvm/test/MC/RISCV/xsmtvdot-valid.s
+++ b/llvm/test/MC/RISCV/xsmtvdot-valid.s
@@ -11,84 +11,84 @@
// CHECK-ENC: encoding: [0x2b,0x38,0x80,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot v16, v0, v8
smt.vmadot v16, v0, v8
// CHECK-ENC: encoding: [0x2b,0x89,0x90,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadotu v18, v1, v9
smt.vmadotu v18, v1, v9
// CHECK-ENC: encoding: [0x2b,0x2a,0xa1,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadotsu v20, v2, v10
smt.vmadotsu v20, v2, v10
// CHECK-ENC: encoding: [0x2b,0x9b,0xb1,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadotus v22, v3, v11
smt.vmadotus v22, v3, v11
// CHECK-ENC: encoding: [0x2b,0x3c,0xc8,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot1 v24, v16, v12
smt.vmadot1 v24, v16, v12
// CHECK-ENC: encoding: [0x2b,0x0d,0xd9,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot1u v26, v18, v13
smt.vmadot1u v26, v18, v13
// CHECK-ENC: encoding: [0x2b,0x2e,0xea,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot1su v28, v20, v14
smt.vmadot1su v28, v20, v14
// CHECK-ENC: encoding: [0x2b,0x1f,0xfb,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot1us v30, v22, v15
smt.vmadot1us v30, v22, v15
// CHECK-ENC: encoding: [0x2b,0x70,0x4c,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot2 v0, v24, v4
smt.vmadot2 v0, v24, v4
// CHECK-ENC: encoding: [0x2b,0x41,0x5d,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot2u v2, v26, v5
smt.vmadot2u v2, v26, v5
// CHECK-ENC: encoding: [0x2b,0x62,0x6e,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot2su v4, v28, v6
smt.vmadot2su v4, v28, v6
// CHECK-ENC: encoding: [0x2b,0x53,0x8f,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot2us v6, v30, v8
smt.vmadot2us v6, v30, v8
// CHECK-ENC: encoding: [0x2b,0xb1,0x80,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot3 v2, v0, v8
smt.vmadot3 v2, v0, v8
// CHECK-ENC: encoding: [0x2b,0x85,0x91,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot3u v10, v2, v9
smt.vmadot3u v10, v2, v9
// CHECK-ENC: encoding: [0x2b,0xa6,0xa2,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot3su v12, v4, v10
smt.vmadot3su v12, v4, v10
// CHECK-ENC: encoding: [0x2b,0x97,0xb3,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot3us v14, v6, v11
smt.vmadot3us v14, v6, v11
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 837a72913dc7d..cdc2fcea37fcb 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1597,6 +1597,7 @@ R"(All available -march extensions for RISC-V
xsifivecdiscarddlone 1.0
xsifivecflushdlone 1.0
xsmtvdot 1.0
+ xsmtvdotii 1.0
xtheadba 1.0
xtheadbb 1.0
xtheadbs 1.0
>From b8a9a99733604adc95790833858e91480bf4b812 Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Thu, 11 Jun 2026 18:12:16 +0800
Subject: [PATCH 2/8] fix comments
---
.../riscv-spacemit-a100.c | 1 +
.../Driver/print-supported-extensions-riscv.c | 2 +-
llvm/docs/RISCVUsage.rst | 4 +-
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 6 +-
.../RISCV/Disassembler/RISCVDisassembler.cpp | 42 ++--
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 2 +-
llvm/lib/Target/RISCV/RISCVFeatures.td | 2 +-
llvm/lib/Target/RISCV/RISCVInstrFormats.td | 1 -
.../RISCV/RISCVInstrFormatsSpacemitV.td | 22 +-
.../Target/RISCV/RISCVInstrInfoXSpacemiT.td | 2 +-
llvm/test/CodeGen/RISCV/features-info.ll | 2 +-
.../rvv/subregister-undef-early-clobber.mir | 16 +-
llvm/test/MC/RISCV/xsmtvdotii-invalid.s | 192 ++++++++++++++++++
llvm/test/MC/RISCV/xsmtvdotii-valid.s | 134 ++++++++++++
14 files changed, 370 insertions(+), 58 deletions(-)
create mode 100644 llvm/test/MC/RISCV/xsmtvdotii-invalid.s
create mode 100644 llvm/test/MC/RISCV/xsmtvdotii-valid.s
diff --git a/clang/test/Driver/print-enabled-extensions/riscv-spacemit-a100.c b/clang/test/Driver/print-enabled-extensions/riscv-spacemit-a100.c
index 11fde408956bc..c56b476145a2a 100644
--- a/clang/test/Driver/print-enabled-extensions/riscv-spacemit-a100.c
+++ b/clang/test/Driver/print-enabled-extensions/riscv-spacemit-a100.c
@@ -96,6 +96,7 @@
// CHECK-NEXT: svinval 1.0 'Svinval' (Fine-Grained Address-Translation Cache Invalidation)
// CHECK-NEXT: svnapot 1.0 'Svnapot' (NAPOT Translation Contiguity)
// CHECK-NEXT: svpbmt 1.0 'Svpbmt' (Page-Based Memory Types)
+// CHECK-NEXT: xsmtvdotii 1.0 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
// CHECK-EMPTY:
// CHECK-NEXT: Experimental extensions
// CHECK-EMPTY:
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 10ac35a77df89..0ab0390627ff6 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -228,7 +228,7 @@
// CHECK-NEXT: xsifivecdiscarddlone 1.0 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction)
// CHECK-NEXT: xsifivecflushdlone 1.0 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction)
// CHECK-NEXT: xsmtvdot 1.0 'XSMTVDot' (SpacemiT Vector Dot Product Extension)
-// CHECK-NEXT: xsmtvdotii 1.0 'XSMTVDotII' (SpacemiT Vector Dot Product 2.0 Extension)
+// CHECK-NEXT: xsmtvdotii 1.0 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
// CHECK-NEXT: xtheadba 1.0 'XTHeadBa' (T-Head address calculation instructions)
// CHECK-NEXT: xtheadbb 1.0 'XTHeadBb' (T-Head basic bit-manipulation instructions)
// CHECK-NEXT: xtheadbs 1.0 'XTHeadBs' (T-Head single-bit instructions)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index d3dc8e3657466..5d043ca286e02 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -586,11 +586,11 @@ The current vendor extensions supported are:
``XSMTVDot``
SpacemiT defines `Integrated Matrix Extension (IME) specification <https://github.com/spacemit-com/riscv-ime-extension-spec/releases/tag/v1.0>`__.
- LLVM implement the hardware-adapted subset for SpacemiT X60, defined in the `feature document <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the implementation guide. Note that this implemented subset is `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification`, which is strictly a subset of the full IME specification to reflect the capabilities of SpacemiT X60 hardware correctly.
+ LLVM implements the hardware-adapted subset for SpacemiT X60, defined in the `feature document <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the implementation guide. Note that this implemented subset is `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification`, which is strictly a subset of the full IME specification to reflect the capabilities of SpacemiT X60 hardware correctly.
``XSMTVDotII``
SpacemiT defines `https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md`.
- LLVM implement the hardware-adapted subset for SpacemiT A100
+ LLVM implements the hardware-adapted subset for SpacemiT A100
Experimental C Intrinsics
=========================
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index d534a789af18e..b60560c6cf7b7 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1169,7 +1169,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
OS << '>';
break;
case KindTy::SMTVType:
- OS << "<smt: ";
+ OS << "<smtvtype: ";
SMTVTypeModeToString(getSMTVType());
OS << '>';
break;
@@ -2810,10 +2810,10 @@ ParseStatus RISCVAsmParser::parseSMTVType(OperandVector &Operands) {
XSMTVTypeMode::SMTVTypeMode VType = XSMTVTypeMode::stringToSMTVTypeMode(Str);
if (!isValidSMTVTypeMode(VType))
- return TokError("SpacemiT AI only support [i4|i8|bfp16|fp16] Mode");
+ return TokError("SpacemiT AI only supports [i4|i8|bfp16|fp16] Mode");
// bfp16 and fp16 has the same encoding in SpacemiT AI
- // In AsmParse, need conside bfp16 as fp16
+ // In AsmParser, need to consider bfp16 as fp16
if (VType == XSMTVTypeMode::SMTVTypeMode::SMT_BFP16) {
VType = XSMTVTypeMode::SMTVTypeMode::SMT_FP16;
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b3c80835e5df7..f6b138d634b7c 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -217,34 +217,20 @@ static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
-static DecodeStatus DecodeVRV0V1RegisterClass(MCInst &Inst, uint32_t RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder) {
- if (RegNo >= 2)
- return MCDisassembler::Fail;
-
- return DecodeSimpleRegisterClass<RISCV::V0, 2>(Inst, RegNo, Address, Decoder);
-}
-
-static DecodeStatus DecodeVRNoV0V1RegisterClass(MCInst &Inst, uint32_t RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder) {
- if (RegNo == 0 || RegNo == 1)
- return MCDisassembler::Fail;
-
- return DecodeSimpleRegisterClass<RISCV::V0, 32>(Inst, RegNo, Address,
- Decoder);
-}
-
-static DecodeStatus DecodeVRM2NoV0RegisterClass(MCInst &Inst, uint32_t RegNo,
- uint64_t Address,
- const MCDisassembler *Decoder) {
- if (RegNo == 0)
- return MCDisassembler::Fail;
-
- return DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>(
- Inst, RegNo, Address, Decoder);
-}
+constexpr auto DecodeVRRegisterClass = DecodeSimpleRegisterClass<RISCV::V0, 32>;
+constexpr auto DecodeVRM2RegisterClass =
+ DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>;
+
+constexpr bool PredV0V1Only(uint32_t RegNo) { return RegNo < 2; }
+constexpr bool PredNoV0V1(uint32_t RegNo) { return RegNo >= 2; }
+constexpr bool PredVM2NOV0(uint32_t RegNo) { return RegNo != 0; }
+
+constexpr auto DecodeVRV0V1RegisterClass =
+ DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredV0V1Only>;
+constexpr auto DecodeVRNoV0V1RegisterClass =
+ DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredNoV0V1>;
+constexpr auto DecodeVRM2NoV0RegisterClass =
+ DecodeFilteredRegisterClass<DecodeVRM2RegisterClass, PredVM2NOV0>;
static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index d6012006bbc09..2524c9ae7db2b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -168,7 +168,7 @@ void RISCVInstPrinter::printSMTVType(const MCInst *MI, unsigned OpNo,
auto VType =
static_cast<XSMTVTypeMode::SMTVTypeMode>(MI->getOperand(OpNo).getImm());
assert(XSMTVTypeMode::isValidSMTVTypeMode(VType) &&
- "SpacemiT AI only support [i4|i8|fp16|bfp16] Mode");
+ "SpacemiT AI only supports [i4|i8|fp16|bfp16] Mode");
O << ", " << XSMTVTypeMode::SMTVTypeModeToString(VType);
}
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index ecab0f66214c4..a04d9636d9d48 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1857,7 +1857,7 @@ def HasVendorXSMTVDot
"'XSMTVDot' (SpacemiT Vector Dot Product Extension)">;
def FeatureVendorXSMTVDotII
- : RISCVExtension<1, 0, "SpacemiT Vector Dot Product 2.0 Extension",
+ : RISCVExtension<1, 0, "SpacemiT Vector Extension for Matrix(2.0)",
[FeatureStdExtZve32f]>;
def HasVendorXSMTVDotII
: Predicate<"Subtarget->hasVendorXSMTVDotII()">,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index d48de5cc0f394..e3c93dc93a686 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -58,7 +58,6 @@ def InstFormatQC_EB : InstFormat<24>;
def InstFormatQC_EJ : InstFormat<25>;
def InstFormatQC_ES : InstFormat<26>;
def InstFormatNDS_BRANCH_10 : InstFormat<27>;
-def InstFormatSMT : InstFormat<28>;
def InstFormatOther : InstFormat<31>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
index aa3e515a8a464..f67374f86c342 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -71,7 +71,7 @@ class SMTVType<bit isFP> : AsmOperandClass {
let DiagnosticType = "InvalidSMTType"#isFP;
let DiagnosticString = !if(isFP,
"This Inst only supports bfp16 and fp16",
- "This Inst only supports i4 and i8, i8 is defuat type"
+ "This Inst only supports i4 and i8, i8 is the default type"
);
let IsOptional = 1;
let DefaultMethod = "defaultSMTVType";
@@ -94,7 +94,7 @@ def SMTI8 : AsmOperandClass {
let Name = "SMTI8";
let RenderMethod = "addSMTVTypeOperand";
let DiagnosticType = "InvalidSMTI8";
- let DiagnosticString = "smt.vmadot with slide only support i8 type";
+ let DiagnosticString = "smt.vmadot with slide only supports i8 type";
let ParserMethod = "parseSMTVType";
let IsOptional = 1;
let DefaultMethod = "defaultSMTVType";
@@ -116,7 +116,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
// Base vector dot product (no slide) format.
class SMTVMADot<bits<2> sign, string opcodestr, bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb), (ins VRM2:$vd, VR:$vs1, VR:$vs2),
- opcodestr, "$vd, $vs1, $vs2", [], InstFormatSMT> {
+ opcodestr, "$vd, $vs1, $vs2", [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -137,7 +137,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVMADotSlide<bits<2> funct2, bits<2> sign, string opcodestr,
bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb), (ins VRM2:$vd, VRM2:$vs1, VR:$vs2),
- opcodestr, "$vd, $vs1, $vs2", [], InstFormatSMT> {
+ opcodestr, "$vd, $vs1, $vs2", [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -157,7 +157,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVMADotII<bits<2> sign, string opcodestr, bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb),
(ins VRM2:$vd, VR:$vs1, VR:$vs2, SMT_INT:$vtype), opcodestr,
- "$vd, $vs1, $vs2$vtype", [], InstFormatSMT> {
+ "$vd, $vs1, $vs2$vtype", [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -177,13 +177,13 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
let UseNamedOperandTable = true;
}
- // Now only support element type i8 for sliding-window dot-product
+ // Currently only i8 element type is supported for sliding-window dot-product
// instructions
class SMTVMADotSlideII<bits<2> slide, bits<2> sign, string opcodestr,
bit EarlyClobber = 0>
: RVInst<(outs VRM2:$vd_wb),
(ins VRM2:$vd, VRM2:$vs1, VR:$vs2, SMT_I8:$vtype), opcodestr,
- "$vd, $vs1, $vs2$vtype", [], InstFormatSMT> {
+ "$vd, $vs1, $vs2$vtype", [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -208,7 +208,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
: RVInst<(outs VRM2NoV0:$vd_wb),
(ins VRM2NoV0:$vd, VRM2NoV0:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm2:$imm2,
SMT_INT:$vtype),
- opcodestr, argstr, [], InstFormatSMT> {
+ opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -238,7 +238,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
: RVInst<(outs VRNoV0V1:$vd_wb),
(ins VRNoV0V1:$vd, VRNoV0V1:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm3:$imm3,
SMT_INT:$vtype),
- opcodestr, argstr, [], InstFormatSMT> {
+ opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -262,7 +262,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVFWMADOT<bits<3> funct3, dag outs, dag ins, string opcodestr,
string argstr>
- : RVInst<outs, ins, opcodestr, argstr, [], InstFormatSMT> {
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
@@ -281,7 +281,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVPACK<bits<7> funct7, bit funct1, dag outs, dag ins,
string opcodestr, string argstr>
- : RVInst<outs, ins, opcodestr, argstr, [], InstFormatSMT> {
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index d28ce0b505675..6cee734e8b31e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -88,7 +88,7 @@ let DecoderNamespace = "XSMT" in {
SMTVMADOTHP<c.Encoding, "smt.vmadot"#c.Name#".hp",
"$vd, $vs1, $vs2, $vmask, $imm3$vtype">, Sched<[]>;
- let DestEEW = EEWSEWx2, Constraints = "$vd = $vd_wb"in {
+ let DestEEW = EEWSEWx2, Constraints = "$vd = $vd_wb" in {
// VFWMADOT
def VFWMADOT :
SMTVFWMADOT<0b100, (outs VRM2:$vd_wb),
diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 9a70ecfc6e3ce..65f6fbf63c990 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -265,7 +265,7 @@
; CHECK-NEXT: xsifivecdiscarddlone - 'XSiFivecdiscarddlone' (SiFive sf.cdiscard.d.l1 Instruction).
; CHECK-NEXT: xsifivecflushdlone - 'XSiFivecflushdlone' (SiFive sf.cflush.d.l1 Instruction).
; CHECK-NEXT: xsmtvdot - 'XSMTVDot' (SpacemiT Vector Dot Product Extension).
-; CHECK-NEXT: xsmtvdotII - 'XSMTVDot' (SpacemiT Vector Dot Product 2.0 Extension).
+; CHECK-NEXT: xsmtvdotii - 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)).
; CHECK-NEXT: xtheadba - 'XTHeadBa' (T-Head address calculation instructions).
; CHECK-NEXT: xtheadbb - 'XTHeadBb' (T-Head basic bit-manipulation instructions).
; CHECK-NEXT: xtheadbs - 'XTHeadBs' (T-Head single-bit instructions).
diff --git a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
index 559dc12be3a3d..3e87d73544fa4 100644
--- a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
@@ -93,7 +93,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_3
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -131,7 +131,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -324,7 +324,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_3
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -364,7 +364,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -404,7 +404,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_5
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -444,7 +444,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_4
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -484,7 +484,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_7
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -524,7 +524,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_6
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
new file mode 100644
index 0000000000000..50913bf9dde2e
--- /dev/null
+++ b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
@@ -0,0 +1,192 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
+# RUN: not llvm-mc -triple riscv64 -mattr=+xsmtvdotii < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+smt.vmadot v3, v2, v0, i4
+// CHECK-ERROR: :[[@LINE-1]]:12: error: invalid operand for instruction{{$}}
+
+smt.vmadot v2, v2, v0, i4
+// CHECK-ERROR: :[[@LINE-1]]:12: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot v0, v2, v0, i4
+// CHECK-ERROR: :[[@LINE-1]]:12: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot v2, v3, v0, i4
+// CHECK-ERROR: :[[@LINE-1]]:12: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot v2, v4, v0, fp16
+// CHECK-ERROR: :[[@LINE-1]]:24: error: This Inst only supports i4 and i8, i8 is the default type
+
+smt.vmadot1 v3, v2, v4, i8
+// CHECK-ERROR: :[[@LINE-1]]:13: error: invalid operand for instruction{{$}}
+
+smt.vmadot1 v0, v3, v4, i8
+// CHECK-ERROR: :[[@LINE-1]]:17: error: invalid operand for instruction{{$}}
+
+smt.vmadot1 v2, v2, v4, i8
+// CHECK-ERROR: :[[@LINE-1]]:13: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot1 v4, v2, v4, i8
+// CHECK-ERROR: :[[@LINE-1]]:13: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot1 v0, v2, v4, i4
+// CHECK-ERROR: :[[@LINE-1]]:25: error: smt.vmadot with slide only supports i8 type{{$}}
+
+smt.vmadot1 v0, v2, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:25: error: smt.vmadot with slide only supports i8 type{{$}}
+
+smt.vmadot.sp v3, v2, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v3, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v2, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot.sp v8, v2, v8, v0, 1, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot.sp v0, v2, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v0, v8, v1, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v4, v0, v1, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v4, v1, v1, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v4, v8, v3, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
+
+smt.vmadot.sp v2, v4, v8, v1, 4, i4
+// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vmadot.hp v2, v2, v8, v0, 4, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot.hp v8, v2, v8, v0, 5, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vmadot.hp v0, v4, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vmadot.hp v2, v0, v8, v0, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+smt.vmadot.hp v8, v2, v0, v0, 5, i4
+// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+
+smt.vmadot.hp v2, v4, v8, v2, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
+
+smt.vmadot.hp v2, v2, v8, v0, 8, i4
+// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 7]
+
+smt.vfwmadot v3, v4, v2, fp16
+// CHECK-ERROR: :[[@LINE-1]]:14: error: invalid operand for instruction{{$}}
+
+smt.vfwmadot v4, v4, v2, fp16
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot v2, v4, v2, fp16
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot v2, v3, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot v2, v4, v3, fp16
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot v4, v2, v3, i8
+// CHECK-ERROR: :[[@LINE-1]]:26: error: This Inst only supports bfp16 and fp16
+
+smt.vfwmadot1 v3, v2, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vfwmadot1 v2, v3, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+smt.vfwmadot1 v2, v2, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot1 v4, v2, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot1 v2, v3, v4, fp16
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+smt.vfwmadot1 v2, v4, v3, fp16
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot1 v0, v2, v4, i8
+// CHECK-ERROR: :[[@LINE-1]]:27: error: This Inst only supports bfp16 and fp16
+
+smt.vnpack.vv v3, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnpack.vv v5, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnpack.vv v1, v3, v5, 4
+// CHECK-ERROR: :[[@LINE-1]]:27: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vnspack.vv v3, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnspack.vv v5, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnspack.vv v1, v3, v5, 4
+// CHECK-ERROR: :[[@LINE-1]]:28: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vnpack4.vv v3, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnpack4.vv v5, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnpack4.vv v1, v3, v5, 4
+// CHECK-ERROR: :[[@LINE-1]]:28: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vnspack.vv v3, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnspack.vv v5, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vnspack.vv v1, v3, v5, 4
+// CHECK-ERROR: :[[@LINE-1]]:28: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vpack.vv v3, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:14: error: invalid operand for instruction{{$}}
+
+smt.vpack.vv v2, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vpack.vv v4, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vpack.vv v0, v1, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vpack.vv v0, v2, v4, 4
+// CHECK-ERROR: :[[@LINE-1]]:26: error: immediate must be an integer in the range [0, 3]{{$}}
+
+smt.vupack.vv v3, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vupack.vv v2, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vupack.vv v4, v2, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vupack.vv v0, v1, v4, 1
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vupack.vv v0, v2, v4, 4
+// CHECK-ERROR: :[[@LINE-1]]:27: error: immediate must be an integer in the range [0, 3]{{$}}
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-valid.s b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
new file mode 100644
index 0000000000000..cbd171b3d3661
--- /dev/null
+++ b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
@@ -0,0 +1,134 @@
+# RUN: llvm-mc -triple=riscv64 -show-encoding -mcpu=spacemit-a100 %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENC
+
+# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+
+# RUN: llvm-mc -triple=riscv64 -filetype=obj -mcpu=spacemit-a100 %s \
+# RUN: | llvm-objdump -d --mcpu=spacemit-a100 -M no-aliases - \
+# RUN: | FileCheck %s --check-prefix=CHECK-INST
+
+// CHECK-ENC: encoding: [0x2b,0xb0,0x2f,0xc2]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot v0, v31, v2, i4
+smt.vmadot v0, v31, v2, i4
+
+// CHECK-ENC: encoding: [0x2b,0xb0,0x2f,0xe2]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot v0, v31, v2, i8
+smt.vmadot v0, v31, v2, i8
+
+// CHECK-ENC: encoding: [0x2b,0xb0,0x2f,0xe2]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot v0, v31, v2, i8
+smt.vmadot v0, v31, v2
+
+// CHECK-ENC: encoding: [0x2b,0x30,0x41,0xe6]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot1 v0, v2, v4, i8
+smt.vmadot1 v0, v2, v4, i8
+
+// CHECK-ENC: encoding: [0x2b,0x30,0x41,0xe6]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot1 v0, v2, v4, i8
+smt.vmadot1 v0, v2, v4, i8
+
+// CHECK-ENC: encoding: [0x2b,0x30,0x41,0xe6]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot1 v0, v2, v4, i8
+smt.vmadot1 v0, v2, v4
+
+// CHECK-ENC: encoding: [0xab,0x38,0x81,0xc8]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.sp v16, v2, v8, v0, 0x1, i4
+smt.vmadot.sp v16, v2, v8, v0, 1, i4
+
+// CHECK-ENC: encoding: [0xab,0x38,0x81,0xe8]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.sp v16, v2, v8, v0, 0x1, i8
+smt.vmadot.sp v16, v2, v8, v0, 1, i8
+
+// CHECK-ENC: encoding: [0xab,0x38,0x81,0xe8]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.sp v16, v2, v8, v0, 0x1, i8
+smt.vmadot.sp v16, v2, v8, v0, 1
+
+// CHECK-ENC: encoding: [0x2b,0xb8,0x81,0xea]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.sp v16, v2, v8, v1, 0x2, i8
+smt.vmadot.sp v16, v2, v8, v1, 2, i8
+
+// CHECK-ENC: encoding: [0x2b,0x38,0x81,0xd0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.hp v16, v2, v8, v0, 0x3, i4
+smt.vmadot.hp v16, v2, v8, v0, 3, i4
+
+// CHECK-ENC: encoding: [0x2b,0x28,0x81,0xf0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.hp v16, v2, v8, v0, 0x2, i8
+smt.vmadot.hp v16, v2, v8, v0, 2, i8
+
+// CHECK-ENC: encoding: [0x2b,0x28,0x81,0xf0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.hp v16, v2, v8, v0, 0x2, i8
+smt.vmadot.hp v16, v2, v8, v0, 2
+
+// CHECK-ENC: encoding: [0x2b,0x48,0x81,0xf2]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.hp v16, v2, v8, v1, 0x4, i8
+smt.vmadot.hp v16, v2, v8, v1, 4, i8
+
+// CHECK-ENC: encoding: [0x2b,0x48,0x81,0xf2]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vmadot.hp v16, v2, v8, v1, 0x4, i8
+smt.vmadot.hp v16, v2, v8, v1, 4
+
+// CHECK-ENC: encoding: [0x2b,0x41,0x62,0x9e]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vfwmadot v2, v4, v6, fp16
+smt.vfwmadot v2, v4, v6, fp16
+
+// CHECK-ENC: encoding: [0x2b,0x41,0x62,0x9e]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vfwmadot v2, v4, v6, fp16
+smt.vfwmadot v2, v4, v6, bfp16
+
+// CHECK-ENC: encoding: [0x2b,0x51,0x62,0x9e]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vfwmadot1 v2, v4, v6, fp16
+smt.vfwmadot1 v2, v4, v6, fp16
+
+// CHECK-ENC: encoding: [0x2b,0x51,0x62,0x9e]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vfwmadot1 v2, v4, v6, fp16
+smt.vfwmadot1 v2, v4, v6, bfp16
+
+// CHECK-ENC: encoding: [0xab,0x90,0x51,0x62]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vnpack.vv v1, v3, v5, 0x1
+smt.vnpack.vv v1, v3, v5, 1
+
+// CHECK-ENC: encoding: [0xab,0xd0,0x51,0x62]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vnspack.vv v1, v3, v5, 0x1
+smt.vnspack.vv v1, v3, v5, 1
+
+// CHECK-ENC: encoding: [0xab,0x90,0x51,0x42]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vnpack4.vv v1, v3, v5, 0x1
+smt.vnpack4.vv v1, v3, v5, 1
+
+// CHECK-ENC: encoding: [0xab,0xd0,0x51,0x42]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vnspack4.vv v1, v3, v5, 0x1
+smt.vnspack4.vv v1, v3, v5, 1
+
+// CHECK-ENC: encoding: [0x2b,0x11,0x52,0x66]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vpack.vv v2, v4, v5, 0x1
+smt.vpack.vv v2, v4, v5, 1
+
+// CHECK-ENC: encoding: [0x2b,0x51,0x52,0x66]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-INST: smt.vupack.vv v2, v4, v5, 0x1
+smt.vupack.vv v2, v4, v5, 1
>From aec25ba06b9d2cbe56f98791328428558e216001 Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Tue, 16 Jun 2026 17:17:51 +0800
Subject: [PATCH 3/8] remove the vtype for vfwmadot && vfwmadot with slide
---
llvm/docs/RISCVUsage.rst | 2 +-
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 28 ++++--------
.../RISCV/Disassembler/RISCVDisassembler.cpp | 4 +-
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 26 +----------
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 2 +-
.../RISCV/RISCVInstrFormatsSpacemitV.td | 26 ++++-------
.../Target/RISCV/RISCVInstrInfoXSpacemiT.td | 8 ++--
llvm/test/MC/RISCV/xsmtvdotii-invalid.s | 44 +++++++++----------
llvm/test/MC/RISCV/xsmtvdotii-valid.s | 18 ++------
9 files changed, 54 insertions(+), 104 deletions(-)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 5d043ca286e02..311a27e1a02a0 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -589,7 +589,7 @@ The current vendor extensions supported are:
LLVM implements the hardware-adapted subset for SpacemiT X60, defined in the `feature document <https://developer.spacemit.com/documentation?token=BWbGwbx7liGW21kq9lucSA6Vnpb#2.1>`__ by SpacemiT. All instructions are prefixed with `smt.` as described in the implementation guide. Note that this implemented subset is `version 1.0.0 of the SpacemiT Vector Dot Product Extension specification`, which is strictly a subset of the full IME specification to reflect the capabilities of SpacemiT X60 hardware correctly.
``XSMTVDotII``
- SpacemiT defines `https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md`.
+ SpacemiT defines the `Integrated Matrix Extension (IME) specification <https://github.com/spacemit-com/docs--ai/blob/main/en/architecture/ime_extension.md>`__
LLVM implements the hardware-adapted subset for SpacemiT A100
Experimental C Intrinsics
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b60560c6cf7b7..449675c66012d 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -694,20 +694,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }
bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }
- // Return true if the operand is a SpacemiT AI Inst support i4/i8
- bool isSMTVType0() const {
+ // Return true if the operand is a valid SpacemiT's Integer Matrix VType(i4/i8)
+ bool isSMTVType() const {
return Kind == KindTy::SMTVType &&
- XSMTVTypeMode::isValidSMTVTypeInt(SMTVType.SMTVType);
- }
-
- // Return true if the operand is a SpacemiT AI Inst support bfp16/fp16
- bool isSMTVType1() const {
- return Kind == KindTy::SMTVType &&
- XSMTVTypeMode::isValidSMTVTypeFP(SMTVType.SMTVType);
+ XSMTVTypeMode::isValidSMTVTypeMode(SMTVType.SMTVType);
}
bool isSMTI8() const {
- return isSMTVType0() && SMTVType.SMTVType == XSMTVTypeMode::SMT_I8;
+ return isSMTVType() && SMTVType.SMTVType == XSMTVTypeMode::SMT_I8;
}
/// Return true if the operand is a valid fli.s floating-point immediate.
@@ -1170,7 +1164,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
break;
case KindTy::SMTVType:
OS << "<smtvtype: ";
- SMTVTypeModeToString(getSMTVType());
+ OS << SMTVTypeModeToString(getSMTVType());
OS << '>';
break;
case KindTy::Fence:
@@ -2804,19 +2798,15 @@ ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands,
ParseStatus RISCVAsmParser::parseSMTVType(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::Identifier))
- return TokError("operand must be a valid SpacemiT VType mnemonic");
+ return TokError(
+ "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
StringRef Str = getLexer().getTok().getIdentifier();
XSMTVTypeMode::SMTVTypeMode VType = XSMTVTypeMode::stringToSMTVTypeMode(Str);
if (!isValidSMTVTypeMode(VType))
- return TokError("SpacemiT AI only supports [i4|i8|bfp16|fp16] Mode");
+ return TokError("SpacemiT's Integer Matrix only supports [i4|i8] mode");
- // bfp16 and fp16 has the same encoding in SpacemiT AI
- // In AsmParser, need to consider bfp16 as fp16
- if (VType == XSMTVTypeMode::SMTVTypeMode::SMT_BFP16) {
- VType = XSMTVTypeMode::SMTVTypeMode::SMT_FP16;
- }
Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
Lex(); // Eat identifier token.
return ParseStatus::Success;
@@ -2841,7 +2831,7 @@ ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
- llvm::SMLoc());
+ SMLoc());
}
ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index f6b138d634b7c..6acbc57f85c5a 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -223,14 +223,14 @@ constexpr auto DecodeVRM2RegisterClass =
constexpr bool PredV0V1Only(uint32_t RegNo) { return RegNo < 2; }
constexpr bool PredNoV0V1(uint32_t RegNo) { return RegNo >= 2; }
-constexpr bool PredVM2NOV0(uint32_t RegNo) { return RegNo != 0; }
+constexpr bool PredNOV0(uint32_t RegNo) { return RegNo != 0; }
constexpr auto DecodeVRV0V1RegisterClass =
DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredV0V1Only>;
constexpr auto DecodeVRNoV0V1RegisterClass =
DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredNoV0V1>;
constexpr auto DecodeVRM2NoV0RegisterClass =
- DecodeFilteredRegisterClass<DecodeVRM2RegisterClass, PredVM2NOV0>;
+ DecodeFilteredRegisterClass<DecodeVRM2RegisterClass, PredNOV0>;
static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ee1966700acee..5963217382b06 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -558,8 +558,6 @@ inline static bool isValidRoundingMode(unsigned Mode) {
namespace XSMTVTypeMode {
enum SMTVTypeMode {
// Define the different SMT VType modes here
- SMT_FP16 = 0,
- SMT_BFP16 = 1,
SMT_I4 = 2,
SMT_I8 = 3,
Invalid
@@ -568,11 +566,7 @@ enum SMTVTypeMode {
inline static StringRef SMTVTypeModeToString(SMTVTypeMode TypeMode) {
switch (TypeMode) {
default:
- llvm_unreachable("Unknown SpacemiT AI VType's mode");
- case XSMTVTypeMode::SMT_BFP16:
- return "bfp16";
- case XSMTVTypeMode::SMT_FP16:
- return "fp16";
+ llvm_unreachable("Unknown VType's mode of SpacemiT Integer Matrix");
case XSMTVTypeMode::SMT_I4:
return "i4";
case XSMTVTypeMode::SMT_I8:
@@ -582,14 +576,12 @@ inline static StringRef SMTVTypeModeToString(SMTVTypeMode TypeMode) {
inline static SMTVTypeMode stringToSMTVTypeMode(StringRef Str) {
return StringSwitch<SMTVTypeMode>(Str)
- .Case("bfp16", XSMTVTypeMode::SMT_BFP16)
- .Case("fp16", XSMTVTypeMode::SMT_FP16)
.Case("i4", XSMTVTypeMode::SMT_I4)
.Case("i8", XSMTVTypeMode::SMT_I8)
.Default(XSMTVTypeMode::Invalid);
}
-inline static bool isValidSMTVTypeInt(unsigned Mode) {
+inline static bool isValidSMTVTypeMode(unsigned Mode) {
switch (Mode) {
default:
return false;
@@ -599,20 +591,6 @@ inline static bool isValidSMTVTypeInt(unsigned Mode) {
}
}
-inline static bool isValidSMTVTypeFP(unsigned Mode) {
- switch (Mode) {
- default:
- return false;
- case XSMTVTypeMode::SMT_BFP16:
- case XSMTVTypeMode::SMT_FP16:
- return true;
- }
-}
-
-inline static bool isValidSMTVTypeMode(unsigned Mode) {
- return isValidSMTVTypeInt(Mode) || isValidSMTVTypeFP(Mode);
-}
-
} // namespace XSMTVTypeMode
namespace RISCVVXRndMode {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 2524c9ae7db2b..1604645520dd1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -168,7 +168,7 @@ void RISCVInstPrinter::printSMTVType(const MCInst *MI, unsigned OpNo,
auto VType =
static_cast<XSMTVTypeMode::SMTVTypeMode>(MI->getOperand(OpNo).getImm());
assert(XSMTVTypeMode::isValidSMTVTypeMode(VType) &&
- "SpacemiT AI only supports [i4|i8|fp16|bfp16] Mode");
+ "SpacemiT's Integer Matrix only supports [i4|i8] mode");
O << ", " << XSMTVTypeMode::SMTVTypeModeToString(VType);
}
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
index f67374f86c342..0001493e2ec7c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -63,33 +63,26 @@ defvar HPEncodes = [HPEncode<0b011, "u">,
HPEncode<0b101, "su">,
HPEncode<0b100, "">];
-// The SpacemiT support element Type
-class SMTVType<bit isFP> : AsmOperandClass {
- let Name = "SMTVType"#isFP;
+def SMTVType : AsmOperandClass {
+ let Name = "SMTVType";
let RenderMethod = "addSMTVTypeOperand";
let ParserMethod = "parseSMTVType";
- let DiagnosticType = "InvalidSMTType"#isFP;
- let DiagnosticString = !if(isFP,
- "This Inst only supports bfp16 and fp16",
- "This Inst only supports i4 and i8, i8 is the default type"
- );
+ let DiagnosticType = "InvalidSMTType";
+ let DiagnosticString =
+ "This Inst only supports i4 and i8, i8 is the default type";
let IsOptional = 1;
let DefaultMethod = "defaultSMTVType";
}
-class SMT_VTYPE<bit isFP> : Operand<XLenVT> {
- let ParserMatchClass = SMTVType<isFP>;
+// SpacemiT's Integer Matrix only supports i4 and i8
+def SMT_INT : Operand<XLenVT> {
+ let ParserMatchClass = SMTVType;
let PrintMethod = "printSMTVType";
let DecoderMethod = "decodeUImmOperand<2>";
let OperandType = "OPERAND_SMTVType";
let OperandNamespace = "RISCVOp";
}
-// Supports i4 and i8
-def SMT_INT : SMT_VTYPE<0>;
-// Supports bfp16 and fp16
-def SMT_FP : SMT_VTYPE<1>;
-
def SMTI8 : AsmOperandClass {
let Name = "SMTI8";
let RenderMethod = "addSMTVTypeOperand";
@@ -266,10 +259,9 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
bits<5> vd;
bits<5> vs1;
bits<5> vs2;
- bits<2> vtype;
let Inst{31} = 0b1;
- let Inst{30-29} = vtype;
+ let Inst{30-29} = 0b00;
let Inst{28-25} = 0b1111;
let Inst{24-20} = vs2;
let Inst{19-15} = vs1;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
index 6cee734e8b31e..2e51186360aec 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
@@ -49,8 +49,8 @@ let DecoderNamespace = "XSMT" in {
class VFWMADTSLIDE_INSN<bits<3> funct3, string opcodestr>
: SMTVFWMADOT<funct3, (outs VRM2:$vd_wb),
- (ins VRM2:$vd, VRM2:$vs1, VR:$vs2, SMT_FP:$vtype),
- opcodestr, "$vd, $vs1, $vs2$vtype">, Sched<[]>;
+ (ins VRM2:$vd, VRM2:$vs1, VR:$vs2),
+ opcodestr, "$vd, $vs1, $vs2">, Sched<[]>;
class VNPACK_INSN<bits<7> funct7, bit funct1, string opcodestr>
: SMTVPACK<funct7, funct1, (outs VR:$vd),
@@ -92,8 +92,8 @@ let DecoderNamespace = "XSMT" in {
// VFWMADOT
def VFWMADOT :
SMTVFWMADOT<0b100, (outs VRM2:$vd_wb),
- (ins VRM2:$vd, VR:$vs1, VR:$vs2, SMT_FP:$vtype),
- "smt.vfwmadot", "$vd, $vs1, $vs2$vtype">, Sched<[]>;
+ (ins VRM2:$vd, VR:$vs1, VR:$vs2),
+ "smt.vfwmadot", "$vd, $vs1, $vs2">, Sched<[]>;
// VFWMADOT Slide
def VFWMADOT1 : VFWMADTSLIDE_INSN<0b101, "smt.vfwmadot1">;
def VFWMADOT2 : VFWMADTSLIDE_INSN<0b110, "smt.vfwmadot2">;
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
index 50913bf9dde2e..1fb740f68d7fb 100644
--- a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
+++ b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
@@ -15,7 +15,7 @@ smt.vmadot v2, v3, v0, i4
// CHECK-ERROR: :[[@LINE-1]]:12: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vmadot v2, v4, v0, fp16
-// CHECK-ERROR: :[[@LINE-1]]:24: error: This Inst only supports i4 and i8, i8 is the default type
+// CHECK-ERROR: :[[@LINE-1]]:24: error: SpacemiT's Integer Matrix only supports [i4|i8] mode{{$}}
smt.vmadot1 v3, v2, v4, i8
// CHECK-ERROR: :[[@LINE-1]]:13: error: invalid operand for instruction{{$}}
@@ -33,7 +33,7 @@ smt.vmadot1 v0, v2, v4, i4
// CHECK-ERROR: :[[@LINE-1]]:25: error: smt.vmadot with slide only supports i8 type{{$}}
smt.vmadot1 v0, v2, v4, fp16
-// CHECK-ERROR: :[[@LINE-1]]:25: error: smt.vmadot with slide only supports i8 type{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:25: error: SpacemiT's Integer Matrix only supports [i4|i8] mode{{$}}
smt.vmadot.sp v3, v2, v8, v0, 3, i4
// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
@@ -84,46 +84,46 @@ smt.vmadot.hp v2, v4, v8, v2, 3, i4
// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
smt.vmadot.hp v2, v2, v8, v0, 8, i4
-// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 7]
+// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 7]{{$}}
-smt.vfwmadot v3, v4, v2, fp16
+smt.vfwmadot v3, v4, v2
// CHECK-ERROR: :[[@LINE-1]]:14: error: invalid operand for instruction{{$}}
-smt.vfwmadot v4, v4, v2, fp16
+smt.vfwmadot v4, v4, v2
// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vfwmadot v2, v4, v2, fp16
+smt.vfwmadot v2, v4, v2
// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vfwmadot v2, v3, v4, fp16
+smt.vfwmadot v2, v3, v4
// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vfwmadot v2, v4, v3, fp16
+smt.vfwmadot v2, v4, v3
// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vfwmadot v4, v2, v3, i8
-// CHECK-ERROR: :[[@LINE-1]]:26: error: This Inst only supports bfp16 and fp16
+// CHECK-ERROR: :[[@LINE-1]]:26: error: invalid operand for instruction{{$}}
-smt.vfwmadot1 v3, v2, v4, fp16
+smt.vfwmadot1 v3, v2, v4
// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
-smt.vfwmadot1 v2, v3, v4, fp16
+smt.vfwmadot1 v2, v3, v4
// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
-smt.vfwmadot1 v2, v2, v4, fp16
+smt.vfwmadot1 v2, v2, v4
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vfwmadot1 v4, v2, v4, fp16
+smt.vfwmadot1 v4, v2, v4
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vfwmadot1 v2, v3, v4, fp16
+smt.vfwmadot1 v2, v3, v4
// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
-smt.vfwmadot1 v2, v4, v3, fp16
+smt.vfwmadot1 v2, v4, v3
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vfwmadot1 v0, v2, v4, i8
-// CHECK-ERROR: :[[@LINE-1]]:27: error: This Inst only supports bfp16 and fp16
+// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
smt.vnpack.vv v3, v3, v5, 1
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
@@ -152,14 +152,14 @@ smt.vnpack4.vv v5, v3, v5, 1
smt.vnpack4.vv v1, v3, v5, 4
// CHECK-ERROR: :[[@LINE-1]]:28: error: immediate must be an integer in the range [0, 3]{{$}}
-smt.vnspack.vv v3, v3, v5, 1
-// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+smt.vnspack4.vv v3, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:17: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vnspack.vv v5, v3, v5, 1
-// CHECK-ERROR: :[[@LINE-1]]:16: error: the destination vector register group cannot overlap the source vector register group{{$}}
+smt.vnspack4.vv v5, v3, v5, 1
+// CHECK-ERROR: :[[@LINE-1]]:17: error: the destination vector register group cannot overlap the source vector register group{{$}}
-smt.vnspack.vv v1, v3, v5, 4
-// CHECK-ERROR: :[[@LINE-1]]:28: error: immediate must be an integer in the range [0, 3]{{$}}
+smt.vnspack4.vv v1, v3, v5, 4
+// CHECK-ERROR: :[[@LINE-1]]:29: error: immediate must be an integer in the range [0, 3]{{$}}
smt.vpack.vv v3, v2, v4, 1
// CHECK-ERROR: :[[@LINE-1]]:14: error: invalid operand for instruction{{$}}
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-valid.s b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
index cbd171b3d3661..28578b75c00df 100644
--- a/llvm/test/MC/RISCV/xsmtvdotii-valid.s
+++ b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
@@ -85,23 +85,13 @@ smt.vmadot.hp v16, v2, v8, v1, 4
// CHECK-ENC: encoding: [0x2b,0x41,0x62,0x9e]
// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
-// CHECK-INST: smt.vfwmadot v2, v4, v6, fp16
-smt.vfwmadot v2, v4, v6, fp16
-
-// CHECK-ENC: encoding: [0x2b,0x41,0x62,0x9e]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
-// CHECK-INST: smt.vfwmadot v2, v4, v6, fp16
-smt.vfwmadot v2, v4, v6, bfp16
-
-// CHECK-ENC: encoding: [0x2b,0x51,0x62,0x9e]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
-// CHECK-INST: smt.vfwmadot1 v2, v4, v6, fp16
-smt.vfwmadot1 v2, v4, v6, fp16
+// CHECK-INST: smt.vfwmadot v2, v4, v6
+smt.vfwmadot v2, v4, v6
// CHECK-ENC: encoding: [0x2b,0x51,0x62,0x9e]
// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
-// CHECK-INST: smt.vfwmadot1 v2, v4, v6, fp16
-smt.vfwmadot1 v2, v4, v6, bfp16
+// CHECK-INST: smt.vfwmadot1 v2, v4, v6
+smt.vfwmadot1 v2, v4, v6
// CHECK-ENC: encoding: [0xab,0x90,0x51,0x62]
// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
>From 18de30b801184d10f3d1ec7ab878262f876cc44e Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Fri, 3 Jul 2026 14:28:32 +0800
Subject: [PATCH 4/8] Relax constriant for sp and sp, when vmask/vcsale use v0
or v1, the vd/vsrc can use the exclude vmask/vscale used reg
---
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 30 +++++++++++++++++
.../RISCV/Disassembler/RISCVDisassembler.cpp | 15 ---------
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 3 ++
llvm/lib/Target/RISCV/RISCVInstrFormats.td | 12 +++++++
.../RISCV/RISCVInstrFormatsSpacemitV.td | 12 +++----
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 4 +--
.../rvv/subregister-undef-early-clobber.mir | 16 +++++-----
llvm/test/MC/RISCV/xsmtvdot-valid.s | 32 +++++++++----------
llvm/test/MC/RISCV/xsmtvdotii-invalid.s | 21 ++++++------
llvm/test/MC/RISCV/xsmtvdotii-valid.s | 24 ++++++++++++++
10 files changed, 109 insertions(+), 60 deletions(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 449675c66012d..7e69dc0d4c254 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -4340,6 +4340,36 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
}
}
+ if (MCID.TSFlags & RISCVII::SMTConstraintMask) {
+ // smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must not
+ // overlap with any of vd, vs1, or vs2.
+ int VMaskIdx =
+ RISCV::getNamedOperandIdx(Inst.getOpcode(), RISCV::OpName::vmask);
+ MCRegister MaskReg = Inst.getOperand(VMaskIdx).getReg();
+ if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
+ return Error(Operands[VMaskIdx]->getStartLoc(),
+ "vmask operand only supports v0 or v1");
+
+ unsigned MaskEnc = RI->getEncodingValue(MaskReg);
+ RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
+ RISCV::OpName::vs2};
+ for (RISCV::OpName OpN : RegOps) {
+ int Idx = RISCV::getNamedOperandIdx(Inst.getOpcode(), OpN);
+ if (Idx < 0 || !Inst.getOperand(Idx).isReg())
+ continue;
+ MCRegister Reg = Inst.getOperand(Idx).getReg();
+ unsigned RegEnc = RI->getEncodingValue(Reg);
+ unsigned RegLmul = getLMULFromVectorRegister(Reg);
+ for (unsigned i = 0; i < RegLmul; i++) {
+ if ((RegEnc + i) == MaskEnc) {
+ SMLoc Loc = Operands[Idx]->getStartLoc();
+ return Error(Loc, Twine("register conflicts with vmask register ") +
+ (MaskReg == RISCV::V0 ? "v0" : "v1"));
+ }
+ }
+ }
+ }
+
return false;
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 6acbc57f85c5a..3b3eb5195a9b4 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -217,21 +217,6 @@ static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo,
return MCDisassembler::Success;
}
-constexpr auto DecodeVRRegisterClass = DecodeSimpleRegisterClass<RISCV::V0, 32>;
-constexpr auto DecodeVRM2RegisterClass =
- DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>;
-
-constexpr bool PredV0V1Only(uint32_t RegNo) { return RegNo < 2; }
-constexpr bool PredNoV0V1(uint32_t RegNo) { return RegNo >= 2; }
-constexpr bool PredNOV0(uint32_t RegNo) { return RegNo != 0; }
-
-constexpr auto DecodeVRV0V1RegisterClass =
- DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredV0V1Only>;
-constexpr auto DecodeVRNoV0V1RegisterClass =
- DecodeFilteredRegisterClass<DecodeVRRegisterClass, PredNoV0V1>;
-constexpr auto DecodeVRM2NoV0RegisterClass =
- DecodeFilteredRegisterClass<DecodeVRM2RegisterClass, PredNOV0>;
-
static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 5963217382b06..9a7292d077e7f 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -282,6 +282,9 @@ enum {
HasTKOpShift = HasTMOpShift + 1,
HasTKOpMask = 1ULL << HasTKOpShift,
+
+ SMTConstraintShift = HasTKOpShift + 1,
+ SMTConstraintMask = 1ULL << SMTConstraintShift,
};
// Helper functions to read TSFlags.
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
index e3c93dc93a686..b945fa957072e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
@@ -108,6 +108,14 @@ def Vrgather : RISCVVConstraint<VS2 = 1, VS1 = 1>;
def Vcompress : RISCVVConstraint<VS2 = 1, VS1 = 1>;
def Sha2Constraint : RISCVVConstraint<VS2 = 1, VS1 = 1>;
+// smt.vmadot with sp and hp: the vmask operand (only use V0 or V1) must not
+// overlap with any of vd, vs1, or vs2.
+class RISCVSMTConstraint<bit DiffClassReg = 0> {
+ bits<1> Value = DiffClassReg;
+}
+def NoSMTConstraint : RISCVSMTConstraint<>;
+def DiffWithMaskConstraint : RISCVSMTConstraint<DiffClassReg = 1>;
+
// The following opcode names match those given in Table 19.1 in the
// RISC-V User-level ISA specification ("RISC-V base opcode map").
class RISCVOpcode<string name, bits<7> val> {
@@ -289,6 +297,10 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
bit HasTkOp = 0;
let TSFlags{31} = HasTkOp;
+
+ // SMT VDOTII register class constraint.
+ RISCVSMTConstraint SMTConstraint = NoSMTConstraint;
+ let TSFlags{32} = SMTConstraint.Value;
}
class RVInst<dag outs, dag ins, string opcodestr, string argstr,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
index 0001493e2ec7c..eeb0e34b30d5f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -198,9 +198,8 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class SMTVMADOTSP<bits<2> sign, string opcodestr, string argstr,
bit EarlyClobber = 0>
- : RVInst<(outs VRM2NoV0:$vd_wb),
- (ins VRM2NoV0:$vd, VRM2NoV0:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm2:$imm2,
- SMT_INT:$vtype),
+ : RVInst<(outs VRM2:$vd_wb),
+ (ins VRM2:$vd, VRM2:$vs1, VR:$vs2, VR:$vmask, uimm2:$imm2, SMT_INT:$vtype),
opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -224,13 +223,13 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
let Constraints =
!if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
let UseNamedOperandTable = true;
+ let SMTConstraint = DiffWithMaskConstraint;
}
class SMTVMADOTHP<bits<3> funct3, string opcodestr, string argstr,
bit EarlyClobber = 0>
- : RVInst<(outs VRNoV0V1:$vd_wb),
- (ins VRNoV0V1:$vd, VRNoV0V1:$vs1, VRNoV0V1:$vs2, VRV0V1:$vmask, uimm3:$imm3,
- SMT_INT:$vtype),
+ : RVInst<(outs VR:$vd_wb),
+ (ins VR:$vd, VR:$vs1, VR:$vs2, VR:$vmask, uimm3:$imm3, SMT_INT:$vtype),
opcodestr, argstr, [], InstFormatR> {
bits<5> vd;
bits<5> vs1;
@@ -251,6 +250,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
let Constraints =
!if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb", "$vd = $vd_wb");
let UseNamedOperandTable = true;
+ let SMTConstraint = DiffWithMaskConstraint;
}
class SMTVFWMADOT<bits<3> funct3, dag outs, dag ins, string opcodestr,
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index a31eb9ad1fb6e..16de1a47f3360 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -867,12 +867,10 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
let DecoderMethod = "DecodeSimpleRegisterClass<RISCV::V0, 32>";
}
-def VRV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (add V0, V1), 1>;
+// def VRV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (add V0, V1), 1>;
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
-def VRNoV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0, V1), 1>;
-
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
(sequence "V%uM2", 6, 0, 2)), 2> {
let DecoderMethod = "DecodeVectorRegisterClass<RISCV::VRM2RegClassID, 32, 2>";
diff --git a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
index 3e87d73544fa4..559dc12be3a3d 100644
--- a/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/subregister-undef-early-clobber.mir
@@ -93,7 +93,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_3
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -131,7 +131,7 @@ body: |
; CHECK-NEXT: %pt2:vrm4 = IMPLICIT_DEF
; CHECK-NEXT: [[INIT_UNDEF:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm4 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm4 = PseudoVRGATHER_VI_M4 %pt2, killed [[INSERT_SUBREG2]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -324,7 +324,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_3
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -364,7 +364,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_1
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_0
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_2
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -404,7 +404,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_5
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -444,7 +444,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_3
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_4
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -484,7 +484,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_7
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
@@ -524,7 +524,7 @@ body: |
; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG]], [[INIT_UNDEF]], %subreg.sub_vrm4_0
; CHECK-NEXT: [[INIT_UNDEF1:%[0-9]+]]:vrm2nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG1]], [[INIT_UNDEF1]], %subreg.sub_vrm2_2
- ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:vrnov0v1 = INIT_UNDEF
+ ; CHECK-NEXT: [[INIT_UNDEF2:%[0-9]+]]:zzz_vrmf8nov0 = INIT_UNDEF
; CHECK-NEXT: [[INSERT_SUBREG3:%[0-9]+]]:vrm8 = INSERT_SUBREG [[INSERT_SUBREG2]], [[INIT_UNDEF2]], %subreg.sub_vrm1_6
; CHECK-NEXT: early-clobber %6:vrm8 = PseudoVRGATHER_VI_M8 %pt2, killed [[INSERT_SUBREG3]], 0, 0 /* vl */, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
; CHECK-NEXT: [[ADDI1:%[0-9]+]]:gpr = ADDI $x0, 0
diff --git a/llvm/test/MC/RISCV/xsmtvdot-valid.s b/llvm/test/MC/RISCV/xsmtvdot-valid.s
index bde8a42403c1b..4f402236099d6 100644
--- a/llvm/test/MC/RISCV/xsmtvdot-valid.s
+++ b/llvm/test/MC/RISCV/xsmtvdot-valid.s
@@ -11,84 +11,84 @@
// CHECK-ENC: encoding: [0x2b,0x38,0x80,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot v16, v0, v8
smt.vmadot v16, v0, v8
// CHECK-ENC: encoding: [0x2b,0x89,0x90,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadotu v18, v1, v9
smt.vmadotu v18, v1, v9
// CHECK-ENC: encoding: [0x2b,0x2a,0xa1,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadotsu v20, v2, v10
smt.vmadotsu v20, v2, v10
// CHECK-ENC: encoding: [0x2b,0x9b,0xb1,0xe2]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadotus v22, v3, v11
smt.vmadotus v22, v3, v11
// CHECK-ENC: encoding: [0x2b,0x3c,0xc8,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot1 v24, v16, v12
smt.vmadot1 v24, v16, v12
// CHECK-ENC: encoding: [0x2b,0x0d,0xd9,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot1u v26, v18, v13
smt.vmadot1u v26, v18, v13
// CHECK-ENC: encoding: [0x2b,0x2e,0xea,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot1su v28, v20, v14
smt.vmadot1su v28, v20, v14
// CHECK-ENC: encoding: [0x2b,0x1f,0xfb,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot1us v30, v22, v15
smt.vmadot1us v30, v22, v15
// CHECK-ENC: encoding: [0x2b,0x70,0x4c,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot2 v0, v24, v4
smt.vmadot2 v0, v24, v4
// CHECK-ENC: encoding: [0x2b,0x41,0x5d,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot2u v2, v26, v5
smt.vmadot2u v2, v26, v5
// CHECK-ENC: encoding: [0x2b,0x62,0x6e,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot2su v4, v28, v6
smt.vmadot2su v4, v28, v6
// CHECK-ENC: encoding: [0x2b,0x53,0x8f,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot2us v6, v30, v8
smt.vmadot2us v6, v30, v8
// CHECK-ENC: encoding: [0x2b,0xb1,0x80,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot3 v2, v0, v8
smt.vmadot3 v2, v0, v8
// CHECK-ENC: encoding: [0x2b,0x85,0x91,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot3u v10, v2, v9
smt.vmadot3u v10, v2, v9
// CHECK-ENC: encoding: [0x2b,0xa6,0xa2,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot3su v12, v4, v10
smt.vmadot3su v12, v4, v10
// CHECK-ENC: encoding: [0x2b,0x97,0xb3,0xe6]
-// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
+// CHECK-ERROR: instruction requires the following: 'XSMTVDot' (SpacemiT Vector Dot Product Extension){{$}}
// CHECK-INST: smt.vmadot3us v14, v6, v11
smt.vmadot3us v14, v6, v11
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
index 1fb740f68d7fb..fe47780d81627 100644
--- a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
+++ b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
@@ -48,19 +48,16 @@ smt.vmadot.sp v8, v2, v8, v0, 1, i4
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vmadot.sp v0, v2, v8, v0, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:15: error: register conflicts with vmask register v0{{$}}
smt.vmadot.sp v2, v0, v8, v1, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
-
-smt.vmadot.sp v2, v4, v0, v1, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:19: error: register conflicts with vmask register v1{{$}}
smt.vmadot.sp v2, v4, v1, v1, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:23: error: register conflicts with vmask register v1{{$}}
smt.vmadot.sp v2, v4, v8, v3, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:27: error: vmask operand only supports v0 or v1{{$}}
smt.vmadot.sp v2, v4, v8, v1, 4, i4
// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 3]{{$}}
@@ -72,18 +69,18 @@ smt.vmadot.hp v8, v2, v8, v0, 5, i4
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vmadot.hp v0, v4, v8, v0, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:15: error: register conflicts with vmask register v0{{$}}
smt.vmadot.hp v2, v0, v8, v0, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:19: error: register conflicts with vmask register v0{{$}}
smt.vmadot.hp v8, v2, v0, v0, 5, i4
-// CHECK-ERROR: :[[@LINE-1]]:23: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:23: error: register conflicts with vmask register v0{{$}}
smt.vmadot.hp v2, v4, v8, v2, 3, i4
-// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:27: error: vmask operand only supports v0 or v1{{$}}
-smt.vmadot.hp v2, v2, v8, v0, 8, i4
+smt.vmadot.hp v2, v4, v8, v0, 8, i4
// CHECK-ERROR: :[[@LINE-1]]:31: error: immediate must be an integer in the range [0, 7]{{$}}
smt.vfwmadot v3, v4, v2
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-valid.s b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
index 28578b75c00df..9b4e1a9c95691 100644
--- a/llvm/test/MC/RISCV/xsmtvdotii-valid.s
+++ b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
@@ -58,6 +58,12 @@ smt.vmadot.sp v16, v2, v8, v0, 1
// CHECK-INST: smt.vmadot.sp v16, v2, v8, v1, 0x2, i8
smt.vmadot.sp v16, v2, v8, v1, 2, i8
+// CHECK-ENC: smt.vmadot.sp v16, v2, v1, v0, 1, i4 # encoding: [0xab,0x38,0x11,0xc8]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
+// CHECK-INST: smt.vmadot.sp v16, v2, v1, v0, 0x1, i4
+// CHECK-UNKNOWN: c81138ab <unknown>
+smt.vmadot.sp v16, v2, v1, v0, 1, i4
+
// CHECK-ENC: encoding: [0x2b,0x38,0x81,0xd0]
// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vmadot.hp v16, v2, v8, v0, 0x3, i4
@@ -83,6 +89,24 @@ smt.vmadot.hp v16, v2, v8, v1, 4, i8
// CHECK-INST: smt.vmadot.hp v16, v2, v8, v1, 0x4, i8
smt.vmadot.hp v16, v2, v8, v1, 4
+// CHECK-ENC: smt.vmadot.hp v1, v2, v8, v0, 3, i4 # encoding: [0xab,0x30,0x81,0xd0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
+// CHECK-INST: smt.vmadot.hp v1, v2, v8, v0, 0x3, i4
+// CHECK-UNKNOWN: d08130ab <unknown>
+smt.vmadot.hp v1, v2, v8, v0, 3, i4
+
+// CHECK-ENC: smt.vmadot.hp v16, v1, v8, v0, 3, i4 # encoding: [0x2b,0xb8,0x80,0xd0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
+// CHECK-INST: smt.vmadot.hp v16, v1, v8, v0, 0x3, i4
+// CHECK-UNKNOWN: d080b82b <unknown>
+smt.vmadot.hp v16, v1, v8, v0, 3, i4
+
+// CHECK-ENC: smt.vmadot.hp v16, v2, v1, v0, 3, i4 # encoding: [0x2b,0x38,0x11,0xd0]
+// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0))
+// CHECK-INST: smt.vmadot.hp v16, v2, v1, v0, 0x3, i4
+// CHECK-UNKNOWN: d011382b <unknown>
+smt.vmadot.hp v16, v2, v1, v0, 3, i4
+
// CHECK-ENC: encoding: [0x2b,0x41,0x62,0x9e]
// CHECK-ERROR: instruction requires the following: 'XSMTVDotII' (SpacemiT Vector Extension for Matrix(2.0)){{$}}
// CHECK-INST: smt.vfwmadot v2, v4, v6
>From 8e07ef6fae5d21c828cd332da87b0c06804b4f44 Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Fri, 3 Jul 2026 15:05:09 +0800
Subject: [PATCH 5/8] clang-format
---
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 7e69dc0d4c254..8a1346bb0f2e1 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -694,7 +694,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }
bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }
- // Return true if the operand is a valid SpacemiT's Integer Matrix VType(i4/i8)
+ // Return true if the operand is a valid SpacemiT's Integer Matrix
+ // VType(i4/i8).
bool isSMTVType() const {
return Kind == KindTy::SMTVType &&
XSMTVTypeMode::isValidSMTVTypeMode(SMTVType.SMTVType);
>From 8b061e3901eff6f064394b9e9cd3a73e312c593f Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Tue, 7 Jul 2026 16:46:04 +0800
Subject: [PATCH 6/8] Build and Test Windows, the test: samtvdotii always
failed
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 9a7292d077e7f..f114486f151da 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -152,7 +152,7 @@ enum OperandType : unsigned {
// RISCVII - This namespace holds all of the target specific flags that
// instruction info tracks. All definitions must match RISCVInstrFormats.td.
namespace RISCVII {
-enum {
+enum : uint64_t {
InstFormatPseudo = 0,
InstFormatR = 1,
InstFormatR4 = 2,
>From 5a3847b40d7f6558ea63e6c2cfaf0129629cae5d Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Wed, 8 Jul 2026 10:01:33 +0800
Subject: [PATCH 7/8] fix the comments
---
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 5 +----
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +-
llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td | 2 +-
llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 2 --
4 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 8a1346bb0f2e1..b52c38eae8801 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1425,8 +1425,6 @@ static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
unsigned RegClassID;
if (Kind == MCK_VRM2)
RegClassID = RISCV::VRM2RegClassID;
- else if (Kind == MCK_VRM2NoV0)
- RegClassID = RISCV::VRM2NoV0RegClassID;
else if (Kind == MCK_VRM4)
RegClassID = RISCV::VRM4RegClassID;
else if (Kind == MCK_VRM8)
@@ -1501,8 +1499,7 @@ unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
// As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
// the register from VR to VRM2/VRM4/VRM8 if necessary.
- if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM2NoV0 ||
- Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
+ if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
Op.Reg.Reg = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind);
if (!Op.Reg.Reg)
return Match_InvalidOperand;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index f114486f151da..e54d57d9f4451 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -569,7 +569,7 @@ enum SMTVTypeMode {
inline static StringRef SMTVTypeModeToString(SMTVTypeMode TypeMode) {
switch (TypeMode) {
default:
- llvm_unreachable("Unknown VType's mode of SpacemiT Integer Matrix");
+ llvm_unreachable("Unknown VType mode of SpacemiT Integer Matrix");
case XSMTVTypeMode::SMT_I4:
return "i4";
case XSMTVTypeMode::SMT_I8:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
index eeb0e34b30d5f..90652e894e4b4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -93,7 +93,7 @@ def SMTI8 : AsmOperandClass {
let DefaultMethod = "defaultSMTVType";
}
-def SMT_I8 : Operand<XLenVT> {
+def SMT_I8 : Operand<XLenVT> {
let ParserMatchClass = SMTI8;
let PrintMethod = "printSMTVType";
let DecoderMethod = "decodeUImmOperand<2>";
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 16de1a47f3360..a3f968b5ab76f 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -867,8 +867,6 @@ def VR : VReg<!listconcat(VM1VTs, VMaskVTs),
let DecoderMethod = "DecodeSimpleRegisterClass<RISCV::V0, 32>";
}
-// def VRV0V1 : VReg<!listconcat(VM1VTs, VMaskVTs), (add V0, V1), 1>;
-
def VRNoV0 : VReg<!listconcat(VM1VTs, VMaskVTs), (sub VR, V0), 1>;
def VRM2 : VReg<VM2VTs, (add (sequence "V%uM2", 8, 31, 2),
>From d4e3690b27f1a72bb48640f9ec5872da92305b01 Mon Sep 17 00:00:00 2001
From: wengliqin <liqin.weng at spacemit.com>
Date: Thu, 9 Jul 2026 12:44:06 +0800
Subject: [PATCH 8/8] rebase main and fix the failed tests and address the
comments
---
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +-
llvm/test/MC/RISCV/xsmtvdotii-invalid.s | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index b52c38eae8801..8563f678464a6 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -4362,7 +4362,7 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
if ((RegEnc + i) == MaskEnc) {
SMLoc Loc = Operands[Idx]->getStartLoc();
return Error(Loc, Twine("register conflicts with vmask register ") +
- (MaskReg == RISCV::V0 ? "v0" : "v1"));
+ RISCVInstPrinter::getRegisterName(MaskReg));
}
}
}
diff --git a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
index fe47780d81627..2ffebd5dab7a2 100644
--- a/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
+++ b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
@@ -99,7 +99,7 @@ smt.vfwmadot v2, v4, v3
// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vfwmadot v4, v2, v3, i8
-// CHECK-ERROR: :[[@LINE-1]]:26: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:26: error: unexpected extra operand for instruction{{$}}
smt.vfwmadot1 v3, v2, v4
// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
@@ -120,7 +120,7 @@ smt.vfwmadot1 v2, v4, v3
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
smt.vfwmadot1 v0, v2, v4, i8
-// CHECK-ERROR: :[[@LINE-1]]:27: error: invalid operand for instruction{{$}}
+// CHECK-ERROR: :[[@LINE-1]]:27: error: unexpected extra operand for instruction{{$}}
smt.vnpack.vv v3, v3, v5, 1
// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
More information about the cfe-commits
mailing list