ARMBaseInstrInfo.h revision e4345c9977e65b14fa4b93d19c7e67a7b15f7f40
1//===- ARMBaseInstrInfo.h - ARM Base Instruction Information ----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Base ARM implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef ARMBASEINSTRUCTIONINFO_H
15#define ARMBASEINSTRUCTIONINFO_H
16
17#include "ARM.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/Target/TargetInstrInfo.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallSet.h"
22
23namespace llvm {
24  class ARMSubtarget;
25  class ARMBaseRegisterInfo;
26
27/// ARMII - This namespace holds all of the target specific flags that
28/// instruction info tracks.
29///
30namespace ARMII {
31  enum {
32    //===------------------------------------------------------------------===//
33    // Instruction Flags.
34
35    //===------------------------------------------------------------------===//
36    // This four-bit field describes the addressing mode used.
37
38    AddrModeMask  = 0x1f,
39    AddrModeNone    = 0,
40    AddrMode1       = 1,
41    AddrMode2       = 2,
42    AddrMode3       = 3,
43    AddrMode4       = 4,
44    AddrMode5       = 5,
45    AddrMode6       = 6,
46    AddrModeT1_1    = 7,
47    AddrModeT1_2    = 8,
48    AddrModeT1_4    = 9,
49    AddrModeT1_s    = 10, // i8 * 4 for pc and sp relative data
50    AddrModeT2_i12  = 11,
51    AddrModeT2_i8   = 12,
52    AddrModeT2_so   = 13,
53    AddrModeT2_pc   = 14, // +/- i12 for pc relative data
54    AddrModeT2_i8s4 = 15, // i8 * 4
55    AddrMode_i12    = 16,
56
57    // Size* - Flags to keep track of the size of an instruction.
58    SizeShift     = 5,
59    SizeMask      = 7 << SizeShift,
60    SizeSpecial   = 1,   // 0 byte pseudo or special case.
61    Size8Bytes    = 2,
62    Size4Bytes    = 3,
63    Size2Bytes    = 4,
64
65    // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
66    // and store ops only.  Generic "updating" flag is used for ld/st multiple.
67    IndexModeShift = 8,
68    IndexModeMask  = 3 << IndexModeShift,
69    IndexModePre   = 1,
70    IndexModePost  = 2,
71    IndexModeUpd   = 3,
72
73    //===------------------------------------------------------------------===//
74    // Instruction encoding formats.
75    //
76    FormShift     = 10,
77    FormMask      = 0x3f << FormShift,
78
79    // Pseudo instructions
80    Pseudo        = 0  << FormShift,
81
82    // Multiply instructions
83    MulFrm        = 1  << FormShift,
84
85    // Branch instructions
86    BrFrm         = 2  << FormShift,
87    BrMiscFrm     = 3  << FormShift,
88
89    // Data Processing instructions
90    DPFrm         = 4  << FormShift,
91    DPSoRegFrm    = 5  << FormShift,
92
93    // Load and Store
94    LdFrm         = 6  << FormShift,
95    StFrm         = 7  << FormShift,
96    LdMiscFrm     = 8  << FormShift,
97    StMiscFrm     = 9  << FormShift,
98    LdStMulFrm    = 10 << FormShift,
99
100    LdStExFrm     = 11 << FormShift,
101
102    // Miscellaneous arithmetic instructions
103    ArithMiscFrm  = 12 << FormShift,
104    SatFrm        = 13 << FormShift,
105
106    // Extend instructions
107    ExtFrm        = 14 << FormShift,
108
109    // VFP formats
110    VFPUnaryFrm   = 15 << FormShift,
111    VFPBinaryFrm  = 16 << FormShift,
112    VFPConv1Frm   = 17 << FormShift,
113    VFPConv2Frm   = 18 << FormShift,
114    VFPConv3Frm   = 19 << FormShift,
115    VFPConv4Frm   = 20 << FormShift,
116    VFPConv5Frm   = 21 << FormShift,
117    VFPLdStFrm    = 22 << FormShift,
118    VFPLdStMulFrm = 23 << FormShift,
119    VFPMiscFrm    = 24 << FormShift,
120
121    // Thumb format
122    ThumbFrm      = 25 << FormShift,
123
124    // Miscelleaneous format
125    MiscFrm       = 26 << FormShift,
126
127    // NEON formats
128    NGetLnFrm     = 27 << FormShift,
129    NSetLnFrm     = 28 << FormShift,
130    NDupFrm       = 29 << FormShift,
131    NLdStFrm      = 30 << FormShift,
132    N1RegModImmFrm= 31 << FormShift,
133    N2RegFrm      = 32 << FormShift,
134    NVCVTFrm      = 33 << FormShift,
135    NVDupLnFrm    = 34 << FormShift,
136    N2RegVShLFrm  = 35 << FormShift,
137    N2RegVShRFrm  = 36 << FormShift,
138    N3RegFrm      = 37 << FormShift,
139    N3RegVShFrm   = 38 << FormShift,
140    NVExtFrm      = 39 << FormShift,
141    NVMulSLFrm    = 40 << FormShift,
142    NVTBLFrm      = 41 << FormShift,
143
144    //===------------------------------------------------------------------===//
145    // Misc flags.
146
147    // UnaryDP - Indicates this is a unary data processing instruction, i.e.
148    // it doesn't have a Rn operand.
149    UnaryDP       = 1 << 16,
150
151    // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
152    // a 16-bit Thumb instruction if certain conditions are met.
153    Xform16Bit    = 1 << 17,
154
155    //===------------------------------------------------------------------===//
156    // Code domain.
157    DomainShift   = 18,
158    DomainMask    = 7 << DomainShift,
159    DomainGeneral = 0 << DomainShift,
160    DomainVFP     = 1 << DomainShift,
161    DomainNEON    = 2 << DomainShift,
162    DomainNEONA8  = 4 << DomainShift,
163
164    //===------------------------------------------------------------------===//
165    // Field shifts - such shifts are used to set field while generating
166    // machine instructions.
167    //
168    // FIXME: This list will need adjusting/fixing as the MC code emitter
169    // takes shape and the ARMCodeEmitter.cpp bits go away.
170    ShiftTypeShift = 4,
171
172    M_BitShift     = 5,
173    ShiftImmShift  = 5,
174    ShiftShift     = 7,
175    N_BitShift     = 7,
176    ImmHiShift     = 8,
177    SoRotImmShift  = 8,
178    RegRsShift     = 8,
179    ExtRotImmShift = 10,
180    RegRdLoShift   = 12,
181    RegRdShift     = 12,
182    RegRdHiShift   = 16,
183    RegRnShift     = 16,
184    S_BitShift     = 20,
185    W_BitShift     = 21,
186    AM3_I_BitShift = 22,
187    D_BitShift     = 22,
188    U_BitShift     = 23,
189    P_BitShift     = 24,
190    I_BitShift     = 25,
191    CondShift      = 28
192  };
193}
194
195class ARMBaseInstrInfo : public TargetInstrInfoImpl {
196  const ARMSubtarget &Subtarget;
197
198protected:
199  // Can be only subclassed.
200  explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
201
202public:
203  // Return the non-pre/post incrementing version of 'Opc'. Return 0
204  // if there is not such an opcode.
205  virtual unsigned getUnindexedOpcode(unsigned Opc) const =0;
206
207  virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
208                                              MachineBasicBlock::iterator &MBBI,
209                                              LiveVariables *LV) const;
210
211  virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
212  const ARMSubtarget &getSubtarget() const { return Subtarget; }
213
214  ScheduleHazardRecognizer *
215  CreateTargetHazardRecognizer(const TargetMachine *TM,
216                               const ScheduleDAG *DAG) const;
217
218  ScheduleHazardRecognizer *
219  CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
220                                     const ScheduleDAG *DAG) const;
221
222  // Branch analysis.
223  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
224                             MachineBasicBlock *&FBB,
225                             SmallVectorImpl<MachineOperand> &Cond,
226                             bool AllowModify = false) const;
227  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
228  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
229                                MachineBasicBlock *FBB,
230                                const SmallVectorImpl<MachineOperand> &Cond,
231                                DebugLoc DL) const;
232
233  virtual
234  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
235
236  // Predication support.
237  bool isPredicated(const MachineInstr *MI) const {
238    int PIdx = MI->findFirstPredOperandIdx();
239    return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
240  }
241
242  ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
243    int PIdx = MI->findFirstPredOperandIdx();
244    return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
245                      : ARMCC::AL;
246  }
247
248  virtual
249  bool PredicateInstruction(MachineInstr *MI,
250                            const SmallVectorImpl<MachineOperand> &Pred) const;
251
252  virtual
253  bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
254                         const SmallVectorImpl<MachineOperand> &Pred2) const;
255
256  virtual bool DefinesPredicate(MachineInstr *MI,
257                                std::vector<MachineOperand> &Pred) const;
258
259  virtual bool isPredicable(MachineInstr *MI) const;
260
261  /// GetInstSize - Returns the size of the specified MachineInstr.
262  ///
263  virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
264
265  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
266                                       int &FrameIndex) const;
267  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
268                                      int &FrameIndex) const;
269
270  virtual void copyPhysReg(MachineBasicBlock &MBB,
271                           MachineBasicBlock::iterator I, DebugLoc DL,
272                           unsigned DestReg, unsigned SrcReg,
273                           bool KillSrc) const;
274
275  virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
276                                   MachineBasicBlock::iterator MBBI,
277                                   unsigned SrcReg, bool isKill, int FrameIndex,
278                                   const TargetRegisterClass *RC,
279                                   const TargetRegisterInfo *TRI) const;
280
281  virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
282                                    MachineBasicBlock::iterator MBBI,
283                                    unsigned DestReg, int FrameIndex,
284                                    const TargetRegisterClass *RC,
285                                    const TargetRegisterInfo *TRI) const;
286
287  virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
288                                                 int FrameIx,
289                                                 uint64_t Offset,
290                                                 const MDNode *MDPtr,
291                                                 DebugLoc DL) const;
292
293  virtual void reMaterialize(MachineBasicBlock &MBB,
294                             MachineBasicBlock::iterator MI,
295                             unsigned DestReg, unsigned SubIdx,
296                             const MachineInstr *Orig,
297                             const TargetRegisterInfo &TRI) const;
298
299  MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
300
301  virtual bool produceSameValue(const MachineInstr *MI0,
302                                const MachineInstr *MI1,
303                                const MachineRegisterInfo *MRI) const;
304
305  /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
306  /// determine if two loads are loading from the same base address. It should
307  /// only return true if the base pointers are the same and the only
308  /// differences between the two addresses is the offset. It also returns the
309  /// offsets by reference.
310  virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
311                                       int64_t &Offset1, int64_t &Offset2)const;
312
313  /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
314  /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
315  /// be scheduled togther. On some targets if two loads are loading from
316  /// addresses in the same cache line, it's better if they are scheduled
317  /// together. This function takes two integers that represent the load offsets
318  /// from the common base address. It returns true if it decides it's desirable
319  /// to schedule the two loads together. "NumLoads" is the number of loads that
320  /// have already been scheduled after Load1.
321  virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
322                                       int64_t Offset1, int64_t Offset2,
323                                       unsigned NumLoads) const;
324
325  virtual bool isSchedulingBoundary(const MachineInstr *MI,
326                                    const MachineBasicBlock *MBB,
327                                    const MachineFunction &MF) const;
328
329  virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
330                                   unsigned NumCyles, unsigned ExtraPredCycles,
331                                   float Prob, float Confidence) const;
332
333  virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
334                                   unsigned NumT, unsigned ExtraT,
335                                   MachineBasicBlock &FMBB,
336                                   unsigned NumF, unsigned ExtraF,
337                                   float Probability, float Confidence) const;
338
339  virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
340                                         unsigned NumCyles,
341                                         float Probability,
342                                         float Confidence) const {
343    return NumCyles == 1;
344  }
345
346  /// AnalyzeCompare - For a comparison instruction, return the source register
347  /// in SrcReg and the value it compares against in CmpValue. Return true if
348  /// the comparison instruction can be analyzed.
349  virtual bool AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
350                              int &CmpMask, int &CmpValue) const;
351
352  /// OptimizeCompareInstr - Convert the instruction to set the zero flag so
353  /// that we can remove a "comparison with zero".
354  virtual bool OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
355                                    int CmpMask, int CmpValue,
356                                    const MachineRegisterInfo *MRI) const;
357
358  /// FoldImmediate - 'Reg' is known to be defined by a move immediate
359  /// instruction, try to fold the immediate into the use instruction.
360  virtual bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
361                             unsigned Reg, MachineRegisterInfo *MRI) const;
362
363  virtual unsigned getNumMicroOps(const InstrItineraryData *ItinData,
364                                  const MachineInstr *MI) const;
365
366  virtual
367  int getOperandLatency(const InstrItineraryData *ItinData,
368                        const MachineInstr *DefMI, unsigned DefIdx,
369                        const MachineInstr *UseMI, unsigned UseIdx) const;
370  virtual
371  int getOperandLatency(const InstrItineraryData *ItinData,
372                        SDNode *DefNode, unsigned DefIdx,
373                        SDNode *UseNode, unsigned UseIdx) const;
374private:
375  int getVLDMDefCycle(const InstrItineraryData *ItinData,
376                      const TargetInstrDesc &DefTID,
377                      unsigned DefClass,
378                      unsigned DefIdx, unsigned DefAlign) const;
379  int getLDMDefCycle(const InstrItineraryData *ItinData,
380                     const TargetInstrDesc &DefTID,
381                     unsigned DefClass,
382                     unsigned DefIdx, unsigned DefAlign) const;
383  int getVSTMUseCycle(const InstrItineraryData *ItinData,
384                      const TargetInstrDesc &UseTID,
385                      unsigned UseClass,
386                      unsigned UseIdx, unsigned UseAlign) const;
387  int getSTMUseCycle(const InstrItineraryData *ItinData,
388                     const TargetInstrDesc &UseTID,
389                     unsigned UseClass,
390                     unsigned UseIdx, unsigned UseAlign) const;
391  int getOperandLatency(const InstrItineraryData *ItinData,
392                        const TargetInstrDesc &DefTID,
393                        unsigned DefIdx, unsigned DefAlign,
394                        const TargetInstrDesc &UseTID,
395                        unsigned UseIdx, unsigned UseAlign) const;
396
397  int getInstrLatency(const InstrItineraryData *ItinData,
398                      const MachineInstr *MI, unsigned *PredCost = 0) const;
399
400  int getInstrLatency(const InstrItineraryData *ItinData,
401                      SDNode *Node) const;
402
403  bool hasHighOperandLatency(const InstrItineraryData *ItinData,
404                             const MachineRegisterInfo *MRI,
405                             const MachineInstr *DefMI, unsigned DefIdx,
406                             const MachineInstr *UseMI, unsigned UseIdx) const;
407  bool hasLowDefLatency(const InstrItineraryData *ItinData,
408                        const MachineInstr *DefMI, unsigned DefIdx) const;
409
410private:
411  /// Modeling special VFP / NEON fp MLA / MLS hazards.
412
413  /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
414  /// MLx table.
415  DenseMap<unsigned, unsigned> MLxEntryMap;
416
417  /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
418  /// stalls when scheduled together with fp MLA / MLS opcodes.
419  SmallSet<unsigned, 16> MLxHazardOpcodes;
420
421public:
422  /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
423  /// instruction.
424  bool isFpMLxInstruction(unsigned Opcode) const {
425    return MLxEntryMap.count(Opcode);
426  }
427
428  /// isFpMLxInstruction - This version also returns the multiply opcode and the
429  /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
430  /// the MLX instructions with an extra lane operand.
431  bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
432                          unsigned &AddSubOpc, bool &NegAcc,
433                          bool &HasLane) const;
434
435  /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
436  /// will cause stalls when scheduled after (within 4-cycle window) a fp
437  /// MLA / MLS instruction.
438  bool canCauseFpMLxStall(unsigned Opcode) const {
439    return MLxHazardOpcodes.count(Opcode);
440  }
441};
442
443static inline
444const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
445  return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
446}
447
448static inline
449const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
450  return MIB.addReg(0);
451}
452
453static inline
454const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB,
455                                          bool isDead = false) {
456  return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead));
457}
458
459static inline
460const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) {
461  return MIB.addReg(0);
462}
463
464static inline
465bool isUncondBranchOpcode(int Opc) {
466  return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
467}
468
469static inline
470bool isCondBranchOpcode(int Opc) {
471  return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
472}
473
474static inline
475bool isJumpTableBranchOpcode(int Opc) {
476  return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd ||
477    Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT;
478}
479
480static inline
481bool isIndirectBranchOpcode(int Opc) {
482  return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
483}
484
485/// getInstrPredicate - If instruction is predicated, returns its predicate
486/// condition, otherwise returns AL. It also returns the condition code
487/// register by reference.
488ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
489
490int getMatchingCondBranchOpcode(int Opc);
491
492/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
493/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
494/// code.
495void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
496                             MachineBasicBlock::iterator &MBBI, DebugLoc dl,
497                             unsigned DestReg, unsigned BaseReg, int NumBytes,
498                             ARMCC::CondCodes Pred, unsigned PredReg,
499                             const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
500
501void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
502                            MachineBasicBlock::iterator &MBBI, DebugLoc dl,
503                            unsigned DestReg, unsigned BaseReg, int NumBytes,
504                            ARMCC::CondCodes Pred, unsigned PredReg,
505                            const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
506void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
507                               MachineBasicBlock::iterator &MBBI, DebugLoc dl,
508                               unsigned DestReg, unsigned BaseReg,
509                               int NumBytes, const TargetInstrInfo &TII,
510                               const ARMBaseRegisterInfo& MRI,
511                               unsigned MIFlags = 0);
512
513
514/// rewriteARMFrameIndex / rewriteT2FrameIndex -
515/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
516/// offset could not be handled directly in MI, and return the left-over
517/// portion by reference.
518bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
519                          unsigned FrameReg, int &Offset,
520                          const ARMBaseInstrInfo &TII);
521
522bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
523                         unsigned FrameReg, int &Offset,
524                         const ARMBaseInstrInfo &TII);
525
526} // End llvm namespace
527
528#endif
529