[clang] 13e9cc2 - [RISCV] Support spacemit vsmtvdotii extensions (#202533)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 13 04:05:57 PDT 2026
Author: LiqinWeng
Date: 2026-07-13T19:05:52+08:00
New Revision: 13e9cc22ce4edfd4b1347d6bed9cd95868e2d4f4
URL: https://github.com/llvm/llvm-project/commit/13e9cc22ce4edfd4b1347d6bed9cd95868e2d4f4
DIFF: https://github.com/llvm/llvm-project/commit/13e9cc22ce4edfd4b1347d6bed9cd95868e2d4f4.diff
LOG: [RISCV] Support spacemit vsmtvdotii extensions (#202533)
SPEC: https://github.com/spacemit-com/docs-ai/blob/main/en/architecture/ime_extension.md
Added:
llvm/test/MC/RISCV/xsmtvdotii-invalid.s
llvm/test/MC/RISCV/xsmtvdotii-valid.s
Modified:
clang/test/Driver/print-enabled-extensions/riscv-spacemit-a100.c
clang/test/Driver/print-supported-extensions-riscv.c
clang/test/Driver/riscv-cpus.c
llvm/docs/RISCVUsage.rst
llvm/docs/ReleaseNotes.md
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrFormats.td
llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoXSpacemiT.td
llvm/lib/Target/RISCV/RISCVProcessors.td
llvm/test/CodeGen/RISCV/features-info.ll
llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Removed:
################################################################################
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..4b8e79b2e16b6 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 34c651891538d..a9af276367817 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 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/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..72428398fc465 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -586,7 +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 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/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 4548be37e7f4c..36fde51b3a3ef 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -263,6 +263,7 @@ Makes programs 10x faster by doing Special New Thing.
Absolute Difference) extension.
* Adds CodeGen support for the 'Zvabd` extension.
* `-mcpu=spacemit-a100` was added.
+* Adds assembler support for the `XSMTVDotII` (SpacemiT Vector Extension for Matrix 2.0) extension.
* The opt-in `-riscv-enable-p-ext-simd-codegen` flag has been removed. P extension SIMD code generation is now enabled automatically if the P extension is supported.
* `-mcpu=xt-c910v2` and `-mcpu=xt-c920v2` were added.
* Adds experimental assembler support for the 'Zvzip` (RISC-V Vector
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 2e287b5386d10..8563f678464a6 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,17 @@ 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).
+ bool isSMTVType() const {
+ return Kind == KindTy::SMTVType &&
+ XSMTVTypeMode::isValidSMTVTypeMode(SMTVType.SMTVType);
+ }
+
+ bool isSMTI8() const {
+ return isSMTVType() && 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 +1121,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 +1163,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
OS << roundingModeToString(getFRM());
OS << '>';
break;
+ case KindTy::SMTVType:
+ OS << "<smtvtype: ";
+ OS << SMTVTypeModeToString(getSMTVType());
+ OS << '>';
+ break;
case KindTy::Fence:
OS << "<fence: ";
OS << getFence();
@@ -1214,6 +1246,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 +1386,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.
@@ -2748,6 +2794,22 @@ 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's Integer Matrix VType mnemonic");
+
+ StringRef Str = getLexer().getTok().getIdentifier();
+ XSMTVTypeMode::SMTVTypeMode VType = XSMTVTypeMode::stringToSMTVTypeMode(Str);
+
+ if (!isValidSMTVTypeMode(VType))
+ return TokError("SpacemiT's Integer Matrix only supports [i4|i8] mode");
+
+ 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 +2827,11 @@ ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
return ParseStatus::Success;
}
+std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
+ return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
+ SMLoc());
+}
+
ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {
const AsmToken &Tok = getLexer().getTok();
@@ -4271,6 +4338,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 ") +
+ RISCVInstPrinter::getRegisterName(MaskReg));
+ }
+ }
+ }
+ }
+
return false;
}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index cf1f8edf16976..3b3eb5195a9b4 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -531,7 +531,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..e54d57d9f4451 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -144,13 +144,15 @@ enum OperandType : unsigned {
OPERAND_BCC_OPCODE,
OPERAND_VMASK,
+ OPERAND_SMTVType,
+ OPERAND_SMTI8,
};
} // namespace RISCVOp
// 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,
@@ -280,6 +282,9 @@ enum {
HasTKOpShift = HasTMOpShift + 1,
HasTKOpMask = 1ULL << HasTKOpShift,
+
+ SMTConstraintShift = HasTKOpShift + 1,
+ SMTConstraintMask = 1ULL << SMTConstraintShift,
};
// Helper functions to read TSFlags.
@@ -553,6 +558,44 @@ inline static bool isValidRoundingMode(unsigned Mode) {
}
} // namespace RISCVFPRndMode
+namespace XSMTVTypeMode {
+enum SMTVTypeMode {
+ // Define the
diff erent SMT VType modes here
+ SMT_I4 = 2,
+ SMT_I8 = 3,
+ Invalid
+};
+
+inline static StringRef SMTVTypeModeToString(SMTVTypeMode TypeMode) {
+ switch (TypeMode) {
+ default:
+ llvm_unreachable("Unknown VType mode of SpacemiT Integer Matrix");
+ case XSMTVTypeMode::SMT_I4:
+ return "i4";
+ case XSMTVTypeMode::SMT_I8:
+ return "i8";
+ }
+}
+
+inline static SMTVTypeMode stringToSMTVTypeMode(StringRef Str) {
+ return StringSwitch<SMTVTypeMode>(Str)
+ .Case("i4", XSMTVTypeMode::SMT_I4)
+ .Case("i8", XSMTVTypeMode::SMT_I8)
+ .Default(XSMTVTypeMode::Invalid);
+}
+
+inline static bool isValidSMTVTypeMode(unsigned Mode) {
+ switch (Mode) {
+ default:
+ return false;
+ case XSMTVTypeMode::SMT_I4:
+ case XSMTVTypeMode::SMT_I8:
+ return true;
+ }
+}
+
+} // 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..1604645520dd1 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's Integer Matrix only supports [i4|i8] 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..03d28b8448ba4 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 Extension for Matrix 2.0",
+ [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..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 66535c4e77f4a..90652e894e4b4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrFormatsSpacemitV.td
@@ -54,6 +54,53 @@ 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, "">];
+
+def SMTVType : AsmOperandClass {
+ let Name = "SMTVType";
+ let RenderMethod = "addSMTVTypeOperand";
+ let ParserMethod = "parseSMTVType";
+ let DiagnosticType = "InvalidSMTType";
+ let DiagnosticString =
+ "This Inst only supports i4 and i8, i8 is the default type";
+ let IsOptional = 1;
+ let DefaultMethod = "defaultSMTVType";
+}
+
+// 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";
+}
+
+def SMTI8 : AsmOperandClass {
+ let Name = "SMTI8";
+ let RenderMethod = "addSMTVTypeOperand";
+ let DiagnosticType = "InvalidSMTI8";
+ let DiagnosticString = "smt.vmadot with slide only supports 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
//===----------------------------------------------------------------------===//
@@ -99,5 +146,146 @@ 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", [], InstFormatR> {
+ 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;
+ }
+
+ // 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", [], InstFormatR> {
+ 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 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;
+ 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;
+ let SMTConstraint = DiffWithMaskConstraint;
+ }
+
+ class SMTVMADOTHP<bits<3> funct3, string opcodestr, string argstr,
+ bit EarlyClobber = 0>
+ : 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;
+ 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;
+ let SMTConstraint = DiffWithMaskConstraint;
+ }
+
+ class SMTVFWMADOT<bits<3> funct3, dag outs, dag ins, string opcodestr,
+ string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+ bits<5> vd;
+ bits<5> vs1;
+ bits<5> vs2;
+
+ let Inst{31} = 0b1;
+ let Inst{30-29} = 0b00;
+ 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, [], InstFormatR> {
+ 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..2e51186360aec 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),
+ opcodestr, "$vd, $vs1, $vs2">, 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.vfwmadot", "$vd, $vs1, $vs2">, 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 a006cea4c3157..6adbbe0af3782 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/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll
index 351018e3fe894..142e6b2694937 100644
--- a/llvm/test/CodeGen/RISCV/features-info.ll
+++ b/llvm/test/CodeGen/RISCV/features-info.ll
@@ -266,6 +266,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 - '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/MC/RISCV/xsmtvdotii-invalid.s b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
new file mode 100644
index 0000000000000..2ffebd5dab7a2
--- /dev/null
+++ b/llvm/test/MC/RISCV/xsmtvdotii-invalid.s
@@ -0,0 +1,189 @@
+// 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: 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{{$}}
+
+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: 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{{$}}
+
+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: register conflicts with vmask register v0{{$}}
+
+smt.vmadot.sp v2, v0, v8, v1, 3, i4
+// 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: register conflicts with vmask register v1{{$}}
+
+smt.vmadot.sp v2, v4, v8, v3, 3, i4
+// 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]{{$}}
+
+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: register conflicts with vmask register v0{{$}}
+
+smt.vmadot.hp v2, v0, v8, v0, 3, i4
+// 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: register conflicts with vmask register v0{{$}}
+
+smt.vmadot.hp v2, v4, v8, v2, 3, i4
+// CHECK-ERROR: :[[@LINE-1]]:27: error: vmask operand only supports v0 or v1{{$}}
+
+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
+// CHECK-ERROR: :[[@LINE-1]]:14: error: invalid operand for instruction{{$}}
+
+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
+// CHECK-ERROR: :[[@LINE-1]]:14: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+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
+// 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: unexpected extra operand for instruction{{$}}
+
+smt.vfwmadot1 v3, v2, v4
+// CHECK-ERROR: :[[@LINE-1]]:15: error: invalid operand for instruction{{$}}
+
+smt.vfwmadot1 v2, v3, v4
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+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
+// CHECK-ERROR: :[[@LINE-1]]:15: error: the destination vector register group cannot overlap the source vector register group{{$}}
+
+smt.vfwmadot1 v2, v3, v4
+// CHECK-ERROR: :[[@LINE-1]]:19: error: invalid operand for instruction{{$}}
+
+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: 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{{$}}
+
+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.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.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.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{{$}}
+
+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..91ca56c3a386e
--- /dev/null
+++ b/llvm/test/MC/RISCV/xsmtvdotii-valid.s
@@ -0,0 +1,148 @@
+# 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: 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
+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: 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
+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
+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){{$}}
+// 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
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
More information about the cfe-commits
mailing list