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