diff options
-rw-r--r-- | include/llvm/Target/TargetAsmParser.h | 14 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 39 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 7 | ||||
-rw-r--r-- | tools/llvm-mc/llvm-mc.cpp | 1 |
4 files changed, 58 insertions, 3 deletions
diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/Target/TargetAsmParser.h index 8b8b210..ef1fc49 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/Target/TargetAsmParser.h @@ -10,6 +10,8 @@ #ifndef LLVM_TARGET_TARGETPARSER_H #define LLVM_TARGET_TARGETPARSER_H +#include "llvm/MC/MCAsmLexer.h" + namespace llvm { class MCAsmParser; class MCInst; @@ -44,6 +46,18 @@ public: /// \param Inst [out] - On success, the parsed instruction. /// \return True on failure. virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst) = 0; + + /// ParseDirective - Parse a target specific assembler directive + /// + /// The parser is positioned following the directive name. The target + /// specific directive parser should parse the entire directive doing or + /// recording any target specific work, or return true and do nothing if the + /// directive is not target specific. If the directive is specific for + /// the target, the entire line is parsed up to and including the + /// end-of-statement token and false is returned. + /// + /// \param ID - the identifier token of the directive. + virtual bool ParseDirective(AsmToken DirectiveID) = 0; }; } // End llvm namespace diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index e5f23e0..aa04ba6 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmLexer.h" #include "llvm/MC/MCAsmParser.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/SourceMgr.h" @@ -39,7 +40,9 @@ private: bool ParseOperand(X86Operand &Op); bool ParseMemOperand(X86Operand &Op); - + + bool ParseDirectiveWord(unsigned Size, SMLoc L); + /// @name Auto-generated Match Functions /// { @@ -57,6 +60,8 @@ public: : TargetAsmParser(T), Parser(_Parser) {} virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst); + + virtual bool ParseDirective(AsmToken DirectiveID); }; } // end anonymous namespace @@ -432,6 +437,38 @@ bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) { return true; } +bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) { + StringRef IDVal = DirectiveID.getIdentifier(); + if (IDVal == ".word") + return ParseDirectiveWord(2, DirectiveID.getLoc()); + return true; +} + +/// ParseDirectiveWord +/// ::= .word [ expression (, expression)* ] +bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + const MCExpr *Value; + if (getParser().ParseExpression(Value)) + return true; + + getParser().getStreamer().EmitValue(Value, Size); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + // FIXME: Improve diagnostic. + if (getLexer().isNot(AsmToken::Comma)) + return Error(L, "unexpected token in directive"); + getLexer().Lex(); + } + } + + getLexer().Lex(); + return false; +} + // Force static initialization. extern "C" void LLVMInitializeX86AsmParser() { RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target); diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index f51f43a..b1e8e9a 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -591,10 +591,9 @@ bool AsmParser::ParseStatement() { if (IDVal == ".asciz") return ParseDirectiveAscii(true); - // FIXME: Target hooks for size? Also for "word", "hword". if (IDVal == ".byte") return ParseDirectiveValue(1); - if (IDVal == ".short" || IDVal == ".word") + if (IDVal == ".short") return ParseDirectiveValue(2); if (IDVal == ".long") return ParseDirectiveValue(4); @@ -685,6 +684,10 @@ bool AsmParser::ParseStatement() { if (IDVal == ".loc") return ParseDirectiveLoc(IDLoc); + // Target hook for parsing target specific directives. + if (!getTargetParser().ParseDirective(ID)) + return false; + Warning(IDLoc, "ignoring directive for now"); EatToEndOfStatement(); return false; diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index bf3c017..e5d99be 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCAsmLexer.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/Support/CommandLine.h" |