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