LLVM API Documentation

SystemZInstrInfo.h
Go to the documentation of this file.
00001 //===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the SystemZ implementation of the TargetInstrInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
00015 #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
00016 
00017 #include "SystemZ.h"
00018 #include "SystemZRegisterInfo.h"
00019 #include "llvm/Target/TargetInstrInfo.h"
00020 
00021 #define GET_INSTRINFO_HEADER
00022 #include "SystemZGenInstrInfo.inc"
00023 
00024 namespace llvm {
00025 
00026 class SystemZTargetMachine;
00027 
00028 namespace SystemZII {
00029 enum {
00030   // See comments in SystemZInstrFormats.td.
00031   SimpleBDXLoad          = (1 << 0),
00032   SimpleBDXStore         = (1 << 1),
00033   Has20BitOffset         = (1 << 2),
00034   HasIndex               = (1 << 3),
00035   Is128Bit               = (1 << 4),
00036   AccessSizeMask         = (31 << 5),
00037   AccessSizeShift        = 5,
00038   CCValuesMask           = (15 << 10),
00039   CCValuesShift          = 10,
00040   CompareZeroCCMaskMask  = (15 << 14),
00041   CompareZeroCCMaskShift = 14,
00042   CCMaskFirst            = (1 << 18),
00043   CCMaskLast             = (1 << 19),
00044   IsLogical              = (1 << 20)
00045 };
00046 static inline unsigned getAccessSize(unsigned int Flags) {
00047   return (Flags & AccessSizeMask) >> AccessSizeShift;
00048 }
00049 static inline unsigned getCCValues(unsigned int Flags) {
00050   return (Flags & CCValuesMask) >> CCValuesShift;
00051 }
00052 static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
00053   return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
00054 }
00055 
00056 // SystemZ MachineOperand target flags.
00057 enum {
00058   // Masks out the bits for the access model.
00059   MO_SYMBOL_MODIFIER = (1 << 0),
00060 
00061   // @GOT (aka @GOTENT)
00062   MO_GOT = (1 << 0)
00063 };
00064 // Classifies a branch.
00065 enum BranchType {
00066   // An instruction that branches on the current value of CC.
00067   BranchNormal,
00068 
00069   // An instruction that peforms a 32-bit signed comparison and branches
00070   // on the result.
00071   BranchC,
00072 
00073   // An instruction that peforms a 32-bit unsigned comparison and branches
00074   // on the result.
00075   BranchCL,
00076 
00077   // An instruction that peforms a 64-bit signed comparison and branches
00078   // on the result.
00079   BranchCG,
00080 
00081   // An instruction that peforms a 64-bit unsigned comparison and branches
00082   // on the result.
00083   BranchCLG,
00084 
00085   // An instruction that decrements a 32-bit register and branches if
00086   // the result is nonzero.
00087   BranchCT,
00088 
00089   // An instruction that decrements a 64-bit register and branches if
00090   // the result is nonzero.
00091   BranchCTG
00092 };
00093 // Information about a branch instruction.
00094 struct Branch {
00095   // The type of the branch.
00096   BranchType Type;
00097 
00098   // CCMASK_<N> is set if CC might be equal to N.
00099   unsigned CCValid;
00100 
00101   // CCMASK_<N> is set if the branch should be taken when CC == N.
00102   unsigned CCMask;
00103 
00104   // The target of the branch.
00105   const MachineOperand *Target;
00106 
00107   Branch(BranchType type, unsigned ccValid, unsigned ccMask,
00108          const MachineOperand *target)
00109     : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
00110 };
00111 } // end namespace SystemZII
00112 
00113 class SystemZSubtarget;
00114 class SystemZInstrInfo : public SystemZGenInstrInfo {
00115   const SystemZRegisterInfo RI;
00116   SystemZSubtarget &STI;
00117 
00118   void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
00119   void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
00120   void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode,
00121                       unsigned HighOpcode, bool ConvertHigh) const;
00122   void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode,
00123                        unsigned LowOpcodeK, unsigned HighOpcode) const;
00124   void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode,
00125                        unsigned HighOpcode) const;
00126   void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode,
00127                         unsigned Size) const;
00128   void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
00129                      DebugLoc DL, unsigned DestReg, unsigned SrcReg,
00130                      unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
00131   virtual void anchor();
00132   
00133 public:
00134   explicit SystemZInstrInfo(SystemZSubtarget &STI);
00135 
00136   // Override TargetInstrInfo.
00137   unsigned isLoadFromStackSlot(const MachineInstr *MI,
00138                                int &FrameIndex) const override;
00139   unsigned isStoreToStackSlot(const MachineInstr *MI,
00140                               int &FrameIndex) const override;
00141   bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
00142                        int &SrcFrameIndex) const override;
00143   bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
00144                      MachineBasicBlock *&FBB,
00145                      SmallVectorImpl<MachineOperand> &Cond,
00146                      bool AllowModify) const override;
00147   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
00148   unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
00149                         MachineBasicBlock *FBB,
00150                         const SmallVectorImpl<MachineOperand> &Cond,
00151                         DebugLoc DL) const override;
00152   bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
00153                       unsigned &SrcReg2, int &Mask, int &Value) const override;
00154   bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
00155                             unsigned SrcReg2, int Mask, int Value,
00156                             const MachineRegisterInfo *MRI) const override;
00157   bool isPredicable(MachineInstr *MI) const override;
00158   bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
00159                            unsigned ExtraPredCycles,
00160                            const BranchProbability &Probability) const override;
00161   bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
00162                            unsigned NumCyclesT, unsigned ExtraPredCyclesT,
00163                            MachineBasicBlock &FMBB,
00164                            unsigned NumCyclesF, unsigned ExtraPredCyclesF,
00165                            const BranchProbability &Probability) const override;
00166   bool PredicateInstruction(MachineInstr *MI,
00167                             const SmallVectorImpl<MachineOperand> &Pred) const
00168     override;
00169   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
00170                    DebugLoc DL, unsigned DestReg, unsigned SrcReg,
00171                    bool KillSrc) const override;
00172   void storeRegToStackSlot(MachineBasicBlock &MBB,
00173                            MachineBasicBlock::iterator MBBI,
00174                            unsigned SrcReg, bool isKill, int FrameIndex,
00175                            const TargetRegisterClass *RC,
00176                            const TargetRegisterInfo *TRI) const override;
00177   void loadRegFromStackSlot(MachineBasicBlock &MBB,
00178                             MachineBasicBlock::iterator MBBI,
00179                             unsigned DestReg, int FrameIdx,
00180                             const TargetRegisterClass *RC,
00181                             const TargetRegisterInfo *TRI) const override;
00182   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
00183                                       MachineBasicBlock::iterator &MBBI,
00184                                       LiveVariables *LV) const override;
00185   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
00186                                       const SmallVectorImpl<unsigned> &Ops,
00187                                       int FrameIndex) const override;
00188   MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
00189                                       const SmallVectorImpl<unsigned> &Ops,
00190                                       MachineInstr* LoadMI) const override;
00191   bool expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const override;
00192   bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
00193     override;
00194 
00195   // Return the SystemZRegisterInfo, which this class owns.
00196   const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
00197 
00198   // Return the size in bytes of MI.
00199   uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
00200 
00201   // Return true if MI is a conditional or unconditional branch.
00202   // When returning true, set Cond to the mask of condition-code
00203   // values on which the instruction will branch, and set Target
00204   // to the operand that contains the branch target.  This target
00205   // can be a register or a basic block.
00206   SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
00207 
00208   // Get the load and store opcodes for a given register class.
00209   void getLoadStoreOpcodes(const TargetRegisterClass *RC,
00210                            unsigned &LoadOpcode, unsigned &StoreOpcode) const;
00211 
00212   // Opcode is the opcode of an instruction that has an address operand,
00213   // and the caller wants to perform that instruction's operation on an
00214   // address that has displacement Offset.  Return the opcode of a suitable
00215   // instruction (which might be Opcode itself) or 0 if no such instruction
00216   // exists.
00217   unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
00218 
00219   // If Opcode is a load instruction that has a LOAD AND TEST form,
00220   // return the opcode for the testing form, otherwise return 0.
00221   unsigned getLoadAndTest(unsigned Opcode) const;
00222 
00223   // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
00224   // Mask of the R2 operand, given that only the low BitSize bits of Mask are
00225   // significant.  Set Start and End to the I3 and I4 operands if so.
00226   bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
00227                    unsigned &Start, unsigned &End) const;
00228 
00229   // If Opcode is a COMPARE opcode for which an associated COMPARE AND
00230   // BRANCH exists, return the opcode for the latter, otherwise return 0.
00231   // MI, if nonnull, is the compare instruction.
00232   unsigned getCompareAndBranch(unsigned Opcode,
00233                                const MachineInstr *MI = nullptr) const;
00234 
00235   // Emit code before MBBI in MI to move immediate value Value into
00236   // physical register Reg.
00237   void loadImmediate(MachineBasicBlock &MBB,
00238                      MachineBasicBlock::iterator MBBI,
00239                      unsigned Reg, uint64_t Value) const;
00240 };
00241 } // end namespace llvm
00242 
00243 #endif