Home | History | Annotate | Download | only in ARM
      1 //===-- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the Thumb-2 implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "Thumb2InstrInfo.h"
     15 #include "ARMConstantPoolValue.h"
     16 #include "ARMMachineFunctionInfo.h"
     17 #include "MCTargetDesc/ARMAddressingModes.h"
     18 #include "llvm/CodeGen/MachineFrameInfo.h"
     19 #include "llvm/CodeGen/MachineInstrBuilder.h"
     20 #include "llvm/CodeGen/MachineMemOperand.h"
     21 #include "llvm/CodeGen/MachineRegisterInfo.h"
     22 #include "llvm/MC/MCInst.h"
     23 #include "llvm/Support/CommandLine.h"
     24 
     25 using namespace llvm;
     26 
     27 static cl::opt<bool>
     28 OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden,
     29            cl::desc("Use old-style Thumb2 if-conversion heuristics"),
     30            cl::init(false));
     31 
     32 Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
     33     : ARMBaseInstrInfo(STI), RI() {}
     34 
     35 /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
     36 void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
     37   NopInst.setOpcode(ARM::tHINT);
     38   NopInst.addOperand(MCOperand::createImm(0));
     39   NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
     40   NopInst.addOperand(MCOperand::createReg(0));
     41 }
     42 
     43 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
     44   // FIXME
     45   return 0;
     46 }
     47 
     48 void
     49 Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
     50                                          MachineBasicBlock *NewDest) const {
     51   MachineBasicBlock *MBB = Tail->getParent();
     52   ARMFunctionInfo *AFI = MBB->getParent()->getInfo<ARMFunctionInfo>();
     53   if (!AFI->hasITBlocks() || Tail->isBranch()) {
     54     TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
     55     return;
     56   }
     57 
     58   // If the first instruction of Tail is predicated, we may have to update
     59   // the IT instruction.
     60   unsigned PredReg = 0;
     61   ARMCC::CondCodes CC = getInstrPredicate(*Tail, PredReg);
     62   MachineBasicBlock::iterator MBBI = Tail;
     63   if (CC != ARMCC::AL)
     64     // Expecting at least the t2IT instruction before it.
     65     --MBBI;
     66 
     67   // Actually replace the tail.
     68   TargetInstrInfo::ReplaceTailWithBranchTo(Tail, NewDest);
     69 
     70   // Fix up IT.
     71   if (CC != ARMCC::AL) {
     72     MachineBasicBlock::iterator E = MBB->begin();
     73     unsigned Count = 4; // At most 4 instructions in an IT block.
     74     while (Count && MBBI != E) {
     75       if (MBBI->isDebugValue()) {
     76         --MBBI;
     77         continue;
     78       }
     79       if (MBBI->getOpcode() == ARM::t2IT) {
     80         unsigned Mask = MBBI->getOperand(1).getImm();
     81         if (Count == 4)
     82           MBBI->eraseFromParent();
     83         else {
     84           unsigned MaskOn = 1 << Count;
     85           unsigned MaskOff = ~(MaskOn - 1);
     86           MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
     87         }
     88         return;
     89       }
     90       --MBBI;
     91       --Count;
     92     }
     93 
     94     // Ctrl flow can reach here if branch folding is run before IT block
     95     // formation pass.
     96   }
     97 }
     98 
     99 bool
    100 Thumb2InstrInfo::isLegalToSplitMBBAt(MachineBasicBlock &MBB,
    101                                      MachineBasicBlock::iterator MBBI) const {
    102   while (MBBI->isDebugValue()) {
    103     ++MBBI;
    104     if (MBBI == MBB.end())
    105       return false;
    106   }
    107 
    108   unsigned PredReg = 0;
    109   return getITInstrPredicate(*MBBI, PredReg) == ARMCC::AL;
    110 }
    111 
    112 void Thumb2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
    113                                   MachineBasicBlock::iterator I,
    114                                   const DebugLoc &DL, unsigned DestReg,
    115                                   unsigned SrcReg, bool KillSrc) const {
    116   // Handle SPR, DPR, and QPR copies.
    117   if (!ARM::GPRRegClass.contains(DestReg, SrcReg))
    118     return ARMBaseInstrInfo::copyPhysReg(MBB, I, DL, DestReg, SrcReg, KillSrc);
    119 
    120   AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
    121     .addReg(SrcReg, getKillRegState(KillSrc)));
    122 }
    123 
    124 void Thumb2InstrInfo::
    125 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
    126                     unsigned SrcReg, bool isKill, int FI,
    127                     const TargetRegisterClass *RC,
    128                     const TargetRegisterInfo *TRI) const {
    129   DebugLoc DL;
    130   if (I != MBB.end()) DL = I->getDebugLoc();
    131 
    132   MachineFunction &MF = *MBB.getParent();
    133   MachineFrameInfo &MFI = *MF.getFrameInfo();
    134   MachineMemOperand *MMO = MF.getMachineMemOperand(
    135       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
    136       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
    137 
    138   if (RC == &ARM::GPRRegClass   || RC == &ARM::tGPRRegClass ||
    139       RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
    140       RC == &ARM::GPRnopcRegClass) {
    141     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2STRi12))
    142                    .addReg(SrcReg, getKillRegState(isKill))
    143                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
    144     return;
    145   }
    146 
    147   if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
    148     // Thumb2 STRD expects its dest-registers to be in rGPR. Not a problem for
    149     // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
    150     // otherwise).
    151     if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
    152       MachineRegisterInfo *MRI = &MF.getRegInfo();
    153       MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
    154     }
    155 
    156     MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
    157     AddDReg(MIB, SrcReg, ARM::gsub_0, getKillRegState(isKill), TRI);
    158     AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
    159     MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
    160     AddDefaultPred(MIB);
    161     return;
    162   }
    163 
    164   ARMBaseInstrInfo::storeRegToStackSlot(MBB, I, SrcReg, isKill, FI, RC, TRI);
    165 }
    166 
    167 void Thumb2InstrInfo::
    168 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
    169                      unsigned DestReg, int FI,
    170                      const TargetRegisterClass *RC,
    171                      const TargetRegisterInfo *TRI) const {
    172   MachineFunction &MF = *MBB.getParent();
    173   MachineFrameInfo &MFI = *MF.getFrameInfo();
    174   MachineMemOperand *MMO = MF.getMachineMemOperand(
    175       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
    176       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
    177   DebugLoc DL;
    178   if (I != MBB.end()) DL = I->getDebugLoc();
    179 
    180   if (RC == &ARM::GPRRegClass   || RC == &ARM::tGPRRegClass ||
    181       RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
    182       RC == &ARM::GPRnopcRegClass) {
    183     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::t2LDRi12), DestReg)
    184                    .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
    185     return;
    186   }
    187 
    188   if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
    189     // Thumb2 LDRD expects its dest-registers to be in rGPR. Not a problem for
    190     // gsub_0, but needs an extra constraint for gsub_1 (which could be sp
    191     // otherwise).
    192     if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
    193       MachineRegisterInfo *MRI = &MF.getRegInfo();
    194       MRI->constrainRegClass(DestReg,
    195                              &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
    196     }
    197 
    198     MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
    199     AddDReg(MIB, DestReg, ARM::gsub_0, RegState::DefineNoRead, TRI);
    200     AddDReg(MIB, DestReg, ARM::gsub_1, RegState::DefineNoRead, TRI);
    201     MIB.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
    202     AddDefaultPred(MIB);
    203 
    204     if (TargetRegisterInfo::isPhysicalRegister(DestReg))
    205       MIB.addReg(DestReg, RegState::ImplicitDefine);
    206     return;
    207   }
    208 
    209   ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
    210 }
    211 
    212 void Thumb2InstrInfo::expandLoadStackGuard(
    213     MachineBasicBlock::iterator MI) const {
    214   MachineFunction &MF = *MI->getParent()->getParent();
    215   if (MF.getTarget().isPositionIndependent())
    216     expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
    217   else
    218     expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
    219 }
    220 
    221 void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
    222                                   MachineBasicBlock::iterator &MBBI,
    223                                   const DebugLoc &dl, unsigned DestReg,
    224                                   unsigned BaseReg, int NumBytes,
    225                                   ARMCC::CondCodes Pred, unsigned PredReg,
    226                                   const ARMBaseInstrInfo &TII,
    227                                   unsigned MIFlags) {
    228   if (NumBytes == 0 && DestReg != BaseReg) {
    229     BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
    230       .addReg(BaseReg, RegState::Kill)
    231       .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
    232     return;
    233   }
    234 
    235   bool isSub = NumBytes < 0;
    236   if (isSub) NumBytes = -NumBytes;
    237 
    238   // If profitable, use a movw or movt to materialize the offset.
    239   // FIXME: Use the scavenger to grab a scratch register.
    240   if (DestReg != ARM::SP && DestReg != BaseReg &&
    241       NumBytes >= 4096 &&
    242       ARM_AM::getT2SOImmVal(NumBytes) == -1) {
    243     bool Fits = false;
    244     if (NumBytes < 65536) {
    245       // Use a movw to materialize the 16-bit constant.
    246       BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
    247         .addImm(NumBytes)
    248         .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
    249       Fits = true;
    250     } else if ((NumBytes & 0xffff) == 0) {
    251       // Use a movt to materialize the 32-bit constant.
    252       BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
    253         .addReg(DestReg)
    254         .addImm(NumBytes >> 16)
    255         .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
    256       Fits = true;
    257     }
    258 
    259     if (Fits) {
    260       if (isSub) {
    261         BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
    262           .addReg(BaseReg)
    263           .addReg(DestReg, RegState::Kill)
    264           .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
    265           .setMIFlags(MIFlags);
    266       } else {
    267         // Here we know that DestReg is not SP but we do not
    268         // know anything about BaseReg. t2ADDrr is an invalid
    269         // instruction is SP is used as the second argument, but
    270         // is fine if SP is the first argument. To be sure we
    271         // do not generate invalid encoding, put BaseReg first.
    272         BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
    273           .addReg(BaseReg)
    274           .addReg(DestReg, RegState::Kill)
    275           .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
    276           .setMIFlags(MIFlags);
    277       }
    278       return;
    279     }
    280   }
    281 
    282   while (NumBytes) {
    283     unsigned ThisVal = NumBytes;
    284     unsigned Opc = 0;
    285     if (DestReg == ARM::SP && BaseReg != ARM::SP) {
    286       // mov sp, rn. Note t2MOVr cannot be used.
    287       AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),DestReg)
    288         .addReg(BaseReg).setMIFlags(MIFlags));
    289       BaseReg = ARM::SP;
    290       continue;
    291     }
    292 
    293     bool HasCCOut = true;
    294     if (BaseReg == ARM::SP) {
    295       // sub sp, sp, #imm7
    296       if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
    297         assert((ThisVal & 3) == 0 && "Stack update is not multiple of 4?");
    298         Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
    299         AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
    300           .addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags));
    301         NumBytes = 0;
    302         continue;
    303       }
    304 
    305       // sub rd, sp, so_imm
    306       Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
    307       if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
    308         NumBytes = 0;
    309       } else {
    310         // FIXME: Move this to ARMAddressingModes.h?
    311         unsigned RotAmt = countLeadingZeros(ThisVal);
    312         ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
    313         NumBytes &= ~ThisVal;
    314         assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
    315                "Bit extraction didn't work?");
    316       }
    317     } else {
    318       assert(DestReg != ARM::SP && BaseReg != ARM::SP);
    319       Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
    320       if (ARM_AM::getT2SOImmVal(NumBytes) != -1) {
    321         NumBytes = 0;
    322       } else if (ThisVal < 4096) {
    323         Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
    324         HasCCOut = false;
    325         NumBytes = 0;
    326       } else {
    327         // FIXME: Move this to ARMAddressingModes.h?
    328         unsigned RotAmt = countLeadingZeros(ThisVal);
    329         ThisVal = ThisVal & ARM_AM::rotr32(0xff000000U, RotAmt);
    330         NumBytes &= ~ThisVal;
    331         assert(ARM_AM::getT2SOImmVal(ThisVal) != -1 &&
    332                "Bit extraction didn't work?");
    333       }
    334     }
    335 
    336     // Build the new ADD / SUB.
    337     MachineInstrBuilder MIB =
    338       AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
    339                      .addReg(BaseReg, RegState::Kill)
    340                      .addImm(ThisVal)).setMIFlags(MIFlags);
    341     if (HasCCOut)
    342       AddDefaultCC(MIB);
    343 
    344     BaseReg = DestReg;
    345   }
    346 }
    347 
    348 static unsigned
    349 negativeOffsetOpcode(unsigned opcode)
    350 {
    351   switch (opcode) {
    352   case ARM::t2LDRi12:   return ARM::t2LDRi8;
    353   case ARM::t2LDRHi12:  return ARM::t2LDRHi8;
    354   case ARM::t2LDRBi12:  return ARM::t2LDRBi8;
    355   case ARM::t2LDRSHi12: return ARM::t2LDRSHi8;
    356   case ARM::t2LDRSBi12: return ARM::t2LDRSBi8;
    357   case ARM::t2STRi12:   return ARM::t2STRi8;
    358   case ARM::t2STRBi12:  return ARM::t2STRBi8;
    359   case ARM::t2STRHi12:  return ARM::t2STRHi8;
    360   case ARM::t2PLDi12:   return ARM::t2PLDi8;
    361 
    362   case ARM::t2LDRi8:
    363   case ARM::t2LDRHi8:
    364   case ARM::t2LDRBi8:
    365   case ARM::t2LDRSHi8:
    366   case ARM::t2LDRSBi8:
    367   case ARM::t2STRi8:
    368   case ARM::t2STRBi8:
    369   case ARM::t2STRHi8:
    370   case ARM::t2PLDi8:
    371     return opcode;
    372 
    373   default:
    374     break;
    375   }
    376 
    377   return 0;
    378 }
    379 
    380 static unsigned
    381 positiveOffsetOpcode(unsigned opcode)
    382 {
    383   switch (opcode) {
    384   case ARM::t2LDRi8:   return ARM::t2LDRi12;
    385   case ARM::t2LDRHi8:  return ARM::t2LDRHi12;
    386   case ARM::t2LDRBi8:  return ARM::t2LDRBi12;
    387   case ARM::t2LDRSHi8: return ARM::t2LDRSHi12;
    388   case ARM::t2LDRSBi8: return ARM::t2LDRSBi12;
    389   case ARM::t2STRi8:   return ARM::t2STRi12;
    390   case ARM::t2STRBi8:  return ARM::t2STRBi12;
    391   case ARM::t2STRHi8:  return ARM::t2STRHi12;
    392   case ARM::t2PLDi8:   return ARM::t2PLDi12;
    393 
    394   case ARM::t2LDRi12:
    395   case ARM::t2LDRHi12:
    396   case ARM::t2LDRBi12:
    397   case ARM::t2LDRSHi12:
    398   case ARM::t2LDRSBi12:
    399   case ARM::t2STRi12:
    400   case ARM::t2STRBi12:
    401   case ARM::t2STRHi12:
    402   case ARM::t2PLDi12:
    403     return opcode;
    404 
    405   default:
    406     break;
    407   }
    408 
    409   return 0;
    410 }
    411 
    412 static unsigned
    413 immediateOffsetOpcode(unsigned opcode)
    414 {
    415   switch (opcode) {
    416   case ARM::t2LDRs:   return ARM::t2LDRi12;
    417   case ARM::t2LDRHs:  return ARM::t2LDRHi12;
    418   case ARM::t2LDRBs:  return ARM::t2LDRBi12;
    419   case ARM::t2LDRSHs: return ARM::t2LDRSHi12;
    420   case ARM::t2LDRSBs: return ARM::t2LDRSBi12;
    421   case ARM::t2STRs:   return ARM::t2STRi12;
    422   case ARM::t2STRBs:  return ARM::t2STRBi12;
    423   case ARM::t2STRHs:  return ARM::t2STRHi12;
    424   case ARM::t2PLDs:   return ARM::t2PLDi12;
    425 
    426   case ARM::t2LDRi12:
    427   case ARM::t2LDRHi12:
    428   case ARM::t2LDRBi12:
    429   case ARM::t2LDRSHi12:
    430   case ARM::t2LDRSBi12:
    431   case ARM::t2STRi12:
    432   case ARM::t2STRBi12:
    433   case ARM::t2STRHi12:
    434   case ARM::t2PLDi12:
    435   case ARM::t2LDRi8:
    436   case ARM::t2LDRHi8:
    437   case ARM::t2LDRBi8:
    438   case ARM::t2LDRSHi8:
    439   case ARM::t2LDRSBi8:
    440   case ARM::t2STRi8:
    441   case ARM::t2STRBi8:
    442   case ARM::t2STRHi8:
    443   case ARM::t2PLDi8:
    444     return opcode;
    445 
    446   default:
    447     break;
    448   }
    449 
    450   return 0;
    451 }
    452 
    453 bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
    454                                unsigned FrameReg, int &Offset,
    455                                const ARMBaseInstrInfo &TII) {
    456   unsigned Opcode = MI.getOpcode();
    457   const MCInstrDesc &Desc = MI.getDesc();
    458   unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
    459   bool isSub = false;
    460 
    461   // Memory operands in inline assembly always use AddrModeT2_i12.
    462   if (Opcode == ARM::INLINEASM)
    463     AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
    464 
    465   if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
    466     Offset += MI.getOperand(FrameRegIdx+1).getImm();
    467 
    468     unsigned PredReg;
    469     if (Offset == 0 && getInstrPredicate(MI, PredReg) == ARMCC::AL) {
    470       // Turn it into a move.
    471       MI.setDesc(TII.get(ARM::tMOVr));
    472       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
    473       // Remove offset and remaining explicit predicate operands.
    474       do MI.RemoveOperand(FrameRegIdx+1);
    475       while (MI.getNumOperands() > FrameRegIdx+1);
    476       MachineInstrBuilder MIB(*MI.getParent()->getParent(), &MI);
    477       AddDefaultPred(MIB);
    478       return true;
    479     }
    480 
    481     bool HasCCOut = Opcode != ARM::t2ADDri12;
    482 
    483     if (Offset < 0) {
    484       Offset = -Offset;
    485       isSub = true;
    486       MI.setDesc(TII.get(ARM::t2SUBri));
    487     } else {
    488       MI.setDesc(TII.get(ARM::t2ADDri));
    489     }
    490 
    491     // Common case: small offset, fits into instruction.
    492     if (ARM_AM::getT2SOImmVal(Offset) != -1) {
    493       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
    494       MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
    495       // Add cc_out operand if the original instruction did not have one.
    496       if (!HasCCOut)
    497         MI.addOperand(MachineOperand::CreateReg(0, false));
    498       Offset = 0;
    499       return true;
    500     }
    501     // Another common case: imm12.
    502     if (Offset < 4096 &&
    503         (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) {
    504       unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
    505       MI.setDesc(TII.get(NewOpc));
    506       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
    507       MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
    508       // Remove the cc_out operand.
    509       if (HasCCOut)
    510         MI.RemoveOperand(MI.getNumOperands()-1);
    511       Offset = 0;
    512       return true;
    513     }
    514 
    515     // Otherwise, extract 8 adjacent bits from the immediate into this
    516     // t2ADDri/t2SUBri.
    517     unsigned RotAmt = countLeadingZeros<unsigned>(Offset);
    518     unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xff000000U, RotAmt);
    519 
    520     // We will handle these bits from offset, clear them.
    521     Offset &= ~ThisImmVal;
    522 
    523     assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 &&
    524            "Bit extraction didn't work?");
    525     MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
    526     // Add cc_out operand if the original instruction did not have one.
    527     if (!HasCCOut)
    528       MI.addOperand(MachineOperand::CreateReg(0, false));
    529 
    530   } else {
    531 
    532     // AddrMode4 and AddrMode6 cannot handle any offset.
    533     if (AddrMode == ARMII::AddrMode4 || AddrMode == ARMII::AddrMode6)
    534       return false;
    535 
    536     // AddrModeT2_so cannot handle any offset. If there is no offset
    537     // register then we change to an immediate version.
    538     unsigned NewOpc = Opcode;
    539     if (AddrMode == ARMII::AddrModeT2_so) {
    540       unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
    541       if (OffsetReg != 0) {
    542         MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
    543         return Offset == 0;
    544       }
    545 
    546       MI.RemoveOperand(FrameRegIdx+1);
    547       MI.getOperand(FrameRegIdx+1).ChangeToImmediate(0);
    548       NewOpc = immediateOffsetOpcode(Opcode);
    549       AddrMode = ARMII::AddrModeT2_i12;
    550     }
    551 
    552     unsigned NumBits = 0;
    553     unsigned Scale = 1;
    554     if (AddrMode == ARMII::AddrModeT2_i8 || AddrMode == ARMII::AddrModeT2_i12) {
    555       // i8 supports only negative, and i12 supports only positive, so
    556       // based on Offset sign convert Opcode to the appropriate
    557       // instruction
    558       Offset += MI.getOperand(FrameRegIdx+1).getImm();
    559       if (Offset < 0) {
    560         NewOpc = negativeOffsetOpcode(Opcode);
    561         NumBits = 8;
    562         isSub = true;
    563         Offset = -Offset;
    564       } else {
    565         NewOpc = positiveOffsetOpcode(Opcode);
    566         NumBits = 12;
    567       }
    568     } else if (AddrMode == ARMII::AddrMode5) {
    569       // VFP address mode.
    570       const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
    571       int InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
    572       if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
    573         InstrOffs *= -1;
    574       NumBits = 8;
    575       Scale = 4;
    576       Offset += InstrOffs * 4;
    577       assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
    578       if (Offset < 0) {
    579         Offset = -Offset;
    580         isSub = true;
    581       }
    582     } else if (AddrMode == ARMII::AddrModeT2_i8s4) {
    583       Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
    584       NumBits = 10; // 8 bits scaled by 4
    585       // MCInst operand expects already scaled value.
    586       Scale = 1;
    587       assert((Offset & 3) == 0 && "Can't encode this offset!");
    588     } else {
    589       llvm_unreachable("Unsupported addressing mode!");
    590     }
    591 
    592     if (NewOpc != Opcode)
    593       MI.setDesc(TII.get(NewOpc));
    594 
    595     MachineOperand &ImmOp = MI.getOperand(FrameRegIdx+1);
    596 
    597     // Attempt to fold address computation
    598     // Common case: small offset, fits into instruction.
    599     int ImmedOffset = Offset / Scale;
    600     unsigned Mask = (1 << NumBits) - 1;
    601     if ((unsigned)Offset <= Mask * Scale) {
    602       // Replace the FrameIndex with fp/sp
    603       MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
    604       if (isSub) {
    605         if (AddrMode == ARMII::AddrMode5)
    606           // FIXME: Not consistent.
    607           ImmedOffset |= 1 << NumBits;
    608         else
    609           ImmedOffset = -ImmedOffset;
    610       }
    611       ImmOp.ChangeToImmediate(ImmedOffset);
    612       Offset = 0;
    613       return true;
    614     }
    615 
    616     // Otherwise, offset doesn't fit. Pull in what we can to simplify
    617     ImmedOffset = ImmedOffset & Mask;
    618     if (isSub) {
    619       if (AddrMode == ARMII::AddrMode5)
    620         // FIXME: Not consistent.
    621         ImmedOffset |= 1 << NumBits;
    622       else {
    623         ImmedOffset = -ImmedOffset;
    624         if (ImmedOffset == 0)
    625           // Change the opcode back if the encoded offset is zero.
    626           MI.setDesc(TII.get(positiveOffsetOpcode(NewOpc)));
    627       }
    628     }
    629     ImmOp.ChangeToImmediate(ImmedOffset);
    630     Offset &= ~(Mask*Scale);
    631   }
    632 
    633   Offset = (isSub) ? -Offset : Offset;
    634   return Offset == 0;
    635 }
    636 
    637 ARMCC::CondCodes llvm::getITInstrPredicate(const MachineInstr &MI,
    638                                            unsigned &PredReg) {
    639   unsigned Opc = MI.getOpcode();
    640   if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
    641     return ARMCC::AL;
    642   return getInstrPredicate(MI, PredReg);
    643 }
    644