[llvm-commits] [llvm] r101974 - in /llvm/trunk: lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp lib/Target/ARM/Disassembler/ARMDisassemblerCore.h lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h test/MC/Disassembler/thumb-tests.txt

Johnny Chen johnny.chen at apple.com
Tue Apr 20 18:01:19 PDT 2010


Author: johnny
Date: Tue Apr 20 20:01:19 2010
New Revision: 101974

URL: http://llvm.org/viewvc/llvm-project?rev=101974&view=rev
Log:
Thumb instructions which have reglist operands at the end and predicate operands
before reglist were not properly handled with respect to IT Block.  Fix that by
creating a new method ARMBasicMCBuilder::DoPredicateOperands() used by those
instructions for disassembly.  Add a test case.

Modified:
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
    llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
    llvm/trunk/test/MC/Disassembler/thumb-tests.txt

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp Tue Apr 20 20:01:19 2010
@@ -3218,6 +3218,40 @@
   return CondField;
 }
 
+/// DoPredicateOperands - DoPredicateOperands process the predicate operands
+/// of some Thumb instructions which come before the reglist operands.  It
+/// returns true if the two predicate operands have been processed.
+bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, unsigned Opcode,
+    uint32_t /* insn */, unsigned short NumOpsRemaining) {
+
+  assert(NumOpsRemaining > 0 && "Invalid argument");
+
+  const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+  unsigned Idx = MI.getNumOperands();
+
+  // First, we check whether this instr specifies the PredicateOperand through
+  // a pair of TargetOperandInfos with isPredicate() property.
+  if (NumOpsRemaining >= 2 &&
+      OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() &&
+      OpInfo[Idx].RegClass == 0 && OpInfo[Idx+1].RegClass == ARM::CCRRegClassID)
+  {
+    // If we are inside an IT block, get the IT condition bits maintained via
+    // ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond().
+    // See also A2.5.2.
+    if (InITBlock())
+      MI.addOperand(MCOperand::CreateImm(GetITCond()));
+    else
+      MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
+    MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
+    return true;
+  }
+
+  return false;
+}
+  
+/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
+/// the possible Predicate and SBitModifier, to build the remaining MCOperand
+/// constituents.
 bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
     uint32_t insn, unsigned short NumOpsRemaining) {
 
@@ -3258,10 +3292,11 @@
     MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
     Idx += 2;
     NumOpsRemaining -= 2;
-    if (NumOpsRemaining == 0)
-      return true;
   }
 
+  if (NumOpsRemaining == 0)
+    return true;
+
   // Next, if OptionalDefOperand exists, we check whether the 'S' bit is set.
   if (OpInfo[Idx].isOptionalDef() && OpInfo[Idx].RegClass==ARM::CCRRegClassID) {
     MI.addOperand(MCOperand::CreateReg(getSBit(insn) == 1 ? ARM::CPSR : 0));

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassemblerCore.h Tue Apr 20 20:01:19 2010
@@ -210,6 +210,12 @@
     Err = ErrCode;
   }
 
+  /// DoPredicateOperands - DoPredicateOperands process the predicate operands
+  /// of some Thumb instructions which come before the reglist operands.  It
+  /// returns true if the two predicate operands have been processed.
+  bool DoPredicateOperands(MCInst& MI, unsigned Opcode,
+      uint32_t insn, unsigned short NumOpsRemaning);
+  
   /// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
   /// the possible Predicate and SBitModifier, to build the remaining MCOperand
   /// constituents.

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h Tue Apr 20 20:01:19 2010
@@ -713,13 +713,17 @@
   unsigned &OpIdx = NumOpsAdded;
 
   // Handling the two predicate operands before the reglist.
-  MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
-  MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
-  OpIdx = 2;
+  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+    OpIdx += 2;
+  else {
+    DEBUG(errs() << "Expected predicate operands not found.\n");
+    return false;
+  }
 
-  // Fill the variadic part of reglist.
   unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
     | slice(insn, 7, 0);
+
+  // Fill the variadic part of reglist.
   for (unsigned i = 0; i < 16; ++i) {
     if ((RegListBits >> i) & 1) {
       MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -840,7 +844,6 @@
   unsigned &OpIdx = NumOpsAdded;
 
   unsigned tRt = getT1tRt(insn);
-  unsigned RegListBits = slice(insn, 7, 0);
 
   OpIdx = 0;
 
@@ -856,13 +859,19 @@
   ++OpIdx;
 
   // A8.6.53 LDM / LDMIA / LDMFD - Encoding T1
+  // A8.6.53 STM / STMIA / STMEA - Encoding T1
   MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)));
   ++OpIdx;
 
   // Handling the two predicate operands before the reglist.
-  MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
-  MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
-  OpIdx += 2;
+  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+    OpIdx += 2;
+  else {
+    DEBUG(errs() << "Expected predicate operands not found.\n");
+    return false;
+  }
+
+  unsigned RegListBits = slice(insn, 7, 0);
 
   // Fill the variadic part of reglist.
   for (unsigned i = 0; i < 8; ++i) {
@@ -1137,12 +1146,16 @@
   ++OpIdx;
 
   // Handling the two predicate operands before the reglist.
-  MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
-  MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
-  OpIdx += 2;
+  if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
+    OpIdx += 2;
+  else {
+    DEBUG(errs() << "Expected predicate operands not found.\n");
+    return false;
+  }
 
-  // Fill the variadic part of reglist.
   unsigned RegListBits = insn & ((1 << 16) - 1);
+
+  // Fill the variadic part of reglist.
   for (unsigned i = 0; i < 16; ++i) {
     if ((RegListBits >> i) & 1) {
       MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,

Modified: llvm/trunk/test/MC/Disassembler/thumb-tests.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/thumb-tests.txt?rev=101974&r1=101973&r2=101974&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/thumb-tests.txt (original)
+++ llvm/trunk/test/MC/Disassembler/thumb-tests.txt Tue Apr 20 20:01:19 2010
@@ -85,6 +85,9 @@
 # CHECK:	lsleq	r1, r0, #28
 0x01 0x07
 
-# CHECK:	rsbne	r1, r2, #0
-0x51 0x42
+# CHECK:	stmiane	r0!, {r1, r2, r3}
+0x0e 0xc0
+
 # IT block end
+# CHECK:	rsbs	r1, r2, #0
+0x51 0x42





More information about the llvm-commits mailing list