summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-02-12 01:34:40 +0000
committerJim Grosbach <grosbach@apple.com>2011-02-12 01:34:40 +0000
commitf922c47143d247cbae14b294a0bada139bcd35f6 (patch)
treee6d368b6102e76c60523202176025779c306887b /lib
parentd7401b35e3a4d08e43b4ab81dffd58099a37c90d (diff)
downloadllvm-f922c47143d247cbae14b294a0bada139bcd35f6.tar.gz
llvm-f922c47143d247cbae14b294a0bada139bcd35f6.tar.bz2
llvm-f922c47143d247cbae14b294a0bada139bcd35f6.tar.xz
AsmMatcher custom operand parser failure enhancements.
Teach the AsmMatcher handling to distinguish between an error custom-parsing an operand and a failure to match. The former should propogate the error upwards, while the latter should continue attempting to parse with alternative matchers. Update the ARM asm parser accordingly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125426 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td2
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp49
3 files changed, 32 insertions, 23 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 43e53ad8d4..e018ab53ca 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -152,7 +152,7 @@ def CCOutOperand : AsmOperandClass {
def MemBarrierOptOperand : AsmOperandClass {
let Name = "MemBarrierOpt";
let SuperClasses = [];
- let ParserMethod = "ParseMemBarrierOptOperand";
+ let ParserMethod = "tryParseMemBarrierOptOperand";
}
// ARM Predicate operand. Default to 14 = always (AL). Second part is CC
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 961649b674..2fd25328d3 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -591,13 +591,13 @@ def nohash_imm : Operand<i32> {
def CoprocNumAsmOperand : AsmOperandClass {
let Name = "CoprocNum";
let SuperClasses = [];
- let ParserMethod = "ParseCoprocNumOperand";
+ let ParserMethod = "tryParseCoprocNumOperand";
}
def CoprocRegAsmOperand : AsmOperandClass {
let Name = "CoprocReg";
let SuperClasses = [];
- let ParserMethod = "ParseCoprocRegOperand";
+ let ParserMethod = "tryParseCoprocRegOperand";
}
def p_imm : Operand<i32> {
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 87f77f25ef..089a08c405 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -55,10 +55,7 @@ class ARMAsmParser : public TargetAsmParser {
int TryParseRegister();
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
- bool ParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
- bool ParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
- bool ParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &);
bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
@@ -95,6 +92,13 @@ class ARMAsmParser : public TargetAsmParser {
/// }
+ OperandMatchResultTy tryParseCoprocNumOperand(
+ SmallVectorImpl<MCParsedAsmOperand*>&);
+ OperandMatchResultTy tryParseCoprocRegOperand(
+ SmallVectorImpl<MCParsedAsmOperand*>&);
+ OperandMatchResultTy tryParseMemBarrierOptOperand(
+ SmallVectorImpl<MCParsedAsmOperand*> &);
+
public:
ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
: TargetAsmParser(T), Parser(_Parser), TM(_TM) {
@@ -734,40 +738,40 @@ static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
return -1;
}
-/// ParseCoprocNumOperand - Try to parse an coprocessor number operand. The
+/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
/// token must be an Identifier when called, and if it is a coprocessor
/// number, the token is eaten and the operand is added to the operand list.
-bool ARMAsmParser::
-ParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
if (Num == -1)
- return true;
+ return MatchOperand_NoMatch;
Parser.Lex(); // Eat identifier token.
Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
- return false;
+ return MatchOperand_Success;
}
-/// ParseCoprocRegOperand - Try to parse an coprocessor register operand. The
+/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
/// token must be an Identifier when called, and if it is a coprocessor
/// number, the token is eaten and the operand is added to the operand list.
-bool ARMAsmParser::
-ParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
if (Reg == -1)
- return true;
+ return MatchOperand_NoMatch;
Parser.Lex(); // Eat identifier token.
Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
- return false;
+ return MatchOperand_Success;
}
/// Parse a register list, return it if successful else return null. The first
@@ -854,9 +858,9 @@ ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return false;
}
-/// ParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
-bool ARMAsmParser::
-ParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+tryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
@@ -874,11 +878,11 @@ ParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
.Default(~0U);
if (Opt == ~0U)
- return true;
+ return MatchOperand_NoMatch;
Parser.Lex(); // Eat identifier token.
Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
- return false;
+ return MatchOperand_Success;
}
/// Parse an ARM memory expression, return false if successful else return true
@@ -1105,9 +1109,14 @@ bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
// Check if the current operand has a custom associated parser, if so, try to
// custom parse the operand, or fallback to the general approach.
- MatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
- if (ResTy == Match_Success)
+ OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
+ if (ResTy == MatchOperand_Success)
return false;
+ // If there wasn't a custom match, try the generic matcher below. Otherwise,
+ // there was a match, but an error occurred, in which case, just return that
+ // the operand parsing failed.
+ if (ResTy == MatchOperand_ParseFail)
+ return true;
switch (getLexer().getKind()) {
default: