1235633Sdim//===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===// 2198090Srdivacky// 3198090Srdivacky// The LLVM Compiler Infrastructure 4198090Srdivacky// 5198090Srdivacky// This file is distributed under the University of Illinois Open Source 6198090Srdivacky// License. See LICENSE.TXT for details. 7198090Srdivacky// 8198090Srdivacky//===----------------------------------------------------------------------===// 9198090Srdivacky// 10198090Srdivacky// This file contains the Base ARM implementation of the TargetInstrInfo class. 11198090Srdivacky// 12198090Srdivacky//===----------------------------------------------------------------------===// 13198090Srdivacky 14198090Srdivacky#ifndef ARMBASEINSTRUCTIONINFO_H 15198090Srdivacky#define ARMBASEINSTRUCTIONINFO_H 16198090Srdivacky 17198090Srdivacky#include "ARM.h" 18252723Sdim#include "llvm/ADT/DenseMap.h" 19252723Sdim#include "llvm/ADT/SmallSet.h" 20198090Srdivacky#include "llvm/CodeGen/MachineInstrBuilder.h" 21198090Srdivacky#include "llvm/Target/TargetInstrInfo.h" 22198090Srdivacky 23224145Sdim#define GET_INSTRINFO_HEADER 24224145Sdim#include "ARMGenInstrInfo.inc" 25224145Sdim 26198090Srdivackynamespace llvm { 27212904Sdim class ARMSubtarget; 28212904Sdim class ARMBaseRegisterInfo; 29198090Srdivacky 30224145Sdimclass ARMBaseInstrInfo : public ARMGenInstrInfo { 31212904Sdim const ARMSubtarget &Subtarget; 32218893Sdim 33198090Srdivackyprotected: 34198090Srdivacky // Can be only subclassed. 35198892Srdivacky explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 36218893Sdim 37198090Srdivackypublic: 38235633Sdim // Return whether the target has an explicit NOP encoding. 39235633Sdim bool hasNOP() const; 40235633Sdim 41198090Srdivacky // Return the non-pre/post incrementing version of 'Opc'. Return 0 42198090Srdivacky // if there is not such an opcode. 43198090Srdivacky virtual unsigned getUnindexedOpcode(unsigned Opc) const =0; 44198090Srdivacky 45198090Srdivacky virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 46198090Srdivacky MachineBasicBlock::iterator &MBBI, 47198090Srdivacky LiveVariables *LV) const; 48198090Srdivacky 49263509Sdim virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0; 50198892Srdivacky const ARMSubtarget &getSubtarget() const { return Subtarget; } 51198090Srdivacky 52218893Sdim ScheduleHazardRecognizer * 53218893Sdim CreateTargetHazardRecognizer(const TargetMachine *TM, 54218893Sdim const ScheduleDAG *DAG) const; 55208599Srdivacky 56218893Sdim ScheduleHazardRecognizer * 57218893Sdim CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 58218893Sdim const ScheduleDAG *DAG) const; 59218893Sdim 60198090Srdivacky // Branch analysis. 61198090Srdivacky virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 62198090Srdivacky MachineBasicBlock *&FBB, 63198090Srdivacky SmallVectorImpl<MachineOperand> &Cond, 64212904Sdim bool AllowModify = false) const; 65198090Srdivacky virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; 66198090Srdivacky virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 67198090Srdivacky MachineBasicBlock *FBB, 68210299Sed const SmallVectorImpl<MachineOperand> &Cond, 69210299Sed DebugLoc DL) const; 70198090Srdivacky 71198090Srdivacky virtual 72198090Srdivacky bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; 73198090Srdivacky 74198090Srdivacky // Predication support. 75235633Sdim bool isPredicated(const MachineInstr *MI) const; 76198090Srdivacky 77198090Srdivacky ARMCC::CondCodes getPredicate(const MachineInstr *MI) const { 78198090Srdivacky int PIdx = MI->findFirstPredOperandIdx(); 79198090Srdivacky return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm() 80198090Srdivacky : ARMCC::AL; 81198090Srdivacky } 82198090Srdivacky 83198090Srdivacky virtual 84198090Srdivacky bool PredicateInstruction(MachineInstr *MI, 85198090Srdivacky const SmallVectorImpl<MachineOperand> &Pred) const; 86198090Srdivacky 87198090Srdivacky virtual 88198090Srdivacky bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 89198090Srdivacky const SmallVectorImpl<MachineOperand> &Pred2) const; 90198090Srdivacky 91198090Srdivacky virtual bool DefinesPredicate(MachineInstr *MI, 92198090Srdivacky std::vector<MachineOperand> &Pred) const; 93198090Srdivacky 94199989Srdivacky virtual bool isPredicable(MachineInstr *MI) const; 95199989Srdivacky 96198090Srdivacky /// GetInstSize - Returns the size of the specified MachineInstr. 97198090Srdivacky /// 98198090Srdivacky virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; 99198090Srdivacky 100198090Srdivacky virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, 101198090Srdivacky int &FrameIndex) const; 102198090Srdivacky virtual unsigned isStoreToStackSlot(const MachineInstr *MI, 103198090Srdivacky int &FrameIndex) const; 104226890Sdim virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, 105226890Sdim int &FrameIndex) const; 106226890Sdim virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, 107226890Sdim int &FrameIndex) const; 108198090Srdivacky 109210299Sed virtual void copyPhysReg(MachineBasicBlock &MBB, 110210299Sed MachineBasicBlock::iterator I, DebugLoc DL, 111210299Sed unsigned DestReg, unsigned SrcReg, 112210299Sed bool KillSrc) const; 113198090Srdivacky 114198090Srdivacky virtual void storeRegToStackSlot(MachineBasicBlock &MBB, 115198090Srdivacky MachineBasicBlock::iterator MBBI, 116198090Srdivacky unsigned SrcReg, bool isKill, int FrameIndex, 117208599Srdivacky const TargetRegisterClass *RC, 118208599Srdivacky const TargetRegisterInfo *TRI) const; 119198090Srdivacky 120198090Srdivacky virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, 121198090Srdivacky MachineBasicBlock::iterator MBBI, 122198090Srdivacky unsigned DestReg, int FrameIndex, 123208599Srdivacky const TargetRegisterClass *RC, 124208599Srdivacky const TargetRegisterInfo *TRI) const; 125198090Srdivacky 126226890Sdim virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const; 127226890Sdim 128199481Srdivacky virtual void reMaterialize(MachineBasicBlock &MBB, 129199481Srdivacky MachineBasicBlock::iterator MI, 130199481Srdivacky unsigned DestReg, unsigned SubIdx, 131199481Srdivacky const MachineInstr *Orig, 132210299Sed const TargetRegisterInfo &TRI) const; 133199481Srdivacky 134202375Srdivacky MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; 135202375Srdivacky 136235633Sdim MachineInstr *commuteInstruction(MachineInstr*, bool=false) const; 137235633Sdim 138252723Sdim const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg, 139252723Sdim unsigned SubIdx, unsigned State, 140252723Sdim const TargetRegisterInfo *TRI) const; 141252723Sdim 142204642Srdivacky virtual bool produceSameValue(const MachineInstr *MI0, 143218893Sdim const MachineInstr *MI1, 144218893Sdim const MachineRegisterInfo *MRI) const; 145210299Sed 146210299Sed /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to 147210299Sed /// determine if two loads are loading from the same base address. It should 148210299Sed /// only return true if the base pointers are the same and the only 149210299Sed /// differences between the two addresses is the offset. It also returns the 150210299Sed /// offsets by reference. 151210299Sed virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 152210299Sed int64_t &Offset1, int64_t &Offset2)const; 153210299Sed 154210299Sed /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to 155224145Sdim /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads 156224145Sdim /// should be scheduled togther. On some targets if two loads are loading from 157210299Sed /// addresses in the same cache line, it's better if they are scheduled 158210299Sed /// together. This function takes two integers that represent the load offsets 159210299Sed /// from the common base address. It returns true if it decides it's desirable 160210299Sed /// to schedule the two loads together. "NumLoads" is the number of loads that 161210299Sed /// have already been scheduled after Load1. 162210299Sed virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, 163210299Sed int64_t Offset1, int64_t Offset2, 164210299Sed unsigned NumLoads) const; 165210299Sed 166210299Sed virtual bool isSchedulingBoundary(const MachineInstr *MI, 167210299Sed const MachineBasicBlock *MBB, 168210299Sed const MachineFunction &MF) const; 169210299Sed 170210299Sed virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, 171221345Sdim unsigned NumCycles, unsigned ExtraPredCycles, 172224145Sdim const BranchProbability &Probability) const; 173210299Sed 174218893Sdim virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB, 175218893Sdim unsigned NumT, unsigned ExtraT, 176218893Sdim MachineBasicBlock &FMBB, 177218893Sdim unsigned NumF, unsigned ExtraF, 178224145Sdim const BranchProbability &Probability) const; 179210299Sed 180210299Sed virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, 181221345Sdim unsigned NumCycles, 182224145Sdim const BranchProbability 183245431Sdim &Probability) const { 184221345Sdim return NumCycles == 1; 185210299Sed } 186212904Sdim 187245431Sdim virtual bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 188245431Sdim MachineBasicBlock &FMBB) const; 189212904Sdim 190245431Sdim /// analyzeCompare - For a comparison instruction, return the source registers 191245431Sdim /// in SrcReg and SrcReg2 if having two register operands, and the value it 192245431Sdim /// compares against in CmpValue. Return true if the comparison instruction 193245431Sdim /// can be analyzed. 194245431Sdim virtual bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 195245431Sdim unsigned &SrcReg2, int &CmpMask, 196245431Sdim int &CmpValue) const; 197245431Sdim 198245431Sdim /// optimizeCompareInstr - Convert the instruction to set the zero flag so 199245431Sdim /// that we can remove a "comparison with zero"; Remove a redundant CMP 200245431Sdim /// instruction if the flags can be updated in the same way by an earlier 201245431Sdim /// instruction such as SUB. 202245431Sdim virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, 203245431Sdim unsigned SrcReg2, int CmpMask, int CmpValue, 204218893Sdim const MachineRegisterInfo *MRI) const; 205218893Sdim 206245431Sdim virtual bool analyzeSelect(const MachineInstr *MI, 207245431Sdim SmallVectorImpl<MachineOperand> &Cond, 208245431Sdim unsigned &TrueOp, unsigned &FalseOp, 209245431Sdim bool &Optimizable) const; 210245431Sdim 211245431Sdim virtual MachineInstr *optimizeSelect(MachineInstr *MI, bool) const; 212245431Sdim 213218893Sdim /// FoldImmediate - 'Reg' is known to be defined by a move immediate 214218893Sdim /// instruction, try to fold the immediate into the use instruction. 215218893Sdim virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI, 216218893Sdim unsigned Reg, MachineRegisterInfo *MRI) const; 217218893Sdim 218218893Sdim virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData, 219218893Sdim const MachineInstr *MI) const; 220218893Sdim 221218893Sdim virtual 222218893Sdim int getOperandLatency(const InstrItineraryData *ItinData, 223218893Sdim const MachineInstr *DefMI, unsigned DefIdx, 224218893Sdim const MachineInstr *UseMI, unsigned UseIdx) const; 225218893Sdim virtual 226218893Sdim int getOperandLatency(const InstrItineraryData *ItinData, 227218893Sdim SDNode *DefNode, unsigned DefIdx, 228218893Sdim SDNode *UseNode, unsigned UseIdx) const; 229226890Sdim 230226890Sdim /// VFP/NEON execution domains. 231226890Sdim std::pair<uint16_t, uint16_t> 232226890Sdim getExecutionDomain(const MachineInstr *MI) const; 233226890Sdim void setExecutionDomain(MachineInstr *MI, unsigned Domain) const; 234226890Sdim 235245431Sdim unsigned getPartialRegUpdateClearance(const MachineInstr*, unsigned, 236245431Sdim const TargetRegisterInfo*) const; 237245431Sdim void breakPartialRegDependency(MachineBasicBlock::iterator, unsigned, 238245431Sdim const TargetRegisterInfo *TRI) const; 239245431Sdim /// Get the number of addresses by LDM or VLDM or zero for unknown. 240245431Sdim unsigned getNumLDMAddresses(const MachineInstr *MI) const; 241245431Sdim 242218893Sdimprivate: 243235633Sdim unsigned getInstBundleLength(const MachineInstr *MI) const; 244235633Sdim 245218893Sdim int getVLDMDefCycle(const InstrItineraryData *ItinData, 246224145Sdim const MCInstrDesc &DefMCID, 247218893Sdim unsigned DefClass, 248218893Sdim unsigned DefIdx, unsigned DefAlign) const; 249218893Sdim int getLDMDefCycle(const InstrItineraryData *ItinData, 250224145Sdim const MCInstrDesc &DefMCID, 251218893Sdim unsigned DefClass, 252218893Sdim unsigned DefIdx, unsigned DefAlign) const; 253218893Sdim int getVSTMUseCycle(const InstrItineraryData *ItinData, 254224145Sdim const MCInstrDesc &UseMCID, 255218893Sdim unsigned UseClass, 256218893Sdim unsigned UseIdx, unsigned UseAlign) const; 257218893Sdim int getSTMUseCycle(const InstrItineraryData *ItinData, 258224145Sdim const MCInstrDesc &UseMCID, 259218893Sdim unsigned UseClass, 260218893Sdim unsigned UseIdx, unsigned UseAlign) const; 261218893Sdim int getOperandLatency(const InstrItineraryData *ItinData, 262224145Sdim const MCInstrDesc &DefMCID, 263218893Sdim unsigned DefIdx, unsigned DefAlign, 264224145Sdim const MCInstrDesc &UseMCID, 265218893Sdim unsigned UseIdx, unsigned UseAlign) const; 266218893Sdim 267263509Sdim unsigned getPredicationCost(const MachineInstr *MI) const; 268263509Sdim 269245431Sdim unsigned getInstrLatency(const InstrItineraryData *ItinData, 270245431Sdim const MachineInstr *MI, 271245431Sdim unsigned *PredCost = 0) const; 272218893Sdim 273218893Sdim int getInstrLatency(const InstrItineraryData *ItinData, 274218893Sdim SDNode *Node) const; 275218893Sdim 276218893Sdim bool hasHighOperandLatency(const InstrItineraryData *ItinData, 277218893Sdim const MachineRegisterInfo *MRI, 278218893Sdim const MachineInstr *DefMI, unsigned DefIdx, 279218893Sdim const MachineInstr *UseMI, unsigned UseIdx) const; 280218893Sdim bool hasLowDefLatency(const InstrItineraryData *ItinData, 281218893Sdim const MachineInstr *DefMI, unsigned DefIdx) const; 282218893Sdim 283226890Sdim /// verifyInstruction - Perform target specific instruction verification. 284226890Sdim bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const; 285226890Sdim 286218893Sdimprivate: 287218893Sdim /// Modeling special VFP / NEON fp MLA / MLS hazards. 288218893Sdim 289218893Sdim /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 290218893Sdim /// MLx table. 291218893Sdim DenseMap<unsigned, unsigned> MLxEntryMap; 292218893Sdim 293218893Sdim /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 294218893Sdim /// stalls when scheduled together with fp MLA / MLS opcodes. 295218893Sdim SmallSet<unsigned, 16> MLxHazardOpcodes; 296218893Sdim 297218893Sdimpublic: 298218893Sdim /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 299218893Sdim /// instruction. 300218893Sdim bool isFpMLxInstruction(unsigned Opcode) const { 301218893Sdim return MLxEntryMap.count(Opcode); 302218893Sdim } 303218893Sdim 304218893Sdim /// isFpMLxInstruction - This version also returns the multiply opcode and the 305218893Sdim /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 306218893Sdim /// the MLX instructions with an extra lane operand. 307218893Sdim bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 308218893Sdim unsigned &AddSubOpc, bool &NegAcc, 309218893Sdim bool &HasLane) const; 310218893Sdim 311218893Sdim /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 312218893Sdim /// will cause stalls when scheduled after (within 4-cycle window) a fp 313218893Sdim /// MLA / MLS instruction. 314218893Sdim bool canCauseFpMLxStall(unsigned Opcode) const { 315218893Sdim return MLxHazardOpcodes.count(Opcode); 316218893Sdim } 317252723Sdim 318252723Sdim /// Returns true if the instruction has a shift by immediate that can be 319252723Sdim /// executed in one cycle less. 320252723Sdim bool isSwiftFastImmShift(const MachineInstr *MI) const; 321198090Srdivacky}; 322198090Srdivacky 323198090Srdivackystatic inline 324198090Srdivackyconst MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 325198090Srdivacky return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 326198090Srdivacky} 327198090Srdivacky 328198090Srdivackystatic inline 329198090Srdivackyconst MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 330198090Srdivacky return MIB.addReg(0); 331198090Srdivacky} 332198090Srdivacky 333198090Srdivackystatic inline 334198090Srdivackyconst MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB, 335198090Srdivacky bool isDead = false) { 336198090Srdivacky return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead)); 337198090Srdivacky} 338198090Srdivacky 339198090Srdivackystatic inline 340198090Srdivackyconst MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) { 341198090Srdivacky return MIB.addReg(0); 342198090Srdivacky} 343198090Srdivacky 344198090Srdivackystatic inline 345198090Srdivackybool isUncondBranchOpcode(int Opc) { 346198090Srdivacky return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 347198090Srdivacky} 348198090Srdivacky 349198090Srdivackystatic inline 350198090Srdivackybool isCondBranchOpcode(int Opc) { 351198090Srdivacky return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 352198090Srdivacky} 353198090Srdivacky 354198090Srdivackystatic inline 355198090Srdivackybool isJumpTableBranchOpcode(int Opc) { 356198090Srdivacky return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd || 357198090Srdivacky Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT; 358198090Srdivacky} 359198090Srdivacky 360198892Srdivackystatic inline 361198892Srdivackybool isIndirectBranchOpcode(int Opc) { 362218893Sdim return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 363198892Srdivacky} 364198892Srdivacky 365263509Sdimstatic inline bool isPopOpcode(int Opc) { 366263509Sdim return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET || 367263509Sdim Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD || 368263509Sdim Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD; 369263509Sdim} 370263509Sdim 371263509Sdimstatic inline bool isPushOpcode(int Opc) { 372263509Sdim return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD || 373263509Sdim Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD; 374263509Sdim} 375263509Sdim 376198090Srdivacky/// getInstrPredicate - If instruction is predicated, returns its predicate 377198090Srdivacky/// condition, otherwise returns AL. It also returns the condition code 378198090Srdivacky/// register by reference. 379198090SrdivackyARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg); 380198090Srdivacky 381198090Srdivackyint getMatchingCondBranchOpcode(int Opc); 382198090Srdivacky 383245431Sdim/// Determine if MI can be folded into an ARM MOVCC instruction, and return the 384245431Sdim/// opcode of the SSA instruction representing the conditional MI. 385245431Sdimunsigned canFoldARMInstrIntoMOVCC(unsigned Reg, 386245431Sdim MachineInstr *&MI, 387245431Sdim const MachineRegisterInfo &MRI); 388226890Sdim 389226890Sdim/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether 390226890Sdim/// the instruction is encoded with an 'S' bit is determined by the optional 391226890Sdim/// CPSR def operand. 392226890Sdimunsigned convertAddSubFlagsOpcode(unsigned OldOpc); 393226890Sdim 394198090Srdivacky/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 395198090Srdivacky/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 396198090Srdivacky/// code. 397198090Srdivackyvoid emitARMRegPlusImmediate(MachineBasicBlock &MBB, 398198090Srdivacky MachineBasicBlock::iterator &MBBI, DebugLoc dl, 399198090Srdivacky unsigned DestReg, unsigned BaseReg, int NumBytes, 400198090Srdivacky ARMCC::CondCodes Pred, unsigned PredReg, 401221345Sdim const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 402198090Srdivacky 403198090Srdivackyvoid emitT2RegPlusImmediate(MachineBasicBlock &MBB, 404198090Srdivacky MachineBasicBlock::iterator &MBBI, DebugLoc dl, 405198090Srdivacky unsigned DestReg, unsigned BaseReg, int NumBytes, 406198090Srdivacky ARMCC::CondCodes Pred, unsigned PredReg, 407221345Sdim const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 408218893Sdimvoid emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 409221345Sdim MachineBasicBlock::iterator &MBBI, DebugLoc dl, 410218893Sdim unsigned DestReg, unsigned BaseReg, 411218893Sdim int NumBytes, const TargetInstrInfo &TII, 412218893Sdim const ARMBaseRegisterInfo& MRI, 413221345Sdim unsigned MIFlags = 0); 414198090Srdivacky 415263509Sdim/// Tries to add registers to the reglist of a given base-updating 416263509Sdim/// push/pop instruction to adjust the stack by an additional 417263509Sdim/// NumBytes. This can save a few bytes per function in code-size, but 418263509Sdim/// obviously generates more memory traffic. As such, it only takes 419263509Sdim/// effect in functions being optimised for size. 420263509Sdimbool tryFoldSPUpdateIntoPushPop(MachineFunction &MF, MachineInstr *MI, 421263509Sdim unsigned NumBytes); 422198090Srdivacky 423198090Srdivacky/// rewriteARMFrameIndex / rewriteT2FrameIndex - 424198090Srdivacky/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 425198090Srdivacky/// offset could not be handled directly in MI, and return the left-over 426198090Srdivacky/// portion by reference. 427198090Srdivackybool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 428198090Srdivacky unsigned FrameReg, int &Offset, 429198090Srdivacky const ARMBaseInstrInfo &TII); 430198090Srdivacky 431198090Srdivackybool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 432198090Srdivacky unsigned FrameReg, int &Offset, 433198090Srdivacky const ARMBaseInstrInfo &TII); 434198090Srdivacky 435198090Srdivacky} // End llvm namespace 436198090Srdivacky 437198090Srdivacky#endif 438