[llvm-commits] [llvm] r156714 - in /llvm/trunk: lib/MC/MCParser/AsmParser.cpp test/MC/AsmParser/macro-rept-err1.s test/MC/AsmParser/macro-rept-err2.s test/MC/AsmParser/macro-rept.s
Rafael Espindola
rafael.espindola at gmail.com
Sat May 12 09:31:10 PDT 2012
Author: rafael
Date: Sat May 12 11:31:10 2012
New Revision: 156714
URL: http://llvm.org/viewvc/llvm-project?rev=156714&view=rev
Log:
Add support for the .rept directive. Patch by Vladmir Sorokin. I added support
for nesting.
Added:
llvm/trunk/test/MC/AsmParser/macro-rept-err1.s
llvm/trunk/test/MC/AsmParser/macro-rept-err2.s
llvm/trunk/test/MC/AsmParser/macro-rept.s
Modified:
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=156714&r1=156713&r2=156714&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sat May 12 11:31:10 2012
@@ -111,6 +111,9 @@
/// ActiveMacros - Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
+ /// ActiveRept - Stack of active .rept directives.
+ std::vector<SMLoc> ActiveRept;
+
/// Boolean tracking whether macro substitution is enabled.
unsigned MacrosEnabled : 1;
@@ -265,6 +268,9 @@
const MCExpr *ApplyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
+
+ bool ParseDirectiveRept(SMLoc DirectiveLoc);
+ bool ParseDirectiveEndRept(SMLoc DirectiveLoc);
};
/// \brief Generic implementations of directive handling, etc. which is shared
@@ -1262,6 +1268,11 @@
if (IDVal == ".code16" || IDVal == ".code16gcc")
return TokError(Twine(IDVal) + " not supported yet");
+ if (IDVal == ".rept")
+ return ParseDirectiveRept(IDLoc);
+ if (IDVal == ".endr")
+ return ParseDirectiveEndRept(IDLoc);
+
// Look up the handler in the handler table.
std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
DirectiveMap.lookup(IDVal);
@@ -3125,6 +3136,86 @@
return false;
}
+bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
+ const MCExpr *Value;
+
+ if (ParseExpression(Value))
+ return true;
+
+ int64_t Count;
+ if (!Value->EvaluateAsAbsolute(Count))
+ return TokError("Cannot evaluate value");
+
+ if (Count < 0)
+ return TokError("Count is negative");
+
+ AsmToken EndToken, StartToken = getTok();
+ unsigned Nest = 1;
+
+ // Lex the macro definition.
+ for (;;) {
+ // Check whether we have reached the end of the file.
+ if (getLexer().is(AsmToken::Eof))
+ return Error(DirectiveLoc, "no matching '.endr' in definition");
+
+ // Chcek if we have a nested .rept.
+ if (getLexer().is(AsmToken::Identifier) &&
+ (getTok().getIdentifier() == ".rept")) {
+ Nest++;
+ EatToEndOfStatement();
+ continue;
+ }
+
+ // Otherwise, check whether we have reach the .endr.
+ if (getLexer().is(AsmToken::Identifier) &&
+ (getTok().getIdentifier() == ".endr")) {
+ Nest--;
+ if (Nest == 0) {
+ EndToken = getTok();
+ Lex();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.endr' directive");
+ break;
+ }
+ }
+
+ // Otherwise, scan til the end of the statement.
+ EatToEndOfStatement();
+ }
+
+ const char *BodyStart = StartToken.getLoc().getPointer();
+ const char *BodyEnd = EndToken.getLoc().getPointer();
+ StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
+
+ SmallString<256> Buf;
+ raw_svector_ostream OS(Buf);
+ for (int i = 0; i < Count; i++)
+ OS << Body;
+ OS << ".endr\n";
+
+ MemoryBuffer *Instantiation =
+ MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
+
+ CurBuffer = SrcMgr.AddNewSourceBuffer(Instantiation, SMLoc());
+ Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
+
+ ActiveRept.push_back(getTok().getLoc());
+
+ return false;
+}
+
+bool AsmParser::ParseDirectiveEndRept(SMLoc DirectiveLoc) {
+ if (ActiveRept.empty())
+ return TokError("unexpected '.endr' directive, no current .rept");
+
+ // The only .repl that should get here are the ones created by
+ // ParseDirectiveRept.
+ assert(getLexer().is(AsmToken::EndOfStatement));
+
+ JumpToLoc(ActiveRept.back());
+ ActiveRept.pop_back();
+ return false;
+}
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM,
Added: llvm/trunk/test/MC/AsmParser/macro-rept-err1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-rept-err1.s?rev=156714&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-rept-err1.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-rept-err1.s Sat May 12 11:31:10 2012
@@ -0,0 +1,6 @@
+// RUN: not llvm-mc -triple x86_64-unknown-unknown %s 2> %t
+// RUN: FileCheck < %t %s
+
+.endr
+
+// CHECK: unexpected '.endr' directive, no current .rept
Added: llvm/trunk/test/MC/AsmParser/macro-rept-err2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-rept-err2.s?rev=156714&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-rept-err2.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-rept-err2.s Sat May 12 11:31:10 2012
@@ -0,0 +1,7 @@
+// RUN: not llvm-mc -triple x86_64-unknown-unknown %s 2> %t
+// RUN: FileCheck < %t %s
+
+.rept 3
+.long
+
+// CHECK: no matching '.endr' in definition
Added: llvm/trunk/test/MC/AsmParser/macro-rept.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-rept.s?rev=156714&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-rept.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-rept.s Sat May 12 11:31:10 2012
@@ -0,0 +1,22 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown %s | FileCheck %s
+
+.rept 2
+ .long 1
+.endr
+
+.rept 3
+.rept 2
+ .long 0
+.endr
+.endr
+
+// CHECK: .long 1
+// CHECK: .long 1
+
+// CHECK: .long 0
+// CHECK: .long 0
+// CHECK: .long 0
+
+// CHECK: .long 0
+// CHECK: .long 0
+// CHECK: .long 0
More information about the llvm-commits
mailing list