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