diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 39002d7b4780a..4ced50ca97821 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -164,6 +164,16 @@ // CHECK-NEXT: xmipscmov 1.0 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov)) // CHECK-NEXT: xmipslsp 1.0 'XMIPSLSP' (MIPS optimization for hardware load-store bonding) // CHECK-NEXT: xsfcease 1.0 'XSfcease' (SiFive sf.cease Instruction) +// CHECK-NEXT: xsfmm128t 0.6 'XSfmm128t' (TE=128 configuration) +// CHECK-NEXT: xsfmm16t 0.6 'XSfmm16t' (TE=16 configuration) +// CHECK-NEXT: xsfmm32a16f 0.6 'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)) +// CHECK-NEXT: xsfmm32a32f 0.6 'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b) +// CHECK-NEXT: xsfmm32a8f 0.6 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8) +// CHECK-NEXT: xsfmm32a8i 0.6 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b) +// CHECK-NEXT: xsfmm32t 0.6 'XSfmm32t' (TE=32 configuration) +// CHECK-NEXT: xsfmm64a64f 0.6 'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64) +// CHECK-NEXT: xsfmm64t 0.6 'XSfmm64t' (TE=64 configuration) +// CHECK-NEXT: xsfmmbase 0.6 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero) // CHECK-NEXT: xsfvcp 1.0 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions) // CHECK-NEXT: xsfvfnrclipxfqf 1.0 'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions) // CHECK-NEXT: xsfvfwmaccqqq 1.0 'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4)) diff --git a/clang/test/Preprocessor/riscv-target-features-sifive.c b/clang/test/Preprocessor/riscv-target-features-sifive.c new file mode 100644 index 0000000000000..e4c03876bd94b --- /dev/null +++ b/clang/test/Preprocessor/riscv-target-features-sifive.c @@ -0,0 +1,79 @@ +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm128t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM128T %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm128t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM128T %s +// CHECK-XSFMM128T: __riscv_xsfmm128t 6000{{$}} +// +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm16t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM16T %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm16t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM16T %s +// CHECK-XSFMM16T: __riscv_xsfmm16t 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm32a8i -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a8I %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm32a8i -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a8I %s +// CHECK-XSFMM32a8I: __riscv_xsfmm32a8i 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm32a8f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32A8F %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm32a8f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32A8F %s +// CHECK-XSFMM32A8F: __riscv_xsfmm32a8f 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm32a16f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a16F %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm32a16f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a16F %s +// CHECK-XSFMM32a16F: __riscv_xsfmm32a16f 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm32a32f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a32F %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm32a32f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32a32F %s +// CHECK-XSFMM32a32F: __riscv_xsfmm32a32f 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm32t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32T %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm32t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM32T %s +// CHECK-XSFMM32T: __riscv_xsfmm32t 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm64a64f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM64a64f %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm64a64f -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM64a64f %s +// CHECK-XSFMM64a64f: __riscv_xsfmm64a64f 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmm64t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM64T %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmm64t -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMM64T %s +// CHECK-XSFMM64T: __riscv_xsfmm64t 6000{{$}} + +// RUN: %clang --target=riscv32 \ +// RUN: -march=rv32i_zve32x_xsfmmbase -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMMBASE %s +// RUN: %clang --target=riscv64 \ +// RUN: -march=rv64i_zve32x_xsfmmbase -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFMMBASE %s +// CHECK-XSFMMBASE: __riscv_xsfmmbase 6000{{$}} diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 137b537f00ea0..fa5b9a3f509c6 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -389,6 +389,9 @@ The current vendor extensions supported are: ``XVentanaCondOps`` LLVM implements `version 1.0.0 of the VTx-family custom instructions specification `__ by Ventana Micro Systems. All instructions are prefixed with `vt.` as described in the specification, and the riscv-toolchain-convention document linked above. These instructions are only available for riscv64 at this time. +``Xsfmm*`` + LLVM implements `version 0.6 of the Xsfmm Family of Attached Matrix Extensions Specification `__ by SiFive. All instructions are prefixed with `sf.` as described in the specification. + ``XSfvcp`` LLVM implements `version 1.1.0 of the SiFive Vector Coprocessor Interface (VCIX) Software Specification `__ by SiFive. All instructions are prefixed with `sf.vc.` as described in the specification, and the riscv-toolchain-convention document linked above. diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 526d6b4002bba..b84789553165e 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -159,6 +159,8 @@ Changes to the RISC-V Backend * Adds assembler support for ``.option exact``, which disables automatic compression, and branch and linker relaxation. This can be disabled with ``.option noexact``, which is also the default. +* Adds experimental assembler support for the SiFive Xsfmm* Attached Matrix + Extensions. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/include/llvm/TargetParser/RISCVTargetParser.h b/llvm/include/llvm/TargetParser/RISCVTargetParser.h index e0105685c210d..a529479b546d9 100644 --- a/llvm/include/llvm/TargetParser/RISCVTargetParser.h +++ b/llvm/include/llvm/TargetParser/RISCVTargetParser.h @@ -89,6 +89,8 @@ inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic); +unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt); + inline static VLMUL getVLMUL(unsigned VType) { unsigned VLMul = VType & 0x7; return static_cast(VLMul); @@ -118,10 +120,34 @@ inline static unsigned getSEW(unsigned VType) { return decodeVSEW(VSEW); } +inline static unsigned decodeTWiden(unsigned TWiden) { + assert((TWiden == 1 || TWiden == 2 || TWiden == 3) && + "Unexpected TWiden value"); + return 1 << (TWiden - 1); +} + +inline static bool hasXSfmmWiden(unsigned VType) { + unsigned TWiden = (VType >> 9) & 0x3; + return TWiden != 0; +} + +inline static unsigned getXSfmmWiden(unsigned VType) { + unsigned TWiden = (VType >> 9) & 0x3; + assert(TWiden != 0 && "Invalid widen value"); + return 1 << (TWiden - 1); +} + +static inline bool isValidXSfmmVType(unsigned VTypeI) { + return (VTypeI & ~0x738) == 0 && RISCVVType::hasXSfmmWiden(VTypeI) && + RISCVVType::getSEW(VTypeI) * RISCVVType::getXSfmmWiden(VTypeI) <= 64; +} + inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; } +inline static bool isAltFmt(unsigned VType) { return VType & 0x100; } + void printVType(unsigned VType, raw_ostream &OS); unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul); diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 013944787ff2d..a54b826d4a2fc 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -77,6 +77,12 @@ class RISCVAsmParser : public MCTargetAsmParser { VTypeState_Done, }; + enum WWEEState { + WWEEState_Widen, + WWEEState_SEW, + WWEEState_Done, + }; + SmallVector FeatureBitStack; SmallVector ParserOptionsStack; @@ -125,6 +131,9 @@ class RISCVAsmParser : public MCTargetAsmParser { bool &MaskAgnostic); bool generateVTypeError(SMLoc ErrorLoc); + bool parseXSfmmVTypeToken(const AsmToken &Tok, WWEEState &State, unsigned &WW, + unsigned &EE, bool &AltFmt); + bool generateXSfmmVTypeError(SMLoc ErrorLoc); // Helper to actually emit an instruction to the MCStreamer. Also, when // possible, compression of the instruction is performed. void emitToStreamer(MCStreamer &S, const MCInst &Inst); @@ -222,6 +231,7 @@ class RISCVAsmParser : public MCTargetAsmParser { } ParseStatus parseRegReg(OperandVector &Operands); + ParseStatus parseXSfmmVType(OperandVector &Operands); ParseStatus parseRetval(OperandVector &Operands); ParseStatus parseZcmpStackAdj(OperandVector &Operands, bool ExpectNegative = false); @@ -635,6 +645,10 @@ struct RISCVOperand final : public MCParsedAsmOperand { return isUImm<11>(); } + bool isXSfmmVType() const { + return Kind == KindTy::VType && RISCVVType::isValidXSfmmVType(VType.Val); + } + /// Return true if the operand is a valid for the fence instruction e.g. /// ('iorw'). bool isFenceArg() const { return Kind == KindTy::Fence; } @@ -2302,6 +2316,81 @@ bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) { "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); } +bool RISCVAsmParser::parseXSfmmVTypeToken(const AsmToken &Tok, WWEEState &State, + unsigned &WW, unsigned &EE, + bool &AltFmt) { + if (getLexer().isNot(AsmToken::Identifier)) + return true; + + StringRef Identifier = getTok().getIdentifier(); + + switch (State) { + case WWEEState_SEW: + if (!Identifier.consume_front("e")) + break; + if (Identifier.getAsInteger(10, EE)) { + if (Identifier != "16alt") + break; + + AltFmt = true; + EE = 16; + } + if (!RISCVVType::isValidSEW(EE)) + break; + State = WWEEState_Widen; + return false; + case WWEEState_Widen: + if (!Identifier.consume_front("w")) + break; + if (Identifier.getAsInteger(10, WW)) + break; + if (WW != 1 && WW != 2 && WW != 4) + break; + State = WWEEState_Done; + return false; + case WWEEState_Done: + // Extra token? + break; + } + + return true; +} + +ParseStatus RISCVAsmParser::parseXSfmmVType(OperandVector &Operands) { + SMLoc S = getLoc(); + + unsigned Widen = 0; + unsigned SEW = 0; + bool AltFmt = false; + + WWEEState State = WWEEState_SEW; + + if (parseXSfmmVTypeToken(getTok(), State, Widen, SEW, AltFmt)) + return generateXSfmmVTypeError(S); + + getLexer().Lex(); + + if (!parseOptionalToken(AsmToken::Comma)) + return generateXSfmmVTypeError(S); + + if (parseXSfmmVTypeToken(getTok(), State, Widen, SEW, AltFmt)) + return generateXSfmmVTypeError(S); + + getLexer().Lex(); + + if (getLexer().is(AsmToken::EndOfStatement) && State == WWEEState_Done) { + Operands.push_back(RISCVOperand::createVType( + RISCVVType::encodeXSfmmVType(SEW, Widen, AltFmt), S)); + return ParseStatus::Success; + } + + return generateXSfmmVTypeError(S); +} + +bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) { + return Error(ErrorLoc, "operand must be e[8|16|16alt|32|64],w[1|2|4]"); +} + ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) { if (getLexer().isNot(AsmToken::Identifier)) return ParseStatus::NoMatch; diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 27809d96b647c..2912bdf7cccc8 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -333,6 +333,39 @@ static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo, return MCDisassembler::Success; } +static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + if (RegNo > 15) + return MCDisassembler::Fail; + + MCRegister Reg = RISCV::T0 + RegNo; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + if (RegNo > 15 || RegNo % 2) + return MCDisassembler::Fail; + + MCRegister Reg = RISCV::T0 + RegNo; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + if (RegNo > 15 || RegNo % 4) + return MCDisassembler::Fail; + + MCRegister Reg = RISCV::T0 + RegNo; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder) { @@ -734,6 +767,7 @@ static constexpr DecoderListEntry DecoderList32[]{ "XVentanaCondOps"}, {DecoderTableXTHead32, XTHeadGroup, "T-Head extensions"}, {DecoderTableXSfvector32, XSfVectorGroup, "SiFive vector extensions"}, + {DecoderTableXSfmm32, {RISCV::FeatureVendorXSfmmbase}, "SiFive XSfmm"}, {DecoderTableXSfsystem32, XSfSystemGroup, "SiFive system extensions"}, {DecoderTableXSfcease32, {RISCV::FeatureVendorXSfcease}, "SiFive sf.cease"}, {DecoderTableXmipslsp32, {RISCV::FeatureVendorXMIPSLSP}, "MIPS mips.lsp"}, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp index dc6937bb74a3c..1f4a77414db6b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -227,6 +227,20 @@ void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo, RISCVVType::printVType(Imm, O); } +void RISCVInstPrinter::printXSfmmVType(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned Imm = MI->getOperand(OpNo).getImm(); + assert(RISCVVType::isValidXSfmmVType(Imm)); + unsigned SEW = RISCVVType::getSEW(Imm); + O << "e" << SEW; + bool AltFmt = RISCVVType::isAltFmt(Imm); + if (AltFmt) + O << "alt"; + unsigned Widen = RISCVVType::getXSfmmWiden(Imm); + O << ", w" << Widen; +} + // Print a Zcmp RList. If we are printing architectural register names rather // than ABI register names, we need to print "{x1, x8-x9, x18-x27}" for all // registers. Otherwise, we print "{ra, s0-s11}". diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h index 8a6129926d4f2..f8b8fd34abbb4 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -48,6 +48,8 @@ class RISCVInstPrinter : public MCInstPrinter { const MCSubtargetInfo &STI, raw_ostream &O); void printVTypeI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printXSfmmVType(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printVMaskReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printRegList(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index f51fcf82077f4..7b81cb42494f0 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -1188,6 +1188,73 @@ def HasVendorXSfvcp : Predicate<"Subtarget->hasVendorXSfvcp()">, AssemblerPredicate<(all_of FeatureVendorXSfvcp), "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)">; +def FeatureVendorXSfmmbase + : RISCVExtension<0, 6, + "All non arithmetic instructions for all TEWs and sf.vtzero", + [FeatureStdExtZve32x]>; +def HasVendorXSfmmbase : Predicate<"Subtarget->hasVendorXSfmmbase()">, + AssemblerPredicate<(all_of FeatureVendorXSfmmbase), + "'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero)">; + +def FeatureVendorXSfmm32a8f + : RISCVExtension<0, 6, + "TEW=32-bit accumulation, operands - float: fp8", + [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>; +def HasVendorXSfmm32a8f : Predicate<"Subtarget->hasVendorXSfmm32a8f()">, + AssemblerPredicate<(all_of FeatureVendorXSfmm32a8f), + "'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8)">; + +def FeatureVendorXSfmm32a16f + : RISCVExtension<0, 6, + "TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)", + [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>; + +def FeatureVendorXSfmm32a32f + : RISCVExtension<0, 6, + "TEW=32-bit accumulation, operands - float: 32b", + [FeatureVendorXSfmmbase, FeatureStdExtZve32f]>; + +def FeatureVendorXSfmm32a8i + : RISCVExtension<0, 6, + "TEW=32-bit accumulation, operands - int: 8b", + [FeatureVendorXSfmmbase]>; +def HasVendorXSfmm32a8i : Predicate<"Subtarget->hasVendorXSfmm32a8i()">, + AssemblerPredicate<(all_of FeatureVendorXSfmm32a8i), + "'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b)">; + +def FeatureVendorXSfmm64a64f + : RISCVExtension<0, 6, + "TEW=64-bit accumulation, operands - float: fp64", + [FeatureVendorXSfmmbase, FeatureStdExtZve64f]>; +def HasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f + : Predicate<"Subtarget->hasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f()">, + AssemblerPredicate<(any_of FeatureVendorXSfmm32a16f, + FeatureVendorXSfmm32a32f, + FeatureVendorXSfmm64a64f), + "'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)), or " + "'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b), or " + "'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64)">; + +def FeatureVendorXSfmm16t + : RISCVExtension<0, 6, + "TE=16 configuration", + [FeatureVendorXSfmmbase, FeatureStdExtZvl64b], "XSfmmTE", "16">; + +def FeatureVendorXSfmm32t + : RISCVExtension<0, 6, + "TE=32 configuration", + [FeatureVendorXSfmmbase, FeatureStdExtZvl128b], "XSfmmTE", "32">; + +def FeatureVendorXSfmm64t + : RISCVExtension<0, 6, + "TE=64 configuration", + [FeatureVendorXSfmmbase, FeatureStdExtZvl256b], "XSfmmTE", "64">; + +def FeatureVendorXSfmm128t + : RISCVExtension<0, 6, + "TE=128 configuration", + [FeatureVendorXSfmmbase, FeatureStdExtZvl512b], "XSfmmTE", "128">; + def FeatureVendorXSfvqmaccdod : RISCVExtension<1, 0, "SiFive Int8 Matrix Multiplication Instructions (2-by-8 and 8-by-2)", diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 1104d9089536f..0a2f87553f8ab 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -2178,6 +2178,7 @@ include "RISCVInstrInfoSFB.td" include "RISCVInstrInfoXVentana.td" include "RISCVInstrInfoXTHead.td" include "RISCVInstrInfoXSf.td" +include "RISCVInstrInfoXSfmm.td" include "RISCVInstrInfoXCV.td" include "RISCVInstrInfoXwch.td" include "RISCVInstrInfoXqci.td" diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td new file mode 100644 index 0000000000000..b2ca6ad5dba77 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSfmm.td @@ -0,0 +1,276 @@ +//===-- RISCVInstrInfoXsfmm.td - SiFive matrix multiply ----*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the Xsfmm* vendor extensions defined by SiFive. +// +//===----------------------------------------------------------------------===// + +def XSfmmVTypeAsmOperand : AsmOperandClass { + let Name = "XSfmmVType"; + let ParserMethod = "parseXSfmmVType"; + let DiagnosticType = "InvalidXSfmmVType"; + let RenderMethod = "addVTypeIOperands"; +} + +def XSfmmVTypeOp : RISCVOp { + let ParserMatchClass = XSfmmVTypeAsmOperand; + let PrintMethod = "printXSfmmVType"; + let OperandType = "OPERAND_XSFMM_VTYPE"; + let MCOperandPredicate = [{ + int64_t Imm; + if (!MCOp.evaluateAsConstantImm(Imm)) + return false; + if (!isUInt<32>(Imm)) + return false; + return RISCVVType::isValidXSfmmVType(Imm); + }]; +} + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class RVInstSetSingle rs2, string opcodestr, + string argstr> + : RVInst { + bits<5> rs1; + bits<5> rd; + + let Inst{31-25} = 0b1000010; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = OPCFG.Value; + let Inst{11-7} = rd; + let Inst{6-0} = OPC_OP_V.Value; + + let Defs = [VTYPE, VL]; +} + +class RVInstTileMemOp nf, RISCVOpcode opcode, + string opcodestr, string argstr> + : RVInst { + bits<5> rs2; + bits<5> rs1; + + let Inst{31-29} = nf; + let Inst{28} = 1; + let Inst{27-26} = MOPLDUnitStride.Value; + let Inst{25} = 1; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = 0b111; + let Inst{11-7} = 0b00000; + let Inst{6-0} = opcode.Value; + + let Uses = [VTYPE, VL]; +} + +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in +class RVInstTileLoad nf, string opcodestr> + : RVInstTileMemOp<(outs), (ins GPR:$rs2, GPRMemZeroOffset:$rs1), nf, + OPC_LOAD_FP, opcodestr, "$rs2, ${rs1}">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in +class RVInstTileStore nf, string opcodestr> + : RVInstTileMemOp<(outs), (ins GPR:$rs2, GPRMemZeroOffset:$rs1), nf, + OPC_STORE_FP, opcodestr, "$rs2, ${rs1}">; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVInstTileMoveOp funct6, dag outs, dag ins, string opcodestr, + string argstr> + : RVInst { + bits<5> rs2; + bits<5> rs1; + bits<5> vd; + + let Inst{31-26} = funct6; + let Inst{25} = 1; + let Inst{24-20} = rs2; + let Inst{19-15} = rs1; + let Inst{14-12} = OPMVX.Value; + let Inst{11-7} = vd; + let Inst{6-0} = OPC_OP_V.Value; + + let Uses = [VTYPE, VL]; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVInstMatmulF + : RVInst { + bits<5> vs2; + bits<5> vs1; + bits<4> rd; + + let Inst{31-26} = 0b111100; + let Inst{25} = 1; + let Inst{24-20} = vs2; + let Inst{19-15} = vs1; + let Inst{14-12} = OPFVV.Value; + let Inst{11-9} = rd{3-1}; + let Inst{8-7} = 0b00; + let Inst{6-0} = OPC_OP_VE.Value; + + let Uses = [VTYPE, VL]; +} + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVInstMatmulF8 + : RVInst { + bits<5> vs2; + bits<5> vs1; + bits<4> rd; + + let Inst{31-27} = 0b11111; + let Inst{26} = a; + let Inst{25} = 1; + let Inst{24-20} = vs2; + let Inst{19-15} = vs1; + let Inst{14-12} = OPFVV.Value; + let Inst{11-10} = rd{3-2}; + let Inst{9-8} = 0b00; + let Inst{7} = b; + let Inst{6-0} = OPC_OP_VE.Value; + + let Uses = [VTYPE, VL]; +} + + +class F8Encode { + bit Encoding = encoding; + string Name = name; +} + +defvar F8Encodes = [F8Encode<0b0, "e5m2">, + F8Encode<0b1, "e4m3">]; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVInstMatmulI8 + : RVInst { + bits<5> vs2; + bits<5> vs1; + bits<4> rd; + + let Inst{31-28} = 0b1111; + let Inst{27} = funct6_1; + let Inst{26} = a; + let Inst{25} = 1; + let Inst{24-20} = vs2; + let Inst{19-15} = vs1; + let Inst{14-12} = OPIVV.Value; + let Inst{11-10} = rd{3-2}; + let Inst{9-8} = 0b00; + let Inst{7} = b; + let Inst{6-0} = OPC_OP_VE.Value; + + let Uses = [VTYPE, VL]; +} + +class I8Encode { + bit Encoding = encoding; + string Name = name; +} + +defvar I8Encodes = [I8Encode<0, "u">, + I8Encode<1, "s">]; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +class RVInstSetZero + : RVInst { + bits<5> vs2; + bits<5> vs1; + bits<4> rd; + + let Inst{31-26} = 0b010000; + let Inst{25} = 1; + let Inst{24-20} = 0b11110; + let Inst{19-15} = 0b00000; + let Inst{14-12} = OPMVX.Value; + let Inst{11-8} = rd; + let Inst{7} = 0; + let Inst{6-0} = OPC_OP_V.Value; + + let Uses = [VTYPE, VL]; +} + +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class RVInstVtDiscard + : RVInst<(outs), (ins), opcodestr, "", [], InstFormatR> { + let Inst{31-26} = 0b010000; + let Inst{25} = 1; + let Inst{24-20} = 0b11100; + let Inst{19-15} = 0b00000; + let Inst{14-12} = OPMVX.Value; + let Inst{11-7} = 0b00000; + let Inst{6-0} = OPC_OP_V.Value; +} + +let Predicates = [HasVendorXSfmmbase] in +def : InstAlias<"sf.vsettnt $rd, $rs1, $vtypei", + (VSETVLI GPR:$rd, GPR:$rs1, XSfmmVTypeOp:$vtypei)>; + +let DecoderNamespace = "XSfmm" in { + +let Predicates = [HasVendorXSfmmbase] in { + def SF_VSETTN : RVInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00000, + "sf.vsettn", "$rd, $rs1">; + def SF_VSETTM : RVInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00001, + "sf.vsettm", "$rd, $rs1">; + def SF_VSETTK : RVInstSetSingle<(outs GPR:$rd), (ins GPR:$rs1), 0b00010, + "sf.vsettk", "$rd, $rs1">; + def SF_VTDISCARD : RVInstVtDiscard<"sf.vtdiscard">; + + def SF_VTMV_V_T : RVInstTileMoveOp<0b010000, (outs VR:$vd), (ins GPR:$rs1), + "sf.vtmv.v.t", "$vd, $rs1"> { + let rs2 = 0b11111; + } + def SF_VTMV_T_V : RVInstTileMoveOp<0b010111, (outs), (ins GPR:$rs1, VR:$rs2), + "sf.vtmv.t.v", "$rs1, $rs2"> { + let vd = 0b00000; + } + + def SF_VTZERO_T : RVInstSetZero<(outs), (ins TR:$rd), "sf.vtzero.t", "$rd">; +} // Predicates = [HasVendorXSfmmbase] + +let Predicates = [HasVendorXSfmmbase] in { + def SF_VLTE8 : RVInstTileLoad<0b000, "sf.vlte8">; + def SF_VLTE16 : RVInstTileLoad<0b001, "sf.vlte16">; + def SF_VLTE32 : RVInstTileLoad<0b010, "sf.vlte32">; + def SF_VLTE64 : RVInstTileLoad<0b011, "sf.vlte64">; + + def SF_VSTE8 : RVInstTileStore<0b000, "sf.vste8">; + def SF_VSTE16 : RVInstTileStore<0b001, "sf.vste16">; + def SF_VSTE32 : RVInstTileStore<0b010, "sf.vste32">; + def SF_VSTE64 : RVInstTileStore<0b011, "sf.vste64">; +} // Predicates = [HasVendorXSfmmbase] + +let Predicates = [HasVendorXSfmm32a16fOrXSfmm32a32fOrXSfmm64a64f] in { + let Uses = [FRM], mayRaiseFPException = true in + def SF_MM_F_F : RVInstMatmulF<(outs), (ins TRM2:$rd, VR:$vs2, VR:$vs1), + "sf.mm.f.f", "$rd, $vs2, $vs1">; +} // Predicates = [HasVendorXSfmm32a16fOrXSfmm64a32fOrXSfmm64a64f] + +let Predicates = [HasVendorXSfmm32a8i] in { + foreach a = I8Encodes in + foreach b = I8Encodes in + def SF_MM_#!toupper(a.Name)#_#!toupper(b.Name) + : RVInstMatmulI8<0, a.Encoding, b.Encoding, + (outs), (ins TRM4:$rd, VR:$vs2, VR:$vs1), + "sf.mm."#a.Name#"."#b.Name, "$rd, $vs2, $vs1">; +} // Predicates = [HasVendorXSfmm32a8i] + +let Predicates = [HasVendorXSfmm32a8f] in { +let Uses = [FRM], mayRaiseFPException = true in { + foreach a = F8Encodes in + foreach b = F8Encodes in + def SF_MM_#!toupper(a.Name)#_#!toupper(b.Name) + : RVInstMatmulF8; +} +} // Predicates = [HasVendorXSfmm32a8f] + +} // DecoderNamespace = "XSfmm" diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index 8d09caf1da2d5..6499c9aa2f49e 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -835,3 +835,16 @@ def : RISCVRegisterClass<[XLenVT], 32, (add SF_VCIX_STATE)> { let RegInfos = XLenRI; let isAllocatable = 0; } + +//===----------------------------------------------------------------------===// +// XSfmmbase tiles +//===----------------------------------------------------------------------===// +foreach Index = 0-15 in + def T#Index : RISCVReg, + DwarfRegNum<[!add(Index, 3072)]>; + +let RegInfos = XLenRI in { + def TR : RISCVRegisterClass<[untyped], 32, (add (sequence "T%u", 0, 15))>; + def TRM2 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 2))>; + def TRM4 : RISCVRegisterClass<[untyped], 32, (add (decimate TR, 4))>; +} diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index 035ce4745cfd9..0eef7b1feaf5b 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -99,6 +99,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { bool ATTRIBUTE = DEFAULT; #include "RISCVGenSubtargetInfo.inc" + unsigned XSfmmTE = 0; unsigned ZvlLen = 0; unsigned RVVVectorBitsMin; unsigned RVVVectorBitsMax; diff --git a/llvm/lib/TargetParser/RISCVTargetParser.cpp b/llvm/lib/TargetParser/RISCVTargetParser.cpp index 5bd7de1d3ca46..2e5e8f4e50c9c 100644 --- a/llvm/lib/TargetParser/RISCVTargetParser.cpp +++ b/llvm/lib/TargetParser/RISCVTargetParser.cpp @@ -164,6 +164,15 @@ unsigned encodeVTYPE(VLMUL VLMul, unsigned SEW, bool TailAgnostic, return VTypeI; } +unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt) { + assert(isValidSEW(SEW) && "Invalid SEW"); + assert((Widen == 1 || Widen == 2 || Widen == 4) && "Invalid Widen"); + unsigned VSEWBits = encodeSEW(SEW); + unsigned TWiden = Log2_32(Widen) + 1; + unsigned VTypeI = (VSEWBits << 3) | AltFmt << 8 | TWiden << 9; + return VTypeI; +} + std::pair decodeVLMUL(VLMUL VLMul) { switch (VLMul) { default: diff --git a/llvm/test/CodeGen/RISCV/attributes-sifive.ll b/llvm/test/CodeGen/RISCV/attributes-sifive.ll new file mode 100644 index 0000000000000..67c5d1c4aba2e --- /dev/null +++ b/llvm/test/CodeGen/RISCV/attributes-sifive.ll @@ -0,0 +1,50 @@ +;; Generate ELF attributes from llc. + +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm128t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM128T %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm16t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM16T %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a8i %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A8I %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a8f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A8F %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a16f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A16F %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32a32f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32A32F %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm32t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM32T %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm64a64f %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM64A64F %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmm64t %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMM64T %s +; RUN: llc -mtriple=riscv32 -mattr=+xsfmmbase %s -o - | FileCheck --check-prefixes=CHECK,RV32XSFMMBASE %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm128t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM128T %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm16t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM16T %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a8i %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A8I %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a8f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A8F %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a16f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A16F %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32a32f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32A32F %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm32t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM32T %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm64a64f %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM64A64F %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmm64t %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMM64T %s +; RUN: llc -mtriple=riscv64 -mattr=+xsfmmbase %s -o - | FileCheck --check-prefixes=CHECK,RV64XSFMMBASE %s + +; CHECK: .attribute 4, 16 + +; RV32XSFMM128T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6" +; RV32XSFMM16T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6" +; RV32XSFMM32A8I: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6" +; RV32XSFMM32A8F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6" +; RV32XSFMM32A16F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6" +; RV32XSFMM32A32F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6" +; RV32XSFMM32T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6" +; RV32XSFMM64A64F: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6" +; RV32XSFMM64T: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6" +; RV32XSFMMBASE: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6" +; RV64XSFMM128T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6" +; RV64XSFMM16T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6" +; RV64XSFMM32A8I: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6" +; RV64XSFMM32A8F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6" +; RV64XSFMM32A16F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6" +; RV64XSFMM32A32F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6" +; RV64XSFMM32T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6" +; RV64XSFMM64A64F: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6" +; RV64XSFMM64T: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6" +; RV64XSFMMBASE: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6" + +define i32 @addi(i32 %a) { + %1 = add i32 %a, 1 + ret i32 %1 +} diff --git a/llvm/test/CodeGen/RISCV/features-info.ll b/llvm/test/CodeGen/RISCV/features-info.ll index d377bda059d33..760e7bc69c5ce 100644 --- a/llvm/test/CodeGen/RISCV/features-info.ll +++ b/llvm/test/CodeGen/RISCV/features-info.ll @@ -177,6 +177,16 @@ ; CHECK-NEXT: xmipscmov - 'XMIPSCMov' (MIPS conditional move instruction (mips.ccmov)). ; CHECK-NEXT: xmipslsp - 'XMIPSLSP' (MIPS optimization for hardware load-store bonding). ; CHECK-NEXT: xsfcease - 'XSfcease' (SiFive sf.cease Instruction). +; CHECK-NEXT: xsfmm128t - 'XSfmm128t' (TE=128 configuration). +; CHECK-NEXT: xsfmm16t - 'XSfmm16t' (TE=16 configuration). +; CHECK-NEXT: xsfmm32a16f - 'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)). +; CHECK-NEXT: xsfmm32a32f - 'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b). +; CHECK-NEXT: xsfmm32a8f - 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8). +; CHECK-NEXT: xsfmm32a8i - 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b). +; CHECK-NEXT: xsfmm32t - 'XSfmm32t' (TE=32 configuration). +; CHECK-NEXT: xsfmm64a64f - 'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64). +; CHECK-NEXT: xsfmm64t - 'XSfmm64t' (TE=64 configuration). +; CHECK-NEXT: xsfmmbase - 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero). ; CHECK-NEXT: xsfvcp - 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions). ; CHECK-NEXT: xsfvfnrclipxfqf - 'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions). ; CHECK-NEXT: xsfvfwmaccqqq - 'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4)). diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir index fc3bb13df77d6..f151569ef4e57 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vsetvli-insert-zve64f.mir @@ -24,7 +24,7 @@ body: | ; CHECK-NEXT: renamable $v8 = PseudoVLE64_V_M1 undef renamable $v8, [[COPY1]], 1, 6 /* e64 */, 2 /* tu, ma */, implicit $vl, implicit $vtype :: (load unknown-size, align 8) ; CHECK-NEXT: dead $x0 = PseudoVSETIVLI 8, 208 /* e32, m1, ta, ma */, implicit-def $vl, implicit-def $vtype ; CHECK-NEXT: renamable $v9 = PseudoVLE32_V_M1 undef renamable $v9, [[COPY]], 8, 5 /* e32 */, 2 /* tu, ma */, implicit $vl, implicit $vtype :: (load unknown-size, align 4) - ; CHECK-NEXT: INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 3997705 /* reguse:VR */, killed renamable $v10, 3997705 /* reguse:VR */, killed renamable $v11, 3997705 /* reguse:VR */, killed renamable $v8, 3997705 /* reguse:VR */, killed renamable $v9 + ; CHECK-NEXT: INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 4194313 /* reguse:VR */, killed renamable $v10, 4194313 /* reguse:VR */, killed renamable $v11, 4194313 /* reguse:VR */, killed renamable $v8, 4194313 /* reguse:VR */, killed renamable $v9 ; CHECK-NEXT: PseudoRET %3:gpr = COPY $x12 %2:gpr = COPY $x11 @@ -34,7 +34,7 @@ body: | renamable $v11 = PseudoVMV_S_X undef renamable $v11, %1, 8, 5 /* e32 */ renamable $v8 = PseudoVLE64_V_M1 undef renamable $v8, %2, 1, 6 /* e64 */, 2 /* tu, ma */ :: (load unknown-size, align 8) renamable $v9 = PseudoVLE32_V_M1 undef renamable $v9, %3, 8, 5 /* e32 */, 2 /* tu, ma */ :: (load unknown-size, align 4) - INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 3997705 /* reguse:VR */, killed renamable $v10, 3997705 /* reguse:VR */, killed renamable $v11, 3997705 /* reguse:VR */, killed renamable $v8, 3997705 /* reguse:VR */, killed renamable $v9 + INLINEASM &"# use $0 $1 $2 $3", 1 /* sideeffect attdialect */, 4194313 /* reguse:VR */, killed renamable $v10, 4194313 /* reguse:VR */, killed renamable $v11, 4194313 /* reguse:VR */, killed renamable $v8, 4194313 /* reguse:VR */, killed renamable $v9 PseudoRET ... diff --git a/llvm/test/MC/RISCV/attribute-arch-sifive.s b/llvm/test/MC/RISCV/attribute-arch-sifive.s new file mode 100644 index 0000000000000..2f2ff356c32e0 --- /dev/null +++ b/llvm/test/MC/RISCV/attribute-arch-sifive.s @@ -0,0 +1,34 @@ +## Arch string without version. + +# RUN: llvm-mc %s -triple=riscv32 -filetype=asm | FileCheck %s +# RUN: llvm-mc %s -triple=riscv64 -filetype=asm | FileCheck %s + +.attribute arch, "rv32i_xsfmm128t" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0_xsfmm128t0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm16t" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0_xsfmm16t0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm32a8i" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmm32a8i0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm32a8f" +# CHECK: attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a8f0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm32a16f" +# CHECK: attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a16f0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm32a32f" +# CHECK: attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvl32b1p0_xsfmm32a32f0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm32t" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xsfmm32t0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm64a64f" +# CHECK: attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zve64f1p0_zve64x1p0_zvl32b1p0_zvl64b1p0_xsfmm64a64f0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmm64t" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0_xsfmm64t0p6_xsfmmbase0p6" + +.attribute arch, "rv32i_xsfmmbase" +# CHECK: attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_xsfmmbase0p6" diff --git a/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s b/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s new file mode 100644 index 0000000000000..2e2122cf40f0f --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/xsfmm-invalid.s @@ -0,0 +1,28 @@ +# RUN: not llvm-mc -triple=riscv32 --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8f,+xsfmm64a64f %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK +# RUN: not llvm-mc -triple=riscv64 --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8f,+xsfmm64a64f %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK + +sf.vsettnt a0, a1, a2, e128, w1 # CHECK: :[[@LINE]]:20: error: operand must be e[8|16|16alt|32|64],w[1|2|4] + +sf.vsettnt a0, a1, a2, e8alt, w1 # CHECK: :[[@LINE]]:20: error: operand must be e[8|16|16alt|32|64],w[1|2|4] + +sf.mm.f.f mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +sf.mm.e5m2.e5m2 mt2, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction + +sf.mm.e5m2.e4m3 mt6, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction + +sf.mm.e4m3.e5m2 mt10, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction + +sf.mm.e4m3.e4m3 mt14, v8, v9 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction + +sf.mm.u.u mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +sf.mm.s.u mt2, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +sf.mm.u.s mt3, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction + +sf.mm.s.s mt1, v8, v9 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/rvv/xsfmm.s b/llvm/test/MC/RISCV/rvv/xsfmm.s new file mode 100644 index 0000000000000..8de520aa964b7 --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/xsfmm.s @@ -0,0 +1,200 @@ +# RUN: llvm-mc -triple=riscv32 -show-encoding --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +# RUN: not llvm-mc -triple=riscv32 -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR +# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR +# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | llvm-objdump -d --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f --no-print-imm-hex - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | llvm-objdump -d --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f --no-print-imm-hex - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST +# RUN: llvm-mc -triple=riscv32 -filetype=obj --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+xsfmmbase, \ +# RUN: --mattr=+xsfmm32a32f,+xsfmm32a8i,+xsfmm32a8f,+xsfmm64a64f %s \ +# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +# CHECK-INST: sf.vsettnt a0, a1, e8, w1 +# CHECK-ENCODING: [0x57,0xf5,0x05,0x20] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 2005f557 +sf.vsettnt a0, a1, e8, w1 + +# CHECK-INST: sf.vsettnt a0, a1, e16alt, w1 +# CHECK-ENCODING: [0x57,0xf5,0x85,0x30] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 3085f557 +sf.vsettnt a0, a1, e16alt, w1 + +# CHECK-INST: sf.vsettnt a0, a1, e8, w1 +# CHECK-ENCODING: [0x57,0xf5,0x05,0x20] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors) +# CHECK-UNKNOWN: 2005f557 +vsetvli a0, a1, 0x200 + +# CHECK-INST: sf.vsettnt a0, a1, e16alt, w1 +# CHECK-ENCODING: [0x57,0xf5,0x85,0x30] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors) +# CHECK-UNKNOWN: 3085f557 +vsetvli a0, a1, 0x308 + +# CHECK-INST: sf.vsettn a0, a1 +# CHECK-ENCODING: [0x57,0xf5,0x05,0x84] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 8405f557 +sf.vsettn a0, a1 + +# CHECK-INST: sf.vsettm a0, a1 +# CHECK-ENCODING: [0x57,0xf5,0x15,0x84] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 8415f557 +sf.vsettm a0, a1 + +# CHECK-INST: sf.vsettk a0, a1 +# CHECK-ENCODING: [0x57,0xf5,0x25,0x84] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 8425f557 +sf.vsettk a0, a1 + +# CHECK-INST: sf.vlte8 a0, (a1) +# CHECK-ENCODING: [0x07,0xf0,0xa5,0x12] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 12a5f007 +sf.vlte8 a0, (a1) + +# CHECK-INST: sf.vlte16 a0, (a1) +# CHECK-ENCODING: [0x07,0xf0,0xa5,0x32] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 32a5f007 +sf.vlte16 a0, (a1) + +# CHECK-INST: sf.vlte32 a0, (a1) +# CHECK-ENCODING: [0x07,0xf0,0xa5,0x52] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 52a5f007 +sf.vlte32 a0, (a1) + +# CHECK-INST: sf.vlte64 a0, (a1) +# CHECK-ENCODING: [0x07,0xf0,0xa5,0x72] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 72a5f007 +sf.vlte64 a0, (a1) + +# CHECK-INST: sf.vste8 a0, (a1) +# CHECK-ENCODING: [0x27,0xf0,0xa5,0x12] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 12a5f027 +sf.vste8 a0, (a1) + +# CHECK-INST: sf.vste16 a0, (a1) +# CHECK-ENCODING: [0x27,0xf0,0xa5,0x32] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 32a5f027 +sf.vste16 a0, (a1) + +# CHECK-INST: sf.vste32 a0, (a1) +# CHECK-ENCODING: [0x27,0xf0,0xa5,0x52] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 52a5f027 +sf.vste32 a0, (a1) + +# CHECK-INST: sf.vste64 a0, (a1) +# CHECK-ENCODING: [0x27,0xf0,0xa5,0x72] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 72a5f027 +sf.vste64 a0, (a1) + +# CHECK-INST: sf.vtmv.v.t v8, a0 +# CHECK-ENCODING: [0x57,0x64,0xf5,0x43] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 43f56457 +sf.vtmv.v.t v8, a0 + +# CHECK-INST: sf.vtmv.t.v a0, v8 +# CHECK-ENCODING: [0x57,0x60,0x85,0x5e] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 5e856057 +sf.vtmv.t.v a0, v8 + +# CHECK-INST: sf.mm.f.f mt2, v8, v9 +# CHECK-ENCODING: [0x77,0x92,0x84,0xf2] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a16f' (TEW=32-bit accumulation, operands - float: 16b, widen=2 (IEEE, BF)), or 'XSfmm32a32f' (TEW=32-bit accumulation, operands - float: 32b), or 'XSfmm64a64f' (TEW=64-bit accumulation, operands - float: fp64){{$}} +# CHECK-UNKNOWN: f2849277 +sf.mm.f.f mt2, v8, v9 + +# CHECK-INST: sf.mm.e5m2.e5m2 mt0, v8, v9 +# CHECK-ENCODING: [0x77,0x90,0x84,0xfa] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}} +# CHECK-UNKNOWN: fa849077 +sf.mm.e5m2.e5m2 mt0, v8, v9 + +# CHECK-INST: sf.mm.e5m2.e4m3 mt4, v8, v9 +# CHECK-ENCODING: [0xf7,0x94,0x84,0xfa] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}} +# CHECK-UNKNOWN: fa8494f7 +sf.mm.e5m2.e4m3 mt4, v8, v9 + +# CHECK-INST: sf.mm.e4m3.e5m2 mt8, v8, v9 +# CHECK-ENCODING: [0x77,0x98,0x84,0xfe] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}} +# CHECK-UNKNOWN: fe849877 +sf.mm.e4m3.e5m2 mt8, v8, v9 + +# CHECK-INST: sf.mm.e4m3.e4m3 mt12, v8, v9 +# CHECK-ENCODING: [0xf7,0x9c,0x84,0xfe] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8f' (TEW=32-bit accumulation, operands - float: fp8){{$}} +# CHECK-UNKNOWN: fe849cf7 +sf.mm.e4m3.e4m3 mt12, v8, v9 + +# CHECK-INST: sf.mm.u.u mt0, v8, v9 +# CHECK-ENCODING: [0x77,0x80,0x84,0xf2] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}} +# CHECK-UNKNOWN: f2848077 +sf.mm.u.u mt0, v8, v9 + +# CHECK-INST: sf.mm.s.u mt4, v8, v9 +# CHECK-ENCODING: [0x77,0x84,0x84,0xf6] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}} +# CHECK-UNKNOWN: f6848477 +sf.mm.s.u mt4, v8, v9 + +# CHECK-INST: sf.mm.u.s mt8, v8, v9 +# CHECK-ENCODING: [0xf7,0x88,0x84,0xf2] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}} +# CHECK-UNKNOWN: f28488f7 +sf.mm.u.s mt8, v8, v9 + +# CHECK-INST: sf.mm.s.s mt12, v8, v9 +# CHECK-ENCODING: [0xf7,0x8c,0x84,0xf6] +# CHECK-ERROR: instruction requires the following: 'XSfmm32a8i' (TEW=32-bit accumulation, operands - int: 8b){{$}} +# CHECK-UNKNOWN: f6848cf7 +sf.mm.s.s mt12, v8, v9 + +# CHECK-INST: sf.vtzero.t mt15 +# CHECK-ENCODING: [0x57,0x6f,0xe0,0x43] +# CHECK-ERROR: instruction requires the following: 'XSfmmbase' (All non arithmetic instructions for all TEWs and sf.vtzero){{$}} +# CHECK-UNKNOWN: 43e06f57 +sf.vtzero.t mt15 + +# CHECK-INST: vsetvl a2, a0, a1 +# CHECK-ENCODING: [0x57,0x76,0xb5,0x80] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors) +# CHECK-UNKNOWN: 80b57657 +vsetvl a2, a0, a1 + +# CHECK-INST: vsetvli a0, a1, e8, m1, tu, mu +# CHECK-ENCODING: [0x57,0xf5,0x05,0x00] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' (Vector Extensions for Embedded Processors) +# CHECK-UNKNOWN: 0005f557 +vsetvli a0, a1, e8, m1, tu, mu diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp index ff0a5e64ab3e1..fe25af2fae394 100644 --- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp +++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp @@ -1117,6 +1117,16 @@ R"(All available -march extensions for RISC-V xmipscmov 1.0 xmipslsp 1.0 xsfcease 1.0 + xsfmm128t 0.6 + xsfmm16t 0.6 + xsfmm32a16f 0.6 + xsfmm32a32f 0.6 + xsfmm32a8f 0.6 + xsfmm32a8i 0.6 + xsfmm32t 0.6 + xsfmm64a64f 0.6 + xsfmm64t 0.6 + xsfmmbase 0.6 xsfvcp 1.0 xsfvfnrclipxfqf 1.0 xsfvfwmaccqqq 1.0