forked from OSchip/llvm-project
ARM assembler support for the target-specific .req directive.
rdar://10549683 llvm-svn: 146543
This commit is contained in:
parent
7fae11b231
commit
ab5830e51b
|
@ -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.
|
||||||
|
|
|
@ -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]
|
Loading…
Reference in New Issue