Fix broken encodings for the Thumb2 LDRD/STRD instructions.
authorOwen Anderson <resistor@mac.com>
Thu, 4 Aug 2011 23:18:05 +0000 (23:18 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 4 Aug 2011 23:18:05 +0000 (23:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136942 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h

index c3d9e39dfa64dde538c64bee23e6d9952c3b5cc4..97e807ccc228a1aa844e41e6c988fd0cf0724944 100644 (file)
@@ -1151,6 +1151,27 @@ class T2Ii8s4<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
   let Inst{7-0}   = addr{7-0};
 }
 
+class T2Ii8s4Tied<bit P, bit W, bit isLoad, dag oops, dag iops, InstrItinClass itin,
+              string opc, string asm, list<dag> pattern>
+  : Thumb2I<oops, iops, AddrModeT2_i8s4, 4, itin, opc, asm, "$base = $wb",
+            pattern> {
+  bits<4> Rt;
+  bits<4> Rt2;
+  bits<4> base;
+  bits<9> imm;
+  let Inst{31-25} = 0b1110100;
+  let Inst{24}    = P;
+  let Inst{23}    = imm{8};
+  let Inst{22}    = 1;
+  let Inst{21}    = W;
+  let Inst{20}    = isLoad;
+  let Inst{19-16} = base{3-0};
+  let Inst{15-12} = Rt{3-0};
+  let Inst{11-8}  = Rt2{3-0};
+  let Inst{7-0}   = imm{7-0};
+}
+
+
 class T2sI<dag oops, dag iops, InstrItinClass itin,
            string opc, string asm, list<dag> pattern>
   : Thumb2sI<oops, iops, AddrModeNone, 4, itin, opc, asm, "", pattern>;
index b53ca16c18c68a7281f10f93924b0116f25bdccb..873c3d6426abd8d356f7348338b5f7696b5da55f 100644 (file)
@@ -141,6 +141,7 @@ def t2addrmode_imm8s4 : Operand<i32> {
 
 def t2am_imm8s4_offset : Operand<i32> {
   let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
+  let DecoderMethod = "DecodeT2Imm8S4";
 }
 
 // t2addrmode_so_reg  := reg + (reg << imm2)
@@ -1354,19 +1355,21 @@ def t2STRHT  : T2IstT<0b01, "strht", IIC_iStore_bh_i>;
 // ldrd / strd pre / post variants
 // For disassembly only.
 
-def t2LDRD_PRE  : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2),
+def t2LDRD_PRE  : T2Ii8s4Tied<1, 1, 1,
+                 (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb),
                  (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
                  "ldrd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
 
-def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2),
+def t2LDRD_POST : T2Ii8s4Tied<0, 1, 1,
+                 (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb),
                  (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru,
                  "ldrd", "\t$Rt, $Rt2, [$base], $imm", []>;
 
-def t2STRD_PRE  : T2Ii8s4<1, 1, 0, (outs),
+def t2STRD_PRE  : T2Ii8s4Tied<1, 1, 0, (outs GPR:$wb),
                  (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
                  IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base, $imm]!", []>;
 
-def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
+def t2STRD_POST : T2Ii8s4Tied<0, 1, 0, (outs GPR:$wb),
                  (ins rGPR:$Rt, rGPR:$Rt2, GPR:$base, t2am_imm8s4_offset:$imm),
                  IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, [$base], $imm", []>;
 
index 66a62ef5a56bffe2e5585af22ef6467289a3ebb2..a1b38f377ad0d880708403b866dba20aeb6eeae9 100644 (file)
@@ -1318,13 +1318,6 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
   const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
   if (!OpInfo) return false;
 
-  assert(NumOps >= 4
-         && OpInfo[0].RegClass > 0
-         && OpInfo[0].RegClass == OpInfo[1].RegClass
-         && OpInfo[2].RegClass > 0
-         && OpInfo[3].RegClass < 0
-         && "Expect >= 4 operands and first 3 as reg operands");
-
   // Thumnb allows for specifying Rt and Rt2, unlike ARM (which has Rt2==Rt+1).
   unsigned Rt  = decodeRd(insn);
   unsigned Rt2 = decodeRs(insn);
@@ -1357,20 +1350,32 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
   // Add the <Rt> <Rt2> operands.
   unsigned RegClassPair = OpInfo[0].RegClass;
   unsigned RegClassBase = OpInfo[2].RegClass;
-  
+
   MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRd(insn))));
   MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
                                                      decodeRs(insn))));
   MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
                                                      decodeRn(insn))));
+  unsigned Added = 4;
+  switch (MI.getOpcode()) {
+    case ARM::t2LDRD_PRE:
+    case ARM::t2LDRD_POST:
+    case ARM::t2STRD_PRE:
+    case ARM::t2STRD_POST:
+      MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
+                                                         decodeRn(insn))));
+      Added = 5;
+    default:
+      break;
+  }
 
   // Finally add (+/-)imm8*4, depending on the U bit.
   int Offset = getImm8(insn) * 4;
   if (getUBit(insn) == 0)
     Offset = -Offset;
   MI.addOperand(MCOperand::CreateImm(Offset));
-  NumOpsAdded = 4;
+  NumOpsAdded = Added;
 
   return true;
 }