Fix issues with disassembly of IT instructions involving condition codes other the...
authorOwen Anderson <resistor@mac.com>
Tue, 30 Aug 2011 22:58:27 +0000 (22:58 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 30 Aug 2011 22:58:27 +0000 (22:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138840 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
test/MC/Disassembler/ARM/thumb2.txt

index a7652f670a908f5868d8c6450359d99c70d2bd4a..e82e32186dde294039ec2b5450cfa7dc5be5596f 100644 (file)
@@ -19,7 +19,6 @@ def it_pred_asmoperand : AsmOperandClass {
 def it_pred : Operand<i32> {
   let PrintMethod = "printMandatoryPredicateOperand";
   let ParserMatchClass = it_pred_asmoperand;
-  let DecoderMethod = "DecodeITCond";
 }
 
 // IT block condition mask
@@ -27,7 +26,6 @@ def it_mask_asmoperand : AsmOperandClass { let Name = "ITMask"; }
 def it_mask : Operand<i32> {
   let PrintMethod = "printThumbITMask";
   let ParserMatchClass = it_mask_asmoperand;
-  let DecoderMethod = "DecodeITMask";
 }
 
 // Shifted operands. No register controlled shifts for Thumb2.
@@ -3013,6 +3011,8 @@ def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
   bits<4> mask;
   let Inst{7-4} = cc;
   let Inst{3-0} = mask;
+
+  let DecoderMethod = "DecodeIT";
 }
 
 // Branch and Exchange Jazelle -- for disassembly only
index c3ad2907c94a2c0983f26faeb1c4d1c611d8fb93..f4ca9ecc5d66010887e7ee05ddb54f6b07cc4e3a 100644 (file)
@@ -230,9 +230,7 @@ static DecodeStatus DecodeThumbBCCTargetOperand(llvm::MCInst &Inst,unsigned Val,
                                 uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
                                 uint64_t Address, const void *Decoder);
-static DecodeStatus DecodeITCond(llvm::MCInst &Inst, unsigned Val,
-                                uint64_t Address, const void *Decoder);
-static DecodeStatus DecodeITMask(llvm::MCInst &Inst, unsigned Val,
+static DecodeStatus DecodeIT(llvm::MCInst &Inst, unsigned Val,
                                 uint64_t Address, const void *Decoder);
 
 #include "ARMGenDisassemblerTables.inc"
@@ -480,18 +478,20 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
     // code and mask operands so that we can apply them correctly
     // to the subsequent instructions.
     if (MI.getOpcode() == ARM::t2IT) {
+      // (3 - the number of trailing zeros) is the number of then / else.
       unsigned firstcond = MI.getOperand(0).getImm();
-      uint32_t mask = MI.getOperand(1).getImm();
-      unsigned zeros = CountTrailingZeros_32(mask);
-      mask >>= zeros+1;
-
-      for (unsigned i = 0; i < 4 - (zeros+1); ++i) {
-        if (firstcond ^ (mask & 1))
-          ITBlock.push_back(firstcond ^ 1);
+      unsigned Mask = MI.getOperand(1).getImm();
+      unsigned CondBit0 = Mask >> 4 & 1;
+      unsigned NumTZ = CountTrailingZeros_32(Mask);
+      assert(NumTZ <= 3 && "Invalid IT mask!");
+      for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
+        bool T = ((Mask >> Pos) & 1) == CondBit0;
+        if (T)
+          ITBlock.insert(ITBlock.begin(), firstcond);
         else
-          ITBlock.push_back(firstcond);
-        mask >>= 1;
+          ITBlock.insert(ITBlock.begin(), firstcond ^ 1);
       }
+
       ITBlock.push_back(firstcond);
     }
 
@@ -3109,7 +3109,7 @@ static DecodeStatus DecodeVLD3LN(llvm::MCInst &Inst, unsigned Insn,
   }
   CHECK(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder));
   Inst.addOperand(MCOperand::CreateImm(align));
-  if (Rm != 0xF) { 
+  if (Rm != 0xF) {
     if (Rm != 0xD)
       CHECK(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder));
     else
@@ -3345,26 +3345,28 @@ static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn,
   return S;
 }
 
-static DecodeStatus DecodeITCond(llvm::MCInst &Inst, unsigned Cond,
-                                 uint64_t Address, const void *Decoder) {
+static DecodeStatus DecodeIT(llvm::MCInst &Inst, unsigned Insn,
+                             uint64_t Address, const void *Decoder) {
   DecodeStatus S = Success;
-  if (Cond == 0xF) {
-    Cond = 0xE;
+  unsigned pred = fieldFromInstruction16(Insn, 4, 4);
+  // The InstPrinter needs to have the low bit of the predicate in
+  // the mask operand to be able to print it properly.
+  unsigned mask = fieldFromInstruction16(Insn, 0, 5);
+
+  if (pred == 0xF) {
+    pred = 0xE;
     CHECK(S, Unpredictable);
   }
 
-  Inst.addOperand(MCOperand::CreateImm(Cond));
-  return S;
-}
-
-static DecodeStatus DecodeITMask(llvm::MCInst &Inst, unsigned Mask,
-                                 uint64_t Address, const void *Decoder) {
-  DecodeStatus S = Success;
-  if (Mask == 0) {
-    Mask = 0x8;
+  if ((mask & 0xF) == 0) {
+    // Preserve the high bit of the mask, which is the low bit of
+    // the predicate.
+    mask &= 0x10;
+    mask |= 0x8;
     CHECK(S, Unpredictable);
   }
-  Inst.addOperand(MCOperand::CreateImm(Mask));
+
+  Inst.addOperand(MCOperand::CreateImm(pred));
+  Inst.addOperand(MCOperand::CreateImm(mask));
   return S;
 }
-
index 11171d83ef0869e253aa44eac5943e71be3153e3..c53910b4fc857eebeb554157dc989444e773166a 100644 (file)
 0x00 0xbf
 0xf5 0x1b
 0x11 0x1d
+
+# CHECK: ittee ls
+# CHECK: addls r0, r1, r2
+# CHECK: nopls
+# CHECK: subhi r5, r6, r7
+# CHECK: addhi r1, r2, #4
+
+0x99 0xbf
+0x88 0x18
+0x00 0xbf
+0xf5 0x1b
+0x11 0x1d