MC: Parse .set and assignments.

llvm-svn: 74208
This commit is contained in:
Daniel Dunbar 2009-06-25 21:56:11 +00:00
parent bf61749b47
commit 2d2ee150eb
6 changed files with 69 additions and 3 deletions

View File

@ -0,0 +1,7 @@
# RUN: llvm-mc %s > %t
# RUN: grep -A 2 TEST0 %t > %t2
# RUN: grep "a = 0" %t2
TEST0:
a = 0

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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"
};