diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-06-25 21:56:11 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-06-25 21:56:11 +0000 |
commit | 8f780cd7896407f743de7538166ff9d40d752086 (patch) | |
tree | 754d486c28381babd3895f5719531ef58577bcbd | |
parent | 5f04d1e522e9f412e716310559b9324564119e45 (diff) | |
download | llvm-8f780cd7896407f743de7538166ff9d40d752086.tar.gz llvm-8f780cd7896407f743de7538166ff9d40d752086.tar.bz2 llvm-8f780cd7896407f743de7538166ff9d40d752086.tar.xz |
MC: Parse .set and assignments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74208 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | test/MC/AsmParser/assignment.s | 7 | ||||
-rw-r--r-- | test/MC/AsmParser/directive_set.s | 7 | ||||
-rw-r--r-- | tools/llvm-mc/AsmLexer.cpp | 1 | ||||
-rw-r--r-- | tools/llvm-mc/AsmLexer.h | 2 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 53 | ||||
-rw-r--r-- | tools/llvm-mc/AsmParser.h | 2 |
6 files changed, 69 insertions, 3 deletions
diff --git a/test/MC/AsmParser/assignment.s b/test/MC/AsmParser/assignment.s new file mode 100644 index 0000000000..8e6ff34fe4 --- /dev/null +++ b/test/MC/AsmParser/assignment.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc %s > %t + +# RUN: grep -A 2 TEST0 %t > %t2 +# RUN: grep "a = 0" %t2 +TEST0: + a = 0 +
\ No newline at end of file diff --git a/test/MC/AsmParser/directive_set.s b/test/MC/AsmParser/directive_set.s new file mode 100644 index 0000000000..51119a661c --- /dev/null +++ b/test/MC/AsmParser/directive_set.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc %s > %t + +# RUN: grep -A 2 TEST0 %t > %t2 +# RUN: grep ".set a, 0" %t2 +TEST0: + .set a, 0 +
\ No newline at end of file diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp index 186a058552..db86825f3d 100644 --- a/tools/llvm-mc/AsmLexer.cpp +++ b/tools/llvm-mc/AsmLexer.cpp @@ -262,6 +262,7 @@ asmtok::TokKind AsmLexer::LexToken() { case '*': return asmtok::Star; case ',': return asmtok::Comma; case '$': return asmtok::Dollar; + case '=': return asmtok::Equal; case '|': return asmtok::Pipe; case '^': return asmtok::Caret; case '&': return asmtok::Amp; diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h index d074db7cd3..19a1b38af4 100644 --- a/tools/llvm-mc/AsmLexer.h +++ b/tools/llvm-mc/AsmLexer.h @@ -42,7 +42,7 @@ namespace asmtok { Plus, Minus, Tilde, Slash, // '/' LParen, RParen, - Star, Comma, Dollar, + Star, Comma, Dollar, Equal, Pipe, Caret, Amp, Exclaim, Percent, LessLess, GreaterGreater diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index d9e14458fd..25955187da 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -182,7 +182,8 @@ bool AsmParser::ParseStatement() { const char *IDVal = Lexer.getCurStrVal(); // Consume the identifier, see what is after it. - if (Lexer.Lex() == asmtok::Colon) { + switch (Lexer.Lex()) { + case asmtok::Colon: // identifier ':' -> Label. Lexer.Lex(); @@ -192,6 +193,15 @@ bool AsmParser::ParseStatement() { Out.EmitLabel(Ctx.GetOrCreateSymbol(IDVal)); return ParseStatement(); + + case asmtok::Equal: + // identifier '=' ... -> assignment statement + Lexer.Lex(); + + return ParseAssignment(IDVal, false); + + default: // Normal instruction or directive. + break; } // Otherwise, we have a normal instruction or directive. @@ -209,7 +219,8 @@ bool AsmParser::ParseStatement() { if (!strcmp(IDVal, ".static_const")) return ParseDirectiveSectionSwitch("__TEXT,__static_const"); if (!strcmp(IDVal, ".cstring")) - return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals"); + return ParseDirectiveSectionSwitch("__TEXT,__cstring", + "cstring_literals"); if (!strcmp(IDVal, ".literal4")) return ParseDirectiveSectionSwitch("__TEXT,__literal4", "4byte_literals"); if (!strcmp(IDVal, ".literal8")) @@ -291,6 +302,10 @@ bool AsmParser::ParseStatement() { if (!strcmp(IDVal, ".objc_selector_strs")) return ParseDirectiveSectionSwitch("__OBJC,__selector_strs"); + // Assembler features + if (!strcmp(IDVal, ".set")) + return ParseDirectiveSet(); + // Data directives if (!strcmp(IDVal, ".ascii")) @@ -336,6 +351,40 @@ bool AsmParser::ParseStatement() { return false; } +bool AsmParser::ParseAssignment(const char *Name, bool IsDotSet) { + int64_t Value; + if (ParseExpression(Value)) + return true; + + if (Lexer.isNot(asmtok::EndOfStatement)) + return TokError("unexpected token in assignment"); + + // Eat the end of statement marker. + Lexer.Lex(); + + // Get the symbol for this name. + // FIXME: Handle '.'. + MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + Out.EmitAssignment(Sym, MCValue::get(Value), IsDotSet); + + return false; +} + +/// ParseDirectiveSet: +/// ::= .set identifier ',' expression +bool AsmParser::ParseDirectiveSet() { + if (Lexer.isNot(asmtok::Identifier)) + return TokError("expected identifier after '.set' directive"); + + const char *Name = Lexer.getCurStrVal(); + + if (Lexer.Lex() != asmtok::Comma) + return TokError("unexpected token in '.set'"); + Lexer.Lex(); + + return ParseAssignment(Name, true); +} + /// ParseDirectiveSection: /// ::= .section identifier (',' identifier)* /// FIXME: This should actually parse out the segment, section, attributes and diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index d0cc0eef2f..4b51ab17ac 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -43,6 +43,7 @@ private: void EatToEndOfStatement(); + bool ParseAssignment(const char *Name, bool IsDotSet); bool ParseExpression(int64_t &Res); bool ParsePrimaryExpr(int64_t &Res); bool ParseBinOpRHS(unsigned Precedence, int64_t &Res); @@ -61,6 +62,7 @@ private: bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ... bool ParseDirectiveFill(); // ".fill" bool ParseDirectiveSpace(); // ".space" + bool ParseDirectiveSet(); // ".set" }; |