39 : IsThumb1Only(STI.isThumb1Only()) {}
47 if (ARM::tGPRRegClass.hasSubClassEq(RC))
48 return &ARM::tGPRRegClass;
56 return &ARM::tGPRRegClass;
61 const DebugLoc &dl,
unsigned DestReg,
62 unsigned SubIdx,
int Val,
81 const DebugLoc &dl,
unsigned DestReg,
82 unsigned SubIdx,
int Val,
109 "Thumb1 does not have ldr to high register");
131 if (BaseReg == ARM::SP &&
133 NumBytes <= 1020 && (NumBytes % 4) == 0) {
149 if (NumBytes < 0 && !isHigh && CanChangeCC) {
151 NumBytes = -NumBytes;
154 if (DestReg == ARM::SP)
155 assert(BaseReg == ARM::SP &&
"Unexpected!");
159 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
164 }
else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
173 }
else if (ST.genExecuteOnly()) {
178 }
else if (!CanChangeCC) {
183 bool LiveCpsr =
false, CpsrWrite =
false;
184 auto isCpsr = [](
auto &MO) {
return MO.getReg() == ARM::CPSR; };
185 for (
auto Iter =
MBBI; Iter !=
MBB.instr_end(); ++Iter) {
188 if (
any_of(Iter->all_uses(), isCpsr)) {
192 if (
any_of(Iter->all_defs(), isCpsr)) {
199 auto liveOutIsCpsr = [](
auto &Out) {
return Out.PhysReg == ARM::CPSR; };
200 if (!LiveCpsr && !CpsrWrite)
201 LiveCpsr =
any_of(
MBB.liveouts(), liveOutIsCpsr);
204 unsigned APSREncoding;
208 ARMSysReg::lookupMClassSysRegByName(
"apsr_nzcvq")->Encoding;
233 int Opc = (isSub) ? ARM::tSUBrr
234 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr);
236 if (
Opc != ARM::tADDhirr)
238 if (DestReg == ARM::SP || isSub)
256 bool isSub = NumBytes < 0;
257 unsigned Bytes = (
unsigned)NumBytes;
258 if (isSub) Bytes = -NumBytes;
261 unsigned CopyBits = 0;
262 unsigned CopyScale = 1;
263 bool CopyNeedsCC =
false;
265 unsigned ExtraBits = 0;
266 unsigned ExtraScale = 1;
267 bool ExtraNeedsCC =
false;
282 if (DestReg == ARM::SP) {
283 if (BaseReg == ARM::SP) {
288 CopyOpc = ARM::tMOVr;
291 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
295 if (BaseReg == ARM::SP) {
297 assert(!isSub &&
"Thumb1 does not have tSUBrSPi");
298 CopyOpc = ARM::tADDrSPi;
301 }
else if (DestReg == BaseReg) {
306 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
311 CopyOpc = ARM::tMOVr;
314 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
318 if (DestReg == BaseReg) {
323 CopyOpc = ARM::tMOVr;
331 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
332 "Unaligned offset, but all instructions require alignment");
334 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
336 if (CopyOpc && Bytes < CopyScale) {
337 CopyOpc = ARM::tMOVr;
342 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale;
343 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
344 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
348 assert(RangeAfterCopy % ExtraScale == 0 &&
349 "Extra instruction requires immediate to be aligned");
351 unsigned RequiredExtraInstrs;
353 RequiredExtraInstrs =
alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
354 else if (RangeAfterCopy > 0)
356 RequiredExtraInstrs = 1000000;
358 RequiredExtraInstrs = 0;
359 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
360 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
363 if (RequiredInstrs > Threshold) {
365 DestReg, BaseReg, NumBytes,
true,
372 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
373 Bytes -= CopyImm * CopyScale;
379 if (CopyOpc != ARM::tMOVr) {
389 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
390 Bytes -= ExtraImm * ExtraScale;
404 for (
unsigned e =
MI.getNumOperands(); i != e; ++i)
405 MI.removeOperand(
Op);
423 unsigned FrameRegIdx,
430 "This isn't needed for thumb2!");
433 unsigned Opcode =
MI.getOpcode();
437 if (Opcode == ARM::tADDframe) {
438 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
449 unsigned ImmIdx = FrameRegIdx + 1;
450 int InstrOffs =
MI.getOperand(ImmIdx).getImm();
451 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
454 Offset += InstrOffs * Scale;
455 assert((
Offset & (Scale - 1)) == 0 &&
"Can't encode this offset!");
459 int ImmedOffset =
Offset / Scale;
460 unsigned Mask = (1 << NumBits) - 1;
462 if ((
unsigned)
Offset <= Mask * Scale) {
468 if (ARM::hGPRRegClass.
contains(FrameReg) && FrameReg != ARM::SP) {
475 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg,
false);
481 if (NewOpc != Opcode && FrameReg != ARM::SP)
482 MI.setDesc(
TII.get(NewOpc));
490 Mask = (1 << NumBits) - 1;
495 if (FrameReg == ARM::SP &&
Offset - (Mask * Scale) <= 1020) {
497 }
else if (ST.genExecuteOnly()) {
503 unsigned BottomBits = (
Offset / Scale) & Mask;
504 bool CanMakeBottomByteZero = ((
Offset - BottomBits * Scale) & 0xff) == 0;
505 bool TopHalfZero = (
Offset & 0xffff0000) == 0;
506 bool CanMakeTopHalfZero = ((
Offset - Mask * Scale) & 0xffff0000) == 0;
507 if (!TopHalfZero && CanMakeTopHalfZero)
509 else if (!ST.useMovt() && CanMakeBottomByteZero)
510 InstrOffs = BottomBits;
513 Offset -= InstrOffs * Scale;
530 while (!
MI.getOperand(i).isFI()) {
532 assert(i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
535 assert (
Done &&
"Unable to resolve frame index!");
540 int SPAdj,
unsigned FIOperandNum,
556 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
565 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
567 "Cannot use SP to access the emergency spill slot in "
568 "functions without a reserved call frame");
570 "Cannot use SP to access the emergency spill slot in "
571 "functions with variable sized frame objects");
576 if (
MI.isDebugValue()) {
577 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg,
false );
578 MI.getOperand(FIOperandNum+1).ChangeToImmediate(
Offset);
584 "This eliminateFrameIndex only supports Thumb1!");
591 assert(
Offset &&
"This code isn't needed if offset already handled!");
593 unsigned Opcode =
MI.getOpcode();
596 int PIdx =
MI.findFirstPredOperandIdx();
604 if (Opcode == ARM::tLDRspi) {
605 if (FrameReg == ARM::SP || STI.genExecuteOnly())
610 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
626 MI.setDesc(
TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
627 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg,
false,
false,
true);
630 "Thumb1 loads can't use high register");
633 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
636 }
else if (
MI.mayStore()) {
640 if (Opcode == ARM::tSTRspi) {
641 if (FrameReg == ARM::SP || STI.genExecuteOnly())
646 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
660 MI.setDesc(
TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
661 MI.getOperand(FIOperandNum).ChangeToRegister(VReg,
false,
false,
true);
664 "Thumb1 stores can't use high register");
667 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
675 if (
MI.isPredicable())
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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...
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &MF) const override
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) 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
This is an important base class in LLVM.
Describe properties that are true of each instruction in the target description file.
MachineInstrBundleIterator< MachineInstr > iterator
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.
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.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
constexpr 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 LLVM_ABI 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.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ 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 bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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.
DWARFExpression::Operation Op
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.
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
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
ThumbRegisterInfo(const ARMSubtarget &STI)
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