ARM assembler support for the target-specific .req directive.

rdar://10549683

llvm-svn: 146543
This commit is contained in:
Jim Grosbach 2011-12-14 02:16:11 +00:00
parent 7fae11b231
commit ab5830e51b
2 changed files with 78 additions and 1 deletions

View File

@ -45,6 +45,9 @@ class ARMAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI; MCSubtargetInfo &STI;
MCAsmParser &Parser; MCAsmParser &Parser;
// Map of register aliases registers via the .req directive.
StringMap<unsigned> RegisterReqs;
struct { struct {
ARMCC::CondCodes Cond; // Condition for IT block. ARMCC::CondCodes Cond; // Condition for IT block.
unsigned Mask:4; // Condition mask for instructions. unsigned Mask:4; // Condition mask for instructions.
@ -96,6 +99,8 @@ class ARMAsmParser : public MCTargetAsmParser {
bool parseDirectiveThumbFunc(SMLoc L); bool parseDirectiveThumbFunc(SMLoc L);
bool parseDirectiveCode(SMLoc L); bool parseDirectiveCode(SMLoc L);
bool parseDirectiveSyntax(SMLoc L); bool parseDirectiveSyntax(SMLoc L);
bool parseDirectiveReq(StringRef Name, SMLoc L);
bool parseDirectiveUnreq(SMLoc L);
StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode, StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
bool &CarrySetting, unsigned &ProcessorIMod, bool &CarrySetting, unsigned &ProcessorIMod,
@ -2167,7 +2172,9 @@ static unsigned MatchRegisterName(StringRef Name);
bool ARMAsmParser::ParseRegister(unsigned &RegNo, bool ARMAsmParser::ParseRegister(unsigned &RegNo,
SMLoc &StartLoc, SMLoc &EndLoc) { SMLoc &StartLoc, SMLoc &EndLoc) {
StartLoc = Parser.getTok().getLoc();
RegNo = tryParseRegister(); RegNo = tryParseRegister();
EndLoc = Parser.getTok().getLoc();
return (RegNo == (unsigned)-1); return (RegNo == (unsigned)-1);
} }
@ -2206,7 +2213,16 @@ int ARMAsmParser::tryParseRegister() {
.Case("fp", ARM::R11) .Case("fp", ARM::R11)
.Default(0); .Default(0);
} }
if (!RegNum) return -1; if (!RegNum) {
// Check for aliases registered via .req.
StringMap<unsigned>::const_iterator Entry =
RegisterReqs.find(Tok.getIdentifier());
// If no match, return failure.
if (Entry == RegisterReqs.end())
return -1;
Parser.Lex(); // Eat identifier token.
return Entry->getValue();
}
Parser.Lex(); // Eat identifier token. Parser.Lex(); // Eat identifier token.
@ -4544,6 +4560,15 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
unsigned AvailableFeatures = getAvailableFeatures(); unsigned AvailableFeatures = getAvailableFeatures();
applyMnemonicAliases(Name, AvailableFeatures); applyMnemonicAliases(Name, AvailableFeatures);
// First check for the ARM-specific .req directive.
if (Parser.getTok().is(AsmToken::Identifier) &&
Parser.getTok().getIdentifier() == ".req") {
parseDirectiveReq(Name, NameLoc);
// We always return 'error' for this, as we're done with this
// statement and don't need to match the 'instruction."
return true;
}
// Create the leading tokens for the mnemonic, split by '.' characters. // Create the leading tokens for the mnemonic, split by '.' characters.
size_t Start = 0, Next = Name.find('.'); size_t Start = 0, Next = Name.find('.');
StringRef Mnemonic = Name.slice(Start, Next); StringRef Mnemonic = Name.slice(Start, Next);
@ -5801,6 +5826,8 @@ bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
return parseDirectiveCode(DirectiveID.getLoc()); return parseDirectiveCode(DirectiveID.getLoc());
else if (IDVal == ".syntax") else if (IDVal == ".syntax")
return parseDirectiveSyntax(DirectiveID.getLoc()); return parseDirectiveSyntax(DirectiveID.getLoc());
else if (IDVal == ".unreq")
return parseDirectiveUnreq(DirectiveID.getLoc());
return true; return true;
} }
@ -5941,6 +5968,45 @@ bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
return false; return false;
} }
/// parseDirectiveReq
/// ::= name .req registername
bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
Parser.Lex(); // Eat the '.req' token.
unsigned Reg;
SMLoc SRegLoc, ERegLoc;
if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
Parser.EatToEndOfStatement();
return Error(SRegLoc, "register name expected");
}
// Shouldn't be anything else.
if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
Parser.EatToEndOfStatement();
return Error(Parser.getTok().getLoc(),
"unexpected input in .req directive.");
}
Parser.Lex(); // Consume the EndOfStatement
if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
return Error(SRegLoc, "redefinition of '" + Name +
"' does not match original.");
return false;
}
/// parseDirectiveUneq
/// ::= .unreq registername
bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
if (Parser.getTok().isNot(AsmToken::Identifier)) {
Parser.EatToEndOfStatement();
return Error(L, "unexpected input in .unreq directive.");
}
RegisterReqs.erase(Parser.getTok().getIdentifier());
Parser.Lex(); // Eat the identifier.
return false;
}
extern "C" void LLVMInitializeARMAsmLexer(); extern "C" void LLVMInitializeARMAsmLexer();
/// Force static initialization. /// Force static initialization.

View File

@ -0,0 +1,11 @@
@ RUN: llvm-mc -triple=armv7-apple-darwin -show-encoding < %s | FileCheck %s
.syntax unified
bar:
fred .req r5
mov r11, fred
.unreq fred
fred .req r6
mov r1, fred
@ CHECK: mov r11, r5 @ encoding: [0x05,0xb0,0xa0,0xe1]
@ CHECK: mov r1, r6 @ encoding: [0x06,0x10,0xa0,0xe1]