[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