Skip to content

Commit

Permalink
[RISCV] add the MC layer support of Zfinx extension
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Shao-Ce SUN committed Feb 17, 2022
1 parent 3f22a49 commit 7798ecc
Show file tree
Hide file tree
Showing 30 changed files with 1,548 additions and 224 deletions.
23 changes: 17 additions & 6 deletions llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -53,6 +53,11 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"zfhmin", RISCVExtensionVersion{1, 0}},
{"zfh", RISCVExtensionVersion{1, 0}},

{"zfinx", RISCVExtensionVersion{1, 0}},
{"zdinx", RISCVExtensionVersion{1, 0}},
{"zhinxmin", RISCVExtensionVersion{1, 0}},
{"zhinx", RISCVExtensionVersion{1, 0}},

{"zba", RISCVExtensionVersion{1, 0}},
{"zbb", RISCVExtensionVersion{1, 0}},
{"zbc", RISCVExtensionVersion{1, 0}},
Expand Down Expand Up @@ -688,6 +693,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasE = Exts.count("e") != 0;
bool HasD = Exts.count("d") != 0;
bool HasF = Exts.count("f") != 0;
bool HasZfinx = Exts.count("zfinx") != 0;
bool HasZdinx = Exts.count("zdinx") != 0;
bool HasVector = Exts.count("zve32x") != 0;
bool HasZve32f = Exts.count("zve32f") != 0;
bool HasZve64d = Exts.count("zve64d") != 0;
Expand All @@ -706,17 +713,15 @@ Error RISCVISAInfo::checkDependency() {
return createStringError(errc::invalid_argument,
"d requires f extension to also be specified");

// FIXME: Consider Zfinx in the future
if (HasZve32f && !HasF)
if (HasZve32f && !HasF && !HasZfinx)
return createStringError(
errc::invalid_argument,
"zve32f requires f extension to also be specified");
"zve32f requires f or zfinx extension to also be specified");

// FIXME: Consider Zdinx in the future
if (HasZve64d && !HasD)
if (HasZve64d && !HasD && !HasZdinx)
return createStringError(
errc::invalid_argument,
"zve64d requires d extension to also be specified");
"zve64d requires d or zdinx extension to also be specified");

if (HasZvl && !HasVector)
return createStringError(
Expand All @@ -733,6 +738,9 @@ Error RISCVISAInfo::checkDependency() {
static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"};
static const char *ImpliedExtsZfhmin[] = {"f"};
static const char *ImpliedExtsZfh[] = {"f"};
static const char *ImpliedExtsZdinx[] = {"zfinx"};
static const char *ImpliedExtsZhinxmin[] = {"zfinx"};
static const char *ImpliedExtsZhinx[] = {"zfinx"};
static const char *ImpliedExtsZve64d[] = {"zve64f"};
static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"};
static const char *ImpliedExtsZve64x[] = {"zve32x", "zvl64b"};
Expand Down Expand Up @@ -767,8 +775,11 @@ struct ImpliedExtsEntry {
// Note: The table needs to be sorted by name.
static constexpr ImpliedExtsEntry ImpliedExts[] = {
{{"v"}, {ImpliedExtsV}},
{{"zdinx"}, {ImpliedExtsZdinx}},
{{"zfh"}, {ImpliedExtsZfh}},
{{"zfhmin"}, {ImpliedExtsZfhmin}},
{{"zhinx"}, {ImpliedExtsZhinx}},
{{"zhinxmin"}, {ImpliedExtsZhinxmin}},
{{"zk"}, {ImpliedExtsZk}},
{{"zkn"}, {ImpliedExtsZkn}},
{{"zks"}, {ImpliedExtsZks}},
Expand Down
35 changes: 34 additions & 1 deletion llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Expand Up @@ -171,6 +171,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseVTypeI(OperandVector &Operands);
OperandMatchResultTy parseMaskReg(OperandVector &Operands);
OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands);
OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands);

bool parseOperand(OperandVector &Operands, StringRef Mnemonic);

Expand Down Expand Up @@ -274,6 +275,8 @@ struct RISCVOperand : public MCParsedAsmOperand {

bool IsRV64;

bool IsGPRAsFPR;

struct RegOp {
MCRegister RegNum;
};
Expand Down Expand Up @@ -344,6 +347,14 @@ struct RISCVOperand : public MCParsedAsmOperand {
RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
}

bool isGPRAsFPR() const { return isGPR() && IsGPRAsFPR; }

bool isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; }

bool isGPRPF64AsFPR() const {
return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1);
}

static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
RISCVMCExpr::VariantKind &VK) {
if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
Expand Down Expand Up @@ -840,12 +851,14 @@ struct RISCVOperand : public MCParsedAsmOperand {
}

static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
SMLoc E, bool IsRV64) {
SMLoc E, bool IsRV64,
bool IsGPRAsFPR = false) {
auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
Op->Reg.RegNum = RegNo;
Op->StartLoc = S;
Op->EndLoc = E;
Op->IsRV64 = IsRV64;
Op->IsGPRAsFPR = IsGPRAsFPR;
return Op;
}

Expand Down Expand Up @@ -1799,6 +1812,26 @@ OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
return MatchOperand_Success;
}

OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
switch (getLexer().getKind()) {
default:
return MatchOperand_NoMatch;
case AsmToken::Identifier:
StringRef Name = getLexer().getTok().getIdentifier();
MCRegister RegNo;
matchRegisterNameHelper(isRV32E(), RegNo, Name);

if (RegNo == RISCV::NoRegister)
return MatchOperand_NoMatch;
SMLoc S = getLoc();
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
getLexer().Lex();
Operands.push_back(RISCVOperand::createReg(
RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF)));
}
return MatchOperand_Success;
}

OperandMatchResultTy
RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
if (getLexer().isNot(AsmToken::LParen)) {
Expand Down
32 changes: 32 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Expand Up @@ -161,6 +161,17 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}

static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo >= 32 || RegNo & 1)
return MCDisassembler::Fail;

MCRegister Reg = RISCV::X0 + RegNo;
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
Expand Down Expand Up @@ -427,6 +438,27 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
return MCDisassembler::Fail;
}
Insn = support::endian::read32le(Bytes.data());
if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
!STI.getFeatureBits()[RISCV::Feature64Bit]) {
LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
"rv32)\n");
Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
}

if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
}
LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
Size = 4;
Expand Down
37 changes: 37 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Expand Up @@ -70,6 +70,43 @@ def HasStdExtZfhOrZfhmin
"'Zfh' (Half-Precision Floating-Point) or "
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;

def FeatureStdExtZfinx
: SubtargetFeature<"zfinx", "HasStdExtZfinx", "true",
"'Zfinx' (Float in Integer)">;
def HasStdExtZfinx : Predicate<"Subtarget->hasStdExtZfinx()">,
AssemblerPredicate<(all_of FeatureStdExtZfinx),
"'Zfinx' (Float in Integer)">;

def FeatureStdExtZdinx
: SubtargetFeature<"zdinx", "HasStdExtZdinx", "true",
"'Zdinx' (Double in Integer)",
[FeatureStdExtZfinx]>;
def HasStdExtZdinx : Predicate<"Subtarget->hasStdExtZdinx()">,
AssemblerPredicate<(all_of FeatureStdExtZdinx),
"'Zdinx' (Double in Integer)">;

def FeatureStdExtZhinxmin
: SubtargetFeature<"zhinxmin", "HasStdExtZhinxmin", "true",
"'Zhinxmin' (Half Float in Integer Minimal)",
[FeatureStdExtZfinx]>;
def HasStdExtZhinxmin : Predicate<"Subtarget->hasStdExtZhinxmin()">,
AssemblerPredicate<(all_of FeatureStdExtZhinxmin),
"'Zhinxmin' (Half Float in Integer Minimal)">;

def FeatureStdExtZhinx
: SubtargetFeature<"zhinx", "HasStdExtZhinx", "true",
"'Zhinx' (Half Float in Integer)",
[FeatureStdExtZfinx]>;
def HasStdExtZhinx : Predicate<"Subtarget->hasStdExtZhinx()">,
AssemblerPredicate<(all_of FeatureStdExtZhinx),
"'Zhinx' (Half Float in Integer)">;

def HasStdExtZhinxOrZhinxmin
: Predicate<"Subtarget->hasStdExtZhinx() || Subtarget->hasStdExtZhinxmin()">,
AssemblerPredicate<(any_of FeatureStdExtZhinx, FeatureStdExtZhinxmin),
"'Zhinx' (Half Float in Integer) or "
"'Zhinxmin' (Half Float in Integer Minimal)">;

def FeatureStdExtC
: SubtargetFeature<"c", "HasStdExtC", "true",
"'C' (Compressed Instructions)">;
Expand Down

0 comments on commit 7798ecc

Please sign in to comment.