[llvm-commits] [llvm] r74731 - in /llvm/trunk/lib/Target/ARM: ARMInstrInfo.cpp ARMInstrInfo.h ARMTargetMachine.cpp ARMTargetMachine.h CMakeLists.txt Thumb1InstrInfo.cpp Thumb1InstrInfo.h Thumb1RegisterInfo.cpp Thumb1RegisterInfo.h Thumb2InstrInfo.cpp Thumb2InstrInfo.h Thumb2RegisterInfo.cpp Thumb2RegisterInfo.h ThumbInstrInfo.cpp ThumbInstrInfo.h ThumbRegisterInfo.cpp ThumbRegisterInfo.h

Evan Cheng evan.cheng at apple.com
Thu Jul 2 16:16:57 PDT 2009


Awesome. Thanks for doing this!

Evan

On Jul 2, 2009, at 3:18 PM, David Goodwin wrote:

> Author: david_goodwin
> Date: Thu Jul  2 17:18:33 2009
> New Revision: 74731
>
> URL: http://llvm.org/viewvc/llvm-project?rev=74731&view=rev
> Log:
> Checkpoint refactoring of ThumbInstrInfo and ThumbRegisterInfo into  
> Thumb1InstrInfo, Thumb2InstrInfo, Thumb1RegisterInfo and  
> Thumb2RegisterInfo. Move methods from ARMInstrInfo to  
> ARMBaseInstrInfo to prepare for sharing with Thumb2.
>
> Added:
>    llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp
>      - copied, changed from r74702, llvm/trunk/lib/Target/ARM/ 
> ThumbInstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h
>      - copied, changed from r74702, llvm/trunk/lib/Target/ARM/ 
> ThumbInstrInfo.h
>    llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp
>      - copied, changed from r74702, llvm/trunk/lib/Target/ARM/ 
> ThumbRegisterInfo.cpp
>    llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h
>      - copied, changed from r74702, llvm/trunk/lib/Target/ARM/ 
> ThumbRegisterInfo.h
>    llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h
>    llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp
>    llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h
> Removed:
>    llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h
>    llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp
>    llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
>    llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
>    llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
>    llvm/trunk/lib/Target/ARM/ARMTargetMachine.h
>    llvm/trunk/lib/Target/ARM/CMakeLists.txt
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=74731&r1=74730&r2=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Thu Jul  2 17:18:33  
> 2009
> @@ -47,91 +47,6 @@
>   : ARMBaseInstrInfo(STI), RI(*this, STI) {
> }
>
> -/// Return true if the instruction is a register to register move and
> -/// leave the source and dest operands in the passed parameters.
> -///
> -bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
> -                               unsigned &SrcReg, unsigned &DstReg,
> -                               unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
> -  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
> -
> -  unsigned oc = MI.getOpcode();
> -  switch (oc) {
> -  default:
> -    return false;
> -  case ARM::FCPYS:
> -  case ARM::FCPYD:
> -  case ARM::VMOVD:
> -  case ARM::VMOVQ:
> -    SrcReg = MI.getOperand(1).getReg();
> -    DstReg = MI.getOperand(0).getReg();
> -    return true;
> -  case ARM::MOVr:
> -    assert(MI.getDesc().getNumOperands() >= 2 &&
> -           MI.getOperand(0).isReg() &&
> -           MI.getOperand(1).isReg() &&
> -           "Invalid ARM MOV instruction");
> -    SrcReg = MI.getOperand(1).getReg();
> -    DstReg = MI.getOperand(0).getReg();
> -    return true;
> -  }
> -}
> -
> -unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> -                                           int &FrameIndex) const {
> -  switch (MI->getOpcode()) {
> -  default: break;
> -  case ARM::LDR:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isReg() &&
> -        MI->getOperand(3).isImm() &&
> -        MI->getOperand(2).getReg() == 0 &&
> -        MI->getOperand(3).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  case ARM::FLDD:
> -  case ARM::FLDS:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isImm() &&
> -        MI->getOperand(2).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  }
> -  return 0;
> -}
> -
> -unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> -                                          int &FrameIndex) const {
> -  switch (MI->getOpcode()) {
> -  default: break;
> -  case ARM::STR:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isReg() &&
> -        MI->getOperand(3).isImm() &&
> -        MI->getOperand(2).getReg() == 0 &&
> -        MI->getOperand(3).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  case ARM::FSTD:
> -  case ARM::FSTS:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isImm() &&
> -        MI->getOperand(2).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  }
> -
> -  return 0;
> -}
> -
> void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB,
>                                  MachineBasicBlock::iterator I,
>                                  unsigned DestReg,
> @@ -335,10 +250,10 @@
>
> // Branch analysis.
> bool
> -  ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock  
> &MBB,MachineBasicBlock *&TBB,
> -                                  MachineBasicBlock *&FBB,
> -                                  SmallVectorImpl<MachineOperand>  
> &Cond,
> -                                  bool AllowModify) const {
> +ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock  
> &MBB,MachineBasicBlock *&TBB,
> +                                MachineBasicBlock *&FBB,
> +                                SmallVectorImpl<MachineOperand>  
> &Cond,
> +                                bool AllowModify) const {
>   // If the block has no terminators, it just falls into the block  
> after it.
>   MachineBasicBlock::iterator I = MBB.end();
>   if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
> @@ -478,132 +393,410 @@
>   return 2;
> }
>
> -bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> -                                MachineBasicBlock::iterator I,
> -                                unsigned DestReg, unsigned SrcReg,
> -                                const TargetRegisterClass *DestRC,
> -                                const TargetRegisterClass *SrcRC)  
> const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> +bool
> +ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock  
> &MBB) const {
> +  if (MBB.empty()) return false;
>
> -  if (DestRC != SrcRC) {
> -    // Not yet supported!
> -    return false;
> +  switch (MBB.back().getOpcode()) {
> +  case ARM::BX_RET:   // Return.
> +  case ARM::LDM_RET:
> +  case ARM::tBX_RET:
> +  case ARM::tBX_RET_vararg:
> +  case ARM::tPOP_RET:
> +  case ARM::B:
> +  case ARM::tB:
> +  case ARM::t2B:      // Uncond branch.
> +  case ARM::tBR_JTr:
> +  case ARM::t2BR_JTr:
> +  case ARM::BR_JTr:   // Jumptable branch.
> +  case ARM::t2BR_JTm:
> +  case ARM::BR_JTm:   // Jumptable branch through mem.
> +  case ARM::t2BR_JTadd:
> +  case ARM::BR_JTadd: // Jumptable branch add to pc.
> +    return true;
> +  default: return false;
>   }
> -
> -  if (DestRC == ARM::GPRRegisterClass)
> -    AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),  
> DestReg)
> -                                .addReg(SrcReg)));
> -  else if (DestRC == ARM::SPRRegisterClass)
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
> -                   .addReg(SrcReg));
> -  else if (DestRC == ARM::DPRRegisterClass)
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
> -                   .addReg(SrcReg));
> -  else if (DestRC == ARM::QPRRegisterClass)
> -    BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
> -  else
> -    return false;
> -
> -  return true;
> }
>
> -void ARMInstrInfo::
> -storeRegToStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> -                    unsigned SrcReg, bool isKill, int FI,
> -                    const TargetRegisterClass *RC) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> +bool ARMBaseInstrInfo::
> +ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
> +  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
> +  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
> +  return false;
> +}
>
> -  if (RC == ARM::GPRRegisterClass) {
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
> -                   .addReg(SrcReg, getKillRegState(isKill))
> -                   .addFrameIndex(FI).addReg(0).addImm(0));
> -  } else if (RC == ARM::DPRRegisterClass) {
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
> -                   .addReg(SrcReg, getKillRegState(isKill))
> -                   .addFrameIndex(FI).addImm(0));
> -  } else {
> -    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
> -                   .addReg(SrcReg, getKillRegState(isKill))
> -                   .addFrameIndex(FI).addImm(0));
> -  }
> +bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
> +  int PIdx = MI->findFirstPredOperandIdx();
> +  return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
> }
>
> -void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> -                                  bool isKill,
> -                                  SmallVectorImpl<MachineOperand>  
> &Addr,
> -                                  const TargetRegisterClass *RC,
> -                                  SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  unsigned Opc = 0;
> -  if (RC == ARM::GPRRegisterClass) {
> -    Opc = ARM::STR;
> -  } else if (RC == ARM::DPRRegisterClass) {
> -    Opc = ARM::FSTD;
> -  } else {
> -    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> -    Opc = ARM::FSTS;
> +bool ARMBaseInstrInfo::
> +PredicateInstruction(MachineInstr *MI,
> +                     const SmallVectorImpl<MachineOperand> &Pred)  
> const {
> +  unsigned Opc = MI->getOpcode();
> +  if (Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B) {
> +    MI->setDesc(get((Opc == ARM::B) ? ARM::Bcc :
> +                    ((Opc == ARM::tB) ? ARM::tBcc : ARM::t2Bcc)));
> +    MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
> +    MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(),  
> false));
> +    return true;
>   }
>
> -  MachineInstrBuilder MIB =
> -    BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState 
> (isKill));
> -  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> -    MIB.addOperand(Addr[i]);
> -  AddDefaultPred(MIB);
> -  NewMIs.push_back(MIB);
> -  return;
> +  int PIdx = MI->findFirstPredOperandIdx();
> +  if (PIdx != -1) {
> +    MachineOperand &PMO = MI->getOperand(PIdx);
> +    PMO.setImm(Pred[0].getImm());
> +    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
> +    return true;
> +  }
> +  return false;
> }
>
> -void ARMInstrInfo::
> -loadRegFromStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> -                     unsigned DestReg, int FI,
> -                     const TargetRegisterClass *RC) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> +bool ARMBaseInstrInfo::
> +SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
> +                  const SmallVectorImpl<MachineOperand> &Pred2)  
> const {
> +  if (Pred1.size() > 2 || Pred2.size() > 2)
> +    return false;
>
> -  if (RC == ARM::GPRRegisterClass) {
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
> -                   .addFrameIndex(FI).addReg(0).addImm(0));
> -  } else if (RC == ARM::DPRRegisterClass) {
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
> -                   .addFrameIndex(FI).addImm(0));
> -  } else {
> -    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> -    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
> -                   .addFrameIndex(FI).addImm(0));
> +  ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
> +  ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
> +  if (CC1 == CC2)
> +    return true;
> +
> +  switch (CC1) {
> +  default:
> +    return false;
> +  case ARMCC::AL:
> +    return true;
> +  case ARMCC::HS:
> +    return CC2 == ARMCC::HI;
> +  case ARMCC::LS:
> +    return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
> +  case ARMCC::GE:
> +    return CC2 == ARMCC::GT;
> +  case ARMCC::LE:
> +    return CC2 == ARMCC::LT;
>   }
> }
>
> -void ARMInstrInfo::
> -loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> -                SmallVectorImpl<MachineOperand> &Addr,
> -                const TargetRegisterClass *RC,
> -                SmallVectorImpl<MachineInstr*> &NewMIs) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  unsigned Opc = 0;
> -  if (RC == ARM::GPRRegisterClass) {
> -    Opc = ARM::LDR;
> -  } else if (RC == ARM::DPRRegisterClass) {
> -    Opc = ARM::FLDD;
> -  } else {
> -    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> -    Opc = ARM::FLDS;
> +bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
> +                                    std::vector<MachineOperand>  
> &Pred) const {
> +  const TargetInstrDesc &TID = MI->getDesc();
> +  if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
> +    return false;
> +
> +  bool Found = false;
> +  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
> +    const MachineOperand &MO = MI->getOperand(i);
> +    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
> +      Pred.push_back(MO);
> +      Found = true;
> +    }
>   }
>
> -  MachineInstrBuilder MIB =  BuildMI(MF, DL, get(Opc), DestReg);
> -  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> -    MIB.addOperand(Addr[i]);
> -  AddDefaultPred(MIB);
> -  NewMIs.push_back(MIB);
> -  return;
> +  return Found;
> }
>
> -MachineInstr *ARMInstrInfo::
> -foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
> -                      const SmallVectorImpl<unsigned> &Ops, int FI)  
> const {
> -  if (Ops.size() != 1) return NULL;
> +
> +/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
> +static unsigned getNumJTEntries(const  
> std::vector<MachineJumpTableEntry> &JT,
> +                                unsigned JTI) DISABLE_INLINE;
> +static unsigned getNumJTEntries(const  
> std::vector<MachineJumpTableEntry> &JT,
> +                                unsigned JTI) {
> +  return JT[JTI].MBBs.size();
> +}
> +
> +/// GetInstSize - Return the size of the specified MachineInstr.
> +///
> +unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr  
> *MI) const {
> +  const MachineBasicBlock &MBB = *MI->getParent();
> +  const MachineFunction *MF = MBB.getParent();
> +  const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo();
> +
> +  // Basic size info comes from the TSFlags field.
> +  const TargetInstrDesc &TID = MI->getDesc();
> +  unsigned TSFlags = TID.TSFlags;
> +
> +  switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
> +  default: {
> +    // If this machine instr is an inline asm, measure it.
> +    if (MI->getOpcode() == ARM::INLINEASM)
> +      return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName 
> ());
> +    if (MI->isLabel())
> +      return 0;
> +    switch (MI->getOpcode()) {
> +    default:
> +      assert(0 && "Unknown or unset size field for instr!");
> +      break;
> +    case TargetInstrInfo::IMPLICIT_DEF:
> +    case TargetInstrInfo::DECLARE:
> +    case TargetInstrInfo::DBG_LABEL:
> +    case TargetInstrInfo::EH_LABEL:
> +      return 0;
> +    }
> +    break;
> +  }
> +  case ARMII::Size8Bytes: return 8;          // Arm instruction x 2.
> +  case ARMII::Size4Bytes: return 4;          // Arm instruction.
> +  case ARMII::Size2Bytes: return 2;          // Thumb instruction.
> +  case ARMII::SizeSpecial: {
> +    switch (MI->getOpcode()) {
> +    case ARM::CONSTPOOL_ENTRY:
> +      // If this machine instr is a constant pool entry, its size  
> is recorded as
> +      // operand #2.
> +      return MI->getOperand(2).getImm();
> +    case ARM::Int_eh_sjlj_setjmp: return 12;
> +    case ARM::BR_JTr:
> +    case ARM::BR_JTm:
> +    case ARM::BR_JTadd:
> +    case ARM::t2BR_JTr:
> +    case ARM::t2BR_JTm:
> +    case ARM::t2BR_JTadd:
> +    case ARM::tBR_JTr: {
> +      // These are jumptable branches, i.e. a branch followed by an  
> inlined
> +      // jumptable. The size is 4 + 4 * number of entries.
> +      unsigned NumOps = TID.getNumOperands();
> +      MachineOperand JTOP =
> +        MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
> +      unsigned JTI = JTOP.getIndex();
> +      const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
> +      const std::vector<MachineJumpTableEntry> &JT = MJTI- 
> >getJumpTables();
> +      assert(JTI < JT.size());
> +      // Thumb instructions are 2 byte aligned, but JT entries are  
> 4 byte
> +      // 4 aligned. The assembler / linker may add 2 byte padding  
> just before
> +      // the JT entries.  The size does not include this padding; the
> +      // constant islands pass does separate bookkeeping for it.
> +      // FIXME: If we know the size of the function is less than (1  
> << 16) *2
> +      // bytes, we can use 16-bit entries instead. Then there won't  
> be an
> +      // alignment issue.
> +      return getNumJTEntries(JT, JTI) * 4 +
> +        ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4);
> +    }
> +    default:
> +      // Otherwise, pseudo-instruction sizes are zero.
> +      return 0;
> +    }
> +  }
> +  }
> +  return 0; // Not reached
> +}
> +
> +/// Return true if the instruction is a register to register move and
> +/// leave the source and dest operands in the passed parameters.
> +///
> +bool
> +ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
> +                              unsigned &SrcReg, unsigned &DstReg,
> +                              unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
> +  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
> +
> +  unsigned oc = MI.getOpcode();
> +  switch (oc) {
> +  default:
> +    return false;
> +  case ARM::FCPYS:
> +  case ARM::FCPYD:
> +  case ARM::VMOVD:
> +  case ARM::VMOVQ:
> +    SrcReg = MI.getOperand(1).getReg();
> +    DstReg = MI.getOperand(0).getReg();
> +    return true;
> +  case ARM::MOVr:
> +    assert(MI.getDesc().getNumOperands() >= 2 &&
> +           MI.getOperand(0).isReg() &&
> +           MI.getOperand(1).isReg() &&
> +           "Invalid ARM MOV instruction");
> +    SrcReg = MI.getOperand(1).getReg();
> +    DstReg = MI.getOperand(0).getReg();
> +    return true;
> +  }
> +}
> +
> +unsigned
> +ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> +                                      int &FrameIndex) const {
> +  switch (MI->getOpcode()) {
> +  default: break;
> +  case ARM::LDR:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isReg() &&
> +        MI->getOperand(3).isImm() &&
> +        MI->getOperand(2).getReg() == 0 &&
> +        MI->getOperand(3).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  case ARM::FLDD:
> +  case ARM::FLDS:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isImm() &&
> +        MI->getOperand(2).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  }
> +  return 0;
> +}
> +
> +unsigned
> +ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> +                                     int &FrameIndex) const {
> +  switch (MI->getOpcode()) {
> +  default: break;
> +  case ARM::STR:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isReg() &&
> +        MI->getOperand(3).isImm() &&
> +        MI->getOperand(2).getReg() == 0 &&
> +        MI->getOperand(3).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  case ARM::FSTD:
> +  case ARM::FSTS:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isImm() &&
> +        MI->getOperand(2).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  }
> +
> +  return 0;
> +}
> +
> +bool
> +ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> +                               MachineBasicBlock::iterator I,
> +                               unsigned DestReg, unsigned SrcReg,
> +                               const TargetRegisterClass *DestRC,
> +                               const TargetRegisterClass *SrcRC)  
> const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  if (DestRC != SrcRC) {
> +    // Not yet supported!
> +    return false;
> +  }
> +
> +  if (DestRC == ARM::GPRRegisterClass)
> +    AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),  
> DestReg)
> +                                .addReg(SrcReg)));
> +  else if (DestRC == ARM::SPRRegisterClass)
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
> +                   .addReg(SrcReg));
> +  else if (DestRC == ARM::DPRRegisterClass)
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
> +                   .addReg(SrcReg));
> +  else if (DestRC == ARM::QPRRegisterClass)
> +    BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
> +  else
> +    return false;
> +
> +  return true;
> +}
> +
> +void ARMBaseInstrInfo::
> +storeRegToStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> +                    unsigned SrcReg, bool isKill, int FI,
> +                    const TargetRegisterClass *RC) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  if (RC == ARM::GPRRegisterClass) {
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
> +                   .addReg(SrcReg, getKillRegState(isKill))
> +                   .addFrameIndex(FI).addReg(0).addImm(0));
> +  } else if (RC == ARM::DPRRegisterClass) {
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
> +                   .addReg(SrcReg, getKillRegState(isKill))
> +                   .addFrameIndex(FI).addImm(0));
> +  } else {
> +    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
> +                   .addReg(SrcReg, getKillRegState(isKill))
> +                   .addFrameIndex(FI).addImm(0));
> +  }
> +}
> +
> +void
> +ARMBaseInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> +                                 bool isKill,
> +                                 SmallVectorImpl<MachineOperand>  
> &Addr,
> +                                 const TargetRegisterClass *RC,
> +                                 SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  unsigned Opc = 0;
> +  if (RC == ARM::GPRRegisterClass) {
> +    Opc = ARM::STR;
> +  } else if (RC == ARM::DPRRegisterClass) {
> +    Opc = ARM::FSTD;
> +  } else {
> +    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> +    Opc = ARM::FSTS;
> +  }
> +
> +  MachineInstrBuilder MIB =
> +    BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState 
> (isKill));
> +  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> +    MIB.addOperand(Addr[i]);
> +  AddDefaultPred(MIB);
> +  NewMIs.push_back(MIB);
> +  return;
> +}
> +
> +void ARMBaseInstrInfo::
> +loadRegFromStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> +                     unsigned DestReg, int FI,
> +                     const TargetRegisterClass *RC) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  if (RC == ARM::GPRRegisterClass) {
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
> +                   .addFrameIndex(FI).addReg(0).addImm(0));
> +  } else if (RC == ARM::DPRRegisterClass) {
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
> +                   .addFrameIndex(FI).addImm(0));
> +  } else {
> +    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> +    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
> +                   .addFrameIndex(FI).addImm(0));
> +  }
> +}
> +
> +void ARMBaseInstrInfo::
> +loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> +                SmallVectorImpl<MachineOperand> &Addr,
> +                const TargetRegisterClass *RC,
> +                SmallVectorImpl<MachineInstr*> &NewMIs) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  unsigned Opc = 0;
> +  if (RC == ARM::GPRRegisterClass) {
> +    Opc = ARM::LDR;
> +  } else if (RC == ARM::DPRRegisterClass) {
> +    Opc = ARM::FLDD;
> +  } else {
> +    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
> +    Opc = ARM::FLDS;
> +  }
> +
> +  MachineInstrBuilder MIB =  BuildMI(MF, DL, get(Opc), DestReg);
> +  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> +    MIB.addOperand(Addr[i]);
> +  AddDefaultPred(MIB);
> +  NewMIs.push_back(MIB);
> +  return;
> +}
> +
> +MachineInstr *ARMBaseInstrInfo::
> +foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
> +                      const SmallVectorImpl<unsigned> &Ops, int FI)  
> const {
> +  if (Ops.size() != 1) return NULL;
>
>   unsigned OpNum = Ops[0];
>   unsigned Opc = MI->getOpcode();
> @@ -688,9 +881,17 @@
>   return NewMI;
> }
>
> +MachineInstr*
> +ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
> +                                        MachineInstr* MI,
> +                                        const  
> SmallVectorImpl<unsigned> &Ops,
> +                                        MachineInstr* LoadMI) const {
> +  return 0;
> +}
> +
> bool
> -ARMInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
> -                                   const SmallVectorImpl<unsigned>  
> &Ops) const {
> +ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
> +                                       const  
> SmallVectorImpl<unsigned> &Ops) const {
>   if (Ops.size() != 1) return false;
>
>   unsigned Opc = MI->getOpcode();
> @@ -710,191 +911,3 @@
>
>   return false;
> }
> -
> -bool
> -ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock  
> &MBB) const {
> -  if (MBB.empty()) return false;
> -
> -  switch (MBB.back().getOpcode()) {
> -  case ARM::BX_RET:   // Return.
> -  case ARM::LDM_RET:
> -  case ARM::tBX_RET:
> -  case ARM::tBX_RET_vararg:
> -  case ARM::tPOP_RET:
> -  case ARM::B:
> -  case ARM::tB:
> -  case ARM::t2B:      // Uncond branch.
> -  case ARM::tBR_JTr:
> -  case ARM::t2BR_JTr:
> -  case ARM::BR_JTr:   // Jumptable branch.
> -  case ARM::t2BR_JTm:
> -  case ARM::BR_JTm:   // Jumptable branch through mem.
> -  case ARM::t2BR_JTadd:
> -  case ARM::BR_JTadd: // Jumptable branch add to pc.
> -    return true;
> -  default: return false;
> -  }
> -}
> -
> -bool ARMBaseInstrInfo::
> -ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
> -  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
> -  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
> -  return false;
> -}
> -
> -bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const {
> -  int PIdx = MI->findFirstPredOperandIdx();
> -  return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
> -}
> -
> -bool ARMBaseInstrInfo::
> -PredicateInstruction(MachineInstr *MI,
> -                     const SmallVectorImpl<MachineOperand> &Pred)  
> const {
> -  unsigned Opc = MI->getOpcode();
> -  if (Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B) {
> -    MI->setDesc(get((Opc == ARM::B) ? ARM::Bcc :
> -                    ((Opc == ARM::tB) ? ARM::tBcc : ARM::t2Bcc)));
> -    MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
> -    MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(),  
> false));
> -    return true;
> -  }
> -
> -  int PIdx = MI->findFirstPredOperandIdx();
> -  if (PIdx != -1) {
> -    MachineOperand &PMO = MI->getOperand(PIdx);
> -    PMO.setImm(Pred[0].getImm());
> -    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
> -    return true;
> -  }
> -  return false;
> -}
> -
> -bool ARMBaseInstrInfo::
> -SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
> -                  const SmallVectorImpl<MachineOperand> &Pred2)  
> const {
> -  if (Pred1.size() > 2 || Pred2.size() > 2)
> -    return false;
> -
> -  ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
> -  ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
> -  if (CC1 == CC2)
> -    return true;
> -
> -  switch (CC1) {
> -  default:
> -    return false;
> -  case ARMCC::AL:
> -    return true;
> -  case ARMCC::HS:
> -    return CC2 == ARMCC::HI;
> -  case ARMCC::LS:
> -    return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
> -  case ARMCC::GE:
> -    return CC2 == ARMCC::GT;
> -  case ARMCC::LE:
> -    return CC2 == ARMCC::LT;
> -  }
> -}
> -
> -bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
> -                                    std::vector<MachineOperand>  
> &Pred) const {
> -  const TargetInstrDesc &TID = MI->getDesc();
> -  if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
> -    return false;
> -
> -  bool Found = false;
> -  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
> -    const MachineOperand &MO = MI->getOperand(i);
> -    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
> -      Pred.push_back(MO);
> -      Found = true;
> -    }
> -  }
> -
> -  return Found;
> -}
> -
> -
> -/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
> -static unsigned getNumJTEntries(const  
> std::vector<MachineJumpTableEntry> &JT,
> -                                unsigned JTI) DISABLE_INLINE;
> -static unsigned getNumJTEntries(const  
> std::vector<MachineJumpTableEntry> &JT,
> -                                unsigned JTI) {
> -  return JT[JTI].MBBs.size();
> -}
> -
> -/// GetInstSize - Return the size of the specified MachineInstr.
> -///
> -unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr  
> *MI) const {
> -  const MachineBasicBlock &MBB = *MI->getParent();
> -  const MachineFunction *MF = MBB.getParent();
> -  const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo();
> -
> -  // Basic size info comes from the TSFlags field.
> -  const TargetInstrDesc &TID = MI->getDesc();
> -  unsigned TSFlags = TID.TSFlags;
> -
> -  switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
> -  default: {
> -    // If this machine instr is an inline asm, measure it.
> -    if (MI->getOpcode() == ARM::INLINEASM)
> -      return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName 
> ());
> -    if (MI->isLabel())
> -      return 0;
> -    switch (MI->getOpcode()) {
> -    default:
> -      assert(0 && "Unknown or unset size field for instr!");
> -      break;
> -    case TargetInstrInfo::IMPLICIT_DEF:
> -    case TargetInstrInfo::DECLARE:
> -    case TargetInstrInfo::DBG_LABEL:
> -    case TargetInstrInfo::EH_LABEL:
> -      return 0;
> -    }
> -    break;
> -  }
> -  case ARMII::Size8Bytes: return 8;          // Arm instruction x 2.
> -  case ARMII::Size4Bytes: return 4;          // Arm instruction.
> -  case ARMII::Size2Bytes: return 2;          // Thumb instruction.
> -  case ARMII::SizeSpecial: {
> -    switch (MI->getOpcode()) {
> -    case ARM::CONSTPOOL_ENTRY:
> -      // If this machine instr is a constant pool entry, its size  
> is recorded as
> -      // operand #2.
> -      return MI->getOperand(2).getImm();
> -    case ARM::Int_eh_sjlj_setjmp: return 12;
> -    case ARM::BR_JTr:
> -    case ARM::BR_JTm:
> -    case ARM::BR_JTadd:
> -    case ARM::t2BR_JTr:
> -    case ARM::t2BR_JTm:
> -    case ARM::t2BR_JTadd:
> -    case ARM::tBR_JTr: {
> -      // These are jumptable branches, i.e. a branch followed by an  
> inlined
> -      // jumptable. The size is 4 + 4 * number of entries.
> -      unsigned NumOps = TID.getNumOperands();
> -      MachineOperand JTOP =
> -        MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
> -      unsigned JTI = JTOP.getIndex();
> -      const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
> -      const std::vector<MachineJumpTableEntry> &JT = MJTI- 
> >getJumpTables();
> -      assert(JTI < JT.size());
> -      // Thumb instructions are 2 byte aligned, but JT entries are  
> 4 byte
> -      // 4 aligned. The assembler / linker may add 2 byte padding  
> just before
> -      // the JT entries.  The size does not include this padding; the
> -      // constant islands pass does separate bookkeeping for it.
> -      // FIXME: If we know the size of the function is less than (1  
> << 16) *2
> -      // bytes, we can use 16-bit entries instead. Then there won't  
> be an
> -      // alignment issue.
> -      return getNumJTEntries(JT, JTI) * 4 +
> -        ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4);
> -    }
> -    default:
> -      // Otherwise, pseudo-instruction sizes are zero.
> -      return 0;
> -    }
> -  }
> -  }
> -  return 0; // Not reached
> -}
>
> Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.h?rev=74731&r1=74730&r2=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.h Thu Jul  2 17:18:33 2009
> @@ -161,6 +161,8 @@
>                                                
> MachineBasicBlock::iterator &MBBI,
>                                               LiveVariables *LV)  
> const;
>
> +  virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
> +
>   // Branch analysis.
>   virtual bool AnalyzeBranch(MachineBasicBlock &MBB,  
> MachineBasicBlock *&TBB,
>                              MachineBasicBlock *&FBB,
> @@ -198,18 +200,6 @@
>   /// GetInstSize - Returns the size of the specified MachineInstr.
>   ///
>   virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
> -};
> -
> -class ARMInstrInfo : public ARMBaseInstrInfo {
> -  ARMRegisterInfo RI;
> -public:
> -  explicit ARMInstrInfo(const ARMSubtarget &STI);
> -
> -  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister  
> info.  As
> -  /// such, whenever a client has an instance of instruction info,  
> it should
> -  /// always be able to get register info as well (through this  
> method).
> -  ///
> -  virtual const ARMRegisterInfo &getRegisterInfo() const { return  
> RI; }
>
>   /// Return true if the instruction is a register to register move  
> and return
>   /// the source and dest operands and their sub-register indices by  
> reference.
> @@ -247,23 +237,33 @@
>                                const TargetRegisterClass *RC,
>                                SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
>
> -  void reMaterialize(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator MI,
> -                     unsigned DestReg, const MachineInstr *Orig)  
> const;
> -
>   virtual bool canFoldMemoryOperand(const MachineInstr *MI,
>                                     const SmallVectorImpl<unsigned>  
> &Ops) const;
> -
> +
>   virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
>                                               MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> +                                              const  
> SmallVectorImpl<unsigned> &Ops,
>                                               int FrameIndex) const;
>
>   virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
>                                               MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> -                                              MachineInstr* LoadMI)  
> const {
> -    return 0;
> -  }
> +                                              const  
> SmallVectorImpl<unsigned> &Ops,
> +                                              MachineInstr* LoadMI)  
> const;
> +};
> +
> +class ARMInstrInfo : public ARMBaseInstrInfo {
> +  ARMRegisterInfo RI;
> +public:
> +  explicit ARMInstrInfo(const ARMSubtarget &STI);
> +
> +  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister  
> info.  As
> +  /// such, whenever a client has an instance of instruction info,  
> it should
> +  /// always be able to get register info as well (through this  
> method).
> +  ///
> +  const ARMRegisterInfo &getRegisterInfo() const { return RI; }
> +
> +  void reMaterialize(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator MI,
> +                     unsigned DestReg, const MachineInstr *Orig)  
> const;
> };
>
> }
>
> Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=74731&r1=74730&r2=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Thu Jul  2  
> 17:18:33 2009
> @@ -95,13 +95,18 @@
> }
>
> ThumbTargetMachine::ThumbTargetMachine(const Module &M, const  
> std::string &FS)
> -  : ARMBaseTargetMachine(M, FS, true), InstrInfo(Subtarget),
> +  : ARMBaseTargetMachine(M, FS, true),
>     DataLayout(Subtarget.isAPCS_ABI() ?
>                std::string("e-p:32:32-f64:32:32-i64:32:32-"
>                            "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
>                std::string("e-p:32:32-f64:64:64-i64:64:64-"
>                            "i16:16:32-i8:8:32-i1:8:32-a:0:32")),
>     TLInfo(*this) {
> +  // Create the approriate type of Thumb InstrInfo
> +  if (Subtarget.hasThumb2())
> +    InstrInfo = new Thumb2InstrInfo(Subtarget);
> +  else
> +    InstrInfo = new Thumb1InstrInfo(Subtarget);
> }
>
> unsigned ARMTargetMachine::getJITMatchQuality() {
>
> Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.h?rev=74731&r1=74730&r2=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.h (original)
> +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.h Thu Jul  2 17:18:33  
> 2009
> @@ -22,7 +22,8 @@
> #include "ARMJITInfo.h"
> #include "ARMSubtarget.h"
> #include "ARMISelLowering.h"
> -#include "ThumbInstrInfo.h"
> +#include "Thumb1InstrInfo.h"
> +#include "Thumb2InstrInfo.h"
>
> namespace llvm {
>
> @@ -111,23 +112,27 @@
> };
>
> /// ThumbTargetMachine - Thumb target machine.
> +/// Due to the way architectures are handled, this represents both
> +///   Thumb-1 and Thumb-2.
> ///
> class ThumbTargetMachine : public ARMBaseTargetMachine {
> -  ThumbInstrInfo      InstrInfo;
> -  const TargetData    DataLayout;       // Calculates type size &  
> alignment
> +  ARMBaseInstrInfo    *InstrInfo;   // either Thumb1InstrInfo or  
> Thumb2InstrInfo
> +  const TargetData    DataLayout;   // Calculates type size &  
> alignment
>   ARMTargetLowering   TLInfo;
> public:
>   ThumbTargetMachine(const Module &M, const std::string &FS);
>
> -  virtual const ThumbRegisterInfo  *getRegisterInfo() const {
> -    return &InstrInfo.getRegisterInfo();
> +  /// returns either Thumb1RegisterInfo of Thumb2RegisterInfo
> +  virtual const ARMBaseRegisterInfo *getRegisterInfo() const {
> +    return &InstrInfo->getRegisterInfo();
>   }
>
> -  virtual       ARMTargetLowering *getTargetLowering() const {
> +  virtual ARMTargetLowering *getTargetLowering() const {
>     return const_cast<ARMTargetLowering*>(&TLInfo);
>   }
>
> -  virtual const ThumbInstrInfo   *getInstrInfo() const { return  
> &InstrInfo; }
> +  /// returns either Thumb1InstrInfo or Thumb2InstrInfo
> +  virtual const ARMBaseInstrInfo *getInstrInfo() const { return  
> InstrInfo; }
>   virtual const TargetData       *getTargetData() const { return  
> &DataLayout; }
>
>   static unsigned getJITMatchQuality();
>
> Modified: llvm/trunk/lib/Target/ARM/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/CMakeLists.txt?rev=74731&r1=74730&r2=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/ARM/CMakeLists.txt Thu Jul  2 17:18:33 2009
> @@ -24,8 +24,10 @@
>   ARMSubtarget.cpp
>   ARMTargetAsmInfo.cpp
>   ARMTargetMachine.cpp
> -  ThumbInstrInfo.cpp
> -  ThumbRegisterInfo.cpp
> +  Thumb1InstrInfo.cpp
> +  Thumb1RegisterInfo.cpp
> +  Thumb2InstrInfo.cpp
> +  Thumb2RegisterInfo.cpp
>   )
>
> target_link_libraries (LLVMARMCodeGen LLVMSelectionDAG)
>
> Copied: llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp (from r74702,  
> llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp)
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp?p2=llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp&p1=llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp&r1=74702&r2=74731&rev=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp Thu Jul  2  
> 17:18:33 2009
> @@ -1,4 +1,4 @@
> -//===- ThumbInstrInfo.cpp - Thumb Instruction Information -------- 
> *- C++ -*-===//
> +//===- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information  
> --------*- C++ -*-===//
> //
> //                     The LLVM Compiler Infrastructure
> //
> @@ -7,7 +7,7 @@
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //
> -// This file contains the Thumb implementation of the  
> TargetInstrInfo class.
> +// This file contains the Thumb-1 implementation of the  
> TargetInstrInfo class.
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> @@ -18,24 +18,23 @@
> #include "llvm/CodeGen/MachineFrameInfo.h"
> #include "llvm/CodeGen/MachineInstrBuilder.h"
> #include "llvm/ADT/SmallVector.h"
> -#include "ThumbInstrInfo.h"
> +#include "Thumb1InstrInfo.h"
>
> using namespace llvm;
>
> -ThumbInstrInfo::ThumbInstrInfo(const ARMSubtarget &STI)
> +Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
>   : ARMBaseInstrInfo(STI), RI(*this, STI) {
> }
>
> -bool ThumbInstrInfo::isMoveInstr(const MachineInstr &MI,
> -                                 unsigned &SrcReg, unsigned &DstReg,
> -                                 unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
> +bool Thumb1InstrInfo::isMoveInstr(const MachineInstr &MI,
> +                                  unsigned &SrcReg, unsigned &DstReg,
> +                                  unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
>   SrcSubIdx = DstSubIdx = 0; // No sub-registers.
>
>   unsigned oc = MI.getOpcode();
>   switch (oc) {
>   default:
>     return false;
> -  // FIXME: Thumb2
>   case ARM::tMOVr:
>   case ARM::tMOVhir2lor:
>   case ARM::tMOVlor2hir:
> @@ -50,11 +49,10 @@
>   }
> }
>
> -unsigned ThumbInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> -                                             int &FrameIndex) const {
> +unsigned Thumb1InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> +                                              int &FrameIndex)  
> const {
>   switch (MI->getOpcode()) {
>   default: break;
> -  // FIXME: Thumb2
>   case ARM::tRestore:
>     if (MI->getOperand(1).isFI() &&
>         MI->getOperand(2).isImm() &&
> @@ -67,11 +65,10 @@
>   return 0;
> }
>
> -unsigned ThumbInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> -                                            int &FrameIndex) const {
> +unsigned Thumb1InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> +                                             int &FrameIndex) const {
>   switch (MI->getOpcode()) {
>   default: break;
> -  // FIXME: Thumb2
>   case ARM::tSpill:
>     if (MI->getOperand(1).isFI() &&
>         MI->getOperand(2).isImm() &&
> @@ -84,15 +81,14 @@
>   return 0;
> }
>
> -bool ThumbInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> -                                  MachineBasicBlock::iterator I,
> -                                  unsigned DestReg, unsigned SrcReg,
> -                                  const TargetRegisterClass *DestRC,
> -                                  const TargetRegisterClass *SrcRC)  
> const {
> +bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> +                                   MachineBasicBlock::iterator I,
> +                                   unsigned DestReg, unsigned SrcReg,
> +                                   const TargetRegisterClass *DestRC,
> +                                   const TargetRegisterClass  
> *SrcRC) const {
>   DebugLoc DL = DebugLoc::getUnknownLoc();
>   if (I != MBB.end()) DL = I->getDebugLoc();
>
> -  // FIXME: Thumb2
>   if (DestRC == ARM::GPRRegisterClass) {
>     if (SrcRC == ARM::GPRRegisterClass) {
>       BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg 
> (SrcReg);
> @@ -114,7 +110,7 @@
>   return false;
> }
>
> -bool ThumbInstrInfo::
> +bool Thumb1InstrInfo::
> canFoldMemoryOperand(const MachineInstr *MI,
>                      const SmallVectorImpl<unsigned> &Ops) const {
>   if (Ops.size() != 1) return false;
> @@ -145,7 +141,7 @@
>   return false;
> }
>
> -void ThumbInstrInfo::
> +void Thumb1InstrInfo::
> storeRegToStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
>                     unsigned SrcReg, bool isKill, int FI,
>                     const TargetRegisterClass *RC) const {
> @@ -154,7 +150,6 @@
>
>   assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
>
> -  // FIXME: Thumb2
>   if (RC == ARM::tGPRRegisterClass) {
>     BuildMI(MBB, I, DL, get(ARM::tSpill))
>       .addReg(SrcReg, getKillRegState(isKill))
> @@ -162,15 +157,14 @@
>   }
> }
>
> -void ThumbInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> -                                    bool isKill,
> -                                    SmallVectorImpl<MachineOperand>  
> &Addr,
> -                                    const TargetRegisterClass *RC,
> -                                   SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
> +void Thumb1InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> +                                     bool isKill,
> +                                      
> SmallVectorImpl<MachineOperand> &Addr,
> +                                     const TargetRegisterClass *RC,
> +                                     SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
>   DebugLoc DL = DebugLoc::getUnknownLoc();
>   unsigned Opc = 0;
>
> -  // FIXME: Thumb2. Is GPRRegClass here correct?
>   assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
>   if (RC == ARM::GPRRegisterClass) {
>     Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
> @@ -184,14 +178,13 @@
>   return;
> }
>
> -void ThumbInstrInfo::
> +void Thumb1InstrInfo::
> loadRegFromStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
>                      unsigned DestReg, int FI,
>                      const TargetRegisterClass *RC) const {
>   DebugLoc DL = DebugLoc::getUnknownLoc();
>   if (I != MBB.end()) DL = I->getDebugLoc();
>
> -  // FIXME: Thumb2
>   assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
>
>   if (RC == ARM::tGPRRegisterClass) {
> @@ -200,7 +193,7 @@
>   }
> }
>
> -void ThumbInstrInfo::
> +void Thumb1InstrInfo::
> loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
>                 SmallVectorImpl<MachineOperand> &Addr,
>                 const TargetRegisterClass *RC,
> @@ -208,7 +201,6 @@
>   DebugLoc DL = DebugLoc::getUnknownLoc();
>   unsigned Opc = 0;
>
> -  // FIXME: Thumb2. Is GPRRegClass ok here?
>   if (RC == ARM::GPRRegisterClass) {
>     Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
>   }
> @@ -220,7 +212,7 @@
>   return;
> }
>
> -bool ThumbInstrInfo::
> +bool Thumb1InstrInfo::
> spillCalleeSavedRegisters(MachineBasicBlock &MBB,
>                           MachineBasicBlock::iterator MI,
>                           const std::vector<CalleeSavedInfo> &CSI)  
> const {
> @@ -240,7 +232,7 @@
>   return true;
> }
>
> -bool ThumbInstrInfo::
> +bool Thumb1InstrInfo::
> restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
>                             MachineBasicBlock::iterator MI,
>                             const std::vector<CalleeSavedInfo> &CSI)  
> const {
> @@ -271,7 +263,7 @@
>   return true;
> }
>
> -MachineInstr *ThumbInstrInfo::
> +MachineInstr *Thumb1InstrInfo::
> foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
>                       const SmallVectorImpl<unsigned> &Ops, int FI)  
> const {
>   if (Ops.size() != 1) return NULL;
>
> Copied: llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h (from r74702,  
> llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h)
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h?p2=llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h&p1=llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h&r1=74702&r2=74731&rev=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h Thu Jul  2 17:18:33  
> 2009
> @@ -1,4 +1,4 @@
> -//===- ThumbInstrInfo.h - Thumb Instruction Information ---------- 
> *- C++ -*-===//
> +//===- Thumb1InstrInfo.h - Thumb-1 Instruction Information  
> ----------*- C++ -*-===//
> //
> //                     The LLVM Compiler Infrastructure
> //
> @@ -7,89 +7,87 @@
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //
> -// This file contains the ARM implementation of the TargetInstrInfo  
> class.
> +// This file contains the Thumb-1 implementation of the  
> TargetInstrInfo class.
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> -#ifndef THUMBINSTRUCTIONINFO_H
> -#define THUMBINSTRUCTIONINFO_H
> +#ifndef THUMB1INSTRUCTIONINFO_H
> +#define THUMB1INSTRUCTIONINFO_H
>
> #include "llvm/Target/TargetInstrInfo.h"
> #include "ARM.h"
> #include "ARMInstrInfo.h"
> -#include "ThumbRegisterInfo.h"
> +#include "Thumb1RegisterInfo.h"
>
> namespace llvm {
>   class ARMSubtarget;
>
> -class ThumbInstrInfo : public ARMBaseInstrInfo {
> -  ThumbRegisterInfo RI;
> +class Thumb1InstrInfo : public ARMBaseInstrInfo {
> +  Thumb1RegisterInfo RI;
> public:
> -  explicit ThumbInstrInfo(const ARMSubtarget &STI);
> +  explicit Thumb1InstrInfo(const ARMSubtarget &STI);
>
>   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister  
> info.  As
>   /// such, whenever a client has an instance of instruction info,  
> it should
>   /// always be able to get register info as well (through this  
> method).
>   ///
> -  virtual const ThumbRegisterInfo &getRegisterInfo() const { return  
> RI; }
> +  const Thumb1RegisterInfo &getRegisterInfo() const { return RI; }
>
> -  /// Return true if the instruction is a register to register move  
> and return
> -  /// the source and dest operands and their sub-register indices  
> by reference.
> -  virtual bool isMoveInstr(const MachineInstr &MI,
> +  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                                 MachineBasicBlock::iterator MI,
> +                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
> +  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                                   MachineBasicBlock::iterator MI,
> +                                   const  
> std::vector<CalleeSavedInfo> &CSI) const;
> +
> +  bool isMoveInstr(const MachineInstr &MI,
>                            unsigned &SrcReg, unsigned &DstReg,
>                            unsigned &SrcSubIdx, unsigned &DstSubIdx)  
> const;
> -
> -  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
> +  unsigned isLoadFromStackSlot(const MachineInstr *MI,
>                                        int &FrameIndex) const;
> -  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
> +  unsigned isStoreToStackSlot(const MachineInstr *MI,
>                                       int &FrameIndex) const;
>
> -  virtual bool copyRegToReg(MachineBasicBlock &MBB,
> +  bool copyRegToReg(MachineBasicBlock &MBB,
>                             MachineBasicBlock::iterator I,
>                             unsigned DestReg, unsigned SrcReg,
>                             const TargetRegisterClass *DestRC,
>                             const TargetRegisterClass *SrcRC) const;
> -  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
> +  void storeRegToStackSlot(MachineBasicBlock &MBB,
>                                    MachineBasicBlock::iterator MBBI,
>                                    unsigned SrcReg, bool isKill, int  
> FrameIndex,
>                                    const TargetRegisterClass *RC)  
> const;
>
> -  virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg,  
> bool isKill,
> +  void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool  
> isKill,
>                               SmallVectorImpl<MachineOperand> &Addr,
>                               const TargetRegisterClass *RC,
>                               SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
>
> -  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
> +  void loadRegFromStackSlot(MachineBasicBlock &MBB,
>                                     MachineBasicBlock::iterator MBBI,
>                                     unsigned DestReg, int FrameIndex,
>                                     const TargetRegisterClass *RC)  
> const;
>
> -  virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> +  void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
>                                SmallVectorImpl<MachineOperand> &Addr,
>                                const TargetRegisterClass *RC,
>                                SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
> -  virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                                          
> MachineBasicBlock::iterator MI,
> -                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
> -  virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                                            
> MachineBasicBlock::iterator MI,
> -                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
>
> -  virtual bool canFoldMemoryOperand(const MachineInstr *MI,
> +  bool canFoldMemoryOperand(const MachineInstr *MI,
>                                     const SmallVectorImpl<unsigned>  
> &Ops) const;
>
> -  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> -                                              MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> -                                              MachineInstr* LoadMI)  
> const {
> +  MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> +                                      MachineInstr* MI,
> +                                      const  
> SmallVectorImpl<unsigned> &Ops,
> +                                      int FrameIndex) const;
> +
> +  MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> +                                      MachineInstr* MI,
> +                                      const  
> SmallVectorImpl<unsigned> &Ops,
> +                                      MachineInstr* LoadMI) const {
>     return 0;
>   }
> -
> -  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> -                                              MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> -                                              int FrameIndex) const;
> };
> }
>
> -#endif // THUMBINSTRUCTIONINFO_H
> +#endif // THUMB1INSTRUCTIONINFO_H
>
> Copied: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (from  
> r74702, llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp)
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?p2=llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp&p1=llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp&r1=74702&r2=74731&rev=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Thu Jul  2  
> 17:18:33 2009
> @@ -1,4 +1,4 @@
> -//===- ThumbRegisterInfo.cpp - Thumb Register Information -------*-  
> C++ -*-===//
> +//===- Thumb1RegisterInfo.cpp - Thumb-1 Register Information ------- 
> *- C++ -*-===//
> //
> //                     The LLVM Compiler Infrastructure
> //
> @@ -7,7 +7,7 @@
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //
> -// This file contains the ARM implementation of the  
> TargetRegisterInfo class.
> +// This file contains the Thumb-1 implementation of the  
> TargetRegisterInfo class.
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> @@ -15,8 +15,8 @@
> #include "ARMAddressingModes.h"
> #include "ARMMachineFunctionInfo.h"
> #include "ARMSubtarget.h"
> -#include "ThumbInstrInfo.h"
> -#include "ThumbRegisterInfo.h"
> +#include "Thumb1InstrInfo.h"
> +#include "Thumb1RegisterInfo.h"
> #include "llvm/Constants.h"
> #include "llvm/DerivedTypes.h"
> #include "llvm/CodeGen/MachineConstantPool.h"
> @@ -37,18 +37,18 @@
>                    cl::Hidden,
>                    cl::desc("Enable register scavenging on Thumb"));
>
> -ThumbRegisterInfo::ThumbRegisterInfo(const TargetInstrInfo &tii,
> -                                     const ARMSubtarget &sti)
> +Thumb1RegisterInfo::Thumb1RegisterInfo(const TargetInstrInfo &tii,
> +                                       const ARMSubtarget &sti)
>   : ARMBaseRegisterInfo(tii, sti) {
> }
>
> /// emitLoadConstPool - Emits a load from constpool to materialize the
> /// specified immediate.
> -void ThumbRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
> -                                           
> MachineBasicBlock::iterator &MBBI,
> -                                          unsigned DestReg, int Val,
> -                                          const TargetInstrInfo *TII,
> -                                          DebugLoc dl) const {
> +void Thumb1RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
> +                                            
> MachineBasicBlock::iterator &MBBI,
> +                                           unsigned DestReg, int Val,
> +                                           const TargetInstrInfo  
> *TII,
> +                                           DebugLoc dl) const {
>   MachineFunction &MF = *MBB.getParent();
>   MachineConstantPool *ConstantPool = MF.getConstantPool();
>   Constant *C = ConstantInt::get(Type::Int32Ty, Val);
> @@ -59,7 +59,7 @@
> }
>
> const TargetRegisterClass*
> -ThumbRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT  
> VT) const {
> +Thumb1RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT  
> VT) const {
>   if (isARMLowRegister(Reg))
>     return ARM::tGPRRegisterClass;
>   switch (Reg) {
> @@ -74,11 +74,11 @@
> }
>
> bool
> -ThumbRegisterInfo::requiresRegisterScavenging(const MachineFunction  
> &MF) const {
> +Thumb1RegisterInfo::requiresRegisterScavenging(const  
> MachineFunction &MF) const {
>   return ThumbRegScavenging;
> }
>
> -bool ThumbRegisterInfo::hasReservedCallFrame(MachineFunction &MF)  
> const {
> +bool Thumb1RegisterInfo::hasReservedCallFrame(MachineFunction &MF)  
> const {
>   const MachineFrameInfo *FFI = MF.getFrameInfo();
>   unsigned CFSize = FFI->getMaxCallFrameSize();
>   // It's not always a good idea to include the call frame as part  
> of the
> @@ -101,7 +101,7 @@
>                               unsigned DestReg, unsigned BaseReg,
>                               int NumBytes, bool CanChangeCC,
>                               const TargetInstrInfo &TII,
> -                              const ThumbRegisterInfo& MRI,
> +                              const Thumb1RegisterInfo& MRI,
>                               DebugLoc dl) {
>     bool isHigh = !isARMLowRegister(DestReg) ||
>                   (BaseReg != 0 && !isARMLowRegister(BaseReg));
> @@ -175,7 +175,7 @@
>                                MachineBasicBlock::iterator &MBBI,
>                                unsigned DestReg, unsigned BaseReg,
>                                int NumBytes, const TargetInstrInfo  
> &TII,
> -                               const ThumbRegisterInfo& MRI,
> +                               const Thumb1RegisterInfo& MRI,
>                                DebugLoc dl) {
>   bool isSub = NumBytes < 0;
>   unsigned Bytes = (unsigned)NumBytes;
> @@ -279,13 +279,13 @@
> static void emitSPUpdate(MachineBasicBlock &MBB,
>                          MachineBasicBlock::iterator &MBBI,
>                          const TargetInstrInfo &TII, DebugLoc dl,
> -                         const ThumbRegisterInfo &MRI,
> +                         const Thumb1RegisterInfo &MRI,
>                          int NumBytes) {
>   emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,  
> TII,
>                             MRI, dl);
> }
>
> -void ThumbRegisterInfo::
> +void Thumb1RegisterInfo::
> eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock  
> &MBB,
>                               MachineBasicBlock::iterator I) const {
>   if (!hasReservedCallFrame(MF)) {
> @@ -321,7 +321,7 @@
>                               MachineBasicBlock::iterator &MBBI,
>                               unsigned DestReg, int Imm,
>                               const TargetInstrInfo &TII,
> -                              const ThumbRegisterInfo& MRI,
> +                              const Thumb1RegisterInfo& MRI,
>                               DebugLoc dl) {
>   bool isSub = Imm < 0;
>   if (isSub) Imm = -Imm;
> @@ -337,8 +337,8 @@
>       .addReg(DestReg, RegState::Kill);
> }
>
> -void ThumbRegisterInfo::eliminateFrameIndex 
> (MachineBasicBlock::iterator II,
> -                                            int SPAdj, RegScavenger  
> *RS) const{
> +void Thumb1RegisterInfo::eliminateFrameIndex 
> (MachineBasicBlock::iterator II,
> +                                             int SPAdj,  
> RegScavenger *RS) const{
>   unsigned i = 0;
>   MachineInstr &MI = *II;
>   MachineBasicBlock &MBB = *MI.getParent();
> @@ -566,7 +566,7 @@
>     assert(false && "Unexpected opcode!");
> }
>
> -void ThumbRegisterInfo::emitPrologue(MachineFunction &MF) const {
> +void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
>   MachineBasicBlock &MBB = MF.front();
>   MachineBasicBlock::iterator MBBI = MBB.begin();
>   MachineFrameInfo  *MFI = MF.getFrameInfo();
> @@ -690,8 +690,8 @@
>           isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
> }
>
> -void ThumbRegisterInfo::emitEpilogue(MachineFunction &MF,
> -                                   MachineBasicBlock &MBB) const {
> +void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
> +                                      MachineBasicBlock &MBB) const {
>   MachineBasicBlock::iterator MBBI = prior(MBB.end());
>   assert((MBBI->getOpcode() == ARM::tBX_RET ||
>           MBBI->getOpcode() == ARM::tPOP_RET) &&
>
> Copied: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h (from r74702,  
> llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h)
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h?p2=llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h&p1=llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h&r1=74702&r2=74731&rev=74731&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.h Thu Jul  2  
> 17:18:33 2009
> @@ -1,4 +1,4 @@
> -//===- ThumbRegisterInfo.h - Thumb Register Information Impl ----*-  
> C++ -*-===//
> +//===- Thumb1RegisterInfo.h - Thumb-1 Register Information Impl ---- 
> *- C++ -*-===//
> //
> //                     The LLVM Compiler Infrastructure
> //
> @@ -7,12 +7,12 @@
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //
> -// This file contains the ARM implementation of the  
> TargetRegisterInfo class.
> +// This file contains the Thumb-1 implementation of the  
> TargetRegisterInfo class.
> //
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> -#ifndef THUMBREGISTERINFO_H
> -#define THUMBREGISTERINFO_H
> +#ifndef THUMB1REGISTERINFO_H
> +#define THUMB1REGISTERINFO_H
>
> #include "ARM.h"
> #include "ARMRegisterInfo.h"
> @@ -23,9 +23,9 @@
>   class TargetInstrInfo;
>   class Type;
>
> -struct ThumbRegisterInfo : public ARMBaseRegisterInfo {
> +struct Thumb1RegisterInfo : public ARMBaseRegisterInfo {
> public:
> -  ThumbRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget  
> &STI);
> +  Thumb1RegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget  
> &STI);
>
>   /// emitLoadConstPool - Emits a load from constpool to materialize  
> the
>   /// specified immediate.
> @@ -57,4 +57,4 @@
> };
> }
>
> -#endif // THUMBREGISTERINFO_H
> +#endif // THUMB1REGISTERINFO_H
>
> Added: llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp?rev=74731&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp (added)
> +++ llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp Thu Jul  2  
> 17:18:33 2009
> @@ -0,0 +1,312 @@
> +//===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information  
> --------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// This file contains the Thumb-2 implementation of the  
> TargetInstrInfo class.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#include "ARMInstrInfo.h"
> +#include "ARM.h"
> +#include "ARMGenInstrInfo.inc"
> +#include "ARMMachineFunctionInfo.h"
> +#include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "Thumb2InstrInfo.h"
> +
> +using namespace llvm;
> +
> +Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
> +  : ARMBaseInstrInfo(STI), RI(*this, STI) {
> +}
> +
> +bool Thumb2InstrInfo::isMoveInstr(const MachineInstr &MI,
> +                                  unsigned &SrcReg, unsigned &DstReg,
> +                                  unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
> +  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
> +
> +  unsigned oc = MI.getOpcode();
> +  switch (oc) {
> +  default:
> +    return false;
> +  // FIXME: Thumb2
> +  case ARM::tMOVr:
> +  case ARM::tMOVhir2lor:
> +  case ARM::tMOVlor2hir:
> +  case ARM::tMOVhir2hir:
> +    assert(MI.getDesc().getNumOperands() >= 2 &&
> +           MI.getOperand(0).isReg() &&
> +           MI.getOperand(1).isReg() &&
> +           "Invalid Thumb MOV instruction");
> +    SrcReg = MI.getOperand(1).getReg();
> +    DstReg = MI.getOperand(0).getReg();
> +    return true;
> +  }
> +}
> +
> +unsigned Thumb2InstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> +                                              int &FrameIndex)  
> const {
> +  switch (MI->getOpcode()) {
> +  default: break;
> +  // FIXME: Thumb2
> +  case ARM::tRestore:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isImm() &&
> +        MI->getOperand(2).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  }
> +  return 0;
> +}
> +
> +unsigned Thumb2InstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> +                                             int &FrameIndex) const {
> +  switch (MI->getOpcode()) {
> +  default: break;
> +  // FIXME: Thumb2
> +  case ARM::tSpill:
> +    if (MI->getOperand(1).isFI() &&
> +        MI->getOperand(2).isImm() &&
> +        MI->getOperand(2).getImm() == 0) {
> +      FrameIndex = MI->getOperand(1).getIndex();
> +      return MI->getOperand(0).getReg();
> +    }
> +    break;
> +  }
> +  return 0;
> +}
> +
> +bool Thumb2InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> +                                   MachineBasicBlock::iterator I,
> +                                   unsigned DestReg, unsigned SrcReg,
> +                                   const TargetRegisterClass *DestRC,
> +                                   const TargetRegisterClass  
> *SrcRC) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  // FIXME: Thumb2
> +  if (DestRC == ARM::GPRRegisterClass) {
> +    if (SrcRC == ARM::GPRRegisterClass) {
> +      BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg 
> (SrcReg);
> +      return true;
> +    } else if (SrcRC == ARM::tGPRRegisterClass) {
> +      BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg 
> (SrcReg);
> +      return true;
> +    }
> +  } else if (DestRC == ARM::tGPRRegisterClass) {
> +    if (SrcRC == ARM::GPRRegisterClass) {
> +      BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg 
> (SrcReg);
> +      return true;
> +    } else if (SrcRC == ARM::tGPRRegisterClass) {
> +      BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
> +      return true;
> +    }
> +  }
> +
> +  return false;
> +}
> +
> +bool Thumb2InstrInfo::
> +canFoldMemoryOperand(const MachineInstr *MI,
> +                     const SmallVectorImpl<unsigned> &Ops) const {
> +  if (Ops.size() != 1) return false;
> +
> +  unsigned OpNum = Ops[0];
> +  unsigned Opc = MI->getOpcode();
> +  switch (Opc) {
> +  default: break;
> +  case ARM::tMOVr:
> +  case ARM::tMOVlor2hir:
> +  case ARM::tMOVhir2lor:
> +  case ARM::tMOVhir2hir: {
> +    if (OpNum == 0) { // move -> store
> +      unsigned SrcReg = MI->getOperand(1).getReg();
> +      if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
> +        // tSpill cannot take a high register operand.
> +        return false;
> +    } else {          // move -> load
> +      unsigned DstReg = MI->getOperand(0).getReg();
> +      if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
> +        // tRestore cannot target a high register operand.
> +        return false;
> +    }
> +    return true;
> +  }
> +  }
> +
> +  return false;
> +}
> +
> +void Thumb2InstrInfo::
> +storeRegToStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> +                    unsigned SrcReg, bool isKill, int FI,
> +                    const TargetRegisterClass *RC) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
> +
> +  // FIXME: Thumb2
> +  if (RC == ARM::tGPRRegisterClass) {
> +    BuildMI(MBB, I, DL, get(ARM::tSpill))
> +      .addReg(SrcReg, getKillRegState(isKill))
> +      .addFrameIndex(FI).addImm(0);
> +  }
> +}
> +
> +void Thumb2InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> +                                     bool isKill,
> +                                      
> SmallVectorImpl<MachineOperand> &Addr,
> +                                     const TargetRegisterClass *RC,
> +                                     SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  unsigned Opc = 0;
> +
> +  // FIXME: Thumb2. Is GPRRegClass here correct?
> +  assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
> +  if (RC == ARM::GPRRegisterClass) {
> +    Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
> +  }
> +
> +  MachineInstrBuilder MIB =
> +    BuildMI(MF, DL,  get(Opc)).addReg(SrcReg, getKillRegState 
> (isKill));
> +  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> +    MIB.addOperand(Addr[i]);
> +  NewMIs.push_back(MIB);
> +  return;
> +}
> +
> +void Thumb2InstrInfo::
> +loadRegFromStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> +                     unsigned DestReg, int FI,
> +                     const TargetRegisterClass *RC) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (I != MBB.end()) DL = I->getDebugLoc();
> +
> +  // FIXME: Thumb2
> +  assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
> +
> +  if (RC == ARM::tGPRRegisterClass) {
> +    BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
> +      .addFrameIndex(FI).addImm(0);
> +  }
> +}
> +
> +void Thumb2InstrInfo::
> +loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> +                SmallVectorImpl<MachineOperand> &Addr,
> +                const TargetRegisterClass *RC,
> +                SmallVectorImpl<MachineInstr*> &NewMIs) const {
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  unsigned Opc = 0;
> +
> +  // FIXME: Thumb2. Is GPRRegClass ok here?
> +  if (RC == ARM::GPRRegisterClass) {
> +    Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
> +  }
> +
> +  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
> +  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> +    MIB.addOperand(Addr[i]);
> +  NewMIs.push_back(MIB);
> +  return;
> +}
> +
> +bool Thumb2InstrInfo::
> +spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                          MachineBasicBlock::iterator MI,
> +                          const std::vector<CalleeSavedInfo> &CSI)  
> const {
> +  if (CSI.empty())
> +    return false;
> +
> +  DebugLoc DL = DebugLoc::getUnknownLoc();
> +  if (MI != MBB.end()) DL = MI->getDebugLoc();
> +
> +  MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
> +  for (unsigned i = CSI.size(); i != 0; --i) {
> +    unsigned Reg = CSI[i-1].getReg();
> +    // Add the callee-saved register as live-in. It's killed at the  
> spill.
> +    MBB.addLiveIn(Reg);
> +    MIB.addReg(Reg, RegState::Kill);
> +  }
> +  return true;
> +}
> +
> +bool Thumb2InstrInfo::
> +restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                            MachineBasicBlock::iterator MI,
> +                            const std::vector<CalleeSavedInfo>  
> &CSI) const {
> +  MachineFunction &MF = *MBB.getParent();
> +  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> +  if (CSI.empty())
> +    return false;
> +
> +  bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
> +  MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI- 
> >getDebugLoc());
> +  for (unsigned i = CSI.size(); i != 0; --i) {
> +    unsigned Reg = CSI[i-1].getReg();
> +    if (Reg == ARM::LR) {
> +      // Special epilogue for vararg functions. See emitEpilogue
> +      if (isVarArg)
> +        continue;
> +      Reg = ARM::PC;
> +      PopMI->setDesc(get(ARM::tPOP_RET));
> +      MI = MBB.erase(MI);
> +    }
> +    PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
> +  }
> +
> +  // It's illegal to emit pop instruction without operands.
> +  if (PopMI->getNumOperands() > 0)
> +    MBB.insert(MI, PopMI);
> +
> +  return true;
> +}
> +
> +MachineInstr *Thumb2InstrInfo::
> +foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
> +                      const SmallVectorImpl<unsigned> &Ops, int FI)  
> const {
> +  if (Ops.size() != 1) return NULL;
> +
> +  unsigned OpNum = Ops[0];
> +  unsigned Opc = MI->getOpcode();
> +  MachineInstr *NewMI = NULL;
> +  switch (Opc) {
> +  default: break;
> +  case ARM::tMOVr:
> +  case ARM::tMOVlor2hir:
> +  case ARM::tMOVhir2lor:
> +  case ARM::tMOVhir2hir: {
> +    if (OpNum == 0) { // move -> store
> +      unsigned SrcReg = MI->getOperand(1).getReg();
> +      bool isKill = MI->getOperand(1).isKill();
> +      if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
> +        // tSpill cannot take a high register operand.
> +        break;
> +      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
> +        .addReg(SrcReg, getKillRegState(isKill))
> +        .addFrameIndex(FI).addImm(0);
> +    } else {          // move -> load
> +      unsigned DstReg = MI->getOperand(0).getReg();
> +      if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
> +        // tRestore cannot target a high register operand.
> +        break;
> +      bool isDead = MI->getOperand(0).isDead();
> +      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
> +        .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
> +        .addFrameIndex(FI).addImm(0);
> +    }
> +    break;
> +  }
> +  }
> +
> +  return NewMI;
> +}
>
> Added: llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h?rev=74731&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h (added)
> +++ llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h Thu Jul  2 17:18:33  
> 2009
> @@ -0,0 +1,93 @@
> +//===- Thumb2InstrInfo.h - Thumb-2 Instruction Information  
> ----------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// This file contains the Thumb-2 implementation of the  
> TargetInstrInfo class.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#ifndef THUMB2INSTRUCTIONINFO_H
> +#define THUMB2INSTRUCTIONINFO_H
> +
> +#include "llvm/Target/TargetInstrInfo.h"
> +#include "ARM.h"
> +#include "ARMInstrInfo.h"
> +#include "Thumb2RegisterInfo.h"
> +
> +namespace llvm {
> +  class ARMSubtarget;
> +
> +class Thumb2InstrInfo : public ARMBaseInstrInfo {
> +  Thumb2RegisterInfo RI;
> +public:
> +  explicit Thumb2InstrInfo(const ARMSubtarget &STI);
> +
> +  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister  
> info.  As
> +  /// such, whenever a client has an instance of instruction info,  
> it should
> +  /// always be able to get register info as well (through this  
> method).
> +  ///
> +  const Thumb2RegisterInfo &getRegisterInfo() const { return RI; }
> +
> +  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                                 MachineBasicBlock::iterator MI,
> +                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
> +  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> +                                   MachineBasicBlock::iterator MI,
> +                                   const  
> std::vector<CalleeSavedInfo> &CSI) const;
> +
> +  bool isMoveInstr(const MachineInstr &MI,
> +                           unsigned &SrcReg, unsigned &DstReg,
> +                           unsigned &SrcSubIdx, unsigned  
> &DstSubIdx) const;
> +  unsigned isLoadFromStackSlot(const MachineInstr *MI,
> +                                       int &FrameIndex) const;
> +  unsigned isStoreToStackSlot(const MachineInstr *MI,
> +                                      int &FrameIndex) const;
> +
> +  bool copyRegToReg(MachineBasicBlock &MBB,
> +                            MachineBasicBlock::iterator I,
> +                            unsigned DestReg, unsigned SrcReg,
> +                            const TargetRegisterClass *DestRC,
> +                            const TargetRegisterClass *SrcRC) const;
> +  void storeRegToStackSlot(MachineBasicBlock &MBB,
> +                                   MachineBasicBlock::iterator MBBI,
> +                                   unsigned SrcReg, bool isKill,  
> int FrameIndex,
> +                                   const TargetRegisterClass *RC)  
> const;
> +
> +  void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool  
> isKill,
> +                              SmallVectorImpl<MachineOperand> &Addr,
> +                              const TargetRegisterClass *RC,
> +                              SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
> +
> +  void loadRegFromStackSlot(MachineBasicBlock &MBB,
> +                                    MachineBasicBlock::iterator MBBI,
> +                                    unsigned DestReg, int FrameIndex,
> +                                    const TargetRegisterClass *RC)  
> const;
> +
> +  void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> +                               SmallVectorImpl<MachineOperand> &Addr,
> +                               const TargetRegisterClass *RC,
> +                               SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
> +
> +  bool canFoldMemoryOperand(const MachineInstr *MI,
> +                                    const SmallVectorImpl<unsigned>  
> &Ops) const;
> +
> +  MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> +                                      MachineInstr* MI,
> +                                      const  
> SmallVectorImpl<unsigned> &Ops,
> +                                      int FrameIndex) const;
> +
> +  MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> +                                      MachineInstr* MI,
> +                                      const  
> SmallVectorImpl<unsigned> &Ops,
> +                                      MachineInstr* LoadMI) const {
> +    return 0;
> +  }
> +};
> +}
> +
> +#endif // THUMB2INSTRUCTIONINFO_H
>
> Added: llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp?rev=74731&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp (added)
> +++ llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.cpp Thu Jul  2  
> 17:18:33 2009
> @@ -0,0 +1,755 @@
> +//===- Thumb2RegisterInfo.cpp - Thumb-2 Register Information ------- 
> *- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// This file contains the Thumb-2 implementation of the  
> TargetRegisterInfo class.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#include "ARM.h"
> +#include "ARMAddressingModes.h"
> +#include "ARMMachineFunctionInfo.h"
> +#include "ARMSubtarget.h"
> +#include "Thumb2InstrInfo.h"
> +#include "Thumb2RegisterInfo.h"
> +#include "llvm/Constants.h"
> +#include "llvm/DerivedTypes.h"
> +#include "llvm/CodeGen/MachineConstantPool.h"
> +#include "llvm/CodeGen/MachineFrameInfo.h"
> +#include "llvm/CodeGen/MachineFunction.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/CodeGen/MachineLocation.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/Target/TargetFrameInfo.h"
> +#include "llvm/Target/TargetMachine.h"
> +#include "llvm/ADT/BitVector.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/Support/CommandLine.h"
> +using namespace llvm;
> +
> +static cl::opt<bool>
> +Thumb2RegScavenging("enable-thumb2-reg-scavenging",
> +                    cl::Hidden,
> +                    cl::desc("Enable register scavenging on  
> Thumb-2"));
> +
> +Thumb2RegisterInfo::Thumb2RegisterInfo(const TargetInstrInfo &tii,
> +                                       const ARMSubtarget &sti)
> +  : ARMBaseRegisterInfo(tii, sti) {
> +}
> +
> +/// emitLoadConstPool - Emits a load from constpool to materialize  
> the
> +/// specified immediate.
> +void Thumb2RegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
> +                                            
> MachineBasicBlock::iterator &MBBI,
> +                                           unsigned DestReg, int Val,
> +                                           const TargetInstrInfo  
> *TII,
> +                                           DebugLoc dl) const {
> +  MachineFunction &MF = *MBB.getParent();
> +  MachineConstantPool *ConstantPool = MF.getConstantPool();
> +  Constant *C = ConstantInt::get(Type::Int32Ty, Val);
> +  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
> +
> +  BuildMI(MBB, MBBI, dl, TII->get(ARM::tLDRcp), DestReg)
> +    .addConstantPoolIndex(Idx);
> +}
> +
> +const TargetRegisterClass*
> +Thumb2RegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT  
> VT) const {
> +  if (isARMLowRegister(Reg))
> +    return ARM::tGPRRegisterClass;
> +  switch (Reg) {
> +   default:
> +    break;
> +   case ARM::R8:  case ARM::R9:  case ARM::R10:  case ARM::R11:
> +   case ARM::R12: case ARM::SP:  case ARM::LR:   case ARM::PC:
> +    return ARM::GPRRegisterClass;
> +  }
> +
> +  return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
> +}
> +
> +bool
> +Thumb2RegisterInfo::requiresRegisterScavenging(const  
> MachineFunction &MF) const {
> +  return Thumb2RegScavenging;
> +}
> +
> +bool Thumb2RegisterInfo::hasReservedCallFrame(MachineFunction &MF)  
> const {
> +  const MachineFrameInfo *FFI = MF.getFrameInfo();
> +  unsigned CFSize = FFI->getMaxCallFrameSize();
> +  // It's not always a good idea to include the call frame as part  
> of the
> +  // stack frame. ARM (especially Thumb) has small immediate offset  
> to
> +  // address the stack frame. So a large call frame can cause poor  
> codegen
> +  // and may even makes it impossible to scavenge a register.
> +  if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
> +    return false;
> +
> +  return !MF.getFrameInfo()->hasVarSizedObjects();
> +}
> +
> +/// emitThumbRegPlusImmInReg - Emits a series of instructions to  
> materialize
> +/// a destreg = basereg + immediate in Thumb code. Materialize the  
> immediate
> +/// in a register using mov / mvn sequences or load the immediate  
> from a
> +/// constpool entry.
> +static
> +void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
> +                              MachineBasicBlock::iterator &MBBI,
> +                              unsigned DestReg, unsigned BaseReg,
> +                              int NumBytes, bool CanChangeCC,
> +                              const TargetInstrInfo &TII,
> +                              const Thumb2RegisterInfo& MRI,
> +                              DebugLoc dl) {
> +    bool isHigh = !isARMLowRegister(DestReg) ||
> +                  (BaseReg != 0 && !isARMLowRegister(BaseReg));
> +    bool isSub = false;
> +    // Subtract doesn't have high register version. Load the  
> negative value
> +    // if either base or dest register is a high register. Also, if  
> do not
> +    // issue sub as part of the sequence if condition register is  
> to be
> +    // preserved.
> +    if (NumBytes < 0 && !isHigh && CanChangeCC) {
> +      isSub = true;
> +      NumBytes = -NumBytes;
> +    }
> +    unsigned LdReg = DestReg;
> +    if (DestReg == ARM::SP) {
> +      assert(BaseReg == ARM::SP && "Unexpected!");
> +      LdReg = ARM::R3;
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> +        .addReg(ARM::R3, RegState::Kill);
> +    }
> +
> +    if (NumBytes <= 255 && NumBytes >= 0)
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm 
> (NumBytes);
> +    else if (NumBytes < 0 && NumBytes >= -255) {
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm 
> (NumBytes);
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
> +        .addReg(LdReg, RegState::Kill);
> +    } else
> +      MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, &TII, dl);
> +
> +    // Emit add / sub.
> +    int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr :  
> ARM::tADDrr);
> +    const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
> +                                            TII.get(Opc), DestReg);
> +    if (DestReg == ARM::SP || isSub)
> +      MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
> +    else
> +      MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
> +    if (DestReg == ARM::SP)
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
> +        .addReg(ARM::R12, RegState::Kill);
> +}
> +
> +/// calcNumMI - Returns the number of instructions required to  
> materialize
> +/// the specific add / sub r, c instruction.
> +static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
> +                          unsigned NumBits, unsigned Scale) {
> +  unsigned NumMIs = 0;
> +  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
> +
> +  if (Opc == ARM::tADDrSPi) {
> +    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> +    Bytes -= ThisVal;
> +    NumMIs++;
> +    NumBits = 8;
> +    Scale = 1;  // Followed by a number of tADDi8.
> +    Chunk = ((1 << NumBits) - 1) * Scale;
> +  }
> +
> +  NumMIs += Bytes / Chunk;
> +  if ((Bytes % Chunk) != 0)
> +    NumMIs++;
> +  if (ExtraOpc)
> +    NumMIs++;
> +  return NumMIs;
> +}
> +
> +/// emitThumbRegPlusImmediate - Emits a series of instructions to  
> materialize
> +/// a destreg = basereg + immediate in Thumb code.
> +static
> +void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
> +                               MachineBasicBlock::iterator &MBBI,
> +                               unsigned DestReg, unsigned BaseReg,
> +                               int NumBytes, const TargetInstrInfo  
> &TII,
> +                               const Thumb2RegisterInfo& MRI,
> +                               DebugLoc dl) {
> +  bool isSub = NumBytes < 0;
> +  unsigned Bytes = (unsigned)NumBytes;
> +  if (isSub) Bytes = -NumBytes;
> +  bool isMul4 = (Bytes & 3) == 0;
> +  bool isTwoAddr = false;
> +  bool DstNotEqBase = false;
> +  unsigned NumBits = 1;
> +  unsigned Scale = 1;
> +  int Opc = 0;
> +  int ExtraOpc = 0;
> +
> +  if (DestReg == BaseReg && BaseReg == ARM::SP) {
> +    assert(isMul4 && "Thumb sp inc / dec size must be multiple of  
> 4!");
> +    NumBits = 7;
> +    Scale = 4;
> +    Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
> +    isTwoAddr = true;
> +  } else if (!isSub && BaseReg == ARM::SP) {
> +    // r1 = add sp, 403
> +    // =>
> +    // r1 = add sp, 100 * 4
> +    // r1 = add r1, 3
> +    if (!isMul4) {
> +      Bytes &= ~3;
> +      ExtraOpc = ARM::tADDi3;
> +    }
> +    NumBits = 8;
> +    Scale = 4;
> +    Opc = ARM::tADDrSPi;
> +  } else {
> +    // sp = sub sp, c
> +    // r1 = sub sp, c
> +    // r8 = sub sp, c
> +    if (DestReg != BaseReg)
> +      DstNotEqBase = true;
> +    NumBits = 8;
> +    Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
> +    isTwoAddr = true;
> +  }
> +
> +  unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
> +  unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
> +  if (NumMIs > Threshold) {
> +    // This will expand into too many instructions. Load the  
> immediate from a
> +    // constpool entry.
> +    emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes,  
> true, TII,
> +                             MRI, dl);
> +    return;
> +  }
> +
> +  if (DstNotEqBase) {
> +    if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
> +      // If both are low registers, emit DestReg = add BaseReg, max 
> (Imm, 7)
> +      unsigned Chunk = (1 << 3) - 1;
> +      unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> +      Bytes -= ThisVal;
> +      BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 :  
> ARM::tADDi3), DestReg)
> +        .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
> +    } else {
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
> +        .addReg(BaseReg, RegState::Kill);
> +    }
> +    BaseReg = DestReg;
> +  }
> +
> +  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
> +  while (Bytes) {
> +    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> +    Bytes -= ThisVal;
> +    ThisVal /= Scale;
> +    // Build the new tADD / tSUB.
> +    if (isTwoAddr)
> +      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
> +        .addReg(DestReg).addImm(ThisVal);
> +    else {
> +      bool isKill = BaseReg != ARM::SP;
> +      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
> +        .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
> +      BaseReg = DestReg;
> +
> +      if (Opc == ARM::tADDrSPi) {
> +        // r4 = add sp, imm
> +        // r4 = add r4, imm
> +        // ...
> +        NumBits = 8;
> +        Scale = 1;
> +        Chunk = ((1 << NumBits) - 1) * Scale;
> +        Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
> +        isTwoAddr = true;
> +      }
> +    }
> +  }
> +
> +  if (ExtraOpc)
> +    BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
> +      .addReg(DestReg, RegState::Kill)
> +      .addImm(((unsigned)NumBytes) & 3);
> +}
> +
> +static void emitSPUpdate(MachineBasicBlock &MBB,
> +                         MachineBasicBlock::iterator &MBBI,
> +                         const TargetInstrInfo &TII, DebugLoc dl,
> +                         const Thumb2RegisterInfo &MRI,
> +                         int NumBytes) {
> +  emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,  
> TII,
> +                            MRI, dl);
> +}
> +
> +void Thumb2RegisterInfo::
> +eliminateCallFramePseudoInstr(MachineFunction &MF,  
> MachineBasicBlock &MBB,
> +                              MachineBasicBlock::iterator I) const {
> +  if (!hasReservedCallFrame(MF)) {
> +    // If we have alloca, convert as follows:
> +    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
> +    // ADJCALLSTACKUP   -> add, sp, sp, amount
> +    MachineInstr *Old = I;
> +    DebugLoc dl = Old->getDebugLoc();
> +    unsigned Amount = Old->getOperand(0).getImm();
> +    if (Amount != 0) {
> +      // We need to keep the stack aligned properly.  To do this,  
> we round the
> +      // amount of space needed for the outgoing arguments up to  
> the next
> +      // alignment boundary.
> +      unsigned Align = MF.getTarget().getFrameInfo()- 
> >getStackAlignment();
> +      Amount = (Amount+Align-1)/Align*Align;
> +
> +      // Replace the pseudo instruction with a new instruction...
> +      unsigned Opc = Old->getOpcode();
> +      if (Opc == ARM::ADJCALLSTACKDOWN || Opc ==  
> ARM::tADJCALLSTACKDOWN) {
> +        emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
> +      } else {
> +        assert(Opc == ARM::ADJCALLSTACKUP || Opc ==  
> ARM::tADJCALLSTACKUP);
> +        emitSPUpdate(MBB, I, TII, dl, *this, Amount);
> +      }
> +    }
> +  }
> +  MBB.erase(I);
> +}
> +
> +/// emitThumbConstant - Emit a series of instructions to  
> materialize a
> +/// constant.
> +static void emitThumbConstant(MachineBasicBlock &MBB,
> +                              MachineBasicBlock::iterator &MBBI,
> +                              unsigned DestReg, int Imm,
> +                              const TargetInstrInfo &TII,
> +                              const Thumb2RegisterInfo& MRI,
> +                              DebugLoc dl) {
> +  bool isSub = Imm < 0;
> +  if (isSub) Imm = -Imm;
> +
> +  int Chunk = (1 << 8) - 1;
> +  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
> +  Imm -= ThisVal;
> +  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm 
> (ThisVal);
> +  if (Imm > 0)
> +    emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm,  
> TII, MRI, dl);
> +  if (isSub)
> +    BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
> +      .addReg(DestReg, RegState::Kill);
> +}
> +
> +void Thumb2RegisterInfo::eliminateFrameIndex 
> (MachineBasicBlock::iterator II,
> +                                             int SPAdj,  
> RegScavenger *RS) const{
> +  unsigned i = 0;
> +  MachineInstr &MI = *II;
> +  MachineBasicBlock &MBB = *MI.getParent();
> +  MachineFunction &MF = *MBB.getParent();
> +  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> +  DebugLoc dl = MI.getDebugLoc();
> +
> +  while (!MI.getOperand(i).isFI()) {
> +    ++i;
> +    assert(i < MI.getNumOperands() && "Instr doesn't have  
> FrameIndex operand!");
> +  }
> +
> +  unsigned FrameReg = ARM::SP;
> +  int FrameIndex = MI.getOperand(i).getIndex();
> +  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
> +               MF.getFrameInfo()->getStackSize() + SPAdj;
> +
> +  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
> +    Offset -= AFI->getGPRCalleeSavedArea1Offset();
> +  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
> +    Offset -= AFI->getGPRCalleeSavedArea2Offset();
> +  else if (hasFP(MF)) {
> +    assert(SPAdj == 0 && "Unexpected");
> +    // There is alloca()'s in this function, must reference off the  
> frame
> +    // pointer instead.
> +    FrameReg = getFrameRegister(MF);
> +    Offset -= AFI->getFramePtrSpillOffset();
> +  }
> +
> +  unsigned Opcode = MI.getOpcode();
> +  const TargetInstrDesc &Desc = MI.getDesc();
> +  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
> +
> +  if (Opcode == ARM::tADDrSPi) {
> +    Offset += MI.getOperand(i+1).getImm();
> +
> +    // Can't use tADDrSPi if it's based off the frame pointer.
> +    unsigned NumBits = 0;
> +    unsigned Scale = 1;
> +    if (FrameReg != ARM::SP) {
> +      Opcode = ARM::tADDi3;
> +      MI.setDesc(TII.get(ARM::tADDi3));
> +      NumBits = 3;
> +    } else {
> +      NumBits = 8;
> +      Scale = 4;
> +      assert((Offset & 3) == 0 &&
> +             "Thumb add/sub sp, #imm immediate must be multiple of  
> 4!");
> +    }
> +
> +    if (Offset == 0) {
> +      // Turn it into a move.
> +      MI.setDesc(TII.get(ARM::tMOVhir2lor));
> +      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> +      MI.RemoveOperand(i+1);
> +      return;
> +    }
> +
> +    // Common case: small offset, fits into instruction.
> +    unsigned Mask = (1 << NumBits) - 1;
> +    if (((Offset / Scale) & ~Mask) == 0) {
> +      // Replace the FrameIndex with sp / fp
> +      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> +      MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
> +      return;
> +    }
> +
> +    unsigned DestReg = MI.getOperand(0).getReg();
> +    unsigned Bytes = (Offset > 0) ? Offset : -Offset;
> +    unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
> +    // MI would expand into a large number of instructions. Don't  
> try to
> +    // simplify the immediate.
> +    if (NumMIs > 2) {
> +      emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset,  
> TII,
> +                                *this, dl);
> +      MBB.erase(II);
> +      return;
> +    }
> +
> +    if (Offset > 0) {
> +      // Translate r0 = add sp, imm to
> +      // r0 = add sp, 255*4
> +      // r0 = add r0, (imm - 255*4)
> +      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> +      MI.getOperand(i+1).ChangeToImmediate(Mask);
> +      Offset = (Offset - Mask * Scale);
> +      MachineBasicBlock::iterator NII = next(II);
> +      emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset,  
> TII,
> +                                *this, dl);
> +    } else {
> +      // Translate r0 = add sp, -imm to
> +      // r0 = -imm (this is then translated into a series of  
> instructons)
> +      // r0 = add r0, sp
> +      emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
> +      MI.setDesc(TII.get(ARM::tADDhirr));
> +      MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
> +      MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
> +    }
> +    return;
> +  } else {
> +    unsigned ImmIdx = 0;
> +    int InstrOffs = 0;
> +    unsigned NumBits = 0;
> +    unsigned Scale = 1;
> +    switch (AddrMode) {
> +    case ARMII::AddrModeT1_s: {
> +      ImmIdx = i+1;
> +      InstrOffs = MI.getOperand(ImmIdx).getImm();
> +      NumBits = (FrameReg == ARM::SP) ? 8 : 5;
> +      Scale = 4;
> +      break;
> +    }
> +    default:
> +      assert(0 && "Unsupported addressing mode!");
> +      abort();
> +      break;
> +    }
> +
> +    Offset += InstrOffs * Scale;
> +    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
> +
> +    // Common case: small offset, fits into instruction.
> +    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
> +    int ImmedOffset = Offset / Scale;
> +    unsigned Mask = (1 << NumBits) - 1;
> +    if ((unsigned)Offset <= Mask * Scale) {
> +      // Replace the FrameIndex with sp
> +      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> +      ImmOp.ChangeToImmediate(ImmedOffset);
> +      return;
> +    }
> +
> +    bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode ==  
> ARM::tSpill;
> +    if (AddrMode == ARMII::AddrModeT1_s) {
> +      // Thumb tLDRspi, tSTRspi. These will change to instructions  
> that use
> +      // a different base register.
> +      NumBits = 5;
> +      Mask = (1 << NumBits) - 1;
> +    }
> +    // If this is a thumb spill / restore, we will be using a  
> constpool load to
> +    // materialize the offset.
> +    if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore)
> +      ImmOp.ChangeToImmediate(0);
> +    else {
> +      // Otherwise, it didn't fit. Pull in what we can to simplify  
> the immed.
> +      ImmedOffset = ImmedOffset & Mask;
> +      ImmOp.ChangeToImmediate(ImmedOffset);
> +      Offset &= ~(Mask*Scale);
> +    }
> +  }
> +
> +  // If we get here, the immediate doesn't fit into the  
> instruction.  We folded
> +  // as much as possible above, handle the rest, providing a  
> register that is
> +  // SP+LargeImm.
> +  assert(Offset && "This code isn't needed if offset already  
> handled!");
> +
> +  if (Desc.mayLoad()) {
> +    // Use the destination register to materialize sp + offset.
> +    unsigned TmpReg = MI.getOperand(0).getReg();
> +    bool UseRR = false;
> +    if (Opcode == ARM::tRestore) {
> +      if (FrameReg == ARM::SP)
> +        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
> +                                 Offset, false, TII, *this, dl);
> +      else {
> +        emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
> +        UseRR = true;
> +      }
> +    } else
> +      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset,  
> TII,
> +                                *this, dl);
> +    MI.setDesc(TII.get(ARM::tLDR));
> +    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
> +    if (UseRR)
> +      // Use [reg, reg] addrmode.
> +      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
> +    else  // tLDR has an extra register operand.
> +      MI.addOperand(MachineOperand::CreateReg(0, false));
> +  } else if (Desc.mayStore()) {
> +    // FIXME! This is horrific!!! We need register scavenging.
> +    // Our temporary workaround has marked r3 unavailable. Of  
> course, r3 is
> +    // also a ABI register so it's possible that is is the register  
> that is
> +    // being storing here. If that's the case, we do the following:
> +    // r12 = r2
> +    // Use r2 to materialize sp + offset
> +    // str r3, r2
> +    // r2 = r12
> +    unsigned ValReg = MI.getOperand(0).getReg();
> +    unsigned TmpReg = ARM::R3;
> +    bool UseRR = false;
> +    if (ValReg == ARM::R3) {
> +      BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> +        .addReg(ARM::R2, RegState::Kill);
> +      TmpReg = ARM::R2;
> +    }
> +    if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
> +      BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> +        .addReg(ARM::R3, RegState::Kill);
> +    if (Opcode == ARM::tSpill) {
> +      if (FrameReg == ARM::SP)
> +        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
> +                                 Offset, false, TII, *this, dl);
> +      else {
> +        emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
> +        UseRR = true;
> +      }
> +    } else
> +      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset,  
> TII,
> +                                *this, dl);
> +    MI.setDesc(TII.get(ARM::tSTR));
> +    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
> +    if (UseRR)  // Use [reg, reg] addrmode.
> +      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
> +    else // tSTR has an extra register operand.
> +      MI.addOperand(MachineOperand::CreateReg(0, false));
> +
> +    MachineBasicBlock::iterator NII = next(II);
> +    if (ValReg == ARM::R3)
> +      BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
> +        .addReg(ARM::R12, RegState::Kill);
> +    if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
> +      BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
> +        .addReg(ARM::R12, RegState::Kill);
> +  } else
> +    assert(false && "Unexpected opcode!");
> +}
> +
> +void Thumb2RegisterInfo::emitPrologue(MachineFunction &MF) const {
> +  MachineBasicBlock &MBB = MF.front();
> +  MachineBasicBlock::iterator MBBI = MBB.begin();
> +  MachineFrameInfo  *MFI = MF.getFrameInfo();
> +  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> +  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
> +  unsigned NumBytes = MFI->getStackSize();
> +  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo 
> ();
> +  DebugLoc dl = (MBBI != MBB.end() ?
> +                 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
> +
> +  // Check if R3 is live in. It might have to be used as a scratch  
> register.
> +  for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo 
> ().livein_begin(),
> +         E = MF.getRegInfo().livein_end(); I != E; ++I) {
> +    if (I->first == ARM::R3) {
> +      AFI->setR3IsLiveIn(true);
> +      break;
> +    }
> +  }
> +
> +  // Thumb add/sub sp, imm8 instructions implicitly multiply the  
> offset by 4.
> +  NumBytes = (NumBytes + 3) & ~3;
> +  MFI->setStackSize(NumBytes);
> +
> +  // Determine the sizes of each callee-save spill areas and record  
> which frame
> +  // belongs to which callee-save spill areas.
> +  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
> +  int FramePtrSpillFI = 0;
> +
> +  if (VARegSaveSize)
> +    emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize);
> +
> +  if (!AFI->hasStackFrame()) {
> +    if (NumBytes != 0)
> +      emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
> +    return;
> +  }
> +
> +  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
> +    unsigned Reg = CSI[i].getReg();
> +    int FI = CSI[i].getFrameIdx();
> +    switch (Reg) {
> +    case ARM::R4:
> +    case ARM::R5:
> +    case ARM::R6:
> +    case ARM::R7:
> +    case ARM::LR:
> +      if (Reg == FramePtr)
> +        FramePtrSpillFI = FI;
> +      AFI->addGPRCalleeSavedArea1Frame(FI);
> +      GPRCS1Size += 4;
> +      break;
> +    case ARM::R8:
> +    case ARM::R9:
> +    case ARM::R10:
> +    case ARM::R11:
> +      if (Reg == FramePtr)
> +        FramePtrSpillFI = FI;
> +      if (STI.isTargetDarwin()) {
> +        AFI->addGPRCalleeSavedArea2Frame(FI);
> +        GPRCS2Size += 4;
> +      } else {
> +        AFI->addGPRCalleeSavedArea1Frame(FI);
> +        GPRCS1Size += 4;
> +      }
> +      break;
> +    default:
> +      AFI->addDPRCalleeSavedAreaFrame(FI);
> +      DPRCSSize += 8;
> +    }
> +  }
> +
> +  if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
> +    ++MBBI;
> +    if (MBBI != MBB.end())
> +      dl = MBBI->getDebugLoc();
> +  }
> +
> +  // Darwin ABI requires FP to point to the stack slot that  
> contains the
> +  // previous FP.
> +  if (STI.isTargetDarwin() || hasFP(MF)) {
> +    MachineInstrBuilder MIB =
> +      BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
> +      .addFrameIndex(FramePtrSpillFI).addImm(0);
> +  }
> +
> +  // Determine starting offsets of spill areas.
> +  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size +  
> DPRCSSize);
> +  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
> +  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
> +  AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI)  
> + NumBytes);
> +  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
> +  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
> +  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
> +
> +  NumBytes = DPRCSOffset;
> +  if (NumBytes) {
> +    // Insert it after all the callee-save spills.
> +    emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
> +  }
> +
> +  if (STI.isTargetELF() && hasFP(MF)) {
> +    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
> +                             AFI->getFramePtrSpillOffset());
> +  }
> +
> +  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
> +  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
> +  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
> +}
> +
> +static bool isCalleeSavedRegister(unsigned Reg, const unsigned  
> *CSRegs) {
> +  for (unsigned i = 0; CSRegs[i]; ++i)
> +    if (Reg == CSRegs[i])
> +      return true;
> +  return false;
> +}
> +
> +static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
> +  return (MI->getOpcode() == ARM::tRestore &&
> +          MI->getOperand(1).isFI() &&
> +          isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
> +}
> +
> +void Thumb2RegisterInfo::emitEpilogue(MachineFunction &MF,
> +                                      MachineBasicBlock &MBB) const {
> +  MachineBasicBlock::iterator MBBI = prior(MBB.end());
> +  assert((MBBI->getOpcode() == ARM::tBX_RET ||
> +          MBBI->getOpcode() == ARM::tPOP_RET) &&
> +         "Can only insert epilog into returning blocks");
> +  DebugLoc dl = MBBI->getDebugLoc();
> +  MachineFrameInfo *MFI = MF.getFrameInfo();
> +  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> +  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
> +  int NumBytes = (int)MFI->getStackSize();
> +
> +  if (!AFI->hasStackFrame()) {
> +    if (NumBytes != 0)
> +      emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
> +  } else {
> +    // Unwind MBBI to point to first LDR / FLDD.
> +    const unsigned *CSRegs = getCalleeSavedRegs();
> +    if (MBBI != MBB.begin()) {
> +      do
> +        --MBBI;
> +      while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
> +      if (!isCSRestore(MBBI, CSRegs))
> +        ++MBBI;
> +    }
> +
> +    // Move SP to start of FP callee save spill area.
> +    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
> +                 AFI->getGPRCalleeSavedArea2Size() +
> +                 AFI->getDPRCalleeSavedAreaSize());
> +
> +    if (hasFP(MF)) {
> +      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
> +      // Reset SP based on frame pointer only if the stack frame  
> extends beyond
> +      // frame pointer stack slot or target is ELF and the function  
> has FP.
> +      if (NumBytes)
> +        emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, - 
> NumBytes,
> +                                  TII, *this, dl);
> +      else
> +        BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
> +          .addReg(FramePtr);
> +    } else {
> +      if (MBBI->getOpcode() == ARM::tBX_RET &&
> +          &MBB.front() != MBBI &&
> +          prior(MBBI)->getOpcode() == ARM::tPOP) {
> +        MachineBasicBlock::iterator PMBBI = prior(MBBI);
> +        emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes);
> +      } else
> +        emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
> +    }
> +  }
> +
> +  if (VARegSaveSize) {
> +    // Epilogue for vararg functions: pop LR to R3 and branch off it.
> +    // FIXME: Verify this is still ok when R3 is no longer being  
> reserved.
> +    BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
> +
> +    emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
> +
> +    BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg 
> (ARM::R3);
> +    MBB.erase(MBBI);
> +  }
> +}
>
> Added: llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h?rev=74731&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h (added)
> +++ llvm/trunk/lib/Target/ARM/Thumb2RegisterInfo.h Thu Jul  2  
> 17:18:33 2009
> @@ -0,0 +1,60 @@
> +//===- Thumb2RegisterInfo.h - Thumb-2 Register Information Impl ---- 
> *- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// This file contains the Thumb-2 implementation of the  
> TargetRegisterInfo class.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#ifndef THUMB2REGISTERINFO_H
> +#define THUMB2REGISTERINFO_H
> +
> +#include "ARM.h"
> +#include "ARMRegisterInfo.h"
> +#include "llvm/Target/TargetRegisterInfo.h"
> +
> +namespace llvm {
> +  class ARMSubtarget;
> +  class TargetInstrInfo;
> +  class Type;
> +
> +struct Thumb2RegisterInfo : public ARMBaseRegisterInfo {
> +public:
> +  Thumb2RegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget  
> &STI);
> +
> +  /// emitLoadConstPool - Emits a load from constpool to  
> materialize the
> +  /// specified immediate.
> +  void emitLoadConstPool(MachineBasicBlock &MBB,
> +                         MachineBasicBlock::iterator &MBBI,
> +                         unsigned DestReg, int Val,
> +                         const TargetInstrInfo *TII,
> +                         DebugLoc dl) const;
> +
> +  /// Code Generation virtual methods...
> +  const TargetRegisterClass *
> +    getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other)  
> const;
> +
> +  bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
> +
> +  bool requiresRegisterScavenging(const MachineFunction &MF) const;
> +
> +  bool hasReservedCallFrame(MachineFunction &MF) const;
> +
> +  void eliminateCallFramePseudoInstr(MachineFunction &MF,
> +                                     MachineBasicBlock &MBB,
> +                                     MachineBasicBlock::iterator I)  
> const;
> +
> +  void eliminateFrameIndex(MachineBasicBlock::iterator II,
> +                           int SPAdj, RegScavenger *RS = NULL) const;
> +
> +  void emitPrologue(MachineFunction &MF) const;
> +  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB)  
> const;
> +};
> +}
> +
> +#endif // THUMB2REGISTERINFO_H
>
> Removed: llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp?rev=74730&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ThumbInstrInfo.cpp (removed)
> @@ -1,312 +0,0 @@
> -//===- ThumbInstrInfo.cpp - Thumb Instruction Information -------- 
> *- C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open  
> Source
> -// License. See LICENSE.TXT for details.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -//
> -// This file contains the Thumb implementation of the  
> TargetInstrInfo class.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -
> -#include "ARMInstrInfo.h"
> -#include "ARM.h"
> -#include "ARMGenInstrInfo.inc"
> -#include "ARMMachineFunctionInfo.h"
> -#include "llvm/CodeGen/MachineFrameInfo.h"
> -#include "llvm/CodeGen/MachineInstrBuilder.h"
> -#include "llvm/ADT/SmallVector.h"
> -#include "ThumbInstrInfo.h"
> -
> -using namespace llvm;
> -
> -ThumbInstrInfo::ThumbInstrInfo(const ARMSubtarget &STI)
> -  : ARMBaseInstrInfo(STI), RI(*this, STI) {
> -}
> -
> -bool ThumbInstrInfo::isMoveInstr(const MachineInstr &MI,
> -                                 unsigned &SrcReg, unsigned &DstReg,
> -                                 unsigned& SrcSubIdx, unsigned&  
> DstSubIdx) const {
> -  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
> -
> -  unsigned oc = MI.getOpcode();
> -  switch (oc) {
> -  default:
> -    return false;
> -  // FIXME: Thumb2
> -  case ARM::tMOVr:
> -  case ARM::tMOVhir2lor:
> -  case ARM::tMOVlor2hir:
> -  case ARM::tMOVhir2hir:
> -    assert(MI.getDesc().getNumOperands() >= 2 &&
> -           MI.getOperand(0).isReg() &&
> -           MI.getOperand(1).isReg() &&
> -           "Invalid Thumb MOV instruction");
> -    SrcReg = MI.getOperand(1).getReg();
> -    DstReg = MI.getOperand(0).getReg();
> -    return true;
> -  }
> -}
> -
> -unsigned ThumbInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> -                                             int &FrameIndex) const {
> -  switch (MI->getOpcode()) {
> -  default: break;
> -  // FIXME: Thumb2
> -  case ARM::tRestore:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isImm() &&
> -        MI->getOperand(2).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  }
> -  return 0;
> -}
> -
> -unsigned ThumbInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> -                                            int &FrameIndex) const {
> -  switch (MI->getOpcode()) {
> -  default: break;
> -  // FIXME: Thumb2
> -  case ARM::tSpill:
> -    if (MI->getOperand(1).isFI() &&
> -        MI->getOperand(2).isImm() &&
> -        MI->getOperand(2).getImm() == 0) {
> -      FrameIndex = MI->getOperand(1).getIndex();
> -      return MI->getOperand(0).getReg();
> -    }
> -    break;
> -  }
> -  return 0;
> -}
> -
> -bool ThumbInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
> -                                  MachineBasicBlock::iterator I,
> -                                  unsigned DestReg, unsigned SrcReg,
> -                                  const TargetRegisterClass *DestRC,
> -                                  const TargetRegisterClass *SrcRC)  
> const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> -
> -  // FIXME: Thumb2
> -  if (DestRC == ARM::GPRRegisterClass) {
> -    if (SrcRC == ARM::GPRRegisterClass) {
> -      BuildMI(MBB, I, DL, get(ARM::tMOVhir2hir), DestReg).addReg 
> (SrcReg);
> -      return true;
> -    } else if (SrcRC == ARM::tGPRRegisterClass) {
> -      BuildMI(MBB, I, DL, get(ARM::tMOVlor2hir), DestReg).addReg 
> (SrcReg);
> -      return true;
> -    }
> -  } else if (DestRC == ARM::tGPRRegisterClass) {
> -    if (SrcRC == ARM::GPRRegisterClass) {
> -      BuildMI(MBB, I, DL, get(ARM::tMOVhir2lor), DestReg).addReg 
> (SrcReg);
> -      return true;
> -    } else if (SrcRC == ARM::tGPRRegisterClass) {
> -      BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
> -      return true;
> -    }
> -  }
> -
> -  return false;
> -}
> -
> -bool ThumbInstrInfo::
> -canFoldMemoryOperand(const MachineInstr *MI,
> -                     const SmallVectorImpl<unsigned> &Ops) const {
> -  if (Ops.size() != 1) return false;
> -
> -  unsigned OpNum = Ops[0];
> -  unsigned Opc = MI->getOpcode();
> -  switch (Opc) {
> -  default: break;
> -  case ARM::tMOVr:
> -  case ARM::tMOVlor2hir:
> -  case ARM::tMOVhir2lor:
> -  case ARM::tMOVhir2hir: {
> -    if (OpNum == 0) { // move -> store
> -      unsigned SrcReg = MI->getOperand(1).getReg();
> -      if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
> -        // tSpill cannot take a high register operand.
> -        return false;
> -    } else {          // move -> load
> -      unsigned DstReg = MI->getOperand(0).getReg();
> -      if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
> -        // tRestore cannot target a high register operand.
> -        return false;
> -    }
> -    return true;
> -  }
> -  }
> -
> -  return false;
> -}
> -
> -void ThumbInstrInfo::
> -storeRegToStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> -                    unsigned SrcReg, bool isKill, int FI,
> -                    const TargetRegisterClass *RC) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> -
> -  assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
> -
> -  // FIXME: Thumb2
> -  if (RC == ARM::tGPRRegisterClass) {
> -    BuildMI(MBB, I, DL, get(ARM::tSpill))
> -      .addReg(SrcReg, getKillRegState(isKill))
> -      .addFrameIndex(FI).addImm(0);
> -  }
> -}
> -
> -void ThumbInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned  
> SrcReg,
> -                                    bool isKill,
> -                                    SmallVectorImpl<MachineOperand>  
> &Addr,
> -                                    const TargetRegisterClass *RC,
> -                                   SmallVectorImpl<MachineInstr*>  
> &NewMIs) const{
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  unsigned Opc = 0;
> -
> -  // FIXME: Thumb2. Is GPRRegClass here correct?
> -  assert(RC == ARM::GPRRegisterClass && "Unknown regclass!");
> -  if (RC == ARM::GPRRegisterClass) {
> -    Opc = Addr[0].isFI() ? ARM::tSpill : ARM::tSTR;
> -  }
> -
> -  MachineInstrBuilder MIB =
> -    BuildMI(MF, DL,  get(Opc)).addReg(SrcReg, getKillRegState 
> (isKill));
> -  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> -    MIB.addOperand(Addr[i]);
> -  NewMIs.push_back(MIB);
> -  return;
> -}
> -
> -void ThumbInstrInfo::
> -loadRegFromStackSlot(MachineBasicBlock &MBB,  
> MachineBasicBlock::iterator I,
> -                     unsigned DestReg, int FI,
> -                     const TargetRegisterClass *RC) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (I != MBB.end()) DL = I->getDebugLoc();
> -
> -  // FIXME: Thumb2
> -  assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
> -
> -  if (RC == ARM::tGPRRegisterClass) {
> -    BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
> -      .addFrameIndex(FI).addImm(0);
> -  }
> -}
> -
> -void ThumbInstrInfo::
> -loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> -                SmallVectorImpl<MachineOperand> &Addr,
> -                const TargetRegisterClass *RC,
> -                SmallVectorImpl<MachineInstr*> &NewMIs) const {
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  unsigned Opc = 0;
> -
> -  // FIXME: Thumb2. Is GPRRegClass ok here?
> -  if (RC == ARM::GPRRegisterClass) {
> -    Opc = Addr[0].isFI() ? ARM::tRestore : ARM::tLDR;
> -  }
> -
> -  MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
> -  for (unsigned i = 0, e = Addr.size(); i != e; ++i)
> -    MIB.addOperand(Addr[i]);
> -  NewMIs.push_back(MIB);
> -  return;
> -}
> -
> -bool ThumbInstrInfo::
> -spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                          MachineBasicBlock::iterator MI,
> -                          const std::vector<CalleeSavedInfo> &CSI)  
> const {
> -  if (CSI.empty())
> -    return false;
> -
> -  DebugLoc DL = DebugLoc::getUnknownLoc();
> -  if (MI != MBB.end()) DL = MI->getDebugLoc();
> -
> -  MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
> -  for (unsigned i = CSI.size(); i != 0; --i) {
> -    unsigned Reg = CSI[i-1].getReg();
> -    // Add the callee-saved register as live-in. It's killed at the  
> spill.
> -    MBB.addLiveIn(Reg);
> -    MIB.addReg(Reg, RegState::Kill);
> -  }
> -  return true;
> -}
> -
> -bool ThumbInstrInfo::
> -restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                            MachineBasicBlock::iterator MI,
> -                            const std::vector<CalleeSavedInfo>  
> &CSI) const {
> -  MachineFunction &MF = *MBB.getParent();
> -  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> -  if (CSI.empty())
> -    return false;
> -
> -  bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
> -  MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI- 
> >getDebugLoc());
> -  for (unsigned i = CSI.size(); i != 0; --i) {
> -    unsigned Reg = CSI[i-1].getReg();
> -    if (Reg == ARM::LR) {
> -      // Special epilogue for vararg functions. See emitEpilogue
> -      if (isVarArg)
> -        continue;
> -      Reg = ARM::PC;
> -      PopMI->setDesc(get(ARM::tPOP_RET));
> -      MI = MBB.erase(MI);
> -    }
> -    PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
> -  }
> -
> -  // It's illegal to emit pop instruction without operands.
> -  if (PopMI->getNumOperands() > 0)
> -    MBB.insert(MI, PopMI);
> -
> -  return true;
> -}
> -
> -MachineInstr *ThumbInstrInfo::
> -foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
> -                      const SmallVectorImpl<unsigned> &Ops, int FI)  
> const {
> -  if (Ops.size() != 1) return NULL;
> -
> -  unsigned OpNum = Ops[0];
> -  unsigned Opc = MI->getOpcode();
> -  MachineInstr *NewMI = NULL;
> -  switch (Opc) {
> -  default: break;
> -  case ARM::tMOVr:
> -  case ARM::tMOVlor2hir:
> -  case ARM::tMOVhir2lor:
> -  case ARM::tMOVhir2hir: {
> -    if (OpNum == 0) { // move -> store
> -      unsigned SrcReg = MI->getOperand(1).getReg();
> -      bool isKill = MI->getOperand(1).isKill();
> -      if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
> -        // tSpill cannot take a high register operand.
> -        break;
> -      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
> -        .addReg(SrcReg, getKillRegState(isKill))
> -        .addFrameIndex(FI).addImm(0);
> -    } else {          // move -> load
> -      unsigned DstReg = MI->getOperand(0).getReg();
> -      if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
> -        // tRestore cannot target a high register operand.
> -        break;
> -      bool isDead = MI->getOperand(0).isDead();
> -      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
> -        .addReg(DstReg, RegState::Define | getDeadRegState(isDead))
> -        .addFrameIndex(FI).addImm(0);
> -    }
> -    break;
> -  }
> -  }
> -
> -  return NewMI;
> -}
>
> Removed: llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h?rev=74730&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ThumbInstrInfo.h (removed)
> @@ -1,95 +0,0 @@
> -//===- ThumbInstrInfo.h - Thumb Instruction Information ---------- 
> *- C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open  
> Source
> -// License. See LICENSE.TXT for details.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -//
> -// This file contains the ARM implementation of the TargetInstrInfo  
> class.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -
> -#ifndef THUMBINSTRUCTIONINFO_H
> -#define THUMBINSTRUCTIONINFO_H
> -
> -#include "llvm/Target/TargetInstrInfo.h"
> -#include "ARM.h"
> -#include "ARMInstrInfo.h"
> -#include "ThumbRegisterInfo.h"
> -
> -namespace llvm {
> -  class ARMSubtarget;
> -
> -class ThumbInstrInfo : public ARMBaseInstrInfo {
> -  ThumbRegisterInfo RI;
> -public:
> -  explicit ThumbInstrInfo(const ARMSubtarget &STI);
> -
> -  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister  
> info.  As
> -  /// such, whenever a client has an instance of instruction info,  
> it should
> -  /// always be able to get register info as well (through this  
> method).
> -  ///
> -  virtual const ThumbRegisterInfo &getRegisterInfo() const { return  
> RI; }
> -
> -  /// Return true if the instruction is a register to register move  
> and return
> -  /// the source and dest operands and their sub-register indices  
> by reference.
> -  virtual bool isMoveInstr(const MachineInstr &MI,
> -                           unsigned &SrcReg, unsigned &DstReg,
> -                           unsigned &SrcSubIdx, unsigned  
> &DstSubIdx) const;
> -
> -  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
> -                                       int &FrameIndex) const;
> -  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
> -                                      int &FrameIndex) const;
> -
> -  virtual bool copyRegToReg(MachineBasicBlock &MBB,
> -                            MachineBasicBlock::iterator I,
> -                            unsigned DestReg, unsigned SrcReg,
> -                            const TargetRegisterClass *DestRC,
> -                            const TargetRegisterClass *SrcRC) const;
> -  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
> -                                   MachineBasicBlock::iterator MBBI,
> -                                   unsigned SrcReg, bool isKill,  
> int FrameIndex,
> -                                   const TargetRegisterClass *RC)  
> const;
> -
> -  virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg,  
> bool isKill,
> -                              SmallVectorImpl<MachineOperand> &Addr,
> -                              const TargetRegisterClass *RC,
> -                              SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
> -
> -  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
> -                                    MachineBasicBlock::iterator MBBI,
> -                                    unsigned DestReg, int FrameIndex,
> -                                    const TargetRegisterClass *RC)  
> const;
> -
> -  virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
> -                               SmallVectorImpl<MachineOperand> &Addr,
> -                               const TargetRegisterClass *RC,
> -                               SmallVectorImpl<MachineInstr*>  
> &NewMIs) const;
> -  virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                                          
> MachineBasicBlock::iterator MI,
> -                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
> -  virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
> -                                            
> MachineBasicBlock::iterator MI,
> -                                 const std::vector<CalleeSavedInfo>  
> &CSI) const;
> -
> -  virtual bool canFoldMemoryOperand(const MachineInstr *MI,
> -                                    const SmallVectorImpl<unsigned>  
> &Ops) const;
> -
> -  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> -                                              MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> -                                              MachineInstr* LoadMI)  
> const {
> -    return 0;
> -  }
> -
> -  virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
> -                                              MachineInstr* MI,
> -                                           const  
> SmallVectorImpl<unsigned> &Ops,
> -                                              int FrameIndex) const;
> -};
> -}
> -
> -#endif // THUMBINSTRUCTIONINFO_H
>
> Removed: llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp?rev=74730&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp (removed)
> @@ -1,755 +0,0 @@
> -//===- ThumbRegisterInfo.cpp - Thumb Register Information -------*-  
> C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open  
> Source
> -// License. See LICENSE.TXT for details.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -//
> -// This file contains the ARM implementation of the  
> TargetRegisterInfo class.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -
> -#include "ARM.h"
> -#include "ARMAddressingModes.h"
> -#include "ARMMachineFunctionInfo.h"
> -#include "ARMSubtarget.h"
> -#include "ThumbInstrInfo.h"
> -#include "ThumbRegisterInfo.h"
> -#include "llvm/Constants.h"
> -#include "llvm/DerivedTypes.h"
> -#include "llvm/CodeGen/MachineConstantPool.h"
> -#include "llvm/CodeGen/MachineFrameInfo.h"
> -#include "llvm/CodeGen/MachineFunction.h"
> -#include "llvm/CodeGen/MachineInstrBuilder.h"
> -#include "llvm/CodeGen/MachineLocation.h"
> -#include "llvm/CodeGen/MachineRegisterInfo.h"
> -#include "llvm/Target/TargetFrameInfo.h"
> -#include "llvm/Target/TargetMachine.h"
> -#include "llvm/ADT/BitVector.h"
> -#include "llvm/ADT/SmallVector.h"
> -#include "llvm/Support/CommandLine.h"
> -using namespace llvm;
> -
> -static cl::opt<bool>
> -ThumbRegScavenging("enable-thumb-reg-scavenging",
> -                   cl::Hidden,
> -                   cl::desc("Enable register scavenging on Thumb"));
> -
> -ThumbRegisterInfo::ThumbRegisterInfo(const TargetInstrInfo &tii,
> -                                     const ARMSubtarget &sti)
> -  : ARMBaseRegisterInfo(tii, sti) {
> -}
> -
> -/// emitLoadConstPool - Emits a load from constpool to materialize  
> the
> -/// specified immediate.
> -void ThumbRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB,
> -                                           
> MachineBasicBlock::iterator &MBBI,
> -                                          unsigned DestReg, int Val,
> -                                          const TargetInstrInfo *TII,
> -                                          DebugLoc dl) const {
> -  MachineFunction &MF = *MBB.getParent();
> -  MachineConstantPool *ConstantPool = MF.getConstantPool();
> -  Constant *C = ConstantInt::get(Type::Int32Ty, Val);
> -  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
> -
> -  BuildMI(MBB, MBBI, dl, TII->get(ARM::tLDRcp), DestReg)
> -    .addConstantPoolIndex(Idx);
> -}
> -
> -const TargetRegisterClass*
> -ThumbRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT  
> VT) const {
> -  if (isARMLowRegister(Reg))
> -    return ARM::tGPRRegisterClass;
> -  switch (Reg) {
> -   default:
> -    break;
> -   case ARM::R8:  case ARM::R9:  case ARM::R10:  case ARM::R11:
> -   case ARM::R12: case ARM::SP:  case ARM::LR:   case ARM::PC:
> -    return ARM::GPRRegisterClass;
> -  }
> -
> -  return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT);
> -}
> -
> -bool
> -ThumbRegisterInfo::requiresRegisterScavenging(const MachineFunction  
> &MF) const {
> -  return ThumbRegScavenging;
> -}
> -
> -bool ThumbRegisterInfo::hasReservedCallFrame(MachineFunction &MF)  
> const {
> -  const MachineFrameInfo *FFI = MF.getFrameInfo();
> -  unsigned CFSize = FFI->getMaxCallFrameSize();
> -  // It's not always a good idea to include the call frame as part  
> of the
> -  // stack frame. ARM (especially Thumb) has small immediate offset  
> to
> -  // address the stack frame. So a large call frame can cause poor  
> codegen
> -  // and may even makes it impossible to scavenge a register.
> -  if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
> -    return false;
> -
> -  return !MF.getFrameInfo()->hasVarSizedObjects();
> -}
> -
> -/// emitThumbRegPlusImmInReg - Emits a series of instructions to  
> materialize
> -/// a destreg = basereg + immediate in Thumb code. Materialize the  
> immediate
> -/// in a register using mov / mvn sequences or load the immediate  
> from a
> -/// constpool entry.
> -static
> -void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB,
> -                              MachineBasicBlock::iterator &MBBI,
> -                              unsigned DestReg, unsigned BaseReg,
> -                              int NumBytes, bool CanChangeCC,
> -                              const TargetInstrInfo &TII,
> -                              const ThumbRegisterInfo& MRI,
> -                              DebugLoc dl) {
> -    bool isHigh = !isARMLowRegister(DestReg) ||
> -                  (BaseReg != 0 && !isARMLowRegister(BaseReg));
> -    bool isSub = false;
> -    // Subtract doesn't have high register version. Load the  
> negative value
> -    // if either base or dest register is a high register. Also, if  
> do not
> -    // issue sub as part of the sequence if condition register is  
> to be
> -    // preserved.
> -    if (NumBytes < 0 && !isHigh && CanChangeCC) {
> -      isSub = true;
> -      NumBytes = -NumBytes;
> -    }
> -    unsigned LdReg = DestReg;
> -    if (DestReg == ARM::SP) {
> -      assert(BaseReg == ARM::SP && "Unexpected!");
> -      LdReg = ARM::R3;
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> -        .addReg(ARM::R3, RegState::Kill);
> -    }
> -
> -    if (NumBytes <= 255 && NumBytes >= 0)
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm 
> (NumBytes);
> -    else if (NumBytes < 0 && NumBytes >= -255) {
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm 
> (NumBytes);
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg)
> -        .addReg(LdReg, RegState::Kill);
> -    } else
> -      MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, &TII, dl);
> -
> -    // Emit add / sub.
> -    int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr :  
> ARM::tADDrr);
> -    const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl,
> -                                            TII.get(Opc), DestReg);
> -    if (DestReg == ARM::SP || isSub)
> -      MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill);
> -    else
> -      MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill);
> -    if (DestReg == ARM::SP)
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
> -        .addReg(ARM::R12, RegState::Kill);
> -}
> -
> -/// calcNumMI - Returns the number of instructions required to  
> materialize
> -/// the specific add / sub r, c instruction.
> -static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
> -                          unsigned NumBits, unsigned Scale) {
> -  unsigned NumMIs = 0;
> -  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
> -
> -  if (Opc == ARM::tADDrSPi) {
> -    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> -    Bytes -= ThisVal;
> -    NumMIs++;
> -    NumBits = 8;
> -    Scale = 1;  // Followed by a number of tADDi8.
> -    Chunk = ((1 << NumBits) - 1) * Scale;
> -  }
> -
> -  NumMIs += Bytes / Chunk;
> -  if ((Bytes % Chunk) != 0)
> -    NumMIs++;
> -  if (ExtraOpc)
> -    NumMIs++;
> -  return NumMIs;
> -}
> -
> -/// emitThumbRegPlusImmediate - Emits a series of instructions to  
> materialize
> -/// a destreg = basereg + immediate in Thumb code.
> -static
> -void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
> -                               MachineBasicBlock::iterator &MBBI,
> -                               unsigned DestReg, unsigned BaseReg,
> -                               int NumBytes, const TargetInstrInfo  
> &TII,
> -                               const ThumbRegisterInfo& MRI,
> -                               DebugLoc dl) {
> -  bool isSub = NumBytes < 0;
> -  unsigned Bytes = (unsigned)NumBytes;
> -  if (isSub) Bytes = -NumBytes;
> -  bool isMul4 = (Bytes & 3) == 0;
> -  bool isTwoAddr = false;
> -  bool DstNotEqBase = false;
> -  unsigned NumBits = 1;
> -  unsigned Scale = 1;
> -  int Opc = 0;
> -  int ExtraOpc = 0;
> -
> -  if (DestReg == BaseReg && BaseReg == ARM::SP) {
> -    assert(isMul4 && "Thumb sp inc / dec size must be multiple of  
> 4!");
> -    NumBits = 7;
> -    Scale = 4;
> -    Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
> -    isTwoAddr = true;
> -  } else if (!isSub && BaseReg == ARM::SP) {
> -    // r1 = add sp, 403
> -    // =>
> -    // r1 = add sp, 100 * 4
> -    // r1 = add r1, 3
> -    if (!isMul4) {
> -      Bytes &= ~3;
> -      ExtraOpc = ARM::tADDi3;
> -    }
> -    NumBits = 8;
> -    Scale = 4;
> -    Opc = ARM::tADDrSPi;
> -  } else {
> -    // sp = sub sp, c
> -    // r1 = sub sp, c
> -    // r8 = sub sp, c
> -    if (DestReg != BaseReg)
> -      DstNotEqBase = true;
> -    NumBits = 8;
> -    Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
> -    isTwoAddr = true;
> -  }
> -
> -  unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
> -  unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
> -  if (NumMIs > Threshold) {
> -    // This will expand into too many instructions. Load the  
> immediate from a
> -    // constpool entry.
> -    emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes,  
> true, TII,
> -                             MRI, dl);
> -    return;
> -  }
> -
> -  if (DstNotEqBase) {
> -    if (isARMLowRegister(DestReg) && isARMLowRegister(BaseReg)) {
> -      // If both are low registers, emit DestReg = add BaseReg, max 
> (Imm, 7)
> -      unsigned Chunk = (1 << 3) - 1;
> -      unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> -      Bytes -= ThisVal;
> -      BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 :  
> ARM::tADDi3), DestReg)
> -        .addReg(BaseReg, RegState::Kill).addImm(ThisVal);
> -    } else {
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
> -        .addReg(BaseReg, RegState::Kill);
> -    }
> -    BaseReg = DestReg;
> -  }
> -
> -  unsigned Chunk = ((1 << NumBits) - 1) * Scale;
> -  while (Bytes) {
> -    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
> -    Bytes -= ThisVal;
> -    ThisVal /= Scale;
> -    // Build the new tADD / tSUB.
> -    if (isTwoAddr)
> -      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
> -        .addReg(DestReg).addImm(ThisVal);
> -    else {
> -      bool isKill = BaseReg != ARM::SP;
> -      BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
> -        .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal);
> -      BaseReg = DestReg;
> -
> -      if (Opc == ARM::tADDrSPi) {
> -        // r4 = add sp, imm
> -        // r4 = add r4, imm
> -        // ...
> -        NumBits = 8;
> -        Scale = 1;
> -        Chunk = ((1 << NumBits) - 1) * Scale;
> -        Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
> -        isTwoAddr = true;
> -      }
> -    }
> -  }
> -
> -  if (ExtraOpc)
> -    BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg)
> -      .addReg(DestReg, RegState::Kill)
> -      .addImm(((unsigned)NumBytes) & 3);
> -}
> -
> -static void emitSPUpdate(MachineBasicBlock &MBB,
> -                         MachineBasicBlock::iterator &MBBI,
> -                         const TargetInstrInfo &TII, DebugLoc dl,
> -                         const ThumbRegisterInfo &MRI,
> -                         int NumBytes) {
> -  emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,  
> TII,
> -                            MRI, dl);
> -}
> -
> -void ThumbRegisterInfo::
> -eliminateCallFramePseudoInstr(MachineFunction &MF,  
> MachineBasicBlock &MBB,
> -                              MachineBasicBlock::iterator I) const {
> -  if (!hasReservedCallFrame(MF)) {
> -    // If we have alloca, convert as follows:
> -    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
> -    // ADJCALLSTACKUP   -> add, sp, sp, amount
> -    MachineInstr *Old = I;
> -    DebugLoc dl = Old->getDebugLoc();
> -    unsigned Amount = Old->getOperand(0).getImm();
> -    if (Amount != 0) {
> -      // We need to keep the stack aligned properly.  To do this,  
> we round the
> -      // amount of space needed for the outgoing arguments up to  
> the next
> -      // alignment boundary.
> -      unsigned Align = MF.getTarget().getFrameInfo()- 
> >getStackAlignment();
> -      Amount = (Amount+Align-1)/Align*Align;
> -
> -      // Replace the pseudo instruction with a new instruction...
> -      unsigned Opc = Old->getOpcode();
> -      if (Opc == ARM::ADJCALLSTACKDOWN || Opc ==  
> ARM::tADJCALLSTACKDOWN) {
> -        emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
> -      } else {
> -        assert(Opc == ARM::ADJCALLSTACKUP || Opc ==  
> ARM::tADJCALLSTACKUP);
> -        emitSPUpdate(MBB, I, TII, dl, *this, Amount);
> -      }
> -    }
> -  }
> -  MBB.erase(I);
> -}
> -
> -/// emitThumbConstant - Emit a series of instructions to  
> materialize a
> -/// constant.
> -static void emitThumbConstant(MachineBasicBlock &MBB,
> -                              MachineBasicBlock::iterator &MBBI,
> -                              unsigned DestReg, int Imm,
> -                              const TargetInstrInfo &TII,
> -                              const ThumbRegisterInfo& MRI,
> -                              DebugLoc dl) {
> -  bool isSub = Imm < 0;
> -  if (isSub) Imm = -Imm;
> -
> -  int Chunk = (1 << 8) - 1;
> -  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
> -  Imm -= ThisVal;
> -  BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm 
> (ThisVal);
> -  if (Imm > 0)
> -    emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm,  
> TII, MRI, dl);
> -  if (isSub)
> -    BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg)
> -      .addReg(DestReg, RegState::Kill);
> -}
> -
> -void ThumbRegisterInfo::eliminateFrameIndex 
> (MachineBasicBlock::iterator II,
> -                                            int SPAdj, RegScavenger  
> *RS) const{
> -  unsigned i = 0;
> -  MachineInstr &MI = *II;
> -  MachineBasicBlock &MBB = *MI.getParent();
> -  MachineFunction &MF = *MBB.getParent();
> -  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> -  DebugLoc dl = MI.getDebugLoc();
> -
> -  while (!MI.getOperand(i).isFI()) {
> -    ++i;
> -    assert(i < MI.getNumOperands() && "Instr doesn't have  
> FrameIndex operand!");
> -  }
> -
> -  unsigned FrameReg = ARM::SP;
> -  int FrameIndex = MI.getOperand(i).getIndex();
> -  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
> -               MF.getFrameInfo()->getStackSize() + SPAdj;
> -
> -  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
> -    Offset -= AFI->getGPRCalleeSavedArea1Offset();
> -  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
> -    Offset -= AFI->getGPRCalleeSavedArea2Offset();
> -  else if (hasFP(MF)) {
> -    assert(SPAdj == 0 && "Unexpected");
> -    // There is alloca()'s in this function, must reference off the  
> frame
> -    // pointer instead.
> -    FrameReg = getFrameRegister(MF);
> -    Offset -= AFI->getFramePtrSpillOffset();
> -  }
> -
> -  unsigned Opcode = MI.getOpcode();
> -  const TargetInstrDesc &Desc = MI.getDesc();
> -  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
> -
> -  if (Opcode == ARM::tADDrSPi) {
> -    Offset += MI.getOperand(i+1).getImm();
> -
> -    // Can't use tADDrSPi if it's based off the frame pointer.
> -    unsigned NumBits = 0;
> -    unsigned Scale = 1;
> -    if (FrameReg != ARM::SP) {
> -      Opcode = ARM::tADDi3;
> -      MI.setDesc(TII.get(ARM::tADDi3));
> -      NumBits = 3;
> -    } else {
> -      NumBits = 8;
> -      Scale = 4;
> -      assert((Offset & 3) == 0 &&
> -             "Thumb add/sub sp, #imm immediate must be multiple of  
> 4!");
> -    }
> -
> -    if (Offset == 0) {
> -      // Turn it into a move.
> -      MI.setDesc(TII.get(ARM::tMOVhir2lor));
> -      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> -      MI.RemoveOperand(i+1);
> -      return;
> -    }
> -
> -    // Common case: small offset, fits into instruction.
> -    unsigned Mask = (1 << NumBits) - 1;
> -    if (((Offset / Scale) & ~Mask) == 0) {
> -      // Replace the FrameIndex with sp / fp
> -      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> -      MI.getOperand(i+1).ChangeToImmediate(Offset / Scale);
> -      return;
> -    }
> -
> -    unsigned DestReg = MI.getOperand(0).getReg();
> -    unsigned Bytes = (Offset > 0) ? Offset : -Offset;
> -    unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
> -    // MI would expand into a large number of instructions. Don't  
> try to
> -    // simplify the immediate.
> -    if (NumMIs > 2) {
> -      emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset,  
> TII,
> -                                *this, dl);
> -      MBB.erase(II);
> -      return;
> -    }
> -
> -    if (Offset > 0) {
> -      // Translate r0 = add sp, imm to
> -      // r0 = add sp, 255*4
> -      // r0 = add r0, (imm - 255*4)
> -      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> -      MI.getOperand(i+1).ChangeToImmediate(Mask);
> -      Offset = (Offset - Mask * Scale);
> -      MachineBasicBlock::iterator NII = next(II);
> -      emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset,  
> TII,
> -                                *this, dl);
> -    } else {
> -      // Translate r0 = add sp, -imm to
> -      // r0 = -imm (this is then translated into a series of  
> instructons)
> -      // r0 = add r0, sp
> -      emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl);
> -      MI.setDesc(TII.get(ARM::tADDhirr));
> -      MI.getOperand(i).ChangeToRegister(DestReg, false, false, true);
> -      MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
> -    }
> -    return;
> -  } else {
> -    unsigned ImmIdx = 0;
> -    int InstrOffs = 0;
> -    unsigned NumBits = 0;
> -    unsigned Scale = 1;
> -    switch (AddrMode) {
> -    case ARMII::AddrModeT1_s: {
> -      ImmIdx = i+1;
> -      InstrOffs = MI.getOperand(ImmIdx).getImm();
> -      NumBits = (FrameReg == ARM::SP) ? 8 : 5;
> -      Scale = 4;
> -      break;
> -    }
> -    default:
> -      assert(0 && "Unsupported addressing mode!");
> -      abort();
> -      break;
> -    }
> -
> -    Offset += InstrOffs * Scale;
> -    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
> -
> -    // Common case: small offset, fits into instruction.
> -    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
> -    int ImmedOffset = Offset / Scale;
> -    unsigned Mask = (1 << NumBits) - 1;
> -    if ((unsigned)Offset <= Mask * Scale) {
> -      // Replace the FrameIndex with sp
> -      MI.getOperand(i).ChangeToRegister(FrameReg, false);
> -      ImmOp.ChangeToImmediate(ImmedOffset);
> -      return;
> -    }
> -
> -    bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode ==  
> ARM::tSpill;
> -    if (AddrMode == ARMII::AddrModeT1_s) {
> -      // Thumb tLDRspi, tSTRspi. These will change to instructions  
> that use
> -      // a different base register.
> -      NumBits = 5;
> -      Mask = (1 << NumBits) - 1;
> -    }
> -    // If this is a thumb spill / restore, we will be using a  
> constpool load to
> -    // materialize the offset.
> -    if (AddrMode == ARMII::AddrModeT1_s && isThumSpillRestore)
> -      ImmOp.ChangeToImmediate(0);
> -    else {
> -      // Otherwise, it didn't fit. Pull in what we can to simplify  
> the immed.
> -      ImmedOffset = ImmedOffset & Mask;
> -      ImmOp.ChangeToImmediate(ImmedOffset);
> -      Offset &= ~(Mask*Scale);
> -    }
> -  }
> -
> -  // If we get here, the immediate doesn't fit into the  
> instruction.  We folded
> -  // as much as possible above, handle the rest, providing a  
> register that is
> -  // SP+LargeImm.
> -  assert(Offset && "This code isn't needed if offset already  
> handled!");
> -
> -  if (Desc.mayLoad()) {
> -    // Use the destination register to materialize sp + offset.
> -    unsigned TmpReg = MI.getOperand(0).getReg();
> -    bool UseRR = false;
> -    if (Opcode == ARM::tRestore) {
> -      if (FrameReg == ARM::SP)
> -        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
> -                                 Offset, false, TII, *this, dl);
> -      else {
> -        emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
> -        UseRR = true;
> -      }
> -    } else
> -      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset,  
> TII,
> -                                *this, dl);
> -    MI.setDesc(TII.get(ARM::tLDR));
> -    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
> -    if (UseRR)
> -      // Use [reg, reg] addrmode.
> -      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
> -    else  // tLDR has an extra register operand.
> -      MI.addOperand(MachineOperand::CreateReg(0, false));
> -  } else if (Desc.mayStore()) {
> -    // FIXME! This is horrific!!! We need register scavenging.
> -    // Our temporary workaround has marked r3 unavailable. Of  
> course, r3 is
> -    // also a ABI register so it's possible that is is the register  
> that is
> -    // being storing here. If that's the case, we do the following:
> -    // r12 = r2
> -    // Use r2 to materialize sp + offset
> -    // str r3, r2
> -    // r2 = r12
> -    unsigned ValReg = MI.getOperand(0).getReg();
> -    unsigned TmpReg = ARM::R3;
> -    bool UseRR = false;
> -    if (ValReg == ARM::R3) {
> -      BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> -        .addReg(ARM::R2, RegState::Kill);
> -      TmpReg = ARM::R2;
> -    }
> -    if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
> -      BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12)
> -        .addReg(ARM::R3, RegState::Kill);
> -    if (Opcode == ARM::tSpill) {
> -      if (FrameReg == ARM::SP)
> -        emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,
> -                                 Offset, false, TII, *this, dl);
> -      else {
> -        emitLoadConstPool(MBB, II, TmpReg, Offset, &TII, dl);
> -        UseRR = true;
> -      }
> -    } else
> -      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset,  
> TII,
> -                                *this, dl);
> -    MI.setDesc(TII.get(ARM::tSTR));
> -    MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true);
> -    if (UseRR)  // Use [reg, reg] addrmode.
> -      MI.addOperand(MachineOperand::CreateReg(FrameReg, false));
> -    else // tSTR has an extra register operand.
> -      MI.addOperand(MachineOperand::CreateReg(0, false));
> -
> -    MachineBasicBlock::iterator NII = next(II);
> -    if (ValReg == ARM::R3)
> -      BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2)
> -        .addReg(ARM::R12, RegState::Kill);
> -    if (TmpReg == ARM::R3 && AFI->isR3LiveIn())
> -      BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3)
> -        .addReg(ARM::R12, RegState::Kill);
> -  } else
> -    assert(false && "Unexpected opcode!");
> -}
> -
> -void ThumbRegisterInfo::emitPrologue(MachineFunction &MF) const {
> -  MachineBasicBlock &MBB = MF.front();
> -  MachineBasicBlock::iterator MBBI = MBB.begin();
> -  MachineFrameInfo  *MFI = MF.getFrameInfo();
> -  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> -  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
> -  unsigned NumBytes = MFI->getStackSize();
> -  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo 
> ();
> -  DebugLoc dl = (MBBI != MBB.end() ?
> -                 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
> -
> -  // Check if R3 is live in. It might have to be used as a scratch  
> register.
> -  for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo 
> ().livein_begin(),
> -         E = MF.getRegInfo().livein_end(); I != E; ++I) {
> -    if (I->first == ARM::R3) {
> -      AFI->setR3IsLiveIn(true);
> -      break;
> -    }
> -  }
> -
> -  // Thumb add/sub sp, imm8 instructions implicitly multiply the  
> offset by 4.
> -  NumBytes = (NumBytes + 3) & ~3;
> -  MFI->setStackSize(NumBytes);
> -
> -  // Determine the sizes of each callee-save spill areas and record  
> which frame
> -  // belongs to which callee-save spill areas.
> -  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
> -  int FramePtrSpillFI = 0;
> -
> -  if (VARegSaveSize)
> -    emitSPUpdate(MBB, MBBI, TII, dl, *this, -VARegSaveSize);
> -
> -  if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0)
> -      emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
> -    return;
> -  }
> -
> -  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
> -    unsigned Reg = CSI[i].getReg();
> -    int FI = CSI[i].getFrameIdx();
> -    switch (Reg) {
> -    case ARM::R4:
> -    case ARM::R5:
> -    case ARM::R6:
> -    case ARM::R7:
> -    case ARM::LR:
> -      if (Reg == FramePtr)
> -        FramePtrSpillFI = FI;
> -      AFI->addGPRCalleeSavedArea1Frame(FI);
> -      GPRCS1Size += 4;
> -      break;
> -    case ARM::R8:
> -    case ARM::R9:
> -    case ARM::R10:
> -    case ARM::R11:
> -      if (Reg == FramePtr)
> -        FramePtrSpillFI = FI;
> -      if (STI.isTargetDarwin()) {
> -        AFI->addGPRCalleeSavedArea2Frame(FI);
> -        GPRCS2Size += 4;
> -      } else {
> -        AFI->addGPRCalleeSavedArea1Frame(FI);
> -        GPRCS1Size += 4;
> -      }
> -      break;
> -    default:
> -      AFI->addDPRCalleeSavedAreaFrame(FI);
> -      DPRCSSize += 8;
> -    }
> -  }
> -
> -  if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
> -    ++MBBI;
> -    if (MBBI != MBB.end())
> -      dl = MBBI->getDebugLoc();
> -  }
> -
> -  // Darwin ABI requires FP to point to the stack slot that  
> contains the
> -  // previous FP.
> -  if (STI.isTargetDarwin() || hasFP(MF)) {
> -    MachineInstrBuilder MIB =
> -      BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
> -      .addFrameIndex(FramePtrSpillFI).addImm(0);
> -  }
> -
> -  // Determine starting offsets of spill areas.
> -  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size +  
> DPRCSSize);
> -  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
> -  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
> -  AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI)  
> + NumBytes);
> -  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
> -  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
> -  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
> -
> -  NumBytes = DPRCSOffset;
> -  if (NumBytes) {
> -    // Insert it after all the callee-save spills.
> -    emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
> -  }
> -
> -  if (STI.isTargetELF() && hasFP(MF)) {
> -    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
> -                             AFI->getFramePtrSpillOffset());
> -  }
> -
> -  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
> -  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
> -  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
> -}
> -
> -static bool isCalleeSavedRegister(unsigned Reg, const unsigned  
> *CSRegs) {
> -  for (unsigned i = 0; CSRegs[i]; ++i)
> -    if (Reg == CSRegs[i])
> -      return true;
> -  return false;
> -}
> -
> -static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
> -  return (MI->getOpcode() == ARM::tRestore &&
> -          MI->getOperand(1).isFI() &&
> -          isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
> -}
> -
> -void ThumbRegisterInfo::emitEpilogue(MachineFunction &MF,
> -                                   MachineBasicBlock &MBB) const {
> -  MachineBasicBlock::iterator MBBI = prior(MBB.end());
> -  assert((MBBI->getOpcode() == ARM::tBX_RET ||
> -          MBBI->getOpcode() == ARM::tPOP_RET) &&
> -         "Can only insert epilog into returning blocks");
> -  DebugLoc dl = MBBI->getDebugLoc();
> -  MachineFrameInfo *MFI = MF.getFrameInfo();
> -  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
> -  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
> -  int NumBytes = (int)MFI->getStackSize();
> -
> -  if (!AFI->hasStackFrame()) {
> -    if (NumBytes != 0)
> -      emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
> -  } else {
> -    // Unwind MBBI to point to first LDR / FLDD.
> -    const unsigned *CSRegs = getCalleeSavedRegs();
> -    if (MBBI != MBB.begin()) {
> -      do
> -        --MBBI;
> -      while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
> -      if (!isCSRestore(MBBI, CSRegs))
> -        ++MBBI;
> -    }
> -
> -    // Move SP to start of FP callee save spill area.
> -    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
> -                 AFI->getGPRCalleeSavedArea2Size() +
> -                 AFI->getDPRCalleeSavedAreaSize());
> -
> -    if (hasFP(MF)) {
> -      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
> -      // Reset SP based on frame pointer only if the stack frame  
> extends beyond
> -      // frame pointer stack slot or target is ELF and the function  
> has FP.
> -      if (NumBytes)
> -        emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, - 
> NumBytes,
> -                                  TII, *this, dl);
> -      else
> -        BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP)
> -          .addReg(FramePtr);
> -    } else {
> -      if (MBBI->getOpcode() == ARM::tBX_RET &&
> -          &MBB.front() != MBBI &&
> -          prior(MBBI)->getOpcode() == ARM::tPOP) {
> -        MachineBasicBlock::iterator PMBBI = prior(MBBI);
> -        emitSPUpdate(MBB, PMBBI, TII, dl, *this, NumBytes);
> -      } else
> -        emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
> -    }
> -  }
> -
> -  if (VARegSaveSize) {
> -    // Epilogue for vararg functions: pop LR to R3 and branch off it.
> -    // FIXME: Verify this is still ok when R3 is no longer being  
> reserved.
> -    BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3);
> -
> -    emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
> -
> -    BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg 
> (ARM::R3);
> -    MBB.erase(MBBI);
> -  }
> -}
>
> Removed: llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h?rev=74730&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h (original)
> +++ llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.h (removed)
> @@ -1,60 +0,0 @@
> -//===- ThumbRegisterInfo.h - Thumb Register Information Impl ----*-  
> C++ -*-===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open  
> Source
> -// License. See LICENSE.TXT for details.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -//
> -// This file contains the ARM implementation of the  
> TargetRegisterInfo class.
> -//
> -// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> -
> -#ifndef THUMBREGISTERINFO_H
> -#define THUMBREGISTERINFO_H
> -
> -#include "ARM.h"
> -#include "ARMRegisterInfo.h"
> -#include "llvm/Target/TargetRegisterInfo.h"
> -
> -namespace llvm {
> -  class ARMSubtarget;
> -  class TargetInstrInfo;
> -  class Type;
> -
> -struct ThumbRegisterInfo : public ARMBaseRegisterInfo {
> -public:
> -  ThumbRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget  
> &STI);
> -
> -  /// emitLoadConstPool - Emits a load from constpool to  
> materialize the
> -  /// specified immediate.
> -  void emitLoadConstPool(MachineBasicBlock &MBB,
> -                         MachineBasicBlock::iterator &MBBI,
> -                         unsigned DestReg, int Val,
> -                         const TargetInstrInfo *TII,
> -                         DebugLoc dl) const;
> -
> -  /// Code Generation virtual methods...
> -  const TargetRegisterClass *
> -    getPhysicalRegisterRegClass(unsigned Reg, MVT VT = MVT::Other)  
> const;
> -
> -  bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
> -
> -  bool requiresRegisterScavenging(const MachineFunction &MF) const;
> -
> -  bool hasReservedCallFrame(MachineFunction &MF) const;
> -
> -  void eliminateCallFramePseudoInstr(MachineFunction &MF,
> -                                     MachineBasicBlock &MBB,
> -                                     MachineBasicBlock::iterator I)  
> const;
> -
> -  void eliminateFrameIndex(MachineBasicBlock::iterator II,
> -                           int SPAdj, RegScavenger *RS = NULL) const;
> -
> -  void emitPrologue(MachineFunction &MF) const;
> -  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB)  
> const;
> -};
> -}
> -
> -#endif // THUMBREGISTERINFO_H
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list