diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h index 7edd1180f27..8bf1b7c0040 100644 --- a/lib/Target/ARM/ARM.h +++ b/lib/Target/ARM/ARM.h @@ -20,7 +20,7 @@ namespace llvm { -class ARMTargetMachine; +class ARMBaseTargetMachine; class FunctionPass; class MachineCodeEmitter; class JITCodeEmitter; @@ -28,8 +28,8 @@ class raw_ostream; // Enums corresponding to ARM condition codes namespace ARMCC { - // The CondCodes constants map directly to the 4-bit encoding of the - // condition field for predicated instructions. + // The CondCodes constants map directly to the 4-bit encoding of the + // condition field for predicated instructions. enum CondCodes { EQ, NE, @@ -47,7 +47,7 @@ namespace ARMCC { LE, AL }; - + inline static CondCodes getOppositeCondition(CondCodes CC){ switch (CC) { default: assert(0 && "Unknown condition code"); @@ -90,17 +90,17 @@ inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) { } } -FunctionPass *createARMISelDag(ARMTargetMachine &TM); +FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM); FunctionPass *createARMCodePrinterPass(raw_ostream &O, - ARMTargetMachine &TM, + ARMBaseTargetMachine &TM, CodeGenOpt::Level OptLevel, bool Verbose); -FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM, +FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM, MachineCodeEmitter &MCE); -FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM, +FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM, MachineCodeEmitter &MCE); -FunctionPass *createARMJITCodeEmitterPass(ARMTargetMachine &TM, +FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM, JITCodeEmitter &JCE); FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index f6629fe3c87..8424c2eaed1 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -176,11 +176,11 @@ namespace { namespace llvm { -FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM, +FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM, MachineCodeEmitter &MCE) { return new Emitter(TM, MCE); } -FunctionPass *createARMJITCodeEmitterPass(ARMTargetMachine &TM, +FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM, JITCodeEmitter &JCE) { return new Emitter(TM, JCE); } diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 0f14428c30d..2145d629b9e 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -41,14 +41,14 @@ static const unsigned arm_dsubreg_1 = 6; /// namespace { class ARMDAGToDAGISel : public SelectionDAGISel { - ARMTargetMachine &TM; + ARMBaseTargetMachine &TM; /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can /// make the right decision when generating code for different targets. const ARMSubtarget *Subtarget; public: - explicit ARMDAGToDAGISel(ARMTargetMachine &tm) + explicit ARMDAGToDAGISel(ARMBaseTargetMachine &tm) : SelectionDAGISel(tm), TM(tm), Subtarget(&TM.getSubtarget()) { } @@ -1002,6 +1002,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, /// createARMISelDag - This pass converts a legalized DAG into a /// ARM-specific DAG, ready for instruction scheduling. /// -FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) { +FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM) { return new ARMDAGToDAGISel(TM); } diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index e8da9276243..d95089dd484 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -39,11 +39,14 @@ const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { return MIB.addReg(0); } -ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) +ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI) : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), RI(*this, STI) { } +ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) + : ARMBaseInstrInfo(STI) { +} /// Return true if the instruction is a register to register move and /// leave the source and dest operands in the passed parameters. @@ -65,10 +68,6 @@ bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI, DstReg = MI.getOperand(0).getReg(); return true; case ARM::MOVr: - 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() && @@ -102,14 +101,6 @@ unsigned ARMInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, return MI->getOperand(0).getReg(); } break; - 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; } @@ -137,22 +128,15 @@ unsigned ARMInstrInfo::isStoreToStackSlot(const MachineInstr *MI, return MI->getOperand(0).getReg(); } break; - 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; } -void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, - const MachineInstr *Orig) const { +void ARMBaseInstrInfo::reMaterialize(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, + const MachineInstr *Orig) const { DebugLoc dl = Orig->getDebugLoc(); if (Orig->getOpcode() == ARM::MOVi2pieces) { RI.emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImm(), @@ -198,9 +182,9 @@ static unsigned getUnindexedOpcode(unsigned Opc) { } MachineInstr * -ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, - MachineBasicBlock::iterator &MBBI, - LiveVariables *LV) const { +ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, + MachineBasicBlock::iterator &MBBI, + LiveVariables *LV) const { if (!EnableARM3Addr) return NULL; @@ -261,7 +245,7 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg) .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) .addImm(Pred).addReg(0).addReg(0); - } else + } else UpdateMI = BuildMI(MF, MI->getDebugLoc(), get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg) .addReg(BaseReg).addReg(OffReg) @@ -312,7 +296,7 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, NewMIs.push_back(UpdateMI); NewMIs.push_back(MemMI); } - + // Transfer LiveVariables states, kill / dead info. if (LV) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -320,7 +304,7 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, if (MO.isReg() && MO.getReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) { unsigned Reg = MO.getReg(); - + LiveVariables::VarInfo &VI = LV->getVarInfo(Reg); if (MO.isDef()) { MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI; @@ -349,18 +333,19 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, } // Branch analysis. -bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl &Cond, - bool AllowModify) const { +bool + ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, + MachineBasicBlock *&FBB, + SmallVectorImpl &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)) return false; - + // Get the last instruction in the block. MachineInstr *LastInst = I; - + // If there is only one terminator instruction, process it. unsigned LastOpc = LastInst->getOpcode(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { @@ -377,14 +362,14 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, } return true; // Can't handle indirect branch. } - + // Get the instruction before it if it is a terminator. MachineInstr *SecondLastInst = I; - + // If there are three terminators, we don't know what sort of block this is. if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) return true; - + // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it. unsigned SecondLastOpc = SecondLastInst->getOpcode(); if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) || @@ -395,8 +380,8 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, FBB = LastInst->getOperand(0).getMBB(); return false; } - - // If the block ends with two unconditional branches, handle it. The second + + // If the block ends with two unconditional branches, handle it. The second // one is not executed, so remove it. if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB) && (LastOpc == ARM::B || LastOpc == ARM::tB)) { @@ -417,14 +402,14 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, if (AllowModify) I->eraseFromParent(); return true; - } + } // Otherwise, can't handle this. return true; } -unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { +unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); int BOpc = AFI->isThumbFunction() ? ARM::tB : ARM::B; @@ -435,26 +420,26 @@ unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { --I; if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc) return 0; - + // Remove the branch. I->eraseFromParent(); - + I = MBB.end(); - + if (I == MBB.begin()) return 1; --I; if (I->getOpcode() != BccOpc) return 1; - + // Remove the branch. I->eraseFromParent(); return 2; } unsigned -ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl &Cond) const { +ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const SmallVectorImpl &Cond) const { // FIXME this should probably have a DebugLoc argument DebugLoc dl = DebugLoc::getUnknownLoc(); MachineFunction &MF = *MBB.getParent(); @@ -466,7 +451,7 @@ ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "ARM branch conditions have two components!"); - + if (FBB == 0) { if (Cond.empty()) // Unconditional branch? BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB); @@ -475,7 +460,7 @@ ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); return 1; } - + // Two-way conditional branch. BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); @@ -488,43 +473,18 @@ bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); DebugLoc DL = DebugLoc::getUnknownLoc(); if (I != MBB.end()) DL = I->getDebugLoc(); - if (!AFI->isThumbFunction()) { - if (DestRC == ARM::GPRRegisterClass) { - AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg) - .addReg(SrcReg))); - return true; - } - } else { - 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; - } - } - } if (DestRC != SrcRC) { // Not yet supported! return false; } - - if (DestRC == ARM::SPRRegisterClass) + 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) @@ -534,7 +494,7 @@ bool ARMInstrInfo::copyRegToReg(MachineBasicBlock &MBB, BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); else return false; - + return true; } @@ -546,19 +506,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (I != MBB.end()) DL = I->getDebugLoc(); if (RC == ARM::GPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - assert (!AFI->isThumbFunction()); AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addReg(0).addImm(0)); - } else if (RC == ARM::tGPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - assert (AFI->isThumbFunction()); - BuildMI(MBB, I, DL, get(ARM::tSpill)) - .addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addImm(0); } else if (RC == ARM::DPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD)) .addReg(SrcReg, getKillRegState(isKill)) @@ -579,16 +529,6 @@ void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, DebugLoc DL = DebugLoc::getUnknownLoc(); unsigned Opc = 0; if (RC == ARM::GPRRegisterClass) { - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->isThumbFunction()) { - 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; - } Opc = ARM::STR; } else if (RC == ARM::DPRRegisterClass) { Opc = ARM::FSTD; @@ -597,7 +537,7 @@ void ARMInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, Opc = ARM::FSTS; } - MachineInstrBuilder MIB = + 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]); @@ -614,17 +554,8 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, if (I != MBB.end()) DL = I->getDebugLoc(); if (RC == ARM::GPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - assert (!AFI->isThumbFunction()); AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) .addFrameIndex(FI).addReg(0).addImm(0)); - } else if (RC == ARM::tGPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - assert (AFI->isThumbFunction()); - BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg) - .addFrameIndex(FI).addImm(0); } else if (RC == ARM::DPRRegisterClass) { AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) .addFrameIndex(FI).addImm(0)); @@ -643,15 +574,6 @@ loadRegFromAddr(MachineFunction &MF, unsigned DestReg, DebugLoc DL = DebugLoc::getUnknownLoc(); unsigned Opc = 0; if (RC == ARM::GPRRegisterClass) { - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->isThumbFunction()) { - 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; - } Opc = ARM::LDR; } else if (RC == ARM::DPRRegisterClass) { Opc = ARM::FLDD; @@ -668,59 +590,6 @@ loadRegFromAddr(MachineFunction &MF, unsigned DestReg, return; } -bool ARMInstrInfo:: -spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (!AFI->isThumbFunction() || 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 ARMInstrInfo:: -restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (!AFI->isThumbFunction() || 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 *ARMInstrInfo:: foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, const SmallVectorImpl &Ops, int FI) const { @@ -752,31 +621,6 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, } 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) && !RI.isLowRegister(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) && !RI.isLowRegister(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; - } case ARM::FCPYS: { unsigned Pred = MI->getOperand(2).getImm(); unsigned PredReg = MI->getOperand(3).getReg(); @@ -816,7 +660,7 @@ foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, return NewMI; } -bool ARMInstrInfo:: +bool ARMBaseInstrInfo:: canFoldMemoryOperand(const MachineInstr *MI, const SmallVectorImpl &Ops) const { if (Ops.size() != 1) return false; @@ -857,9 +701,10 @@ canFoldMemoryOperand(const MachineInstr *MI, return false; } -bool ARMInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { +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: @@ -877,19 +722,19 @@ bool ARMInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { } } -bool ARMInstrInfo:: +bool ARMBaseInstrInfo:: ReverseBranchCondition(SmallVectorImpl &Cond) const { ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm(); Cond[0].setImm(ARMCC::getOppositeCondition(CC)); return false; } -bool ARMInstrInfo::isPredicated(const MachineInstr *MI) const { +bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const { int PIdx = MI->findFirstPredOperandIdx(); return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL; } -bool ARMInstrInfo:: +bool ARMBaseInstrInfo:: PredicateInstruction(MachineInstr *MI, const SmallVectorImpl &Pred) const { unsigned Opc = MI->getOpcode(); @@ -910,7 +755,7 @@ PredicateInstruction(MachineInstr *MI, return false; } -bool ARMInstrInfo:: +bool ARMBaseInstrInfo:: SubsumesPredicate(const SmallVectorImpl &Pred1, const SmallVectorImpl &Pred2) const { if (Pred1.size() > 2 || Pred2.size() > 2) @@ -937,7 +782,7 @@ SubsumesPredicate(const SmallVectorImpl &Pred1, } } -bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI, +bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, std::vector &Pred) const { const TargetInstrDesc &TID = MI->getDesc(); if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) @@ -966,7 +811,7 @@ static unsigned getNumJTEntries(const std::vector &JT, /// GetInstSize - Return the size of the specified MachineInstr. /// -unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { +unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { const MachineBasicBlock &MBB = *MI->getParent(); const MachineFunction *MF = MBB.getParent(); const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo(); @@ -974,7 +819,7 @@ unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { // 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. @@ -1024,7 +869,7 @@ unsigned ARMInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { // 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 + + return getNumJTEntries(JT, JTI) * 4 + (MI->getOpcode()==ARM::tBR_JTr ? 2 : 4); } default: diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index 9658f3bcba8..131960b9c7a 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -51,14 +51,14 @@ namespace ARMII { Size8Bytes = 2, Size4Bytes = 3, Size2Bytes = 4, - + // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load - // and store ops + // and store ops IndexModeShift = 7, IndexModeMask = 3 << IndexModeShift, IndexModePre = 1, IndexModePost = 2, - + //===------------------------------------------------------------------===// // Misc flags. @@ -146,10 +146,12 @@ namespace ARMII { }; } -class ARMInstrInfo : public TargetInstrInfoImpl { +class ARMBaseInstrInfo : public TargetInstrInfoImpl { const ARMRegisterInfo RI; +protected: + // Can be only subclassed. + explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 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 @@ -157,17 +159,6 @@ public: /// 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. - 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; - void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; @@ -184,6 +175,54 @@ public: virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl &Cond) const; + + virtual bool canFoldMemoryOperand(const MachineInstr *MI, + const SmallVectorImpl &Ops) const; + + virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; + virtual + bool ReverseBranchCondition(SmallVectorImpl &Cond) const; + + // Predication support. + virtual bool isPredicated(const MachineInstr *MI) const; + + ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { + int PIdx = MI->findFirstPredOperandIdx(); + return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() + : ARMCC::AL; + } + + virtual + bool PredicateInstruction(MachineInstr *MI, + const SmallVectorImpl &Pred) const; + + virtual + bool SubsumesPredicate(const SmallVectorImpl &Pred1, + const SmallVectorImpl &Pred2) const; + + virtual bool DefinesPredicate(MachineInstr *MI, + std::vector &Pred) const; + + /// GetInstSize - Returns the size of the specified MachineInstr. + /// + virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; +}; + +class ARMInstrInfo : public ARMBaseInstrInfo { +public: + explicit ARMInstrInfo(const ARMSubtarget &STI); + + /// 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, @@ -208,13 +247,7 @@ public: SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const; - virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const; - virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const; - + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, const SmallVectorImpl &Ops, @@ -226,37 +259,6 @@ public: MachineInstr* LoadMI) const { return 0; } - - virtual bool canFoldMemoryOperand(const MachineInstr *MI, - const SmallVectorImpl &Ops) const; - - virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; - virtual - bool ReverseBranchCondition(SmallVectorImpl &Cond) const; - - // Predication support. - virtual bool isPredicated(const MachineInstr *MI) const; - - ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { - int PIdx = MI->findFirstPredOperandIdx(); - return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() - : ARMCC::AL; - } - - virtual - bool PredicateInstruction(MachineInstr *MI, - const SmallVectorImpl &Pred) const; - - virtual - bool SubsumesPredicate(const SmallVectorImpl &Pred1, - const SmallVectorImpl &Pred2) const; - - virtual bool DefinesPredicate(MachineInstr *MI, - std::vector &Pred) const; - - /// GetInstSize - Returns the size of the specified MachineInstr. - /// - virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; }; } diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp index 42b8eae5e05..bf2c14e8596 100644 --- a/lib/Target/ARM/ARMTargetAsmInfo.cpp +++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp @@ -43,7 +43,7 @@ const char *const llvm::arm_asm_table[] = { 0,0 }; -ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM): +ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM): ARMTargetAsmInfo(TM) { Subtarget = &TM.getSubtarget(); @@ -55,7 +55,7 @@ ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM): SupportsDebugInformation = true; } -ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMTargetMachine &TM): +ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM): ARMTargetAsmInfo(TM) { Subtarget = &TM.getSubtarget(); diff --git a/lib/Target/ARM/ARMTargetAsmInfo.h b/lib/Target/ARM/ARMTargetAsmInfo.h index 683692f00aa..d3f2da0f4b0 100644 --- a/lib/Target/ARM/ARMTargetAsmInfo.h +++ b/lib/Target/ARM/ARMTargetAsmInfo.h @@ -26,7 +26,7 @@ namespace llvm { template struct ARMTargetAsmInfo : public BaseTAI { - explicit ARMTargetAsmInfo(const ARMTargetMachine &TM) : BaseTAI(TM) { + explicit ARMTargetAsmInfo(const ARMBaseTargetMachine &TM) : BaseTAI(TM) { BaseTAI::AsmTransCBE = arm_asm_table; BaseTAI::AlignmentIsInBytes = false; @@ -51,11 +51,11 @@ namespace llvm { EXTERN_TEMPLATE_INSTANTIATION(class ARMTargetAsmInfo); struct ARMDarwinTargetAsmInfo : public ARMTargetAsmInfo { - explicit ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM); + explicit ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM); }; struct ARMELFTargetAsmInfo : public ARMTargetAsmInfo { - explicit ARMELFTargetAsmInfo(const ARMTargetMachine &TM); + explicit ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM); }; } // namespace llvm diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 35737e7800c..f7b821539df 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -43,7 +43,7 @@ static RegisterTarget Y("thumb", "Thumb"); extern "C" void LLVMInitializeARMTarget() { } // No assembler printer by default -ARMTargetMachine::AsmPrinterCtorFn ARMTargetMachine::AsmPrinterCtor = 0; +ARMBaseTargetMachine::AsmPrinterCtorFn ARMBaseTargetMachine::AsmPrinterCtor = 0; /// ThumbTargetMachine - Create an Thumb architecture model. /// @@ -74,34 +74,36 @@ unsigned ThumbTargetMachine::getModuleMatchQuality(const Module &M) { return getJITMatchQuality()/2; } -ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS) - : ARMTargetMachine(M, FS, true) { -} - /// TargetMachine ctor - Create an ARM architecture model. /// -ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS, - bool isThumb) +ARMBaseTargetMachine::ARMBaseTargetMachine(const Module &M, + const std::string &FS, + bool isThumb) : Subtarget(M, FS, isThumb), - DataLayout(Subtarget.isAPCS_ABI() ? - // APCS ABI - (isThumb ? - 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:32:32-i64:32:32")) : - // AAPCS ABI - (isThumb ? - std::string("e-p:32:32-f64:64:64-i64:64:64-" - "i16:16:32-i8:8:32-i1:8:32-a:0:32") : - std::string("e-p:32:32-f64:64:64-i64:64:64"))), - InstrInfo(Subtarget), FrameInfo(Subtarget), JITInfo(), - TLInfo(*this), InstrItins(Subtarget.getInstrItineraryData()) { DefRelocModel = getRelocationModel(); } +ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS) + : ARMBaseTargetMachine(M, FS, false), InstrInfo(Subtarget), + DataLayout(Subtarget.isAPCS_ABI() ? + std::string("e-p:32:32-f64:32:32-i64:32:32") : + std::string("e-p:32:32-f64:64:64-i64:64:64")), + TLInfo(*this) { +} + +ThumbTargetMachine::ThumbTargetMachine(const Module &M, const std::string &FS) + : ARMBaseTargetMachine(M, FS, true), InstrInfo(Subtarget), + 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) { +} + unsigned ARMTargetMachine::getJITMatchQuality() { #if defined(__arm__) return 10; @@ -129,7 +131,7 @@ unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) { } -const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const { +const TargetAsmInfo *ARMBaseTargetMachine::createTargetAsmInfo() const { switch (Subtarget.TargetType) { case ARMSubtarget::isDarwin: return new ARMDarwinTargetAsmInfo(*this); @@ -142,22 +144,22 @@ const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const { // Pass Pipeline Configuration -bool ARMTargetMachine::addInstSelector(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { +bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { PM.add(createARMISelDag(*this)); return false; } -bool ARMTargetMachine::addPreRegAlloc(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { +bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb mode. if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb()) PM.add(createARMLoadStoreOptimizationPass(true)); return true; } -bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM, - CodeGenOpt::Level OptLevel) { +bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb mode. if (OptLevel != CodeGenOpt::None && !DisableLdStOpti && !Subtarget.isThumb()) PM.add(createARMLoadStoreOptimizationPass()); @@ -170,10 +172,10 @@ bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM, return true; } -bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { +bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool Verbose, + raw_ostream &Out) { // Output assembly language. assert(AsmPrinterCtor && "AsmPrinter was not linked in"); if (AsmPrinterCtor) @@ -183,10 +185,10 @@ bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM, } -bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - MachineCodeEmitter &MCE) { +bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool DumpAsm, + MachineCodeEmitter &MCE) { // FIXME: Move this to TargetJITInfo! if (DefRelocModel == Reloc::Default) setRelocationModel(Reloc::Static); @@ -202,10 +204,10 @@ bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM, return false; } -bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - JITCodeEmitter &JCE) { +bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool DumpAsm, + JITCodeEmitter &JCE) { // FIXME: Move this to TargetJITInfo! if (DefRelocModel == Reloc::Default) setRelocationModel(Reloc::Static); @@ -221,10 +223,10 @@ bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM, return false; } -bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - MachineCodeEmitter &MCE) { +bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool DumpAsm, + MachineCodeEmitter &MCE) { // Machine code emitter pass for ARM. PM.add(createARMCodeEmitterPass(*this, MCE)); if (DumpAsm) { @@ -236,10 +238,10 @@ bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, return false; } -bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - JITCodeEmitter &JCE) { +bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool DumpAsm, + JITCodeEmitter &JCE) { // Machine code emitter pass for ARM. PM.add(createARMJITCodeEmitterPass(*this, JCE)); if (DumpAsm) { diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index c4c8e6c1d98..0b49b9275b9 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -22,18 +22,19 @@ #include "ARMJITInfo.h" #include "ARMSubtarget.h" #include "ARMISelLowering.h" +#include "ThumbInstrInfo.h" namespace llvm { class Module; -class ARMTargetMachine : public LLVMTargetMachine { +class ARMBaseTargetMachine : public LLVMTargetMachine { +protected: ARMSubtarget Subtarget; - const TargetData DataLayout; // Calculates type size & alignment - ARMInstrInfo InstrInfo; + +private: ARMFrameInfo FrameInfo; ARMJITInfo JITInfo; - ARMTargetLowering TLInfo; InstrItineraryData InstrItins; Reloc::Model DefRelocModel; // Reloc model before it's overridden. @@ -41,26 +42,18 @@ protected: // To avoid having target depend on the asmprinter stuff libraries, asmprinter // set this functions to ctor pointer at startup time if they are linked in. typedef FunctionPass *(*AsmPrinterCtorFn)(raw_ostream &o, - ARMTargetMachine &tm, + ARMBaseTargetMachine &tm, CodeGenOpt::Level OptLevel, bool verbose); static AsmPrinterCtorFn AsmPrinterCtor; public: - ARMTargetMachine(const Module &M, const std::string &FS, bool isThumb = false); + ARMBaseTargetMachine(const Module &M, const std::string &FS, bool isThumb); - virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const ARMFrameInfo *getFrameInfo() const { return &FrameInfo; } virtual ARMJITInfo *getJITInfo() { return &JITInfo; } - virtual const ARMRegisterInfo *getRegisterInfo() const { - return &InstrInfo.getRegisterInfo(); - } - virtual const TargetData *getTargetData() const { return &DataLayout; } virtual const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; } - virtual ARMTargetLowering *getTargetLowering() const { - return const_cast(&TLInfo); - } - virtual const InstrItineraryData getInstrItineraryData() const { + virtual const InstrItineraryData getInstrItineraryData() const { return InstrItins; } @@ -94,12 +87,50 @@ public: JITCodeEmitter &MCE); }; +/// ARMTargetMachine - ARM target machine. +/// +class ARMTargetMachine : public ARMBaseTargetMachine { + ARMInstrInfo InstrInfo; + const TargetData DataLayout; // Calculates type size & alignment + ARMTargetLowering TLInfo; +public: + ARMTargetMachine(const Module &M, const std::string &FS); + + virtual const ARMRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + + virtual ARMTargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } + + virtual const ARMInstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const TargetData *getTargetData() const { return &DataLayout; } + + static unsigned getJITMatchQuality(); + static unsigned getModuleMatchQuality(const Module &M); +}; + /// ThumbTargetMachine - Thumb target machine. /// -class ThumbTargetMachine : public ARMTargetMachine { +class ThumbTargetMachine : public ARMBaseTargetMachine { + ThumbInstrInfo InstrInfo; + const TargetData DataLayout; // Calculates type size & alignment + ARMTargetLowering TLInfo; public: ThumbTargetMachine(const Module &M, const std::string &FS); + virtual const ARMRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + + virtual ARMTargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } + + virtual const ThumbInstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const TargetData *getTargetData() const { return &DataLayout; } + static unsigned getJITMatchQuality(); static unsigned getModuleMatchQuality(const Module &M); }; diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index 17e6d16a2f3..46037dcc261 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -1138,7 +1138,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) { /// regardless of whether the function is in SSA form. /// FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o, - ARMTargetMachine &tm, + ARMBaseTargetMachine &tm, CodeGenOpt::Level OptLevel, bool verbose) { return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose); @@ -1147,7 +1147,7 @@ FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o, namespace { static struct Register { Register() { - ARMTargetMachine::registerAsmPrinter(createARMCodePrinterPass); + ARMBaseTargetMachine::registerAsmPrinter(createARMCodePrinterPass); } } Registrator; } diff --git a/lib/Target/ARM/ThumbInstrInfo.cpp b/lib/Target/ARM/ThumbInstrInfo.cpp new file mode 100644 index 00000000000..075d940bcca --- /dev/null +++ b/lib/Target/ARM/ThumbInstrInfo.cpp @@ -0,0 +1,282 @@ +//===- 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) { +} + +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; +} + +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 &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &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 &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &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 &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 &CSI) const { + MachineFunction &MF = *MBB.getParent(); + ARMFunctionInfo *AFI = MF.getInfo(); + 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 &Ops, int FI) const { + if (Ops.size() != 1) return NULL; + const ARMRegisterInfo &RI = getRegisterInfo(); + + 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) && !RI.isLowRegister(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) && !RI.isLowRegister(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; +} diff --git a/lib/Target/ARM/ThumbInstrInfo.h b/lib/Target/ARM/ThumbInstrInfo.h new file mode 100644 index 00000000000..dcf10957508 --- /dev/null +++ b/lib/Target/ARM/ThumbInstrInfo.h @@ -0,0 +1,85 @@ +//===- 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 "ARMRegisterInfo.h" +#include "ARM.h" +#include "ARMInstrInfo.h" + +namespace llvm { + class ARMSubtarget; + +class ThumbInstrInfo : public ARMBaseInstrInfo { +public: + explicit ThumbInstrInfo(const ARMSubtarget &STI); + + /// 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 &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &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 &Addr, + const TargetRegisterClass *RC, + SmallVectorImpl &NewMIs) const; + virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { + return 0; + } + + virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const; +}; +} + +#endif // THUMBINSTRUCTIONINFO_H