[llvm-commits] [llvm] r121401 - in /llvm/trunk: lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/arm_instructions.s

Kevin Enderby enderby at apple.com
Thu Dec 9 11:19:43 PST 2010


Author: enderby
Date: Thu Dec  9 13:19:43 2010
New Revision: 121401

URL: http://llvm.org/viewvc/llvm-project?rev=121401&view=rev
Log:
Add support for parsing ARM arithmetic instructions that update or don't update
the condition codes.  Where the ones that do have an 's' suffix and the ones
that don't don't have the suffix.  The trick is if MatchInstructionImpl() fails
we try again after adding a CCOut operand with the correct value and removing
the 's' if present.  Four simple test cases added for now, lots more to come.

Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/arm_instructions.s

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=121401&r1=121400&r2=121401&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Dec  9 13:19:43 2010
@@ -874,11 +874,6 @@
   // FIXME: We need a way to check whether a prefix supports predication,
   // otherwise we will end up with an ambiguity for instructions that happen to
   // end with a predicate name.
-  // FIXME: Likewise, some arithmetic instructions have an 's' prefix which
-  // indicates to update the condition codes. Those instructions have an
-  // additional immediate operand which encodes the prefix as reg0 or CPSR.
-  // Just checking for a suffix of 's' definitely creates ambiguities; e.g,
-  // the SMMLS instruction.
   unsigned CC = StringSwitch<unsigned>(Head.substr(Head.size()-2))
     .Case("eq", ARMCC::EQ)
     .Case("ne", ARMCC::NE)
@@ -954,7 +949,51 @@
                         MCStreamer &Out) {
   MCInst Inst;
   unsigned ErrorInfo;
-  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) {
+  MatchResultTy MatchResult, MatchResult2;
+  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
+  if (MatchResult != Match_Success) {
+    // If we get a Match_InvalidOperand it might be some arithmetic instruction
+    // that does not update the condition codes.  So try adding a CCOut operand
+    // with a value of reg0.
+    if (MatchResult == Match_InvalidOperand) {
+      Operands.insert(Operands.begin() + 1,
+                      ARMOperand::CreateCCOut(0,
+                                  ((ARMOperand*)Operands[0])->getStartLoc()));
+      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
+      if (MatchResult2 == Match_Success)
+        MatchResult = Match_Success;
+      else
+        Operands.erase(Operands.begin() + 1);
+    }
+    // If we get a Match_MnemonicFail it might be some arithmetic instruction
+    // that updates the condition codes if it ends in 's'.  So see if the
+    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
+    // operand with a value of CPSR.
+    else if(MatchResult == Match_MnemonicFail) {
+      // Get the instruction mnemonic, which is the first token.
+      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
+      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
+        // removed the 's' from the mnemonic for matching.
+        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
+        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
+	Operands.erase(Operands.begin());
+	Operands.insert(Operands.begin(),
+                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
+        Operands.insert(Operands.begin() + 1,
+                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
+        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
+        if (MatchResult2 == Match_Success)
+          MatchResult = Match_Success;
+        else {
+	  Operands.erase(Operands.begin());
+	  Operands.insert(Operands.begin(),
+                          ARMOperand::CreateToken(Mnemonic, NameLoc));
+	  Operands.erase(Operands.begin() + 1);
+        }
+      }
+    }
+  }
+  switch (MatchResult) {
   case Match_Success:
     Out.EmitInstruction(Inst);
     return false;

Modified: llvm/trunk/test/MC/ARM/arm_instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_instructions.s?rev=121401&r1=121400&r2=121401&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm_instructions.s (original)
+++ llvm/trunk/test/MC/ARM/arm_instructions.s Thu Dec  9 13:19:43 2010
@@ -55,3 +55,12 @@
         stmib     r2!, {r1,r3-r6,sp}
         stmda     r2!, {r1,r3-r6,sp}
         stmdb     r2!, {r1,r3-r6,sp}
+
+@ CHECK: and r1, r2, r3 @ encoding: [0x03,0x10,0x02,0xe0]
+        and r1, r2, r3
+@ CHECK: ands r1, r2, r3 @ encoding: [0x03,0x10,0x12,0xe0]
+        ands r1, r2, r3
+@ CHECK: eor r1, r2, r3 @ encoding: [0x03,0x10,0x22,0xe0]
+        eor r1, r2, r3
+@ CHECK: eors r1, r2, r3 @ encoding: [0x03,0x10,0x32,0xe0]
+        eors r1, r2, r3





More information about the llvm-commits mailing list