mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 13:10:34 +00:00
MC: Parse .set and assignments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74208 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5f04d1e522
commit
8f780cd789
7
test/MC/AsmParser/assignment.s
Normal file
7
test/MC/AsmParser/assignment.s
Normal 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
|
||||
|
7
test/MC/AsmParser/directive_set.s
Normal file
7
test/MC/AsmParser/directive_set.s
Normal 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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user