Hi Daniel,
attached is a patch that pushes most of the object file specific parsing
out of AsmParser and down into MachOAsmParser. This was done as a
cleanup for the ELF work. I know that you're not happy with this
approach, particularly the fact that as we add more object file formats
and assembler dialects, it's going to cause a class explosion. But I was
hoping that we could use this as a foundation for further discussion.
Is there anything else about this patch that you don't like, or anything
that you think could be done better? What approach would you recommend
for solving this problem?
--->From d353b9af08cf1e1bb71fa20630f01a969a10925f Mon Sep 17 00:00:00 2001
Message-Id: <d353b9af08cf1e1bb71fa20630f01a969a10925f.1277162708.git.matt at
console-pimps.org>
From: Matt Fleming <matt at console-pimps.org>
Date: Sun, 13 Jun 2010 13:00:04 +0100
Subject: [PATCH] Create a new class hierarchy for assembly parsers.
This commit pulls all of the Mach-O specific bits out of lib/MC and puts
them into a MachOAsmParser class. This allows MachOAsmParser to take
care of implementing all the Mach-O assembler directives and the only
directives that are parsed in AsmParser are target-independent.
TargetAsmParser is deleted and all targets should interit from the
object file that the asm parser understands (currently just
MachOAsmParser).
Note that there's a missing commit to clang (because this repo doesn't
mirror the clang/ source).
---
include/llvm/MC/MCParser/AsmParser.h | 51 +-
include/llvm/MC/MCParser/MachOAsmParser.h | 56 +++
include/llvm/Target/TargetRegistry.h | 22 +-
lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 12 +-
lib/MC/MCParser/AsmParser.cpp | 573 +---------------------
lib/MC/MCParser/CMakeLists.txt | 2 +-
lib/MC/MCParser/MachOAsmParser.cpp | 630 ++++++++++++++++++++++++
lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 186 ++++----
lib/Target/X86/AsmParser/X86AsmParser.cpp | 293 +++++++----
tools/edis/EDDisassembler.cpp | 12 +-
tools/llvm-mc/llvm-mc.cpp | 10 +-
11 files changed, 1037 insertions(+), 810 deletions(-)
create mode 100644 include/llvm/MC/MCParser/MachOAsmParser.h
create mode 100644 lib/MC/MCParser/MachOAsmParser.cpp
diff --git a/include/llvm/MC/MCParser/AsmParser.h
b/include/llvm/MC/MCParser/AsmParser.h
index e929fd1..dc74299 100644
--- a/include/llvm/MC/MCParser/AsmParser.h
+++ b/include/llvm/MC/MCParser/AsmParser.h
@@ -17,6 +17,7 @@
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/AsmCond.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -36,10 +37,11 @@ class TargetAsmParser;
class Twine;
class AsmParser : public MCAsmParser {
-private:
+protected:
AsmLexer Lexer;
MCContext &Ctx;
MCStreamer &Out;
+private:
SourceMgr &SrcMgr;
TargetAsmParser *TargetParser;
@@ -88,14 +90,23 @@ public:
virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool ParseAbsoluteExpression(int64_t &Res);
+ virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*>
&Operands) = 0;
+ virtual const MCSection *getInitialTextSection() = 0;
/// }
-private:
+protected:
+
+ bool TokError(const char *Msg);
+
+ /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// and set \arg Res to the identifier contents.
+ bool ParseIdentifier(StringRef &Res);
+
MCSymbol *CreateSymbol(StringRef Name);
+private:
bool ParseStatement();
-
- bool TokError(const char *Msg);
void PrintMessage(SMLoc Loc, const std::string &Msg, const char *Type)
const;
@@ -110,15 +121,7 @@ private:
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc
&EndLoc);
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \arg Res to the identifier contents.
- bool ParseIdentifier(StringRef &Res);
-
// Directive Parsing.
- bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
- bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section,
- unsigned TAA = 0, unsigned ImplicitAlign =
0,
- unsigned StubSize = 0);
bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii",
".asciiz"
bool ParseDirectiveValue(unsigned Size); // ".byte",
".long", ...
bool ParseDirectiveFill(); // ".fill"
@@ -132,17 +135,6 @@ private:
/// accepts a single symbol (which should be a label or an external).
bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
bool ParseDirectiveELFType(); // ELF specific ".type"
- bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
- bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
-
- bool ParseDirectiveComm(bool IsLocal); // ".comm" and
".lcomm"
- bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill"
- bool ParseDirectiveDarwinTBSS(); // Darwin specific ".tbss"
-
- // Darwin specific ".subsections_via_symbols"
- bool ParseDirectiveDarwinSubsectionsViaSymbols();
- // Darwin specific .dump and .load
- bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump);
bool ParseDirectiveAbort(); // ".abort"
bool ParseDirectiveInclude(); // ".include"
@@ -159,6 +151,19 @@ private:
/// ParseEscapedString - Parse the current token as a string which may
include
/// escaped characters and return the string contents.
bool ParseEscapedString(std::string &Data);
+
+
+ virtual bool ParseDirective(AsmToken DirectiveID) {
+ assert(0 && "ParseDirective must be implemented by a
subclass");
+ };
+
+ // ParseTargetDirective - Parse a target-specific assembler directive.
+ virtual bool ParseTargetDirective(AsmToken DirectiveID) {
+ assert(0 && "ParseTargetDirective must be implemented in a
subclass");
+ };
+
+ virtual bool MatchInstruction(const
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCInst &Inst) = 0;
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCParser/MachOAsmParser.h
b/include/llvm/MC/MCParser/MachOAsmParser.h
new file mode 100644
index 0000000..e183b11
--- /dev/null
+++ b/include/llvm/MC/MCParser/MachOAsmParser.h
@@ -0,0 +1,56 @@
+//===- MachOAsmParser.h - Parser for Mach-O Assembly Files ------*- C++
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class declares the parser for Mach-O assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MACHOASMPARSER_H
+#define MACHOASMPARSER_H
+
+#include "llvm/MC/MCParser/AsmParser.h"
+
+namespace llvm {
+class MCContext;
+class MCStreamer;
+class MCAsmInfo;
+class SourceMgr;
+
+class MachOAsmParser : public AsmParser {
+public:
+ MachOAsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
+ const MCAsmInfo &MAI)
+ : AsmParser(SM, Ctx, Out, MAI) {}
+
+ ~MachOAsmParser() {};
+
+ /// ParseDirectiveSectionSwitch - Parse Mach-O specific asssembler
+ /// section directives.
+ bool ParseDirectiveSectionSwitch(StringRef Section);
+ bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
+
+ bool ParseDirectiveDarwinSymbolDesc(); // Darwin specific ".desc"
+ bool ParseDirectiveDarwinLsym(); // Darwin specific ".lsym"
+
+ bool ParseDirectiveDarwinZerofill(); // Darwin specific ".zerofill"
+ bool ParseDirectiveDarwinTBSS(); // Darwin specific ".tbss"
+
+ // Darwin specific ".subsections_via_symbols"
+ bool ParseDirectiveDarwinSubsectionsViaSymbols();
+ // Darwin specific .dump and .load
+ bool ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump);
+
+ bool ParseDirectiveComm(bool IsLocal);
+ bool ParseDirective(AsmToken DirectiveID);
+ const MCSection *getInitialTextSection();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetRegistry.h
b/include/llvm/Target/TargetRegistry.h
index 1418bee..0270e96 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -24,6 +24,7 @@
#include <cassert>
namespace llvm {
+ class AsmParser;
class AsmPrinter;
class Module;
class MCAssembler;
@@ -34,9 +35,9 @@ namespace llvm {
class MCDisassembler;
class MCInstPrinter;
class MCStreamer;
+ class SourceMgr;
class TargetAsmBackend;
class TargetAsmLexer;
- class TargetAsmParser;
class TargetMachine;
class raw_ostream;
@@ -65,7 +66,11 @@ namespace llvm {
const std::string &TT);
typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T,
const MCAsmInfo &MAI);
- typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,MCAsmParser
&P);
+ typedef AsmParser *(*AsmParserCtorTy)(const Target &T,
+ const std::string &Triple,
+ SourceMgr &SM,
+ MCContext &Ctx, MCStreamer
&Out,
+ const MCAsmInfo &MAI);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
unsigned SyntaxVariant,
@@ -235,12 +240,15 @@ namespace llvm {
/// createAsmParser - Create a target specific assembly parser.
///
+ /// \arg Triple - The target triple string.
/// \arg Parser - The target independent parser implementation to use for
/// parsing and lexing.
- TargetAsmParser *createAsmParser(MCAsmParser &Parser) const {
+ AsmParser *createAsmParser(const std::string &Triple, SourceMgr
&SM,
+ MCContext &Ctx, MCStreamer &Out,
+ const MCAsmInfo &MAI) const {
if (!AsmParserCtorFn)
return 0;
- return AsmParserCtorFn(*this, Parser);
+ return AsmParserCtorFn(*this, Triple, SM, Ctx, Out, MAI);
}
/// createAsmPrinter - Create a target specific assembly printer pass.
This
@@ -667,8 +675,10 @@ namespace llvm {
}
private:
- static TargetAsmParser *Allocator(const Target &T, MCAsmParser &P)
{
- return new AsmParserImpl(T, P);
+ static AsmParser *Allocator(const Target &T, const std::string
&Truple,
+ SourceMgr &S, MCContext &C,
+ MCStreamer &O, const MCAsmInfo &M) {
+ return new AsmParserImpl(T, S, C, O, M);
}
};
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index ba6fed2..1034b8f 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Host.h"
using namespace llvm;
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
@@ -83,16 +84,17 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned
LocCookie) const {
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
- AsmParser Parser(SrcMgr, OutContext, OutStreamer, *MAI);
- OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(Parser));
+ // FIXME: Doesn't work with cross-compilation currently.
+ OwningPtr<AsmParser>
TAP(TM.getTarget().createAsmParser(sys::getHostTriple(),
+ SrcMgr, OutContext,
+ OutStreamer, *MAI));
if (!TAP)
report_fatal_error("Inline asm not supported by this streamer
because"
" we don't have an asm parser for this
target\n");
- Parser.setTargetParser(*TAP.get());
// Don't implicitly switch to the text section before the asm.
- int Res = Parser.Run(/*NoInitialTextSection*/ true,
- /*NoFinalize*/ true);
+ int Res = TAP.get()->Run(/*NoInitialTextSection*/ true,
+ /*NoFinalize*/ true);
if (Res && !HasDiagHandler)
report_fatal_error("Error parsing inline asm\n");
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 4523eab..6b582e1 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -105,9 +105,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool
NoFinalize) {
//
// FIXME: Target hook & command line option for initial section.
if (!NoInitialTextSection)
- Out.SwitchSection(Ctx.getMachOSection("__TEXT",
"__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind::getText()));
+ Out.SwitchSection(getInitialTextSection());
// Prime the lexer.
Lex();
@@ -530,158 +528,7 @@ bool AsmParser::ParseStatement() {
// Otherwise, we have a normal instruction or directive.
if (IDVal[0] == '.') {
- // FIXME: This should be driven based on a hash lookup and callback.
- if (IDVal == ".section")
- return ParseDirectiveDarwinSection();
- if (IDVal == ".text")
- // FIXME: This changes behavior based on the -static flag to the
- // assembler.
- return ParseDirectiveSectionSwitch("__TEXT",
"__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
- if (IDVal == ".const")
- return ParseDirectiveSectionSwitch("__TEXT",
"__const");
- if (IDVal == ".static_const")
- return ParseDirectiveSectionSwitch("__TEXT",
"__static_const");
- if (IDVal == ".cstring")
- return
ParseDirectiveSectionSwitch("__TEXT","__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".literal4")
- return ParseDirectiveSectionSwitch("__TEXT",
"__literal4",
- MCSectionMachO::S_4BYTE_LITERALS,
- 4);
- if (IDVal == ".literal8")
- return ParseDirectiveSectionSwitch("__TEXT",
"__literal8",
- MCSectionMachO::S_8BYTE_LITERALS,
- 8);
- if (IDVal == ".literal16")
- return
ParseDirectiveSectionSwitch("__TEXT","__literal16",
- MCSectionMachO::S_16BYTE_LITERALS,
- 16);
- if (IDVal == ".constructor")
- return
ParseDirectiveSectionSwitch("__TEXT","__constructor");
- if (IDVal == ".destructor")
- return
ParseDirectiveSectionSwitch("__TEXT","__destructor");
- if (IDVal == ".fvmlib_init0")
- return
ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0");
- if (IDVal == ".fvmlib_init1")
- return
ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1");
-
- // FIXME: The assembler manual claims that this has the self modify code
- // flag, at least on x86-32, but that does not appear to be correct.
- if (IDVal == ".symbol_stub")
- return
ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
-
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- // FIXME: Different on PPC and ARM.
- 0, 16);
- // FIXME: PowerPC only?
- if (IDVal == ".picsymbol_stub")
- return
ParseDirectiveSectionSwitch("__TEXT","__picsymbol_stub",
- MCSectionMachO::S_SYMBOL_STUBS |
-
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, 26);
- if (IDVal == ".data")
- return ParseDirectiveSectionSwitch("__DATA",
"__data");
- if (IDVal == ".static_data")
- return ParseDirectiveSectionSwitch("__DATA",
"__static_data");
-
- // FIXME: The section names of these two are misspelled in the assembler
- // manual.
- if (IDVal == ".non_lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA",
"__nl_symbol_ptr",
-
MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
- 4);
- if (IDVal == ".lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA",
"__la_symbol_ptr",
-
MCSectionMachO::S_LAZY_SYMBOL_POINTERS,
- 4);
-
- if (IDVal == ".dyld")
- return ParseDirectiveSectionSwitch("__DATA",
"__dyld");
- if (IDVal == ".mod_init_func")
- return ParseDirectiveSectionSwitch("__DATA",
"__mod_init_func",
-
MCSectionMachO::S_MOD_INIT_FUNC_POINTERS,
- 4);
- if (IDVal == ".mod_term_func")
- return ParseDirectiveSectionSwitch("__DATA",
"__mod_term_func",
-
MCSectionMachO::S_MOD_TERM_FUNC_POINTERS,
- 4);
- if (IDVal == ".const_data")
- return ParseDirectiveSectionSwitch("__DATA",
"__const");
-
-
- if (IDVal == ".objc_class")
- return ParseDirectiveSectionSwitch("__OBJC",
"__class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_meta_class")
- return ParseDirectiveSectionSwitch("__OBJC",
"__meta_class",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cat_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC",
"__cat_cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cat_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC",
"__cat_inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_protocol")
- return ParseDirectiveSectionSwitch("__OBJC",
"__protocol",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_string_object")
- return ParseDirectiveSectionSwitch("__OBJC",
"__string_object",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC",
"__cls_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC",
"__inst_meth",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_cls_refs")
- return ParseDirectiveSectionSwitch("__OBJC",
"__cls_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS,
- 4);
- if (IDVal == ".objc_message_refs")
- return ParseDirectiveSectionSwitch("__OBJC",
"__message_refs",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
- MCSectionMachO::S_LITERAL_POINTERS,
- 4);
- if (IDVal == ".objc_symbols")
- return ParseDirectiveSectionSwitch("__OBJC",
"__symbols",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_category")
- return ParseDirectiveSectionSwitch("__OBJC",
"__category",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_class_vars")
- return ParseDirectiveSectionSwitch("__OBJC",
"__class_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_instance_vars")
- return ParseDirectiveSectionSwitch("__OBJC",
"__instance_vars",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_module_info")
- return ParseDirectiveSectionSwitch("__OBJC",
"__module_info",
- MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
- if (IDVal == ".objc_class_names")
- return ParseDirectiveSectionSwitch("__TEXT",
"__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_meth_var_types")
- return ParseDirectiveSectionSwitch("__TEXT",
"__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_meth_var_names")
- return ParseDirectiveSectionSwitch("__TEXT",
"__cstring",
- MCSectionMachO::S_CSTRING_LITERALS);
- if (IDVal == ".objc_selector_strs")
- return ParseDirectiveSectionSwitch("__OBJC",
"__selector_strs",
- MCSectionMachO::S_CSTRING_LITERALS);
-
- if (IDVal == ".tdata")
- return ParseDirectiveSectionSwitch("__DATA",
"__thread_data",
-
MCSectionMachO::S_THREAD_LOCAL_REGULAR);
- if (IDVal == ".tlv")
- return ParseDirectiveSectionSwitch("__DATA",
"__thread_vars",
-
MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
- if (IDVal == ".thread_init_func")
- return ParseDirectiveSectionSwitch("__DATA",
"__thread_init",
- MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
-
+
// Assembler features
if (IDVal == ".set")
return ParseDirectiveSet();
@@ -757,37 +604,22 @@ bool AsmParser::ParseStatement() {
if (IDVal == ".weak_reference")
return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
- if (IDVal == ".comm")
- return ParseDirectiveComm(/*IsLocal=*/false);
- if (IDVal == ".lcomm")
- return ParseDirectiveComm(/*IsLocal=*/true);
- if (IDVal == ".zerofill")
- return ParseDirectiveDarwinZerofill();
- if (IDVal == ".desc")
- return ParseDirectiveDarwinSymbolDesc();
- if (IDVal == ".lsym")
- return ParseDirectiveDarwinLsym();
- if (IDVal == ".tbss")
- return ParseDirectiveDarwinTBSS();
-
- if (IDVal == ".subsections_via_symbols")
- return ParseDirectiveDarwinSubsectionsViaSymbols();
if (IDVal == ".abort")
return ParseDirectiveAbort();
if (IDVal == ".include")
return ParseDirectiveInclude();
- if (IDVal == ".dump")
- return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
- if (IDVal == ".load")
- return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
+
+ // Architecture hook for parsing target specific directives.
+ if (!ParseDirective(ID))
+ return false;
// Look up the handler in the handler table,
bool(AsmParser::*Handler)(StringRef, SMLoc) = DirectiveMap[IDVal];
if (Handler)
return (this->*Handler)(IDVal, IDLoc);
-
+
// Target hook for parsing target specific directives.
- if (!getTargetParser().ParseDirective(ID))
+ if (!ParseTargetDirective(ID))
return false;
Warning(IDLoc, "ignoring directive for now");
@@ -801,15 +633,14 @@ bool AsmParser::ParseStatement() {
Opcode.push_back(tolower(IDVal[i]));
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
- bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
- ParsedOperands);
+ bool HadError = ParseInstruction(Opcode.str(), IDLoc, ParsedOperands);
if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
HadError = TokError("unexpected token in argument list");
// If parsing succeeded, match the instruction.
if (!HadError) {
MCInst Inst;
- if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
+ if (!MatchInstruction(ParsedOperands, Inst)) {
// Emit the instruction on success.
Out.EmitInstruction(Inst);
} else {
@@ -909,81 +740,6 @@ bool AsmParser::ParseDirectiveSet() {
return ParseAssignment(Name);
}
-/// ParseDirectiveSection:
-/// ::= .section identifier (',' identifier)*
-/// FIXME: This should actually parse out the segment, section, attributes and
-/// sizeof_stub fields.
-bool AsmParser::ParseDirectiveDarwinSection() {
- SMLoc Loc = Lexer.getLoc();
-
- StringRef SectionName;
- if (ParseIdentifier(SectionName))
- return Error(Loc, "expected identifier after '.section'
directive");
-
- // Verify there is a following comma.
- if (!Lexer.is(AsmToken::Comma))
- return TokError("unexpected token in '.section'
directive");
-
- std::string SectionSpec = SectionName;
- SectionSpec += ",";
-
- // Add all the tokens until the end of the line, ParseSectionSpecifier will
- // handle this.
- StringRef EOL = Lexer.LexUntilEndOfStatement();
- SectionSpec.append(EOL.begin(), EOL.end());
-
- Lex();
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.section'
directive");
- Lex();
-
-
- StringRef Segment, Section;
- unsigned TAA, StubSize;
- std::string ErrorStr =
- MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
- TAA, StubSize);
-
- if (!ErrorStr.empty())
- return Error(Loc, ErrorStr.c_str());
-
- // FIXME: Arch specific.
- bool isText = Segment == "__TEXT"; // FIXME: Hack.
- Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
- isText ? SectionKind::getText()
- : SectionKind::getDataRel()));
- return false;
-}
-
-/// ParseDirectiveSectionSwitch -
-bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
- const char *Section,
- unsigned TAA, unsigned Align,
- unsigned StubSize) {
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in section switching
directive");
- Lex();
-
- // FIXME: Arch specific.
- bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
- Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
- isText ? SectionKind::getText()
- : SectionKind::getDataRel()));
-
- // Set the implicit alignment, if any.
- //
- // FIXME: This isn't really what 'as' does; I think it just uses
the implicit
- // alignment on the section (e.g., if one manually inserts bytes into the
- // section, then just issueing the section switch directive will not realign
- // the section. However, this is arguably more reasonable behavior, and there
- // is no good reason for someone to intentionally emit incorrectly sized
- // values into the implicitly aligned sections.
- if (Align)
- Out.EmitValueToAlignment(Align, 0, 1, 0);
-
- return false;
-}
-
bool AsmParser::ParseEscapedString(std::string &Data) {
assert(Lexer.is(AsmToken::String) && "Unexpected current
token!");
@@ -1368,261 +1124,6 @@ bool AsmParser::ParseDirectiveELFType() {
return false;
}
-/// ParseDirectiveDarwinSymbolDesc
-/// ::= .desc identifier , expression
-bool AsmParser::ParseDirectiveDarwinSymbolDesc() {
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.desc' directive");
- Lex();
-
- SMLoc DescLoc = Lexer.getLoc();
- int64_t DescValue;
- if (ParseAbsoluteExpression(DescValue))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.desc' directive");
-
- Lex();
-
- // Set the n_desc field of this Symbol to this DescValue
- Out.EmitSymbolDesc(Sym, DescValue);
-
- return false;
-}
-
-/// ParseDirectiveComm
-/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
-bool AsmParser::ParseDirectiveComm(bool IsLocal) {
- SMLoc IDLoc = Lexer.getLoc();
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (Lexer.is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
-
- // If this target takes alignments in bytes (not log) validate and convert.
- if (Lexer.getMAI().getAlignmentIsInBytes()) {
- if (!isPowerOf2_64(Pow2Alignment))
- return Error(Pow2AlignmentLoc, "alignment must be a power of
2");
- Pow2Alignment = Log2_64(Pow2Alignment);
- }
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.comm' or
'.lcomm' directive");
-
- Lex();
-
- // NOTE: a size of zero for a .comm should create a undefined symbol
- // but a size of .lcomm creates a bss symbol of size zero.
- if (Size < 0)
- return Error(SizeLoc, "invalid '.comm' or '.lcomm'
directive size, can't "
- "be less than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assembler
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.comm' or
'.lcomm' directive "
- "alignment, can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // '.lcomm' is equivalent to '.zerofill'.
- // Create the Symbol as a common or local common with Size and Pow2Alignment
- if (IsLocal) {
- Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()),
- Sym, Size, 1 << Pow2Alignment);
- return false;
- }
-
- Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
-}
-
-/// ParseDirectiveDarwinZerofill
-/// ::= .zerofill segname , sectname [, identifier , size_expression [
-/// , align_expression ]]
-bool AsmParser::ParseDirectiveDarwinZerofill() {
- StringRef Segment;
- if (ParseIdentifier(Segment))
- return TokError("expected segment name after '.zerofill'
directive");
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- StringRef Section;
- if (ParseIdentifier(Section))
- return TokError("expected section name after comma in
'.zerofill' "
- "directive");
-
- // If this is the end of the line all that was wanted was to create the
- // the section but with no symbol.
- if (Lexer.is(AsmToken::EndOfStatement)) {
- // Create the zerofill section but no symbol
- Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()));
- return false;
- }
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- SMLoc IDLoc = Lexer.getLoc();
- StringRef IDStr;
- if (ParseIdentifier(IDStr))
- return TokError("expected identifier in directive");
-
- // handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(IDStr);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (Lexer.is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.zerofill'
directive");
-
- Lex();
-
- if (Size < 0)
- return Error(SizeLoc, "invalid '.zerofill' directive size,
can't be less "
- "than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assembler
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive
alignment, "
- "can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // Create the zerofill Symbol with Size and Pow2Alignment
- //
- // FIXME: Arch specific.
- Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
- MCSectionMachO::S_ZEROFILL, 0,
- SectionKind::getBSS()),
- Sym, Size, 1 << Pow2Alignment);
-
- return false;
-}
-
-/// ParseDirectiveDarwinTBSS
-/// ::= .tbss identifier, size, align
-bool AsmParser::ParseDirectiveDarwinTBSS() {
- SMLoc IDLoc = Lexer.getLoc();
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (Lexer.is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = Lexer.getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
- return true;
- }
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.tbss' directive");
-
- Lex();
-
- if (Size < 0)
- return Error(SizeLoc, "invalid '.tbss' directive size,
can't be less than"
- "zero");
-
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment,
can't be less"
- "than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- Out.EmitTBSSSymbol(Ctx.getMachOSection("__DATA",
"__thread_bss",
-
MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
- 0, SectionKind::getThreadBSS()),
- Sym, Size, 1 << Pow2Alignment);
-
- return false;
-}
-
-/// ParseDirectiveDarwinSubsectionsViaSymbols
-/// ::= .subsections_via_symbols
-bool AsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in
'.subsections_via_symbols' directive");
-
- Lex();
-
- Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
-
- return false;
-}
-
/// ParseDirectiveAbort
/// ::= .abort [ "abort_string" ]
bool AsmParser::ParseDirectiveAbort() {
@@ -1653,37 +1154,6 @@ bool AsmParser::ParseDirectiveAbort() {
return false;
}
-/// ParseDirectiveLsym
-/// ::= .lsym identifier , expression
-bool AsmParser::ParseDirectiveDarwinLsym() {
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = CreateSymbol(Name);
-
- if (Lexer.isNot(AsmToken::Comma))
- return TokError("unexpected token in '.lsym' directive");
- Lex();
-
- const MCExpr *Value;
- SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Value))
- return true;
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.lsym' directive");
-
- Lex();
-
- // We don't currently support this directive.
- //
- // FIXME: Diagnostic location!
- (void) Sym;
- return TokError("directive '.lsym' is unsupported");
-}
-
/// ParseDirectiveInclude
/// ::= .include "filename"
bool AsmParser::ParseDirectiveInclude() {
@@ -1712,29 +1182,6 @@ bool AsmParser::ParseDirectiveInclude() {
return false;
}
-/// ParseDirectiveDarwinDumpOrLoad
-/// ::= ( .dump | .load ) "filename"
-bool AsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
- if (Lexer.isNot(AsmToken::String))
- return TokError("expected string in '.dump' or '.load'
directive");
-
- Lex();
-
- if (Lexer.isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.dump' or
'.load' directive");
-
- Lex();
-
- // FIXME: If/when .dump and .load are implemented they will be done in the
- // the assembly parser and not have any need for an MCStreamer API.
- if (IsDump)
- Warning(IDLoc, "ignoring directive .dump for now");
- else
- Warning(IDLoc, "ignoring directive .load for now");
-
- return false;
-}
-
/// ParseDirectiveIf
/// ::= .if expression
bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
diff --git a/lib/MC/MCParser/CMakeLists.txt b/lib/MC/MCParser/CMakeLists.txt
index a5c0818..059f0fe 100644
--- a/lib/MC/MCParser/CMakeLists.txt
+++ b/lib/MC/MCParser/CMakeLists.txt
@@ -1,7 +1,7 @@
add_llvm_library(LLVMMCParser
AsmLexer.cpp
AsmParser.cpp
+ MachOAsmParser.cpp
MCAsmLexer.cpp
MCAsmParser.cpp
- TargetAsmParser.cpp
)
diff --git a/lib/MC/MCParser/MachOAsmParser.cpp
b/lib/MC/MCParser/MachOAsmParser.cpp
new file mode 100644
index 0000000..9c0802d
--- /dev/null
+++ b/lib/MC/MCParser/MachOAsmParser.cpp
@@ -0,0 +1,630 @@
+//===- MachOAsmParser.cpp - Parser for Mach-O Assembly
Files---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements the parser for Mach-O assembly files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCParser/MachOAsmParser.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+
+using namespace llvm;
+
+bool MachOAsmParser::ParseDirective(AsmToken DirectiveID) {
+ StringRef IDVal = DirectiveID.getIdentifier();
+ SMLoc IDLoc = DirectiveID.getLoc();
+
+ // FIXME: This should be driven based on a hash lookup and callback.
+ if (IDVal == ".section")
+ return ParseDirectiveDarwinSection();
+
+ if (IDVal == ".zerofill")
+ return ParseDirectiveDarwinZerofill();
+ if (IDVal == ".desc")
+ return ParseDirectiveDarwinSymbolDesc();
+ if (IDVal == ".lsym")
+ return ParseDirectiveDarwinLsym();
+ if (IDVal == ".tbss")
+ return ParseDirectiveDarwinTBSS();
+
+ if (IDVal == ".comm")
+ return ParseDirectiveComm(/*IsLocal=*/false);
+ if (IDVal == ".lcomm")
+ return ParseDirectiveComm(/*IsLocal=*/true);
+
+ if (IDVal == ".subsections_via_symbols")
+ return ParseDirectiveDarwinSubsectionsViaSymbols();
+ if (IDVal == ".dump")
+ return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsDump=*/true);
+ if (IDVal == ".load")
+ return ParseDirectiveDarwinDumpOrLoad(IDLoc, /*IsLoad=*/false);
+
+ if (!ParseDirectiveSectionSwitch(IDVal))
+ return false;
+
+ // Don't understand directive.
+ return true;
+}
+
+/// ParseDirectiveSectionSwitch -
+bool MachOAsmParser::ParseDirectiveSectionSwitch(StringRef S) {
+ const char *Segment;
+ const char *Section;
+ unsigned TAA = 0;
+ unsigned Align = 0;
+ unsigned StubSize = 0;
+
+ if (S == ".text") {
+ Segment = "__TEXT";
+ Section = "__text";
+ TAA = MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
+ } else if (S == ".const") {
+ Segment = "__TEXT";
+ Section = "__const";
+ } else if (S == ".static_const") {
+ Segment = "__TEXT";
+ Section = "__static_const";
+ } else if (S == ".cstring") {
+ Segment = "__TEXT";
+ Section = "__cstring";
+ TAA = MCSectionMachO::S_CSTRING_LITERALS;
+ } else if (S == ".literal4") {
+ Segment = "__TEXT";
+ Section = "__literal4";
+ TAA = MCSectionMachO::S_4BYTE_LITERALS;
+ Align = 4;
+ } else if (S == ".literal8") {
+ Segment = "__TEXT";
+ Section = "__literal8";
+ TAA = MCSectionMachO::S_8BYTE_LITERALS;
+ Align = 8;
+ } else if (S == ".literal16") {
+ Segment = "__TEXT";
+ Section = "__literal16";
+ TAA = MCSectionMachO::S_16BYTE_LITERALS;
+ Align = 16;
+ } else if (S == ".constructor") {
+ Segment = "__TEXT";
+ Section = "__constructor";
+ } else if (S == ".destructor") {
+ Segment = "__TEXT";
+ Section = "__destructor";
+ } else if (S == ".fvmlib_init0") {
+ Segment = "__TEXT";
+ Section = "__fvmlib_init0";
+ } else if (S == ".fvmlib_init1") {
+ Segment = "__TEXT";
+ Section = "__fvmlib_init1";
+
+ // FIXME: The assembler manual claims that this has the self modify code
+ // flag, at least on x86-32, but that does not appear to be correct.
+ } else if (S == ".symbol_stub") {
+ Segment = "__TEXT";
+ Section = "__symbol_stub";
+ TAA = MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
+ // FIXME: Different on PPC and ARM.
+ StubSize = 16;
+ // FIXME: PowerPC only?
+ } else if (S == ".picsymbol_stub") {
+ Segment = "__TEXT";
+ Section = "__picsymbol_stub";
+ TAA = MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
+ StubSize = 26;
+ } else if (S == ".data") {
+ Segment = "__DATA";
+ Section = "__data";
+ } else if (S == ".static_data") {
+ Segment = "__DATA";
+ Section = "__static_data";
+
+ // FIXME: The section names of these two are misspelled in the assembler
+ // manual.
+ } else if (S == ".non_lazy_symbol_pointer") {
+ Segment = "__DATA";
+ Section = "__nl_symbol_ptr";
+ TAA = MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS;
+ Align = 4;
+ } else if (S == ".lazy_symbol_pointer") {
+ Segment = "__DATA";
+ Section = "__la_symbol_ptr";
+ TAA = MCSectionMachO::S_LAZY_SYMBOL_POINTERS;
+ Align = 4;
+ } else if (S == ".dyld") {
+ Segment = "__DATA";
+ Section = "__dyld";
+ } else if (S == ".mod_init_func") {
+ Segment = "__DATA";
+ Section = "__mod_init_func";
+ TAA = MCSectionMachO::S_MOD_INIT_FUNC_POINTERS;
+ Align = 4;
+ } else if (S == ".mod_term_func") {
+ Segment = "__DATA";
+ Section = "__mod_term_func";
+ TAA = MCSectionMachO::S_MOD_TERM_FUNC_POINTERS;
+ Align = 4;
+ } else if (S == ".const_data") {
+ Segment = "__DATA";
+ Section = "__const";
+ } else if (S == ".objc_class") {
+ Segment = "__OBJC";
+ Section = "__class";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_meta_class") {
+ Segment = "__OBJC";
+ Section = "__meta_class";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_cat_cls_meth") {
+ Segment = "__OBJC";
+ Section = "__cat_cls_meth";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_cat_inst_meth") {
+ Segment = "__OBJC";
+ Section = "__cat_inst_meth";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_protocol") {
+ Segment = "__OBJC";
+ Section = "__protocol";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_string_object") {
+ Segment = "__OBJC";
+ Section = "__string_object";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_cls_meth") {
+ Segment = "__OBJC";
+ Section = "__cls_meth";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_inst_meth") {
+ Segment = "__OBJC";
+ Section = "__inst_meth";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_cls_refs") {
+ Segment = "__OBJC";
+ Section = "__cls_refs";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
+ MCSectionMachO::S_LITERAL_POINTERS;
+ Align = 4;
+ } else if (S == ".objc_message_refs") {
+ Segment = "__OBJC";
+ Section = "__message_refs";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
+ MCSectionMachO::S_LITERAL_POINTERS;
+ Align = 4;
+ } else if (S == ".objc_symbols") {
+ Segment = "__OBJC";
+ Section = "__symbols";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_category") {
+ Segment = "__OBJC";
+ Section = "__category";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_class_vars") {
+ Segment = "__OBJC";
+ Section = "__class_vars";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_instance_vars") {
+ Segment = "__OBJC";
+ Section = "__instance_vars";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_module_info") {
+ Segment = "__OBJC";
+ Section = "__module_info";
+ TAA = MCSectionMachO::S_ATTR_NO_DEAD_STRIP;
+ } else if (S == ".objc_class_names") {
+ Segment = "__TEXT";
+ Section = "__cstring";
+ TAA = MCSectionMachO::S_CSTRING_LITERALS;
+ } else if (S == ".objc_meth_var_types") {
+ Segment = "__TEXT";
+ Section = "__cstring";
+ TAA = MCSectionMachO::S_CSTRING_LITERALS;
+ } else if (S == ".objc_meth_var_names") {
+ Segment = "__TEXT";
+ Section = "__cstring";
+ TAA = MCSectionMachO::S_CSTRING_LITERALS;
+ } else if (S == ".objc_selector_strs") {
+ Segment = "__OBJC";
+ Section = "__selector_strs";
+ TAA = MCSectionMachO::S_CSTRING_LITERALS;
+ } else if (S == ".tdata") {
+ Segment = "__DATA";
+ Section = "__thread_data";
+ TAA = MCSectionMachO::S_THREAD_LOCAL_REGULAR;
+ } else if (S == ".tlv") {
+ Segment = "__DATA";
+ Section = "__thread_vars";
+ TAA = MCSectionMachO::S_THREAD_LOCAL_VARIABLES;
+ } else if (S == ".thread_init_func") {
+ Segment = "__DATA";
+ Section = "__thread_init";
+ TAA = MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS;
+ } else {
+ return true;
+ }
+
+ bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
+ Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
+
+ // Set the implicit alignment, if any.
+ //
+ // FIXME: This isn't really what 'as' does; I think it just uses
the implicit
+ // alignment on the section (e.g., if one manually inserts bytes into the
+ // section, then just issueing the section switch directive will not realign
+ // the section. However, this is arguably more reasonable behavior, and there
+ // is no good reason for someone to intentionally emit incorrectly sized
+ // values into the implicitly aligned sections.
+ if (Align)
+ Out.EmitValueToAlignment(Align, 0, 1, 0);
+
+ return false;
+}
+
+/// ParseDirectiveSection:
+/// ::= .section identifier (',' identifier)*
+/// FIXME: This should actually parse out the segment, section, attributes and
+/// sizeof_stub fields.
+bool MachOAsmParser::ParseDirectiveDarwinSection() {
+ SMLoc Loc = Lexer.getLoc();
+
+ StringRef SectionName;
+ if (ParseIdentifier(SectionName))
+ return Error(Loc, "expected identifier after '.section'
directive");
+
+ // Verify there is a following comma.
+ if (!Lexer.is(AsmToken::Comma))
+ return TokError("unexpected token in '.section'
directive");
+
+ std::string SectionSpec = SectionName;
+ SectionSpec += ",";
+
+ // Add all the tokens until the end of the line, ParseSectionSpecifier will
+ // handle this.
+ StringRef EOL = Lexer.LexUntilEndOfStatement();
+ SectionSpec.append(EOL.begin(), EOL.end());
+
+ Lex();
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.section'
directive");
+ Lex();
+
+
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ std::string ErrorStr + MCSectionMachO::ParseSectionSpecifier(SectionSpec,
Segment, Section,
+ TAA, StubSize);
+
+ if (!ErrorStr.empty())
+ return Error(Loc, ErrorStr.c_str());
+
+ bool isText = Segment == "__TEXT"; // FIXME: Hack.
+ Out.SwitchSection(Ctx.getMachOSection(Segment, Section, TAA, StubSize,
+ isText ? SectionKind::getText()
+ : SectionKind::getDataRel()));
+ return false;
+}
+
+/// ParseDirectiveDarwinZerofill
+/// ::= .zerofill segname , sectname [, identifier , size_expression [
+/// , align_expression ]]
+bool MachOAsmParser::ParseDirectiveDarwinZerofill() {
+ StringRef Segment;
+ if (ParseIdentifier(Segment))
+ return TokError("expected segment name after '.zerofill'
directive");
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ StringRef Section;
+ if (ParseIdentifier(Section))
+ return TokError("expected section name after comma in
'.zerofill' "
+ "directive");
+
+ // If this is the end of the line all that was wanted was to create the
+ // the section but with no symbol.
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ // Create the zerofill section but no symbol
+ Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()));
+ return false;
+ }
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ SMLoc IDLoc = Lexer.getLoc();
+ StringRef IDStr;
+ if (ParseIdentifier(IDStr))
+ return TokError("expected identifier in directive");
+
+ // handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(IDStr);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (Lexer.is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Pow2Alignment))
+ return true;
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.zerofill'
directive");
+
+ Lex();
+
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.zerofill' directive size,
can't be less "
+ "than zero");
+
+ // NOTE: The alignment in the directive is a power of 2 value, the assembler
+ // may internally end up wanting an alignment in bytes.
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive
alignment, "
+ "can't be less than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // Create the zerofill Symbol with Size and Pow2Alignment
+ Out.EmitZerofill(Ctx.getMachOSection(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()),
+ Sym, Size, 1 << Pow2Alignment);
+
+ return false;
+}
+
+/// ParseDirectiveDarwinTBSS
+/// ::= .tbss identifier, size, align
+bool MachOAsmParser::ParseDirectiveDarwinTBSS() {
+ SMLoc IDLoc = Lexer.getLoc();
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (Lexer.is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Pow2Alignment))
+ return true;
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.tbss' directive");
+
+ Lex();
+
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.tbss' directive size,
can't be less than"
+ "zero");
+
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment,
can't be less"
+ "than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ Out.EmitTBSSSymbol(Ctx.getMachOSection("__DATA",
"__thread_bss",
+
MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
+ 0, SectionKind::getThreadBSS()),
+ Sym, Size, 1 << Pow2Alignment);
+
+ return false;
+}
+
+/// ParseDirectiveDarwinSubsectionsViaSymbols
+/// ::= .subsections_via_symbols
+bool MachOAsmParser::ParseDirectiveDarwinSubsectionsViaSymbols() {
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in
'.subsections_via_symbols' directive");
+
+ Lex();
+
+ Out.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
+
+ return false;
+}
+
+/// ParseDirectiveComm
+/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
+bool MachOAsmParser::ParseDirectiveComm(bool IsLocal) {
+ SMLoc IDLoc = Lexer.getLoc();
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (Lexer.is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = Lexer.getLoc();
+ if (ParseAbsoluteExpression(Pow2Alignment))
+ return true;
+
+ // If this target takes alignments in bytes (not log) validate and convert.
+ if (Lexer.getMAI().getAlignmentIsInBytes()) {
+ if (!isPowerOf2_64(Pow2Alignment))
+ return Error(Pow2AlignmentLoc, "alignment must be a power of
2");
+ Pow2Alignment = Log2_64(Pow2Alignment);
+ }
+ }
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.comm' or
'.lcomm' directive");
+
+ Lex();
+
+ // NOTE: a size of zero for a .comm should create a undefined symbol
+ // but a size of .lcomm creates a bss symbol of size zero.
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.comm' or '.lcomm'
directive size, can't "
+ "be less than zero");
+
+ // NOTE: The alignment in the directive is a power of 2 value, the assembler
+ // may internally end up wanting an alignment in bytes.
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.comm' or
'.lcomm' directive "
+ "alignment, can't be less than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // '.lcomm' is equivalent to '.zerofill'.
+ // Create the Symbol as a common or local common with Size and Pow2Alignment
+ if (IsLocal) {
+ Out.EmitZerofill(Ctx.getMachOSection("__DATA", "__bss",
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind::getBSS()),
+ Sym, Size, 1 << Pow2Alignment);
+ return false;
+ }
+
+ Out.EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
+ return false;
+}
+
+/// ParseDirectiveDarwinDumpOrLoad
+/// ::= ( .dump | .load ) "filename"
+bool MachOAsmParser::ParseDirectiveDarwinDumpOrLoad(SMLoc IDLoc, bool IsDump) {
+ if (Lexer.isNot(AsmToken::String))
+ return TokError("expected string in '.dump' or '.load'
directive");
+
+ Lex();
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.dump' or
'.load' directive");
+
+ Lex();
+
+ // FIXME: If/when .dump and .load are implemented they will be done in the
+ // the assembly parser and not have any need for an MCStreamer API.
+ if (IsDump)
+ Warning(IDLoc, "ignoring directive .dump for now");
+ else
+ Warning(IDLoc, "ignoring directive .load for now");
+
+ return false;
+}
+
+/// ParseDirectiveLsym
+/// ::= .lsym identifier , expression
+
+bool MachOAsmParser::ParseDirectiveDarwinLsym() {
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.lsym' directive");
+ Lex();
+
+ const MCExpr *Value;
+ SMLoc StartLoc = Lexer.getLoc();
+ if (ParseExpression(Value))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.lsym' directive");
+
+ Lex();
+
+ // We don't currently support this directive.
+ //
+ // FIXME: Diagnostic location!
+ (void) Sym;
+ return TokError("directive '.lsym' is unsupported");
+}
+
+/// ParseDirectiveDarwinSymbolDesc
+/// ::= .desc identifier , expression
+bool MachOAsmParser::ParseDirectiveDarwinSymbolDesc() {
+ StringRef Name;
+ if (ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = CreateSymbol(Name);
+
+ if (Lexer.isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.desc' directive");
+ Lex();
+
+ SMLoc DescLoc = Lexer.getLoc();
+ int64_t DescValue;
+ if (ParseAbsoluteExpression(DescValue))
+ return true;
+
+ if (Lexer.isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.desc' directive");
+
+ Lex();
+
+ // Set the n_desc field of this Symbol to this DescValue
+ Out.EmitSymbolDesc(Sym, DescValue);
+
+ return false;
+}
+
+const MCSection *MachOAsmParser::getInitialTextSection() {
+ return getContext().getMachOSection("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 0, SectionKind::getText());
+}
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index bfa89c4..cfcd032 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "ARM.h"
+#include "llvm/MC/MCParser/MachOAsmParser.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
@@ -15,7 +16,6 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/ADT/OwningPtr.h"
@@ -35,18 +35,9 @@ enum ShiftType {
Rrx
};
-class ARMAsmParser : public TargetAsmParser {
- MCAsmParser &Parser;
+class ARMAsmParser : public MachOAsmParser {
private:
- MCAsmParser &getParser() const { return Parser; }
-
- MCAsmLexer &getLexer() const { return Parser.getLexer(); }
-
- void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
-
- bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
-
bool MaybeParseRegister(OwningPtr<ARMOperand> &Op, bool
ParseWriteBack);
bool ParseRegisterList(OwningPtr<ARMOperand> &Op);
@@ -81,8 +72,8 @@ private:
/// @name Auto-generated Match Functions
/// {
- bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
- MCInst &Inst);
+ virtual bool MatchInstruction(const
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCInst &Inst);
/// MatchRegisterName - Match the given string to a register name and return
/// its register number, or -1 if there is no match. To allow return values
@@ -94,13 +85,14 @@ private:
public:
- ARMAsmParser(const Target &T, MCAsmParser &_Parser)
- : TargetAsmParser(T), Parser(_Parser) {}
+ ARMAsmParser(const Target &T, SourceMgr &SM, MCContext &Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : MachOAsmParser(SM, Ctx, Out, MAI) {}
virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*>
&Operands);
- virtual bool ParseDirective(AsmToken DirectiveID);
+ bool ParseTargetDirective(AsmToken DirectiveID);
};
/// ARMOperand - Instances of this class represent a parsed ARM machine
@@ -270,7 +262,7 @@ public:
bool ARMAsmParser::MaybeParseRegister
(OwningPtr<ARMOperand> &Op, bool ParseWriteBack) {
SMLoc S, E;
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an
Identifier");
// FIXME: Validate register for the current architecture; we have to do
@@ -283,17 +275,17 @@ bool ARMAsmParser::MaybeParseRegister
S = Tok.getLoc();
- Parser.Lex(); // Eat identifier token.
+ Lex(); // Eat identifier token.
- E = Parser.getTok().getLoc();
+ E = getTok().getLoc();
bool Writeback = false;
if (ParseWriteBack) {
- const AsmToken &ExclaimTok = Parser.getTok();
+ const AsmToken &ExclaimTok = getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
E = ExclaimTok.getLoc();
Writeback = true;
- Parser.Lex(); // Eat exclaim token
+ Lex(); // Eat exclaim token
}
}
@@ -306,27 +298,27 @@ bool ARMAsmParser::MaybeParseRegister
/// error. The first token must be a '{' when called.
bool ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) {
SMLoc S, E;
- assert(Parser.getTok().is(AsmToken::LCurly) &&
+ assert(getTok().is(AsmToken::LCurly) &&
"Token is not an Left Curly Brace");
- S = Parser.getTok().getLoc();
- Parser.Lex(); // Eat left curly brace token.
+ S = getTok().getLoc();
+ Lex(); // Eat left curly brace token.
- const AsmToken &RegTok = Parser.getTok();
+ const AsmToken &RegTok = getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
int RegNum = MatchRegisterName(RegTok.getString());
if (RegNum == -1)
return Error(RegLoc, "register expected");
- Parser.Lex(); // Eat identifier token.
+ Lex(); // Eat identifier token.
unsigned RegList = 1 << RegNum;
int HighRegNum = RegNum;
// TODO ranges like "{Rn-Rm}"
- while (Parser.getTok().is(AsmToken::Comma)) {
- Parser.Lex(); // Eat comma token.
+ while (getTok().is(AsmToken::Comma)) {
+ Lex(); // Eat comma token.
- const AsmToken &RegTok = Parser.getTok();
+ const AsmToken &RegTok = getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
@@ -341,13 +333,13 @@ bool
ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) {
RegList |= 1 << RegNum;
HighRegNum = RegNum;
- Parser.Lex(); // Eat identifier token.
+ Lex(); // Eat identifier token.
}
- const AsmToken &RCurlyTok = Parser.getTok();
+ const AsmToken &RCurlyTok = getTok();
if (RCurlyTok.isNot(AsmToken::RCurly))
return Error(RCurlyTok.getLoc(), "'}' expected");
E = RCurlyTok.getLoc();
- Parser.Lex(); // Eat left curly brace token.
+ Lex(); // Eat left curly brace token.
return false;
}
@@ -358,12 +350,12 @@ bool
ARMAsmParser::ParseRegisterList(OwningPtr<ARMOperand> &Op) {
/// with option, etc are still to do.
bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand> &Op) {
SMLoc S, E;
- assert(Parser.getTok().is(AsmToken::LBrac) &&
+ assert(getTok().is(AsmToken::LBrac) &&
"Token is not an Left Bracket");
- S = Parser.getTok().getLoc();
- Parser.Lex(); // Eat left bracket token.
+ S = getTok().getLoc();
+ Lex(); // Eat left bracket token.
- const AsmToken &BaseRegTok = Parser.getTok();
+ const AsmToken &BaseRegTok = getTok();
if (BaseRegTok.isNot(AsmToken::Identifier))
return Error(BaseRegTok.getLoc(), "register expected");
if (MaybeParseRegister(Op, false))
@@ -378,10 +370,10 @@ bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand>
&Op) {
// First look for preindexed address forms, that is after the "[Rn"
we now
// have to see if the next token is a comma.
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.is(AsmToken::Comma)) {
Preindexed = true;
- Parser.Lex(); // Eat comma token.
+ Lex(); // Eat comma token.
int OffsetRegNum;
bool OffsetRegShifted;
enum ShiftType ShiftType;
@@ -390,17 +382,17 @@ bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand>
&Op) {
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum, E))
return true;
- const AsmToken &RBracTok = Parser.getTok();
+ const AsmToken &RBracTok = getTok();
if (RBracTok.isNot(AsmToken::RBrac))
return Error(RBracTok.getLoc(), "']' expected");
E = RBracTok.getLoc();
- Parser.Lex(); // Eat right bracket token.
+ Lex(); // Eat right bracket token.
- const AsmToken &ExclaimTok = Parser.getTok();
+ const AsmToken &ExclaimTok = getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
E = ExclaimTok.getLoc();
Writeback = true;
- Parser.Lex(); // Eat exclaim token
+ Lex(); // Eat exclaim token
}
ARMOperand::CreateMem(Op, BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
@@ -414,7 +406,7 @@ bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand>
&Op) {
Postindexed = true;
Writeback = true;
E = Tok.getLoc();
- Parser.Lex(); // Eat right bracket token.
+ Lex(); // Eat right bracket token.
int OffsetRegNum = 0;
bool OffsetRegShifted = false;
@@ -422,11 +414,11 @@ bool ARMAsmParser::ParseMemory(OwningPtr<ARMOperand>
&Op) {
const MCExpr *ShiftAmount;
const MCExpr *Offset;
- const AsmToken &NextTok = Parser.getTok();
+ const AsmToken &NextTok = getTok();
if (NextTok.isNot(AsmToken::EndOfStatement)) {
if (NextTok.isNot(AsmToken::Comma))
return Error(NextTok.getLoc(), "',' expected");
- Parser.Lex(); // Eat comma token.
+ Lex(); // Eat comma token.
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
E))
@@ -462,16 +454,16 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool
&Negative,
OffsetRegShifted = false;
OffsetIsReg = false;
OffsetRegNum = -1;
- const AsmToken &NextTok = Parser.getTok();
+ const AsmToken &NextTok = getTok();
E = NextTok.getLoc();
if (NextTok.is(AsmToken::Plus))
- Parser.Lex(); // Eat plus token.
+ Lex(); // Eat plus token.
else if (NextTok.is(AsmToken::Minus)) {
Negative = true;
- Parser.Lex(); // Eat minus token
+ Lex(); // Eat minus token
}
// See if there is a register following the "[Rn," or
"[Rn]," we have so far.
- const AsmToken &OffsetRegTok = Parser.getTok();
+ const AsmToken &OffsetRegTok = getTok();
if (OffsetRegTok.is(AsmToken::Identifier)) {
OffsetIsReg = !MaybeParseRegister(Op, false);
if (OffsetIsReg) {
@@ -482,11 +474,11 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool
&Negative,
// If we parsed a register as the offset then their can be a shift after that
if (OffsetRegNum != -1) {
// Look for a comma then a shift
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.is(AsmToken::Comma)) {
- Parser.Lex(); // Eat comma token.
+ Lex(); // Eat comma token.
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (ParseShift(ShiftType, ShiftAmount, E))
return Error(Tok.getLoc(), "shift expected");
OffsetRegShifted = true;
@@ -494,15 +486,15 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool
&Negative,
}
else { // the "[Rn," or "[Rn,]" we have so far was not
followed by "Rm"
// Look for #offset following the "[Rn," or "[Rn],"
- const AsmToken &HashTok = Parser.getTok();
+ const AsmToken &HashTok = getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- Parser.Lex(); // Eat hash token.
+ Lex(); // Eat hash token.
- if (getParser().ParseExpression(Offset))
+ if (ParseExpression(Offset))
return true;
- E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ E = SMLoc::getFromPointer(getTok().getLoc().getPointer() - 1);
}
return false;
}
@@ -514,7 +506,7 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
bool ARMAsmParser::ParseShift(ShiftType &St,
const MCExpr *&ShiftAmount,
SMLoc &E) {
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.isNot(AsmToken::Identifier))
return true;
const StringRef &ShiftName = Tok.getString();
@@ -530,19 +522,19 @@ bool ARMAsmParser::ParseShift(ShiftType &St,
St = Rrx;
else
return true;
- Parser.Lex(); // Eat shift type token.
+ Lex(); // Eat shift type token.
// Rrx stands alone.
if (St == Rrx)
return false;
// Otherwise, there must be a '#' and a shift amount.
- const AsmToken &HashTok = Parser.getTok();
+ const AsmToken &HashTok = getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- Parser.Lex(); // Eat hash token.
+ Lex(); // Eat hash token.
- if (getParser().ParseExpression(ShiftAmount))
+ if (ParseExpression(ShiftAmount))
return true;
return false;
@@ -631,10 +623,10 @@ bool
ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) {
// This was not a register so parse other operands that start with an
// identifier (like labels) as expressions and create them as immediates.
const MCExpr *IdVal;
- S = Parser.getTok().getLoc();
- if (getParser().ParseExpression(IdVal))
+ S = getTok().getLoc();
+ if (ParseExpression(IdVal))
return true;
- E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ E = SMLoc::getFromPointer(getTok().getLoc().getPointer() - 1);
ARMOperand::CreateImm(Op, IdVal, S, E);
return false;
case AsmToken::LBrac:
@@ -644,16 +636,16 @@ bool
ARMAsmParser::ParseOperand(OwningPtr<ARMOperand> &Op) {
case AsmToken::Hash:
// #42 -> immediate.
// TODO: ":lower16:" and ":upper16:" modifiers after #
before immediate
- S = Parser.getTok().getLoc();
- Parser.Lex();
+ S = getTok().getLoc();
+ Lex();
const MCExpr *ImmVal;
- if (getParser().ParseExpression(ImmVal))
+ if (ParseExpression(ImmVal))
return true;
- E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ E = SMLoc::getFromPointer(getTok().getLoc().getPointer() - 1);
ARMOperand::CreateImm(Op, ImmVal, S, E);
return false;
default:
- return Error(Parser.getTok().getLoc(), "unexpected token in
operand");
+ return Error(getTok().getLoc(), "unexpected token in operand");
}
}
@@ -665,7 +657,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef
&Name, SMLoc NameLoc,
Operands.push_back(Op.take());
- SMLoc Loc = Parser.getTok().getLoc();
+ SMLoc Loc = getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
@@ -674,7 +666,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef
&Name, SMLoc NameLoc,
Operands.push_back(Op.take());
while (getLexer().is(AsmToken::Comma)) {
- Parser.Lex(); // Eat the comma.
+ Lex(); // Eat the comma.
// Parse and remember the operand.
if (ParseOperand(Op)) return true;
@@ -684,8 +676,8 @@ bool ARMAsmParser::ParseInstruction(const StringRef
&Name, SMLoc NameLoc,
return false;
}
-/// ParseDirective parses the arm specific directives
-bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
+/// ParseTargetDirective parses the arm specific directives
+bool ARMAsmParser::ParseTargetDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getIdentifier();
if (IDVal == ".word")
return ParseDirectiveWord(4, DirectiveID.getLoc());
@@ -706,10 +698,10 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc
L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
+ getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -717,11 +709,11 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc
L) {
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
- Parser.Lex();
+ Lex();
}
}
- Parser.Lex();
+ Lex();
return false;
}
@@ -730,85 +722,85 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc
L) {
bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- Parser.Lex();
+ Lex();
// TODO: set thumb mode
// TODO: tell the MC streamer the mode
- // getParser().getStreamer().Emit???();
+ // getStreamer().Emit???();
return false;
}
/// ParseDirectiveThumbFunc
/// ::= .thumbfunc symbol_name
bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
return Error(L, "unexpected token in .syntax directive");
- StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier();
- Parser.Lex(); // Consume the identifier token.
+ StringRef ATTRIBUTE_UNUSED SymbolName = getTok().getIdentifier();
+ Lex(); // Consume the identifier token.
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- Parser.Lex();
+ Lex();
// TODO: mark symbol as a thumb symbol
- // getParser().getStreamer().Emit???();
+ // getStreamer().Emit???();
return false;
}
/// ParseDirectiveSyntax
/// ::= .syntax unified | divided
bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.isNot(AsmToken::Identifier))
return Error(L, "unexpected token in .syntax directive");
const StringRef &Mode = Tok.getString();
bool unified_syntax;
if (Mode == "unified" || Mode == "UNIFIED") {
- Parser.Lex();
+ Lex();
unified_syntax = true;
}
else if (Mode == "divided" || Mode == "DIVIDED") {
- Parser.Lex();
+ Lex();
unified_syntax = false;
}
else
return Error(L, "unrecognized syntax mode in .syntax directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(Parser.getTok().getLoc(), "unexpected token in
directive");
- Parser.Lex();
+ return Error(getTok().getLoc(), "unexpected token in directive");
+ Lex();
// TODO tell the MC streamer the mode
- // getParser().getStreamer().Emit???();
+ // getStreamer().Emit???();
return false;
}
/// ParseDirectiveCode
/// ::= .code 16 | 32
bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = getTok();
if (Tok.isNot(AsmToken::Integer))
return Error(L, "unexpected token in .code directive");
- int64_t Val = Parser.getTok().getIntVal();
+ int64_t Val = getTok().getIntVal();
bool thumb_mode;
if (Val == 16) {
- Parser.Lex();
+ Lex();
thumb_mode = true;
}
else if (Val == 32) {
- Parser.Lex();
+ Lex();
thumb_mode = false;
}
else
return Error(L, "invalid operand to .code directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(Parser.getTok().getLoc(), "unexpected token in
directive");
- Parser.Lex();
+ return Error(getTok().getLoc(), "unexpected token in directive");
+ Lex();
// TODO tell the MC streamer the mode
- // getParser().getStreamer().Emit???();
+ // getStreamer().Emit???();
return false;
}
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp
b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 7037796..59eacdf 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -15,31 +15,24 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCParser/MachOAsmParser.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetAsmParser.h"
using namespace llvm;
namespace {
struct X86Operand;
-class X86ATTAsmParser : public TargetAsmParser {
- MCAsmParser &Parser;
+class X86ATTAsmParser {
protected:
unsigned Is64Bit : 1;
private:
- MCAsmParser &getParser() const { return Parser; }
-
- MCAsmLexer &getLexer() const { return Parser.getLexer(); }
-
- void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
-
- bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
+ AsmParser *Parser;
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc
&EndLoc);
@@ -53,37 +46,106 @@ private:
/// @name Auto-generated Match Functions
/// {
- bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
- MCInst &Inst);
-
bool MatchInstructionImpl(
const SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCInst
&Inst);
/// }
public:
- X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
- : TargetAsmParser(T), Parser(_Parser) {}
+ X86ATTAsmParser(const Target &T, bool _Is64Bit, AsmParser *_Parser) {
+ Is64Bit = _Is64Bit;
+ Parser = _Parser;
+ }
- virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
- SmallVectorImpl<MCParsedAsmOperand*>
&Operands);
+ bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*>
&Operands);
+ bool ParseDirective(AsmToken DirectiveID);
- virtual bool ParseDirective(AsmToken DirectiveID);
+ bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
+ MCInst &Inst);
};
-
-class X86_32ATTAsmParser : public X86ATTAsmParser {
+
+class X86_ATTMachOAsmParser : public MachOAsmParser {
+protected:
+ X86ATTAsmParser *X86Parser;
+
public:
- X86_32ATTAsmParser(const Target &T, MCAsmParser &_Parser)
- : X86ATTAsmParser(T, _Parser) {
- Is64Bit = false;
+ X86_ATTMachOAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : MachOAsmParser(SM, Ctx, Out, MAI) {}
+
+ bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*>
&Operands) {
+ return X86Parser->ParseInstruction(Name, NameLoc, Operands);
}
+
+ bool ParseTargetDirective(AsmToken DirectiveID) {
+ return X86Parser->ParseDirective(DirectiveID);
+ };
+
+ bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
+ MCInst &Inst) {
+ return X86Parser->MatchInstruction(Operands, Inst);
+ };
};
-class X86_64ATTAsmParser : public X86ATTAsmParser {
+class X86_32ATTMachOAsmParser : public X86_ATTMachOAsmParser {
public:
- X86_64ATTAsmParser(const Target &T, MCAsmParser &_Parser)
- : X86ATTAsmParser(T, _Parser) {
- Is64Bit = true;
+ X86_32ATTMachOAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : X86_ATTMachOAsmParser(T, SM, Ctx, Out, MAI) {
+ X86Parser = new X86ATTAsmParser(T, /*Is64Bit=*/false, this);
+ }
+};
+
+class X86_64ATTMachOAsmParser : public X86_ATTMachOAsmParser {
+public:
+ X86_64ATTMachOAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : X86_ATTMachOAsmParser(T, SM, Ctx, Out, MAI) {
+ X86Parser = new X86ATTAsmParser(T, /*Is64Bit=*/true, this);
+ }
+};
+
+class X86_ATTELFAsmParser : public ELFAsmParser {
+protected:
+ X86ATTAsmParser *X86Parser;
+
+public:
+ X86_ATTELFAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : ELFAsmParser(SM, Ctx, Out, MAI) {}
+
+ bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*>
&Operands) {
+ return X86Parser->ParseInstruction(Name, NameLoc, Operands);
+ }
+
+ bool ParseTargetDirective(AsmToken DirectiveID) {
+ return X86Parser->ParseDirective(DirectiveID);
+ };
+
+ bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*>
&Operands,
+ MCInst &Inst) {
+ return X86Parser->MatchInstruction(Operands, Inst);
+ };
+};
+
+class X86_32ATTELFAsmParser : public X86_ATTELFAsmParser {
+public:
+ X86_32ATTELFAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : X86_ATTELFAsmParser(T, SM, Ctx, Out, MAI) {
+ X86Parser = new X86ATTAsmParser(T, /*Is64Bit=*/false, this);
+ }
+};
+
+class X86_64ATTELFAsmParser : public X86_ATTELFAsmParser {
+public:
+ X86_64ATTELFAsmParser(const Target &T, SourceMgr &SM, MCContext
&Ctx,
+ MCStreamer &Out, const MCAsmInfo &MAI)
+ : X86_ATTELFAsmParser(T, SM, Ctx, Out, MAI) {
+ X86Parser = new X86ATTAsmParser(T, /*Is64Bit=*/true, this);
}
};
@@ -364,14 +426,14 @@ struct X86Operand : public MCParsedAsmOperand {
bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
SMLoc &StartLoc, SMLoc &EndLoc) {
RegNo = 0;
- const AsmToken &TokPercent = Parser.getTok();
+ const AsmToken &TokPercent = Parser->getTok();
assert(TokPercent.is(AsmToken::Percent) && "Invalid token
kind!");
StartLoc = TokPercent.getLoc();
- Parser.Lex(); // Eat percent token.
+ Parser->Lex(); // Eat percent token.
- const AsmToken &Tok = Parser.getTok();
+ const AsmToken &Tok = Parser->getTok();
if (Tok.isNot(AsmToken::Identifier))
- return Error(Tok.getLoc(), "invalid register name");
+ return Parser->Error(Tok.getLoc(), "invalid register name");
// FIXME: Validate register for the current architecture; we have to do
// validation later, so maybe there is no need for this here.
@@ -381,17 +443,17 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
if (RegNo == 0 && Tok.getString() == "st") {
RegNo = X86::ST0;
EndLoc = Tok.getLoc();
- Parser.Lex(); // Eat 'st'
+ Parser->Lex(); // Eat 'st'
// Check to see if we have '(4)' after %st.
- if (getLexer().isNot(AsmToken::LParen))
+ if (Parser->getLexer().isNot(AsmToken::LParen))
return false;
// Lex the paren.
- getParser().Lex();
+ Parser->Lex();
- const AsmToken &IntTok = Parser.getTok();
+ const AsmToken &IntTok = Parser->getTok();
if (IntTok.isNot(AsmToken::Integer))
- return Error(IntTok.getLoc(), "expected stack index");
+ return Parser->Error(IntTok.getLoc(), "expected stack
index");
switch (IntTok.getIntVal()) {
case 0: RegNo = X86::ST0; break;
case 1: RegNo = X86::ST1; break;
@@ -401,30 +463,30 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
case 5: RegNo = X86::ST5; break;
case 6: RegNo = X86::ST6; break;
case 7: RegNo = X86::ST7; break;
- default: return Error(IntTok.getLoc(), "invalid stack index");
+ default: return Parser->Error(IntTok.getLoc(), "invalid stack
index");
}
- if (getParser().Lex().isNot(AsmToken::RParen))
- return Error(Parser.getTok().getLoc(), "expected ')'");
+ if (Parser->Lex().isNot(AsmToken::RParen))
+ return Parser->Error(Parser->getTok().getLoc(), "expected
')'");
EndLoc = Tok.getLoc();
- Parser.Lex(); // Eat ')'
+ Parser->Lex(); // Eat ')'
return false;
}
if (RegNo == 0)
- return Error(Tok.getLoc(), "invalid register name");
+ return Parser->Error(Tok.getLoc(), "invalid register name");
EndLoc = Tok.getLoc();
- Parser.Lex(); // Eat identifier token.
+ Parser->Lex(); // Eat identifier token.
return false;
}
X86Operand *X86ATTAsmParser::ParseOperand() {
- switch (getLexer().getKind()) {
+ switch (Parser->getLexer().getKind()) {
default:
// Parse a memory operand with no segment register.
- return ParseMemOperand(0, Parser.getTok().getLoc());
+ return ParseMemOperand(0, Parser->getTok().getLoc());
case AsmToken::Percent: {
// Read the register.
unsigned RegNo;
@@ -433,19 +495,19 @@ X86Operand *X86ATTAsmParser::ParseOperand() {
// If this is a segment register followed by a ':', then this is
the start
// of a memory reference, otherwise this is a normal register reference.
- if (getLexer().isNot(AsmToken::Colon))
+ if (Parser->getLexer().isNot(AsmToken::Colon))
return X86Operand::CreateReg(RegNo, Start, End);
- getParser().Lex(); // Eat the colon.
+ Parser->Lex(); // Eat the colon.
return ParseMemOperand(RegNo, Start);
}
case AsmToken::Dollar: {
// $42 -> immediate.
- SMLoc Start = Parser.getTok().getLoc(), End;
- Parser.Lex();
+ SMLoc Start = Parser->getTok().getLoc(), End;
+ Parser->Lex();
const MCExpr *Val;
- if (getParser().ParseExpression(Val, End))
+ if (Parser->ParseExpression(Val, End))
return 0;
return X86Operand::CreateImm(Val, Start, End);
}
@@ -460,14 +522,14 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned
SegReg, SMLoc MemStart) {
// of a memory operand with a missing displacement "(%ebx)" or
"(,%eax)". The
// only way to do this without lookahead is to eat the '(' and see
what is
// after it.
- const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
- if (getLexer().isNot(AsmToken::LParen)) {
+ const MCExpr *Disp = MCConstantExpr::Create(0, Parser->getContext());
+ if (Parser->getLexer().isNot(AsmToken::LParen)) {
SMLoc ExprEnd;
- if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
+ if (Parser->ParseExpression(Disp, ExprEnd)) return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
- if (getLexer().isNot(AsmToken::LParen)) {
+ if (Parser->getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
if (SegReg == 0)
return X86Operand::CreateMem(Disp, MemStart, ExprEnd);
@@ -475,26 +537,26 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned
SegReg, SMLoc MemStart) {
}
// Eat the '('.
- Parser.Lex();
+ Parser->Lex();
} else {
// Okay, we have a '('. We don't know if this is an expression
or not, but
// so we have to eat the ( to see beyond it.
- SMLoc LParenLoc = Parser.getTok().getLoc();
- Parser.Lex(); // Eat the '('.
+ SMLoc LParenLoc = Parser->getTok().getLoc();
+ Parser->Lex(); // Eat the '('.
- if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
+ if (Parser->getLexer().is(AsmToken::Percent) ||
Parser->getLexer().is(AsmToken::Comma)) {
// Nothing to do here, fall into the code below with the '(' part
of the
// memory operand consumed.
} else {
SMLoc ExprEnd;
// It must be an parenthesized expression, parse it now.
- if (getParser().ParseParenExpression(Disp, ExprEnd))
+ if (Parser->ParseParenExpression(Disp, ExprEnd))
return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
- if (getLexer().isNot(AsmToken::LParen)) {
+ if (Parser->getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
if (SegReg == 0)
return X86Operand::CreateMem(Disp, LParenLoc, ExprEnd);
@@ -502,7 +564,7 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned
SegReg, SMLoc MemStart) {
}
// Eat the '('.
- Parser.Lex();
+ Parser->Lex();
}
}
@@ -510,13 +572,13 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned
SegReg, SMLoc MemStart) {
// the rest of the memory operand.
unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
- if (getLexer().is(AsmToken::Percent)) {
+ if (Parser->getLexer().is(AsmToken::Percent)) {
SMLoc L;
if (ParseRegister(BaseReg, L, L)) return 0;
}
- if (getLexer().is(AsmToken::Comma)) {
- Parser.Lex(); // Eat the comma.
+ if (Parser->getLexer().is(AsmToken::Comma)) {
+ Parser->Lex(); // Eat the comma.
// Following the comma we should have either an index register, or a scale
// value. We don't support the later form, but we want to parse it
@@ -524,56 +586,56 @@ X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned
SegReg, SMLoc MemStart) {
//
// Not that even though it would be completely consistent to support syntax
// like "1(%eax,,1)", the assembler doesn't.
- if (getLexer().is(AsmToken::Percent)) {
+ if (Parser->getLexer().is(AsmToken::Percent)) {
SMLoc L;
if (ParseRegister(IndexReg, L, L)) return 0;
- if (getLexer().isNot(AsmToken::RParen)) {
+ if (Parser->getLexer().isNot(AsmToken::RParen)) {
// Parse the scale amount:
// ::= ',' [scale-expression]
- if (getLexer().isNot(AsmToken::Comma)) {
- Error(Parser.getTok().getLoc(),
+ if (Parser->getLexer().isNot(AsmToken::Comma)) {
+ Parser->Error(Parser->getTok().getLoc(),
"expected comma in scale expression");
return 0;
}
- Parser.Lex(); // Eat the comma.
+ Parser->Lex(); // Eat the comma.
- if (getLexer().isNot(AsmToken::RParen)) {
- SMLoc Loc = Parser.getTok().getLoc();
+ if (Parser->getLexer().isNot(AsmToken::RParen)) {
+ SMLoc Loc = Parser->getTok().getLoc();
int64_t ScaleVal;
- if (getParser().ParseAbsoluteExpression(ScaleVal))
+ if (Parser->ParseAbsoluteExpression(ScaleVal))
return 0;
// Validate the scale amount.
if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4
&& ScaleVal != 8){
- Error(Loc, "scale factor in address must be 1, 2, 4 or
8");
+ Parser->Error(Loc, "scale factor in address must be 1, 2, 4
or 8");
return 0;
}
Scale = (unsigned)ScaleVal;
}
}
- } else if (getLexer().isNot(AsmToken::RParen)) {
+ } else if (Parser->getLexer().isNot(AsmToken::RParen)) {
// Otherwise we have the unsupported form of a scale amount without an
// index.
- SMLoc Loc = Parser.getTok().getLoc();
+ SMLoc Loc = Parser->getTok().getLoc();
int64_t Value;
- if (getParser().ParseAbsoluteExpression(Value))
+ if (Parser->ParseAbsoluteExpression(Value))
return 0;
- Error(Loc, "cannot have scale factor without index register");
+ Parser->Error(Loc, "cannot have scale factor without index
register");
return 0;
}
}
// Ok, we've eaten the memory operand, verify we have a ')' and
eat it too.
- if (getLexer().isNot(AsmToken::RParen)) {
- Error(Parser.getTok().getLoc(), "unexpected token in memory
operand");
+ if (Parser->getLexer().isNot(AsmToken::RParen)) {
+ Parser->Error(Parser->getTok().getLoc(), "unexpected token in
memory operand");
return 0;
}
- SMLoc MemEnd = Parser.getTok().getLoc();
- Parser.Lex(); // Eat the ')'.
+ SMLoc MemEnd = Parser->getTok().getLoc();
+ Parser->Lex(); // Eat the ')'.
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
MemStart, MemEnd);
@@ -587,24 +649,24 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
// For now, just do a manual check to prevent silent misencoding.
if (Is64Bit) {
if (Name == "popfl")
- return Error(NameLoc, "popfl cannot be encoded in 64-bit
mode");
+ return Parser->Error(NameLoc, "popfl cannot be encoded in 64-bit
mode");
else if (Name == "pushfl")
- return Error(NameLoc, "pushfl cannot be encoded in 64-bit
mode");
+ return Parser->Error(NameLoc, "pushfl cannot be encoded in 64-bit
mode");
} else {
if (Name == "popfq")
- return Error(NameLoc, "popfq cannot be encoded in 32-bit
mode");
+ return Parser->Error(NameLoc, "popfq cannot be encoded in 32-bit
mode");
else if (Name == "pushfq")
- return Error(NameLoc, "pushfq cannot be encoded in 32-bit
mode");
+ return Parser->Error(NameLoc, "pushfq cannot be encoded in 32-bit
mode");
}
// The "Jump if rCX Zero" form jcxz is not allowed in 64-bit mode
and
// the form jrcxz is not allowed in 32-bit mode.
if (Is64Bit) {
if (Name == "jcxz")
- return Error(NameLoc, "jcxz cannot be encoded in 64-bit mode");
+ return Parser->Error(NameLoc, "jcxz cannot be encoded in 64-bit
mode");
} else {
if (Name == "jrcxz")
- return Error(NameLoc, "jrcxz cannot be encoded in 32-bit
mode");
+ return Parser->Error(NameLoc, "jrcxz cannot be encoded in 32-bit
mode");
}
// FIXME: Hack to recognize "sal..." and "rep..." for
now. We need a way to
@@ -679,8 +741,7 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
.Case("ord", 7)
.Default(~0U);
if (SSEComparisonCode != ~0U) {
- ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
- getParser().getContext());
+ ExtraImmOp = MCConstantExpr::Create(SSEComparisonCode,
Parser->getContext());
if (PatchedName.endswith("ss")) {
PatchedName = "cmpss";
} else if (PatchedName.endswith("sd")) {
@@ -698,13 +759,13 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
if (ExtraImmOp)
Operands.push_back(X86Operand::CreateImm(ExtraImmOp, NameLoc, NameLoc));
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (Parser->getLexer().isNot(AsmToken::EndOfStatement)) {
// Parse '*' modifier.
- if (getLexer().is(AsmToken::Star)) {
- SMLoc Loc = Parser.getTok().getLoc();
+ if (Parser->getLexer().is(AsmToken::Star)) {
+ SMLoc Loc = Parser->getTok().getLoc();
Operands.push_back(X86Operand::CreateToken("*", Loc));
- Parser.Lex(); // Eat the star.
+ Parser->Lex(); // Eat the star.
}
// Read the first operand.
@@ -713,8 +774,8 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
else
return true;
- while (getLexer().is(AsmToken::Comma)) {
- Parser.Lex(); // Eat the comma.
+ while (Parser->getLexer().is(AsmToken::Comma)) {
+ Parser->Lex(); // Eat the comma.
// Parse and remember the operand.
if (X86Operand *Op = ParseOperand())
@@ -759,25 +820,25 @@ bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID)
{
/// ParseDirectiveWord
/// ::= .word [ expression (, expression)* ]
bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (Parser->getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (Parser->ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
+ Parser->getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
- if (getLexer().is(AsmToken::EndOfStatement))
+ if (Parser->getLexer().is(AsmToken::EndOfStatement))
break;
// FIXME: Improve diagnostic.
- if (getLexer().isNot(AsmToken::Comma))
- return Error(L, "unexpected token in directive");
- Parser.Lex();
+ if (Parser->getLexer().isNot(AsmToken::Comma))
+ return Parser->Error(L, "unexpected token in directive");
+ Parser->Lex();
}
}
- Parser.Lex();
+ Parser->Lex();
return false;
}
@@ -881,13 +942,37 @@ X86ATTAsmParser::MatchInstruction(const
SmallVectorImpl<MCParsedAsmOperand*>
return true;
}
+static AsmParser *createX86_32AsmParser(const Target &T, const std::string
&TT,
+ SourceMgr &Src, MCContext &Ctx,
+ MCStreamer &Out, const MCAsmInfo
&MAI) {
+ Triple TheTriple(TT);
+ switch (TheTriple.getOS()) {
+ case Triple::Linux:
+ return new X86_32ATTELFAsmParser(T, Src, Ctx, Out, MAI);
+ default:
+ return new X86_32ATTMachOAsmParser(T, Src, Ctx, Out, MAI);
+ }
+}
+
+static AsmParser *createX86_64AsmParser(const Target &T, const std::string
&TT,
+ SourceMgr &Src, MCContext &Ctx,
+ MCStreamer &Out, const MCAsmInfo
&MAI) {
+ Triple TheTriple(TT);
+ switch (TheTriple.getOS()) {
+ case Triple::Linux:
+ return new X86_64ATTELFAsmParser(T, Src, Ctx, Out, MAI);
+ default:
+ return new X86_64ATTMachOAsmParser(T, Src, Ctx, Out, MAI);
+ }
+}
extern "C" void LLVMInitializeX86AsmLexer();
// Force static initialization.
extern "C" void LLVMInitializeX86AsmParser() {
- RegisterAsmParser<X86_32ATTAsmParser> X(TheX86_32Target);
- RegisterAsmParser<X86_64ATTAsmParser> Y(TheX86_64Target);
+ // Register the asm parser.
+ TargetRegistry::RegisterAsmParser(TheX86_32Target, createX86_32AsmParser);
+ TargetRegistry::RegisterAsmParser(TheX86_64Target, createX86_64AsmParser);
LLVMInitializeX86AsmLexer();
}
diff --git a/tools/edis/EDDisassembler.cpp b/tools/edis/EDDisassembler.cpp
index 00b5d8d..c83923f 100644
--- a/tools/edis/EDDisassembler.cpp
+++ b/tools/edis/EDDisassembler.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/System/Host.h"
#include "llvm/Target/TargetAsmLexer.h"
#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Target/TargetRegistry.h"
@@ -364,18 +365,19 @@ int
EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*>
&operands,
sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
MCContext context(*AsmInfo);
OwningPtr<MCStreamer> streamer(createNullStreamer(context));
- AsmParser genericParser(sourceMgr, context, *streamer, *AsmInfo);
- OwningPtr<TargetAsmParser>
TargetParser(Tgt->createAsmParser(genericParser));
+ OwningPtr<AsmParser>
genericParser(Tgt->createAsmParser(sys::getHostTriple(),
+ sourceMgr, context,
+ *streamer,
*AsmInfo));
- AsmToken OpcodeToken = genericParser.Lex();
- AsmToken NextToken = genericParser.Lex(); // consume next token, because
specificParser expects us to
+ AsmToken OpcodeToken = genericParser->Lex();
+ AsmToken NextToken = genericParser->Lex(); // consume next token, because
specificParser expects us to
if (OpcodeToken.is(AsmToken::Identifier)) {
instName = OpcodeToken.getString();
instLoc = OpcodeToken.getLoc();
if (NextToken.isNot(AsmToken::Eof) &&
- TargetParser->ParseInstruction(instName, instLoc, operands))
+ genericParser->ParseInstruction(instName, instLoc, operands))
ret = -1;
} else {
ret = -1;
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 6de6bfb..fd38805 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -312,17 +312,15 @@ static int AssembleInput(const char *ProgName) {
Str.reset(createLoggingStreamer(Str.take(), errs()));
}
- AsmParser Parser(SrcMgr, Ctx, *Str.get(), *MAI);
- OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(Parser));
- if (!TAP) {
+ OwningPtr<AsmParser> Parser(TheTarget->createAsmParser(TripleName,
SrcMgr, Ctx,
+ *Str.get(), *MAI));
+ if (!Parser) {
errs() << ProgName
<< ": error: this target does not support assembly
parsing.\n";
return 1;
}
- Parser.setTargetParser(*TAP.get());
-
- int Res = Parser.Run(NoInitialTextSection);
+ int Res = Parser->Run(NoInitialTextSection);
delete Out;
// Delete output on errors.
--
1.6.4.rc0