Second attempt at converting Thumb2's LDRpci, including updating the gazillion places...
authorOwen Anderson <resistor@mac.com>
Tue, 7 Dec 2010 00:45:21 +0000 (00:45 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 7 Dec 2010 00:45:21 +0000 (00:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121082 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMConstantIslandPass.cpp
lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/ARMMCCodeEmitter.cpp
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/Thumb2SizeReduction.cpp
test/MC/Disassembler/ARM/thumb-tests.txt

index 3c2540856478b62591643f7215c42f3262332fb8..dee50f685c164a4589439dc9c44acfb2980244fc 100644 (file)
@@ -605,7 +605,11 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &MF,
 
           case ARM::LDRi12:
           case ARM::LDRcp:
-          case ARM::t2LDRpci:
+          case ARM::t2LDRi12:
+          case ARM::t2LDRHi12:
+          case ARM::t2LDRBi12:
+          case ARM::t2LDRSHi12:
+          case ARM::t2LDRSBi12:
             Bits = 12;  // +-offset_12
             NegOk = true;
             break;
index 1c02c34e82666d7b814be0350ad0eea66d1517df..ca7a90aa12f3a55b3ac5fb58ac51029331d03b67 100644 (file)
@@ -699,16 +699,48 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
       MI.eraseFromParent();
       break;
     }
+    case ARM::t2LDRHpci:
+    case ARM::t2LDRBpci:
+    case ARM::t2LDRSHpci:
+    case ARM::t2LDRSBpci:
+    case ARM::t2LDRpci: {
+      unsigned NewLdOpc;
+      if (Opcode == ARM::t2LDRpci)
+        NewLdOpc = ARM::t2LDRi12;
+      else if (Opcode == ARM::t2LDRHpci)
+        NewLdOpc = ARM::t2LDRHi12;
+      else if (Opcode == ARM::t2LDRBpci)
+        NewLdOpc = ARM::t2LDRBi12;
+      else if (Opcode == ARM::t2LDRSHpci)
+        NewLdOpc = ARM::t2LDRSHi12;
+      else if (Opcode == ARM::t2LDRSBpci)
+        NewLdOpc = ARM::t2LDRSBi12;
+      else
+        llvm_unreachable("Not a known opcode?");
+
+      unsigned DstReg = MI.getOperand(0).getReg();
+      MachineInstrBuilder MIB =
+        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
+                               TII->get(NewLdOpc), DstReg)
+                .addReg(ARM::PC)
+                .addOperand(MI.getOperand(1)));
+      (*MIB).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
+      TransferImpOps(MI, MIB, MIB);
+      MI.eraseFromParent();
+      break;
+    }
     case ARM::tLDRpci_pic:
     case ARM::t2LDRpci_pic: {
       unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
-        ? ARM::tLDRpci : ARM::t2LDRpci;
+        ? ARM::tLDRpci : ARM::t2LDRi12;
       unsigned DstReg = MI.getOperand(0).getReg();
       bool DstIsDead = MI.getOperand(0).isDead();
       MachineInstrBuilder MIB1 =
-        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
-                               TII->get(NewLdOpc), DstReg)
-                       .addOperand(MI.getOperand(1)));
+        BuildMI(MBB, MBBI, MI.getDebugLoc(),
+        TII->get(NewLdOpc), DstReg);
+      if (Opcode == ARM::t2LDRpci_pic) MIB1.addReg(ARM::PC);
+      MIB1.addOperand(MI.getOperand(1));
+      AddDefaultPred(MIB1);
       (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
       MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
                                          TII->get(ARM::tPICADD))
index 0adcba02d3bc8a7ea494e6ee94b7a69253b4bac8..98b7d067129986cb04aba7f96fd1b66d666a3695 100644 (file)
@@ -888,24 +888,8 @@ multiclass T2I_ld<bit signed, bits<2> opcod, string opc,
     let Inst{5-4}   = addr{1-0}; // imm
   }
 
-  // FIXME: Is the pci variant actually needed?
-  def pci : T2Ipc <(outs GPR:$Rt), (ins i32imm:$addr), iii,
-                   opc, ".w\t$Rt, $addr",
-                   [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> {
-    let isReMaterializable = 1;
-    let Inst{31-27} = 0b11111;
-    let Inst{26-25} = 0b00;
-    let Inst{24} = signed;
-    let Inst{23} = ?; // add = (U == '1')
-    let Inst{22-21} = opcod;
-    let Inst{20} = 1; // load
-    let Inst{19-16} = 0b1111; // Rn
-
-    bits<4> Rt;
-    bits<12> addr;
-    let Inst{15-12} = Rt{3-0};
-    let Inst{11-0}  = addr{11-0};
-  }
+  def pci : tPseudoInst<(outs GPR:$Rt), (ins i32imm:$addr), Size4Bytes, iis,
+                      [(set GPR:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]>;
 }
 
 /// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
index b8939a1531c3a4b41cfaf5a15ede74f86fb6556c..b0113476fa8f7cc4df227bca8d938c67945876c6 100644 (file)
@@ -462,13 +462,18 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
   bool isAdd = true;
   // If The first operand isn't a register, we have a label reference.
   const MCOperand &MO = MI.getOperand(OpIdx);
-  if (!MO.isReg()) {
+  const MCOperand &MO2 = MI.getOperand(OpIdx+1);
+  if (!MO.isReg() || (MO.getReg() == ARM::PC && MO2.isExpr())) {
     Reg = getARMRegisterNumbering(ARM::PC);   // Rn is PC.
     Imm12 = 0;
     isAdd = false ; // 'U' bit is set as part of the fixup.
 
-    assert(MO.isExpr() && "Unexpected machine operand type!");
-    const MCExpr *Expr = MO.getExpr();
+    const MCExpr *Expr = 0;
+    if (!MO.isReg())
+      Expr = MO.getExpr();
+    else
+      Expr = MO2.getExpr();
+    
     MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
     Fixups.push_back(MCFixup::Create(0, Expr, Kind));
 
index c3d24d2d70ec1fd8a1b055cb781a92775da4676d..4964c642424fd7e97693fb3b463d3e92649cb942 100644 (file)
@@ -256,27 +256,27 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) {
   case ARM::t2LDR_POST:   case ARM::t2LDR_PRE:
   case ARM::t2LDRi12:     case ARM::t2LDRi8:
   case ARM::t2LDRs:       case ARM::t2LDRT:
-    return ARM::t2LDRpci;
+    return ARM::t2LDRi12;
 
   case ARM::t2LDRB_POST:  case ARM::t2LDRB_PRE:
   case ARM::t2LDRBi12:    case ARM::t2LDRBi8:
   case ARM::t2LDRBs:      case ARM::t2LDRBT:
-    return ARM::t2LDRBpci;
+    return ARM::t2LDRBi12;
 
   case ARM::t2LDRH_POST:  case ARM::t2LDRH_PRE:
   case ARM::t2LDRHi12:    case ARM::t2LDRHi8:
   case ARM::t2LDRHs:      case ARM::t2LDRHT:
-    return ARM::t2LDRHpci;
+    return ARM::t2LDRHi12;
 
   case ARM::t2LDRSB_POST:  case ARM::t2LDRSB_PRE:
   case ARM::t2LDRSBi12:    case ARM::t2LDRSBi8:
   case ARM::t2LDRSBs:      case ARM::t2LDRSBT:
-    return ARM::t2LDRSBpci;
+    return ARM::t2LDRSBi12;
 
   case ARM::t2LDRSH_POST:  case ARM::t2LDRSH_PRE:
   case ARM::t2LDRSHi12:    case ARM::t2LDRSHi8:
   case ARM::t2LDRSHs:      case ARM::t2LDRSHT:
-    return ARM::t2LDRSHpci;
+    return ARM::t2LDRSHi12;
   }
 }
 
index 2c8345c1d411845744346bded6aff01d7b830c02..0418543f83fd3f3012c98efe64d69b8e0bb337d3 100644 (file)
@@ -1777,37 +1777,6 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
   return true;
 }
 
-// A8.6.63 LDRB (literal)
-// A8.6.79 LDRSB (literal)
-// A8.6.75 LDRH (literal)
-// A8.6.83 LDRSH (literal)
-// A8.6.59 LDR (literal)
-//
-// These instrs calculate an address from the PC value and an immediate offset.
-// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
-static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
-    uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
-
-  const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
-  if (!OpInfo) return false;
-
-  assert(NumOps >= 2 &&
-         OpInfo[0].RegClass == ARM::GPRRegClassID &&
-         OpInfo[1].RegClass < 0 &&
-         "Expect >= 2 operands, first as reg, and second as imm operand");
-
-  // Build the register operand, followed by the (+/-)imm12 immediate.
-
-  MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
-                                                     decodeRd(insn))));
-
-  MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
-
-  NumOpsAdded = 2;
-
-  return true;
-}
-
 // A6.3.10 Store single data item
 // A6.3.9 Load byte, memory hints
 // A6.3.8 Load halfword, memory hints
@@ -1843,10 +1812,6 @@ static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
   if (Thumb2PreloadOpcode(Opcode))
     return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
 
-  // See, for example, A6.3.7 Load word: Table A6-18 Load word.
-  if (Load && Rn == 15)
-    return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
-
   const TargetInstrDesc &TID = ARMInsts[Opcode];
   const TargetOperandInfo *OpInfo = TID.OpInfo;
   unsigned &OpIdx = NumOpsAdded;
index 42f94ee5e3481b32ce6022401449ca407e7ccff2..4f401b9a8f5cdfd588c89161306f14021a7f518e 100644 (file)
@@ -560,6 +560,9 @@ void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
     printOperand(MI, OpNum, O);
     return;
+  } else if (MO1.getReg() == ARM::PC && MO2.isExpr()) {
+    printOperand(MI, OpNum+1, O);
+    return;
   }
 
   O << "[" << getRegisterName(MO1.getReg());
index a44ac07cd67d4142ae5528764d4569c8b7582b0c..68a781c18078fccfb189a8568f6196eb076e8086 100644 (file)
@@ -236,7 +236,7 @@ static bool VerifyLowRegs(MachineInstr *MI) {
   unsigned Opc = MI->getOpcode();
   bool isPCOk = (Opc == ARM::t2LDMIA_RET || Opc == ARM::t2LDMIA     ||
                  Opc == ARM::t2LDMDB     || Opc == ARM::t2LDMIA_UPD ||
-                 Opc == ARM::t2LDMDB_UPD);
+                 Opc == ARM::t2LDMDB_UPD || Opc == ARM::t2LDRi12);
   bool isLROk = (Opc == ARM::t2STMIA_UPD || Opc == ARM::t2STMDB_UPD);
   bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi);
   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
@@ -270,10 +270,12 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
     return false;
 
   unsigned Scale = 1;
+  bool HasBaseReg = true;
   bool HasImmOffset = false;
   bool HasShift = false;
   bool HasOffReg = true;
   bool isLdStMul = false;
+  bool InsertImmOffset = true;
   unsigned Opc = Entry.NarrowOpc1;
   unsigned OpNum = 3; // First 'rest' of operands.
   uint8_t  ImmLimit = Entry.Imm1Limit;
@@ -290,17 +292,50 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
       HasOffReg = false;
     }
     Scale = 4;
-    HasImmOffset = true;
+    if (MI->getOperand(2).isImm())
+      HasImmOffset = true;
+    else {
+      if (Entry.WideOpc == ARM::t2LDRi12) {
+        Opc = ARM::tLDRpci;
+        OpNum = 2;
+      }
+      HasImmOffset = false;
+      InsertImmOffset = false;
+      HasBaseReg = false;
+      HasOffReg = false;
+    }
     break;
   }
   case ARM::t2LDRBi12:
   case ARM::t2STRBi12:
-    HasImmOffset = true;
+    if (MI->getOperand(2).isImm())
+      HasImmOffset = true;
+    else {
+      if (Entry.WideOpc == ARM::t2LDRBi12) {
+        Opc = ARM::tLDRpci;
+        OpNum = 2;
+      }
+      HasImmOffset = false;
+      InsertImmOffset = false;
+      HasBaseReg = false;
+      HasOffReg = false;
+    }
     break;
   case ARM::t2LDRHi12:
   case ARM::t2STRHi12:
     Scale = 2;
-    HasImmOffset = true;
+    if (MI->getOperand(2).isImm())
+      HasImmOffset = true;
+    else {
+      if (Entry.WideOpc == ARM::t2LDRHi12) {
+        Opc = ARM::tLDRpci;
+        OpNum = 2;
+      }
+      HasImmOffset = false;
+      InsertImmOffset = false;
+      HasBaseReg = false;
+      HasOffReg = false;
+    }
     break;
   case ARM::t2LDRs:
   case ARM::t2LDRBs:
@@ -388,8 +423,9 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
   DebugLoc dl = MI->getDebugLoc();
   MachineInstrBuilder MIB = BuildMI(MBB, *MI, dl, TII->get(Opc));
   if (!isLdStMul) {
-    MIB.addOperand(MI->getOperand(0)).addOperand(MI->getOperand(1));
-    if (Opc != ARM::tLDRSB && Opc != ARM::tLDRSH) {
+    MIB.addOperand(MI->getOperand(0));
+    if (HasBaseReg) MIB.addOperand(MI->getOperand(1));
+    if (InsertImmOffset && Opc != ARM::tLDRSB && Opc != ARM::tLDRSH) {
       // tLDRSB and tLDRSH do not have an immediate offset field. On the other
       // hand, it must have an offset register.
       // FIXME: Remove this special case.
index 29c67e7a03508db9c8a693ab066399961d56a5ae..2870d500cea5b7587c202e9ffcb7a969fd118bde 100644 (file)
@@ -27,7 +27,7 @@
 # CHECK:       ldmia   r0!, {r1}
 0x02 0xc8
 
-# CHECK:       ldrb.w  r8, #-24
+# CHECK:       ldrb.w  r8, [pc, #-24]
 0x1f 0xf8 0x18 0x80
 
 # CHECK:       ldrd    r0, r1, [r7, #64]!