39 : IsThumb1Only(STI.isThumb1Only()) {}
47 if (ARM::tGPRRegClass.hasSubClassEq(RC))
48 return &ARM::tGPRRegClass;
54 const DebugLoc &dl,
unsigned DestReg,
55 unsigned SubIdx,
int Val,
74 const DebugLoc &dl,
unsigned DestReg,
75 unsigned SubIdx,
int Val,
102 "Thumb1 does not have ldr to high register");
124 if (BaseReg == ARM::SP &&
126 NumBytes <= 1020 && (NumBytes % 4) == 0) {
142 if (NumBytes < 0 && !isHigh && CanChangeCC) {
144 NumBytes = -NumBytes;
147 if (DestReg == ARM::SP)
148 assert(BaseReg == ARM::SP &&
"Unexpected!");
152 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
157 }
else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
166 }
else if (ST.genExecuteOnly()) {
171 }
else if (!CanChangeCC) {
176 bool LiveCpsr =
false, CpsrWrite =
false;
177 auto isCpsr = [](
auto &MO) {
return MO.getReg() == ARM::CPSR; };
178 for (
auto Iter =
MBBI; Iter !=
MBB.instr_end(); ++Iter) {
181 if (
any_of(Iter->all_uses(), isCpsr)) {
185 if (
any_of(Iter->all_defs(), isCpsr)) {
192 auto liveOutIsCpsr = [](
auto &Out) {
return Out.PhysReg == ARM::CPSR; };
193 if (!LiveCpsr && !CpsrWrite)
194 LiveCpsr =
any_of(
MBB.liveouts(), liveOutIsCpsr);
197 unsigned APSREncoding;
201 ARMSysReg::lookupMClassSysRegByName(
"apsr_nzcvq")->Encoding;
226 int Opc = (isSub) ? ARM::tSUBrr
227 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr);
229 if (
Opc != ARM::tADDhirr)
231 if (DestReg == ARM::SP || isSub)
249 bool isSub = NumBytes < 0;
250 unsigned Bytes = (
unsigned)NumBytes;
251 if (isSub) Bytes = -NumBytes;
254 unsigned CopyBits = 0;
255 unsigned CopyScale = 1;
256 bool CopyNeedsCC =
false;
258 unsigned ExtraBits = 0;
259 unsigned ExtraScale = 1;
260 bool ExtraNeedsCC =
false;
275 if (DestReg == ARM::SP) {
276 if (BaseReg == ARM::SP) {
281 CopyOpc = ARM::tMOVr;
284 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
288 if (BaseReg == ARM::SP) {
290 assert(!isSub &&
"Thumb1 does not have tSUBrSPi");
291 CopyOpc = ARM::tADDrSPi;
294 }
else if (DestReg == BaseReg) {
299 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
304 CopyOpc = ARM::tMOVr;
307 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
311 if (DestReg == BaseReg) {
316 CopyOpc = ARM::tMOVr;
324 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
325 "Unaligned offset, but all instructions require alignment");
327 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
329 if (CopyOpc && Bytes < CopyScale) {
330 CopyOpc = ARM::tMOVr;
335 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale;
336 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
337 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
341 assert(RangeAfterCopy % ExtraScale == 0 &&
342 "Extra instruction requires immediate to be aligned");
344 unsigned RequiredExtraInstrs;
346 RequiredExtraInstrs =
alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
347 else if (RangeAfterCopy > 0)
349 RequiredExtraInstrs = 1000000;
351 RequiredExtraInstrs = 0;
352 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
353 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
356 if (RequiredInstrs > Threshold) {
358 DestReg, BaseReg, NumBytes,
true,
365 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
366 Bytes -= CopyImm * CopyScale;
372 if (CopyOpc != ARM::tMOVr) {
382 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
383 Bytes -= ExtraImm * ExtraScale;
397 for (
unsigned e =
MI.getNumOperands(); i != e; ++i)
398 MI.removeOperand(
Op);
416 unsigned FrameRegIdx,
423 "This isn't needed for thumb2!");
426 unsigned Opcode =
MI.getOpcode();
430 if (Opcode == ARM::tADDframe) {
431 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
442 unsigned ImmIdx = FrameRegIdx + 1;
443 int InstrOffs =
MI.getOperand(ImmIdx).getImm();
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) {
461 if (ARM::hGPRRegClass.
contains(FrameReg) && FrameReg != ARM::SP) {
468 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg,
false);
474 if (NewOpc != Opcode && FrameReg != ARM::SP)
475 MI.setDesc(
TII.get(NewOpc));
483 Mask = (1 << NumBits) - 1;
488 if (FrameReg == ARM::SP &&
Offset - (Mask * Scale) <= 1020) {
490 }
else if (ST.genExecuteOnly()) {
496 unsigned BottomBits = (
Offset / Scale) & Mask;
497 bool CanMakeBottomByteZero = ((
Offset - BottomBits * Scale) & 0xff) == 0;
498 bool TopHalfZero = (
Offset & 0xffff0000) == 0;
499 bool CanMakeTopHalfZero = ((
Offset - Mask * Scale) & 0xffff0000) == 0;
500 if (!TopHalfZero && CanMakeTopHalfZero)
502 else if (!ST.useMovt() && CanMakeBottomByteZero)
503 InstrOffs = BottomBits;
506 Offset -= InstrOffs * Scale;
523 while (!
MI.getOperand(i).isFI()) {
525 assert(i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
528 assert (
Done &&
"Unable to resolve frame index!");
533 int SPAdj,
unsigned FIOperandNum,
549 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
558 if (RS && FrameReg == ARM::SP && RS->isScavengingFrameIndex(FrameIndex)){
560 "Cannot use SP to access the emergency spill slot in "
561 "functions without a reserved call frame");
563 "Cannot use SP to access the emergency spill slot in "
564 "functions with variable sized frame objects");
569 if (
MI.isDebugValue()) {
570 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg,
false );
571 MI.getOperand(FIOperandNum+1).ChangeToImmediate(
Offset);
577 "This eliminateFrameIndex only supports Thumb1!");
584 assert(
Offset &&
"This code isn't needed if offset already handled!");
586 unsigned Opcode =
MI.getOpcode();
589 int PIdx =
MI.findFirstPredOperandIdx();
597 if (Opcode == ARM::tLDRspi) {
598 if (FrameReg == ARM::SP || STI.genExecuteOnly())
603 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
619 MI.setDesc(
TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
620 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg,
false,
false,
true);
623 "Thumb1 loads can't use high register");
626 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
629 }
else if (
MI.mayStore()) {
633 if (Opcode == ARM::tSTRspi) {
634 if (FrameReg == ARM::SP || STI.genExecuteOnly())
639 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
653 MI.setDesc(
TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
654 MI.getOperand(FIOperandNum).ChangeToRegister(VReg,
false,
false,
true);
657 "Thumb1 stores can't use high register");
660 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
668 if (
MI.isPredicable())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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...
virtual 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
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
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
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & 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.
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.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
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.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState 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...
DWARFExpression::Operation Op
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
MCRegisterClass TargetRegisterClass
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
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