160#define DEBUG_TYPE "arm-frame-lowering" 
  166                     cl::desc(
"Align ARM NEON spills in prolog and epilog"));
 
  170                        unsigned NumAlignedDPRCS2Regs);
 
  185                       unsigned NumAlignedDPRCS2Regs,
 
  284    if (
Reg >= ARM::D8 && 
Reg < ARM::D8 + NumAlignedDPRCS2Regs)
 
 
  370  if (CFSize >= ((1 << 12) - 1) / 2)  
 
 
  393  bool IsTailCallReturn = 
false;
 
  395    unsigned RetOpcode = 
MBBI->getOpcode();
 
  396    IsTailCallReturn = RetOpcode == ARM::TCRETURNdi ||
 
  397                       RetOpcode == ARM::TCRETURNri ||
 
  398                       RetOpcode == ARM::TCRETURNrinotr12;
 
  402  int ArgumentPopSize = 0;
 
  403  if (IsTailCallReturn) {
 
  409    ArgumentPopSize = StackAdjust.
getImm();
 
  418  return ArgumentPopSize;
 
 
  424         F.needsUnwindTableEntry();
 
 
  432  unsigned Opc = 
MBBI->getOpcode();
 
  458  case ARM::t2MOVi16: { 
 
  459    bool Wide = 
MBBI->getOperand(1).getImm() >= 256;
 
  463      NewInstr.
add(
MBBI->getOperand(0));
 
  481  case ARM::t2MOVi32imm: 
 
  499    if (
MBBI->getOperand(0).getReg() == ARM::SP &&
 
  500        MBBI->getOperand(2).getReg() == ARM::SP &&
 
  501        MBBI->getOperand(3).getImm() == -4) {
 
  502      unsigned Reg = 
RegInfo->getSEHRegNum(
MBBI->getOperand(1).getReg());
 
  512  case ARM::t2LDR_POST:
 
  513    if (
MBBI->getOperand(1).getReg() == ARM::SP &&
 
  514        MBBI->getOperand(2).getReg() == ARM::SP &&
 
  515        MBBI->getOperand(3).getImm() == 4) {
 
  516      unsigned Reg = 
RegInfo->getSEHRegNum(
MBBI->getOperand(0).getReg());
 
  526  case ARM::t2LDMIA_RET:
 
  527  case ARM::t2LDMIA_UPD:
 
  528  case ARM::t2STMDB_UPD: {
 
  538      if (
Reg >= 8 && 
Reg <= 13)
 
  540      else if (
Opc == ARM::t2LDMIA_UPD && 
Reg == 14)
 
  547      case ARM::t2LDMIA_RET:
 
  548        NewOpc = ARM::tPOP_RET;
 
  550      case ARM::t2LDMIA_UPD:
 
  553      case ARM::t2STMDB_UPD:
 
  562        NewInstr.
add(
MBBI->getOperand(i));
 
  568        (
Opc == ARM::t2LDMIA_RET) ? ARM::SEH_SaveRegs_Ret : ARM::SEH_SaveRegs;
 
  575  case ARM::VSTMDDB_UPD:
 
  576  case ARM::VLDMDIA_UPD: {
 
  579      unsigned Reg = 
RegInfo->getSEHRegNum(MO.getReg());
 
  597  case ARM::t2SUBspImm:
 
  598  case ARM::t2SUBspImm12:
 
  599  case ARM::t2ADDspImm:
 
  600  case ARM::t2ADDspImm12:
 
  608    if (
MBBI->getOperand(1).getReg() == ARM::SP &&
 
  610      unsigned Reg = 
RegInfo->getSEHRegNum(
MBBI->getOperand(0).getReg());
 
  614    } 
else if (
MBBI->getOperand(0).getReg() == ARM::SP &&
 
  616      unsigned Reg = 
RegInfo->getSEHRegNum(
MBBI->getOperand(1).getReg());
 
  626  case ARM::TCRETURNri:
 
  627  case ARM::TCRETURNrinotr12:
 
  633  case ARM::TCRETURNdi:
 
  639  return MBB->insertAfter(
MBBI, MIB);
 
 
  646  return std::prev(
MBBI);
 
 
  654    Start = std::next(Start);
 
  658  for (
auto MI = Start; 
MI != End;) {
 
  659    auto Next = std::next(
MI);
 
 
  680                            Pred, PredReg, 
TII, MIFlags);
 
  683                           Pred, PredReg, 
TII, MIFlags);
 
 
  691                         unsigned PredReg = 0) {
 
  693                       MIFlags, Pred, PredReg);
 
 
  698  switch (
MI.getOpcode()) {
 
  699  case ARM::VSTMDDB_UPD:
 
  703  case ARM::t2STMDB_UPD:
 
  707  case ARM::STR_PRE_IMM:
 
  716  for (
int i = 
MI.getNumOperands() - 1; i >= 4; --i)
 
 
  722                                      size_t StackSizeInBytes) {
 
  728      F.getFnAttributeAsParsedInteger(
"stack-probe-size", StackProbeSize);
 
  729  return (StackSizeInBytes >= StackProbeSize) &&
 
  730         !
F.hasFnAttribute(
"no-stack-arg-probe");
 
 
  735struct StackAdjustingInsts {
 
  741#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
  743      dbgs() << 
"  " << (BeforeFPSet ? 
"before-fp " : 
"          ")
 
  744             << 
"sp-adjust=" << SPAdjust;
 
  753               bool BeforeFPSet = 
false) {
 
  754    InstInfo 
Info = {
I, SPAdjust, BeforeFPSet};
 
  761    assert(
Info != Insts.
end() && 
"invalid sp adjusting instruction");
 
  762    Info->SPAdjust += ExtraBytes;
 
  765  void emitDefCFAOffsets(MachineBasicBlock &
MBB, 
bool HasFP) {
 
  767    unsigned CFAOffset = 0;
 
  768    for (
auto &
Info : Insts) {
 
  769      if (HasFP && !
Info.BeforeFPSet)
 
  772      CFAOffset += 
Info.SPAdjust;
 
  773      CFIBuilder.setInsertPoint(std::next(
Info.I));
 
  774      CFIBuilder.buildDefCFAOffset(CFAOffset);
 
  778#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
  780    dbgs() << 
"StackAdjustingInsts:\n";
 
  781    for (
auto &
Info : Insts)
 
  801                                     const Align Alignment,
 
  802                                     const bool MustBeSingleInstruction) {
 
  804  const bool CanUseBFC = AST.hasV6T2Ops() || AST.hasV7Ops();
 
  805  const unsigned AlignMask = Alignment.
value() - 1U;
 
  806  const unsigned NrBitsToZero = 
Log2(Alignment);
 
  823    } 
else if (AlignMask <= 255) {
 
  830      assert(!MustBeSingleInstruction &&
 
  831             "Shouldn't call emitAligningInstructions demanding a single " 
  832             "instruction to be emitted for large stack alignment for a target " 
 
  872  int MaxRegBytes = 8 * 4;
 
  875    MaxRegBytes = 11 * 4;
 
  878    MaxRegBytes = 11 * 4 + 8 * 8;
 
 
  894         "This emitPrologue does not support Thumb1!");
 
  896  Align Alignment = 
STI.getFrameLowering()->getStackAlign();
 
  900  int FPCXTSaveSize = 0;
 
  903      STI.getPushPopSplitVariation(MF);
 
  915  unsigned GPRCS1Size = 0, GPRCS2Size = 0, FPStatusSize = 0,
 
  916           DPRCS1Size = 0, GPRCS3Size = 0, DPRCS2Size = 0;
 
  917  int FramePtrSpillFI = 0;
 
  925  StackAdjustingInsts DefCFAOffsetCandidates;
 
  926  bool HasFP = 
hasFP(MF);
 
  933      DefCFAOffsetCandidates.addInst(std::prev(
MBBI), NumBytes, 
true);
 
  936      DefCFAOffsetCandidates.emitDefCFAOffsets(
MBB, HasFP);
 
  937    if (NeedsWinCFI && 
MBBI != 
MBB.begin()) {
 
  948  bool BeforeFPPush = 
true;
 
  951    int FI = 
I.getFrameIdx();
 
  957      FramePtrSpillFI = FI;
 
  958      FramePtrSpillArea = Area;
 
  989                              DPRCS1Push, GPRCS3Push;
 
  996  if (FPCXTSaveSize > 0) {
 
  998    DefCFAOffsetCandidates.addInst(LastPush, FPCXTSaveSize, BeforeFPPush);
 
 1002  if (ArgRegsSaveSize) {
 
 1005    LastPush = std::prev(
MBBI);
 
 1006    DefCFAOffsetCandidates.addInst(LastPush, ArgRegsSaveSize, BeforeFPPush);
 
 1010  if (GPRCS1Size > 0) {
 
 1011    GPRCS1Push = LastPush = 
MBBI++;
 
 1012    DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size, BeforeFPPush);
 
 1014      BeforeFPPush = 
false;
 
 1021  unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
 
 1022  unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
 
 1023  unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
 
 1024  unsigned FPStatusOffset = GPRCS2Offset - FPStatusSize;
 
 1026  Align DPRAlign = DPRCS1Size ? std::min(
Align(8), Alignment) : 
Align(4);
 
 1027  unsigned DPRGapSize = (ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
 
 1028                         GPRCS2Size + FPStatusSize) %
 
 1031  unsigned DPRCS1Offset = FPStatusOffset - DPRGapSize - DPRCS1Size;
 
 1037                      << 
", FPOffset: " << FPOffset << 
"\n");
 
 1039           "Max FP estimation is wrong");
 
 1048  if (GPRCS2Size > 0) {
 
 1050    GPRCS2Push = LastPush = 
MBBI++;
 
 1051    DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size, BeforeFPPush);
 
 1053      BeforeFPPush = 
false;
 
 1057  if (FPStatusSize > 0) {
 
 1059      unsigned Opc = 
MBBI->getOpcode();
 
 1060      if (
Opc == ARM::VMRS || 
Opc == ARM::VMRS_FPEXC)
 
 1066    DefCFAOffsetCandidates.addInst(LastPush, FPStatusSize);
 
 1072    assert(DPRGapSize == 4 && 
"unexpected alignment requirements for DPRs");
 
 1073    if (LastPush != 
MBB.end() &&
 
 1075      DefCFAOffsetCandidates.addExtraBytes(LastPush, DPRGapSize);
 
 1079      DefCFAOffsetCandidates.addInst(std::prev(
MBBI), DPRGapSize, BeforeFPPush);
 
 1084  if (DPRCS1Size > 0) {
 
 1087    while (
MBBI != 
MBB.end() && 
MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
 
 1090      DPRCS1Push = LastPush = 
MBBI++;
 
 1095  if (DPRCS2Size > 0) {
 
 1103    NumBytes = DPRCS1Offset;
 
 1106  if (GPRCS3Size > 0) {
 
 1108    GPRCS3Push = LastPush = 
MBBI++;
 
 1109    DefCFAOffsetCandidates.addInst(LastPush, GPRCS3Size, BeforeFPPush);
 
 1111      BeforeFPPush = 
false;
 
 1114  bool NeedsWinCFIStackAlloc = NeedsWinCFI;
 
 1116    NeedsWinCFIStackAlloc = 
false;
 
 1121    if (NumWords < 65536) {
 
 1131          .
addImm(NumWords & 0xffff)
 
 1141    switch (TM.getCodeModel()) {
 
 1173    if (NeedsWinCFIStackAlloc) {
 
 1174      SEH = 
BuildMI(MF, dl, 
TII.get(ARM::SEH_StackAlloc))
 
 1178      MBB.insertAfter(Instr, SEH);
 
 1187      DefCFAOffsetCandidates.addExtraBytes(LastPush, NumBytes);
 
 1191      DefCFAOffsetCandidates.addInst(std::prev(
MBBI), NumBytes);
 
 1217    int64_t FPOffsetAfterPush;
 
 1218    switch (FramePtrSpillArea) {
 
 1220      FPPushInst = GPRCS1Push;
 
 1222                          ArgRegsSaveSize + FPCXTSaveSize +
 
 1225                        << FPOffsetAfterPush << 
"  after that push\n");
 
 1228      FPPushInst = GPRCS2Push;
 
 1230                          ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
 
 1233                        << FPOffsetAfterPush << 
"  after that push\n");
 
 1236      FPPushInst = GPRCS3Push;
 
 1238                          ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
 
 1239                          FPStatusSize + GPRCS2Size + DPRCS1Size + DPRGapSize +
 
 1242                        << FPOffsetAfterPush << 
"  after that push\n");
 
 1248    AfterPush = std::next(FPPushInst);
 
 1250      assert(FPOffsetAfterPush == 0);
 
 1254                         FramePtr, ARM::SP, FPOffsetAfterPush,
 
 1261      if (FPOffsetAfterPush != 0)
 
 1270  if (NeedsWinCFI && 
MBBI != 
MBB.begin()) {
 
 1284    for (
const auto &Entry : 
reverse(CSI)) {
 
 1286      int FI = Entry.getFrameIdx();
 
 1291        CFIPos = std::next(GPRCS1Push);
 
 1294        CFIPos = std::next(GPRCS2Push);
 
 1297        CFIPos = std::next(DPRCS1Push);
 
 1300        CFIPos = std::next(GPRCS3Push);
 
 1311            .
buildOffset(Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg,
 
 1323    DefCFAOffsetCandidates.emitDefCFAOffsets(
MBB, HasFP);
 
 1326  if (
STI.isTargetELF() && 
hasFP(MF))
 
 1374  if (RegInfo->hasBasePointer(MF)) {
 
 
 1401         "This emitEpilogue does not support Thumb1!");
 
 1404      STI.getPushPopSplitVariation(MF);
 
 1435    if (NumBytes + IncomingArgStackToRestore != 0)
 
 1437                   NumBytes + IncomingArgStackToRestore,
 
 1444      } 
while (
MBBI != 
MBB.begin() &&
 
 1481                 "No scratch register to restore SP from FP!");
 
 1503    } 
else if (NumBytes &&
 
 1519      while (
MBBI != 
MBB.end() && 
MBBI->getOpcode() == ARM::VLDMDIA_UPD)
 
 1524             "unexpected DPR alignment gap");
 
 1536    if (ReservedArgStack || IncomingArgStackToRestore) {
 
 1537      assert((
int)ReservedArgStack + IncomingArgStackToRestore >= 0 &&
 
 1538             "attempting to restore negative stack amount");
 
 1540                   ReservedArgStack + IncomingArgStackToRestore,
 
 
 1589  if (RegInfo->hasStackRealignment(MF)) {
 
 1590    assert(
hasFP(MF) && 
"dynamic stack realignment without a FP!");
 
 1592      FrameReg = RegInfo->getFrameRegister(MF);
 
 1594    } 
else if (hasMovingSP) {
 
 1595      assert(RegInfo->hasBasePointer(MF) &&
 
 1596             "VLAs and dynamic stack alignment, but missing base pointer!");
 
 1597      FrameReg = RegInfo->getBaseRegister();
 
 1607    if (isFixed || (hasMovingSP && !RegInfo->hasBasePointer(MF))) {
 
 1608      FrameReg = RegInfo->getFrameRegister(MF);
 
 1610    } 
else if (hasMovingSP) {
 
 1611      assert(RegInfo->hasBasePointer(MF) && 
"missing base pointer!");
 
 1616        if (FPOffset >= -255 && FPOffset < 0) {
 
 1617          FrameReg = RegInfo->getFrameRegister(MF);
 
 1632        FrameReg = RegInfo->getFrameRegister(MF);
 
 1635    } 
else if (
Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) {
 
 1637      FrameReg = RegInfo->getFrameRegister(MF);
 
 1644  if (RegInfo->hasBasePointer(MF)) {
 
 1645    FrameReg = RegInfo->getBaseRegister();
 
 
 1654                                    unsigned StmOpc, 
unsigned StrOpc,
 
 1663  using RegAndKill = std::pair<unsigned, bool>;
 
 1666  unsigned i = CSI.
size();
 
 1668    unsigned LastReg = 0;
 
 1669    for (; i != 0; --i) {
 
 1675      bool isLiveIn = 
MRI.isLiveIn(Reg);
 
 1676      if (!isLiveIn && !
MRI.isReserved(Reg))
 
 1681      if (NoGap && LastReg && LastReg != Reg-1)
 
 1689      Regs.
push_back(std::make_pair(Reg, !isLiveIn));
 
 1696      return TRI.getEncodingValue(
LHS.first) < 
TRI.getEncodingValue(
RHS.first);
 
 1699    if (Regs.
size() > 1 || StrOpc== 0) {
 
 1704      for (
const auto &[
Reg, Kill] : Regs)
 
 1706    } 
else if (Regs.size() == 1) {
 
 1727                                   unsigned LdmOpc, 
unsigned LdrOpc,
 
 1728                                   bool isVarArg, 
bool NoGap,
 
 1732  const TargetRegisterInfo &
TRI = *
STI.getRegisterInfo();
 
 1733  ARMFunctionInfo *AFI = MF.
getInfo<ARMFunctionInfo>();
 
 1736  bool isTailCall = 
false;
 
 1737  bool isInterrupt = 
false;
 
 1738  bool isTrap = 
false;
 
 1739  bool isCmseEntry = 
false;
 
 1741      STI.getPushPopSplitVariation(MF);
 
 1743    DL = 
MI->getDebugLoc();
 
 1744    unsigned RetOpcode = 
MI->getOpcode();
 
 1746        (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNri ||
 
 1747         RetOpcode == ARM::TCRETURNrinotr12);
 
 1749        RetOpcode == ARM::SUBS_PC_LR || RetOpcode == ARM::t2SUBS_PC_LR;
 
 1750    isTrap = RetOpcode == ARM::TRAP || RetOpcode == ARM::tTRAP;
 
 1751    isCmseEntry = (RetOpcode == ARM::tBXNS || RetOpcode == ARM::tBXNS_RET);
 
 1754  SmallVector<unsigned, 4> Regs;
 
 1755  unsigned i = CSI.
size();
 
 1757    unsigned LastReg = 0;
 
 1758    bool DeleteRet = 
false;
 
 1759    for (; i != 0; --i) {
 
 1760      CalleeSavedInfo &
Info = CSI[i-1];
 
 1761      MCRegister 
Reg = 
Info.getReg();
 
 1765      if (
Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
 
 1779      if (NoGap && LastReg && LastReg != 
Reg-1)
 
 1790      return TRI.getEncodingValue(
LHS) < 
TRI.getEncodingValue(
RHS);
 
 1793    if (Regs.
size() > 1 || LdrOpc == 0) {
 
 1798      for (
unsigned Reg : Regs)
 
 1803          MI->eraseFromParent();
 
 1807    } 
else if (Regs.size() == 1) {
 
 1810      if (Regs[0] == ARM::PC)
 
 1812      MachineInstrBuilder MIB =
 
 1819      if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) {
 
 1838                                         unsigned PushOpc)
 const {
 
 1843  auto RegPresent = [&CSI](MCRegister 
Reg) {
 
 1845      return C.getReg() == 
Reg;
 
 1851  if (RegPresent(ARM::FPSCR)) {
 
 1861  if (RegPresent(ARM::FPEXC)) {
 
 1870  if (Regs.
size() == 0)
 
 1874  MachineInstrBuilder MIB =
 
 1885void ARMFrameLowering::emitFPStatusRestores(
 
 1891  auto RegPresent = [&CSI](MCRegister 
Reg) {
 
 1893      return C.getReg() == 
Reg;
 
 1898  if (!RegPresent(ARM::FPSCR) && !RegPresent(ARM::FPEXC))
 
 1902  MachineInstrBuilder MIB =
 
 1909  if (RegPresent(ARM::FPSCR)) {
 
 1914  if (RegPresent(ARM::FPEXC)) {
 
 1919  if (RegPresent(ARM::FPSCR)) {
 
 1928  if (RegPresent(ARM::FPEXC)) {
 
 1941                                    unsigned NumAlignedDPRCS2Regs,
 
 1954    unsigned DNum = 
I.getReg() - ARM::D8;
 
 1955    if (DNum > NumAlignedDPRCS2Regs - 1)
 
 1957    int FI = 
I.getFrameIdx();
 
 1985  unsigned Opc = 
isThumb ? ARM::t2SUBri : ARM::SUBri;
 
 1988      .
addImm(8 * NumAlignedDPRCS2Regs)
 
 2013  unsigned NextReg = ARM::D8;
 
 2017  if (NumAlignedDPRCS2Regs >= 6) {
 
 2019        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QQPRRegClass);
 
 2020    MBB.addLiveIn(SupReg);
 
 2028    NumAlignedDPRCS2Regs -= 4;
 
 2033  unsigned R4BaseReg = NextReg;
 
 2036  if (NumAlignedDPRCS2Regs >= 4) {
 
 2038        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QQPRRegClass);
 
 2039    MBB.addLiveIn(SupReg);
 
 2047    NumAlignedDPRCS2Regs -= 4;
 
 2051  if (NumAlignedDPRCS2Regs >= 2) {
 
 2053        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QPRRegClass);
 
 2054    MBB.addLiveIn(SupReg);
 
 2061    NumAlignedDPRCS2Regs -= 2;
 
 2065  if (NumAlignedDPRCS2Regs) {
 
 2066    MBB.addLiveIn(NextReg);
 
 2071        .
addImm((NextReg - R4BaseReg) * 2)
 
 2076  std::prev(
MI)->addRegisterKilled(ARM::R4, 
TRI);
 
 
 2083                        unsigned NumAlignedDPRCS2Regs) {
 
 2088  assert(
MI->mayStore() && 
"Expecting spill instruction");
 
 2091  switch(NumAlignedDPRCS2Regs) {
 
 2094    assert(
MI->mayStore() && 
"Expecting spill instruction");
 
 2098    assert(
MI->mayStore() && 
"Expecting spill instruction");
 
 2103    assert(
MI->killsRegister(ARM::R4, 
nullptr) && 
"Missed kill flag");
 
 
 2114                                      unsigned NumAlignedDPRCS2Regs,
 
 2125    if (
I.getReg() == ARM::D8) {
 
 2126      D8SpillFI = 
I.getFrameIdx();
 
 2138  unsigned Opc = 
isThumb ? ARM::t2ADDri : ARM::ADDri;
 
 2146  unsigned NextReg = ARM::D8;
 
 2149  if (NumAlignedDPRCS2Regs >= 6) {
 
 2151        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QQPRRegClass);
 
 2159    NumAlignedDPRCS2Regs -= 4;
 
 2164  unsigned R4BaseReg = NextReg;
 
 2167  if (NumAlignedDPRCS2Regs >= 4) {
 
 2169        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QQPRRegClass);
 
 2176    NumAlignedDPRCS2Regs -= 4;
 
 2180  if (NumAlignedDPRCS2Regs >= 2) {
 
 2182        TRI->getMatchingSuperReg(NextReg, ARM::dsub_0, &ARM::QPRRegClass);
 
 2188    NumAlignedDPRCS2Regs -= 2;
 
 2192  if (NumAlignedDPRCS2Regs)
 
 2195        .
addImm(2 * (NextReg - R4BaseReg))
 
 
 2211      STI.getPushPopSplitVariation(MF);
 
 2214  unsigned PushOpc = AFI->
isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
 
 2216    ARM::t2STR_PRE : ARM::STR_PRE_IMM;
 
 2217  unsigned FltOpc = ARM::VSTMDDB_UPD;
 
 2226        return C.getReg() == ARM::FPCXTNS;
 
 2235  auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
 
 2236                       RegInfo](
unsigned Reg, 
SpillArea TestArea) {
 
 2237    return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
 
 2240  auto IsGPRCS1 = [&CheckRegArea](
unsigned Reg) {
 
 2243  auto IsGPRCS2 = [&CheckRegArea](
unsigned Reg) {
 
 2246  auto IsDPRCS1 = [&CheckRegArea](
unsigned Reg) {
 
 2249  auto IsGPRCS3 = [&CheckRegArea](
unsigned Reg) {
 
 2253  emitPushInst(
MBB, 
MI, CSI, PushOpc, PushOneOpc, 
false, IsGPRCS1);
 
 2254  emitPushInst(
MBB, 
MI, CSI, PushOpc, PushOneOpc, 
false, IsGPRCS2);
 
 2255  emitFPStatusSaves(
MBB, 
MI, CSI, PushOpc);
 
 2256  emitPushInst(
MBB, 
MI, CSI, FltOpc, 0, 
true, IsDPRCS1);
 
 2257  emitPushInst(
MBB, 
MI, CSI, PushOpc, PushOneOpc, 
false, IsGPRCS3);
 
 2262  if (NumAlignedDPRCS2Regs)
 
 
 2281      STI.getPushPopSplitVariation(MF);
 
 2285  if (NumAlignedDPRCS2Regs)
 
 2288  unsigned PopOpc = AFI->
isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
 
 2291  unsigned FltOpc = ARM::VLDMDIA_UPD;
 
 2293  auto CheckRegArea = [PushPopSplit, NumAlignedDPRCS2Regs,
 
 2294                       RegInfo](
unsigned Reg, 
SpillArea TestArea) {
 
 2295    return getSpillArea(Reg, PushPopSplit, NumAlignedDPRCS2Regs, RegInfo) ==
 
 2298  auto IsGPRCS1 = [&CheckRegArea](
unsigned Reg) {
 
 2301  auto IsGPRCS2 = [&CheckRegArea](
unsigned Reg) {
 
 2304  auto IsDPRCS1 = [&CheckRegArea](
unsigned Reg) {
 
 2307  auto IsGPRCS3 = [&CheckRegArea](
unsigned Reg) {
 
 2311  emitPopInst(
MBB, 
MI, CSI, PopOpc, LdrOpc, isVarArg, 
false, IsGPRCS3);
 
 2312  emitPopInst(
MBB, 
MI, CSI, FltOpc, 0, isVarArg, 
true, IsDPRCS1);
 
 2313  emitFPStatusRestores(
MBB, 
MI, CSI, PopOpc);
 
 2314  emitPopInst(
MBB, 
MI, CSI, PopOpc, LdrOpc, isVarArg, 
false, IsGPRCS2);
 
 2315  emitPopInst(
MBB, 
MI, CSI, PopOpc, LdrOpc, isVarArg, 
false, IsGPRCS1);
 
 
 2323  unsigned FnSize = 0;
 
 2324  for (
auto &
MBB : MF) {
 
 2325    for (
auto &
MI : 
MBB)
 
 2326      FnSize += 
TII.getInstSizeInBytes(
MI);
 
 2330      FnSize += Table.MBBs.size() * 4;
 
 
 2341                                         bool &HasNonSPFrameIndex) {
 
 2346  unsigned Limit = (1 << 12) - 1;
 
 2347  for (
auto &
MBB : MF) {
 
 2348    for (
auto &
MI : 
MBB) {
 
 2349      if (
MI.isDebugInstr())
 
 2351      for (
unsigned i = 0, e = 
MI.getNumOperands(); i != e; ++i) {
 
 2352        if (!
MI.getOperand(i).isFI())
 
 2357        if (
MI.getOpcode() == ARM::ADDri) {
 
 2358          Limit = std::min(Limit, (1U << 8) - 1);
 
 2363        if (
MI.getOpcode() == ARM::t2ADDri || 
MI.getOpcode() == ARM::t2ADDri12)
 
 2368        if (RegClass && !RegClass->
contains(ARM::SP))
 
 2369          HasNonSPFrameIndex = 
true;
 
 2379          Limit = std::min(Limit, (1U << 8) - 1);
 
 2382          Limit = std::min(Limit, ((1U << 8) - 1) * 2);
 
 2387          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
 
 2393            Limit = std::min(Limit, (1U << 8) - 1);
 
 2401          Limit = std::min(Limit, ((1U << 7) - 1) * 1);
 
 2404          Limit = std::min(Limit, ((1U << 7) - 1) * 2);
 
 2407          Limit = std::min(Limit, ((1U << 7) - 1) * 4);
 
 2410          llvm_unreachable(
"Unhandled addressing mode in stack size limit calculation");
 
 
 2451  unsigned NumSpills = 0;
 
 2452  for (; NumSpills < 8; ++NumSpills)
 
 2453    if (!SavedRegs.
test(ARM::D8 + NumSpills))
 
 2464  SavedRegs.
set(ARM::R4);
 
 
 2470  if (
STI.hasV8_1MMainlineOps() &&
 
 
 2487  return Subtarget.createAAPCSFrameChain() && 
hasFP(MF);
 
 
 2500  for (
const auto &
MBB : MF)
 
 2501    for (
const auto &
MI : 
MBB)
 
 2502      if (
MI.getOpcode() == ARM::tSTRspi || 
MI.getOpcode() == ARM::tSTRi ||
 
 2503          STI.genExecuteOnly())
 
 2504        for (
const auto &
Op : 
MI.operands())
 
 
 2524  bool CS1Spilled = 
false;
 
 2525  bool LRSpilled = 
false;
 
 2526  unsigned NumGPRSpills = 0;
 
 2527  unsigned NumFPRSpills = 0;
 
 2542      STI.getPushPopSplitVariation(MF);
 
 2546  if (
F.hasFnAttribute(
"interrupt") && 
F.hasFnAttribute(
"save-fp")) {
 
 2547    SavedRegs.
set(ARM::FPSCR);
 
 2548    SavedRegs.
set(ARM::R4);
 
 2551    if (
STI.isMClass()) {
 
 2552      SavedRegs.
reset(ARM::FPEXC);
 
 2554      SavedRegs.
set(ARM::FPEXC);
 
 2555      SavedRegs.
set(ARM::R5);
 
 2565      (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF)))
 
 2566    SavedRegs.
set(ARM::R4);
 
 2573  if (
STI.isTargetWindows() &&
 
 2575    SavedRegs.
set(ARM::R4);
 
 2576    SavedRegs.
set(ARM::LR);
 
 2582      SavedRegs.
set(ARM::LR);
 
 2590    if (MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(MF) ||
 
 2591        MFI.estimateStackSize(MF) > 508)
 
 2592      SavedRegs.
set(ARM::R4);
 
 2599  if (RegInfo->hasBasePointer(MF))
 
 2600    SavedRegs.
set(RegInfo->getBaseRegister());
 
 2604    CanEliminateFrame = 
false;
 
 2608    CanEliminateFrame = 
false;
 
 2612  const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);
 
 2613  for (
unsigned i = 0; CSRegs[i]; ++i) {
 
 2614    unsigned Reg = CSRegs[i];
 
 2615    bool Spilled = 
false;
 
 2616    if (SavedRegs.
test(Reg)) {
 
 2618      CanEliminateFrame = 
false;
 
 2621    if (!ARM::GPRRegClass.
contains(Reg)) {
 
 2623        if (ARM::SPRRegClass.
contains(Reg))
 
 2625        else if (ARM::DPRRegClass.
contains(Reg))
 
 2627        else if (ARM::QPRRegClass.
contains(Reg))
 
 2648      case ARM::R0: 
case ARM::R1:
 
 2649      case ARM::R2: 
case ARM::R3:
 
 2650      case ARM::R4: 
case ARM::R5:
 
 2651      case ARM::R6: 
case ARM::R7:
 
 2664      case ARM::R0: 
case ARM::R1:
 
 2665      case ARM::R2: 
case ARM::R3:
 
 2666      case ARM::R4: 
case ARM::R5:
 
 2667      case ARM::R6: 
case ARM::R7:
 
 2678  bool ForceLRSpill = 
false;
 
 2683    if (FnSize >= (1 << 11)) {
 
 2684      CanEliminateFrame = 
false;
 
 2685      ForceLRSpill = 
true;
 
 2703  unsigned EstimatedStackSize =
 
 2704      MFI.estimateStackSize(MF) + 4 * (NumGPRSpills + NumFPRSpills);
 
 2707  int MaxFixedOffset = 0;
 
 2708  for (
int I = MFI.getObjectIndexBegin(); 
I < 0; ++
I) {
 
 2709    int MaxObjectOffset = MFI.getObjectOffset(
I) + MFI.getObjectSize(
I);
 
 2710    MaxFixedOffset = std::max(MaxFixedOffset, MaxObjectOffset);
 
 2713  bool HasFP = 
hasFP(MF);
 
 2716      EstimatedStackSize += 4;
 
 2720    EstimatedStackSize += MaxFixedOffset;
 
 2722  EstimatedStackSize += 16; 
 
 2724  unsigned EstimatedRSStackSizeLimit, EstimatedRSFixedSizeLimit;
 
 2725  bool HasNonSPFrameIndex = 
false;
 
 2745    if (RegInfo->hasBasePointer(MF))
 
 2746      EstimatedRSStackSizeLimit = (1U << 5) * 4;
 
 2748      EstimatedRSStackSizeLimit = (1U << 8) * 4;
 
 2749    EstimatedRSFixedSizeLimit = (1U << 5) * 4;
 
 2751    EstimatedRSStackSizeLimit =
 
 2753    EstimatedRSFixedSizeLimit = EstimatedRSStackSizeLimit;
 
 2757  bool HasLargeStack = EstimatedStackSize > EstimatedRSStackSizeLimit;
 
 2763  bool HasMovingSP = MFI.hasVarSizedObjects() ||
 
 2765  bool HasBPOrFixedSP = RegInfo->hasBasePointer(MF) || !HasMovingSP;
 
 2774  bool HasLargeArgumentList =
 
 2775      HasFP && (MaxFixedOffset - MaxFPOffset) > (
int)EstimatedRSFixedSizeLimit;
 
 2777  bool BigFrameOffsets = HasLargeStack || !HasBPOrFixedSP ||
 
 2778                         HasLargeArgumentList || HasNonSPFrameIndex;
 
 2779  LLVM_DEBUG(
dbgs() << 
"EstimatedLimit: " << EstimatedRSStackSizeLimit
 
 2780                    << 
"; EstimatedStack: " << EstimatedStackSize
 
 2781                    << 
"; EstimatedFPStack: " << MaxFixedOffset - MaxFPOffset
 
 2782                    << 
"; BigFrameOffsets: " << BigFrameOffsets << 
"\n");
 
 2783  if (BigFrameOffsets ||
 
 2784      !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
 
 2794        SavedRegs.
set(ARM::LR);
 
 2797        auto LRPos = 
llvm::find(UnspilledCS1GPRs, ARM::LR);
 
 2798        if (LRPos != UnspilledCS1GPRs.
end())
 
 2799          UnspilledCS1GPRs.
erase(LRPos);
 
 2802      if (FPPos != UnspilledCS1GPRs.
end())
 
 2803        UnspilledCS1GPRs.
erase(FPPos);
 
 2821    unsigned NumExtraCSSpill = 0;
 
 2838      int EntryRegDeficit = 0;
 
 2839      for (
unsigned Reg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3}) {
 
 2844                     << 
" is unused argument register, EntryRegDeficit = " 
 2845                     << EntryRegDeficit << 
"\n");
 
 2852                        << 
" return regs used, ExitRegDeficit = " 
 2853                        << ExitRegDeficit << 
"\n");
 
 2855      int RegDeficit = std::max(EntryRegDeficit, ExitRegDeficit);
 
 2860      for (
unsigned Reg : {ARM::R4, ARM::R5, ARM::R6}) {
 
 2861        if (SavedRegs.
test(Reg)) {
 
 2864                            << 
" is saved low register, RegDeficit = " 
 2865                            << RegDeficit << 
"\n");
 
 2871              << 
" is non-saved low register, adding to AvailableRegs\n");
 
 2876      if (!HasFP || 
FramePtr != ARM::R7) {
 
 2877        if (SavedRegs.
test(ARM::R7)) {
 
 2880                            << RegDeficit << 
"\n");
 
 2885              << 
"%r7 is non-saved low register, adding to AvailableRegs\n");
 
 2890      for (
unsigned Reg : {ARM::R8, ARM::R9, ARM::R10, ARM::R11}) {
 
 2891        if (SavedRegs.
test(Reg)) {
 
 2894                            << 
" is saved high register, RegDeficit = " 
 2895                            << RegDeficit << 
"\n");
 
 2902      if ((EntryRegDeficit > ExitRegDeficit) &&
 
 2905        if (SavedRegs.
test(ARM::LR)) {
 
 2908                            << RegDeficit << 
"\n");
 
 2911          LLVM_DEBUG(
dbgs() << 
"%lr is not saved, adding to AvailableRegs\n");
 
 2920      LLVM_DEBUG(
dbgs() << 
"Final RegDeficit = " << RegDeficit << 
"\n");
 
 2921      for (; RegDeficit > 0 && !AvailableRegs.
empty(); --RegDeficit) {
 
 2924                          << 
" to make up reg deficit\n");
 
 2928        assert(!
MRI.isReserved(Reg) && 
"Should not be reserved");
 
 2929        if (Reg != ARM::LR && !
MRI.isPhysRegUsed(Reg))
 
 2935      LLVM_DEBUG(
dbgs() << 
"After adding spills, RegDeficit = " << RegDeficit
 
 2945    if (!LRSpilled && CS1Spilled && !ExpensiveLRRestore) {
 
 2946      SavedRegs.
set(ARM::LR);
 
 2949      LRPos = 
llvm::find(UnspilledCS1GPRs, (
unsigned)ARM::LR);
 
 2950      if (LRPos != UnspilledCS1GPRs.
end())
 
 2951        UnspilledCS1GPRs.
erase(LRPos);
 
 2953      ForceLRSpill = 
false;
 
 2954      if (!
MRI.isReserved(ARM::LR) && !
MRI.isPhysRegUsed(ARM::LR) &&
 
 2964    if (TargetAlign >= 
Align(8) && (NumGPRSpills & 1)) {
 
 2965      if (CS1Spilled && !UnspilledCS1GPRs.
empty()) {
 
 2966        for (
unsigned Reg : UnspilledCS1GPRs) {
 
 2970              (
STI.isTargetWindows() && Reg == ARM::R11) ||
 
 2972              (Reg == ARM::LR && !ExpensiveLRRestore)) {
 
 2975                              << 
" to make up alignment\n");
 
 2976            if (!
MRI.isReserved(Reg) && !
MRI.isPhysRegUsed(Reg) &&
 
 2983        unsigned Reg = UnspilledCS2GPRs.
front();
 
 2986                          << 
" to make up alignment\n");
 
 2987        if (!
MRI.isReserved(Reg) && !
MRI.isPhysRegUsed(Reg))
 
 2998    unsigned RegsNeeded = 0;
 
 3007    if (RegsNeeded > NumExtraCSSpill) {
 
 3010      unsigned NumExtras = TargetAlign.
value() / 4;
 
 3012      while (NumExtras && !UnspilledCS1GPRs.
empty()) {
 
 3014        if (!
MRI.isReserved(Reg) &&
 
 3022        while (NumExtras && !UnspilledCS2GPRs.
empty()) {
 
 3024          if (!
MRI.isReserved(Reg)) {
 
 3030      if (NumExtras == 0) {
 
 3031        for (
unsigned Reg : Extras) {
 
 3033          if (!
MRI.isPhysRegUsed(Reg))
 
 3037      while ((RegsNeeded > NumExtraCSSpill) && RS) {
 
 3041        unsigned Size = 
TRI->getSpillSize(RC);
 
 3042        Align Alignment = 
TRI->getSpillAlign(RC);
 
 3043        RS->addScavengingFrameIndex(
 
 3044            MFI.CreateSpillStackObject(
Size, Alignment));
 
 3051    SavedRegs.
set(ARM::LR);
 
 
 3064    if (Info.getReg() != ARM::LR)
 
 3068            return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
 
 3069                   Term.getOpcode() == ARM::t2LDMIA_RET ||
 
 3070                   Term.getOpcode() == ARM::tPOP_RET;
 
 3073      Info.setRestored(
false);
 
 
 3094    SavedRegs.
set(ARM::R0);
 
 
 3099    std::vector<CalleeSavedInfo> &CSI)
 const {
 
 3102  if (
STI.hasV8_1MMainlineOps() &&
 
 3104    CSI.emplace_back(ARM::FPCXTNS);
 
 3105    CSI.back().setRestored(
false);
 
 3117    switch (
STI.getPushPopSplitVariation(MF)) {
 
 3121                         [=](
const auto &CS) {
 
 3123                           return Reg == ARM::R10 || Reg == ARM::R11 ||
 
 3124                                  Reg == ARM::R8 || Reg == ARM::R9 ||
 
 3125                                  ARM::DPRRegClass.contains(Reg);
 
 3136             "ABI-required frame pointers need a CSR split when signing return " 
 3139                         [=](
const auto &CS) {
 
 3141                           return Reg != ARM::LR;
 
 
 3155  static const SpillSlot FixedSpillOffsets[] = {{ARM::FPCXTNS, -4}};
 
 3156  NumEntries = std::size(FixedSpillOffsets);
 
 3157  return FixedSpillOffsets;
 
 
 3168  unsigned Opc = 
I->getOpcode();
 
 3169  bool IsDestroy = 
Opc == 
TII.getCallFrameDestroyOpcode();
 
 3170  unsigned CalleePopAmount = IsDestroy ? 
I->getOperand(1).getImm() : 0;
 
 3173         "This eliminateCallFramePseudoInstr does not support Thumb1!");
 
 3175  int PIdx = 
I->findFirstPredOperandIdx();
 
 3179  unsigned PredReg = 
TII.getFramePred(*
I);
 
 3183    if (IsDestroy && CalleePopAmount != -1U)
 
 3184      return MBB.erase(
I);
 
 3189    unsigned Amount = 
TII.getFrameSize(*
I);
 
 3196      if (
Opc == ARM::ADJCALLSTACKDOWN || 
Opc == ARM::tADJCALLSTACKDOWN) {
 
 3200        assert(
Opc == ARM::ADJCALLSTACKUP || 
Opc == ARM::tADJCALLSTACKUP);
 
 3205  } 
else if (CalleePopAmount != -1U) {
 
 3219  unsigned Shifted = 0;
 
 3224  while (!(
Value & 0xC0000000)) {
 
 3229  bool Carry = (
Value & 0x00FFFFFF);
 
 3230  Value = ((
Value & 0xFF000000) >> 24) + Carry;
 
 3232  if (
Value & 0x0000100)
 
 
 3275  bool Thumb = ST->isThumb();
 
 3276  bool Thumb2 = ST->isThumb2();
 
 3282  if (!ST->isTargetAndroid() && !ST->isTargetLinux())
 
 3298  unsigned ScratchReg0 = ARM::R4;
 
 3299  unsigned ScratchReg1 = ARM::R5;
 
 3300  unsigned MovOp = ST->useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
 
 3317      if (BeforePrologueRegion.
insert(PredBB).second)
 
 3320  } 
while (!WalkList.
empty());
 
 3331  for (
const auto &LI : PrologueMBB.
liveins()) {
 
 3333      PredBB->addLiveIn(LI);
 
 3339    BeforePrologueRegion.
erase(
B);
 
 3345    MBB->sortUniqueLiveIns();
 
 3348    if (
MBB->isSuccessor(&PrologueMBB))
 
 3349      MBB->ReplaceUsesOfBlockWith(&PrologueMBB, AddedBlocks[0]);
 
 3394  } 
else if (CompareStackPointer) {
 
 3402  if (!CompareStackPointer && Thumb) {
 
 3403    if (AlignedStackSize < 256) {
 
 3407          .
addImm(AlignedStackSize)
 
 3410      if (Thumb2 || ST->genExecuteOnly()) {
 
 3412            .
addImm(AlignedStackSize);
 
 3415        auto RegInfo = 
STI.getRegisterInfo();
 
 3416        RegInfo->emitLoadConstPool(*McrMBB, 
MBBI, 
DL, ScratchReg0, 0,
 
 3425  } 
else if (!CompareStackPointer) {
 
 3426    if (AlignedStackSize < 256) {
 
 3429          .
addImm(AlignedStackSize)
 
 3434      auto RegInfo = 
STI.getRegisterInfo();
 
 3435      RegInfo->emitLoadConstPool(*McrMBB, 
MBBI, 
DL, ScratchReg0, 0,
 
 3445  if (Thumb && ST->isThumb1Only()) {
 
 3446    if (ST->genExecuteOnly()) {
 
 3457      BuildMI(GetMBB, 
DL, 
TII.get(ARM::tLDRpci), ScratchReg0)
 
 3470    BuildMI(McrMBB, 
DL, 
TII.get(Thumb ? ARM::t2MRC : ARM::MRC),
 
 3480    assert(ST->isTargetAndroid() || ST->isTargetLinux());
 
 3481    unsigned TlsOffset = ST->isTargetAndroid() ? 63 : 1;
 
 3485    BuildMI(GetMBB, 
DL, 
TII.get(Thumb ? ARM::t2LDRi12 : ARM::LDRi12),
 
 3494  Opcode = Thumb ? ARM::tCMPr : ARM::CMPrr;
 
 3501  Opcode = Thumb ? ARM::tBcc : ARM::Bcc;
 
 3514    if (AlignedStackSize < 256) {
 
 3515      BuildMI(AllocMBB, 
DL, 
TII.get(ARM::tMOVi8), ScratchReg0)
 
 3517          .
addImm(AlignedStackSize)
 
 3520      if (Thumb2 || ST->genExecuteOnly()) {
 
 3522            .
addImm(AlignedStackSize);
 
 3525        auto RegInfo = 
STI.getRegisterInfo();
 
 3526        RegInfo->emitLoadConstPool(*AllocMBB, 
MBBI, 
DL, ScratchReg0, 0,
 
 3531    if (AlignedStackSize < 256) {
 
 3533          .
addImm(AlignedStackSize)
 
 3538      auto RegInfo = 
STI.getRegisterInfo();
 
 3539      RegInfo->emitLoadConstPool(*AllocMBB, 
MBBI, 
DL, ScratchReg0, 0,
 
 3548      BuildMI(AllocMBB, 
DL, 
TII.get(ARM::tMOVi8), ScratchReg1)
 
 3553      if (Thumb2 || ST->genExecuteOnly()) {
 
 3558        auto RegInfo = 
STI.getRegisterInfo();
 
 3559        RegInfo->emitLoadConstPool(
 
 3560            *AllocMBB, 
MBBI, 
DL, ScratchReg1, 0,
 
 3572      auto RegInfo = 
STI.getRegisterInfo();
 
 3573      RegInfo->emitLoadConstPool(
 
 3574          *AllocMBB, 
MBBI, 
DL, ScratchReg1, 0,
 
 3612    if (ST->isThumb1Only()) {
 
 3699#ifdef EXPENSIVE_CHECKS 
 
unsigned const MachineRegisterInfo * MRI
static unsigned estimateRSStackSizeLimit(MachineFunction &MF)
Look at each instruction that references stack frames and return the stack size limit beyond which so...
static bool needsWinCFI(const MachineFunction *MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isThumb(const MCSubtargetInfo &STI)
static MachineBasicBlock::iterator skipAlignedDPRCS2Spills(MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs)
Skip past the code inserted by emitAlignedDPRCS2Spills, and return an iterator to the following instr...
static void emitAligningInstructions(MachineFunction &MF, ARMFunctionInfo *AFI, const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, const unsigned Reg, const Align Alignment, const bool MustBeSingleInstruction)
Emit an instruction sequence that will align the address in register Reg by zero-ing out the lower bi...
static uint32_t alignToARMConstant(uint32_t Value)
Get the minimum constant for ARM that is greater than or equal to the argument.
static void checkNumAlignedDPRCS2Regs(MachineFunction &MF, BitVector &SavedRegs)
static void insertSEHRange(MachineBasicBlock &MBB, MachineBasicBlock::iterator Start, const MachineBasicBlock::iterator &End, const ARMBaseInstrInfo &TII, unsigned MIFlags)
static void emitAlignedDPRCS2Restores(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
Emit aligned reload instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
static void emitAlignedDPRCS2Spills(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned NumAlignedDPRCS2Regs, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI)
Emit aligned spill instructions for NumAlignedDPRCS2Regs D-registers starting from d8.
static int getArgumentStackToRestore(MachineFunction &MF, MachineBasicBlock &MBB)
static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
static unsigned EstimateFunctionSizeInBytes(const MachineFunction &MF, const ARMBaseInstrInfo &TII)
static MachineBasicBlock::iterator insertSEH(MachineBasicBlock::iterator MBBI, const TargetInstrInfo &TII, unsigned Flags)
SpillArea getSpillArea(Register Reg, ARMSubtarget::PushPopSplitVariation Variation, unsigned NumAlignedDPRCS2Regs, const ARMBaseRegisterInfo *RegInfo)
Get the spill area that Reg should be saved into in the prologue.
static bool canSpillOnFrameIndexAccess(const MachineFunction &MF, const TargetFrameLowering &TFI)
static bool WindowsRequiresStackProbe(const MachineFunction &MF, size_t StackSizeInBytes)
static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI, const MachineFunction &MF)
We need the offset of the frame pointer relative to other MachineFrameInfo offsets which are encoded ...
static MachineBasicBlock::iterator initMBBRange(MachineBasicBlock &MBB, const MachineBasicBlock::iterator &MBBI)
static int sizeOfSPAdjustment(const MachineInstr &MI)
static const uint64_t kSplitStackAvailable
static cl::opt< bool > SpillAlignedNEONRegs("align-neon-spills", cl::Hidden, cl::init(true), cl::desc("Align ARM NEON spills in prolog and epilog"))
static void emitRegPlusImmediate(bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, const ARMBaseInstrInfo &TII, unsigned DestReg, unsigned SrcReg, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags, ARMCC::CondCodes Pred=ARMCC::AL, unsigned PredReg=0)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static const unsigned FramePtr
bool canRealignStack(const MachineFunction &MF) const override
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj)
ARMConstantPoolValue - ARM specific constantpool value.
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - Provide a base+offset reference to an FI slot for debug info.
bool keepFramePointer(const MachineFunction &MF) const
static void updateLRRestored(MachineFunction &MF)
Update the IsRestored flag on LR if it is spilled, based on the return instructions.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
ARMFrameLowering(const ARMSubtarget &sti)
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool requiresAAPCSFrameRecord(const MachineFunction &MF) const
bool isFPReserved(const MachineFunction &MF) const
isFPReserved - Return true if the frame pointer register should be considered a reserved register on ...
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - If there is a reserved call frame, the call frame pseudos can be simpli...
void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &MBB) const override
Adjust the prologue to have the function use segmented stacks.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
bool hasFPImpl(const MachineFunction &MF) const override
hasFPImpl - Return true if the specified function should have a dedicated frame pointer register.
int ResolveFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg, int SPAdj) const
void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const override
Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool hasStackFrame() const
bool isThumb2Function() const
unsigned getFPCXTSaveAreaSize() const
unsigned getGPRCalleeSavedArea1Size() const
unsigned getDPRCalleeSavedGapSize() const
unsigned getDPRCalleeSavedArea1Size() const
unsigned createPICLabelUId()
void setLRIsSpilled(bool s)
void setDPRCalleeSavedArea1Offset(unsigned o)
void setGPRCalleeSavedArea2Size(unsigned s)
bool isThumb1OnlyFunction() const
void setHasStackFrame(bool s)
bool isThumbFunction() const
void setFramePtrSpillOffset(unsigned o)
unsigned getGPRCalleeSavedArea2Size() const
unsigned getNumAlignedDPRCS2Regs() const
bool shouldSignReturnAddress() const
void setGPRCalleeSavedArea1Size(unsigned s)
unsigned getArgumentStackToRestore() const
void setFPCXTSaveAreaSize(unsigned s)
bool isCmseNSEntryFunction() const
unsigned getGPRCalleeSavedArea3Size() const
unsigned getFramePtrSpillOffset() const
bool shouldRestoreSPFromFP() const
unsigned getArgRegsSaveSize() const
void setGPRCalleeSavedArea2Offset(unsigned o)
void setGPRCalleeSavedArea1Offset(unsigned o)
void setDPRCalleeSavedArea1Size(unsigned s)
void setDPRCalleeSavedGapSize(unsigned s)
void setFPStatusSavesSize(unsigned s)
unsigned getArgumentStackSize() const
void setShouldRestoreSPFromFP(bool s)
unsigned getReturnRegsCount() const
void setGPRCalleeSavedArea3Size(unsigned s)
bool getPreservesR0() const
unsigned getFPStatusSavesSize() const
const ARMBaseRegisterInfo * getRegisterInfo() const override
enum PushPopSplitVariation getPushPopSplitVariation(const MachineFunction &MF) const
PushPopSplitVariation
How the push and pop instructions of callee saved general-purpose registers should be split.
@ SplitR11WindowsSEH
When the stack frame size is not known (because of variable-sized objects or realignment),...
@ SplitR7
R7 and LR must be adjacent, because R7 is the frame pointer, and must point to a frame record consist...
@ SplitR11AAPCSSignRA
When generating AAPCS-compilant frame chains, R11 is the frame pointer, and must be pushed adjacent t...
@ NoSplit
All GPRs can be pushed in a single instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
Helper class for creating CFI instructions and inserting them into MIR.
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label=nullptr) const
void buildDefCFARegister(MCRegister Reg) const
void buildSameValue(MCRegister Reg) const
void buildOffset(MCRegister Reg, int64_t Offset) const
void buildDefCFA(MCRegister Reg, int64_t Offset) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool usesWindowsCFI() const
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
iterator_range< livein_iterator > liveins() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool needsSplitStackProlog() const
Return true if this function requires a split stack prolog, even if it uses no stack space.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int getStackProtectorIndex() const
Return the index for the stack protector object.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
LLVM_ABI BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
void setHasWinCFI(bool v)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger 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.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) 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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
bool isValid() const
Check for null.
Representation of each machine instruction.
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool isLiveIn(Register Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
bool erase(PtrType Ptr)
Remove pointer from the set.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
iterator erase(const_iterator CI)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
virtual void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const
Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment.
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
LLVM_ABI bool FramePointerIsReserved(const MachineFunction &MF) const
FramePointerIsReserved - This returns true if the frame pointer must always either point to a new fra...
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
@ D16
Only 16 D registers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ C
The default llvm calling convention, compatible with C.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
static bool isSEHInstruction(const MachineInstr &MI)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
FunctionAddr VTableAddr Next
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
unsigned Log2(Align A)
Returns the log2 of the alignment.
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.