SystemZInstrInfo.h revision b21ab43cfc3fa0dacf5c95f04e58b6d804b59a16
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
24namespace llvm {
25
26class SystemZTargetMachine;
27
28namespace 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}
112
113class SystemZInstrInfo : public SystemZGenInstrInfo {
114  const SystemZRegisterInfo RI;
115  SystemZTargetMachine &TM;
116
117  void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
118  void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
119  void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode,
120                      unsigned HighOpcode, bool ConvertHigh) const;
121  void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode,
122                       unsigned LowOpcodeK, unsigned HighOpcode) const;
123  void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode,
124                       unsigned HighOpcode) const;
125  void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode,
126                        unsigned Size) const;
127  void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
128                     DebugLoc DL, unsigned DestReg, unsigned SrcReg,
129                     unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
130
131public:
132  explicit SystemZInstrInfo(SystemZTargetMachine &TM);
133
134  // Override TargetInstrInfo.
135  virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
136                                       int &FrameIndex) const LLVM_OVERRIDE;
137  virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
138                                      int &FrameIndex) const LLVM_OVERRIDE;
139  virtual bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
140                               int &SrcFrameIndex) const LLVM_OVERRIDE;
141  virtual bool AnalyzeBranch(MachineBasicBlock &MBB,
142                             MachineBasicBlock *&TBB,
143                             MachineBasicBlock *&FBB,
144                             SmallVectorImpl<MachineOperand> &Cond,
145                             bool AllowModify) const LLVM_OVERRIDE;
146  virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const LLVM_OVERRIDE;
147  virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
148                                MachineBasicBlock *FBB,
149                                const SmallVectorImpl<MachineOperand> &Cond,
150                                DebugLoc DL) const LLVM_OVERRIDE;
151  bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
152                      unsigned &SrcReg2, int &Mask, int &Value) const
153    LLVM_OVERRIDE;
154  bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
155                            unsigned SrcReg2, int Mask, int Value,
156                            const MachineRegisterInfo *MRI) const LLVM_OVERRIDE;
157  virtual bool isPredicable(MachineInstr *MI) const LLVM_OVERRIDE;
158  virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
159                                   unsigned ExtraPredCycles,
160                                   const BranchProbability &Probability) const
161    LLVM_OVERRIDE;
162  virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
163                                   unsigned NumCyclesT,
164                                   unsigned ExtraPredCyclesT,
165                                   MachineBasicBlock &FMBB,
166                                   unsigned NumCyclesF,
167                                   unsigned ExtraPredCyclesF,
168                                   const BranchProbability &Probability) const
169    LLVM_OVERRIDE;
170  virtual bool
171    PredicateInstruction(MachineInstr *MI,
172                         const SmallVectorImpl<MachineOperand> &Pred) const
173    LLVM_OVERRIDE;
174  virtual void copyPhysReg(MachineBasicBlock &MBB,
175                           MachineBasicBlock::iterator MBBI, DebugLoc DL,
176                           unsigned DestReg, unsigned SrcReg,
177                           bool KillSrc) const LLVM_OVERRIDE;
178  virtual void
179    storeRegToStackSlot(MachineBasicBlock &MBB,
180                        MachineBasicBlock::iterator MBBI,
181                        unsigned SrcReg, bool isKill, int FrameIndex,
182                        const TargetRegisterClass *RC,
183                        const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
184  virtual void
185    loadRegFromStackSlot(MachineBasicBlock &MBB,
186                         MachineBasicBlock::iterator MBBI,
187                         unsigned DestReg, int FrameIdx,
188                         const TargetRegisterClass *RC,
189                         const TargetRegisterInfo *TRI) const LLVM_OVERRIDE;
190  virtual MachineInstr *
191    convertToThreeAddress(MachineFunction::iterator &MFI,
192                          MachineBasicBlock::iterator &MBBI,
193                          LiveVariables *LV) const;
194  virtual MachineInstr *
195    foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
196                          const SmallVectorImpl<unsigned> &Ops,
197                          int FrameIndex) const;
198  virtual MachineInstr *
199    foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
200                          const SmallVectorImpl<unsigned> &Ops,
201                          MachineInstr* LoadMI) const;
202  virtual bool
203    expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const LLVM_OVERRIDE;
204  virtual bool
205    ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
206    LLVM_OVERRIDE;
207
208  // Return the SystemZRegisterInfo, which this class owns.
209  const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
210
211  // Return the size in bytes of MI.
212  uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
213
214  // Return true if MI is a conditional or unconditional branch.
215  // When returning true, set Cond to the mask of condition-code
216  // values on which the instruction will branch, and set Target
217  // to the operand that contains the branch target.  This target
218  // can be a register or a basic block.
219  SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
220
221  // Get the load and store opcodes for a given register class.
222  void getLoadStoreOpcodes(const TargetRegisterClass *RC,
223                           unsigned &LoadOpcode, unsigned &StoreOpcode) const;
224
225  // Opcode is the opcode of an instruction that has an address operand,
226  // and the caller wants to perform that instruction's operation on an
227  // address that has displacement Offset.  Return the opcode of a suitable
228  // instruction (which might be Opcode itself) or 0 if no such instruction
229  // exists.
230  unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
231
232  // If Opcode is a load instruction that has a LOAD AND TEST form,
233  // return the opcode for the testing form, otherwise return 0.
234  unsigned getLoadAndTest(unsigned Opcode) const;
235
236  // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
237  // Mask of the R2 operand, given that only the low BitSize bits of Mask are
238  // significant.  Set Start and End to the I3 and I4 operands if so.
239  bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
240                   unsigned &Start, unsigned &End) const;
241
242  // If Opcode is a COMPARE opcode for which an associated COMPARE AND
243  // BRANCH exists, return the opcode for the latter, otherwise return 0.
244  // MI, if nonnull, is the compare instruction.
245  unsigned getCompareAndBranch(unsigned Opcode,
246                               const MachineInstr *MI = 0) const;
247
248  // Emit code before MBBI in MI to move immediate value Value into
249  // physical register Reg.
250  void loadImmediate(MachineBasicBlock &MBB,
251                     MachineBasicBlock::iterator MBBI,
252                     unsigned Reg, uint64_t Value) const;
253};
254} // end namespace llvm
255
256#endif
257