SystemZInstrInfo.h revision 280031
1251607Sdim//===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
2251607Sdim//
3251607Sdim//                     The LLVM Compiler Infrastructure
4251607Sdim//
5251607Sdim// This file is distributed under the University of Illinois Open Source
6251607Sdim// License. See LICENSE.TXT for details.
7251607Sdim//
8251607Sdim//===----------------------------------------------------------------------===//
9251607Sdim//
10251607Sdim// This file contains the SystemZ implementation of the TargetInstrInfo class.
11251607Sdim//
12251607Sdim//===----------------------------------------------------------------------===//
13251607Sdim
14280031Sdim#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
15280031Sdim#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
16251607Sdim
17251607Sdim#include "SystemZ.h"
18251607Sdim#include "SystemZRegisterInfo.h"
19251607Sdim#include "llvm/Target/TargetInstrInfo.h"
20251607Sdim
21251607Sdim#define GET_INSTRINFO_HEADER
22251607Sdim#include "SystemZGenInstrInfo.inc"
23251607Sdim
24251607Sdimnamespace llvm {
25251607Sdim
26251607Sdimclass SystemZTargetMachine;
27251607Sdim
28251607Sdimnamespace SystemZII {
29276479Sdimenum {
30276479Sdim  // See comments in SystemZInstrFormats.td.
31276479Sdim  SimpleBDXLoad          = (1 << 0),
32276479Sdim  SimpleBDXStore         = (1 << 1),
33276479Sdim  Has20BitOffset         = (1 << 2),
34276479Sdim  HasIndex               = (1 << 3),
35276479Sdim  Is128Bit               = (1 << 4),
36276479Sdim  AccessSizeMask         = (31 << 5),
37276479Sdim  AccessSizeShift        = 5,
38276479Sdim  CCValuesMask           = (15 << 10),
39276479Sdim  CCValuesShift          = 10,
40276479Sdim  CompareZeroCCMaskMask  = (15 << 14),
41276479Sdim  CompareZeroCCMaskShift = 14,
42276479Sdim  CCMaskFirst            = (1 << 18),
43276479Sdim  CCMaskLast             = (1 << 19),
44276479Sdim  IsLogical              = (1 << 20)
45276479Sdim};
46276479Sdimstatic inline unsigned getAccessSize(unsigned int Flags) {
47276479Sdim  return (Flags & AccessSizeMask) >> AccessSizeShift;
48276479Sdim}
49276479Sdimstatic inline unsigned getCCValues(unsigned int Flags) {
50276479Sdim  return (Flags & CCValuesMask) >> CCValuesShift;
51276479Sdim}
52276479Sdimstatic inline unsigned getCompareZeroCCMask(unsigned int Flags) {
53276479Sdim  return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
54276479Sdim}
55261991Sdim
56276479Sdim// SystemZ MachineOperand target flags.
57276479Sdimenum {
58276479Sdim  // Masks out the bits for the access model.
59276479Sdim  MO_SYMBOL_MODIFIER = (1 << 0),
60251607Sdim
61276479Sdim  // @GOT (aka @GOTENT)
62276479Sdim  MO_GOT = (1 << 0)
63276479Sdim};
64276479Sdim// Classifies a branch.
65276479Sdimenum BranchType {
66276479Sdim  // An instruction that branches on the current value of CC.
67276479Sdim  BranchNormal,
68261991Sdim
69276479Sdim  // An instruction that peforms a 32-bit signed comparison and branches
70276479Sdim  // on the result.
71276479Sdim  BranchC,
72261991Sdim
73276479Sdim  // An instruction that peforms a 32-bit unsigned comparison and branches
74276479Sdim  // on the result.
75276479Sdim  BranchCL,
76261991Sdim
77276479Sdim  // An instruction that peforms a 64-bit signed comparison and branches
78276479Sdim  // on the result.
79276479Sdim  BranchCG,
80261991Sdim
81276479Sdim  // An instruction that peforms a 64-bit unsigned comparison and branches
82276479Sdim  // on the result.
83276479Sdim  BranchCLG,
84261991Sdim
85276479Sdim  // An instruction that decrements a 32-bit register and branches if
86276479Sdim  // the result is nonzero.
87276479Sdim  BranchCT,
88261991Sdim
89276479Sdim  // An instruction that decrements a 64-bit register and branches if
90276479Sdim  // the result is nonzero.
91276479Sdim  BranchCTG
92276479Sdim};
93276479Sdim// Information about a branch instruction.
94276479Sdimstruct Branch {
95276479Sdim  // The type of the branch.
96276479Sdim  BranchType Type;
97261991Sdim
98276479Sdim  // CCMASK_<N> is set if CC might be equal to N.
99276479Sdim  unsigned CCValid;
100261991Sdim
101276479Sdim  // CCMASK_<N> is set if the branch should be taken when CC == N.
102276479Sdim  unsigned CCMask;
103261991Sdim
104276479Sdim  // The target of the branch.
105276479Sdim  const MachineOperand *Target;
106261991Sdim
107276479Sdim  Branch(BranchType type, unsigned ccValid, unsigned ccMask,
108276479Sdim         const MachineOperand *target)
109276479Sdim    : Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
110276479Sdim};
111276479Sdim} // end namespace SystemZII
112251607Sdim
113276479Sdimclass SystemZSubtarget;
114251607Sdimclass SystemZInstrInfo : public SystemZGenInstrInfo {
115251607Sdim  const SystemZRegisterInfo RI;
116276479Sdim  SystemZSubtarget &STI;
117251607Sdim
118251607Sdim  void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
119251607Sdim  void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
120261991Sdim  void expandRIPseudo(MachineInstr *MI, unsigned LowOpcode,
121261991Sdim                      unsigned HighOpcode, bool ConvertHigh) const;
122261991Sdim  void expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode,
123261991Sdim                       unsigned LowOpcodeK, unsigned HighOpcode) const;
124261991Sdim  void expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode,
125261991Sdim                       unsigned HighOpcode) const;
126261991Sdim  void expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode,
127261991Sdim                        unsigned Size) const;
128261991Sdim  void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
129261991Sdim                     DebugLoc DL, unsigned DestReg, unsigned SrcReg,
130261991Sdim                     unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
131261991Sdim  virtual void anchor();
132261991Sdim
133251607Sdimpublic:
134276479Sdim  explicit SystemZInstrInfo(SystemZSubtarget &STI);
135251607Sdim
136251607Sdim  // Override TargetInstrInfo.
137276479Sdim  unsigned isLoadFromStackSlot(const MachineInstr *MI,
138276479Sdim                               int &FrameIndex) const override;
139276479Sdim  unsigned isStoreToStackSlot(const MachineInstr *MI,
140276479Sdim                              int &FrameIndex) const override;
141276479Sdim  bool isStackSlotCopy(const MachineInstr *MI, int &DestFrameIndex,
142276479Sdim                       int &SrcFrameIndex) const override;
143276479Sdim  bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
144276479Sdim                     MachineBasicBlock *&FBB,
145276479Sdim                     SmallVectorImpl<MachineOperand> &Cond,
146276479Sdim                     bool AllowModify) const override;
147276479Sdim  unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
148276479Sdim  unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
149276479Sdim                        MachineBasicBlock *FBB,
150276479Sdim                        const SmallVectorImpl<MachineOperand> &Cond,
151276479Sdim                        DebugLoc DL) const override;
152261991Sdim  bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
153276479Sdim                      unsigned &SrcReg2, int &Mask, int &Value) const override;
154261991Sdim  bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
155261991Sdim                            unsigned SrcReg2, int Mask, int Value,
156276479Sdim                            const MachineRegisterInfo *MRI) const override;
157276479Sdim  bool isPredicable(MachineInstr *MI) const override;
158276479Sdim  bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
159276479Sdim                           unsigned ExtraPredCycles,
160276479Sdim                           const BranchProbability &Probability) const override;
161276479Sdim  bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
162276479Sdim                           unsigned NumCyclesT, unsigned ExtraPredCyclesT,
163276479Sdim                           MachineBasicBlock &FMBB,
164276479Sdim                           unsigned NumCyclesF, unsigned ExtraPredCyclesF,
165276479Sdim                           const BranchProbability &Probability) const override;
166276479Sdim  bool PredicateInstruction(MachineInstr *MI,
167276479Sdim                            const SmallVectorImpl<MachineOperand> &Pred) const
168276479Sdim    override;
169276479Sdim  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
170276479Sdim                   DebugLoc DL, unsigned DestReg, unsigned SrcReg,
171276479Sdim                   bool KillSrc) const override;
172276479Sdim  void storeRegToStackSlot(MachineBasicBlock &MBB,
173276479Sdim                           MachineBasicBlock::iterator MBBI,
174276479Sdim                           unsigned SrcReg, bool isKill, int FrameIndex,
175276479Sdim                           const TargetRegisterClass *RC,
176276479Sdim                           const TargetRegisterInfo *TRI) const override;
177276479Sdim  void loadRegFromStackSlot(MachineBasicBlock &MBB,
178276479Sdim                            MachineBasicBlock::iterator MBBI,
179276479Sdim                            unsigned DestReg, int FrameIdx,
180276479Sdim                            const TargetRegisterClass *RC,
181276479Sdim                            const TargetRegisterInfo *TRI) const override;
182276479Sdim  MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
183276479Sdim                                      MachineBasicBlock::iterator &MBBI,
184276479Sdim                                      LiveVariables *LV) const override;
185276479Sdim  MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
186276479Sdim                                      const SmallVectorImpl<unsigned> &Ops,
187276479Sdim                                      int FrameIndex) const override;
188276479Sdim  MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI,
189276479Sdim                                      const SmallVectorImpl<unsigned> &Ops,
190276479Sdim                                      MachineInstr* LoadMI) const override;
191276479Sdim  bool expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const override;
192276479Sdim  bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
193276479Sdim    override;
194251607Sdim
195251607Sdim  // Return the SystemZRegisterInfo, which this class owns.
196251607Sdim  const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
197251607Sdim
198261991Sdim  // Return the size in bytes of MI.
199261991Sdim  uint64_t getInstSizeInBytes(const MachineInstr *MI) const;
200261991Sdim
201251607Sdim  // Return true if MI is a conditional or unconditional branch.
202251607Sdim  // When returning true, set Cond to the mask of condition-code
203251607Sdim  // values on which the instruction will branch, and set Target
204251607Sdim  // to the operand that contains the branch target.  This target
205251607Sdim  // can be a register or a basic block.
206261991Sdim  SystemZII::Branch getBranchInfo(const MachineInstr *MI) const;
207251607Sdim
208251607Sdim  // Get the load and store opcodes for a given register class.
209251607Sdim  void getLoadStoreOpcodes(const TargetRegisterClass *RC,
210251607Sdim                           unsigned &LoadOpcode, unsigned &StoreOpcode) const;
211251607Sdim
212251607Sdim  // Opcode is the opcode of an instruction that has an address operand,
213251607Sdim  // and the caller wants to perform that instruction's operation on an
214251607Sdim  // address that has displacement Offset.  Return the opcode of a suitable
215251607Sdim  // instruction (which might be Opcode itself) or 0 if no such instruction
216251607Sdim  // exists.
217251607Sdim  unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const;
218251607Sdim
219261991Sdim  // If Opcode is a load instruction that has a LOAD AND TEST form,
220261991Sdim  // return the opcode for the testing form, otherwise return 0.
221261991Sdim  unsigned getLoadAndTest(unsigned Opcode) const;
222261991Sdim
223261991Sdim  // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
224261991Sdim  // Mask of the R2 operand, given that only the low BitSize bits of Mask are
225261991Sdim  // significant.  Set Start and End to the I3 and I4 operands if so.
226261991Sdim  bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
227261991Sdim                   unsigned &Start, unsigned &End) const;
228261991Sdim
229261991Sdim  // If Opcode is a COMPARE opcode for which an associated COMPARE AND
230261991Sdim  // BRANCH exists, return the opcode for the latter, otherwise return 0.
231261991Sdim  // MI, if nonnull, is the compare instruction.
232261991Sdim  unsigned getCompareAndBranch(unsigned Opcode,
233276479Sdim                               const MachineInstr *MI = nullptr) const;
234261991Sdim
235251607Sdim  // Emit code before MBBI in MI to move immediate value Value into
236251607Sdim  // physical register Reg.
237251607Sdim  void loadImmediate(MachineBasicBlock &MBB,
238251607Sdim                     MachineBasicBlock::iterator MBBI,
239251607Sdim                     unsigned Reg, uint64_t Value) const;
240251607Sdim};
241251607Sdim} // end namespace llvm
242251607Sdim
243251607Sdim#endif
244