mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[mips] Process numeric register name in the .set assignment directive
Now LLVM assembler cannot process the following code and generates an error. GNU tools support .set assignment directive with numeric register name. ``` .set r4, 4 test.s:1:11: error: invalid token in expression .set r4, $4 ^ ``` This patch teach assembler to handle such directives correctly. Unfortunately a numeric register name cannot be represented as an expression. That's why we have to maintain a separate `StringMap` in the `MipsAsmParser` to keep mapping between aliases names and register numbers. Differential revision: https://reviews.llvm.org/D47464 llvm-svn: 333428
This commit is contained in:
parent
128e26e6c5
commit
5a9ddc59d3
@ -146,6 +146,9 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
/// If true, then CpSaveLocation is a register, otherwise it's an offset.
|
||||
bool CpSaveLocationIsRegister;
|
||||
|
||||
// Map of register aliases created via the .set directive.
|
||||
StringMap<AsmToken> RegisterSets;
|
||||
|
||||
// Print a warning along with its fix-it message at the given range.
|
||||
void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
|
||||
SMRange Range, bool ShowColors = true);
|
||||
@ -183,6 +186,9 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
OperandMatchResultTy
|
||||
matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
||||
StringRef Identifier, SMLoc S);
|
||||
OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
|
||||
const AsmToken &Token,
|
||||
SMLoc S);
|
||||
OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
|
||||
SMLoc S);
|
||||
OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
|
||||
@ -5991,6 +5997,19 @@ bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
|
||||
llvm_unreachable("Should never ParseFail");
|
||||
}
|
||||
}
|
||||
} else if (Sym->isUnset()) {
|
||||
// If symbol is unset, it might be created in the `parseSetAssignment`
|
||||
// routine as an alias for a numeric register name.
|
||||
// Lookup in the aliases list.
|
||||
auto Entry = RegisterSets.find(Sym->getName());
|
||||
if (Entry != RegisterSets.end()) {
|
||||
OperandMatchResultTy ResTy =
|
||||
matchAnyRegisterWithoutDollar(Operands, Entry->getValue(), S);
|
||||
if (ResTy == MatchOperand_Success) {
|
||||
Parser.Lex();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -6060,10 +6079,8 @@ MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
|
||||
}
|
||||
|
||||
OperandMatchResultTy
|
||||
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
auto Token = Parser.getLexer().peekTok(false);
|
||||
|
||||
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands,
|
||||
const AsmToken &Token, SMLoc S) {
|
||||
if (Token.is(AsmToken::Identifier)) {
|
||||
LLVM_DEBUG(dbgs() << ".. identifier\n");
|
||||
StringRef Identifier = Token.getIdentifier();
|
||||
@ -6090,6 +6107,12 @@ MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
|
||||
return MatchOperand_NoMatch;
|
||||
}
|
||||
|
||||
OperandMatchResultTy
|
||||
MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
|
||||
auto Token = getLexer().peekTok(false);
|
||||
return matchAnyRegisterWithoutDollar(Operands, Token, S);
|
||||
}
|
||||
|
||||
OperandMatchResultTy
|
||||
MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
@ -6849,11 +6872,24 @@ bool MipsAsmParser::parseSetAssignment() {
|
||||
return reportParseError("unexpected token, expected comma");
|
||||
Lex(); // Eat comma
|
||||
|
||||
if (Parser.parseExpression(Value))
|
||||
if (getLexer().is(AsmToken::Dollar) &&
|
||||
getLexer().peekTok().is(AsmToken::Integer)) {
|
||||
// Parse assignment of a numeric register:
|
||||
// .set r1,$1
|
||||
Parser.Lex(); // Eat $.
|
||||
RegisterSets[Name] = Parser.getTok();
|
||||
Parser.Lex(); // Eat identifier.
|
||||
getContext().getOrCreateSymbol(Name);
|
||||
} else if (!Parser.parseExpression(Value)) {
|
||||
// Parse assignment of an expression including
|
||||
// symbolic registers:
|
||||
// .set $tmp, $BB0-$BB1
|
||||
// .set r2, $f2
|
||||
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
|
||||
Sym->setVariableValue(Value);
|
||||
} else {
|
||||
return reportParseError("expected valid expression after comma");
|
||||
|
||||
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
|
||||
Sym->setVariableValue(Value);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -52,11 +52,12 @@ $BB0_4:
|
||||
.set FPU_MASK,$f7
|
||||
.set $tmp7, $BB0_4-$BB0_2
|
||||
.set f6,$f6
|
||||
.set r1,$1
|
||||
# CHECK: abs.s $f6, $f7 # encoding: [0x46,0x00,0x39,0x85]
|
||||
# CHECK: lui $1, %hi($tmp7) # encoding: [0x3c,0x01,A,A]
|
||||
# CHECK: # fixup A - offset: 0, value: %hi($tmp7), kind: fixup_Mips_HI16
|
||||
abs.s f6,FPU_MASK
|
||||
lui $1, %hi($tmp7)
|
||||
lui r1, %hi($tmp7)
|
||||
|
||||
# CHECK: .set mips32r2
|
||||
# CHECK: ldxc1 $f0, $zero($5) # encoding: [0x4c,0xa0,0x00,0x01]
|
||||
@ -89,4 +90,4 @@ $BB0_4:
|
||||
# CHECK: balign $5, $6, 3 # encoding: [0x7c,0xc5,0x1c,0x31]
|
||||
.set dspr2
|
||||
append $7, $10, 2
|
||||
balign $5, $6, 3
|
||||
balign $5, $6, 3
|
||||
|
Loading…
Reference in New Issue
Block a user