48 if (ARM::tGPRRegClass.hasSubClassEq(RC))
49 return &ARM::tGPRRegClass;
55 unsigned Kind)
const {
58 return &ARM::tGPRRegClass;
63 const DebugLoc &dl,
unsigned DestReg,
64 unsigned SubIdx,
int Val,
83 const DebugLoc &dl,
unsigned DestReg,
84 unsigned SubIdx,
int Val,
111 "Thumb1 does not have ldr to high register");
137 if (NumBytes < 0 && !isHigh && CanChangeCC) {
139 NumBytes = -NumBytes;
142 if (DestReg == ARM::SP)
143 assert(BaseReg == ARM::SP &&
"Unexpected!");
147 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
152 }
else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
161 }
else if (ST.genExecuteOnly()) {
169 int Opc = (isSub) ? ARM::tSUBrr
170 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr);
172 if (Opc != ARM::tADDhirr)
174 if (DestReg == ARM::SP || isSub)
192 bool isSub = NumBytes < 0;
193 unsigned Bytes = (
unsigned)NumBytes;
194 if (isSub) Bytes = -NumBytes;
197 unsigned CopyBits = 0;
198 unsigned CopyScale = 1;
199 bool CopyNeedsCC =
false;
201 unsigned ExtraBits = 0;
202 unsigned ExtraScale = 1;
203 bool ExtraNeedsCC =
false;
218 if (DestReg == ARM::SP) {
219 if (BaseReg == ARM::SP) {
224 CopyOpc = ARM::tMOVr;
227 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
231 if (BaseReg == ARM::SP) {
233 assert(!isSub &&
"Thumb1 does not have tSUBrSPi");
234 CopyOpc = ARM::tADDrSPi;
237 }
else if (DestReg == BaseReg) {
242 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
247 CopyOpc = ARM::tMOVr;
250 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
254 if (DestReg == BaseReg) {
259 CopyOpc = ARM::tMOVr;
267 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
268 "Unaligned offset, but all instructions require alignment");
270 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
272 if (CopyOpc && Bytes < CopyScale) {
273 CopyOpc = ARM::tMOVr;
278 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale;
279 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
280 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
284 assert(RangeAfterCopy % ExtraScale == 0 &&
285 "Extra instruction requires immediate to be aligned");
287 unsigned RequiredExtraInstrs;
289 RequiredExtraInstrs =
alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
290 else if (RangeAfterCopy > 0)
292 RequiredExtraInstrs = 1000000;
294 RequiredExtraInstrs = 0;
295 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
296 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
299 if (RequiredInstrs > Threshold) {
301 DestReg, BaseReg, NumBytes,
true,
308 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
309 Bytes -= CopyImm * CopyScale;
315 if (CopyOpc != ARM::tMOVr) {
325 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
326 Bytes -= ExtraImm * ExtraScale;
340 for (
unsigned e =
MI.getNumOperands(); i != e; ++i)
341 MI.removeOperand(Op);
359 unsigned FrameRegIdx,
366 "This isn't needed for thumb2!");
369 unsigned Opcode =
MI.getOpcode();
373 if (Opcode == ARM::tADDframe) {
374 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
385 unsigned ImmIdx = FrameRegIdx + 1;
386 int InstrOffs =
MI.getOperand(ImmIdx).getImm();
387 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
390 Offset += InstrOffs * Scale;
391 assert((
Offset & (Scale - 1)) == 0 &&
"Can't encode this offset!");
395 int ImmedOffset =
Offset / Scale;
396 unsigned Mask = (1 << NumBits) - 1;
398 if ((
unsigned)
Offset <= Mask * Scale) {
404 if (ARM::hGPRRegClass.
contains(FrameReg) && FrameReg != ARM::SP) {
411 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg,
false);
417 if (NewOpc != Opcode && FrameReg != ARM::SP)
418 MI.setDesc(
TII.get(NewOpc));
424 Mask = (1 << NumBits) - 1;
428 if (Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
432 ImmedOffset = ImmedOffset & Mask;
434 Offset &= ~(Mask * Scale);
452 while (!
MI.getOperand(i).isFI()) {
454 assert(i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
457 assert (
Done &&
"Unable to resolve frame index!");
462 int SPAdj,
unsigned FIOperandNum,
478 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
489 "Cannot use SP to access the emergency spill slot in "
490 "functions without a reserved call frame");
492 "Cannot use SP to access the emergency spill slot in "
493 "functions with variable sized frame objects");
498 if (
MI.isDebugValue()) {
499 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg,
false );
500 MI.getOperand(FIOperandNum+1).ChangeToImmediate(
Offset);
506 "This eliminateFrameIndex only supports Thumb1!");
513 assert(
Offset &&
"This code isn't needed if offset already handled!");
515 unsigned Opcode =
MI.getOpcode();
518 int PIdx =
MI.findFirstPredOperandIdx();
526 if (Opcode == ARM::tLDRspi) {
527 if (FrameReg == ARM::SP || STI.genExecuteOnly())
532 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
548 MI.setDesc(
TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
549 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg,
false,
false,
true);
552 "Thumb1 loads can't use high register");
555 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
558 }
else if (
MI.mayStore()) {
562 if (Opcode == ARM::tSTRspi) {
563 if (FrameReg == ARM::SP || STI.genExecuteOnly())
568 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
582 MI.setDesc(
TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
583 MI.getOperand(FIOperandNum).ChangeToRegister(VReg,
false,
false,
true);
586 "Thumb1 stores can't use high register");
589 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
597 if (
MI.isPredicable())
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, bool CanChangeCC, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=MachineInstr::NoFlags)
emitThumbRegPlusImmInReg - Emits a series of instructions to materialize a destreg = basereg + immedi...
static void removeOperands(MachineInstr &MI, unsigned i)
static void emitThumb1LoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags)
static void emitThumb2LoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred, unsigned PredReg, unsigned MIFlags)
static unsigned convertToNonSPOpcode(unsigned Opcode)
convertToNonSPOpcode - Change the opcode to the non-SP version, because we're replacing the frame ind...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, int SPAdj) const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool isThumbFunction() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
const ARMFrameLowering * getFrameLowering() const override
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
This is an important base class in LLVM.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Describe properties that are true of each instruction in the target description file.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
Wrapper class representing virtual and physical registers.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
static IntegerType * getInt32Ty(LLVMContext &C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
cl::opt< bool > ReuseFrameIndexVals
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
unsigned getDefRegState(bool B)
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
emitThumbRegPlusImmediate - Emits a series of instructions to materialize a destreg = basereg + immed...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool useFPForScavengingIndex(const MachineFunction &MF) const override
void emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, unsigned SubIdx, int Val, ARMCC::CondCodes Pred=ARMCC::AL, Register PredReg=Register(), unsigned MIFlags=MachineInstr::NoFlags) const override
emitLoadConstPool - Emits a load from constpool to materialize the specified immediate.
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx, Register FrameReg, int &Offset, const ARMBaseInstrInfo &TII) const