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