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 32-bit unsigned comparison and branches
     74   // on the result.
     75   BranchCL,
     76 
     77   // An instruction that peforms a 64-bit signed comparison and branches
     78   // on the result.
     79   BranchCG,
     80 
     81   // An instruction that peforms a 64-bit unsigned comparison and branches
     82   // on the result.
     83   BranchCLG,
     84 
     85   // An instruction that decrements a 32-bit register and branches if
     86   // the result is nonzero.
     87   BranchCT,
     88 
     89   // An instruction that decrements a 64-bit register and branches if
     90   // the result is nonzero.
     91   BranchCTG
     92 };
     93 // Information about a branch instruction.
     94 struct Branch {
     95   // The type of the branch.
     96   BranchType Type;
     97 
     98   // CCMASK_<N> is set if CC might be equal to N.
     99   unsigned CCValid;
    100 
    101   // CCMASK_<N> is set if the branch should be taken when CC == N.
    102   unsigned CCMask;
    103 
    104   // The target of the branch.
    105   const MachineOperand *Target;
    106 
    107   Branch(BranchType type, unsigned ccValid, unsigned ccMask,
    108          const MachineOperand *target)
    109     : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
    110 };
    111 } // end namespace SystemZII
    112 
    113 class SystemZSubtarget;
    114 class SystemZInstrInfo : public SystemZGenInstrInfo {
    115   const SystemZRegisterInfo RI;
    116   SystemZSubtarget &STI;
    117 
    118   void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
    119   void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
    120   void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode,
    121                       unsigned HighOpcode, bool ConvertHigh) const;
    122   void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode,
    123                        unsigned LowOpcodeK, unsigned HighOpcode) const;
    124   void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode,
    125                        unsigned HighOpcode) const;
    126   void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode,
    127                         unsigned Size) const;
    128   void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
    129                      DebugLoc DL, unsigned DestReg, unsigned SrcReg,
    130                      unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
    131   virtual void anchor();
    132 
    133 public:
    134   explicit SystemZInstrInfo(SystemZSubtarget &STI);
    135 
    136   // Override TargetInstrInfo.
    137   unsigned isLoadFromStackSlot(const MachineInstr *MI,
    138                                int &FrameIndex) const override;
    139   unsigned isStoreToStackSlot(const MachineInstr *MI,
    140                               int &FrameIndex) const override;
    141   bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
    142                        int &SrcFrameIndex) const override;
    143   bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
    144                      MachineBasicBlock *&FBB,
    145                      SmallVectorImpl<MachineOperand> &Cond,
    146                      bool AllowModify) const override;
    147   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
    148   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    149                         MachineBasicBlock *FBB,
    150                         const SmallVectorImpl<MachineOperand> &Cond,
    151                         DebugLoc DL) const override;
    152   bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
    153                       unsigned &SrcReg2, int &Mask, int &Value) const override;
    154   bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
    155                             unsigned SrcReg2, int Mask, int Value,
    156                             const MachineRegisterInfo *MRI) const override;
    157   bool isPredicable(MachineInstr *MI) const override;
    158   bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
    159                            unsigned ExtraPredCycles,
    160                            const BranchProbability &Probability) const override;
    161   bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
    162                            unsigned NumCyclesT, unsigned ExtraPredCyclesT,
    163                            MachineBasicBlock &FMBB,
    164                            unsigned NumCyclesF, unsigned ExtraPredCyclesF,
    165                            const BranchProbability &Probability) const override;
    166   bool PredicateInstruction(MachineInstr *MI,
    167                             const SmallVectorImpl<MachineOperand> &Pred) const
    168     override;
    169   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
    170                    DebugLoc DL, unsigned DestReg, unsigned SrcReg,
    171                    bool KillSrc) const override;
    172   void storeRegToStackSlot(MachineBasicBlock &MBB,
    173                            MachineBasicBlock::iterator MBBI,
    174                            unsigned SrcReg, bool isKill, int FrameIndex,
    175                            const TargetRegisterClass *RC,
    176                            const TargetRegisterInfo *TRI) const override;
    177   void loadRegFromStackSlot(MachineBasicBlock &MBB,
    178                             MachineBasicBlock::iterator MBBI,
    179                             unsigned DestReg, int FrameIdx,
    180                             const TargetRegisterClass *RC,
    181                             const TargetRegisterInfo *TRI) const override;
    182   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
    183                                       MachineBasicBlock::iterator &MBBI,
    184                                       LiveVariables *LV) const override;
    185   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
    186                                       const SmallVectorImpl<unsigned> &Ops,
    187                                       int FrameIndex) const override;
    188   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
    189                                       const SmallVectorImpl<unsigned> &Ops,
    190                                       MachineInstr* LoadMI) const override;
    191   bool expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const override;
    192   bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
    193     override;
    194 
    195   // Return the SystemZRegisterInfo, which this class owns.
    196   const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
    197 
    198   // Return the size in bytes of MI.
    199   uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
    200 
    201   // Return true if MI is a conditional or unconditional branch.
    202   // When returning true, set Cond to the mask of condition-code
    203   // values on which the instruction will branch, and set Target
    204   // to the operand that contains the branch target.  This target
    205   // can be a register or a basic block.
    206   SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
    207 
    208   // Get the load and store opcodes for a given register class.
    209   void getLoadStoreOpcodes(const TargetRegisterClass *RC,
    210                            unsigned &LoadOpcode, unsigned &StoreOpcode) const;
    211 
    212   // Opcode is the opcode of an instruction that has an address operand,
    213   // and the caller wants to perform that instruction's operation on an
    214   // address that has displacement Offset.  Return the opcode of a suitable
    215   // instruction (which might be Opcode itself) or 0 if no such instruction
    216   // exists.
    217   unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
    218 
    219   // If Opcode is a load instruction that has a LOAD AND TEST form,
    220   // return the opcode for the testing form, otherwise return 0.
    221   unsigned getLoadAndTest(unsigned Opcode) const;
    222 
    223   // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
    224   // Mask of the R2 operand, given that only the low BitSize bits of Mask are
    225   // significant.  Set Start and End to the I3 and I4 operands if so.
    226   bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
    227                    unsigned &Start, unsigned &End) const;
    228 
    229   // If Opcode is a COMPARE opcode for which an associated COMPARE AND
    230   // BRANCH exists, return the opcode for the latter, otherwise return 0.
    231   // MI, if nonnull, is the compare instruction.
    232   unsigned getCompareAndBranch(unsigned Opcode,
    233                                const MachineInstr *MI = nullptr) const;
    234 
    235   // Emit code before MBBI in MI to move immediate value Value into
    236   // physical register Reg.
    237   void loadImmediate(MachineBasicBlock &MBB,
    238                      MachineBasicBlock::iterator MBBI,
    239                      unsigned Reg, uint64_t Value) const;
    240 };
    241 } // end namespace llvm
    242 
    243 #endif
    244