aboutsummaryrefslogtreecommitdiffstats
path: root/tools/llvm-mc/AsmParser.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-24 23:30:00 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-24 23:30:00 +0000
commita0527a92adae8c6e3db84cafcef81921e5fe790c (patch)
tree89e76fdb73b893ab20a7e7eb83bcc0c1d429a748 /tools/llvm-mc/AsmParser.cpp
parentba83d7c950a813b2d87b386397e7e086a014acd9 (diff)
downloadexternal_llvm-a0527a92adae8c6e3db84cafcef81921e5fe790c.zip
external_llvm-a0527a92adae8c6e3db84cafcef81921e5fe790c.tar.gz
external_llvm-a0527a92adae8c6e3db84cafcef81921e5fe790c.tar.bz2
Basic .s parsing for .asci[iz], .fill, .space, {.byte, .short, ... }
- Includes some DG tests in test/MC/AsmParser, which are rather primitive since we don't have a -verify mode yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74139 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mc/AsmParser.cpp')
-rw-r--r--tools/llvm-mc/AsmParser.cpp150
1 files changed, 149 insertions, 1 deletions
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp
index e493812..d9e1445 100644
--- a/tools/llvm-mc/AsmParser.cpp
+++ b/tools/llvm-mc/AsmParser.cpp
@@ -291,7 +291,27 @@ bool AsmParser::ParseStatement() {
if (!strcmp(IDVal, ".objc_selector_strs"))
return ParseDirectiveSectionSwitch("__OBJC,__selector_strs");
-
+ // Data directives
+
+ if (!strcmp(IDVal, ".ascii"))
+ return ParseDirectiveAscii(false);
+ if (!strcmp(IDVal, ".asciz"))
+ return ParseDirectiveAscii(true);
+
+ // FIXME: Target hooks for size? Also for "word", "hword".
+ if (!strcmp(IDVal, ".byte"))
+ return ParseDirectiveValue(1);
+ if (!strcmp(IDVal, ".short"))
+ return ParseDirectiveValue(2);
+ if (!strcmp(IDVal, ".long"))
+ return ParseDirectiveValue(4);
+ if (!strcmp(IDVal, ".quad"))
+ return ParseDirectiveValue(8);
+ if (!strcmp(IDVal, ".fill"))
+ return ParseDirectiveFill();
+ if (!strcmp(IDVal, ".space"))
+ return ParseDirectiveSpace();
+
Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
EatToEndOfStatement();
return false;
@@ -361,3 +381,131 @@ bool AsmParser::ParseDirectiveSectionSwitch(const char *Section,
Out.SwitchSection(Ctx.GetSection(Section));
return false;
}
+
+/// ParseDirectiveAscii:
+/// ::= ( .ascii | .asciiz ) [ "string" ( , "string" )* ]
+bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
+ if (Lexer.isNot(asmtok::EndOfStatement)) {
+ for (;;) {
+ if (Lexer.isNot(asmtok::String))
+ return TokError("expected string in '.ascii' or '.asciz' directive");
+
+ // FIXME: This shouldn't use a const char* + strlen, the string could have
+ // embedded nulls.
+ // FIXME: Should have accessor for getting string contents.
+ const char *Str = Lexer.getCurStrVal();
+ Out.EmitBytes(Str + 1, strlen(Str) - 2);
+ if (ZeroTerminated)
+ Out.EmitBytes("\0", 1);
+
+ Lexer.Lex();
+
+ if (Lexer.is(asmtok::EndOfStatement))
+ break;
+
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in '.ascii' or '.asciz' directive");
+ Lexer.Lex();
+ }
+ }
+
+ Lexer.Lex();
+ return false;
+}
+
+/// ParseDirectiveValue
+/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
+bool AsmParser::ParseDirectiveValue(unsigned Size) {
+ if (Lexer.isNot(asmtok::EndOfStatement)) {
+ for (;;) {
+ int64_t Expr;
+ if (ParseExpression(Expr))
+ return true;
+
+ Out.EmitValue(MCValue::get(Expr), Size);
+
+ if (Lexer.is(asmtok::EndOfStatement))
+ break;
+
+ // FIXME: Improve diagnostic.
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in directive");
+ Lexer.Lex();
+ }
+ }
+
+ Lexer.Lex();
+ return false;
+}
+
+/// ParseDirectiveSpace
+/// ::= .space expression [ , expression ]
+bool AsmParser::ParseDirectiveSpace() {
+ int64_t NumBytes;
+ if (ParseExpression(NumBytes))
+ return true;
+
+ int64_t FillExpr = 0;
+ bool HasFillExpr = false;
+ if (Lexer.isNot(asmtok::EndOfStatement)) {
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in '.space' directive");
+ Lexer.Lex();
+
+ if (ParseExpression(FillExpr))
+ return true;
+
+ HasFillExpr = true;
+
+ if (Lexer.isNot(asmtok::EndOfStatement))
+ return TokError("unexpected token in '.space' directive");
+ }
+
+ Lexer.Lex();
+
+ if (NumBytes <= 0)
+ return TokError("invalid number of bytes in '.space' directive");
+
+ // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
+ for (uint64_t i = 0, e = NumBytes; i != e; ++i)
+ Out.EmitValue(MCValue::get(FillExpr), 1);
+
+ return false;
+}
+
+/// ParseDirectiveFill
+/// ::= .fill expression , expression , expression
+bool AsmParser::ParseDirectiveFill() {
+ int64_t NumValues;
+ if (ParseExpression(NumValues))
+ return true;
+
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lexer.Lex();
+
+ int64_t FillSize;
+ if (ParseExpression(FillSize))
+ return true;
+
+ if (Lexer.isNot(asmtok::Comma))
+ return TokError("unexpected token in '.fill' directive");
+ Lexer.Lex();
+
+ int64_t FillExpr;
+ if (ParseExpression(FillExpr))
+ return true;
+
+ if (Lexer.isNot(asmtok::EndOfStatement))
+ return TokError("unexpected token in '.fill' directive");
+
+ Lexer.Lex();
+
+ if (FillSize != 1 && FillSize != 2 && FillSize != 4)
+ return TokError("invalid '.fill' size, expected 1, 2, or 4");
+
+ for (uint64_t i = 0, e = NumValues; i != e; ++i)
+ Out.EmitValue(MCValue::get(FillExpr), FillSize);
+
+ return false;
+}