summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2011-01-11 15:59:53 +0000
committerDaniel Dunbar <daniel@zuster.org>2011-01-11 15:59:53 +0000
commit5a384c86b278588647a26615b3ecfdb0c0b117fd (patch)
tree3509e61449960a9838ffef30f9fca5e95802f14b /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parent9d944b3fcc724746a741c3130a6a2c80c8b8dcbe (diff)
downloadbcm5719-llvm-5a384c86b278588647a26615b3ecfdb0c0b117fd.tar.gz
bcm5719-llvm-5a384c86b278588647a26615b3ecfdb0c0b117fd.zip
McARM: Sketch some logic for determining when to add carry set and predication code operands based on the "canonical mnemonic".
llvm-svn: 123239
Diffstat (limited to 'llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp52
1 files changed, 48 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 3e35c347034..5346106c58a 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/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.
OpenPOWER on IntegriCloud