This patch enables the Mips .set directive to define aliases

The .set directive in the Mips the assembler can be 
used to set the value of a symbol to an expression. 
This changes the symbol's value and type to conform 
to the expression's.

Syntax: .set symbol, expression

This patch implements the parsing of the above syntax 
and enables the parser to use defined symbols when 
parsing operands.

Contributor: Vladimir Medic
llvm-svn: 177667
This commit is contained in:
Jack Carter 2013-03-21 21:44:16 +00:00
parent 756810fe36
commit d76b2376f2
2 changed files with 99 additions and 6 deletions

View File

@ -101,6 +101,9 @@ class MipsAsmParser : public MCTargetAsmParser {
MipsAsmParser::OperandMatchResultTy
parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned RegisterClass);
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
StringRef Mnemonic);
@ -133,6 +136,8 @@ class MipsAsmParser : public MCTargetAsmParser {
bool parseSetReorderDirective();
bool parseSetNoReorderDirective();
bool parseSetAssignment();
bool parseDirectiveWord(unsigned Size, SMLoc L);
MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
@ -817,6 +822,11 @@ bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
return false;
}
case AsmToken::Identifier:
// Look for the existing symbol, we should check if
// we need to assigne the propper RegisterKind
if (searchSymbolAlias(Operands,MipsOperand::Kind_None))
return false;
//else drop to expression parsing
case AsmToken::LParen:
case AsmToken::Minus:
case AsmToken::Plus:
@ -1009,6 +1019,11 @@ MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
if (!isMips64())
return MatchOperand_NoMatch;
if (getLexer().getKind() == AsmToken::Identifier) {
if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs))
return MatchOperand_Success;
return MatchOperand_NoMatch;
}
// if the first token is not '$' we have an error
if (Parser.getTok().isNot(AsmToken::Dollar))
return MatchOperand_NoMatch;
@ -1023,9 +1038,52 @@ MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_NoMatch;
}
bool MipsAsmParser::
searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
unsigned RegisterKind) {
MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
if (Sym) {
SMLoc S = Parser.getTok().getLoc();
const MCExpr *Expr;
if (Sym->isVariable())
Expr = Sym->getVariableValue();
else
return false;
if (Expr->getKind() == MCExpr::SymbolRef) {
const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
const StringRef DefSymbol = Ref->getSymbol().getName();
if (DefSymbol.startswith("$")) {
// Lookup for the register with corresponding name
int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64());
if (RegNum > -1) {
Parser.Lex();
MipsOperand *op = MipsOperand::CreateReg(RegNum,S,
Parser.getTok().getLoc());
op->setRegKind((MipsOperand::RegisterKind)RegisterKind);
Operands.push_back(op);
return true;
}
}
} else if (Expr->getKind() == MCExpr::Constant) {
Parser.Lex();
const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
MipsOperand *op = MipsOperand::CreateImm(Const,S,
Parser.getTok().getLoc());
Operands.push_back(op);
return true;
}
}
return false;
}
MipsAsmParser::OperandMatchResultTy
MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
if (getLexer().getKind() == AsmToken::Identifier) {
if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs))
return MatchOperand_Success;
return MatchOperand_NoMatch;
}
// if the first token is not '$' we have an error
if (Parser.getTok().isNot(AsmToken::Dollar))
return MatchOperand_NoMatch;
@ -1321,13 +1379,13 @@ bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
}
bool MipsAsmParser::parseSetNoAtDirective() {
// line should look like:
// Line should look like:
// .set noat
// set at reg to 0
Options.setATReg(0);
// eat noat
Parser.Lex();
// if this is not the end of the statement, report error
// If this is not the end of the statement, report error
if (getLexer().isNot(AsmToken::EndOfStatement)) {
reportParseError("unexpected token in statement");
return false;
@ -1346,12 +1404,12 @@ bool MipsAsmParser::parseSetAtDirective() {
Parser.Lex(); // Consume the EndOfStatement
return false;
} else if (getLexer().is(AsmToken::Equal)) {
getParser().Lex(); //eat '='
getParser().Lex(); // eat '='
if (getLexer().isNot(AsmToken::Dollar)) {
reportParseError("unexpected token in statement");
return false;
}
Parser.Lex(); // eat '$'
Parser.Lex(); // Eat '$'
const AsmToken &Reg = Parser.getTok();
if (Reg.is(AsmToken::Identifier)) {
AtRegNo = matchCPURegisterName(Reg.getIdentifier());
@ -1371,7 +1429,7 @@ bool MipsAsmParser::parseSetAtDirective() {
reportParseError("unexpected token in statement");
return false;
}
getParser().Lex(); //eat reg
getParser().Lex(); // Eat reg
if (getLexer().isNot(AsmToken::EndOfStatement)) {
reportParseError("unexpected token in statement");
@ -1387,7 +1445,7 @@ bool MipsAsmParser::parseSetAtDirective() {
bool MipsAsmParser::parseSetReorderDirective() {
Parser.Lex();
// if this is not the end of the statement, report error
// If this is not the end of the statement, report error
if (getLexer().isNot(AsmToken::EndOfStatement)) {
reportParseError("unexpected token in statement");
return false;
@ -1436,6 +1494,31 @@ bool MipsAsmParser::parseSetNoMacroDirective() {
Parser.Lex(); // Consume the EndOfStatement
return false;
}
bool MipsAsmParser::parseSetAssignment() {
StringRef Name;
const MCExpr *Value;
if (Parser.parseIdentifier(Name))
reportParseError("expected identifier after .set");
if (getLexer().isNot(AsmToken::Comma))
return reportParseError("unexpected token in .set directive");
Lex(); //eat comma
if (Parser.parseExpression(Value))
reportParseError("expected valid expression after comma");
// check if the Name already exists as a symbol
MCSymbol *Sym = getContext().LookupSymbol(Name);
if (Sym) {
return reportParseError("symbol already defined");
}
Sym = getContext().GetOrCreateSymbol(Name);
Sym->setVariableValue(Value);
return false;
}
bool MipsAsmParser::parseDirectiveSet() {
// get next token
@ -1461,6 +1544,10 @@ bool MipsAsmParser::parseDirectiveSet() {
// ignore this directive for now
Parser.eatToEndOfStatement();
return false;
} else {
// it is just an identifier, look for assignment
parseSetAssignment();
return false;
}
return true;

View File

@ -17,3 +17,9 @@ $JTI0_0:
.set macro
.set reorder
.set at=$a0
.set STORE_MASK,$t7
.set FPU_MASK,$f7
#CHECK: abs.s $f6, $f7 # encoding: [0x46,0x00,0x39,0x85]
#CHECK: and $3, $15, $15 # encoding: [0x01,0xef,0x18,0x24]
abs.s $f6,FPU_MASK
and $3,$t7,STORE_MASK