[clang] 71a7108 - [RISCV][MC] MC layer support for xcvmem and xcvelw extensions
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 15 17:46:22 PST 2023
Author: LiaoChunyu
Date: 2023-11-16T09:46:11+08:00
New Revision: 71a7108ee91a522251ff37638e26158570c1e2a5
URL: https://github.com/llvm/llvm-project/commit/71a7108ee91a522251ff37638e26158570c1e2a5
DIFF: https://github.com/llvm/llvm-project/commit/71a7108ee91a522251ff37638e26158570c1e2a5.diff
LOG: [RISCV][MC] MC layer support for xcvmem and xcvelw extensions
This commit is part of a patch-set to upstream the 7 vendor specific extensions of CV32E40P.
Several other extensions have been merged.
Spec:
https://github.com/openhwgroup/cv32e40p/blob/master/docs/source/instruction_set_extensions.rst
Contributors: @CharKeaney, @jeremybennett, @lewis-revill, Nandni Jamnadas, @PaoloS, @simoncook, @xmj, @realqhc, @melonedo, @adeelahmad81299
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D158824
Added:
llvm/test/MC/RISCV/corev/XCVelw-invalid.s
llvm/test/MC/RISCV/corev/XCVelw-valid.s
llvm/test/MC/RISCV/corev/XCVmem-invalid.s
llvm/test/MC/RISCV/corev/XCVmem-valid.s
Modified:
clang/test/Preprocessor/riscv-target-features.c
llvm/docs/RISCVUsage.rst
llvm/lib/Support/RISCVISAInfo.cpp
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
llvm/lib/Target/RISCV/RISCVFeatures.td
llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
llvm/test/CodeGen/RISCV/attributes.ll
llvm/test/MC/RISCV/attribute-arch.s
llvm/unittests/Support/RISCVISAInfoTest.cpp
Removed:
################################################################################
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 9f86427e25f53f4..6fc921a8c6ee155 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -29,7 +29,9 @@
// CHECK-NOT: __riscv_xcvalu {{.*$}}
// CHECK-NOT: __riscv_xcvbi {{.*$}}
// CHECK-NOT: __riscv_xcvbitmanip {{.*$}}
+// CHECK-NOT: __riscv_xcvelw {{.*$}}
// CHECK-NOT: __riscv_xcvmac {{.*$}}
+// CHECK-NOT: __riscv_xcvmem {{.*$}}
// CHECK-NOT: __riscv_xcvsimd {{.*$}}
// CHECK-NOT: __riscv_xsfcie {{.*$}}
// CHECK-NOT: __riscv_xsfvcp {{.*$}}
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index e1d5557888bd071..65dd0d83448ed10 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -263,9 +263,15 @@ The current vendor extensions supported are:
``XCVbitmanip``
LLVM implements `version 1.0.0 of the CORE-V Bit Manipulation custom instructions specification <https://github.com/openhwgroup/cv32e40p/blob/62bec66b36182215e18c9cf10f723567e23878e9/docs/source/instruction_set_extensions.rst>`_ by OpenHW Group. All instructions are prefixed with `cv.` as described in the specification.
+``XCVelw``
+ LLVM implements `version 1.0.0 of the CORE-V Event load custom instructions specification <https://github.com/openhwgroup/cv32e40p/blob/master/docs/source/instruction_set_extensions.rst>`_ by OpenHW Group. All instructions are prefixed with `cv.` as described in the specification. These instructions are only available for riscv32 at this time.
+
``XCVmac``
LLVM implements `version 1.0.0 of the CORE-V Multiply-Accumulate (MAC) custom instructions specification <https://github.com/openhwgroup/cv32e40p/blob/4f024fe4b15a68b76615b0630c07a6745c620da7/docs/source/instruction_set_extensions.rst>`_ by OpenHW Group. All instructions are prefixed with `cv.mac` as described in the specification. These instructions are only available for riscv32 at this time.
+``XCVmem``
+ LLVM implements `version 1.0.0 of the CORE-V Post-Increment load and stores custom instructions specification <https://github.com/openhwgroup/cv32e40p/blob/master/docs/source/instruction_set_extensions.rst>`_ by OpenHW Group. All instructions are prefixed with `cv.` as described in the specification. These instructions are only available for riscv32 at this time.
+
``XCValu``
LLVM implements `version 1.0.0 of the Core-V ALU custom instructions specification <https://github.com/openhwgroup/cv32e40p/blob/4f024fe4b15a68b76615b0630c07a6745c620da7/docs/source/instruction_set_extensions.rst>`_ by Core-V. All instructions are prefixed with `cv.` as described in the specification. These instructions are only available for riscv32 at this time.
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index c89be27a0be12ce..6322748430063ce 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -71,7 +71,9 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"xcvalu", RISCVExtensionVersion{1, 0}},
{"xcvbi", RISCVExtensionVersion{1, 0}},
{"xcvbitmanip", RISCVExtensionVersion{1, 0}},
+ {"xcvelw", RISCVExtensionVersion{1, 0}},
{"xcvmac", RISCVExtensionVersion{1, 0}},
+ {"xcvmem", RISCVExtensionVersion{1, 0}},
{"xcvsimd", RISCVExtensionVersion{1, 0}},
{"xsfcie", RISCVExtensionVersion{1, 0}},
{"xsfvcp", RISCVExtensionVersion{1, 0}},
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index e9264a5d851c0b5..138134d00f64a65 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -202,6 +202,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
ParseStatus parseFRMArg(OperandVector &Operands);
ParseStatus parseFenceArg(OperandVector &Operands);
ParseStatus parseReglist(OperandVector &Operands);
+ ParseStatus parseRegReg(OperandVector &Operands);
ParseStatus parseRetval(OperandVector &Operands);
ParseStatus parseZcmpSpimm(OperandVector &Operands);
@@ -324,6 +325,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
Fence,
Rlist,
Spimm,
+ RegReg,
} Kind;
struct RegOp {
@@ -368,6 +370,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
unsigned Val;
};
+ struct RegRegOp {
+ MCRegister Reg1;
+ MCRegister Reg2;
+ };
+
SMLoc StartLoc, EndLoc;
union {
StringRef Tok;
@@ -380,6 +387,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
struct FenceOp Fence;
struct RlistOp Rlist;
struct SpimmOp Spimm;
+ struct RegRegOp RegReg;
};
RISCVOperand(KindTy K) : Kind(K) {}
@@ -420,6 +428,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
case KindTy::Spimm:
Spimm = o.Spimm;
break;
+ case KindTy::RegReg:
+ RegReg = o.RegReg;
+ break;
}
}
@@ -444,6 +455,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isImm() const override { return Kind == KindTy::Immediate; }
bool isMem() const override { return false; }
bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
+ bool isRegReg() const { return Kind == KindTy::RegReg; }
bool isRlist() const { return Kind == KindTy::Rlist; }
bool isSpimm() const { return Kind == KindTy::Spimm; }
@@ -1025,6 +1037,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
RISCVZC::printSpimm(Spimm.Val, OS);
OS << '>';
break;
+ case KindTy::RegReg:
+ OS << "<RegReg: Reg1 " << RegName(RegReg.Reg1);
+ OS << " Reg2 " << RegName(RegReg.Reg2);
+ break;
}
}
@@ -1108,6 +1124,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return Op;
}
+ static std::unique_ptr<RISCVOperand> createRegReg(unsigned Reg1No,
+ unsigned Reg2No, SMLoc S) {
+ auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
+ Op->RegReg.Reg1 = Reg1No;
+ Op->RegReg.Reg2 = Reg2No;
+ Op->StartLoc = S;
+ Op->EndLoc = S;
+ return Op;
+ }
+
static std::unique_ptr<RISCVOperand> createSpimm(unsigned Spimm, SMLoc S) {
auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
Op->Spimm.Val = Spimm;
@@ -1183,6 +1209,12 @@ struct RISCVOperand final : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createImm(Rlist.Val));
}
+ void addRegRegOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
+ Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
+ }
+
void addSpimmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createImm(Spimm.Val));
@@ -1549,6 +1581,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidRnumArg: {
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
}
+ case Match_InvalidRegReg: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return Error(ErrorLoc, "operands must be register and register");
+ }
}
llvm_unreachable("Unknown match type detected!");
@@ -2381,6 +2417,37 @@ ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {
return ParseStatus::Success;
}
+ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
+ // RR : a2(a1)
+ if (getLexer().getKind() != AsmToken::Identifier)
+ return ParseStatus::NoMatch;
+
+ StringRef RegName = getLexer().getTok().getIdentifier();
+ MCRegister Reg = matchRegisterNameHelper(isRVE(), RegName);
+ if (!Reg)
+ return Error(getLoc(), "invalid register");
+ getLexer().Lex();
+
+ if (parseToken(AsmToken::LParen, "expected '(' or invalid operand"))
+ return ParseStatus::Failure;
+
+ if (getLexer().getKind() != AsmToken::Identifier)
+ return Error(getLoc(), "expected register");
+
+ StringRef Reg2Name = getLexer().getTok().getIdentifier();
+ MCRegister Reg2 = matchRegisterNameHelper(isRVE(), Reg2Name);
+ if (!Reg2)
+ return Error(getLoc(), "invalid register");
+ getLexer().Lex();
+
+ if (parseToken(AsmToken::RParen, "expected ')'"))
+ return ParseStatus::Failure;
+
+ Operands.push_back(RISCVOperand::createRegReg(Reg, Reg2, getLoc()));
+
+ return ParseStatus::Success;
+}
+
ParseStatus RISCVAsmParser::parseReglist(OperandVector &Operands) {
// Rlist: {ra [, s0[-sN]]}
// XRlist: {x1 [, x8[-x9][, x18[-xN]]]}
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index f3a4945ca6285ef..53e2b6b4d94ea04 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -353,6 +353,9 @@ static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
+static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
+ const MCDisassembler *Decoder);
+
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder);
@@ -450,6 +453,15 @@ static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
return MCDisassembler::Success;
}
+static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
+ const MCDisassembler *Decoder) {
+ uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);
+ uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);
+ DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
+ DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
+ return MCDisassembler::Success;
+}
+
// spimm is based on rlist now.
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
uint64_t Address, const void *Decoder) {
@@ -561,8 +573,12 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
DecoderTableXCVbitmanip32,
"CORE-V Bit Manipulation custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
+ "CORE-V Event load custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
"CORE-V MAC custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
+ "CORE-V MEM custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
"CORE-V ALU custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index e31c53e52bba556..a6f3f7f8d18e069 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -279,6 +279,22 @@ void RISCVInstPrinter::printRlist(const MCInst *MI, unsigned OpNo,
O << "}";
}
+void RISCVInstPrinter::printRegReg(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNo);
+
+ assert(MO.isReg() && "printRegReg can only print register operands");
+ if (MO.getReg() == RISCV::NoRegister)
+ return;
+ printRegName(O, MO.getReg());
+
+ O << "(";
+ const MCOperand &MO1 = MI->getOperand(OpNo + 1);
+ assert(MO1.isReg() && "printRegReg can only print register operands");
+ printRegName(O, MO1.getReg());
+ O << ")";
+}
+
void RISCVInstPrinter::printSpimm(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O) {
int64_t Imm = MI->getOperand(OpNo).getImm();
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index 852d281bb395bfe..4512bd5f4c4b7a2 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -54,7 +54,8 @@ class RISCVInstPrinter : public MCInstPrinter {
raw_ostream &O);
void printSpimm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
-
+ void printRegReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
// Autogenerated by tblgen.
std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
void printInstruction(const MCInst *MI, uint64_t Address,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index c5f2d92e9e47c27..82fed50bce753a9 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -92,6 +92,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+
+ unsigned getRegReg(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
};
} // end anonymous namespace
@@ -506,4 +510,17 @@ unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
return Imm;
}
+unsigned RISCVMCCodeEmitter::getRegReg(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ const MCOperand &MO1 = MI.getOperand(OpNo + 1);
+ assert(MO.isReg() && MO1.isReg() && "Expected registers.");
+
+ unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
+ unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
+
+ return Op | Op1 << 5;
+}
+
#include "RISCVGenMCCodeEmitter.inc"
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index d6f988ede7f5bf9..f8fb54bb47a100e 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -851,6 +851,13 @@ def FeatureVendorXSfvfnrclipxfqf
def HasVendorXSfvfnrclipxfqf : Predicate<"Subtarget->hasVendorXSfvfnrclipxfqf()">,
AssemblerPredicate<(all_of FeatureVendorXSfvfnrclipxfqf),
"'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)">;
+def FeatureVendorXCVelw
+ : SubtargetFeature<"xcvelw", "HasVendorXCVelw", "true",
+ "'XCVelw' (CORE-V Event Load Word)">;
+def HasVendorXCVelw
+ : Predicate<"Subtarget->hasVendorXCVelw()">,
+ AssemblerPredicate<(any_of FeatureVendorXCVelw),
+ "'XCVelw' (CORE-V Event Load Word)">;
def FeatureVendorXCVbitmanip
: SubtargetFeature<"xcvbitmanip", "HasVendorXCVbitmanip", "true",
@@ -866,6 +873,14 @@ def HasVendorXCVmac : Predicate<"Subtarget->hasVendorXCVmac()">,
AssemblerPredicate<(all_of FeatureVendorXCVmac),
"'XCVmac' (CORE-V Multiply-Accumulate)">;
+def FeatureVendorXCVmem
+ : SubtargetFeature<"xcvmem", "HasVendorXCVmem", "true",
+ "'XCVmem' (CORE-V Post-incrementing Load & Store)">;
+def HasVendorXCVmem
+ : Predicate<"Subtarget->hasVendorXCVmem()">,
+ AssemblerPredicate<(any_of FeatureVendorXCVmem),
+ "'XCVmem' (CORE-V Post-incrementing Load & Store)">;
+
def FeatureVendorXCValu
: SubtargetFeature<"xcvalu", "HasVendorXCValu", "true",
"'XCValu' (CORE-V ALU Operations)">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
index e85ad4f7433a390..6622e811bbb86d9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
@@ -505,3 +505,156 @@ let Predicates = [HasVendorXCVbi, IsRV32], hasSideEffects = 0, mayLoad = 0,
(ins GPR:$rs1, simm5:$imm5, simm13_lsb0:$imm12),
"cv.bneimm", "$rs1, $imm5, $imm12">, Sched<[]>;
}
+
+def CVrrAsmOperand : AsmOperandClass {
+ let Name = "RegReg";
+ let ParserMethod = "parseRegReg";
+ let DiagnosticType = "InvalidRegReg";
+}
+
+def CVrr : Operand<OtherVT> {
+ let ParserMatchClass = CVrrAsmOperand;
+ let EncoderMethod = "getRegReg";
+ let DecoderMethod = "decodeRegReg";
+ let PrintMethod = "printRegReg";
+}
+
+class CVLoad_ri_inc<bits<3> funct3, string opcodestr>
+ : RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd, GPR:$rs1_wb), (ins GPRMem:$rs1, simm12:$imm12),
+ opcodestr, "$rd, (${rs1}), ${imm12}"> {
+ let Constraints = "$rs1_wb = $rs1";
+ let DecoderNamespace = "XCVmem";
+}
+
+class CVLoad_rr_inc<bits<7> funct7, bits<3> funct3, string opcodestr>
+ : RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd, GPR:$rs1_wb), (ins GPRMem:$rs1, GPR:$rs2),
+ opcodestr, "$rd, (${rs1}), ${rs2}"> {
+ let Constraints = "$rs1_wb = $rs1";
+ let DecoderNamespace = "XCVmem";
+}
+
+class CVLoad_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
+ : RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd), (ins CVrr:$cvrr),
+ opcodestr, "$rd, $cvrr"> {
+ bits<5> rd;
+ bits<10> cvrr;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-20} = cvrr{4-0};
+ let Inst{19-15} = cvrr{9-5};
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let DecoderNamespace = "XCVmem";
+}
+
+let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0,
+ mayLoad = 1, mayStore = 0, Constraints = "$rs1_wb = $rs1" in {
+ // Register-Immediate load with post-increment
+ def CV_LB_ri_inc : CVLoad_ri_inc<0b000, "cv.lb">;
+ def CV_LBU_ri_inc : CVLoad_ri_inc<0b100, "cv.lbu">;
+ def CV_LH_ri_inc : CVLoad_ri_inc<0b001, "cv.lh">;
+ def CV_LHU_ri_inc : CVLoad_ri_inc<0b101, "cv.lhu">;
+ def CV_LW_ri_inc : CVLoad_ri_inc<0b010, "cv.lw">;
+
+ // Register-Register load with post-increment
+ def CV_LB_rr_inc : CVLoad_rr_inc<0b0000000, 0b011, "cv.lb">;
+ def CV_LBU_rr_inc : CVLoad_rr_inc<0b0001000, 0b011, "cv.lbu">;
+ def CV_LH_rr_inc : CVLoad_rr_inc<0b0000001, 0b011, "cv.lh">;
+ def CV_LHU_rr_inc : CVLoad_rr_inc<0b0001001, 0b011, "cv.lhu">;
+ def CV_LW_rr_inc : CVLoad_rr_inc<0b0000010, 0b011, "cv.lw">;
+}
+
+let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0,
+ mayLoad = 1, mayStore = 0 in {
+ // Register-Register load
+ def CV_LB_rr : CVLoad_rr<0b0000100, 0b011, "cv.lb">;
+ def CV_LBU_rr : CVLoad_rr<0b0001100, 0b011, "cv.lbu">;
+ def CV_LH_rr : CVLoad_rr<0b0000101, 0b011, "cv.lh">;
+ def CV_LHU_rr : CVLoad_rr<0b0001101, 0b011, "cv.lhu">;
+ def CV_LW_rr : CVLoad_rr<0b0000110, 0b011, "cv.lw">;
+}
+
+class CVStore_ri_inc<bits<3> funct3, string opcodestr>
+ : RVInstS<funct3, OPC_CUSTOM_1, (outs GPR:$rs1_wb),
+ (ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
+ opcodestr, "$rs2, (${rs1}), ${imm12}"> {
+ let Constraints = "$rs1_wb = $rs1";
+ let DecoderNamespace = "XCVmem";
+}
+
+class CVStore_rr_inc<bits<3> funct3, bits<7> funct7, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+ bits<5> rs3;
+ bits<5> rs2;
+ bits<5> rs1;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rs3;
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let DecoderNamespace = "XCVmem";
+}
+
+
+class CVStore_rr<bits<3> funct3, bits<7> funct7, dag outs, dag ins,
+ string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+ bits<5> rs2;
+ bits<10> cvrr;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = cvrr{9-5};
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = cvrr{4-0};
+ let Inst{6-0} = OPC_CUSTOM_1.Value;
+ let DecoderNamespace = "XCVmem";
+}
+
+let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0,
+ mayLoad = 0, mayStore = 1, Constraints = "$rs1_wb = $rs1" in {
+ // Register-Immediate store with post-increment
+ def CV_SB_ri_inc : CVStore_ri_inc<0b000, "cv.sb">;
+ def CV_SH_ri_inc : CVStore_ri_inc<0b001, "cv.sh">;
+ def CV_SW_ri_inc : CVStore_ri_inc<0b010, "cv.sw">;
+
+ // Register-Register store with post-increment
+ def CV_SB_rr_inc : CVStore_rr_inc<0b011, 0b0010000,
+ (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3),
+ "cv.sb", "$rs2, (${rs1}), ${rs3}">;
+ def CV_SH_rr_inc : CVStore_rr_inc<0b011, 0b0010001,
+ (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3),
+ "cv.sh", "$rs2, (${rs1}), ${rs3}">;
+ def CV_SW_rr_inc : CVStore_rr_inc<0b011, 0b0010010,
+ (outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3),
+ "cv.sw", "$rs2, (${rs1}), ${rs3}">;
+}
+
+
+let Predicates = [HasVendorXCVmem, IsRV32], hasSideEffects = 0,
+ mayLoad = 0, mayStore = 1 in {
+ // Register-Register store
+ def CV_SB_rr : CVStore_rr<0b011, 0b0010100,
+ (outs), (ins GPR:$rs2, CVrr:$cvrr),
+ "cv.sb", "$rs2, $cvrr">;
+ def CV_SH_rr : CVStore_rr<0b011, 0b0010101,
+ (outs), (ins GPR:$rs2, CVrr:$cvrr),
+ "cv.sh", "$rs2, $cvrr">;
+ def CV_SW_rr : CVStore_rr<0b011, 0b0010110,
+ (outs), (ins GPR:$rs2, CVrr:$cvrr),
+ "cv.sw", "$rs2, $cvrr">;
+}
+
+let DecoderNamespace = "XCVelw" in
+class CVLoad_ri<bits<3> funct3, string opcodestr>
+ : RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd),
+ (ins GPRMem:$rs1, simm12:$imm12), opcodestr, "$rd, ${imm12}(${rs1})">;
+
+let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0,
+ mayLoad = 1, mayStore = 0 in {
+ // Event load
+ def CV_ELW : CVLoad_ri<0b011, "cv.elw">;
+}
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 1d987b4c87391aa..030ae06af6d2828 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -43,7 +43,9 @@
; RUN: llc -mtriple=riscv32 -mattr=+svinval %s -o - | FileCheck --check-prefixes=CHECK,RV32SVINVAL %s
; RUN: llc -mtriple=riscv32 -mattr=+xcvalu %s -o - | FileCheck --check-prefix=RV32XCVALU %s
; RUN: llc -mtriple=riscv32 -mattr=+xcvbitmanip %s -o - | FileCheck --check-prefix=RV32XCVBITMANIP %s
+; RUN: llc -mtriple=riscv32 -mattr=+xcvelw %s -o - | FileCheck --check-prefix=RV32XCVELW %s
; RUN: llc -mtriple=riscv32 -mattr=+xcvmac %s -o - | FileCheck --check-prefix=RV32XCVMAC %s
+; RUN: llc -mtriple=riscv32 -mattr=+xcvmem %s -o - | FileCheck --check-prefix=RV32XCVMEM %s
; RUN: llc -mtriple=riscv32 -mattr=+xcvsimd %s -o - | FileCheck --check-prefix=RV32XCVSIMD %s
; RUN: llc -mtriple=riscv32 -mattr=+xcvbi %s -o - | FileCheck --check-prefix=RV32XCVBI %s
; RUN: llc -mtriple=riscv32 -mattr=+xtheadcmo %s -o - | FileCheck --check-prefix=RV32XTHEADCMO %s
@@ -223,7 +225,9 @@
; RV32SVINVAL: .attribute 5, "rv32i2p1_svinval1p0"
; RV32XCVALU: .attribute 5, "rv32i2p1_xcvalu1p0"
; RV32XCVBITMANIP: .attribute 5, "rv32i2p1_xcvbitmanip1p0"
+; RV32XCVELW: .attribute 5, "rv32i2p1_xcvelw1p0"
; RV32XCVMAC: .attribute 5, "rv32i2p1_xcvmac1p0"
+; RV32XCVMEM: .attribute 5, "rv32i2p1_xcvmem1p0"
; RV32XCVSIMD: .attribute 5, "rv32i2p1_xcvsimd1p0"
; RV32XCVBI: .attribute 5, "rv32i2p1_xcvbi1p0"
; RV32XTHEADCMO: .attribute 5, "rv32i2p1_xtheadcmo1p0"
diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 4e773d897df1223..aa919f266592f45 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -294,9 +294,15 @@
.attribute arch, "rv32i_xcvbitmanip"
# CHECK: attribute 5, "rv32i2p1_xcvbitmanip1p0"
+.attribute arch, "rv32i_xcvelw"
+# CHECK: attribute 5, "rv32i2p1_xcvelw1p0"
+
.attribute arch, "rv32i_xcvmac"
# CHECK: attribute 5, "rv32i2p1_xcvmac1p0"
+.attribute arch, "rv32i_xcvmem"
+# CHECK: attribute 5, "rv32i2p1_xcvmem1p0"
+
.attribute arch, "rv32i_xcvsimd"
# CHECK: attribute 5, "rv32i2p1_xcvsimd1p0"
diff --git a/llvm/test/MC/RISCV/corev/XCVelw-invalid.s b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s
new file mode 100644
index 000000000000000..24870904ac49b1c
--- /dev/null
+++ b/llvm/test/MC/RISCV/corev/XCVelw-invalid.s
@@ -0,0 +1,26 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+xcvelw %s 2>&1 \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR
+
+cv.elw t0, 0(0)
+# CHECK-ERROR: expected register
+
+cv.elw 0, 0(x6)
+# CHECK-ERROR: invalid operand for instruction
+
+cv.elw x12, 2048(x6)
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.elw x12, x1(2047)
+# CHECK-ERROR: unexpected token
+
+cv.elw 0, x12(x6)
+# CHECK-ERROR: unexpected token
+
+cv.elw x12, x12(x6)
+# CHECK-ERROR: unexpected token
+
+cv.elw 0, 0(x6)
+# CHECK-ERROR: invalid operand for instruction
+
+cv.elw x0
+# CHECK-ERROR: too few operands for instruction
diff --git a/llvm/test/MC/RISCV/corev/XCVelw-valid.s b/llvm/test/MC/RISCV/corev/XCVelw-valid.s
new file mode 100644
index 000000000000000..c3e406af446b37f
--- /dev/null
+++ b/llvm/test/MC/RISCV/corev/XCVelw-valid.s
@@ -0,0 +1,22 @@
+# RUN: llvm-mc -triple=riscv32 --mattr=+xcvelw -show-encoding %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INSTR
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xcvelw < %s \
+# RUN: | llvm-objdump --mattr=+xcvelw -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-INSTR %s
+# RUN: not llvm-mc -triple riscv32 %s 2>&1 \
+# RUN: | FileCheck -check-prefix=CHECK-NO-EXT %s
+
+cv.elw a0, 1024(a0)
+# CHECK-INSTR: cv.elw a0, 1024(a0)
+# CHECK-ENCODING: [0x0b,0x35,0x05,0x40]
+# CHECK-NO-EXT: instruction requires the following: 'XCVelw' (CORE-V Event Load Word){{$}}
+
+cv.elw a1, 1(a1)
+# CHECK-INSTR: cv.elw a1, 1(a1)
+# CHECK-ENCODING: [0x8b,0xb5,0x15,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVelw' (CORE-V Event Load Word){{$}}
+
+cv.elw a2, -1024(a3)
+# CHECK-INSTR: cv.elw a2, -1024(a3)
+# CHECK-ENCODING: [0x0b,0xb6,0x06,0xc0]
+# CHECK-NO-EXT: instruction requires the following: 'XCVelw' (CORE-V Event Load Word){{$}}
diff --git a/llvm/test/MC/RISCV/corev/XCVmem-invalid.s b/llvm/test/MC/RISCV/corev/XCVmem-invalid.s
new file mode 100644
index 000000000000000..e71cd7daa890e60
--- /dev/null
+++ b/llvm/test/MC/RISCV/corev/XCVmem-invalid.s
@@ -0,0 +1,224 @@
+# RUN: not llvm-mc -triple=riscv32 --mattr=+xcvmem %s 2>&1 \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR
+
+cv.lb t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.lb 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lb 0, (0), t2
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lb t0, (t1), -2049
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lb t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lb t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.lb 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lb t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.lb t0, (t2)
+# CHECK-ERROR: too few operands for instruction
+
+cv.lb t0, (t1), t2, t3
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lbu t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.lbu 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lbu 0, (0), t0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lbu t0, (t1), -2049
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lbu t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lbu t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.lbu 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lbu t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.lbu t0, (t2)
+# CHECK-ERROR: too few operands for instruction
+
+cv.lbu t0, (t1), t2, t3
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lh t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.lh 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lh 0, (0), t2
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lh t0, (t1), -2049
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lh t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lh t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.lh t0, t1(0)
+# CHECK-ERROR: expected register
+
+cv.lh 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lh t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.lh t0, (t1)
+# CHECK-ERROR: too few operands for instruction
+
+cv.lh t0, (t1), t2, t3
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lhu t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.lhu 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lhu 0, 0(t1)
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lhu t0, (t1), -2049
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lhu t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lhu t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.lhu t0, t1(0)
+# CHECK-ERROR: expected register
+
+cv.lhu 0, t0, t1
+# CHECK-ERROR: expected '(' or invalid operand
+
+cv.lhu t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.lhu t0, (t1)
+# CHECK-ERROR: too few operands for instruction
+
+cv.lhu t0, (t1), t2, t3
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lw t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.lw 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lw 0, (0), t2
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lw t0, (t1), -2049
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lw t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.lw t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.lw t0, t1(0)
+# CHECK-ERROR: expected register
+
+cv.lw 0, (t0), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.lw t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.lw t0, (t1)
+# CHECK-ERROR: too few operands for instruction
+
+cv.lw t0, (t1), t2, t3
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sb t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.sb 0, (t0), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sb t0, 0(t1)
+# CHECK-ERROR: operands must be register and register
+
+cv.sb t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.sb t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.sb 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sb t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.sh t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.sh 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sh t0, 0(t1)
+# CHECK-ERROR: operands must be register and register
+
+cv.sh t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.sh t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.sh 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sh t0
+# CHECK-ERROR: too few operands for instruction
+
+cv.sw t0, (0), 0
+# CHECK-ERROR: operands must be register and register
+
+cv.sw 0, (t1), 0
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sw t0, 0(t1)
+# CHECK-ERROR: operands must be register and register
+
+cv.sw t0, (t1), 2048
+# CHECK-ERROR: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
+
+cv.sw t0, (0), t1
+# CHECK-ERROR: operands must be register and register
+
+cv.sw 0, (t1), t1
+# CHECK-ERROR: invalid operand for instruction
+
+cv.sw t0
+# CHECK-ERROR: too few operands for instruction
diff --git a/llvm/test/MC/RISCV/corev/XCVmem-valid.s b/llvm/test/MC/RISCV/corev/XCVmem-valid.s
new file mode 100644
index 000000000000000..474a0cba2eca22d
--- /dev/null
+++ b/llvm/test/MC/RISCV/corev/XCVmem-valid.s
@@ -0,0 +1,247 @@
+# RUN: llvm-mc -triple=riscv32 --mattr=+xcvmem -show-encoding %s \
+# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INSTR
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xcvmem < %s \
+# RUN: | llvm-objdump --mattr=+xcvmem -M no-aliases -d -r - \
+# RUN: | FileCheck --check-prefix=CHECK-INSTR %s
+# RUN: not llvm-mc -triple riscv32 %s 2>&1 \
+# RUN: | FileCheck -check-prefix=CHECK-NO-EXT %s
+
+cv.lb t0, (t1), 0
+# CHECK-INSTR: cv.lb t0, (t1), 0
+# CHECK-ENCODING: [0x8b,0x02,0x03,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lb a0, (a1), 2047
+# CHECK-INSTR: cv.lb a0, (a1), 2047
+# CHECK-ENCODING: [0x0b,0x85,0xf5,0x7f]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lb t0, (t1), t2
+# CHECK-INSTR: cv.lb t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x32,0x73,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lb a0, (a1), a2
+# CHECK-INSTR: cv.lb a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lb t0, t2(t1)
+# CHECK-INSTR: cv.lb t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x32,0x73,0x08]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lb a0, a2(a1)
+# CHECK-INSTR: cv.lb a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x08]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu t0, (t1), 0
+# CHECK-INSTR: cv.lbu t0, (t1), 0
+# CHECK-ENCODING: [0x8b,0x42,0x03,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu a0, (a1), 2047
+# CHECK-INSTR: cv.lbu a0, (a1), 2047
+# CHECK-ENCODING: [0x0b,0xc5,0xf5,0x7f]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu t0, (t1), t2
+# CHECK-INSTR: cv.lbu t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x32,0x73,0x10]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu a0, (a1), a2
+# CHECK-INSTR: cv.lbu a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x10]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu t0, t2(t1)
+# CHECK-INSTR: cv.lbu t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x32,0x73,0x18]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lbu a0, a2(a1)
+# CHECK-INSTR: cv.lbu a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x18]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh t0, (t1), 0
+# CHECK-INSTR: cv.lh t0, (t1), 0
+# CHECK-ENCODING: [0x8b,0x12,0x03,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh a0, (a1), 2047
+# CHECK-INSTR: cv.lh a0, (a1), 2047
+# CHECK-ENCODING: [0x0b,0x95,0xf5,0x7f]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh t0, (t1), t2
+# CHECK-INSTR: cv.lh t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x32,0x73,0x02]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh a0, (a1), a2
+# CHECK-INSTR: cv.lh a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x02]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh t0, t2(t1)
+# CHECK-INSTR: cv.lh t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x32,0x73,0x0a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lh a0, a2(a1)
+# CHECK-INSTR: cv.lh a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x0a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu t0, (t1), 0
+# CHECK-INSTR: cv.lhu t0, (t1), 0
+# CHECK-ENCODING: [0x8b,0x52,0x03,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu a0, (a1), 2047
+# CHECK-INSTR: cv.lhu a0, (a1), 2047
+# CHECK-ENCODING: [0x0b,0xd5,0xf5,0x7f]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu t0, (t1), t2
+# CHECK-INSTR: cv.lhu t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x32,0x73,0x12]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu a0, (a1), a2
+# CHECK-INSTR: cv.lhu a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x12]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu t0, t2(t1)
+# CHECK-INSTR: cv.lhu t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x32,0x73,0x1a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lhu a0, a2(a1)
+# CHECK-INSTR: cv.lhu a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x1a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw t0, (t1), 0
+# CHECK-INSTR: cv.lw t0, (t1), 0
+# CHECK-ENCODING: [0x8b,0x22,0x03,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw a0, (a1), 2047
+# CHECK-INSTR: cv.lw a0, (a1), 2047
+# CHECK-ENCODING: [0x0b,0xa5,0xf5,0x7f]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw t0, (t1), t2
+# CHECK-INSTR: cv.lw t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x32,0x73,0x04]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw a0, (a1), a2
+# CHECK-INSTR: cv.lw a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x04]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw t0, t2(t1)
+# CHECK-INSTR: cv.lw t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x32,0x73,0x0c]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.lw a0, a2(a1)
+# CHECK-INSTR: cv.lw a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb5,0xc5,0x0c]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb t0, (t1), 0
+# CHECK-INSTR: cv.sb t0, (t1), 0
+# CHECK-ENCODING: [0x2b,0x00,0x53,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb a0, (a1), 2047
+# CHECK-INSTR: cv.sb a0, (a1), 2047
+# CHECK-ENCODING: [0xab,0x8f,0xa5,0x7e]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb t0, (t1), t2
+# CHECK-INSTR: cv.sb t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x33,0x53,0x20]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb a0, (a1), a2
+# CHECK-INSTR: cv.sb a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x20]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb t0, t2(t1)
+# CHECK-INSTR: cv.sb t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x33,0x53,0x28]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sb a0, a2(a1)
+# CHECK-INSTR: cv.sb a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x28]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh t0, (t1), 0
+# CHECK-INSTR: cv.sh t0, (t1), 0
+# CHECK-ENCODING: [0x2b,0x10,0x53,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh a0, (a1), 2047
+# CHECK-INSTR: cv.sh a0, (a1), 2047
+# CHECK-ENCODING: [0xab,0x9f,0xa5,0x7e]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh t0, (t1), t2
+# CHECK-INSTR: cv.sh t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x33,0x53,0x22]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh a0, (a1), a2
+# CHECK-INSTR: cv.sh a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x22]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh t0, t2(t1)
+# CHECK-INSTR: cv.sh t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x33,0x53,0x2a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sh a0, a2(a1)
+# CHECK-INSTR: cv.sh a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x2a]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw t0, (t1), 0
+# CHECK-INSTR: cv.sw t0, (t1), 0
+# CHECK-ENCODING: [0x2b,0x20,0x53,0x00]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw a0, (a1), 2047
+# CHECK-INSTR: cv.sw a0, (a1), 2047
+# CHECK-ENCODING: [0xab,0xaf,0xa5,0x7e]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw t0, (t1), t2
+# CHECK-INSTR: cv.sw t0, (t1), t2
+# CHECK-ENCODING: [0xab,0x33,0x53,0x24]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw a0, (a1), a2
+# CHECK-INSTR: cv.sw a0, (a1), a2
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x24]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw t0, t2(t1)
+# CHECK-INSTR: cv.sw t0, t2(t1)
+# CHECK-ENCODING: [0xab,0x33,0x53,0x2c]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
+
+cv.sw a0, a2(a1)
+# CHECK-INSTR: cv.sw a0, a2(a1)
+# CHECK-ENCODING: [0x2b,0xb6,0xa5,0x2c]
+# CHECK-NO-EXT: instruction requires the following: 'XCVmem' (CORE-V Post-incrementing Load & Store){{$}}
diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index d7f5c5d4ee5e2ca..549964eed55518e 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -712,7 +712,9 @@ R"(All available -march extensions for RISC-V
xcvalu 1.0
xcvbi 1.0
xcvbitmanip 1.0
+ xcvelw 1.0
xcvmac 1.0
+ xcvmem 1.0
xcvsimd 1.0
xsfcie 1.0
xsfvcp 1.0
More information about the cfe-commits
mailing list