32 #define GET_INSTRINFO_CTOR_DTOR
33 #include "AArch64GenInstrInfo.inc"
43 unsigned DestReg,
unsigned SrcReg,
47 if (DestReg == AArch64::XSP || SrcReg == AArch64::XSP) {
49 BuildMI(MBB, I, DL,
get(AArch64::ADDxxi_lsl0_s), DestReg)
53 }
else if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) {
55 BuildMI(MBB, I, DL,
get(AArch64::ADDwwi_lsl0_s), DestReg)
60 assert(AArch64::GPR64RegClass.contains(SrcReg));
62 BuildMI(MBB, I, DL,
get(AArch64::MSRix))
66 assert(AArch64::GPR64RegClass.contains(DestReg));
68 BuildMI(MBB, I, DL,
get(AArch64::MRSxi), DestReg)
70 }
else if (AArch64::GPR64RegClass.contains(DestReg)) {
71 if(AArch64::GPR64RegClass.contains(SrcReg)){
72 Opc = AArch64::ORRxxx_lsl;
73 ZeroReg = AArch64::XZR;
75 assert(AArch64::FPR64RegClass.contains(SrcReg));
76 BuildMI(MBB, I, DL,
get(AArch64::FMOVxd), DestReg)
80 }
else if (AArch64::GPR32RegClass.contains(DestReg)) {
81 if(AArch64::GPR32RegClass.contains(SrcReg)){
82 Opc = AArch64::ORRwww_lsl;
83 ZeroReg = AArch64::WZR;
85 assert(AArch64::FPR32RegClass.contains(SrcReg));
86 BuildMI(MBB, I, DL,
get(AArch64::FMOVws), DestReg)
90 }
else if (AArch64::FPR32RegClass.contains(DestReg)) {
91 if(AArch64::FPR32RegClass.contains(SrcReg)){
92 BuildMI(MBB, I, DL,
get(AArch64::FMOVss), DestReg)
97 assert(AArch64::GPR32RegClass.contains(SrcReg));
98 BuildMI(MBB, I, DL,
get(AArch64::FMOVsw), DestReg)
102 }
else if (AArch64::FPR64RegClass.contains(DestReg)) {
103 if(AArch64::FPR64RegClass.contains(SrcReg)){
104 BuildMI(MBB, I, DL,
get(AArch64::FMOVdd), DestReg)
109 assert(AArch64::GPR64RegClass.contains(SrcReg));
110 BuildMI(MBB, I, DL,
get(AArch64::FMOVdx), DestReg)
114 }
else if (AArch64::FPR128RegClass.contains(DestReg)) {
115 assert(AArch64::FPR128RegClass.contains(SrcReg));
120 BuildMI(MBB, I, DL,
get(AArch64::ORRvvv_16B), DestReg)
125 BuildMI(MBB, I, DL,
get(AArch64::LSFP128_PreInd_STR), AArch64::XSP)
130 BuildMI(MBB, I, DL,
get(AArch64::LSFP128_PostInd_LDR), DestReg)
141 BuildMI(MBB, I, DL,
get(Opc), DestReg)
150 return Opc == AArch64::Bcc || Opc == AArch64::CBZw || Opc == AArch64::CBZx ||
151 Opc == AArch64::CBNZw || Opc == AArch64::CBNZx ||
152 Opc == AArch64::TBZwii || Opc == AArch64::TBZxii ||
153 Opc == AArch64::TBNZwii || Opc == AArch64::TBNZxii;
175 case AArch64::TBZwii:
176 case AArch64::TBZxii:
177 case AArch64::TBNZwii:
178 case AArch64::TBNZxii:
195 bool AllowModify)
const {
198 if (I == MBB.
begin())
201 while (I->isDebugValue()) {
202 if (I == MBB.
begin())
206 if (!isUnpredicatedTerminator(I))
213 unsigned LastOpc = LastInst->
getOpcode();
214 if (I == MBB.
begin() || !isUnpredicatedTerminator(--I)) {
215 if (LastOpc == AArch64::Bimm) {
228 unsigned SecondLastOpc = SecondLastInst->
getOpcode();
232 if (AllowModify && LastOpc == AArch64::Bimm) {
233 while (SecondLastOpc == AArch64::Bimm) {
235 LastInst = SecondLastInst;
237 if (I == MBB.
begin() || !isUnpredicatedTerminator(--I)) {
243 SecondLastOpc = SecondLastInst->
getOpcode();
249 if (SecondLastInst && I != MBB.
begin() && isUnpredicatedTerminator(--I))
253 if (LastOpc == AArch64::Bimm) {
254 if (SecondLastOpc == AArch64::Bcc) {
269 if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) {
283 switch (Cond[0].getImm()) {
291 Cond[0].setImm(AArch64::CBNZw);
294 Cond[0].setImm(AArch64::CBNZx);
297 Cond[0].setImm(AArch64::CBZw);
300 Cond[0].setImm(AArch64::CBZx);
302 case AArch64::TBZwii:
303 Cond[0].setImm(AArch64::TBNZwii);
305 case AArch64::TBZxii:
306 Cond[0].setImm(AArch64::TBNZxii);
308 case AArch64::TBNZwii:
309 Cond[0].setImm(AArch64::TBZwii);
311 case AArch64::TBNZxii:
312 Cond[0].setImm(AArch64::TBZxii);
325 if (FBB == 0 && Cond.
empty()) {
328 }
else if (FBB == 0) {
330 for (
int i = 1, e = Cond.
size(); i != e; ++i)
337 for (
int i = 1, e = Cond.
size(); i != e; ++i)
347 if (I == MBB.
begin())
return 0;
349 while (I->isDebugValue()) {
350 if (I == MBB.
begin())
354 if (I->getOpcode() != AArch64::Bimm && !
isCondBranch(I->getOpcode()))
358 I->eraseFromParent();
362 if (I == MBB.
begin())
return 1;
368 I->eraseFromParent();
379 case AArch64::TLSDESC_BLRx: {
383 MI.
setDesc(
get(AArch64::BLRx));
398 unsigned SrcReg,
bool isKill,
413 unsigned StoreOp = 0;
416 case 4: StoreOp = AArch64::LS32_STR;
break;
417 case 8: StoreOp = AArch64::LS64_STR;
break;
424 &&
"Expected integer or floating type for store");
426 case 4: StoreOp = AArch64::LSFP32_STR;
break;
427 case 8: StoreOp = AArch64::LSFP64_STR;
break;
428 case 16: StoreOp = AArch64::LSFP128_STR;
break;
445 unsigned DestReg,
int FrameIdx,
462 case 4: LoadOp = AArch64::LS32_LDR;
break;
463 case 8: LoadOp = AArch64::LS64_LDR;
break;
470 &&
"Expected integer or floating type for store");
472 case 4: LoadOp = AArch64::LSFP32_LDR;
break;
473 case 8: LoadOp = AArch64::LSFP64_LDR;
break;
474 case 16: LoadOp = AArch64::LSFP128_LDR;
break;
487 unsigned Limit = (1 << 16) - 1;
491 for (
unsigned i = 0, e =
I->getNumOperands(); i != e; ++i) {
492 if (!
I->getOperand(i).isFI())
continue;
496 if (
I->getOpcode() == AArch64::ADDxxi_lsl0_s) {
497 Limit = std::min(Limit, 0xfffu);
503 Limit = std::min(Limit, static_cast<unsigned>(MaxOffset));
513 int &AccessScale,
int &MinOffset,
522 case AArch64::LS8_LDR:
case AArch64::LS8_STR:
523 case AArch64::LSFP8_LDR:
case AArch64::LSFP8_STR:
524 case AArch64::LDRSBw:
525 case AArch64::LDRSBx:
530 case AArch64::LS16_LDR:
case AArch64::LS16_STR:
531 case AArch64::LSFP16_LDR:
case AArch64::LSFP16_STR:
532 case AArch64::LDRSHw:
533 case AArch64::LDRSHx:
536 MaxOffset = 0xfff * AccessScale;
538 case AArch64::LS32_LDR:
case AArch64::LS32_STR:
539 case AArch64::LSFP32_LDR:
case AArch64::LSFP32_STR:
540 case AArch64::LDRSWx:
541 case AArch64::LDPSWx:
544 MaxOffset = 0xfff * AccessScale;
546 case AArch64::LS64_LDR:
case AArch64::LS64_STR:
547 case AArch64::LSFP64_LDR:
case AArch64::LSFP64_STR:
551 MaxOffset = 0xfff * AccessScale;
553 case AArch64::LSFP128_LDR:
case AArch64::LSFP128_STR:
556 MaxOffset = 0xfff * AccessScale;
558 case AArch64::LSPair32_LDR:
case AArch64::LSPair32_STR:
559 case AArch64::LSFPPair32_LDR:
case AArch64::LSFPPair32_STR:
561 MinOffset = -0x40 * AccessScale;
562 MaxOffset = 0x3f * AccessScale;
564 case AArch64::LSPair64_LDR:
case AArch64::LSPair64_STR:
565 case AArch64::LSFPPair64_LDR:
case AArch64::LSFPPair64_STR:
567 MinOffset = -0x40 * AccessScale;
568 MaxOffset = 0x3f * AccessScale;
570 case AArch64::LSFPPair128_LDR:
case AArch64::LSFPPair128_STR:
572 MinOffset = -0x40 * AccessScale;
573 MaxOffset = 0x3f * AccessScale;
613 while (++I != E && I->isInsideBundle()) {
614 assert(!I->isBundle() &&
"No nested bundle!");
621 unsigned FrameReg,
int &Offset,
634 unsigned DstReg,
unsigned SrcReg,
unsigned ScratchReg,
636 if (NumBytes == 0 && DstReg == SrcReg)
638 else if (
abs64(NumBytes) & ~0xffffff) {
642 uint64_t
Bits =
static_cast<uint64_t
>(
abs64(NumBytes));
643 BuildMI(MBB, MBBI, dl, TII.
get(AArch64::MOVZxii), ScratchReg)
644 .addImm(0xffff & Bits).
addImm(0)
649 BuildMI(MBB, MBBI, dl, TII.
get(AArch64::MOVKxii), ScratchReg)
657 BuildMI(MBB, MBBI, dl, TII.
get(AArch64::MOVKxii), ScratchReg)
665 BuildMI(MBB, MBBI, dl, TII.
get(AArch64::MOVKxii), ScratchReg)
672 unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
673 BuildMI(MBB, MBBI, dl, TII.
get(AddOp), DstReg)
686 unsigned LowOp, HighOp;
688 LowOp = AArch64::ADDxxi_lsl0_s;
689 HighOp = AArch64::ADDxxi_lsl12_s;
691 LowOp = AArch64::SUBxxi_lsl0_s;
692 HighOp = AArch64::SUBxxi_lsl12_s;
693 NumBytes =
abs64(NumBytes);
698 if ((NumBytes & 0xfff) || NumBytes == 0) {
699 BuildMI(MBB, MBBI, dl, TII.
get(LowOp), DstReg)
708 if (NumBytes & 0xfff000) {
709 BuildMI(MBB, MBBI, dl, TII.
get(HighOp), DstReg)
718 unsigned ScratchReg, int64_t NumBytes,
720 emitRegUpdate(MBB, MI, dl, TII, AArch64::XSP, AArch64::XSP, AArch64::X16,
749 bool Changed =
false;
754 switch (
I->getOpcode()) {
755 case AArch64::TLSDESC_BLRx:
757 if (!
I->getOperand(1).isSymbol() ||
758 strcmp(
I->getOperand(1).getSymbolName(),
"_TLS_MODULE_BASE_"))
762 I = ReplaceTLSBaseAddrCall(
I, TLSBaseAddrReg);
764 I = SetRegister(
I, &TLSBaseAddrReg);
775 Changed |= VisitNode(*
I, TLSBaseAddrReg);
784 unsigned TLSBaseAddrReg) {
795 .addReg(TLSBaseAddrReg);
820 .addReg(AArch64::X0);
825 virtual const char *getPassName()
const {
826 return "Local Dynamic TLS Access Clean-up";
unsigned getNumLocalDynamicTLSAccesses() const
int strcmp(const char *s1, const char *s2);
void push_back(const T &Elt)
The memory access reads data.
const MachineFunction * getParent() const
const AArch64InstrInfo * getInstrInfo() const
The memory access writes data.
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
MachineDomTreeNode * getRootNode() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const MDNode *TBAAInfo=0, const MDNode *Ranges=0)
const MCInstrDesc & getDesc() const
const char * getSymbolName() const
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
AnalysisUsage & addRequired()
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const
const HexagonInstrInfo * TII
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
const MCAsmInfo * getMCAsmInfo() const
#define llvm_unreachable(msg)
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
unsigned estimateRSStackLimit(MachineFunction &MF) const
const MachineInstrBuilder & addImm(int64_t Val) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const AArch64InstrInfo &TII)
unsigned getKillRegState(bool B)
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
const MachineOperand & getOperand(unsigned i) const
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getInstSizeInBytes(const MachineInstr &MI) const
const MCInstrDesc & get(unsigned Opcode) const
int64_t getObjectOffset(int ObjectIdx) const
DebugLoc findDebugLoc(instr_iterator MBBI)
unsigned RemoveBranch(MachineBasicBlock &MBB) const
void setDesc(const MCInstrDesc &tid)
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
const MachineInstrBuilder & addFrameIndex(int Idx) const
AArch64InstrInfo(const AArch64Subtarget &TM)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const
const AArch64Subtarget & getSubTarget() const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
static MachineOperand CreateImm(int64_t Val)
static A64CC::CondCodes A64InvertCondCode(A64CC::CondCodes CC)
void getAddressConstraints(const MachineInstr &MI, int &AccessScale, int &MinOffset, int &MaxOffset) const
const TargetMachine & getTarget() const
bool hasType(EVT vt) const
static void classifyCondBranch(MachineInstr *I, MachineBasicBlock *&TBB, SmallVectorImpl< MachineOperand > &Cond)
void emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc dl, const TargetInstrInfo &TII, unsigned DstReg, unsigned SrcReg, unsigned ScratchReg, int64_t NumBytes, MachineInstr::MIFlag MIFlags=MachineInstr::NoFlags)
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
static bool isCondBranch(unsigned Opc)
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
int64_t getObjectSize(int ObjectIdx) const
unsigned getInstBundleLength(const MachineInstr &MI) const
FunctionPass * createAArch64CleanupLocalDynamicTLSPass()
DebugLoc getDebugLoc() const