Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
//===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===// | //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===// | ||||
// | // | ||||
// The LLVM Compiler Infrastructure | // The LLVM Compiler Infrastructure | ||||
// | // | ||||
// This file is distributed under the University of Illinois Open Source | // This file is distributed under the University of Illinois Open Source | ||||
// License. See LICENSE.TXT for details. | // License. See LICENSE.TXT for details. | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "MCTargetDesc/RISCVBaseInfo.h" | #include "MCTargetDesc/RISCVBaseInfo.h" | ||||
#include "MCTargetDesc/RISCVMCExpr.h" | #include "MCTargetDesc/RISCVMCExpr.h" | ||||
#include "MCTargetDesc/RISCVMCTargetDesc.h" | #include "MCTargetDesc/RISCVMCTargetDesc.h" | ||||
#include "MCTargetDesc/RISCVTargetStreamer.h" | |||||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | ||||
#include "llvm/ADT/StringSwitch.h" | #include "llvm/ADT/StringSwitch.h" | ||||
#include "llvm/MC/MCContext.h" | #include "llvm/MC/MCContext.h" | ||||
#include "llvm/MC/MCExpr.h" | #include "llvm/MC/MCExpr.h" | ||||
#include "llvm/MC/MCInst.h" | #include "llvm/MC/MCInst.h" | ||||
#include "llvm/MC/MCParser/MCAsmLexer.h" | #include "llvm/MC/MCParser/MCAsmLexer.h" | ||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h" | #include "llvm/MC/MCParser/MCParsedAsmOperand.h" | ||||
#include "llvm/MC/MCParser/MCTargetAsmParser.h" | #include "llvm/MC/MCParser/MCTargetAsmParser.h" | ||||
Show All 11 Lines | |||||
namespace { | namespace { | ||||
struct RISCVOperand; | struct RISCVOperand; | ||||
class RISCVAsmParser : public MCTargetAsmParser { | class RISCVAsmParser : public MCTargetAsmParser { | ||||
SMLoc getLoc() const { return getParser().getTok().getLoc(); } | SMLoc getLoc() const { return getParser().getTok().getLoc(); } | ||||
bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } | bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } | ||||
RISCVTargetStreamer &getTargetStreamer() { | |||||
MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); | |||||
return static_cast<RISCVTargetStreamer &>(TS); | |||||
} | |||||
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, | unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, | ||||
unsigned Kind) override; | unsigned Kind) override; | ||||
bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, | bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, | ||||
int Lower, int Upper, Twine Msg); | int Lower, int Upper, Twine Msg); | ||||
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, | ||||
OperandVector &Operands, MCStreamer &Out, | OperandVector &Operands, MCStreamer &Out, | ||||
Show All 14 Lines | #include "RISCVGenAsmMatcher.inc" | ||||
OperandMatchResultTy parseImmediate(OperandVector &Operands); | OperandMatchResultTy parseImmediate(OperandVector &Operands); | ||||
OperandMatchResultTy parseRegister(OperandVector &Operands, | OperandMatchResultTy parseRegister(OperandVector &Operands, | ||||
bool AllowParens = false); | bool AllowParens = false); | ||||
OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); | OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); | ||||
OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); | OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); | ||||
bool parseOperand(OperandVector &Operands, bool ForceImmediate); | bool parseOperand(OperandVector &Operands, bool ForceImmediate); | ||||
bool parseDirectiveOption(); | |||||
void setFeatureBits(uint64_t Feature, StringRef FeatureString) { | |||||
if (!(getSTI().getFeatureBits()[Feature])) { | |||||
MCSubtargetInfo &STI = copySTI(); | |||||
setAvailableFeatures( | |||||
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); | |||||
} | |||||
} | |||||
void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { | |||||
if (getSTI().getFeatureBits()[Feature]) { | |||||
MCSubtargetInfo &STI = copySTI(); | |||||
setAvailableFeatures( | |||||
ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); | |||||
} | |||||
} | |||||
public: | public: | ||||
enum RISCVMatchResultTy { | enum RISCVMatchResultTy { | ||||
Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, | Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, | ||||
#define GET_OPERAND_DIAGNOSTIC_TYPES | #define GET_OPERAND_DIAGNOSTIC_TYPES | ||||
#include "RISCVGenAsmMatcher.inc" | #include "RISCVGenAsmMatcher.inc" | ||||
#undef GET_OPERAND_DIAGNOSTIC_TYPES | #undef GET_OPERAND_DIAGNOSTIC_TYPES | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 901 Lines • ▼ Show 20 Lines | bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, | ||||
Addend = AddendExpr->getValue(); | Addend = AddendExpr->getValue(); | ||||
if (BE->getOpcode() == MCBinaryExpr::Sub) | if (BE->getOpcode() == MCBinaryExpr::Sub) | ||||
Addend = -Addend; | Addend = -Addend; | ||||
// It's some symbol reference + a constant addend | // It's some symbol reference + a constant addend | ||||
return Kind != RISCVMCExpr::VK_RISCV_Invalid; | return Kind != RISCVMCExpr::VK_RISCV_Invalid; | ||||
} | } | ||||
bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } | bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { | ||||
// This returns false if this function recognizes the directive | |||||
// regardless of whether it is successfully handles or reports an | |||||
// error. Otherwise it returns true to give the generic parser a | |||||
// chance at recognizing it. | |||||
StringRef IDVal = DirectiveID.getString(); | |||||
if (IDVal == ".option") | |||||
return parseDirectiveOption(); | |||||
return true; | |||||
} | |||||
bool RISCVAsmParser::parseDirectiveOption() { | |||||
MCAsmParser &Parser = getParser(); | |||||
// Get the option token. | |||||
AsmToken Tok = Parser.getTok(); | |||||
// At the moment only identifiers are supported. | |||||
if (Tok.isNot(AsmToken::Identifier)) | |||||
return Error(Parser.getTok().getLoc(), | |||||
"unexpected token, expected identifier"); | |||||
StringRef Option = Tok.getIdentifier(); | |||||
if (Option == "rvc") { | |||||
getTargetStreamer().emitDirectiveOptionRVC(); | |||||
Parser.Lex(); | |||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) | |||||
return Error(Parser.getTok().getLoc(), | |||||
"unexpected token, expected end of statement"); | |||||
setFeatureBits(RISCV::FeatureStdExtC, "c"); | |||||
return false; | |||||
} | |||||
if (Option == "norvc") { | |||||
getTargetStreamer().emitDirectiveOptionNoRVC(); | |||||
Parser.Lex(); | |||||
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) | |||||
return Error(Parser.getTok().getLoc(), | |||||
"unexpected token, expected end of statement"); | |||||
clearFeatureBits(RISCV::FeatureStdExtC, "c"); | |||||
return false; | |||||
} | |||||
// Unknown option. | |||||
Warning(Parser.getTok().getLoc(), | |||||
"unknown option, expected 'rvc' or 'norvc'"); | |||||
Parser.eatToEndOfStatement(); | |||||
return false; | |||||
} | |||||
extern "C" void LLVMInitializeRISCVAsmParser() { | extern "C" void LLVMInitializeRISCVAsmParser() { | ||||
RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); | RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); | ||||
RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); | RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); | ||||
} | } |