mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
Split the TargetAsmParser "ParseInstruction" interface in half:
the new ParseInstruction method just parses and returns a list of target operands. A new MatchInstruction interface is used to turn the operand list into an MCInst. This requires new/deleting all the operands, but it also gives targets the ability to use polymorphic operands if they want to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93469 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
74a265686d
commit
9898671a74
@ -17,6 +17,8 @@ class StringRef;
|
|||||||
class Target;
|
class Target;
|
||||||
class SMLoc;
|
class SMLoc;
|
||||||
class AsmToken;
|
class AsmToken;
|
||||||
|
class MCParsedAsmOperand;
|
||||||
|
template <typename T> class SmallVectorImpl;
|
||||||
|
|
||||||
/// TargetAsmParser - Generic interface to target specific assembly parsers.
|
/// TargetAsmParser - Generic interface to target specific assembly parsers.
|
||||||
class TargetAsmParser {
|
class TargetAsmParser {
|
||||||
@ -43,10 +45,11 @@ public:
|
|||||||
//
|
//
|
||||||
/// \param AP - The current parser object.
|
/// \param AP - The current parser object.
|
||||||
/// \param Name - The instruction name.
|
/// \param Name - The instruction name.
|
||||||
/// \param Inst [out] - On success, the parsed instruction.
|
/// \param Operands [out] - The list of parsed operands, this returns
|
||||||
|
/// ownership of them to the caller.
|
||||||
/// \return True on failure.
|
/// \return True on failure.
|
||||||
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
MCInst &Inst) = 0;
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
|
||||||
|
|
||||||
/// ParseDirective - Parse a target specific assembler directive
|
/// ParseDirective - Parse a target specific assembler directive
|
||||||
///
|
///
|
||||||
@ -59,6 +62,14 @@ public:
|
|||||||
///
|
///
|
||||||
/// \param ID - the identifier token of the directive.
|
/// \param ID - the identifier token of the directive.
|
||||||
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
|
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
|
||||||
|
|
||||||
|
/// MatchInstruction - Recognize a series of operands of a parsed instruction
|
||||||
|
/// as an actual MCInst. This returns false and fills in Inst on success and
|
||||||
|
/// returns true on failure to match.
|
||||||
|
virtual bool
|
||||||
|
MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
|
MCInst &Inst) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -79,7 +79,7 @@ private:
|
|||||||
|
|
||||||
/// @name Auto-generated Match Functions
|
/// @name Auto-generated Match Functions
|
||||||
/// {
|
/// {
|
||||||
bool MatchInstruction(SmallVectorImpl<ARMOperand> &Operands,
|
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
MCInst &Inst);
|
MCInst &Inst);
|
||||||
|
|
||||||
/// MatchRegisterName - Match the given string to a register name and return
|
/// MatchRegisterName - Match the given string to a register name and return
|
||||||
@ -96,7 +96,7 @@ public:
|
|||||||
: TargetAsmParser(T), Parser(_Parser) {}
|
: TargetAsmParser(T), Parser(_Parser) {}
|
||||||
|
|
||||||
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
MCInst &Inst);
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||||
|
|
||||||
virtual bool ParseDirective(AsmToken DirectiveID);
|
virtual bool ParseDirective(AsmToken DirectiveID);
|
||||||
};
|
};
|
||||||
@ -517,9 +517,10 @@ int ARMAsmParser::MatchRegisterName(const StringRef &Name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A hack to allow some testing, to be replaced by a real table gen version.
|
/// A hack to allow some testing, to be replaced by a real table gen version.
|
||||||
bool ARMAsmParser::MatchInstruction(SmallVectorImpl<ARMOperand> &Operands,
|
bool ARMAsmParser::
|
||||||
MCInst &Inst) {
|
MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
struct ARMOperand Op0 = Operands[0];
|
MCInst &Inst) {
|
||||||
|
ARMOperand &Op0 = *(ARMOperand*)Operands[0];
|
||||||
assert(Op0.Kind == ARMOperand::Token && "First operand not a Token");
|
assert(Op0.Kind == ARMOperand::Token && "First operand not a Token");
|
||||||
const StringRef &Mnemonic = Op0.getToken();
|
const StringRef &Mnemonic = Op0.getToken();
|
||||||
if (Mnemonic == "add" ||
|
if (Mnemonic == "add" ||
|
||||||
@ -581,33 +582,26 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
|
|||||||
|
|
||||||
/// Parse an arm instruction mnemonic followed by its operands.
|
/// Parse an arm instruction mnemonic followed by its operands.
|
||||||
bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
MCInst &Inst) {
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
SmallVector<ARMOperand, 7> Operands;
|
Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
|
||||||
|
|
||||||
Operands.push_back(ARMOperand::CreateToken(Name));
|
|
||||||
|
|
||||||
SMLoc Loc = getLexer().getTok().getLoc();
|
SMLoc Loc = getLexer().getTok().getLoc();
|
||||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||||
|
|
||||||
// Read the first operand.
|
// Read the first operand.
|
||||||
Operands.push_back(ARMOperand());
|
ARMOperand Op;
|
||||||
if (ParseOperand(Operands.back()))
|
if (ParseOperand(Op)) return true;
|
||||||
return true;
|
Operands.push_back(new ARMOperand(Op));
|
||||||
|
|
||||||
while (getLexer().is(AsmToken::Comma)) {
|
while (getLexer().is(AsmToken::Comma)) {
|
||||||
getLexer().Lex(); // Eat the comma.
|
getLexer().Lex(); // Eat the comma.
|
||||||
|
|
||||||
// Parse and remember the operand.
|
// Parse and remember the operand.
|
||||||
Operands.push_back(ARMOperand());
|
if (ParseOperand(Op)) return true;
|
||||||
if (ParseOperand(Operands.back()))
|
Operands.push_back(new ARMOperand(Op));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!MatchInstruction(Operands, Inst))
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseDirective parses the arm specific directives
|
/// ParseDirective parses the arm specific directives
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Target/TargetAsmParser.h"
|
||||||
#include "X86.h"
|
#include "X86.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
@ -47,7 +48,7 @@ private:
|
|||||||
/// @name Auto-generated Match Functions
|
/// @name Auto-generated Match Functions
|
||||||
/// {
|
/// {
|
||||||
|
|
||||||
bool MatchInstruction(SmallVectorImpl<X86Operand> &Operands,
|
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
|
||||||
MCInst &Inst);
|
MCInst &Inst);
|
||||||
|
|
||||||
/// MatchRegisterName - Match the given string to a register name, or 0 if
|
/// MatchRegisterName - Match the given string to a register name, or 0 if
|
||||||
@ -61,7 +62,7 @@ public:
|
|||||||
: TargetAsmParser(T), Parser(_Parser) {}
|
: TargetAsmParser(T), Parser(_Parser) {}
|
||||||
|
|
||||||
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
MCInst &Inst);
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
|
||||||
|
|
||||||
virtual bool ParseDirective(AsmToken DirectiveID);
|
virtual bool ParseDirective(AsmToken DirectiveID);
|
||||||
};
|
};
|
||||||
@ -402,11 +403,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86ATTAsmParser::ParseInstruction(const StringRef &Name,
|
bool X86ATTAsmParser::
|
||||||
SMLoc NameLoc, MCInst &Inst) {
|
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
|
||||||
SmallVector<X86Operand, 8> Operands;
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
|
|
||||||
Operands.push_back(X86Operand::CreateToken(Name));
|
Operands.push_back(new X86Operand(X86Operand::CreateToken(Name)));
|
||||||
|
|
||||||
SMLoc Loc = getLexer().getTok().getLoc();
|
SMLoc Loc = getLexer().getTok().getLoc();
|
||||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||||
@ -414,31 +415,27 @@ bool X86ATTAsmParser::ParseInstruction(const StringRef &Name,
|
|||||||
// Parse '*' modifier.
|
// Parse '*' modifier.
|
||||||
if (getLexer().is(AsmToken::Star)) {
|
if (getLexer().is(AsmToken::Star)) {
|
||||||
getLexer().Lex(); // Eat the star.
|
getLexer().Lex(); // Eat the star.
|
||||||
Operands.push_back(X86Operand::CreateToken("*"));
|
Operands.push_back(new X86Operand(X86Operand::CreateToken("*")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the first operand.
|
// Read the first operand.
|
||||||
Operands.push_back(X86Operand());
|
X86Operand Op;
|
||||||
if (ParseOperand(Operands.back()))
|
if (ParseOperand(Op))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
Operands.push_back(new X86Operand(Op));
|
||||||
|
|
||||||
while (getLexer().is(AsmToken::Comma)) {
|
while (getLexer().is(AsmToken::Comma)) {
|
||||||
getLexer().Lex(); // Eat the comma.
|
getLexer().Lex(); // Eat the comma.
|
||||||
|
|
||||||
// Parse and remember the operand.
|
// Parse and remember the operand.
|
||||||
Operands.push_back(X86Operand());
|
if (ParseOperand(Op))
|
||||||
if (ParseOperand(Operands.back()))
|
|
||||||
return true;
|
return true;
|
||||||
|
Operands.push_back(new X86Operand(Op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MatchInstruction(Operands, Inst))
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
// FIXME: We should give nicer diagnostics about the exact failure.
|
|
||||||
|
|
||||||
Error(Loc, "unrecognized instruction");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
|
bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||||
|
@ -44,7 +44,7 @@ void AsmLexer::PrintMessage(SMLoc Loc, const std::string &Msg,
|
|||||||
/// ReturnError - Set the error to the specified string at the specified
|
/// ReturnError - Set the error to the specified string at the specified
|
||||||
/// location. This is defined to always return AsmToken::Error.
|
/// location. This is defined to always return AsmToken::Error.
|
||||||
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
|
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
|
||||||
SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
|
PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
|
||||||
return AsmToken(AsmToken::Error, StringRef(Loc, 0));
|
return AsmToken(AsmToken::Error, StringRef(Loc, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#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/MCParsedAsmOperand.h"
|
||||||
#include "llvm/MC/MCSectionMachO.h"
|
#include "llvm/MC/MCSectionMachO.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
@ -710,16 +711,34 @@ bool AsmParser::ParseStatement() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCInst Inst;
|
|
||||||
if (getTargetParser().ParseInstruction(IDVal, IDLoc, Inst))
|
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
|
||||||
|
if (getTargetParser().ParseInstruction(IDVal, IDLoc, ParsedOperands))
|
||||||
|
// FIXME: Leaking ParsedOperands on failure.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (Lexer.isNot(AsmToken::EndOfStatement))
|
if (Lexer.isNot(AsmToken::EndOfStatement))
|
||||||
|
// FIXME: Leaking ParsedOperands on failure.
|
||||||
return TokError("unexpected token in argument list");
|
return TokError("unexpected token in argument list");
|
||||||
|
|
||||||
// Eat the end of statement marker.
|
// Eat the end of statement marker.
|
||||||
Lexer.Lex();
|
Lexer.Lex();
|
||||||
|
|
||||||
|
|
||||||
|
MCInst Inst;
|
||||||
|
|
||||||
|
bool MatchFail = getTargetParser().MatchInstruction(ParsedOperands, Inst);
|
||||||
|
|
||||||
|
// Free any parsed operands.
|
||||||
|
for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
|
||||||
|
delete ParsedOperands[i];
|
||||||
|
|
||||||
|
if (MatchFail) {
|
||||||
|
// FIXME: We should give nicer diagnostics about the exact failure.
|
||||||
|
Error(IDLoc, "unrecognized instruction");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Instruction is good, process it.
|
// Instruction is good, process it.
|
||||||
Out.EmitInstruction(Inst);
|
Out.EmitInstruction(Inst);
|
||||||
|
|
||||||
|
@ -961,8 +961,8 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
|
|
||||||
CvtOS << "static bool ConvertToMCInst(ConversionKind Kind, MCInst &Inst, "
|
CvtOS << "static bool ConvertToMCInst(ConversionKind Kind, MCInst &Inst, "
|
||||||
<< "unsigned Opcode,\n"
|
<< "unsigned Opcode,\n"
|
||||||
<< " SmallVectorImpl<"
|
<< " const SmallVectorImpl<MCParsedAsmOperand*"
|
||||||
<< Target.getName() << "Operand> &Operands) {\n";
|
<< "> &Operands) {\n";
|
||||||
CvtOS << " Inst.setOpcode(Opcode);\n";
|
CvtOS << " Inst.setOpcode(Opcode);\n";
|
||||||
CvtOS << " switch (Kind) {\n";
|
CvtOS << " switch (Kind) {\n";
|
||||||
CvtOS << " default:\n";
|
CvtOS << " default:\n";
|
||||||
@ -972,6 +972,9 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
OS << "// Unified function for converting operants to MCInst instances.\n\n";
|
OS << "// Unified function for converting operants to MCInst instances.\n\n";
|
||||||
OS << "enum ConversionKind {\n";
|
OS << "enum ConversionKind {\n";
|
||||||
|
|
||||||
|
// TargetOperandClass - This is the target's operand class, like X86Operand.
|
||||||
|
std::string TargetOperandClass = Target.getName() + "Operand";
|
||||||
|
|
||||||
for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(),
|
for (std::vector<InstructionInfo*>::const_iterator it = Infos.begin(),
|
||||||
ie = Infos.end(); it != ie; ++it) {
|
ie = Infos.end(); it != ie; ++it) {
|
||||||
InstructionInfo &II = **it;
|
InstructionInfo &II = **it;
|
||||||
@ -1050,8 +1053,9 @@ static void EmitConvertToMCInst(CodeGenTarget &Target,
|
|||||||
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
|
for (; CurIndex != Op.OperandInfo->MIOperandNo; ++CurIndex)
|
||||||
CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
|
CvtOS << " Inst.addOperand(MCOperand::CreateReg(0));\n";
|
||||||
|
|
||||||
CvtOS << " Operands[" << MIOperandList[i].second
|
CvtOS << " ((" << TargetOperandClass << "*)Operands["
|
||||||
<< "]." << Op.Class->RenderMethod
|
<< MIOperandList[i].second
|
||||||
|
<< "])->" << Op.Class->RenderMethod
|
||||||
<< "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
|
<< "(Inst, " << Op.OperandInfo->MINumOperands << ");\n";
|
||||||
CurIndex += Op.OperandInfo->MINumOperands;
|
CurIndex += Op.OperandInfo->MINumOperands;
|
||||||
}
|
}
|
||||||
@ -1111,8 +1115,9 @@ static void EmitMatchClassEnumeration(CodeGenTarget &Target,
|
|||||||
static void EmitClassifyOperand(CodeGenTarget &Target,
|
static void EmitClassifyOperand(CodeGenTarget &Target,
|
||||||
AsmMatcherInfo &Info,
|
AsmMatcherInfo &Info,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
OS << "static MatchClassKind ClassifyOperand("
|
OS << "static MatchClassKind ClassifyOperand(MCParsedAsmOperand *GOp) {\n"
|
||||||
<< Target.getName() << "Operand &Operand) {\n";
|
<< " " << Target.getName() << "Operand &Operand = *("
|
||||||
|
<< Target.getName() << "Operand*)GOp;\n";
|
||||||
|
|
||||||
// Classify tokens.
|
// Classify tokens.
|
||||||
OS << " if (Operand.isToken())\n";
|
OS << " if (Operand.isToken())\n";
|
||||||
@ -1467,9 +1472,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
|
MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
|
||||||
|
|
||||||
OS << "bool " << Target.getName() << ClassName
|
OS << "bool " << Target.getName() << ClassName
|
||||||
<< "::MatchInstruction("
|
<< "::\nMatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> "
|
||||||
<< "SmallVectorImpl<" << Target.getName() << "Operand> &Operands, "
|
"&Operands,\n MCInst &Inst) {\n";
|
||||||
<< "MCInst &Inst) {\n";
|
|
||||||
|
|
||||||
// Emit the static match table; unused classes get initalized to 0 which is
|
// Emit the static match table; unused classes get initalized to 0 which is
|
||||||
// guaranteed to be InvalidMatchClass.
|
// guaranteed to be InvalidMatchClass.
|
||||||
|
Loading…
Reference in New Issue
Block a user