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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
