Skip to content

Commit 192d968

Browse files
author
Shao-Ce SUN
committed
[RISCV] add the MC layer support of Zfinx extension
This patch added the MC layer support of Zfinx extension. Authored-by: StephenFan Co-Authored-by: Shao-Ce Sun Reviewed By: asb Differential Revision: https://reviews.llvm.org/D93298 (cherry picked from commit 7798ecc)
1 parent 1e348e6 commit 192d968

30 files changed

+1548
-224
lines changed

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
5151
{"zfhmin", RISCVExtensionVersion{1, 0}},
5252
{"zfh", RISCVExtensionVersion{1, 0}},
5353

54+
{"zfinx", RISCVExtensionVersion{1, 0}},
55+
{"zdinx", RISCVExtensionVersion{1, 0}},
56+
{"zhinxmin", RISCVExtensionVersion{1, 0}},
57+
{"zhinx", RISCVExtensionVersion{1, 0}},
58+
5459
{"zba", RISCVExtensionVersion{1, 0}},
5560
{"zbb", RISCVExtensionVersion{1, 0}},
5661
{"zbc", RISCVExtensionVersion{1, 0}},
@@ -686,6 +691,8 @@ Error RISCVISAInfo::checkDependency() {
686691
bool HasE = Exts.count("e") != 0;
687692
bool HasD = Exts.count("d") != 0;
688693
bool HasF = Exts.count("f") != 0;
694+
bool HasZfinx = Exts.count("zfinx") != 0;
695+
bool HasZdinx = Exts.count("zdinx") != 0;
689696
bool HasZve32x = Exts.count("zve32x") != 0;
690697
bool HasZve32f = Exts.count("zve32f") != 0;
691698
bool HasZve64d = Exts.count("zve64d") != 0;
@@ -706,17 +713,15 @@ Error RISCVISAInfo::checkDependency() {
706713
return createStringError(errc::invalid_argument,
707714
"d requires f extension to also be specified");
708715

709-
// FIXME: Consider Zfinx in the future
710-
if (HasZve32f && !HasF)
716+
if (HasZve32f && !HasF && !HasZfinx)
711717
return createStringError(
712718
errc::invalid_argument,
713-
"zve32f requires f extension to also be specified");
719+
"zve32f requires f or zfinx extension to also be specified");
714720

715-
// FIXME: Consider Zdinx in the future
716-
if (HasZve64d && !HasD)
721+
if (HasZve64d && !HasD && !HasZdinx)
717722
return createStringError(
718723
errc::invalid_argument,
719-
"zve64d requires d extension to also be specified");
724+
"zve64d requires d or zdinx extension to also be specified");
720725

721726
if (HasZvl && !HasVector)
722727
return createStringError(
@@ -733,6 +738,9 @@ Error RISCVISAInfo::checkDependency() {
733738
static const char *ImpliedExtsV[] = {"zvl128b", "f", "d"};
734739
static const char *ImpliedExtsZfhmin[] = {"f"};
735740
static const char *ImpliedExtsZfh[] = {"f"};
741+
static const char *ImpliedExtsZdinx[] = {"zfinx"};
742+
static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
743+
static const char *ImpliedExtsZhinx[] = {"zfinx"};
736744
static const char *ImpliedExtsZve64d[] = {"zve64f"};
737745
static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"};
738746
static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"};
@@ -767,8 +775,11 @@ struct ImpliedExtsEntry {
767775
// Note: The table needs to be sorted by name.
768776
static constexpr ImpliedExtsEntry ImpliedExts[] = {
769777
{{"v"}, {ImpliedExtsV}},
778+
{{"zdinx"}, {ImpliedExtsZdinx}},
770779
{{"zfh"}, {ImpliedExtsZfh}},
771780
{{"zfhmin"}, {ImpliedExtsZfhmin}},
781+
{{"zhinx"}, {ImpliedExtsZhinx}},
782+
{{"zhinxmin"}, {ImpliedExtsZhinxmin}},
772783
{{"zk"}, {ImpliedExtsZk}},
773784
{{"zkn"}, {ImpliedExtsZkn}},
774785
{{"zks"}, {ImpliedExtsZks}},

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
170170
OperandMatchResultTy parseVTypeI(OperandVector &Operands);
171171
OperandMatchResultTy parseMaskReg(OperandVector &Operands);
172172
OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands);
173+
OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands);
173174

174175
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
175176

@@ -273,6 +274,8 @@ struct RISCVOperand : public MCParsedAsmOperand {
273274

274275
bool IsRV64;
275276

277+
bool IsGPRAsFPR;
278+
276279
struct RegOp {
277280
MCRegister RegNum;
278281
};
@@ -343,6 +346,14 @@ struct RISCVOperand : public MCParsedAsmOperand {
343346
RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
344347
}
345348

349+
bool isGPRAsFPR() const { return isGPR() && IsGPRAsFPR; }
350+
351+
bool isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; }
352+
353+
bool isGPRPF64AsFPR() const {
354+
return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1);
355+
}
356+
346357
static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
347358
RISCVMCExpr::VariantKind &VK) {
348359
if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
@@ -831,12 +842,14 @@ struct RISCVOperand : public MCParsedAsmOperand {
831842
}
832843

833844
static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
834-
SMLoc E, bool IsRV64) {
845+
SMLoc E, bool IsRV64,
846+
bool IsGPRAsFPR = false) {
835847
auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
836848
Op->Reg.RegNum = RegNo;
837849
Op->StartLoc = S;
838850
Op->EndLoc = E;
839851
Op->IsRV64 = IsRV64;
852+
Op->IsGPRAsFPR = IsGPRAsFPR;
840853
return Op;
841854
}
842855

@@ -1780,6 +1793,26 @@ OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
17801793
return MatchOperand_Success;
17811794
}
17821795

1796+
OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
1797+
switch (getLexer().getKind()) {
1798+
default:
1799+
return MatchOperand_NoMatch;
1800+
case AsmToken::Identifier:
1801+
StringRef Name = getLexer().getTok().getIdentifier();
1802+
MCRegister RegNo;
1803+
matchRegisterNameHelper(isRV32E(), RegNo, Name);
1804+
1805+
if (RegNo == RISCV::NoRegister)
1806+
return MatchOperand_NoMatch;
1807+
SMLoc S = getLoc();
1808+
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1809+
getLexer().Lex();
1810+
Operands.push_back(RISCVOperand::createReg(
1811+
RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF)));
1812+
}
1813+
return MatchOperand_Success;
1814+
}
1815+
17831816
OperandMatchResultTy
17841817
RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
17851818
if (getLexer().isNot(AsmToken::LParen)) {

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
161161
return MCDisassembler::Success;
162162
}
163163

164+
static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
165+
uint64_t Address,
166+
const void *Decoder) {
167+
if (RegNo >= 32 || RegNo & 1)
168+
return MCDisassembler::Fail;
169+
170+
MCRegister Reg = RISCV::X0 + RegNo;
171+
Inst.addOperand(MCOperand::createReg(Reg));
172+
return MCDisassembler::Success;
173+
}
174+
164175
static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
165176
uint64_t Address,
166177
const void *Decoder) {
@@ -427,6 +438,27 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
427438
return MCDisassembler::Fail;
428439
}
429440
Insn = support::endian::read32le(Bytes.data());
441+
if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
442+
!STI.getFeatureBits()[RISCV::Feature64Bit]) {
443+
LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
444+
"rv32)\n");
445+
Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
446+
this, STI);
447+
if (Result != MCDisassembler::Fail) {
448+
Size = 4;
449+
return Result;
450+
}
451+
}
452+
453+
if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
454+
LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
455+
Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
456+
STI);
457+
if (Result != MCDisassembler::Fail) {
458+
Size = 4;
459+
return Result;
460+
}
461+
}
430462
LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
431463
Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
432464
Size = 4;

llvm/lib/Target/RISCV/RISCV.td

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,43 @@ def HasStdExtZfhOrZfhmin
6363
"'Zfh' (Half-Precision Floating-Point) or "
6464
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;
6565

66+
def FeatureStdExtZfinx
67+
: SubtargetFeature<"zfinx", "HasStdExtZfinx", "true",
68+
"'Zfinx' (Float in Integer)">;
69+
def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">,
70+
AssemblerPredicate<(all_of FeatureStdExtZfinx),
71+
"'Zfinx' (Float in Integer)">;
72+
73+
def FeatureStdExtZdinx
74+
: SubtargetFeature<"zdinx", "HasStdExtZdinx", "true",
75+
"'Zdinx' (Double in Integer)",
76+
[FeatureStdExtZfinx]>;
77+
def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">,
78+
AssemblerPredicate<(all_of FeatureStdExtZdinx),
79+
"'Zdinx' (Double in Integer)">;
80+
81+
def FeatureStdExtZhinxmin
82+
: SubtargetFeature<"zhinxmin", "HasStdExtZhinxmin", "true",
83+
"'Zhinxmin' (Half Float in Integer Minimal)",
84+
[FeatureStdExtZfinx]>;
85+
def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">,
86+
AssemblerPredicate<(all_of FeatureStdExtZhinxmin),
87+
"'Zhinxmin' (Half Float in Integer Minimal)">;
88+
89+
def FeatureStdExtZhinx
90+
: SubtargetFeature<"zhinx", "HasStdExtZhinx", "true",
91+
"'Zhinx' (Half Float in Integer)",
92+
[FeatureStdExtZfinx]>;
93+
def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">,
94+
AssemblerPredicate<(all_of FeatureStdExtZhinx),
95+
"'Zhinx' (Half Float in Integer)">;
96+
97+
def HasStdExtZhinxOrZhinxmin
98+
: Predicate<"Subtarget->hasStdExtZhinx() || Subtarget->hasStdExtZhinxmin()">,
99+
AssemblerPredicate<(any_of FeatureStdExtZhinx, FeatureStdExtZhinxmin),
100+
"'Zhinx' (Half Float in Integer) or "
101+
"'Zhinxmin' (Half Float in Integer Minimal)">;
102+
66103
def FeatureStdExtC
67104
: SubtargetFeature<"c", "HasStdExtC", "true",
68105
"'C' (Compressed Instructions)">;

0 commit comments

Comments
 (0)