From 3771dd041f6a68bef08b6f685a41d1d54f4e8b9d Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 11 Jan 2011 15:59:53 +0000 Subject: [PATCH] McARM: Sketch some logic for determining when to add carry set and predication code operands based on the "canonical mnemonic". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123239 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 52 +++++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 3e35c347034..5346106c58a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -930,6 +930,20 @@ static StringRef SplitMnemonicAndCC(StringRef Mnemonic, return Mnemonic; } + +/// \brief Given a canonical mnemonic, determine if the instruction ever allows +/// inclusion of carry set or predication code operands. +// +// FIXME: It would be nice to autogen this. +static void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, + bool &CanAcceptPredicationCode) { + CanAcceptCarrySet = false; + + if (Mnemonic == "trap") { + CanAcceptPredicationCode = false; + } else { + CanAcceptPredicationCode = true; + } } /// Parse an arm instruction mnemonic followed by its operands. @@ -946,10 +960,40 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, Operands.push_back(ARMOperand::CreateToken(Head, NameLoc)); - // FIXME: Should only add this operand for predicated instructions - if (Head != "trap") { - Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), - NameLoc)); + // Next, add the CCOut and ConditionCode operands, if needed. + // + // For mnemonics which can ever incorporate a carry setting bit or predication + // code, our matching model involves us always generating CCOut and + // ConditionCode operands to match the mnemonic "as written" and then we let + // the matcher deal with finding the right instruction or generating an + // appropriate error. + bool CanAcceptCarrySet, CanAcceptPredicationCode; + GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); + + // Add the carry setting operand, if necessary. + // + // FIXME: It would be awesome if we could somehow invent a location such that + // match errors on this operand would print a nice diagnostic about how the + // 's' character in the mnemonic resulted in a CCOut operand. + if (CanAcceptCarrySet) { + Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, + NameLoc)); + } else { + // This mnemonic can't ever accept a carry set, but the user wrote one (or + // misspelled another mnemonic). + + // FIXME: Issue a nice error. + } + + // Add the predication code operand, if necessary. + if (CanAcceptPredicationCode) { + Operands.push_back(ARMOperand::CreateCondCode( + ARMCC::CondCodes(PredicationCode), NameLoc)); + } else { + // This mnemonic can't ever accept a predication code, but the user wrote + // one (or misspelled another mnemonic). + + // FIXME: Issue a nice error. } // Add the remaining tokens in the mnemonic.