Home | History | Annotate | Download | only in SystemZ
      1 //===-- SystemZInstrInfo.h - SystemZ 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 SystemZ implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H
     15 #define LLVM_TARGET_SYSTEMZINSTRINFO_H
     16 
     17 #include "SystemZ.h"
     18 #include "SystemZRegisterInfo.h"
     19 #include "llvm/Target/TargetInstrInfo.h"
     20 
     21 #define GET_INSTRINFO_HEADER
     22 #include "SystemZGenInstrInfo.inc"
     23 
     24 namespace llvm {
     25 
     26 class SystemZTargetMachine;
     27 
     28 namespace SystemZII {
     29   enum {
     30     // See comments in SystemZInstrFormats.td.
     31     SimpleBDXLoad          = (1 << 0),
     32     SimpleBDXStore         = (1 << 1),
     33     Has20BitOffset         = (1 << 2),
     34     HasIndex               = (1 << 3),
     35     Is128Bit               = (1 << 4),
     36     AccessSizeMask         = (31 << 5),
     37     AccessSizeShift        = 5,
     38     CCValuesMask           = (15 << 10),
     39     CCValuesShift          = 10,
     40     CompareZeroCCMaskMask  = (15 << 14),
     41     CompareZeroCCMaskShift = 14,
     42     CCMaskFirst            = (1 << 18),
     43     CCMaskLast             = (1 << 19),
     44     IsLogical              = (1 << 20)
     45   };
     46   static inline unsigned getAccessSize(unsigned int Flags) {
     47     return (Flags & AccessSizeMask) >> AccessSizeShift;
     48   }
     49   static inline unsigned getCCValues(unsigned int Flags) {
     50     return (Flags & CCValuesMask) >> CCValuesShift;
     51   }
     52   static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
     53     return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
     54   }
     55 
     56   // SystemZ MachineOperand target flags.
     57   enum {
     58     // Masks out the bits for the access model.
     59     MO_SYMBOL_MODIFIER = (1 << 0),
     60 
     61     // @GOT (aka @GOTENT)
     62     MO_GOT = (1 << 0)
     63   };
     64   // Classifies a branch.
     65   enum BranchType {
     66     // An instruction that branches on the current value of CC.
     67     BranchNormal,
     68 
     69     // An instruction that peforms a 32-bit signed comparison and branches
     70     // on the result.
     71     BranchC,
     72 
     73     // An instruction that peforms a 64-bit signed comparison and branches
     74     // on the result.
     75     BranchCG,
     76 
     77     // An instruction that decrements a 32-bit register and branches if
     78     // the result is nonzero.
     79     BranchCT,
     80 
     81     // An instruction that decrements a 64-bit register and branches if
     82     // the result is nonzero.
     83     BranchCTG
     84   };
     85   // Information about a branch instruction.
     86   struct Branch {
     87     // The type of the branch.
     88     BranchType Type;
     89 
     90     // CCMASK_<N> is set if CC might be equal to N.
     91     unsigned CCValid;
     92 
     93     // CCMASK_<N> is set if the branch should be taken when CC == N.
     94     unsigned CCMask;
     95 
     96     // The target of the branch.
     97     const MachineOperand *Target;
     98 
     99     Branch(BranchType type, unsigned ccValid, unsigned ccMask,
    100            const MachineOperand *target)
    101       : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
    102   };
    103 }
    104 
    105 class SystemZInstrInfo : public SystemZGenInstrInfo {
    106   const SystemZRegisterInfo RI;
    107   SystemZTargetMachine &TM;
    108 
    109   void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
    110   void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
    111 
    112 public:
    113   explicit SystemZInstrInfo(SystemZTargetMachine &TM);
    114 
    115   // Override TargetInstrInfo.
    116   virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
    117                                        int &FrameIndex) const LLVM_OVERRIDE;
    118   virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
    119                                       int &FrameIndex) const LLVM_OVERRIDE;
    120   virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
    121                                int &SrcFrameIndex) const LLVM_OVERRIDE;
    122   virtual bool AnalyzeBranch(MachineBasicBlock &MBB,
    123                              MachineBasicBlock *&TBB,
    124                              MachineBasicBlock *&FBB,
    125                              SmallVectorImpl<MachineOperand> &Cond,
    126                              bool AllowModify) const LLVM_OVERRIDE;
    127   virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE;
    128   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    129                                 MachineBasicBlock *FBB,
    130                                 const SmallVectorImpl<MachineOperand> &Cond,
    131                                 DebugLoc DL) const LLVM_OVERRIDE;
    132   virtual bool isPredicable(MachineInstr *MI) const LLVM_OVERRIDE;
    133   virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
    134                                    unsigned ExtraPredCycles,
    135                                    const BranchProbability &Probability) const
    136     LLVM_OVERRIDE;
    137   virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
    138                                    unsigned NumCyclesT,
    139                                    unsigned ExtraPredCyclesT,
    140                                    MachineBasicBlock &FMBB,
    141                                    unsigned NumCyclesF,
    142                                    unsigned ExtraPredCyclesF,
    143                                    const BranchProbability &Probability) const
    144     LLVM_OVERRIDE;
    145   virtual bool
    146     PredicateInstruction(MachineInstr *MI,
    147                          const SmallVectorImpl<MachineOperand> &Pred) const
    148     LLVM_OVERRIDE;
    149   virtual void copyPhysReg(MachineBasicBlock &MBB,
    150                            MachineBasicBlock::iterator MBBI, DebugLoc DL,
    151                            unsigned DestReg, unsigned SrcReg,
    152                            bool KillSrc) const LLVM_OVERRIDE;
    153   virtual void
    154     storeRegToStackSlot(MachineBasicBlock &MBB,
    155                         MachineBasicBlock::iterator MBBI,
    156                         unsigned SrcReg, bool isKill, int FrameIndex,
    157                         const TargetRegisterClass *RC,
    158                         const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
    159   virtual void
    160     loadRegFromStackSlot(MachineBasicBlock &MBB,
    161                          MachineBasicBlock::iterator MBBI,
    162                          unsigned DestReg, int FrameIdx,
    163                          const TargetRegisterClass *RC,
    164                          const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
    165   virtual MachineInstr *
    166     convertToThreeAddress(MachineFunction::iterator &MFI,
    167                           MachineBasicBlock::iterator &MBBI,
    168                           LiveVariables *LV) const;
    169   virtual MachineInstr *
    170     foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
    171                           const SmallVectorImpl<unsigned> &Ops,
    172                           int FrameIndex) const;
    173   virtual MachineInstr *
    174     foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
    175                           const SmallVectorImpl<unsigned> &Ops,
    176                           MachineInstr* LoadMI) const;
    177   virtual bool
    178     expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE;
    179   virtual bool
    180     ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
    181     LLVM_OVERRIDE;
    182 
    183   // Return the SystemZRegisterInfo, which this class owns.
    184   const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
    185 
    186   // Return the size in bytes of MI.
    187   uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
    188 
    189   // Return true if MI is a conditional or unconditional branch.
    190   // When returning true, set Cond to the mask of condition-code
    191   // values on which the instruction will branch, and set Target
    192   // to the operand that contains the branch target.  This target
    193   // can be a register or a basic block.
    194   SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
    195 
    196   // Get the load and store opcodes for a given register class.
    197   void getLoadStoreOpcodes(const TargetRegisterClass *RC,
    198                            unsigned &LoadOpcode, unsigned &StoreOpcode) const;
    199 
    200   // Opcode is the opcode of an instruction that has an address operand,
    201   // and the caller wants to perform that instruction's operation on an
    202   // address that has displacement Offset.  Return the opcode of a suitable
    203   // instruction (which might be Opcode itself) or 0 if no such instruction
    204   // exists.
    205   unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
    206 
    207   // If Opcode is a load instruction that has a LOAD AND TEST form,
    208   // return the opcode for the testing form, otherwise return 0.
    209   unsigned getLoadAndTest(unsigned Opcode) const;
    210 
    211   // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
    212   // Mask of the R2 operand, given that only the low BitSize bits of Mask are
    213   // significant.  Set Start and End to the I3 and I4 operands if so.
    214   bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
    215                    unsigned &Start, unsigned &End) const;
    216 
    217   // If Opcode is a COMPARE opcode for which an associated COMPARE AND
    218   // BRANCH exists, return the opcode for the latter, otherwise return 0.
    219   // MI, if nonnull, is the compare instruction.
    220   unsigned getCompareAndBranch(unsigned Opcode,
    221                                const MachineInstr *MI = 0) const;
    222 
    223   // Emit code before MBBI in MI to move immediate value Value into
    224   // physical register Reg.
    225   void loadImmediate(MachineBasicBlock &MBB,
    226                      MachineBasicBlock::iterator MBBI,
    227                      unsigned Reg, uint64_t Value) const;
    228 };
    229 } // end namespace llvm
    230 
    231 #endif
    232