46 if (ARM::tGPRRegClass.hasSubClassEq(RC))
47 return &ARM::tGPRRegClass;
53 unsigned Kind)
const {
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; };
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)
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();
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
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 ...
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 * 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
This is an important base class in LLVM.
This class represents an Operation in the Expression.
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.
iterator_range< liveout_iterator > liveouts() const
instr_iterator instr_end()
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.
Register getReg(unsigned Idx) const
Get the register for the operand index.
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.
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 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.
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.
Description of the encoding of one expression Op.
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