mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Match X86 register names to number.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77404 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
55e459aa75
commit
0e2771f4c4
@ -410,6 +410,27 @@ def COPY_TO_REGCLASS : Instruction {
|
|||||||
let isAsCheapAsAMove = 1;
|
let isAsCheapAsAMove = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// AsmParser - This class can be implemented by targets that wish to implement
|
||||||
|
// .s file parsing.
|
||||||
|
//
|
||||||
|
// Subtargets can have multiple different assembly parsers (e.g. AT&T vs Intel
|
||||||
|
// syntax on X86 for example).
|
||||||
|
//
|
||||||
|
class AsmParser {
|
||||||
|
// AsmWriterClassName - This specifies the suffix to use for the asmwriter
|
||||||
|
// class. Generated AsmWriter classes are always prefixed with the target
|
||||||
|
// name.
|
||||||
|
string AsmParserClassName = "AsmParser";
|
||||||
|
|
||||||
|
// Variant - AsmParsers can be of multiple different variants. Variants are
|
||||||
|
// used to support targets that need to parser multiple formats for the
|
||||||
|
// assembly language.
|
||||||
|
int Variant = 0;
|
||||||
|
}
|
||||||
|
def DefaultAsmParser : AsmParser;
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// AsmWriter - This class can be implemented by targets that need to customize
|
// AsmWriter - This class can be implemented by targets that need to customize
|
||||||
// the format of the .s file writer.
|
// the format of the .s file writer.
|
||||||
@ -445,6 +466,9 @@ class Target {
|
|||||||
// InstructionSet - Instruction set description for this target.
|
// InstructionSet - Instruction set description for this target.
|
||||||
InstrInfo InstructionSet;
|
InstrInfo InstructionSet;
|
||||||
|
|
||||||
|
// AssemblyParsers - The AsmParser instances available for this target.
|
||||||
|
list<AsmParser> AssemblyParsers = [DefaultAsmParser];
|
||||||
|
|
||||||
// AssemblyWriters - The AsmWriter instances available for this target.
|
// AssemblyWriters - The AsmWriter instances available for this target.
|
||||||
list<AsmWriter> AssemblyWriters = [DefaultAsmWriter];
|
list<AsmWriter> AssemblyWriters = [DefaultAsmWriter];
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,13 @@ private:
|
|||||||
bool ParseOperand(X86Operand &Op);
|
bool ParseOperand(X86Operand &Op);
|
||||||
|
|
||||||
bool ParseMemOperand(X86Operand &Op);
|
bool ParseMemOperand(X86Operand &Op);
|
||||||
|
|
||||||
|
/// @name Auto-generated Match Functions
|
||||||
|
/// {
|
||||||
|
|
||||||
|
bool MatchRegisterName(const StringRef &Name, unsigned &RegNo);
|
||||||
|
|
||||||
|
/// }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
|
X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
|
||||||
@ -118,10 +125,17 @@ struct X86Operand {
|
|||||||
//
|
//
|
||||||
|
|
||||||
bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
|
bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
|
||||||
assert(getLexer().is(AsmToken::Register) && "Invalid token kind!");
|
AsmToken Tok = getLexer().getTok();
|
||||||
|
assert(Tok.is(AsmToken::Register) && "Invalid token kind!");
|
||||||
|
|
||||||
// FIXME: Decode register number.
|
// FIXME: Validate register for the current architecture; we have to do
|
||||||
Op = X86Operand::CreateReg(123);
|
// validation later, so maybe there is no need for this here.
|
||||||
|
unsigned RegNo;
|
||||||
|
assert(Tok.getString().startswith("%") && "Invalid register name!");
|
||||||
|
if (MatchRegisterName(Tok.getString().substr(1), RegNo))
|
||||||
|
return Error(Tok.getLoc(), "invalid register name");
|
||||||
|
|
||||||
|
Op = X86Operand::CreateReg(RegNo);
|
||||||
getLexer().Lex(); // Eat register token.
|
getLexer().Lex(); // Eat register token.
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -308,3 +322,5 @@ extern "C" void LLVMInitializeX86AsmParser() {
|
|||||||
RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
|
RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
|
||||||
RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
|
RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "X86GenAsmMatcher.inc"
|
||||||
|
@ -178,6 +178,12 @@ include "X86CallingConv.td"
|
|||||||
// Assembly Printers
|
// Assembly Printers
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Currently the X86 assembly parser only supports ATT syntax.
|
||||||
|
def ATTAsmParser : AsmParser {
|
||||||
|
string AsmParserClassName = "ATTAsmParser";
|
||||||
|
int Variant = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// The X86 target supports two different syntaxes for emitting machine code.
|
// The X86 target supports two different syntaxes for emitting machine code.
|
||||||
// This is controlled by the -x86-asm-syntax={att|intel}
|
// This is controlled by the -x86-asm-syntax={att|intel}
|
||||||
def ATTAsmWriter : AsmWriter {
|
def ATTAsmWriter : AsmWriter {
|
||||||
@ -189,10 +195,11 @@ def IntelAsmWriter : AsmWriter {
|
|||||||
int Variant = 1;
|
int Variant = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def X86 : Target {
|
def X86 : Target {
|
||||||
// Information about the instructions...
|
// Information about the instructions...
|
||||||
let InstructionSet = X86InstrInfo;
|
let InstructionSet = X86InstrInfo;
|
||||||
|
|
||||||
|
let AssemblyParsers = [ATTAsmParser];
|
||||||
|
|
||||||
let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
|
let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,17 @@ using namespace llvm;
|
|||||||
void AsmMatcherEmitter::run(raw_ostream &OS) {
|
void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||||
CodeGenTarget Target;
|
CodeGenTarget Target;
|
||||||
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
||||||
|
Record *AsmParser = Target.getAsmParser();
|
||||||
|
std::string ClassName = AsmParser->getValueAsString("AsmParserClassName");
|
||||||
|
|
||||||
std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
|
std::string Namespace = Registers[0].TheDef->getValueAsString("Namespace");
|
||||||
|
|
||||||
EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
|
EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
|
||||||
OS << "namespace llvm {\n\n";
|
|
||||||
|
|
||||||
// Emit the function to match a register name to number.
|
// Emit the function to match a register name to number.
|
||||||
|
|
||||||
if (!Namespace.empty())
|
OS << "bool " << Target.getName() << ClassName
|
||||||
OS << "namespace " << Namespace << " {\n";
|
<< "::MatchRegisterName(const StringRef &Name, unsigned &RegNo) {\n";
|
||||||
OS << "bool MatchRegisterName(const std::string &Name, unsigned &RegNo) {\n";
|
|
||||||
|
|
||||||
// FIXME: TableGen should have a fast string matcher generator.
|
// FIXME: TableGen should have a fast string matcher generator.
|
||||||
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
|
||||||
@ -44,8 +44,4 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
}
|
}
|
||||||
OS << " return true;\n";
|
OS << " return true;\n";
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
||||||
if (!Namespace.empty())
|
|
||||||
OS << "}\n";
|
|
||||||
OS << "} // End llvm namespace \n";
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
static cl::opt<unsigned>
|
||||||
|
AsmParserNum("asmparsernum", cl::init(0),
|
||||||
|
cl::desc("Make -gen-asm-parser emit assembly parser #N"));
|
||||||
|
|
||||||
static cl::opt<unsigned>
|
static cl::opt<unsigned>
|
||||||
AsmWriterNum("asmwriternum", cl::init(0),
|
AsmWriterNum("asmwriternum", cl::init(0),
|
||||||
cl::desc("Make -gen-asm-writer emit assembly writer #N"));
|
cl::desc("Make -gen-asm-writer emit assembly writer #N"));
|
||||||
@ -133,6 +137,15 @@ Record *CodeGenTarget::getInstructionSet() const {
|
|||||||
return TargetRec->getValueAsDef("InstructionSet");
|
return TargetRec->getValueAsDef("InstructionSet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getAsmParser - Return the AssemblyParser definition for this target.
|
||||||
|
///
|
||||||
|
Record *CodeGenTarget::getAsmParser() const {
|
||||||
|
std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
|
||||||
|
if (AsmParserNum >= LI.size())
|
||||||
|
throw "Target does not have an AsmParser #" + utostr(AsmParserNum) + "!";
|
||||||
|
return LI[AsmParserNum];
|
||||||
|
}
|
||||||
|
|
||||||
/// getAsmWriter - Return the AssemblyWriter definition for this target.
|
/// getAsmWriter - Return the AssemblyWriter definition for this target.
|
||||||
///
|
///
|
||||||
Record *CodeGenTarget::getAsmWriter() const {
|
Record *CodeGenTarget::getAsmWriter() const {
|
||||||
|
@ -87,6 +87,10 @@ public:
|
|||||||
///
|
///
|
||||||
Record *getInstructionSet() const;
|
Record *getInstructionSet() const;
|
||||||
|
|
||||||
|
/// getAsmParser - Return the AssemblyParser definition for this target.
|
||||||
|
///
|
||||||
|
Record *getAsmParser() const;
|
||||||
|
|
||||||
/// getAsmWriter - Return the AssemblyWriter definition for this target.
|
/// getAsmWriter - Return the AssemblyWriter definition for this target.
|
||||||
///
|
///
|
||||||
Record *getAsmWriter() const;
|
Record *getAsmWriter() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user