aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2012-09-25 17:30:25 -0700
committerDerek Schuff <dschuff@chromium.org>2012-09-25 18:01:23 -0700
commita27c28b1427dc2082ab2b31efdbb25f9fde31b61 (patch)
tree6f3ff025f542ca3f66a1a01cbf239aeef7784511 /lib/MC
parent0e15ffd8cb1ec642eddb96380660914ff2b007e1 (diff)
parentbc4021f31eaa97ee52655828da3e3de14a39e4a6 (diff)
Merge commit 'bc4021f31eaa97ee52655828da3e3de14a39e4a6'
Conflicts: lib/MC/MCAssembler.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp lib/Target/X86/X86ISelLowering.h
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAssembler.cpp9
-rw-r--r--lib/MC/MCContext.cpp6
-rw-r--r--lib/MC/MCDwarf.cpp2
-rw-r--r--lib/MC/MCELFStreamer.cpp2
-rw-r--r--lib/MC/MCExpr.cpp2
-rw-r--r--lib/MC/MCInst.cpp4
-rw-r--r--lib/MC/MCLabel.cpp2
-rw-r--r--lib/MC/MCObjectFileInfo.cpp20
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp13
-rw-r--r--lib/MC/MCParser/AsmParser.cpp199
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp3
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp2
-rw-r--r--lib/MC/MCSubtargetInfo.cpp51
-rw-r--r--lib/MC/MCSymbol.cpp4
-rw-r--r--lib/MC/MCValue.cpp2
-rw-r--r--lib/MC/MachObjectWriter.cpp47
-rw-r--r--lib/MC/SubtargetFeature.cpp2
17 files changed, 282 insertions, 88 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 02bd6deb62..80bf4f9309 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -330,8 +330,7 @@ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
raw_ostream &OS_)
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
- OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false)
-{
+ OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false) {
}
MCAssembler::~MCAssembler() {
@@ -631,7 +630,7 @@ static void WriteBundlePadding(const MCAssembler &Asm,
}
// @LOCALMOD-END
-/// WriteFragmentData - Write the \arg F data to the output file.
+/// WriteFragmentData - Write the \p F data to the output file.
static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment &F) {
MCObjectWriter *OW = &Asm.getWriter();
@@ -810,7 +809,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
}
uint64_t Start = getWriter().getStream().tell();
- (void) Start;
+ (void)Start;
for (MCSectionData::const_iterator it = SD->begin(),
ie = SD->end(); it != ie; ++it)
@@ -1107,7 +1106,7 @@ raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) {
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCFragment::dump() {
raw_ostream &OS = llvm::errs();
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index b5b14b95f6..477bd17c0d 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -153,6 +153,12 @@ MCSymbol *MCContext::LookupSymbol(StringRef Name) const {
return Symbols.lookup(Name);
}
+MCSymbol *MCContext::LookupSymbol(const Twine &Name) const {
+ SmallString<128> NameSV;
+ Name.toVector(NameSV);
+ return LookupSymbol(NameSV.str());
+}
+
//===----------------------------------------------------------------------===//
// Section Management
//===----------------------------------------------------------------------===//
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index ee597cfa21..a1643b2da5 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -425,7 +425,7 @@ void MCDwarfFile::print(raw_ostream &OS) const {
OS << '"' << getName() << '"';
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCDwarfFile::dump() const {
print(dbgs());
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index bf35ab7fc3..d1aeaf36c7 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -247,7 +247,6 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
switch (Attribute) {
case MCSA_LazyReference:
case MCSA_Reference:
- case MCSA_NoDeadStrip:
case MCSA_SymbolResolver:
case MCSA_PrivateExtern:
case MCSA_WeakDefinition:
@@ -256,6 +255,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_IndirectSymbol:
llvm_unreachable("Invalid symbol attribute for ELF!");
+ case MCSA_NoDeadStrip:
case MCSA_ELF_TypeGnuUniqueObject:
// Ignore for now.
break;
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index b19665949d..8fed48cef2 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -136,7 +136,7 @@ void MCExpr::print(raw_ostream &OS) const {
llvm_unreachable("Invalid expression kind!");
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCExpr::dump() const {
print(dbgs());
dbgs() << '\n';
diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp
index e96010bd5c..124cc149be 100644
--- a/lib/MC/MCInst.cpp
+++ b/lib/MC/MCInst.cpp
@@ -32,7 +32,7 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << ">";
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCOperand::dump() const {
print(dbgs(), 0);
dbgs() << "\n";
@@ -64,7 +64,7 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI,
OS << ">";
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCInst::dump() const {
print(dbgs(), 0);
dbgs() << "\n";
diff --git a/lib/MC/MCLabel.cpp b/lib/MC/MCLabel.cpp
index 95d7d16a19..1d3022a93e 100644
--- a/lib/MC/MCLabel.cpp
+++ b/lib/MC/MCLabel.cpp
@@ -16,7 +16,7 @@ void MCLabel::print(raw_ostream &OS) const {
OS << '"' << getInstance() << '"';
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCLabel::dump() const {
print(dbgs());
}
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index 29b4a94653..8053624831 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -430,12 +430,20 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
}
- StaticDtorSection =
- Ctx->getCOFFSection(".dtors",
- COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
- COFF::IMAGE_SCN_MEM_READ |
- COFF::IMAGE_SCN_MEM_WRITE,
- SectionKind::getDataRel());
+ if (T.getOS() == Triple::Win32) {
+ StaticDtorSection =
+ Ctx->getCOFFSection(".CRT$XTX",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
+ } else {
+ StaticDtorSection =
+ Ctx->getCOFFSection(".dtors",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
+ }
// FIXME: We're emitting LSDA info into a readonly section on COFF, even
// though it contains relocatable pointers. In PIC mode, this is probably a
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index c76052d66e..f93f685bf5 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -396,8 +396,17 @@ AsmToken AsmLexer::LexToken() {
case 0:
case ' ':
case '\t':
- // Ignore whitespace.
- return LexToken();
+ if (SkipSpace) {
+ // Ignore whitespace.
+ return LexToken();
+ } else {
+ int len = 1;
+ while (*CurPtr==' ' || *CurPtr=='\t') {
+ CurPtr++;
+ len++;
+ }
+ return AsmToken(AsmToken::Space, StringRef(TokStart, len));
+ }
case '\n': // FALL THROUGH.
case '\r':
isAtStartOfLine = true;
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 40e6b92174..fc0bc35347 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -47,7 +47,7 @@ namespace {
/// \brief Helper class for tracking macro definitions.
typedef std::vector<AsmToken> MacroArgument;
typedef std::vector<MacroArgument> MacroArguments;
-typedef StringRef MacroParameter;
+typedef std::pair<StringRef, MacroArgument> MacroParameter;
typedef std::vector<MacroParameter> MacroParameters;
struct Macro {
@@ -84,8 +84,8 @@ public:
class AsmParser : public MCAsmParser {
friend class GenericAsmParser;
- AsmParser(const AsmParser &); // DO NOT IMPLEMENT
- void operator=(const AsmParser &); // DO NOT IMPLEMENT
+ AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION;
+ void operator=(const AsmParser &) LLVM_DELETED_FUNCTION;
private:
AsmLexer Lexer;
MCContext &Ctx;
@@ -130,6 +130,9 @@ private:
/// AssemblerDialect. ~OU means unset value and use value provided by MAI.
unsigned AssemblerDialect;
+ /// IsDarwin - is Darwin compatibility enabled?
+ bool IsDarwin;
+
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI);
@@ -202,14 +205,15 @@ private:
/// This returns true on failure.
bool ProcessIncbinFile(const std::string &Filename);
- /// \brief Reset the current lexer position to that given by \arg Loc. The
+ /// \brief Reset the current lexer position to that given by \p Loc. The
/// current token is not set; clients should ensure Lex() is called
/// subsequently.
void JumpToLoc(SMLoc Loc);
virtual void EatToEndOfStatement();
- bool ParseMacroArgument(MacroArgument &MA);
+ bool ParseMacroArgument(MacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter);
bool ParseMacroArguments(const Macro *M, MacroArguments &A);
/// \brief Parse up to the end of statement and a return the contents from the
@@ -221,7 +225,8 @@ private:
/// return the contents from the current token up to the end or comma.
StringRef ParseStringToComma();
- bool ParseAssignment(StringRef Name, bool allow_redef);
+ bool ParseAssignment(StringRef Name, bool allow_redef,
+ bool NoDeadStrip = false);
bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
@@ -229,7 +234,7 @@ private:
bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \arg Res to the identifier contents.
+ /// and set \p Res to the identifier contents.
virtual bool ParseIdentifier(StringRef &Res);
// Directive Parsing.
@@ -413,8 +418,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI)
: Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0),
- CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
- AssemblerDialect(~0U) {
+ CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0),
+ AssemblerDialect(~0U), IsDarwin(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -435,6 +440,7 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
} else if (_MAI.hasSubsectionsViaSymbols()) {
PlatformParser = createDarwinAsmParser();
PlatformParser->Initialize(*this);
+ IsDarwin = true;
} else {
PlatformParser = createELFAsmParser();
PlatformParser->Initialize(*this);
@@ -1495,6 +1501,8 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
if (NParameters != 0 && NParameters != A.size())
return Error(L, "Wrong number of arguments");
+ // A macro without parameters is handled differently on Darwin:
+ // gas accepts no arguments and does no substitutions
while (!Body.empty()) {
// Scan for the next substitution.
std::size_t End = Body.size(), Pos = 0;
@@ -1558,18 +1566,26 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
StringRef Argument(Begin, I - (Pos +1));
unsigned Index = 0;
for (; Index < NParameters; ++Index)
- if (Parameters[Index] == Argument)
+ if (Parameters[Index].first == Argument)
break;
- // FIXME: We should error at the macro definition.
- if (Index == NParameters)
- return Error(L, "Parameter not found");
-
- for (MacroArgument::const_iterator it = A[Index].begin(),
- ie = A[Index].end(); it != ie; ++it)
- OS << it->getString();
+ if (Index == NParameters) {
+ if (Body[Pos+1] == '(' && Body[Pos+2] == ')')
+ Pos += 3;
+ else {
+ OS << '\\' << Argument;
+ Pos = I;
+ }
+ } else {
+ for (MacroArgument::const_iterator it = A[Index].begin(),
+ ie = A[Index].end(); it != ie; ++it)
+ if (it->getKind() == AsmToken::String)
+ OS << it->getStringContents();
+ else
+ OS << it->getString();
- Pos += 1 + Argument.size();
+ Pos += 1 + Argument.size();
+ }
}
// Update the scan point.
Body = Body.substr(Pos);
@@ -1584,22 +1600,97 @@ MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL,
{
}
+static bool IsOperator(AsmToken::TokenKind kind)
+{
+ switch (kind)
+ {
+ default:
+ return false;
+ case AsmToken::Plus:
+ case AsmToken::Minus:
+ case AsmToken::Tilde:
+ case AsmToken::Slash:
+ case AsmToken::Star:
+ case AsmToken::Dot:
+ case AsmToken::Equal:
+ case AsmToken::EqualEqual:
+ case AsmToken::Pipe:
+ case AsmToken::PipePipe:
+ case AsmToken::Caret:
+ case AsmToken::Amp:
+ case AsmToken::AmpAmp:
+ case AsmToken::Exclaim:
+ case AsmToken::ExclaimEqual:
+ case AsmToken::Percent:
+ case AsmToken::Less:
+ case AsmToken::LessEqual:
+ case AsmToken::LessLess:
+ case AsmToken::LessGreater:
+ case AsmToken::Greater:
+ case AsmToken::GreaterEqual:
+ case AsmToken::GreaterGreater:
+ return true;
+ }
+}
+
/// ParseMacroArgument - Extract AsmTokens for a macro argument.
/// This is used for both default macro parameter values and the
/// arguments in macro invocations
-bool AsmParser::ParseMacroArgument(MacroArgument &MA) {
+bool AsmParser::ParseMacroArgument(MacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter) {
unsigned ParenLevel = 0;
+ unsigned AddTokens = 0;
+
+ // gas accepts arguments separated by whitespace, except on Darwin
+ if (!IsDarwin)
+ Lexer.setSkipSpace(false);
for (;;) {
- if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
+ if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) {
+ Lexer.setSkipSpace(true);
return TokError("unexpected token in macro instantiation");
+ }
+
+ if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) {
+ // Spaces and commas cannot be mixed to delimit parameters
+ if (ArgumentDelimiter == AsmToken::Eof)
+ ArgumentDelimiter = AsmToken::Comma;
+ else if (ArgumentDelimiter != AsmToken::Comma) {
+ Lexer.setSkipSpace(true);
+ return TokError("expected ' ' for macro argument separator");
+ }
+ break;
+ }
+
+ if (Lexer.is(AsmToken::Space)) {
+ Lex(); // Eat spaces
+
+ // Spaces can delimit parameters, but could also be part an expression.
+ // If the token after a space is an operator, add the token and the next
+ // one into this argument
+ if (ArgumentDelimiter == AsmToken::Space ||
+ ArgumentDelimiter == AsmToken::Eof) {
+ if (IsOperator(Lexer.getKind())) {
+ // Check to see whether the token is used as an operator,
+ // or part of an identifier
+ const char *NextChar = getTok().getEndLoc().getPointer() + 1;
+ if (*NextChar == ' ')
+ AddTokens = 2;
+ }
+
+ if (!AddTokens && ParenLevel == 0) {
+ if (ArgumentDelimiter == AsmToken::Eof &&
+ !IsOperator(Lexer.getKind()))
+ ArgumentDelimiter = AsmToken::Space;
+ break;
+ }
+ }
+ }
// HandleMacroEntry relies on not advancing the lexer here
// to be able to fill in the remaining default parameter values
if (Lexer.is(AsmToken::EndOfStatement))
break;
- if (ParenLevel == 0 && Lexer.is(AsmToken::Comma))
- break;
// Adjust the current parentheses level.
if (Lexer.is(AsmToken::LParen))
@@ -1609,8 +1700,12 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA) {
// Append the token to the current argument list.
MA.push_back(getTok());
+ if (AddTokens)
+ AddTokens--;
Lex();
}
+
+ Lexer.setSkipSpace(true);
if (ParenLevel != 0)
return TokError("unbalanced parentheses in macro argument");
return false;
@@ -1619,6 +1714,9 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA) {
// Parse the macro instantiation arguments.
bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
+ // Argument delimiter is initially unknown. It will be set by
+ // ParseMacroArgument()
+ AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
// Parse two kinds of macro invocations:
// - macros defined without any parameters accept an arbitrary number of them
@@ -1627,13 +1725,30 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
++Parameter) {
MacroArgument MA;
- if (ParseMacroArgument(MA))
+ if (ParseMacroArgument(MA, ArgumentDelimiter))
return true;
- A.push_back(MA);
+ if (!MA.empty() || !NParameters)
+ A.push_back(MA);
+ else if (NParameters) {
+ if (!M->Parameters[Parameter].second.empty())
+ A.push_back(M->Parameters[Parameter].second);
+ }
- if (Lexer.is(AsmToken::EndOfStatement))
+ // At the end of the statement, fill in remaining arguments that have
+ // default values. If there aren't any, then the next argument is
+ // required but missing
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ if (NParameters && Parameter < NParameters - 1) {
+ if (M->Parameters[Parameter + 1].second.empty())
+ return TokError("macro argument '" +
+ Twine(M->Parameters[Parameter + 1].first) +
+ "' is missing");
+ else
+ continue;
+ }
return false;
+ }
if (Lexer.is(AsmToken::Comma))
Lex();
@@ -1722,7 +1837,8 @@ static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) {
llvm_unreachable("Unknown expr kind!");
}
-bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
+bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
+ bool NoDeadStrip) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Lexer.getLoc();
@@ -1777,6 +1893,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
// Do the assignment.
Out.EmitAssignment(Sym, Value);
+ if (NoDeadStrip)
+ Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip);
+
return false;
}
@@ -1834,7 +1953,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
return TokError("unexpected token in '" + Twine(IDVal) + "'");
Lex();
- return ParseAssignment(Name, allow_redef);
+ return ParseAssignment(Name, allow_redef, true);
}
bool AsmParser::ParseEscapedString(std::string &Data) {
@@ -3152,22 +3271,30 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
return TokError("expected identifier in '.macro' directive");
MacroParameters Parameters;
+ // Argument delimiter is initially unknown. It will be set by
+ // ParseMacroArgument()
+ AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
MacroParameter Parameter;
- if (getParser().ParseIdentifier(Parameter))
+ if (getParser().ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.macro' directive");
+
+ if (getLexer().is(AsmToken::Equal)) {
+ Lex();
+ if (getParser().ParseMacroArgument(Parameter.second, ArgumentDelimiter))
+ return true;
+ }
+
Parameters.push_back(Parameter);
- if (getLexer().isNot(AsmToken::Comma))
+ if (getLexer().is(AsmToken::Comma))
+ Lex();
+ else if (getLexer().is(AsmToken::EndOfStatement))
break;
- Lex();
}
}
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.macro' directive");
-
// Eat the end of statement.
Lex();
@@ -3372,7 +3499,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
- if (ParseIdentifier(Parameter))
+ if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irp' directive");
Parameters.push_back(Parameter);
@@ -3418,7 +3545,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
MacroParameters Parameters;
MacroParameter Parameter;
- if (ParseIdentifier(Parameter))
+ if (ParseIdentifier(Parameter.first))
return TokError("expected identifier in '.irpc' directive");
Parameters.push_back(Parameter);
@@ -3468,7 +3595,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
if (ActiveMacros.empty())
- return TokError("unexpected '.endr' directive, no current .rept");
+ return TokError("unmatched '.endr' directive");
// The only .repl that should get here are the ones created by
// InstantiateMacroLikeBody.
diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index 3a3ff14711..384b341bc7 100644
--- a/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -12,7 +12,8 @@
using namespace llvm;
-MCAsmLexer::MCAsmLexer() : CurTok(AsmToken::Error, StringRef()), TokStart(0) {
+MCAsmLexer::MCAsmLexer() : CurTok(AsmToken::Error, StringRef()),
+ TokStart(0), SkipSpace(true) {
}
MCAsmLexer::~MCAsmLexer() {
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index 93ee2dd0c0..6967feef24 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -44,7 +44,7 @@ bool MCAsmParser::ParseExpression(const MCExpr *&Res) {
}
void MCParsedAsmOperand::dump() const {
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dbgs() << " " << *this;
#endif
}
diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp
index cbf853cd8e..8be07eed82 100644
--- a/lib/MC/MCSubtargetInfo.cpp
+++ b/lib/MC/MCSubtargetInfo.cpp
@@ -19,11 +19,28 @@ using namespace llvm;
MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors.
+/// ReInitMCSubtargetInfo - Set or change the CPU (optionally supplemented
+/// with feature string). Recompute feature bits and scheduling model.
+void
+MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) {
+ SubtargetFeatures Features(FS);
+ FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
+ ProcFeatures, NumFeatures);
+
+ if (!CPU.empty())
+ CPUSchedModel = getSchedModelForCPU(CPU);
+ else
+ CPUSchedModel = &MCSchedModel::DefaultSchedModel;
+}
+
void
MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR,
+ const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA,
const InstrStage *IS,
const unsigned *OC,
const unsigned *FP,
@@ -31,26 +48,18 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS,
TargetTriple = TT;
ProcFeatures = PF;
ProcDesc = PD;
- ProcSchedModel = ProcSched;
+ ProcSchedModels = ProcSched;
+ WriteProcResTable = WPR;
+ WriteLatencyTable = WL;
+ ReadAdvanceTable = RA;
+
Stages = IS;
OperandCycles = OC;
ForwardingPaths = FP;
NumFeatures = NF;
NumProcs = NP;
- SubtargetFeatures Features(FS);
- FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
- ProcFeatures, NumFeatures);
-}
-
-
-/// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
-/// feature string) and recompute feature bits.
-uint64_t MCSubtargetInfo::ReInitMCSubtargetInfo(StringRef CPU, StringRef FS) {
- SubtargetFeatures Features(FS);
- FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs,
- ProcFeatures, NumFeatures);
- return FeatureBits;
+ InitMCProcessorInfo(CPU, FS);
}
/// ToggleFeature - Toggle a feature and returns the re-computed feature
@@ -72,11 +81,11 @@ uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) {
const MCSchedModel *
MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
- assert(ProcSchedModel && "Processor machine model not available!");
+ assert(ProcSchedModels && "Processor machine model not available!");
#ifndef NDEBUG
for (size_t i = 1; i < NumProcs; i++) {
- assert(strcmp(ProcSchedModel[i - 1].Key, ProcSchedModel[i].Key) < 0 &&
+ assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 &&
"Processor machine model table is not sorted");
}
#endif
@@ -85,8 +94,8 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const {
SubtargetInfoKV KV;
KV.Key = CPU.data();
const SubtargetInfoKV *Found =
- std::lower_bound(ProcSchedModel, ProcSchedModel+NumProcs, KV);
- if (Found == ProcSchedModel+NumProcs || StringRef(Found->Key) != CPU) {
+ std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, KV);
+ if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) {
errs() << "'" << CPU
<< "' is not a recognized processor for this target"
<< " (ignoring processor)\n";
@@ -101,3 +110,9 @@ MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const {
const MCSchedModel *SchedModel = getSchedModelForCPU(CPU);
return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths);
}
+
+/// Initialize an InstrItineraryData instance.
+void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const {
+ InstrItins =
+ InstrItineraryData(CPUSchedModel, Stages, OperandCycles, ForwardingPaths);
+}
diff --git a/lib/MC/MCSymbol.cpp b/lib/MC/MCSymbol.cpp
index f60126b8fa..b973c57f7b 100644
--- a/lib/MC/MCSymbol.cpp
+++ b/lib/MC/MCSymbol.cpp
@@ -26,7 +26,7 @@ static bool isAcceptableChar(char C) {
return true;
}
-/// NameNeedsQuoting - Return true if the identifier \arg Str needs quotes to be
+/// NameNeedsQuoting - Return true if the identifier \p Str needs quotes to be
/// syntactically correct.
static bool NameNeedsQuoting(StringRef Str) {
assert(!Str.empty() && "Cannot create an empty MCSymbol");
@@ -76,7 +76,7 @@ void MCSymbol::print(raw_ostream &OS) const {
OS << '"' << getName() << '"';
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCSymbol::dump() const {
print(dbgs());
}
diff --git a/lib/MC/MCValue.cpp b/lib/MC/MCValue.cpp
index a37149d788..4393777211 100644
--- a/lib/MC/MCValue.cpp
+++ b/lib/MC/MCValue.cpp
@@ -31,7 +31,7 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
OS << " + " << getConstant();
}
-#ifndef NDEBUG
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void MCValue::dump() const {
print(dbgs(), 0);
}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index c57b0d65c1..a94b214022 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -68,6 +68,11 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
// If this is a variable, then recursively evaluate now.
if (S.isVariable()) {
+ if (const MCConstantExpr *C =
+ dyn_cast<const MCConstantExpr>(S.getVariableValue()))
+ return C->getValue();
+
+
MCValue Target;
if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
report_fatal_error("unable to evaluate offset for variable '" +
@@ -140,8 +145,8 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
/// WriteSegmentLoadCommand - Write a segment load command.
///
-/// \arg NumSections - The number of sections in this segment.
-/// \arg SectionDataSize - The total size of the sections.
+/// \param NumSections The number of sections in this segment.
+/// \param SectionDataSize The total size of the sections.
void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
@@ -315,11 +320,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
// Compute the symbol address.
if (Symbol.isDefined()) {
- if (Symbol.isAbsolute()) {
- Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
- } else {
- Address = getSymbolAddress(&Data, Layout);
- }
+ Address = getSymbolAddress(&Data, Layout);
} else if (Data.isCommon()) {
// Common symbols are encoded with the size in the address
// field, and their alignment in the flags.
@@ -557,6 +558,26 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
}
}
+void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ for (MCAssembler::symbol_iterator i = Asm.symbol_begin(),
+ e = Asm.symbol_end();
+ i != e; ++i) {
+ MCSymbolData &SD = *i;
+ if (!SD.getSymbol().isVariable())
+ continue;
+
+ // Is the variable is a symbol difference (SA - SB + C) expression,
+ // and neither symbol is external, mark the variable as absolute.
+ const MCExpr *Expr = SD.getSymbol().getVariableValue();
+ MCValue Value;
+ if (Expr->EvaluateAsRelocatable(Value, Layout)) {
+ if (Value.getSymA() && Value.getSymB())
+ const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
+ }
+ }
+}
+
void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
computeSectionAddresses(Asm, Layout);
@@ -564,6 +585,10 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
// Create symbol data for any indirect symbols.
BindIndirectSymbols(Asm);
+ //