diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 300ba8dc675c..53562f42a184 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -15,6 +15,7 @@ #include "Utils/RISCVMatInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/Register.h" #include "llvm/MC/MCAssembler.h" @@ -37,10 +38,15 @@ using namespace llvm; +#define DEBUG_TYPE "riscv-asm-parser" + // Include the auto-generated portion of the compress emitter. #define GEN_COMPRESS_INSTR #include "RISCVGenCompressInstEmitter.inc" +STATISTIC(RISCVNumInstrsCompressed, + "Number of RISC-V Compressed instructions emitted"); + namespace { struct RISCVOperand; @@ -188,6 +194,18 @@ public: Parser.addAliasForDirective(".word", ".4byte"); Parser.addAliasForDirective(".dword", ".8byte"); setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); + + if (Options.ABIName.back() == 'f' && + !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) { + errs() << "Hard-float 'f' ABI can't be used for a target that " + "doesn't support the F instruction set extension (ignoring " + "target-abi)\n"; + } else if (Options.ABIName.back() == 'd' && + !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) { + errs() << "Hard-float 'd' ABI can't be used for a target that " + "doesn't support the D instruction set extension (ignoring " + "target-abi)\n"; + } } }; @@ -258,6 +276,11 @@ public: bool isMem() const override { return false; } bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } + bool isGPR() const { + return Kind == KindTy::Register && + RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); + } + static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, RISCVMCExpr::VariantKind &VK) { if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { @@ -738,7 +761,9 @@ public: } // end anonymous namespace. #define GET_REGISTER_MATCHER +#define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION +#define GET_MNEMONIC_SPELL_CHECKER #include "RISCVGenAsmMatcher.inc" static Register convertFPR64ToFPR32(Register Reg) { @@ -775,24 +800,45 @@ bool RISCVAsmParser::generateImmOutOfRangeError( return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); } +static std::string RISCVMnemonicSpellCheck(StringRef S, + const FeatureBitset &FBS, + unsigned VariantID = 0); + bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; + FeatureBitset MissingFeatures; auto Result = - MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); + MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, + MatchingInlineAsm); switch (Result) { default: break; case Match_Success: return processInstruction(Inst, IDLoc, Operands, Out); - case Match_MissingFeature: - return Error(IDLoc, "instruction use requires an option to be enabled"); - case Match_MnemonicFail: - return Error(IDLoc, "unrecognized instruction mnemonic"); + case Match_MissingFeature: { + assert(MissingFeatures.any() && "Unknown missing features!"); + bool FirstFeature = true; + std::string Msg = "instruction requires the following:"; + for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { + if (MissingFeatures[i]) { + Msg += FirstFeature ? " " : ", "; + Msg += getSubtargetFeatureName(i); + FirstFeature = false; + } + } + return Error(IDLoc, Msg); + } + case Match_MnemonicFail: { + FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); + std::string Suggestion = RISCVMnemonicSpellCheck( + ((RISCVOperand &)*Operands[0]).getToken(), FBS); + return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); + } case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0U) { @@ -1587,7 +1633,8 @@ bool RISCVAsmParser::parseDirectiveOption() { void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); - CInst.setLoc(Inst.getLoc()); + if (Res) + ++RISCVNumInstrsCompressed; S.EmitInstruction((Res ? CInst : Inst), getSTI()); } @@ -1837,7 +1884,7 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, return false; } -extern "C" void LLVMInitializeRISCVAsmParser() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); } |