50 if (ARM::tGPRRegClass.hasSubClassEq(RC))
51 return &ARM::tGPRRegClass;
58 return &ARM::tGPRRegClass;
67 unsigned DestReg,
unsigned SubIdx,
70 unsigned MIFlags)
const {
93 unsigned DestReg,
unsigned BaseReg,
94 int NumBytes,
bool CanChangeCC,
106 if (NumBytes < 0 && !isHigh && CanChangeCC) {
108 NumBytes = -NumBytes;
110 unsigned LdReg = DestReg;
111 if (DestReg == ARM::SP) {
112 assert(BaseReg == ARM::SP &&
"Unexpected!");
116 if (NumBytes <= 255 && NumBytes >= 0)
119 else if (NumBytes < 0 && NumBytes >= -255) {
129 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
131 BuildMI(MBB, MBBI, dl, TII.
get(Opc), DestReg);
132 if (Opc != ARM::tADDhirr)
134 if (DestReg == ARM::SP || isSub)
143 static unsigned calcNumMI(
int Opc,
int ExtraOpc,
unsigned Bytes,
144 unsigned NumBits,
unsigned Scale) {
146 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
148 if (Opc == ARM::tADDrSPi) {
149 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
154 Chunk = ((1 << NumBits) - 1) * Scale;
157 NumMIs += Bytes / Chunk;
158 if ((Bytes % Chunk) != 0)
170 unsigned DestReg,
unsigned BaseReg,
174 bool isSub = NumBytes < 0;
175 unsigned Bytes = (
unsigned)NumBytes;
176 if (isSub) Bytes = -NumBytes;
177 bool isMul4 = (Bytes & 3) == 0;
178 bool isTwoAddr =
false;
179 bool DstNotEqBase =
false;
180 unsigned NumBits = 1;
186 if (DestReg == BaseReg && BaseReg == ARM::SP) {
187 assert(isMul4 &&
"Thumb sp inc / dec size must be multiple of 4!");
190 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
192 }
else if (!isSub && BaseReg == ARM::SP) {
199 ExtraOpc = ARM::tADDi3;
208 if (DestReg != BaseReg)
211 if (DestReg == ARM::SP) {
212 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
213 assert(isMul4 &&
"Thumb sp inc / dec size must be multiple of 4!");
217 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
224 unsigned NumMIs =
calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
225 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
226 if (NumMIs > Threshold) {
230 DestReg, BaseReg, NumBytes,
true,
238 unsigned Chunk = (1 << 3) - 1;
239 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
241 const MCInstrDesc &MCID = TII.
get(isSub ? ARM::tSUBi3 : ARM::tADDi3);
244 .setMIFlags(MIFlags));
249 .setMIFlags(MIFlags);
254 unsigned Chunk = ((1 << NumBits) - 1) * Scale;
256 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
268 bool isKill = BaseReg != ARM::SP;
277 if (Opc == ARM::tADDrSPi) {
283 Chunk = ((1 << NumBits) - 1) * Scale;
284 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
285 NeedCC = isTwoAddr =
true;
294 .addImm(((
unsigned)NumBytes) & 3)
295 .setMIFlags(MIFlags));
303 unsigned DestReg,
int Imm,
307 bool isSub = Imm < 0;
308 if (isSub) Imm = -Imm;
310 int Chunk = (1 << 8) - 1;
311 int ThisVal = (Imm > Chunk) ? Chunk : Imm;
347 unsigned FrameReg,
int &Offset,
357 if (Opcode == ARM::tADDrSPi) {
361 unsigned NumBits = 0;
363 if (FrameReg != ARM::SP) {
364 Opcode = ARM::tADDi3;
369 assert((Offset & 3) == 0 &&
370 "Thumb add/sub sp, #imm immediate must be multiple of 4!");
376 MI.
setDesc(TII.get(ARM::tMOVr));
384 unsigned Mask = (1 << NumBits) - 1;
385 if (((Offset / Scale) & ~Mask) == 0) {
387 if (Opcode == ARM::tADDi3) {
391 .addImm(Offset / Scale));
400 unsigned Bytes = (Offset > 0) ? Offset : -Offset;
401 unsigned NumMIs =
calcNumMI(Opcode, 0, Bytes, NumBits, Scale);
415 if (Opcode == ARM::tADDi3) {
423 Offset = (Offset - Mask * Scale);
433 MI.
setDesc(TII.get(ARM::tADDhirr));
442 unsigned ImmIdx = FrameRegIdx + 1;
444 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
447 Offset += InstrOffs * Scale;
448 assert((Offset & (Scale - 1)) == 0 &&
"Can't encode this offset!");
452 int ImmedOffset = Offset / Scale;
453 unsigned Mask = (1 << NumBits) - 1;
455 if ((
unsigned)Offset <= Mask * Scale) {
463 if (NewOpc != Opcode && FrameReg != ARM::SP)
470 Mask = (1 << NumBits) - 1;
474 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
478 ImmedOffset = ImmedOffset & Mask;
480 Offset &= ~(Mask * Scale);
489 unsigned BaseReg, int64_t Offset)
const {
499 assert(i < MI.
getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
502 assert (Done &&
"Unable to resolve frame index!");
513 unsigned Reg)
const {
530 if (II->isDebugValue())
533 for (
unsigned i = 0, e = II->getNumOperands(); i != e; ++i) {
543 if (MO.
getReg() == ARM::R12) {
559 int SPAdj,
unsigned FIOperandNum,
571 unsigned FrameReg = ARM::SP;
595 "Cannot use SP to access the emergency spill slot in "
596 "functions without a reserved call frame");
598 "Cannot use SP to access the emergency spill slot in "
599 "functions with variable sized frame objects");
605 MI.
getOperand(FIOperandNum). ChangeToRegister(FrameReg,
false );
612 "This eliminateFrameIndex only supports Thumb1!");
619 assert(Offset &&
"This code isn't needed if offset already handled!");
632 if (Opcode == ARM::tLDRspi) {
633 if (FrameReg == ARM::SP)
635 Offset,
false, TII, *
this);
645 MI.
setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
656 if (Opcode == ARM::tSTRspi) {
657 if (FrameReg == ARM::SP)
659 Offset,
false, TII, *
this);
667 MI.
setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
unsigned getFrameRegister(const MachineFunction &MF) const
const MachineFunction * getParent() const
The machine constant pool.
instr_iterator erase(instr_iterator I)
LLVMContext & getContext() const
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
void resolveFrameIndex(MachineBasicBlock::iterator I, unsigned BaseReg, int64_t Offset) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, unsigned NumBits, unsigned Scale)
bool mayStore(QueryType Type=AnyInBundle) const
static bool isVirtualRegister(unsigned Reg)
bool isPredicable(QueryType Type=AllInBundle) const
const MCInstrDesc & getDesc() const
static void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, bool CanChangeCC, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=MachineInstr::NoFlags)
bool isThumbFunction() const
const Function * getFunction() const
bool saveScavengerRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC, unsigned Reg) const
uint64_t getStackSize() const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC) const
const HexagonInstrInfo * TII
virtual bool hasFP(const MachineFunction &MF) const =0
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
void RemoveOperand(unsigned i)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const
unsigned getKillRegState(bool B)
void ChangeToImmediate(int64_t ImmVal)
const MachineBasicBlock * getParent() const
bool isDebugValue() const
unsigned getDefRegState(bool B)
bundle_iterator< MachineInstr, instr_iterator > iterator
static void emitThumbConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, int Imm, const TargetInstrInfo &TII, const Thumb1RegisterInfo &MRI, DebugLoc dl)
bool rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII) const
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
LLVM Constant Representation.
const MachineOperand & getOperand(unsigned i) const
unsigned getFramePtrSpillOffset() const
ItTy next(ItTy it, Dist n)
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineConstantPool * getConstantPool()
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual const TargetFrameLowering * getFrameLowering() const
Thumb1RegisterInfo(const ARMSubtarget &STI)
const MCInstrDesc & get(unsigned Opcode) const
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
int64_t getObjectOffset(int ObjectIdx) const
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
virtual const TargetInstrInfo * getInstrInfo() const
void setDesc(const MCInstrDesc &tid)
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
MachineFrameInfo * getFrameInfo()
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
bool hasBasePointer(const MachineFunction &MF) const
AddrMode
ARM Addressing Modes.
int findFirstPredOperandIdx() const
static void removeOperands(MachineInstr &MI, unsigned i)
cl::opt< bool > ReuseFrameIndexVals
static bool isARMLowRegister(unsigned Reg)
MachineRegisterInfo & getRegInfo()
static IntegerType * getInt32Ty(LLVMContext &C)
static unsigned convertToNonSPOpcode(unsigned Opcode)
const TargetMachine & getTarget() const
bool hasVarSizedObjects() const
virtual void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0, unsigned MIFlags=MachineInstr::NoFlags) const
static int const Threshold
unsigned getReg() const
getReg - Returns the register number.
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC) const
const MCRegisterInfo & MRI
void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0, unsigned MIFlags=MachineInstr::NoFlags) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
DebugLoc getDebugLoc() const
static const MachineInstrBuilder & AddDefaultT1CC(const MachineInstrBuilder &MIB, bool isDead=false)