From: Jim Grosbach Date: Wed, 6 Feb 2013 06:00:06 +0000 (+0000) Subject: Allow targets to add custom asm operand matching logic. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=86c652a6b23556afd7e830eba2e6f099ed15aa5e;p=platform%2Fupstream%2Fllvm.git Allow targets to add custom asm operand matching logic. For example, ARM has several instructions with a literal '#0' immediate in the syntax that's not represented as an actual operand. The asm matcher is expected a token operand, but the parser will have created an immediate operand. This is currently handled by dedicated per-instruction C++ munging of the ParsedAsmOperand list, but will be better handled by this hook. llvm-svn: 174487 --- diff --git a/llvm/include/llvm/MC/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCTargetAsmParser.h index 483a80b..84585d6 100644 --- a/llvm/include/llvm/MC/MCTargetAsmParser.h +++ b/llvm/include/llvm/MC/MCTargetAsmParser.h @@ -142,6 +142,15 @@ public: MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm) = 0; + /// Allow a target to add special case operand matching for things that + /// tblgen doesn't/can't handle effectively. For example, literal + /// immediates on ARM. TableGen expects a token operand, but the parser + /// will recognize them as immediates. + virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, + unsigned Kind) { + return Match_InvalidOperand; + } + /// checkTargetMatchPredicate - Validate the instruction match against /// any complex target predicates not expressible via match classes. virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 6d62d6b..6faf819 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -2878,6 +2878,15 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "(MatchClassKind)it->Classes[i]);\n"; OS << " if (Diag == Match_Success)\n"; OS << " continue;\n"; + OS << " // If the generic handler indicates an invalid operand\n"; + OS << " // failure, check for a special case.\n"; + OS << " if (Diag == Match_InvalidOperand) {\n"; + OS << " Diag = validateTargetOperandClass(Operands[i+1],\n"; + OS.indent(43); + OS << "(MatchClassKind)it->Classes[i]);\n"; + OS << " if (Diag == Match_Success)\n"; + OS << " continue;\n"; + OS << " }\n"; OS << " // If this operand is broken for all of the instances of this\n"; OS << " // mnemonic, keep track of it so we can report loc info.\n"; OS << " // If we already had a match that only failed due to a\n";