39 cl::desc(
"Use old-style Thumb2 if-conversion heuristics"),
84 while (Count && MBBI != E) {
85 if (MBBI->isDebugInstr()) {
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->isDebugInstr()) {
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 (ARM::GPRRegClass.hasSubClassEq(RC)) {
150 BuildMI(MBB, I, DL,
get(ARM::t2STRi12))
159 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
170 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
180 unsigned DestReg,
int FI,
189 if (I != MBB.
end()) DL = I->getDebugLoc();
191 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
192 BuildMI(MBB, I, DL,
get(ARM::t2LDRi12), DestReg)
200 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
207 &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
223 void Thumb2InstrInfo::expandLoadStackGuard(
234 const DebugLoc &dl,
unsigned DestReg,
235 unsigned BaseReg,
int NumBytes,
239 if (NumBytes == 0 && DestReg != BaseReg) {
240 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
246 bool isSub = NumBytes < 0;
247 if (isSub) NumBytes = -NumBytes;
251 if (DestReg != ARM::SP && DestReg != BaseReg &&
255 if (NumBytes < 65536) {
257 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
261 }
else if ((NumBytes & 0xffff) == 0) {
263 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
272 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
284 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
296 unsigned ThisVal = NumBytes;
298 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
300 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
308 bool HasCCOut =
true;
309 if (BaseReg == ARM::SP) {
311 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
312 assert((ThisVal & 3) == 0 &&
"Stack update is not multiple of 4?");
313 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
314 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
324 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
331 NumBytes &= ~ThisVal;
333 "Bit extraction didn't work?");
336 assert(DestReg != ARM::SP && BaseReg != ARM::SP);
337 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
340 }
else if (ThisVal < 4096) {
341 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
348 NumBytes &= ~ThisVal;
350 "Bit extraction didn't work?");
371 case ARM::t2LDRi12:
return ARM::t2LDRi8;
372 case ARM::t2LDRHi12:
return ARM::t2LDRHi8;
373 case ARM::t2LDRBi12:
return ARM::t2LDRBi8;
374 case ARM::t2LDRSHi12:
return ARM::t2LDRSHi8;
375 case ARM::t2LDRSBi12:
return ARM::t2LDRSBi8;
376 case ARM::t2STRi12:
return ARM::t2STRi8;
377 case ARM::t2STRBi12:
return ARM::t2STRBi8;
378 case ARM::t2STRHi12:
return ARM::t2STRHi8;
379 case ARM::t2PLDi12:
return ARM::t2PLDi8;
403 case ARM::t2LDRi8:
return ARM::t2LDRi12;
404 case ARM::t2LDRHi8:
return ARM::t2LDRHi12;
405 case ARM::t2LDRBi8:
return ARM::t2LDRBi12;
406 case ARM::t2LDRSHi8:
return ARM::t2LDRSHi12;
407 case ARM::t2LDRSBi8:
return ARM::t2LDRSBi12;
408 case ARM::t2STRi8:
return ARM::t2STRi12;
409 case ARM::t2STRBi8:
return ARM::t2STRBi12;
410 case ARM::t2STRHi8:
return ARM::t2STRHi12;
411 case ARM::t2PLDi8:
return ARM::t2PLDi12;
416 case ARM::t2LDRSHi12:
417 case ARM::t2LDRSBi12:
435 case ARM::t2LDRs:
return ARM::t2LDRi12;
436 case ARM::t2LDRHs:
return ARM::t2LDRHi12;
437 case ARM::t2LDRBs:
return ARM::t2LDRBi12;
438 case ARM::t2LDRSHs:
return ARM::t2LDRSHi12;
439 case ARM::t2LDRSBs:
return ARM::t2LDRSBi12;
440 case ARM::t2STRs:
return ARM::t2STRi12;
441 case ARM::t2STRBs:
return ARM::t2STRBi12;
442 case ARM::t2STRHs:
return ARM::t2STRHi12;
443 case ARM::t2PLDs:
return ARM::t2PLDi12;
448 case ARM::t2LDRSHi12:
449 case ARM::t2LDRSBi12:
473 unsigned FrameReg,
int &
Offset,
484 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
491 MI.
setDesc(TII.get(ARM::tMOVr));
501 bool HasCCOut = Opcode != ARM::t2ADDri12;
506 MI.
setDesc(TII.get(ARM::t2SUBri));
508 MI.
setDesc(TII.get(ARM::t2ADDri));
524 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
537 unsigned RotAmt = countLeadingZeros<unsigned>(
Offset);
538 unsigned ThisImmVal = Offset &
ARM_AM::rotr32(0xff000000U, RotAmt);
541 Offset &= ~ThisImmVal;
544 "Bit extraction didn't work?");
556 unsigned NewOpc = Opcode;
559 if (OffsetReg != 0) {
570 unsigned NumBits = 0;
594 Offset += InstrOffs * 4;
595 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
608 Offset += InstrOffs * 2;
609 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
619 assert((Offset & 3) == 0 &&
"Can't encode this offset!");
624 assert((Offset & 3) == 0 &&
"Can't encode this offset!");
629 if (NewOpc != Opcode)
636 int ImmedOffset = Offset / Scale;
637 unsigned Mask = (1 << NumBits) - 1;
638 if ((
unsigned)Offset <= Mask * Scale) {
644 ImmedOffset |= 1 << NumBits;
646 ImmedOffset = -ImmedOffset;
654 ImmedOffset = ImmedOffset &
Mask;
658 ImmedOffset |= 1 << NumBits;
660 ImmedOffset = -ImmedOffset;
661 if (ImmedOffset == 0)
667 Offset &= ~(Mask*Scale);
670 Offset = (isSub) ? -Offset : Offset;
677 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
This class represents lattice values for constants.
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)
unsigned const TargetRegisterInfo * TRI
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
Retuns the total number of operands.
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.
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)
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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)
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
unsigned char getAM5FP16Offset(unsigned AM5Opc)
AddrOpc getAM5Op(unsigned AM5Opc)
const MachineOperand & getOperand(unsigned i) const
static MCOperand createImm(int64_t Val)