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");
133 if (BaseReg == ARM::SP &&
135 NumBytes <= 1020 && (NumBytes % 4) == 0) {
151 if (NumBytes < 0 && !isHigh && CanChangeCC) {
153 NumBytes = -NumBytes;
156 if (DestReg == ARM::SP)
157 assert(BaseReg == ARM::SP &&
"Unexpected!");
161 if (NumBytes <= 255 && NumBytes >= 0 && CanChangeCC) {
166 }
else if (NumBytes < 0 && NumBytes >= -255 && CanChangeCC) {
175 }
else if (ST.genExecuteOnly()) {
180 }
else if (!CanChangeCC) {
185 bool LiveCpsr =
false, CpsrWrite =
false;
186 auto isCpsr = [](
auto &MO) {
return MO.
getReg() == ARM::CPSR; };
190 if (
any_of(Iter->all_uses(), isCpsr)) {
194 if (
any_of(Iter->all_defs(), isCpsr)) {
201 auto liveOutIsCpsr = [](
auto &Out) {
return Out.PhysReg == ARM::CPSR; };
202 if (!LiveCpsr && !CpsrWrite)
206 unsigned APSREncoding;
210 ARMSysReg::lookupMClassSysRegByName(
"apsr_nzcvq")->Encoding;
235 int Opc = (isSub) ? ARM::tSUBrr
236 : ((isHigh || !CanChangeCC) ? ARM::tADDhirr : ARM::tADDrr);
238 if (Opc != ARM::tADDhirr)
240 if (DestReg == ARM::SP || isSub)
258 bool isSub = NumBytes < 0;
259 unsigned Bytes = (
unsigned)NumBytes;
260 if (isSub) Bytes = -NumBytes;
263 unsigned CopyBits = 0;
264 unsigned CopyScale = 1;
265 bool CopyNeedsCC =
false;
267 unsigned ExtraBits = 0;
268 unsigned ExtraScale = 1;
269 bool ExtraNeedsCC =
false;
284 if (DestReg == ARM::SP) {
285 if (BaseReg == ARM::SP) {
290 CopyOpc = ARM::tMOVr;
293 ExtraOpc = isSub ? ARM::tSUBspi : ARM::tADDspi;
297 if (BaseReg == ARM::SP) {
299 assert(!isSub &&
"Thumb1 does not have tSUBrSPi");
300 CopyOpc = ARM::tADDrSPi;
303 }
else if (DestReg == BaseReg) {
308 CopyOpc = isSub ? ARM::tSUBi3 : ARM::tADDi3;
313 CopyOpc = ARM::tMOVr;
316 ExtraOpc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
320 if (DestReg == BaseReg) {
325 CopyOpc = ARM::tMOVr;
333 assert(((Bytes & 3) == 0 || ExtraScale == 1) &&
334 "Unaligned offset, but all instructions require alignment");
336 unsigned CopyRange = ((1 << CopyBits) - 1) * CopyScale;
338 if (CopyOpc && Bytes < CopyScale) {
339 CopyOpc = ARM::tMOVr;
344 unsigned ExtraRange = ((1 << ExtraBits) - 1) * ExtraScale;
345 unsigned RequiredCopyInstrs = CopyOpc ? 1 : 0;
346 unsigned RangeAfterCopy = (CopyRange > Bytes) ? 0 : (Bytes - CopyRange);
350 assert(RangeAfterCopy % ExtraScale == 0 &&
351 "Extra instruction requires immediate to be aligned");
353 unsigned RequiredExtraInstrs;
355 RequiredExtraInstrs =
alignTo(RangeAfterCopy, ExtraRange) / ExtraRange;
356 else if (RangeAfterCopy > 0)
358 RequiredExtraInstrs = 1000000;
360 RequiredExtraInstrs = 0;
361 unsigned RequiredInstrs = RequiredCopyInstrs + RequiredExtraInstrs;
362 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
365 if (RequiredInstrs > Threshold) {
367 DestReg, BaseReg, NumBytes,
true,
374 unsigned CopyImm = std::min(Bytes, CopyRange) / CopyScale;
375 Bytes -= CopyImm * CopyScale;
381 if (CopyOpc != ARM::tMOVr) {
391 unsigned ExtraImm = std::min(Bytes, ExtraRange) / ExtraScale;
392 Bytes -= ExtraImm * ExtraScale;
406 for (
unsigned e =
MI.getNumOperands(); i != e; ++i)
407 MI.removeOperand(
Op);
425 unsigned FrameRegIdx,
432 "This isn't needed for thumb2!");
435 unsigned Opcode =
MI.getOpcode();
439 if (Opcode == ARM::tADDframe) {
440 Offset +=
MI.getOperand(FrameRegIdx+1).getImm();
451 unsigned ImmIdx = FrameRegIdx + 1;
452 int InstrOffs =
MI.getOperand(ImmIdx).getImm();
453 unsigned NumBits = (FrameReg == ARM::SP) ? 8 : 5;
456 Offset += InstrOffs * Scale;
457 assert((
Offset & (Scale - 1)) == 0 &&
"Can't encode this offset!");
461 int ImmedOffset =
Offset / Scale;
462 unsigned Mask = (1 << NumBits) - 1;
464 if ((
unsigned)
Offset <= Mask * Scale) {
470 if (ARM::hGPRRegClass.
contains(FrameReg) && FrameReg != ARM::SP) {
477 MI.getOperand(FrameRegIdx).ChangeToRegister(DestReg,
false);
483 if (NewOpc != Opcode && FrameReg != ARM::SP)
484 MI.setDesc(
TII.get(NewOpc));
492 Mask = (1 << NumBits) - 1;
497 if (FrameReg == ARM::SP &&
Offset - (Mask * Scale) <= 1020) {
499 }
else if (ST.genExecuteOnly()) {
505 unsigned BottomBits = (
Offset / Scale) & Mask;
506 bool CanMakeBottomByteZero = ((
Offset - BottomBits * Scale) & 0xff) == 0;
507 bool TopHalfZero = (
Offset & 0xffff0000) == 0;
508 bool CanMakeTopHalfZero = ((
Offset - Mask * Scale) & 0xffff0000) == 0;
509 if (!TopHalfZero && CanMakeTopHalfZero)
511 else if (!ST.useMovt() && CanMakeBottomByteZero)
512 InstrOffs = BottomBits;
515 Offset -= InstrOffs * Scale;
532 while (!
MI.getOperand(i).isFI()) {
534 assert(i <
MI.getNumOperands() &&
"Instr doesn't have FrameIndex operand!");
537 assert (
Done &&
"Unable to resolve frame index!");
542 int SPAdj,
unsigned FIOperandNum,
558 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
569 "Cannot use SP to access the emergency spill slot in "
570 "functions without a reserved call frame");
572 "Cannot use SP to access the emergency spill slot in "
573 "functions with variable sized frame objects");
578 if (
MI.isDebugValue()) {
579 MI.getOperand(FIOperandNum). ChangeToRegister(FrameReg,
false );
580 MI.getOperand(FIOperandNum+1).ChangeToImmediate(
Offset);
586 "This eliminateFrameIndex only supports Thumb1!");
593 assert(
Offset &&
"This code isn't needed if offset already handled!");
595 unsigned Opcode =
MI.getOpcode();
598 int PIdx =
MI.findFirstPredOperandIdx();
606 if (Opcode == ARM::tLDRspi) {
607 if (FrameReg == ARM::SP || STI.genExecuteOnly())
612 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
628 MI.setDesc(
TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
629 MI.getOperand(FIOperandNum).ChangeToRegister(TmpReg,
false,
false,
true);
632 "Thumb1 loads can't use high register");
635 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
638 }
else if (
MI.mayStore()) {
642 if (Opcode == ARM::tSTRspi) {
643 if (FrameReg == ARM::SP || STI.genExecuteOnly())
648 if (!ARM::hGPRRegClass.
contains(FrameReg)) {
662 MI.setDesc(
TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
663 MI.getOperand(FIOperandNum).ChangeToRegister(VReg,
false,
false,
true);
666 "Thumb1 stores can't use high register");
669 MI.getOperand(FIOperandNum+1).ChangeToRegister(FrameReg,
false,
false,
677 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 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
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 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.
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.
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