38 cl::desc(
"Use old-style Thumb2 if-conversion heuristics"),
83 while (Count && MBBI != E) {
84 if (MBBI->isDebugInstr()) {
88 if (MBBI->getOpcode() == ARM::t2IT) {
89 unsigned Mask = MBBI->getOperand(1).getImm();
91 MBBI->eraseFromParent();
93 unsigned MaskOn = 1 << Count;
94 unsigned MaskOff = ~(MaskOn - 1);
95 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
111 while (MBBI->isDebugInstr()) {
113 if (MBBI == MBB.
end())
117 unsigned PredReg = 0;
123 const DebugLoc &DL,
unsigned DestReg,
124 unsigned SrcReg,
bool KillSrc)
const {
126 if (!ARM::GPRRegClass.
contains(DestReg, SrcReg))
129 BuildMI(MBB, I, DL,
get(ARM::tMOVr), DestReg)
136 unsigned SrcReg,
bool isKill,
int FI,
140 if (I != MBB.
end()) DL = I->getDebugLoc();
148 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
149 BuildMI(MBB, I, DL,
get(ARM::t2STRi12))
158 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
169 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
179 unsigned DestReg,
int FI,
188 if (I != MBB.
end()) DL = I->getDebugLoc();
190 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
191 BuildMI(MBB, I, DL,
get(ARM::t2LDRi12), DestReg)
199 if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
206 &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
222 void Thumb2InstrInfo::expandLoadStackGuard(
233 const DebugLoc &dl,
unsigned DestReg,
234 unsigned BaseReg,
int NumBytes,
238 if (NumBytes == 0 && DestReg != BaseReg) {
239 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
245 bool isSub = NumBytes < 0;
246 if (isSub) NumBytes = -NumBytes;
250 if (DestReg != ARM::SP && DestReg != BaseReg &&
254 if (NumBytes < 65536) {
256 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
260 }
else if ((NumBytes & 0xffff) == 0) {
262 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
271 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
283 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
295 unsigned ThisVal = NumBytes;
297 if (DestReg == ARM::SP && BaseReg != ARM::SP) {
299 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
307 bool HasCCOut =
true;
308 if (BaseReg == ARM::SP) {
310 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) {
311 assert((ThisVal & 3) == 0 &&
"Stack update is not multiple of 4?");
312 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
313 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
323 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
330 NumBytes &= ~ThisVal;
332 "Bit extraction didn't work?");
335 assert(DestReg != ARM::SP && BaseReg != ARM::SP);
336 Opc = isSub ? ARM::t2SUBri : ARM::t2ADDri;
339 }
else if (ThisVal < 4096) {
340 Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
347 NumBytes &= ~ThisVal;
349 "Bit extraction didn't work?");
370 case ARM::t2LDRi12:
return ARM::t2LDRi8;
371 case ARM::t2LDRHi12:
return ARM::t2LDRHi8;
372 case ARM::t2LDRBi12:
return ARM::t2LDRBi8;
373 case ARM::t2LDRSHi12:
return ARM::t2LDRSHi8;
374 case ARM::t2LDRSBi12:
return ARM::t2LDRSBi8;
375 case ARM::t2STRi12:
return ARM::t2STRi8;
376 case ARM::t2STRBi12:
return ARM::t2STRBi8;
377 case ARM::t2STRHi12:
return ARM::t2STRHi8;
378 case ARM::t2PLDi12:
return ARM::t2PLDi8;
402 case ARM::t2LDRi8:
return ARM::t2LDRi12;
403 case ARM::t2LDRHi8:
return ARM::t2LDRHi12;
404 case ARM::t2LDRBi8:
return ARM::t2LDRBi12;
405 case ARM::t2LDRSHi8:
return ARM::t2LDRSHi12;
406 case ARM::t2LDRSBi8:
return ARM::t2LDRSBi12;
407 case ARM::t2STRi8:
return ARM::t2STRi12;
408 case ARM::t2STRBi8:
return ARM::t2STRBi12;
409 case ARM::t2STRHi8:
return ARM::t2STRHi12;
410 case ARM::t2PLDi8:
return ARM::t2PLDi12;
415 case ARM::t2LDRSHi12:
416 case ARM::t2LDRSBi12:
434 case ARM::t2LDRs:
return ARM::t2LDRi12;
435 case ARM::t2LDRHs:
return ARM::t2LDRHi12;
436 case ARM::t2LDRBs:
return ARM::t2LDRBi12;
437 case ARM::t2LDRSHs:
return ARM::t2LDRSHi12;
438 case ARM::t2LDRSBs:
return ARM::t2LDRSBi12;
439 case ARM::t2STRs:
return ARM::t2STRi12;
440 case ARM::t2STRBs:
return ARM::t2STRBi12;
441 case ARM::t2STRHs:
return ARM::t2STRHi12;
442 case ARM::t2PLDs:
return ARM::t2PLDi12;
447 case ARM::t2LDRSHi12:
448 case ARM::t2LDRSBi12:
472 unsigned FrameReg,
int &
Offset,
483 if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
490 MI.
setDesc(TII.get(ARM::tMOVr));
500 bool HasCCOut = Opcode != ARM::t2ADDri12;
505 MI.
setDesc(TII.get(ARM::t2SUBri));
507 MI.
setDesc(TII.get(ARM::t2ADDri));
523 unsigned NewOpc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12;
536 unsigned RotAmt = countLeadingZeros<unsigned>(
Offset);
537 unsigned ThisImmVal = Offset &
ARM_AM::rotr32(0xff000000U, RotAmt);
540 Offset &= ~ThisImmVal;
543 "Bit extraction didn't work?");
555 unsigned NewOpc = Opcode;
558 if (OffsetReg != 0) {
569 unsigned NumBits = 0;
593 Offset += InstrOffs * 4;
594 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
607 Offset += InstrOffs * 2;
608 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
618 assert((Offset & 3) == 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
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)