39 cl::desc(
"Use old-style Thumb2 if-conversion heuristics"),
84 while (Count && MBBI != E) {
85 if (MBBI->isDebugValue()) {
89 if (MBBI->getOpcode() == ARM::t2IT) {
90 unsigned Mask = MBBI->getOperand(1).getImm();
92 MBBI->eraseFromParent();
94 unsigned MaskOn = 1 << Count;
95 unsigned MaskOff = ~(MaskOn - 1);
96 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
112 while (MBBI->isDebugValue()) {
114 if (MBBI == MBB.
end())
118 unsigned PredReg = 0;
124 const DebugLoc &DL,
unsigned DestReg,
125 unsigned SrcReg,
bool KillSrc)
const {
127 if (!ARM::GPRRegClass.
contains(DestReg, SrcReg))
130 BuildMI(MBB, I, DL,
get(ARM::tMOVr), DestReg)
137 unsigned SrcReg,
bool isKill,
int FI,
141 if (I != MBB.
end()) DL = I->getDebugLoc();
149 if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
150 RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
151 RC == &ARM::GPRnopcRegClass) {
152 BuildMI(MBB, I, DL,
get(ARM::t2STRi12))
161 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
172 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
182 unsigned DestReg,
int FI,
191 if (I != MBB.
end()) DL = I->getDebugLoc();
193 if (RC == &ARM::GPRRegClass || RC == &ARM::tGPRRegClass ||
194 RC == &ARM::tcGPRRegClass || RC == &ARM::rGPRRegClass ||
195 RC == &ARM::GPRnopcRegClass) {
196 BuildMI(MBB, I, DL,
get(ARM::t2LDRi12), DestReg)
204 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
211 &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
227 void Thumb2InstrInfo::expandLoadStackGuard(
238 const DebugLoc &dl,
unsigned DestReg,
239 unsigned BaseReg,
int NumBytes,
243 if (NumBytes == 0 && DestReg != BaseReg) {
244 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
250 bool isSub = NumBytes < 0;
251 if (isSub) NumBytes = -NumBytes;
255 if (DestReg != ARM::SP && DestReg != BaseReg &&
259 if (NumBytes < 65536) {
261 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
265 }
else if ((NumBytes & 0xffff) == 0) {
267 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
276 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
288 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
300 unsigned ThisVal = NumBytes;
302 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
304 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
312 bool HasCCOut =
true;
313 if (BaseReg == ARM::SP) {
315 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
316 assert((ThisVal & 3) == 0 &&
"Stack update is not multiple of 4?");
317 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
318 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
328 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
335 NumBytes &= ~ThisVal;
337 "Bit extraction didn't work?");
340 assert(DestReg != ARM::SP && BaseReg != ARM::SP);
341 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
344 }
else if (ThisVal < 4096) {
345 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
352 NumBytes &= ~ThisVal;
354 "Bit extraction didn't work?");
375 case ARM::t2LDRi12:
return ARM::t2LDRi8;
376 case ARM::t2LDRHi12:
return ARM::t2LDRHi8;
377 case ARM::t2LDRBi12:
return ARM::t2LDRBi8;
378 case ARM::t2LDRSHi12:
return ARM::t2LDRSHi8;
379 case ARM::t2LDRSBi12:
return ARM::t2LDRSBi8;
380 case ARM::t2STRi12:
return ARM::t2STRi8;
381 case ARM::t2STRBi12:
return ARM::t2STRBi8;
382 case ARM::t2STRHi12:
return ARM::t2STRHi8;
383 case ARM::t2PLDi12:
return ARM::t2PLDi8;
407 case ARM::t2LDRi8:
return ARM::t2LDRi12;
408 case ARM::t2LDRHi8:
return ARM::t2LDRHi12;
409 case ARM::t2LDRBi8:
return ARM::t2LDRBi12;
410 case ARM::t2LDRSHi8:
return ARM::t2LDRSHi12;
411 case ARM::t2LDRSBi8:
return ARM::t2LDRSBi12;
412 case ARM::t2STRi8:
return ARM::t2STRi12;
413 case ARM::t2STRBi8:
return ARM::t2STRBi12;
414 case ARM::t2STRHi8:
return ARM::t2STRHi12;
415 case ARM::t2PLDi8:
return ARM::t2PLDi12;
420 case ARM::t2LDRSHi12:
421 case ARM::t2LDRSBi12:
439 case ARM::t2LDRs:
return ARM::t2LDRi12;
440 case ARM::t2LDRHs:
return ARM::t2LDRHi12;
441 case ARM::t2LDRBs:
return ARM::t2LDRBi12;
442 case ARM::t2LDRSHs:
return ARM::t2LDRSHi12;
443 case ARM::t2LDRSBs:
return ARM::t2LDRSBi12;
444 case ARM::t2STRs:
return ARM::t2STRi12;
445 case ARM::t2STRBs:
return ARM::t2STRBi12;
446 case ARM::t2STRHs:
return ARM::t2STRHi12;
447 case ARM::t2PLDs:
return ARM::t2PLDi12;
452 case ARM::t2LDRSHi12:
453 case ARM::t2LDRSBi12:
477 unsigned FrameReg,
int &
Offset,
488 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
495 MI.
setDesc(TII.get(ARM::tMOVr));
505 bool HasCCOut = Opcode != ARM::t2ADDri12;
510 MI.
setDesc(TII.get(ARM::t2SUBri));
512 MI.
setDesc(TII.get(ARM::t2ADDri));
528 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
541 unsigned RotAmt = countLeadingZeros<unsigned>(
Offset);
542 unsigned ThisImmVal = Offset &
ARM_AM::rotr32(0xff000000U, RotAmt);
545 Offset &= ~ThisImmVal;
548 "Bit extraction didn't work?");
560 unsigned NewOpc = Opcode;
563 if (OffsetReg != 0) {
574 unsigned NumBits = 0;
598 Offset += InstrOffs * 4;
599 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
612 Offset += InstrOffs * 2;
613 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
623 assert((Offset & 3) == 0 &&
"Can't encode this offset!");
628 if (NewOpc != Opcode)
635 int ImmedOffset = Offset / Scale;
636 unsigned Mask = (1 << NumBits) - 1;
637 if ((
unsigned)Offset <= Mask * Scale) {
643 ImmedOffset |= 1 << NumBits;
645 ImmedOffset = -ImmedOffset;
653 ImmedOffset = ImmedOffset &
Mask;
657 ImmedOffset |= 1 << NumBits;
659 ImmedOffset = -ImmedOffset;
660 if (ImmedOffset == 0)
666 Offset &= ~(Mask*Scale);
669 Offset = (isSub) ? -Offset : Offset;
676 if (Opc == ARM::tBcc || Opc == ARM::t2Bcc)
const MachineInstrBuilder & add(const MachineOperand &MO) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Compute iterated dominance frontiers using a linear time algorithm.
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
static unsigned negativeOffsetOpcode(unsigned opcode)
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
return AArch64::GPR64RegClass contains(Reg)
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static cl::opt< bool > OldT2IfCvt("old-thumb2-ifcvt", cl::Hidden, cl::desc("Use old-style Thumb2 if-conversion heuristics"), cl::init(false))
bool isLegalToSplitMBBAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override
A description of a memory reference used in the backend.
static MCOperand createReg(unsigned Reg)
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Access to explicit operands of the instruction.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
INLINEASM - Represents an inline asm block.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
Instances of this class represent a single low-level machine instruction.
unsigned getKillRegState(bool B)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
unsigned getUnindexedOpcode(unsigned Opc) const override
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const
Delete the instruction OldInst and everything after it, replacing it with an unconditional branch to ...
initializer< Ty > init(const Ty &Val)
unsigned char getAM5Offset(unsigned AM5Opc)
unsigned const MachineRegisterInfo * MRI
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
void getNoop(MCInst &NopInst) const override
Return the noop instruction to use for a noop.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
Thumb2InstrInfo(const ARMSubtarget &STI)
const MachineInstrBuilder & addFrameIndex(int Idx) const
unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
static unsigned immediateOffsetOpcode(unsigned opcode)
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The memory access writes data.
void setOpcode(unsigned Op)
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
ARMCC::CondCodes getITInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getITInstrPredicate - Valid only in Thumb2 mode.
MachineOperand class - Representation of each machine instruction operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail, MachineBasicBlock *NewDest) const override
AddrOpc getAM5FP16Op(unsigned AM5Opc)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
AddrMode
ARM Addressing Modes.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static unsigned positiveOffsetOpcode(unsigned opcode)
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool isPositionIndependent() const
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
void addOperand(const MCOperand &Op)
unsigned char getAM5FP16Offset(unsigned AM5Opc)
AddrOpc getAM5Op(unsigned AM5Opc)
const MachineOperand & getOperand(unsigned i) const
static MCOperand createImm(int64_t Val)