mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Split thumb-related stuff into separate classes.
Step 1: ARMInstructionInfo => {ARM,Thumb}InstructionInfo git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c4233af200
commit
d49ea77cbc
@ -20,7 +20,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class ARMTargetMachine;
|
||||
class ARMBaseTargetMachine;
|
||||
class FunctionPass;
|
||||
class MachineCodeEmitter;
|
||||
class JITCodeEmitter;
|
||||
@ -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);
|
||||
|
@ -176,11 +176,11 @@ namespace {
|
||||
|
||||
namespace llvm {
|
||||
|
||||
FunctionPass *createARMCodeEmitterPass(ARMTargetMachine &TM,
|
||||
FunctionPass *createARMCodeEmitterPass(ARMBaseTargetMachine &TM,
|
||||
MachineCodeEmitter &MCE) {
|
||||
return new Emitter<MachineCodeEmitter>(TM, MCE);
|
||||
}
|
||||
FunctionPass *createARMJITCodeEmitterPass(ARMTargetMachine &TM,
|
||||
FunctionPass *createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
|
||||
JITCodeEmitter &JCE) {
|
||||
return new Emitter<JITCodeEmitter>(TM, JCE);
|
||||
}
|
||||
|
@ -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<ARMSubtarget>()) {
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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,19 +128,12 @@ 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,
|
||||
void ARMBaseInstrInfo::reMaterialize(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned DestReg,
|
||||
const MachineInstr *Orig) const {
|
||||
@ -198,7 +182,7 @@ static unsigned getUnindexedOpcode(unsigned Opc) {
|
||||
}
|
||||
|
||||
MachineInstr *
|
||||
ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
MachineBasicBlock::iterator &MBBI,
|
||||
LiveVariables *LV) const {
|
||||
if (!EnableARM3Addr)
|
||||
@ -349,7 +333,8 @@ ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
|
||||
}
|
||||
|
||||
// Branch analysis.
|
||||
bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
bool
|
||||
ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const {
|
||||
@ -424,7 +409,7 @@ bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
}
|
||||
|
||||
|
||||
unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
int BOpc = AFI->isThumbFunction() ? ARM::tB : ARM::B;
|
||||
@ -452,7 +437,7 @@ unsigned ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
}
|
||||
|
||||
unsigned
|
||||
ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
// FIXME this should probably have a DebugLoc argument
|
||||
@ -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<ARMFunctionInfo>();
|
||||
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)
|
||||
@ -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<ARMFunctionInfo>();
|
||||
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<ARMFunctionInfo>();
|
||||
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<ARMFunctionInfo>();
|
||||
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;
|
||||
@ -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<ARMFunctionInfo>();
|
||||
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<ARMFunctionInfo>();
|
||||
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<ARMFunctionInfo>();
|
||||
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<CalleeSavedInfo> &CSI) const {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
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<CalleeSavedInfo> &CSI) const {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
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<unsigned> &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<unsigned> &Ops) const {
|
||||
if (Ops.size() != 1) return false;
|
||||
@ -857,7 +701,8 @@ 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()) {
|
||||
@ -877,19 +722,19 @@ bool ARMInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::
|
||||
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 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<MachineOperand> &Pred) const {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
@ -910,7 +755,7 @@ PredicateInstruction(MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::
|
||||
bool ARMBaseInstrInfo::
|
||||
SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
|
||||
const SmallVectorImpl<MachineOperand> &Pred2) const {
|
||||
if (Pred1.size() > 2 || Pred2.size() > 2)
|
||||
@ -937,7 +782,7 @@ SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
|
||||
}
|
||||
}
|
||||
|
||||
bool ARMInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||
bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
|
||||
std::vector<MachineOperand> &Pred) const {
|
||||
const TargetInstrDesc &TID = MI->getDesc();
|
||||
if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
|
||||
@ -966,7 +811,7 @@ static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &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();
|
||||
|
@ -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,48 +175,6 @@ public:
|
||||
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond) 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 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
|
||||
MachineInstr* MI,
|
||||
const SmallVectorImpl<unsigned> &Ops,
|
||||
int FrameIndex) const;
|
||||
|
||||
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
|
||||
MachineInstr* MI,
|
||||
const SmallVectorImpl<unsigned> &Ops,
|
||||
MachineInstr* LoadMI) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool canFoldMemoryOperand(const MachineInstr *MI,
|
||||
const SmallVectorImpl<unsigned> &Ops) const;
|
||||
@ -259,6 +208,59 @@ public:
|
||||
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,
|
||||
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 MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
|
||||
MachineInstr* MI,
|
||||
const SmallVectorImpl<unsigned> &Ops,
|
||||
int FrameIndex) const;
|
||||
|
||||
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
|
||||
MachineInstr* MI,
|
||||
const SmallVectorImpl<unsigned> &Ops,
|
||||
MachineInstr* LoadMI) const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ const char *const llvm::arm_asm_table[] = {
|
||||
0,0
|
||||
};
|
||||
|
||||
ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM):
|
||||
ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM):
|
||||
ARMTargetAsmInfo<DarwinTargetAsmInfo>(TM) {
|
||||
Subtarget = &TM.getSubtarget<ARMSubtarget>();
|
||||
|
||||
@ -55,7 +55,7 @@ ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM):
|
||||
SupportsDebugInformation = true;
|
||||
}
|
||||
|
||||
ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMTargetMachine &TM):
|
||||
ARMELFTargetAsmInfo::ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM):
|
||||
ARMTargetAsmInfo<ELFTargetAsmInfo>(TM) {
|
||||
Subtarget = &TM.getSubtarget<ARMSubtarget>();
|
||||
|
||||
|
@ -26,7 +26,7 @@ namespace llvm {
|
||||
|
||||
template <class BaseTAI>
|
||||
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<TargetAsmInfo>);
|
||||
|
||||
struct ARMDarwinTargetAsmInfo : public ARMTargetAsmInfo<DarwinTargetAsmInfo> {
|
||||
explicit ARMDarwinTargetAsmInfo(const ARMTargetMachine &TM);
|
||||
explicit ARMDarwinTargetAsmInfo(const ARMBaseTargetMachine &TM);
|
||||
};
|
||||
|
||||
struct ARMELFTargetAsmInfo : public ARMTargetAsmInfo<ELFTargetAsmInfo> {
|
||||
explicit ARMELFTargetAsmInfo(const ARMTargetMachine &TM);
|
||||
explicit ARMELFTargetAsmInfo(const ARMBaseTargetMachine &TM);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -43,7 +43,7 @@ static RegisterTarget<ThumbTargetMachine> 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,
|
||||
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,13 +144,13 @@ const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
|
||||
|
||||
|
||||
// Pass Pipeline Configuration
|
||||
bool ARMTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createARMISelDag(*this));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addPreRegAlloc(PassManagerBase &PM,
|
||||
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())
|
||||
@ -156,7 +158,7 @@ bool ARMTargetMachine::addPreRegAlloc(PassManagerBase &PM,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM,
|
||||
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())
|
||||
@ -170,7 +172,7 @@ bool ARMTargetMachine::addPreEmitPass(PassManagerBase &PM,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool Verbose,
|
||||
raw_ostream &Out) {
|
||||
@ -183,7 +185,7 @@ bool ARMTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
|
||||
}
|
||||
|
||||
|
||||
bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool DumpAsm,
|
||||
MachineCodeEmitter &MCE) {
|
||||
@ -202,7 +204,7 @@ bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool DumpAsm,
|
||||
JITCodeEmitter &JCE) {
|
||||
@ -221,7 +223,7 @@ bool ARMTargetMachine::addCodeEmitter(PassManagerBase &PM,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool DumpAsm,
|
||||
MachineCodeEmitter &MCE) {
|
||||
@ -236,7 +238,7 @@ bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ARMTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
||||
bool ARMBaseTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool DumpAsm,
|
||||
JITCodeEmitter &JCE) {
|
||||
|
@ -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,25 +42,17 @@ 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<ARMTargetLowering*>(&TLInfo);
|
||||
}
|
||||
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<ARMTargetLowering*>(&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<ARMTargetLowering*>(&TLInfo);
|
||||
}
|
||||
|
||||
virtual const ThumbInstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
|
||||
static unsigned getJITMatchQuality();
|
||||
static unsigned getModuleMatchQuality(const Module &M);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
282
lib/Target/ARM/ThumbInstrInfo.cpp
Normal file
282
lib/Target/ARM/ThumbInstrInfo.cpp
Normal file
@ -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<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;
|
||||
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;
|
||||
}
|
85
lib/Target/ARM/ThumbInstrInfo.h
Normal file
85
lib/Target/ARM/ThumbInstrInfo.h
Normal file
@ -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<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 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
|
Loading…
Reference in New Issue
Block a user