diff options
author | Jim Grosbach <grosbach@apple.com> | 2013-02-06 06:00:11 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2013-02-06 06:00:11 +0000 |
commit | 5bc79cc4e833fea68f15780f191cbf4881679646 (patch) | |
tree | 5526ce41129a25a34ec2e7138f3b6e482c25d4f9 /lib/Target/ARM/AsmParser | |
parent | fa05def52c6bb8266d856a9af2de6fa066d93d44 (diff) | |
download | external_llvm-5bc79cc4e833fea68f15780f191cbf4881679646.zip external_llvm-5bc79cc4e833fea68f15780f191cbf4881679646.tar.gz external_llvm-5bc79cc4e833fea68f15780f191cbf4881679646.tar.bz2 |
ARM: Use MCTargetAsmParser::validateTargetOperandClass().
Use the validateTargetOperandClass() hook to match literal '#0' operands in
InstAlias definitions. Previously this required per-instruction C++ munging of the
operand list, but not is handled as a natural part of the matcher. Much better.
No additional tests are required, as the pre-existing tests for these instructions
exercise the new behaviour as being functionally equivalent to the old.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174488 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 66 |
1 files changed, 19 insertions, 47 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 106fd13..3174e9a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -269,6 +269,7 @@ public: SmallVectorImpl<MCParsedAsmOperand*> &Operands); bool ParseDirective(AsmToken DirectiveID); + unsigned validateTargetOperandClass(MCParsedAsmOperand *Op, unsigned Kind); unsigned checkTargetMatchPredicate(MCInst &Inst); bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, @@ -5158,53 +5159,6 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, delete Op; } - // The vector-compare-to-zero instructions have a literal token "#0" at - // the end that comes to here as an immediate operand. Convert it to a - // token to play nicely with the matcher. - if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" || - Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 && - static_cast<ARMOperand*>(Operands[5])->isImm()) { - ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); - const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); - if (CE && CE->getValue() == 0) { - Operands.erase(Operands.begin() + 5); - Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); - delete Op; - } - } - // VCMP{E} does the same thing, but with a different operand count. - if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 && - static_cast<ARMOperand*>(Operands[4])->isImm()) { - ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]); - const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); - if (CE && CE->getValue() == 0) { - Operands.erase(Operands.begin() + 4); - Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); - delete Op; - } - } - // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the - // end. Convert it to a token here. Take care not to convert those - // that should hit the Thumb2 encoding. - if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 && - static_cast<ARMOperand*>(Operands[3])->isReg() && - static_cast<ARMOperand*>(Operands[4])->isReg() && - static_cast<ARMOperand*>(Operands[5])->isImm()) { - ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]); - const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); - if (CE && CE->getValue() == 0 && - (isThumbOne() || - // The cc_out operand matches the IT block. - ((inITBlock() != CarrySetting) && - // Neither register operand is a high register. - (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) && - isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){ - Operands.erase(Operands.begin() + 5); - Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc())); - delete Op; - } - } - // Adjust operands of ldrexd/strexd to MCK_GPRPair. // ldrexd/strexd require even/odd GPR pair. To enforce this constraint, // a single GPRPair reg operand is used in the .td file to replace the two @@ -7857,3 +7811,21 @@ extern "C" void LLVMInitializeARMAsmParser() { #define GET_SUBTARGET_FEATURE_NAME #define GET_MATCHER_IMPLEMENTATION #include "ARMGenAsmMatcher.inc" + +// Define this matcher function after the auto-generated include so we +// have the match class enum definitions. +unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand *AsmOp, + unsigned Kind) { + ARMOperand *Op = static_cast<ARMOperand*>(AsmOp); + // If the kind is a token for a literal immediate, check if our asm + // operand matches. This is for InstAliases which have a fixed-value + // immediate in the syntax. + if (Kind == MCK__35_0 && Op->isImm()) { + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm()); + if (!CE) + return Match_InvalidOperand; + if (CE->getValue() == 0) + return Match_Success; + } + return Match_InvalidOperand; +} |