Skip to content

Commit 71a7108

Browse files
committed
[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
1 parent 10cc3a8 commit 71a7108

File tree

17 files changed

+827
-1
lines changed

17 files changed

+827
-1
lines changed

clang/test/Preprocessor/riscv-target-features.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
// CHECK-NOT: __riscv_xcvalu {{.*$}}
3030
// CHECK-NOT: __riscv_xcvbi {{.*$}}
3131
// CHECK-NOT: __riscv_xcvbitmanip {{.*$}}
32+
// CHECK-NOT: __riscv_xcvelw {{.*$}}
3233
// CHECK-NOT: __riscv_xcvmac {{.*$}}
34+
// CHECK-NOT: __riscv_xcvmem {{.*$}}
3335
// CHECK-NOT: __riscv_xcvsimd {{.*$}}
3436
// CHECK-NOT: __riscv_xsfcie {{.*$}}
3537
// CHECK-NOT: __riscv_xsfvcp {{.*$}}

llvm/docs/RISCVUsage.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,15 @@ The current vendor extensions supported are:
263263
``XCVbitmanip``
264264
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.
265265

266+
``XCVelw``
267+
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.
268+
266269
``XCVmac``
267270
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.
268271

272+
``XCVmem``
273+
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.
274+
269275
``XCValu``
270276
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.
271277

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
7171
{"xcvalu", RISCVExtensionVersion{1, 0}},
7272
{"xcvbi", RISCVExtensionVersion{1, 0}},
7373
{"xcvbitmanip", RISCVExtensionVersion{1, 0}},
74+
{"xcvelw", RISCVExtensionVersion{1, 0}},
7475
{"xcvmac", RISCVExtensionVersion{1, 0}},
76+
{"xcvmem", RISCVExtensionVersion{1, 0}},
7577
{"xcvsimd", RISCVExtensionVersion{1, 0}},
7678
{"xsfcie", RISCVExtensionVersion{1, 0}},
7779
{"xsfvcp", RISCVExtensionVersion{1, 0}},

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
202202
ParseStatus parseFRMArg(OperandVector &Operands);
203203
ParseStatus parseFenceArg(OperandVector &Operands);
204204
ParseStatus parseReglist(OperandVector &Operands);
205+
ParseStatus parseRegReg(OperandVector &Operands);
205206
ParseStatus parseRetval(OperandVector &Operands);
206207
ParseStatus parseZcmpSpimm(OperandVector &Operands);
207208

@@ -324,6 +325,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
324325
Fence,
325326
Rlist,
326327
Spimm,
328+
RegReg,
327329
} Kind;
328330

329331
struct RegOp {
@@ -368,6 +370,11 @@ struct RISCVOperand final : public MCParsedAsmOperand {
368370
unsigned Val;
369371
};
370372

373+
struct RegRegOp {
374+
MCRegister Reg1;
375+
MCRegister Reg2;
376+
};
377+
371378
SMLoc StartLoc, EndLoc;
372379
union {
373380
StringRef Tok;
@@ -380,6 +387,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
380387
struct FenceOp Fence;
381388
struct RlistOp Rlist;
382389
struct SpimmOp Spimm;
390+
struct RegRegOp RegReg;
383391
};
384392

385393
RISCVOperand(KindTy K) : Kind(K) {}
@@ -420,6 +428,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
420428
case KindTy::Spimm:
421429
Spimm = o.Spimm;
422430
break;
431+
case KindTy::RegReg:
432+
RegReg = o.RegReg;
433+
break;
423434
}
424435
}
425436

@@ -444,6 +455,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
444455
bool isImm() const override { return Kind == KindTy::Immediate; }
445456
bool isMem() const override { return false; }
446457
bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
458+
bool isRegReg() const { return Kind == KindTy::RegReg; }
447459
bool isRlist() const { return Kind == KindTy::Rlist; }
448460
bool isSpimm() const { return Kind == KindTy::Spimm; }
449461

@@ -1025,6 +1037,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
10251037
RISCVZC::printSpimm(Spimm.Val, OS);
10261038
OS << '>';
10271039
break;
1040+
case KindTy::RegReg:
1041+
OS << "<RegReg: Reg1 " << RegName(RegReg.Reg1);
1042+
OS << " Reg2 " << RegName(RegReg.Reg2);
1043+
break;
10281044
}
10291045
}
10301046

@@ -1108,6 +1124,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
11081124
return Op;
11091125
}
11101126

1127+
static std::unique_ptr<RISCVOperand> createRegReg(unsigned Reg1No,
1128+
unsigned Reg2No, SMLoc S) {
1129+
auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1130+
Op->RegReg.Reg1 = Reg1No;
1131+
Op->RegReg.Reg2 = Reg2No;
1132+
Op->StartLoc = S;
1133+
Op->EndLoc = S;
1134+
return Op;
1135+
}
1136+
11111137
static std::unique_ptr<RISCVOperand> createSpimm(unsigned Spimm, SMLoc S) {
11121138
auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
11131139
Op->Spimm.Val = Spimm;
@@ -1183,6 +1209,12 @@ struct RISCVOperand final : public MCParsedAsmOperand {
11831209
Inst.addOperand(MCOperand::createImm(Rlist.Val));
11841210
}
11851211

1212+
void addRegRegOperands(MCInst &Inst, unsigned N) const {
1213+
assert(N == 1 && "Invalid number of operands!");
1214+
Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
1215+
Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
1216+
}
1217+
11861218
void addSpimmOperands(MCInst &Inst, unsigned N) const {
11871219
assert(N == 1 && "Invalid number of operands!");
11881220
Inst.addOperand(MCOperand::createImm(Spimm.Val));
@@ -1549,6 +1581,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15491581
case Match_InvalidRnumArg: {
15501582
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
15511583
}
1584+
case Match_InvalidRegReg: {
1585+
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1586+
return Error(ErrorLoc, "operands must be register and register");
1587+
}
15521588
}
15531589

15541590
llvm_unreachable("Unknown match type detected!");
@@ -2381,6 +2417,37 @@ ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {
23812417
return ParseStatus::Success;
23822418
}
23832419

2420+
ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
2421+
// RR : a2(a1)
2422+
if (getLexer().getKind() != AsmToken::Identifier)
2423+
return ParseStatus::NoMatch;
2424+
2425+
StringRef RegName = getLexer().getTok().getIdentifier();
2426+
MCRegister Reg = matchRegisterNameHelper(isRVE(), RegName);
2427+
if (!Reg)
2428+
return Error(getLoc(), "invalid register");
2429+
getLexer().Lex();
2430+
2431+
if (parseToken(AsmToken::LParen, "expected '(' or invalid operand"))
2432+
return ParseStatus::Failure;
2433+
2434+
if (getLexer().getKind() != AsmToken::Identifier)
2435+
return Error(getLoc(), "expected register");
2436+
2437+
StringRef Reg2Name = getLexer().getTok().getIdentifier();
2438+
MCRegister Reg2 = matchRegisterNameHelper(isRVE(), Reg2Name);
2439+
if (!Reg2)
2440+
return Error(getLoc(), "invalid register");
2441+
getLexer().Lex();
2442+
2443+
if (parseToken(AsmToken::RParen, "expected ')'"))
2444+
return ParseStatus::Failure;
2445+
2446+
Operands.push_back(RISCVOperand::createRegReg(Reg, Reg2, getLoc()));
2447+
2448+
return ParseStatus::Success;
2449+
}
2450+
23842451
ParseStatus RISCVAsmParser::parseReglist(OperandVector &Operands) {
23852452
// Rlist: {ra [, s0[-sN]]}
23862453
// XRlist: {x1 [, x8[-x9][, x18[-xN]]]}

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
353353
static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
354354
uint64_t Address, const void *Decoder);
355355

356+
static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
357+
const MCDisassembler *Decoder);
358+
356359
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
357360
uint64_t Address, const void *Decoder);
358361

@@ -450,6 +453,15 @@ static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
450453
return MCDisassembler::Success;
451454
}
452455

456+
static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
457+
const MCDisassembler *Decoder) {
458+
uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);
459+
uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);
460+
DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
461+
DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
462+
return MCDisassembler::Success;
463+
}
464+
453465
// spimm is based on rlist now.
454466
static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
455467
uint64_t Address, const void *Decoder) {
@@ -561,8 +573,12 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
561573
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
562574
DecoderTableXCVbitmanip32,
563575
"CORE-V Bit Manipulation custom opcode table");
576+
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
577+
"CORE-V Event load custom opcode table");
564578
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
565579
"CORE-V MAC custom opcode table");
580+
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
581+
"CORE-V MEM custom opcode table");
566582
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
567583
"CORE-V ALU custom opcode table");
568584
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,22 @@ void RISCVInstPrinter::printRlist(const MCInst *MI, unsigned OpNo,
279279
O << "}";
280280
}
281281

282+
void RISCVInstPrinter::printRegReg(const MCInst *MI, unsigned OpNo,
283+
const MCSubtargetInfo &STI, raw_ostream &O) {
284+
const MCOperand &MO = MI->getOperand(OpNo);
285+
286+
assert(MO.isReg() && "printRegReg can only print register operands");
287+
if (MO.getReg() == RISCV::NoRegister)
288+
return;
289+
printRegName(O, MO.getReg());
290+
291+
O << "(";
292+
const MCOperand &MO1 = MI->getOperand(OpNo + 1);
293+
assert(MO1.isReg() && "printRegReg can only print register operands");
294+
printRegName(O, MO1.getReg());
295+
O << ")";
296+
}
297+
282298
void RISCVInstPrinter::printSpimm(const MCInst *MI, unsigned OpNo,
283299
const MCSubtargetInfo &STI, raw_ostream &O) {
284300
int64_t Imm = MI->getOperand(OpNo).getImm();

llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ class RISCVInstPrinter : public MCInstPrinter {
5454
raw_ostream &O);
5555
void printSpimm(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
5656
raw_ostream &O);
57-
57+
void printRegReg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
58+
raw_ostream &O);
5859
// Autogenerated by tblgen.
5960
std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
6061
void printInstruction(const MCInst *MI, uint64_t Address,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
9292
unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
9393
SmallVectorImpl<MCFixup> &Fixups,
9494
const MCSubtargetInfo &STI) const;
95+
96+
unsigned getRegReg(const MCInst &MI, unsigned OpNo,
97+
SmallVectorImpl<MCFixup> &Fixups,
98+
const MCSubtargetInfo &STI) const;
9599
};
96100
} // end anonymous namespace
97101

@@ -506,4 +510,17 @@ unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
506510
return Imm;
507511
}
508512

513+
unsigned RISCVMCCodeEmitter::getRegReg(const MCInst &MI, unsigned OpNo,
514+
SmallVectorImpl<MCFixup> &Fixups,
515+
const MCSubtargetInfo &STI) const {
516+
const MCOperand &MO = MI.getOperand(OpNo);
517+
const MCOperand &MO1 = MI.getOperand(OpNo + 1);
518+
assert(MO.isReg() && MO1.isReg() && "Expected registers.");
519+
520+
unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
521+
unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
522+
523+
return Op | Op1 << 5;
524+
}
525+
509526
#include "RISCVGenMCCodeEmitter.inc"

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,13 @@ def FeatureVendorXSfvfnrclipxfqf
851851
def HasVendorXSfvfnrclipxfqf : Predicate<"Subtarget->hasVendorXSfvfnrclipxfqf()">,
852852
AssemblerPredicate<(all_of FeatureVendorXSfvfnrclipxfqf),
853853
"'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions)">;
854+
def FeatureVendorXCVelw
855+
: SubtargetFeature<"xcvelw", "HasVendorXCVelw", "true",
856+
"'XCVelw' (CORE-V Event Load Word)">;
857+
def HasVendorXCVelw
858+
: Predicate<"Subtarget->hasVendorXCVelw()">,
859+
AssemblerPredicate<(any_of FeatureVendorXCVelw),
860+
"'XCVelw' (CORE-V Event Load Word)">;
854861

855862
def FeatureVendorXCVbitmanip
856863
: SubtargetFeature<"xcvbitmanip", "HasVendorXCVbitmanip", "true",
@@ -866,6 +873,14 @@ def HasVendorXCVmac : Predicate<"Subtarget->hasVendorXCVmac()">,
866873
AssemblerPredicate<(all_of FeatureVendorXCVmac),
867874
"'XCVmac' (CORE-V Multiply-Accumulate)">;
868875

876+
def FeatureVendorXCVmem
877+
: SubtargetFeature<"xcvmem", "HasVendorXCVmem", "true",
878+
"'XCVmem' (CORE-V Post-incrementing Load & Store)">;
879+
def HasVendorXCVmem
880+
: Predicate<"Subtarget->hasVendorXCVmem()">,
881+
AssemblerPredicate<(any_of FeatureVendorXCVmem),
882+
"'XCVmem' (CORE-V Post-incrementing Load & Store)">;
883+
869884
def FeatureVendorXCValu
870885
: SubtargetFeature<"xcvalu", "HasVendorXCValu", "true",
871886
"'XCValu' (CORE-V ALU Operations)">;

0 commit comments

Comments
 (0)