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