/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- SystemZInstrInfo.cpp - SystemZ instruction information ------------===// |
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 | | #include "SystemZInstrInfo.h" |
15 | | #include "MCTargetDesc/SystemZMCTargetDesc.h" |
16 | | #include "SystemZ.h" |
17 | | #include "SystemZInstrBuilder.h" |
18 | | #include "SystemZSubtarget.h" |
19 | | #include "llvm/CodeGen/LiveInterval.h" |
20 | | #include "llvm/CodeGen/LiveIntervalAnalysis.h" |
21 | | #include "llvm/CodeGen/LiveVariables.h" |
22 | | #include "llvm/CodeGen/MachineBasicBlock.h" |
23 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
24 | | #include "llvm/CodeGen/MachineFunction.h" |
25 | | #include "llvm/CodeGen/MachineInstr.h" |
26 | | #include "llvm/CodeGen/MachineMemOperand.h" |
27 | | #include "llvm/CodeGen/MachineOperand.h" |
28 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
29 | | #include "llvm/CodeGen/SlotIndexes.h" |
30 | | #include "llvm/MC/MCInstrDesc.h" |
31 | | #include "llvm/MC/MCRegisterInfo.h" |
32 | | #include "llvm/Support/BranchProbability.h" |
33 | | #include "llvm/Support/ErrorHandling.h" |
34 | | #include "llvm/Support/MathExtras.h" |
35 | | #include "llvm/Target/TargetInstrInfo.h" |
36 | | #include "llvm/Target/TargetMachine.h" |
37 | | #include "llvm/Target/TargetSubtargetInfo.h" |
38 | | #include <cassert> |
39 | | #include <cstdint> |
40 | | #include <iterator> |
41 | | |
42 | | using namespace llvm; |
43 | | |
44 | | #define GET_INSTRINFO_CTOR_DTOR |
45 | | #define GET_INSTRMAP_INFO |
46 | | #include "SystemZGenInstrInfo.inc" |
47 | | |
48 | | // Return a mask with Count low bits set. |
49 | 3.69k | static uint64_t allOnes(unsigned int Count) { |
50 | 3.69k | return Count == 0 ? 00 : (uint64_t(1) << (Count - 1) << 1) - 13.69k ; |
51 | 3.69k | } |
52 | | |
53 | | // Reg should be a 32-bit GPR. Return true if it is a high register rather |
54 | | // than a low register. |
55 | 1.84k | static bool isHighReg(unsigned int Reg) { |
56 | 1.84k | if (SystemZ::GRH32BitRegClass.contains(Reg)) |
57 | 262 | return true; |
58 | 1.84k | assert(SystemZ::GR32BitRegClass.contains(Reg) && "Invalid GRX32"); |
59 | 1.57k | return false; |
60 | 1.57k | } |
61 | | |
62 | | // Pin the vtable to this file. |
63 | 0 | void SystemZInstrInfo::anchor() {} |
64 | | |
65 | | SystemZInstrInfo::SystemZInstrInfo(SystemZSubtarget &sti) |
66 | | : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), |
67 | 857 | RI(), STI(sti) { |
68 | 857 | } |
69 | | |
70 | | // MI is a 128-bit load or store. Split it into two 64-bit loads or stores, |
71 | | // each having the opcode given by NewOpcode. |
72 | | void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, |
73 | 440 | unsigned NewOpcode) const { |
74 | 440 | MachineBasicBlock *MBB = MI->getParent(); |
75 | 440 | MachineFunction &MF = *MBB->getParent(); |
76 | 440 | |
77 | 440 | // Get two load or store instructions. Use the original instruction for one |
78 | 440 | // of them (arbitrarily the second here) and create a clone for the other. |
79 | 440 | MachineInstr *EarlierMI = MF.CloneMachineInstr(&*MI); |
80 | 440 | MBB->insert(MI, EarlierMI); |
81 | 440 | |
82 | 440 | // Set up the two 64-bit registers and remember super reg and its flags. |
83 | 440 | MachineOperand &HighRegOp = EarlierMI->getOperand(0); |
84 | 440 | MachineOperand &LowRegOp = MI->getOperand(0); |
85 | 440 | unsigned Reg128 = LowRegOp.getReg(); |
86 | 440 | unsigned Reg128Killed = getKillRegState(LowRegOp.isKill()); |
87 | 440 | unsigned Reg128Undef = getUndefRegState(LowRegOp.isUndef()); |
88 | 440 | HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_h64)); |
89 | 440 | LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_l64)); |
90 | 440 | |
91 | 440 | if (MI->mayStore()440 ) { |
92 | 256 | // Add implicit uses of the super register in case one of the subregs is |
93 | 256 | // undefined. We could track liveness and skip storing an undefined |
94 | 256 | // subreg, but this is hopefully rare (discovered with llvm-stress). |
95 | 256 | // If Reg128 was killed, set kill flag on MI. |
96 | 256 | unsigned Reg128UndefImpl = (Reg128Undef | RegState::Implicit); |
97 | 256 | MachineInstrBuilder(MF, EarlierMI).addReg(Reg128, Reg128UndefImpl); |
98 | 256 | MachineInstrBuilder(MF, MI).addReg(Reg128, (Reg128UndefImpl | Reg128Killed)); |
99 | 256 | } |
100 | 440 | |
101 | 440 | // The address in the first (high) instruction is already correct. |
102 | 440 | // Adjust the offset in the second (low) instruction. |
103 | 440 | MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); |
104 | 440 | MachineOperand &LowOffsetOp = MI->getOperand(2); |
105 | 440 | LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); |
106 | 440 | |
107 | 440 | // Clear the kill flags on the registers in the first instruction. |
108 | 440 | if (EarlierMI->getOperand(0).isReg() && 440 EarlierMI->getOperand(0).isUse()440 ) |
109 | 256 | EarlierMI->getOperand(0).setIsKill(false); |
110 | 440 | EarlierMI->getOperand(1).setIsKill(false); |
111 | 440 | EarlierMI->getOperand(3).setIsKill(false); |
112 | 440 | |
113 | 440 | // Set the opcodes. |
114 | 440 | unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); |
115 | 440 | unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); |
116 | 440 | assert(HighOpcode && LowOpcode && "Both offsets should be in range"); |
117 | 440 | |
118 | 440 | EarlierMI->setDesc(get(HighOpcode)); |
119 | 440 | MI->setDesc(get(LowOpcode)); |
120 | 440 | } |
121 | | |
122 | | // Split ADJDYNALLOC instruction MI. |
123 | 45 | void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { |
124 | 45 | MachineBasicBlock *MBB = MI->getParent(); |
125 | 45 | MachineFunction &MF = *MBB->getParent(); |
126 | 45 | MachineFrameInfo &MFFrame = MF.getFrameInfo(); |
127 | 45 | MachineOperand &OffsetMO = MI->getOperand(2); |
128 | 45 | |
129 | 45 | uint64_t Offset = (MFFrame.getMaxCallFrameSize() + |
130 | 45 | SystemZMC::CallFrameSize + |
131 | 45 | OffsetMO.getImm()); |
132 | 45 | unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); |
133 | 45 | assert(NewOpcode && "No support for huge argument lists yet"); |
134 | 45 | MI->setDesc(get(NewOpcode)); |
135 | 45 | OffsetMO.setImm(Offset); |
136 | 45 | } |
137 | | |
138 | | // MI is an RI-style pseudo instruction. Replace it with LowOpcode |
139 | | // if the first operand is a low GR32 and HighOpcode if the first operand |
140 | | // is a high GR32. ConvertHigh is true if LowOpcode takes a signed operand |
141 | | // and HighOpcode takes an unsigned 32-bit operand. In those cases, |
142 | | // MI has the same kind of operand as LowOpcode, so needs to be converted |
143 | | // if HighOpcode is used. |
144 | | void SystemZInstrInfo::expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, |
145 | | unsigned HighOpcode, |
146 | 491 | bool ConvertHigh) const { |
147 | 491 | unsigned Reg = MI.getOperand(0).getReg(); |
148 | 491 | bool IsHigh = isHighReg(Reg); |
149 | 491 | MI.setDesc(get(IsHigh ? HighOpcode62 : LowOpcode429 )); |
150 | 491 | if (IsHigh && 491 ConvertHigh62 ) |
151 | 14 | MI.getOperand(1).setImm(uint32_t(MI.getOperand(1).getImm())); |
152 | 491 | } |
153 | | |
154 | | // MI is a three-operand RIE-style pseudo instruction. Replace it with |
155 | | // LowOpcodeK if the registers are both low GR32s, otherwise use a move |
156 | | // followed by HighOpcode or LowOpcode, depending on whether the target |
157 | | // is a high or low GR32. |
158 | | void SystemZInstrInfo::expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode, |
159 | | unsigned LowOpcodeK, |
160 | 9 | unsigned HighOpcode) const { |
161 | 9 | unsigned DestReg = MI.getOperand(0).getReg(); |
162 | 9 | unsigned SrcReg = MI.getOperand(1).getReg(); |
163 | 9 | bool DestIsHigh = isHighReg(DestReg); |
164 | 9 | bool SrcIsHigh = isHighReg(SrcReg); |
165 | 9 | if (!DestIsHigh && 9 !SrcIsHigh8 ) |
166 | 7 | MI.setDesc(get(LowOpcodeK)); |
167 | 2 | else { |
168 | 2 | emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(), DestReg, SrcReg, |
169 | 2 | SystemZ::LR, 32, MI.getOperand(1).isKill(), |
170 | 2 | MI.getOperand(1).isUndef()); |
171 | 2 | MI.setDesc(get(DestIsHigh ? HighOpcode1 : LowOpcode1 )); |
172 | 2 | MI.getOperand(1).setReg(DestReg); |
173 | 2 | MI.tieOperands(0, 1); |
174 | 2 | } |
175 | 9 | } |
176 | | |
177 | | // MI is an RXY-style pseudo instruction. Replace it with LowOpcode |
178 | | // if the first operand is a low GR32 and HighOpcode if the first operand |
179 | | // is a high GR32. |
180 | | void SystemZInstrInfo::expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode, |
181 | 476 | unsigned HighOpcode) const { |
182 | 476 | unsigned Reg = MI.getOperand(0).getReg(); |
183 | 476 | unsigned Opcode = getOpcodeForOffset(isHighReg(Reg) ? HighOpcode104 : LowOpcode372 , |
184 | 476 | MI.getOperand(2).getImm()); |
185 | 476 | MI.setDesc(get(Opcode)); |
186 | 476 | } |
187 | | |
188 | | // MI is a load-on-condition pseudo instruction with a single register |
189 | | // (source or destination) operand. Replace it with LowOpcode if the |
190 | | // register is a low GR32 and HighOpcode if the register is a high GR32. |
191 | | void SystemZInstrInfo::expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode, |
192 | 42 | unsigned HighOpcode) const { |
193 | 42 | unsigned Reg = MI.getOperand(0).getReg(); |
194 | 42 | unsigned Opcode = isHighReg(Reg) ? HighOpcode19 : LowOpcode23 ; |
195 | 42 | MI.setDesc(get(Opcode)); |
196 | 42 | } |
197 | | |
198 | | // MI is a load-register-on-condition pseudo instruction. Replace it with |
199 | | // LowOpcode if source and destination are both low GR32s and HighOpcode if |
200 | | // source and destination are both high GR32s. |
201 | | void SystemZInstrInfo::expandLOCRPseudo(MachineInstr &MI, unsigned LowOpcode, |
202 | 13 | unsigned HighOpcode) const { |
203 | 13 | unsigned DestReg = MI.getOperand(0).getReg(); |
204 | 13 | unsigned SrcReg = MI.getOperand(2).getReg(); |
205 | 13 | bool DestIsHigh = isHighReg(DestReg); |
206 | 13 | bool SrcIsHigh = isHighReg(SrcReg); |
207 | 13 | |
208 | 13 | if (!DestIsHigh && 13 !SrcIsHigh8 ) |
209 | 6 | MI.setDesc(get(LowOpcode)); |
210 | 7 | else if (7 DestIsHigh && 7 SrcIsHigh5 ) |
211 | 3 | MI.setDesc(get(HighOpcode)); |
212 | 13 | |
213 | 13 | // If we were unable to implement the pseudo with a single instruction, we |
214 | 13 | // need to convert it back into a branch sequence. This cannot be done here |
215 | 13 | // since the caller of expandPostRAPseudo does not handle changes to the CFG |
216 | 13 | // correctly. This change is defered to the SystemZExpandPseudo pass. |
217 | 13 | } |
218 | | |
219 | | // MI is an RR-style pseudo instruction that zero-extends the low Size bits |
220 | | // of one GRX32 into another. Replace it with LowOpcode if both operands |
221 | | // are low registers, otherwise use RISB[LH]G. |
222 | | void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode, |
223 | 78 | unsigned Size) const { |
224 | 78 | MachineInstrBuilder MIB = |
225 | 78 | emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(), |
226 | 78 | MI.getOperand(0).getReg(), MI.getOperand(1).getReg(), LowOpcode, |
227 | 78 | Size, MI.getOperand(1).isKill(), MI.getOperand(1).isUndef()); |
228 | 78 | |
229 | 78 | // Keep the remaining operands as-is. |
230 | 85 | for (unsigned I = 2; I < MI.getNumOperands()85 ; ++I7 ) |
231 | 7 | MIB.add(MI.getOperand(I)); |
232 | 78 | |
233 | 78 | MI.eraseFromParent(); |
234 | 78 | } |
235 | | |
236 | 2 | void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const { |
237 | 2 | MachineBasicBlock *MBB = MI->getParent(); |
238 | 2 | MachineFunction &MF = *MBB->getParent(); |
239 | 2 | const unsigned Reg64 = MI->getOperand(0).getReg(); |
240 | 2 | const unsigned Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32); |
241 | 2 | |
242 | 2 | // EAR can only load the low subregister so us a shift for %a0 to produce |
243 | 2 | // the GR containing %a0 and %a1. |
244 | 2 | |
245 | 2 | // ear <reg>, %a0 |
246 | 2 | BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32) |
247 | 2 | .addReg(SystemZ::A0) |
248 | 2 | .addReg(Reg64, RegState::ImplicitDefine); |
249 | 2 | |
250 | 2 | // sllg <reg>, <reg>, 32 |
251 | 2 | BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::SLLG), Reg64) |
252 | 2 | .addReg(Reg64) |
253 | 2 | .addReg(0) |
254 | 2 | .addImm(32); |
255 | 2 | |
256 | 2 | // ear <reg>, %a1 |
257 | 2 | BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32) |
258 | 2 | .addReg(SystemZ::A1); |
259 | 2 | |
260 | 2 | // lg <reg>, 40(<reg>) |
261 | 2 | MI->setDesc(get(SystemZ::LG)); |
262 | 2 | MachineInstrBuilder(MF, MI).addReg(Reg64).addImm(40).addReg(0); |
263 | 2 | } |
264 | | |
265 | | // Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR |
266 | | // DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg |
267 | | // are low registers, otherwise use RISB[LH]G. Size is the number of bits |
268 | | // taken from the low end of SrcReg (8 for LLCR, 16 for LLHR and 32 for LR). |
269 | | // KillSrc is true if this move is the last use of SrcReg. |
270 | | MachineInstrBuilder |
271 | | SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB, |
272 | | MachineBasicBlock::iterator MBBI, |
273 | | const DebugLoc &DL, unsigned DestReg, |
274 | | unsigned SrcReg, unsigned LowLowOpcode, |
275 | | unsigned Size, bool KillSrc, |
276 | 356 | bool UndefSrc) const { |
277 | 356 | unsigned Opcode; |
278 | 356 | bool DestIsHigh = isHighReg(DestReg); |
279 | 356 | bool SrcIsHigh = isHighReg(SrcReg); |
280 | 356 | if (DestIsHigh && 356 SrcIsHigh13 ) |
281 | 4 | Opcode = SystemZ::RISBHH; |
282 | 352 | else if (352 DestIsHigh && 352 !SrcIsHigh9 ) |
283 | 9 | Opcode = SystemZ::RISBHL; |
284 | 343 | else if (343 !DestIsHigh && 343 SrcIsHigh343 ) |
285 | 39 | Opcode = SystemZ::RISBLH; |
286 | 304 | else { |
287 | 304 | return BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg) |
288 | 304 | .addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc)); |
289 | 304 | } |
290 | 52 | unsigned Rotate = (DestIsHigh != SrcIsHigh ? 52 3248 : 04 ); |
291 | 356 | return BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) |
292 | 356 | .addReg(DestReg, RegState::Undef) |
293 | 356 | .addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc)) |
294 | 356 | .addImm(32 - Size).addImm(128 + 31).addImm(Rotate); |
295 | 356 | } |
296 | | |
297 | | MachineInstr *SystemZInstrInfo::commuteInstructionImpl(MachineInstr &MI, |
298 | | bool NewMI, |
299 | | unsigned OpIdx1, |
300 | 2.00k | unsigned OpIdx2) const { |
301 | 188 | auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & { |
302 | 188 | if (NewMI) |
303 | 0 | return *MI.getParent()->getParent()->CloneMachineInstr(&MI); |
304 | 188 | return MI; |
305 | 188 | }; |
306 | 2.00k | |
307 | 2.00k | switch (MI.getOpcode()) { |
308 | 188 | case SystemZ::LOCRMux: |
309 | 188 | case SystemZ::LOCFHR: |
310 | 188 | case SystemZ::LOCR: |
311 | 188 | case SystemZ::LOCGR: { |
312 | 188 | auto &WorkingMI = cloneIfNew(MI); |
313 | 188 | // Invert condition. |
314 | 188 | unsigned CCValid = WorkingMI.getOperand(3).getImm(); |
315 | 188 | unsigned CCMask = WorkingMI.getOperand(4).getImm(); |
316 | 188 | WorkingMI.getOperand(4).setImm(CCMask ^ CCValid); |
317 | 188 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, |
318 | 188 | OpIdx1, OpIdx2); |
319 | 188 | } |
320 | 1.81k | default: |
321 | 1.81k | return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2); |
322 | 0 | } |
323 | 0 | } |
324 | | |
325 | | // If MI is a simple load or store for a frame object, return the register |
326 | | // it loads or stores and set FrameIndex to the index of the frame object. |
327 | | // Return 0 otherwise. |
328 | | // |
329 | | // Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. |
330 | | static int isSimpleMove(const MachineInstr &MI, int &FrameIndex, |
331 | 12.6k | unsigned Flag) { |
332 | 12.6k | const MCInstrDesc &MCID = MI.getDesc(); |
333 | 12.6k | if ((MCID.TSFlags & Flag) && 12.6k MI.getOperand(1).isFI()542 && |
334 | 12.6k | MI.getOperand(2).getImm() == 0139 && MI.getOperand(3).getReg() == 0137 ) { |
335 | 137 | FrameIndex = MI.getOperand(1).getIndex(); |
336 | 137 | return MI.getOperand(0).getReg(); |
337 | 137 | } |
338 | 12.5k | return 0; |
339 | 12.5k | } |
340 | | |
341 | | unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, |
342 | 7.49k | int &FrameIndex) const { |
343 | 7.49k | return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); |
344 | 7.49k | } |
345 | | |
346 | | unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr &MI, |
347 | 5.18k | int &FrameIndex) const { |
348 | 5.18k | return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); |
349 | 5.18k | } |
350 | | |
351 | | bool SystemZInstrInfo::isStackSlotCopy(const MachineInstr &MI, |
352 | | int &DestFrameIndex, |
353 | 919 | int &SrcFrameIndex) const { |
354 | 919 | // Check for MVC 0(Length,FI1),0(FI2) |
355 | 919 | const MachineFrameInfo &MFI = MI.getParent()->getParent()->getFrameInfo(); |
356 | 919 | if (MI.getOpcode() != SystemZ::MVC || 919 !MI.getOperand(0).isFI()4 || |
357 | 919 | MI.getOperand(1).getImm() != 03 || !MI.getOperand(3).isFI()3 || |
358 | 2 | MI.getOperand(4).getImm() != 0) |
359 | 917 | return false; |
360 | 2 | |
361 | 2 | // Check that Length covers the full slots. |
362 | 2 | int64_t Length = MI.getOperand(2).getImm(); |
363 | 2 | unsigned FI1 = MI.getOperand(0).getIndex(); |
364 | 2 | unsigned FI2 = MI.getOperand(3).getIndex(); |
365 | 2 | if (MFI.getObjectSize(FI1) != Length || |
366 | 2 | MFI.getObjectSize(FI2) != Length) |
367 | 0 | return false; |
368 | 2 | |
369 | 2 | DestFrameIndex = FI1; |
370 | 2 | SrcFrameIndex = FI2; |
371 | 2 | return true; |
372 | 2 | } |
373 | | |
374 | | bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB, |
375 | | MachineBasicBlock *&TBB, |
376 | | MachineBasicBlock *&FBB, |
377 | | SmallVectorImpl<MachineOperand> &Cond, |
378 | 124k | bool AllowModify) const { |
379 | 124k | // Most of the code and comments here are boilerplate. |
380 | 124k | |
381 | 124k | // Start from the bottom of the block and work up, examining the |
382 | 124k | // terminator instructions. |
383 | 124k | MachineBasicBlock::iterator I = MBB.end(); |
384 | 163k | while (I != MBB.begin()163k ) { |
385 | 160k | --I; |
386 | 160k | if (I->isDebugValue()) |
387 | 0 | continue; |
388 | 160k | |
389 | 160k | // Working from the bottom, when we see a non-terminator instruction, we're |
390 | 160k | // done. |
391 | 160k | if (160k !isUnpredicatedTerminator(*I)160k ) |
392 | 66.9k | break; |
393 | 93.9k | |
394 | 93.9k | // A terminator that isn't a branch can't easily be handled by this |
395 | 93.9k | // analysis. |
396 | 93.9k | if (93.9k !I->isBranch()93.9k ) |
397 | 54.0k | return true; |
398 | 39.9k | |
399 | 39.9k | // Can't handle indirect branches. |
400 | 39.9k | SystemZII::Branch Branch(getBranchInfo(*I)); |
401 | 39.9k | if (!Branch.Target->isMBB()) |
402 | 224 | return true; |
403 | 39.7k | |
404 | 39.7k | // Punt on compound branches. |
405 | 39.7k | if (39.7k Branch.Type != SystemZII::BranchNormal39.7k ) |
406 | 110 | return true; |
407 | 39.6k | |
408 | 39.6k | if (39.6k Branch.CCMask == SystemZ::CCMASK_ANY39.6k ) { |
409 | 4.91k | // Handle unconditional branches. |
410 | 4.91k | if (!AllowModify4.91k ) { |
411 | 3.15k | TBB = Branch.Target->getMBB(); |
412 | 3.15k | continue; |
413 | 3.15k | } |
414 | 1.75k | |
415 | 1.75k | // If the block has any instructions after a JMP, delete them. |
416 | 1.75k | while (1.75k std::next(I) != MBB.end()1.75k ) |
417 | 0 | std::next(I)->eraseFromParent(); |
418 | 1.75k | |
419 | 1.75k | Cond.clear(); |
420 | 1.75k | FBB = nullptr; |
421 | 1.75k | |
422 | 1.75k | // Delete the JMP if it's equivalent to a fall-through. |
423 | 1.75k | if (MBB.isLayoutSuccessor(Branch.Target->getMBB())1.75k ) { |
424 | 542 | TBB = nullptr; |
425 | 542 | I->eraseFromParent(); |
426 | 542 | I = MBB.end(); |
427 | 542 | continue; |
428 | 542 | } |
429 | 1.21k | |
430 | 1.21k | // TBB is used to indicate the unconditinal destination. |
431 | 1.21k | TBB = Branch.Target->getMBB(); |
432 | 1.21k | continue; |
433 | 1.21k | } |
434 | 34.7k | |
435 | 34.7k | // Working from the bottom, handle the first conditional branch. |
436 | 34.7k | if (34.7k Cond.empty()34.7k ) { |
437 | 34.7k | // FIXME: add X86-style branch swap |
438 | 34.7k | FBB = TBB; |
439 | 34.7k | TBB = Branch.Target->getMBB(); |
440 | 34.7k | Cond.push_back(MachineOperand::CreateImm(Branch.CCValid)); |
441 | 34.7k | Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); |
442 | 34.7k | continue; |
443 | 34.7k | } |
444 | 0 |
|
445 | 0 | // Handle subsequent conditional branches. |
446 | 34.7k | assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch"); |
447 | 0 |
|
448 | 0 | // Only handle the case where all conditional branches branch to the same |
449 | 0 | // destination. |
450 | 0 | if (TBB != Branch.Target->getMBB()) |
451 | 0 | return true; |
452 | 0 |
|
453 | 0 | // If the conditions are the same, we can leave them alone. |
454 | 0 | unsigned OldCCValid = Cond[0].getImm(); |
455 | 0 | unsigned OldCCMask = Cond[1].getImm(); |
456 | 0 | if (OldCCValid == Branch.CCValid && 0 OldCCMask == Branch.CCMask0 ) |
457 | 0 | continue; |
458 | 0 |
|
459 | 0 | // FIXME: Try combining conditions like X86 does. Should be easy on Z! |
460 | 0 | return false; |
461 | 0 | } |
462 | 124k | |
463 | 69.6k | return false; |
464 | 124k | } |
465 | | |
466 | | unsigned SystemZInstrInfo::removeBranch(MachineBasicBlock &MBB, |
467 | 6.78k | int *BytesRemoved) const { |
468 | 6.78k | assert(!BytesRemoved && "code size not handled"); |
469 | 6.78k | |
470 | 6.78k | // Most of the code and comments here are boilerplate. |
471 | 6.78k | MachineBasicBlock::iterator I = MBB.end(); |
472 | 6.78k | unsigned Count = 0; |
473 | 6.78k | |
474 | 13.6k | while (I != MBB.begin()13.6k ) { |
475 | 13.4k | --I; |
476 | 13.4k | if (I->isDebugValue()) |
477 | 0 | continue; |
478 | 13.4k | if (13.4k !I->isBranch()13.4k ) |
479 | 6.54k | break; |
480 | 6.87k | if (6.87k !getBranchInfo(*I).Target->isMBB()6.87k ) |
481 | 0 | break; |
482 | 6.87k | // Remove the branch. |
483 | 6.87k | I->eraseFromParent(); |
484 | 6.87k | I = MBB.end(); |
485 | 6.87k | ++Count; |
486 | 6.87k | } |
487 | 6.78k | |
488 | 6.78k | return Count; |
489 | 6.78k | } |
490 | | |
491 | | bool SystemZInstrInfo:: |
492 | 8.49k | reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { |
493 | 8.49k | assert(Cond.size() == 2 && "Invalid condition"); |
494 | 8.49k | Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm()); |
495 | 8.49k | return false; |
496 | 8.49k | } |
497 | | |
498 | | unsigned SystemZInstrInfo::insertBranch(MachineBasicBlock &MBB, |
499 | | MachineBasicBlock *TBB, |
500 | | MachineBasicBlock *FBB, |
501 | | ArrayRef<MachineOperand> Cond, |
502 | | const DebugLoc &DL, |
503 | 6.04k | int *BytesAdded) const { |
504 | 6.04k | // In this function we output 32-bit branches, which should always |
505 | 6.04k | // have enough range. They can be shortened and relaxed by later code |
506 | 6.04k | // in the pipeline, if desired. |
507 | 6.04k | |
508 | 6.04k | // Shouldn't be a fall through. |
509 | 6.04k | assert(TBB && "insertBranch must not be told to insert a fallthrough"); |
510 | 6.04k | assert((Cond.size() == 2 || Cond.size() == 0) && |
511 | 6.04k | "SystemZ branch conditions have one component!"); |
512 | 6.04k | assert(!BytesAdded && "code size not handled"); |
513 | 6.04k | |
514 | 6.04k | if (Cond.empty()6.04k ) { |
515 | 493 | // Unconditional branch? |
516 | 493 | assert(!FBB && "Unconditional branch with multiple successors!"); |
517 | 493 | BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); |
518 | 493 | return 1; |
519 | 493 | } |
520 | 5.54k | |
521 | 5.54k | // Conditional branch. |
522 | 5.54k | unsigned Count = 0; |
523 | 5.54k | unsigned CCValid = Cond[0].getImm(); |
524 | 5.54k | unsigned CCMask = Cond[1].getImm(); |
525 | 5.54k | BuildMI(&MBB, DL, get(SystemZ::BRC)) |
526 | 5.54k | .addImm(CCValid).addImm(CCMask).addMBB(TBB); |
527 | 5.54k | ++Count; |
528 | 5.54k | |
529 | 5.54k | if (FBB5.54k ) { |
530 | 106 | // Two-way Conditional branch. Insert the second branch. |
531 | 106 | BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); |
532 | 106 | ++Count; |
533 | 106 | } |
534 | 6.04k | return Count; |
535 | 6.04k | } |
536 | | |
537 | | bool SystemZInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, |
538 | | unsigned &SrcReg2, int &Mask, |
539 | 1.46k | int &Value) const { |
540 | 1.46k | assert(MI.isCompare() && "Caller should have checked for a comparison"); |
541 | 1.46k | |
542 | 1.46k | if (MI.getNumExplicitOperands() == 2 && 1.46k MI.getOperand(0).isReg()1.08k && |
543 | 1.46k | MI.getOperand(1).isImm()1.08k ) { |
544 | 641 | SrcReg = MI.getOperand(0).getReg(); |
545 | 641 | SrcReg2 = 0; |
546 | 641 | Value = MI.getOperand(1).getImm(); |
547 | 641 | Mask = ~0; |
548 | 641 | return true; |
549 | 641 | } |
550 | 819 | |
551 | 819 | return false; |
552 | 819 | } |
553 | | |
554 | | // If Reg is a virtual register, return its definition, otherwise return null. |
555 | | static MachineInstr *getDef(unsigned Reg, |
556 | 237 | const MachineRegisterInfo *MRI) { |
557 | 237 | if (TargetRegisterInfo::isPhysicalRegister(Reg)) |
558 | 0 | return nullptr; |
559 | 237 | return MRI->getUniqueVRegDef(Reg); |
560 | 237 | } |
561 | | |
562 | | // Return true if MI is a shift of type Opcode by Imm bits. |
563 | 226 | static bool isShift(MachineInstr *MI, unsigned Opcode, int64_t Imm) { |
564 | 226 | return (MI->getOpcode() == Opcode && |
565 | 16 | !MI->getOperand(2).getReg() && |
566 | 16 | MI->getOperand(3).getImm() == Imm); |
567 | 226 | } |
568 | | |
569 | | // If the destination of MI has no uses, delete it as dead. |
570 | 24 | static void eraseIfDead(MachineInstr *MI, const MachineRegisterInfo *MRI) { |
571 | 24 | if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) |
572 | 18 | MI->eraseFromParent(); |
573 | 24 | } |
574 | | |
575 | | // Compare compares SrcReg against zero. Check whether SrcReg contains |
576 | | // the result of an IPM sequence whose input CC survives until Compare, |
577 | | // and whether Compare is therefore redundant. Delete it and return |
578 | | // true if so. |
579 | | static bool removeIPMBasedCompare(MachineInstr &Compare, unsigned SrcReg, |
580 | | const MachineRegisterInfo *MRI, |
581 | 218 | const TargetRegisterInfo *TRI) { |
582 | 218 | MachineInstr *LGFR = nullptr; |
583 | 218 | MachineInstr *RLL = getDef(SrcReg, MRI); |
584 | 218 | if (RLL && 218 RLL->getOpcode() == SystemZ::LGFR218 ) { |
585 | 3 | LGFR = RLL; |
586 | 3 | RLL = getDef(LGFR->getOperand(1).getReg(), MRI); |
587 | 3 | } |
588 | 218 | if (!RLL || 218 !isShift(RLL, SystemZ::RLL, 31)218 ) |
589 | 210 | return false; |
590 | 8 | |
591 | 8 | MachineInstr *SRL = getDef(RLL->getOperand(1).getReg(), MRI); |
592 | 8 | if (!SRL || 8 !isShift(SRL, SystemZ::SRL, SystemZ::IPM_CC)8 ) |
593 | 0 | return false; |
594 | 8 | |
595 | 8 | MachineInstr *IPM = getDef(SRL->getOperand(1).getReg(), MRI); |
596 | 8 | if (!IPM || 8 IPM->getOpcode() != SystemZ::IPM8 ) |
597 | 0 | return false; |
598 | 8 | |
599 | 8 | // Check that there are no assignments to CC between the IPM and Compare, |
600 | 8 | if (8 IPM->getParent() != Compare.getParent()8 ) |
601 | 0 | return false; |
602 | 8 | MachineBasicBlock::iterator MBBI = IPM, MBBE = Compare.getIterator(); |
603 | 24 | for (++MBBI; MBBI != MBBE24 ; ++MBBI16 ) { |
604 | 16 | MachineInstr &MI = *MBBI; |
605 | 16 | if (MI.modifiesRegister(SystemZ::CC, TRI)) |
606 | 0 | return false; |
607 | 16 | } |
608 | 8 | |
609 | 8 | Compare.eraseFromParent(); |
610 | 8 | if (LGFR) |
611 | 0 | eraseIfDead(LGFR, MRI); |
612 | 8 | eraseIfDead(RLL, MRI); |
613 | 8 | eraseIfDead(SRL, MRI); |
614 | 8 | eraseIfDead(IPM, MRI); |
615 | 8 | |
616 | 8 | return true; |
617 | 218 | } |
618 | | |
619 | | bool SystemZInstrInfo::optimizeCompareInstr( |
620 | | MachineInstr &Compare, unsigned SrcReg, unsigned SrcReg2, int Mask, |
621 | 641 | int Value, const MachineRegisterInfo *MRI) const { |
622 | 641 | assert(!SrcReg2 && "Only optimizing constant comparisons so far"); |
623 | 641 | bool IsLogical = (Compare.getDesc().TSFlags & SystemZII::IsLogical) != 0; |
624 | 218 | return Value == 0 && !IsLogical && |
625 | 218 | removeIPMBasedCompare(Compare, SrcReg, MRI, &RI); |
626 | 641 | } |
627 | | |
628 | | bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB, |
629 | | ArrayRef<MachineOperand> Pred, |
630 | | unsigned TrueReg, unsigned FalseReg, |
631 | | int &CondCycles, int &TrueCycles, |
632 | 709 | int &FalseCycles) const { |
633 | 709 | // Not all subtargets have LOCR instructions. |
634 | 709 | if (!STI.hasLoadStoreOnCond()) |
635 | 631 | return false; |
636 | 78 | if (78 Pred.size() != 278 ) |
637 | 0 | return false; |
638 | 78 | |
639 | 78 | // Check register classes. |
640 | 78 | const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); |
641 | 78 | const TargetRegisterClass *RC = |
642 | 78 | RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); |
643 | 78 | if (!RC) |
644 | 0 | return false; |
645 | 78 | |
646 | 78 | // We have LOCR instructions for 32 and 64 bit general purpose registers. |
647 | 78 | if (78 (STI.hasLoadStoreOnCond2() && |
648 | 46 | SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) || |
649 | 68 | SystemZ::GR32BitRegClass.hasSubClassEq(RC) || |
650 | 78 | SystemZ::GR64BitRegClass.hasSubClassEq(RC)59 ) { |
651 | 26 | CondCycles = 2; |
652 | 26 | TrueCycles = 2; |
653 | 26 | FalseCycles = 2; |
654 | 26 | return true; |
655 | 26 | } |
656 | 52 | |
657 | 52 | // Can't do anything else. |
658 | 52 | return false; |
659 | 52 | } |
660 | | |
661 | | void SystemZInstrInfo::insertSelect(MachineBasicBlock &MBB, |
662 | | MachineBasicBlock::iterator I, |
663 | | const DebugLoc &DL, unsigned DstReg, |
664 | | ArrayRef<MachineOperand> Pred, |
665 | | unsigned TrueReg, |
666 | 22 | unsigned FalseReg) const { |
667 | 22 | MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); |
668 | 22 | const TargetRegisterClass *RC = MRI.getRegClass(DstReg); |
669 | 22 | |
670 | 22 | assert(Pred.size() == 2 && "Invalid condition"); |
671 | 22 | unsigned CCValid = Pred[0].getImm(); |
672 | 22 | unsigned CCMask = Pred[1].getImm(); |
673 | 22 | |
674 | 22 | unsigned Opc; |
675 | 22 | if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)22 ) { |
676 | 16 | if (STI.hasLoadStoreOnCond2()) |
677 | 8 | Opc = SystemZ::LOCRMux; |
678 | 8 | else { |
679 | 8 | Opc = SystemZ::LOCR; |
680 | 8 | MRI.constrainRegClass(DstReg, &SystemZ::GR32BitRegClass); |
681 | 8 | unsigned TReg = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass); |
682 | 8 | unsigned FReg = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass); |
683 | 8 | BuildMI(MBB, I, DL, get(TargetOpcode::COPY), TReg).addReg(TrueReg); |
684 | 8 | BuildMI(MBB, I, DL, get(TargetOpcode::COPY), FReg).addReg(FalseReg); |
685 | 8 | TrueReg = TReg; |
686 | 8 | FalseReg = FReg; |
687 | 8 | } |
688 | 22 | } else if (6 SystemZ::GR64BitRegClass.hasSubClassEq(RC)6 ) |
689 | 6 | Opc = SystemZ::LOCGR; |
690 | 6 | else |
691 | 0 | llvm_unreachable("Invalid register class"); |
692 | 22 | |
693 | 22 | BuildMI(MBB, I, DL, get(Opc), DstReg) |
694 | 22 | .addReg(FalseReg).addReg(TrueReg) |
695 | 22 | .addImm(CCValid).addImm(CCMask); |
696 | 22 | } |
697 | | |
698 | | bool SystemZInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, |
699 | | unsigned Reg, |
700 | 1.53k | MachineRegisterInfo *MRI) const { |
701 | 1.53k | unsigned DefOpc = DefMI.getOpcode(); |
702 | 1.53k | if (DefOpc != SystemZ::LHIMux && 1.53k DefOpc != SystemZ::LHI1.46k && |
703 | 1.24k | DefOpc != SystemZ::LGHI) |
704 | 1.03k | return false; |
705 | 505 | if (505 DefMI.getOperand(0).getReg() != Reg505 ) |
706 | 0 | return false; |
707 | 505 | int32_t ImmVal = (int32_t)DefMI.getOperand(1).getImm(); |
708 | 505 | |
709 | 505 | unsigned UseOpc = UseMI.getOpcode(); |
710 | 505 | unsigned NewUseOpc; |
711 | 505 | unsigned UseIdx; |
712 | 505 | int CommuteIdx = -1; |
713 | 505 | switch (UseOpc) { |
714 | 4 | case SystemZ::LOCRMux: |
715 | 4 | if (!STI.hasLoadStoreOnCond2()) |
716 | 0 | return false; |
717 | 4 | NewUseOpc = SystemZ::LOCHIMux; |
718 | 4 | if (UseMI.getOperand(2).getReg() == Reg) |
719 | 2 | UseIdx = 2; |
720 | 2 | else if (2 UseMI.getOperand(1).getReg() == Reg2 ) |
721 | 2 | UseIdx = 2, CommuteIdx = 1; |
722 | 2 | else |
723 | 0 | return false; |
724 | 4 | break; |
725 | 2 | case SystemZ::LOCGR: |
726 | 2 | if (!STI.hasLoadStoreOnCond2()) |
727 | 0 | return false; |
728 | 2 | NewUseOpc = SystemZ::LOCGHI; |
729 | 2 | if (UseMI.getOperand(2).getReg() == Reg) |
730 | 1 | UseIdx = 2; |
731 | 1 | else if (1 UseMI.getOperand(1).getReg() == Reg1 ) |
732 | 1 | UseIdx = 2, CommuteIdx = 1; |
733 | 1 | else |
734 | 0 | return false; |
735 | 2 | break; |
736 | 499 | default: |
737 | 499 | return false; |
738 | 6 | } |
739 | 6 | |
740 | 6 | if (6 CommuteIdx != -16 ) |
741 | 3 | if (3 !commuteInstruction(UseMI, false, CommuteIdx, UseIdx)3 ) |
742 | 0 | return false; |
743 | 6 | |
744 | 6 | bool DeleteDef = MRI->hasOneNonDBGUse(Reg); |
745 | 6 | UseMI.setDesc(get(NewUseOpc)); |
746 | 6 | UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal); |
747 | 6 | if (DeleteDef) |
748 | 6 | DefMI.eraseFromParent(); |
749 | 1.53k | |
750 | 1.53k | return true; |
751 | 1.53k | } |
752 | | |
753 | 10.0k | bool SystemZInstrInfo::isPredicable(const MachineInstr &MI) const { |
754 | 10.0k | unsigned Opcode = MI.getOpcode(); |
755 | 10.0k | if (Opcode == SystemZ::Return || |
756 | 9.14k | Opcode == SystemZ::Trap || |
757 | 9.10k | Opcode == SystemZ::CallJG || |
758 | 9.05k | Opcode == SystemZ::CallBR) |
759 | 1.04k | return true; |
760 | 9.01k | return false; |
761 | 9.01k | } |
762 | | |
763 | | bool SystemZInstrInfo:: |
764 | | isProfitableToIfCvt(MachineBasicBlock &MBB, |
765 | | unsigned NumCycles, unsigned ExtraPredCycles, |
766 | 3.13k | BranchProbability Probability) const { |
767 | 3.13k | // Avoid using conditional returns at the end of a loop (since then |
768 | 3.13k | // we'd need to emit an unconditional branch to the beginning anyway, |
769 | 3.13k | // making the loop body longer). This doesn't apply for low-probability |
770 | 3.13k | // loops (eg. compare-and-swap retry), so just decide based on branch |
771 | 3.13k | // probability instead of looping structure. |
772 | 3.13k | // However, since Compare and Trap instructions cost the same as a regular |
773 | 3.13k | // Compare instruction, we should allow the if conversion to convert this |
774 | 3.13k | // into a Conditional Compare regardless of the branch probability. |
775 | 3.13k | if (MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap && |
776 | 3.13k | MBB.succ_empty()3.06k && Probability < BranchProbability(1, 8)1.09k ) |
777 | 12 | return false; |
778 | 3.12k | // For now only convert single instructions. |
779 | 3.12k | return NumCycles == 1; |
780 | 3.12k | } |
781 | | |
782 | | bool SystemZInstrInfo:: |
783 | | isProfitableToIfCvt(MachineBasicBlock &TMBB, |
784 | | unsigned NumCyclesT, unsigned ExtraPredCyclesT, |
785 | | MachineBasicBlock &FMBB, |
786 | | unsigned NumCyclesF, unsigned ExtraPredCyclesF, |
787 | 4 | BranchProbability Probability) const { |
788 | 4 | // For now avoid converting mutually-exclusive cases. |
789 | 4 | return false; |
790 | 4 | } |
791 | | |
792 | | bool SystemZInstrInfo:: |
793 | | isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, |
794 | 2.93k | BranchProbability Probability) const { |
795 | 2.93k | // For now only duplicate single instructions. |
796 | 2.93k | return NumCycles == 1; |
797 | 2.93k | } |
798 | | |
799 | | bool SystemZInstrInfo::PredicateInstruction( |
800 | 736 | MachineInstr &MI, ArrayRef<MachineOperand> Pred) const { |
801 | 736 | assert(Pred.size() == 2 && "Invalid condition"); |
802 | 736 | unsigned CCValid = Pred[0].getImm(); |
803 | 736 | unsigned CCMask = Pred[1].getImm(); |
804 | 736 | assert(CCMask > 0 && CCMask < 15 && "Invalid predicate"); |
805 | 736 | unsigned Opcode = MI.getOpcode(); |
806 | 736 | if (Opcode == SystemZ::Trap736 ) { |
807 | 33 | MI.setDesc(get(SystemZ::CondTrap)); |
808 | 33 | MachineInstrBuilder(*MI.getParent()->getParent(), MI) |
809 | 33 | .addImm(CCValid).addImm(CCMask) |
810 | 33 | .addReg(SystemZ::CC, RegState::Implicit); |
811 | 33 | return true; |
812 | 33 | } |
813 | 703 | if (703 Opcode == SystemZ::Return703 ) { |
814 | 658 | MI.setDesc(get(SystemZ::CondReturn)); |
815 | 658 | MachineInstrBuilder(*MI.getParent()->getParent(), MI) |
816 | 658 | .addImm(CCValid).addImm(CCMask) |
817 | 658 | .addReg(SystemZ::CC, RegState::Implicit); |
818 | 658 | return true; |
819 | 658 | } |
820 | 45 | if (45 Opcode == SystemZ::CallJG45 ) { |
821 | 22 | MachineOperand FirstOp = MI.getOperand(0); |
822 | 22 | const uint32_t *RegMask = MI.getOperand(1).getRegMask(); |
823 | 22 | MI.RemoveOperand(1); |
824 | 22 | MI.RemoveOperand(0); |
825 | 22 | MI.setDesc(get(SystemZ::CallBRCL)); |
826 | 22 | MachineInstrBuilder(*MI.getParent()->getParent(), MI) |
827 | 22 | .addImm(CCValid) |
828 | 22 | .addImm(CCMask) |
829 | 22 | .add(FirstOp) |
830 | 22 | .addRegMask(RegMask) |
831 | 22 | .addReg(SystemZ::CC, RegState::Implicit); |
832 | 22 | return true; |
833 | 22 | } |
834 | 23 | if (23 Opcode == SystemZ::CallBR23 ) { |
835 | 23 | const uint32_t *RegMask = MI.getOperand(0).getRegMask(); |
836 | 23 | MI.RemoveOperand(0); |
837 | 23 | MI.setDesc(get(SystemZ::CallBCR)); |
838 | 23 | MachineInstrBuilder(*MI.getParent()->getParent(), MI) |
839 | 23 | .addImm(CCValid).addImm(CCMask) |
840 | 23 | .addRegMask(RegMask) |
841 | 23 | .addReg(SystemZ::CC, RegState::Implicit); |
842 | 23 | return true; |
843 | 23 | } |
844 | 0 | return false; |
845 | 0 | } |
846 | | |
847 | | void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, |
848 | | MachineBasicBlock::iterator MBBI, |
849 | | const DebugLoc &DL, unsigned DestReg, |
850 | 1.71k | unsigned SrcReg, bool KillSrc) const { |
851 | 1.71k | // Split 128-bit GPR moves into two 64-bit moves. Add implicit uses of the |
852 | 1.71k | // super register in case one of the subregs is undefined. |
853 | 1.71k | // This handles ADDR128 too. |
854 | 1.71k | if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)1.71k ) { |
855 | 35 | copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_h64), |
856 | 35 | RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc); |
857 | 35 | MachineInstrBuilder(*MBB.getParent(), std::prev(MBBI)) |
858 | 35 | .addReg(SrcReg, RegState::Implicit); |
859 | 35 | copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_l64), |
860 | 35 | RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc); |
861 | 35 | MachineInstrBuilder(*MBB.getParent(), std::prev(MBBI)) |
862 | 35 | .addReg(SrcReg, (getKillRegState(KillSrc) | RegState::Implicit)); |
863 | 35 | return; |
864 | 35 | } |
865 | 1.67k | |
866 | 1.67k | if (1.67k SystemZ::GRX32BitRegClass.contains(DestReg, SrcReg)1.67k ) { |
867 | 276 | emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc, |
868 | 276 | false); |
869 | 276 | return; |
870 | 276 | } |
871 | 1.39k | |
872 | 1.39k | // Move 128-bit floating-point values between VR128 and FP128. |
873 | 1.39k | if (1.39k SystemZ::VR128BitRegClass.contains(DestReg) && |
874 | 1.39k | SystemZ::FP128BitRegClass.contains(SrcReg)34 ) { |
875 | 4 | unsigned SrcRegHi = |
876 | 4 | RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64), |
877 | 4 | SystemZ::subreg_r64, &SystemZ::VR128BitRegClass); |
878 | 4 | unsigned SrcRegLo = |
879 | 4 | RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64), |
880 | 4 | SystemZ::subreg_r64, &SystemZ::VR128BitRegClass); |
881 | 4 | |
882 | 4 | BuildMI(MBB, MBBI, DL, get(SystemZ::VMRHG), DestReg) |
883 | 4 | .addReg(SrcRegHi, getKillRegState(KillSrc)) |
884 | 4 | .addReg(SrcRegLo, getKillRegState(KillSrc)); |
885 | 4 | return; |
886 | 4 | } |
887 | 1.39k | if (1.39k SystemZ::FP128BitRegClass.contains(DestReg) && |
888 | 1.39k | SystemZ::VR128BitRegClass.contains(SrcReg)10 ) { |
889 | 5 | unsigned DestRegHi = |
890 | 5 | RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64), |
891 | 5 | SystemZ::subreg_r64, &SystemZ::VR128BitRegClass); |
892 | 5 | unsigned DestRegLo = |
893 | 5 | RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64), |
894 | 5 | SystemZ::subreg_r64, &SystemZ::VR128BitRegClass); |
895 | 5 | |
896 | 5 | if (DestRegHi != SrcReg) |
897 | 0 | copyPhysReg(MBB, MBBI, DL, DestRegHi, SrcReg, false); |
898 | 5 | BuildMI(MBB, MBBI, DL, get(SystemZ::VREPG), DestRegLo) |
899 | 5 | .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1); |
900 | 5 | return; |
901 | 5 | } |
902 | 1.39k | |
903 | 1.39k | // Everything else needs only one instruction. |
904 | 1.39k | unsigned Opcode; |
905 | 1.39k | if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) |
906 | 558 | Opcode = SystemZ::LGR; |
907 | 832 | else if (832 SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)832 ) |
908 | 832 | // For z13 we prefer LDR over LER to avoid partial register dependencies. |
909 | 107 | Opcode = STI.hasVector() ? 107 SystemZ::LDR3223 : SystemZ::LER84 ; |
910 | 725 | else if (725 SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)725 ) |
911 | 663 | Opcode = SystemZ::LDR; |
912 | 62 | else if (62 SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)62 ) |
913 | 5 | Opcode = SystemZ::LXR; |
914 | 57 | else if (57 SystemZ::VR32BitRegClass.contains(DestReg, SrcReg)57 ) |
915 | 1 | Opcode = SystemZ::VLR32; |
916 | 56 | else if (56 SystemZ::VR64BitRegClass.contains(DestReg, SrcReg)56 ) |
917 | 2 | Opcode = SystemZ::VLR64; |
918 | 54 | else if (54 SystemZ::VR128BitRegClass.contains(DestReg, SrcReg)54 ) |
919 | 30 | Opcode = SystemZ::VLR; |
920 | 24 | else if (24 SystemZ::AR32BitRegClass.contains(DestReg, SrcReg)24 ) |
921 | 0 | Opcode = SystemZ::CPYA; |
922 | 24 | else if (24 SystemZ::AR32BitRegClass.contains(DestReg) && |
923 | 0 | SystemZ::GR32BitRegClass.contains(SrcReg)) |
924 | 0 | Opcode = SystemZ::SAR; |
925 | 24 | else if (24 SystemZ::GR32BitRegClass.contains(DestReg) && |
926 | 24 | SystemZ::AR32BitRegClass.contains(SrcReg)) |
927 | 24 | Opcode = SystemZ::EAR; |
928 | 24 | else |
929 | 0 | llvm_unreachable("Impossible reg-to-reg copy"); |
930 | 1.39k | |
931 | 1.39k | BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) |
932 | 1.39k | .addReg(SrcReg, getKillRegState(KillSrc)); |
933 | 1.39k | } |
934 | | |
935 | | void SystemZInstrInfo::storeRegToStackSlot( |
936 | | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, |
937 | | bool isKill, int FrameIdx, const TargetRegisterClass *RC, |
938 | 737 | const TargetRegisterInfo *TRI) const { |
939 | 737 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc()732 : DebugLoc()5 ; |
940 | 737 | |
941 | 737 | // Callers may expect a single instruction, so keep 128-bit moves |
942 | 737 | // together for now and lower them after register allocation. |
943 | 737 | unsigned LoadOpcode, StoreOpcode; |
944 | 737 | getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); |
945 | 737 | addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) |
946 | 737 | .addReg(SrcReg, getKillRegState(isKill)), |
947 | 737 | FrameIdx); |
948 | 737 | } |
949 | | |
950 | | void SystemZInstrInfo::loadRegFromStackSlot( |
951 | | MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, |
952 | | int FrameIdx, const TargetRegisterClass *RC, |
953 | 678 | const TargetRegisterInfo *TRI) const { |
954 | 678 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc()678 : DebugLoc()0 ; |
955 | 678 | |
956 | 678 | // Callers may expect a single instruction, so keep 128-bit moves |
957 | 678 | // together for now and lower them after register allocation. |
958 | 678 | unsigned LoadOpcode, StoreOpcode; |
959 | 678 | getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); |
960 | 678 | addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), |
961 | 678 | FrameIdx); |
962 | 678 | } |
963 | | |
964 | | // Return true if MI is a simple load or store with a 12-bit displacement |
965 | | // and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. |
966 | 212 | static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) { |
967 | 212 | const MCInstrDesc &MCID = MI->getDesc(); |
968 | 212 | return ((MCID.TSFlags & Flag) && |
969 | 118 | isUInt<12>(MI->getOperand(2).getImm()) && |
970 | 118 | MI->getOperand(3).getReg() == 0); |
971 | 212 | } |
972 | | |
973 | | namespace { |
974 | | |
975 | | struct LogicOp { |
976 | 64 | LogicOp() = default; |
977 | | LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize) |
978 | 333 | : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {} |
979 | | |
980 | 397 | explicit operator bool() const { return RegSize; } |
981 | | |
982 | | unsigned RegSize = 0; |
983 | | unsigned ImmLSB = 0; |
984 | | unsigned ImmSize = 0; |
985 | | }; |
986 | | |
987 | | } // end anonymous namespace |
988 | | |
989 | 397 | static LogicOp interpretAndImmediate(unsigned Opcode) { |
990 | 397 | switch (Opcode) { |
991 | 4 | case SystemZ::NILMux: return LogicOp(32, 0, 16); |
992 | 1 | case SystemZ::NIHMux: return LogicOp(32, 16, 16); |
993 | 294 | case SystemZ::NILL64: return LogicOp(64, 0, 16); |
994 | 4 | case SystemZ::NILH64: return LogicOp(64, 16, 16); |
995 | 4 | case SystemZ::NIHL64: return LogicOp(64, 32, 16); |
996 | 4 | case SystemZ::NIHH64: return LogicOp(64, 48, 16); |
997 | 11 | case SystemZ::NIFMux: return LogicOp(32, 0, 32); |
998 | 4 | case SystemZ::NILF64: return LogicOp(64, 0, 32); |
999 | 7 | case SystemZ::NIHF64: return LogicOp(64, 32, 32); |
1000 | 64 | default: return LogicOp(); |
1001 | 0 | } |
1002 | 0 | } |
1003 | | |
1004 | 523 | static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI) { |
1005 | 523 | if (OldMI->registerDefIsDead(SystemZ::CC)523 ) { |
1006 | 404 | MachineOperand *CCDef = NewMI->findRegisterDefOperand(SystemZ::CC); |
1007 | 404 | if (CCDef != nullptr) |
1008 | 391 | CCDef->setIsDead(true); |
1009 | 404 | } |
1010 | 523 | } |
1011 | | |
1012 | | // Used to return from convertToThreeAddress after replacing two-address |
1013 | | // instruction OldMI with three-address instruction NewMI. |
1014 | | static MachineInstr *finishConvertToThreeAddress(MachineInstr *OldMI, |
1015 | | MachineInstr *NewMI, |
1016 | 336 | LiveVariables *LV) { |
1017 | 336 | if (LV336 ) { |
1018 | 336 | unsigned NumOps = OldMI->getNumOperands(); |
1019 | 1.34k | for (unsigned I = 1; I < NumOps1.34k ; ++I1.00k ) { |
1020 | 1.00k | MachineOperand &Op = OldMI->getOperand(I); |
1021 | 1.00k | if (Op.isReg() && 1.00k Op.isKill()686 ) |
1022 | 48 | LV->replaceKillInstruction(Op.getReg(), *OldMI, *NewMI); |
1023 | 1.00k | } |
1024 | 336 | } |
1025 | 336 | transferDeadCC(OldMI, NewMI); |
1026 | 336 | return NewMI; |
1027 | 336 | } |
1028 | | |
1029 | | MachineInstr *SystemZInstrInfo::convertToThreeAddress( |
1030 | 427 | MachineFunction::iterator &MFI, MachineInstr &MI, LiveVariables *LV) const { |
1031 | 427 | MachineBasicBlock *MBB = MI.getParent(); |
1032 | 427 | MachineFunction *MF = MBB->getParent(); |
1033 | 427 | MachineRegisterInfo &MRI = MF->getRegInfo(); |
1034 | 427 | |
1035 | 427 | unsigned Opcode = MI.getOpcode(); |
1036 | 427 | unsigned NumOps = MI.getNumOperands(); |
1037 | 427 | |
1038 | 427 | // Try to convert something like SLL into SLLK, if supported. |
1039 | 427 | // We prefer to keep the two-operand form where possible both |
1040 | 427 | // because it tends to be shorter and because some instructions |
1041 | 427 | // have memory forms that can be used during spilling. |
1042 | 427 | if (STI.hasDistinctOps()427 ) { |
1043 | 46 | MachineOperand &Dest = MI.getOperand(0); |
1044 | 46 | MachineOperand &Src = MI.getOperand(1); |
1045 | 46 | unsigned DestReg = Dest.getReg(); |
1046 | 46 | unsigned SrcReg = Src.getReg(); |
1047 | 46 | // AHIMux is only really a three-operand instruction when both operands |
1048 | 46 | // are low registers. Try to constrain both operands to be low if |
1049 | 46 | // possible. |
1050 | 46 | if (Opcode == SystemZ::AHIMux && |
1051 | 9 | TargetRegisterInfo::isVirtualRegister(DestReg) && |
1052 | 9 | TargetRegisterInfo::isVirtualRegister(SrcReg) && |
1053 | 9 | MRI.getRegClass(DestReg)->contains(SystemZ::R1L) && |
1054 | 46 | MRI.getRegClass(SrcReg)->contains(SystemZ::R1L)9 ) { |
1055 | 7 | MRI.constrainRegClass(DestReg, &SystemZ::GR32BitRegClass); |
1056 | 7 | MRI.constrainRegClass(SrcReg, &SystemZ::GR32BitRegClass); |
1057 | 7 | } |
1058 | 46 | int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); |
1059 | 46 | if (ThreeOperandOpcode >= 046 ) { |
1060 | 30 | // Create three address instruction without adding the implicit |
1061 | 30 | // operands. Those will instead be copied over from the original |
1062 | 30 | // instruction by the loop below. |
1063 | 30 | MachineInstrBuilder MIB( |
1064 | 30 | *MF, MF->CreateMachineInstr(get(ThreeOperandOpcode), MI.getDebugLoc(), |
1065 | 30 | /*NoImplicit=*/true)); |
1066 | 30 | MIB.add(Dest); |
1067 | 30 | // Keep the kill state, but drop the tied flag. |
1068 | 30 | MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()); |
1069 | 30 | // Keep the remaining operands as-is. |
1070 | 91 | for (unsigned I = 2; I < NumOps91 ; ++I61 ) |
1071 | 61 | MIB.add(MI.getOperand(I)); |
1072 | 30 | MBB->insert(MI, MIB); |
1073 | 30 | return finishConvertToThreeAddress(&MI, MIB, LV); |
1074 | 30 | } |
1075 | 397 | } |
1076 | 397 | |
1077 | 397 | // Try to convert an AND into an RISBG-type instruction. |
1078 | 397 | if (LogicOp 397 And397 = interpretAndImmediate(Opcode)) { |
1079 | 333 | uint64_t Imm = MI.getOperand(2).getImm() << And.ImmLSB; |
1080 | 333 | // AND IMMEDIATE leaves the other bits of the register unchanged. |
1081 | 333 | Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB); |
1082 | 333 | unsigned Start, End; |
1083 | 333 | if (isRxSBGMask(Imm, And.RegSize, Start, End)333 ) { |
1084 | 306 | unsigned NewOpcode; |
1085 | 306 | if (And.RegSize == 64306 ) { |
1086 | 293 | NewOpcode = SystemZ::RISBG; |
1087 | 293 | // Prefer RISBGN if available, since it does not clobber CC. |
1088 | 293 | if (STI.hasMiscellaneousExtensions()) |
1089 | 0 | NewOpcode = SystemZ::RISBGN; |
1090 | 306 | } else { |
1091 | 13 | NewOpcode = SystemZ::RISBMux; |
1092 | 13 | Start &= 31; |
1093 | 13 | End &= 31; |
1094 | 13 | } |
1095 | 306 | MachineOperand &Dest = MI.getOperand(0); |
1096 | 306 | MachineOperand &Src = MI.getOperand(1); |
1097 | 306 | MachineInstrBuilder MIB = |
1098 | 306 | BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpcode)) |
1099 | 306 | .add(Dest) |
1100 | 306 | .addReg(0) |
1101 | 306 | .addReg(Src.getReg(), getKillRegState(Src.isKill()), |
1102 | 306 | Src.getSubReg()) |
1103 | 306 | .addImm(Start) |
1104 | 306 | .addImm(End + 128) |
1105 | 306 | .addImm(0); |
1106 | 306 | return finishConvertToThreeAddress(&MI, MIB, LV); |
1107 | 306 | } |
1108 | 91 | } |
1109 | 91 | return nullptr; |
1110 | 91 | } |
1111 | | |
1112 | | MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl( |
1113 | | MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, |
1114 | | MachineBasicBlock::iterator InsertPt, int FrameIndex, |
1115 | 703 | LiveIntervals *LIS) const { |
1116 | 703 | const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); |
1117 | 703 | const MachineFrameInfo &MFI = MF.getFrameInfo(); |
1118 | 703 | unsigned Size = MFI.getObjectSize(FrameIndex); |
1119 | 703 | unsigned Opcode = MI.getOpcode(); |
1120 | 703 | |
1121 | 703 | if (Ops.size() == 2 && 703 Ops[0] == 02 && Ops[1] == 12 ) { |
1122 | 2 | if (LIS != nullptr && 2 (Opcode == SystemZ::LA || 2 Opcode == SystemZ::LAY0 ) && |
1123 | 2 | isInt<8>(MI.getOperand(2).getImm())2 && !MI.getOperand(3).getReg()2 ) { |
1124 | 2 | |
1125 | 2 | // Check CC liveness, since new instruction introduces a dead |
1126 | 2 | // def of CC. |
1127 | 2 | MCRegUnitIterator CCUnit(SystemZ::CC, TRI); |
1128 | 2 | LiveRange &CCLiveRange = LIS->getRegUnit(*CCUnit); |
1129 | 2 | ++CCUnit; |
1130 | 2 | assert(!CCUnit.isValid() && "CC only has one reg unit."); |
1131 | 2 | SlotIndex MISlot = |
1132 | 2 | LIS->getSlotIndexes()->getInstructionIndex(MI).getRegSlot(); |
1133 | 2 | if (!CCLiveRange.liveAt(MISlot)2 ) { |
1134 | 2 | // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST |
1135 | 2 | MachineInstr *BuiltMI = BuildMI(*InsertPt->getParent(), InsertPt, |
1136 | 2 | MI.getDebugLoc(), get(SystemZ::AGSI)) |
1137 | 2 | .addFrameIndex(FrameIndex) |
1138 | 2 | .addImm(0) |
1139 | 2 | .addImm(MI.getOperand(2).getImm()); |
1140 | 2 | BuiltMI->findRegisterDefOperand(SystemZ::CC)->setIsDead(true); |
1141 | 2 | CCLiveRange.createDeadDef(MISlot, LIS->getVNInfoAllocator()); |
1142 | 2 | return BuiltMI; |
1143 | 2 | } |
1144 | 0 | } |
1145 | 0 | return nullptr; |
1146 | 0 | } |
1147 | 701 | |
1148 | 701 | // All other cases require a single operand. |
1149 | 701 | if (701 Ops.size() != 1701 ) |
1150 | 0 | return nullptr; |
1151 | 701 | |
1152 | 701 | unsigned OpNum = Ops[0]; |
1153 | 701 | assert(Size * 8 == |
1154 | 701 | TRI->getRegSizeInBits(*MF.getRegInfo() |
1155 | 701 | .getRegClass(MI.getOperand(OpNum).getReg())) && |
1156 | 701 | "Invalid size combination"); |
1157 | 701 | |
1158 | 701 | if ((Opcode == SystemZ::AHI || 701 Opcode == SystemZ::AGHI699 ) && OpNum == 03 && |
1159 | 701 | isInt<8>(MI.getOperand(2).getImm())3 ) { |
1160 | 3 | // A(G)HI %reg, CONST -> A(G)SI %mem, CONST |
1161 | 3 | Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI2 : SystemZ::AGSI1 ); |
1162 | 3 | MachineInstr *BuiltMI = |
1163 | 3 | BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), get(Opcode)) |
1164 | 3 | .addFrameIndex(FrameIndex) |
1165 | 3 | .addImm(0) |
1166 | 3 | .addImm(MI.getOperand(2).getImm()); |
1167 | 3 | transferDeadCC(&MI, BuiltMI); |
1168 | 3 | return BuiltMI; |
1169 | 3 | } |
1170 | 698 | |
1171 | 698 | if (698 Opcode == SystemZ::LGDR || 698 Opcode == SystemZ::LDGR694 ) { |
1172 | 9 | bool Op0IsGPR = (Opcode == SystemZ::LGDR); |
1173 | 9 | bool Op1IsGPR = (Opcode == SystemZ::LDGR); |
1174 | 9 | // If we're spilling the destination of an LDGR or LGDR, store the |
1175 | 9 | // source register instead. |
1176 | 9 | if (OpNum == 09 ) { |
1177 | 5 | unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG3 : SystemZ::STD2 ; |
1178 | 5 | return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), |
1179 | 5 | get(StoreOpcode)) |
1180 | 5 | .add(MI.getOperand(1)) |
1181 | 5 | .addFrameIndex(FrameIndex) |
1182 | 5 | .addImm(0) |
1183 | 5 | .addReg(0); |
1184 | 5 | } |
1185 | 4 | // If we're spilling the source of an LDGR or LGDR, load the |
1186 | 4 | // destination register instead. |
1187 | 4 | if (4 OpNum == 14 ) { |
1188 | 4 | unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG2 : SystemZ::LD2 ; |
1189 | 4 | return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), |
1190 | 4 | get(LoadOpcode)) |
1191 | 4 | .add(MI.getOperand(0)) |
1192 | 4 | .addFrameIndex(FrameIndex) |
1193 | 4 | .addImm(0) |
1194 | 4 | .addReg(0); |
1195 | 4 | } |
1196 | 689 | } |
1197 | 689 | |
1198 | 689 | // Look for cases where the source of a simple store or the destination |
1199 | 689 | // of a simple load is being spilled. Try to use MVC instead. |
1200 | 689 | // |
1201 | 689 | // Although MVC is in practice a fast choice in these cases, it is still |
1202 | 689 | // logically a bytewise copy. This means that we cannot use it if the |
1203 | 689 | // load or store is volatile. We also wouldn't be able to use MVC if |
1204 | 689 | // the two memories partially overlap, but that case cannot occur here, |
1205 | 689 | // because we know that one of the memories is a full frame index. |
1206 | 689 | // |
1207 | 689 | // For performance reasons, we also want to avoid using MVC if the addresses |
1208 | 689 | // might be equal. We don't worry about that case here, because spill slot |
1209 | 689 | // coloring happens later, and because we have special code to remove |
1210 | 689 | // MVCs that turn out to be redundant. |
1211 | 689 | if (689 OpNum == 0 && 689 MI.hasOneMemOperand()399 ) { |
1212 | 330 | MachineMemOperand *MMO = *MI.memoperands_begin(); |
1213 | 330 | if (MMO->getSize() == Size && 330 !MMO->isVolatile()323 ) { |
1214 | 159 | // Handle conversion of loads. |
1215 | 159 | if (isSimpleBD12Move(&MI, SystemZII::SimpleBDXLoad)159 ) { |
1216 | 106 | return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), |
1217 | 106 | get(SystemZ::MVC)) |
1218 | 106 | .addFrameIndex(FrameIndex) |
1219 | 106 | .addImm(0) |
1220 | 106 | .addImm(Size) |
1221 | 106 | .add(MI.getOperand(1)) |
1222 | 106 | .addImm(MI.getOperand(2).getImm()) |
1223 | 106 | .addMemOperand(MMO); |
1224 | 106 | } |
1225 | 53 | // Handle conversion of stores. |
1226 | 53 | if (53 isSimpleBD12Move(&MI, SystemZII::SimpleBDXStore)53 ) { |
1227 | 12 | return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), |
1228 | 12 | get(SystemZ::MVC)) |
1229 | 12 | .add(MI.getOperand(1)) |
1230 | 12 | .addImm(MI.getOperand(2).getImm()) |
1231 | 12 | .addImm(Size) |
1232 | 12 | .addFrameIndex(FrameIndex) |
1233 | 12 | .addImm(0) |
1234 | 12 | .addMemOperand(MMO); |
1235 | 12 | } |
1236 | 571 | } |
1237 | 330 | } |
1238 | 571 | |
1239 | 571 | // If the spilled operand is the final one, try to change <INSN>R |
1240 | 571 | // into <INSN>. |
1241 | 571 | int MemOpcode = SystemZ::getMemOpcode(Opcode); |
1242 | 571 | if (MemOpcode >= 0571 ) { |
1243 | 191 | unsigned NumOps = MI.getNumExplicitOperands(); |
1244 | 191 | if (OpNum == NumOps - 1191 ) { |
1245 | 184 | const MCInstrDesc &MemDesc = get(MemOpcode); |
1246 | 184 | uint64_t AccessBytes = SystemZII::getAccessSize(MemDesc.TSFlags); |
1247 | 184 | assert(AccessBytes != 0 && "Size of access should be known"); |
1248 | 184 | assert(AccessBytes <= Size && "Access outside the frame index"); |
1249 | 184 | uint64_t Offset = Size - AccessBytes; |
1250 | 184 | MachineInstrBuilder MIB = BuildMI(*InsertPt->getParent(), InsertPt, |
1251 | 184 | MI.getDebugLoc(), get(MemOpcode)); |
1252 | 483 | for (unsigned I = 0; I < OpNum483 ; ++I299 ) |
1253 | 299 | MIB.add(MI.getOperand(I)); |
1254 | 184 | MIB.addFrameIndex(FrameIndex).addImm(Offset); |
1255 | 184 | if (MemDesc.TSFlags & SystemZII::HasIndex) |
1256 | 184 | MIB.addReg(0); |
1257 | 184 | transferDeadCC(&MI, MIB); |
1258 | 184 | return MIB; |
1259 | 184 | } |
1260 | 387 | } |
1261 | 387 | |
1262 | 387 | return nullptr; |
1263 | 387 | } |
1264 | | |
1265 | | MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl( |
1266 | | MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, |
1267 | | MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, |
1268 | 0 | LiveIntervals *LIS) const { |
1269 | 0 | return nullptr; |
1270 | 0 | } |
1271 | | |
1272 | 14.6k | bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { |
1273 | 14.6k | switch (MI.getOpcode()) { |
1274 | 30 | case SystemZ::L128: |
1275 | 30 | splitMove(MI, SystemZ::LG); |
1276 | 30 | return true; |
1277 | 14.6k | |
1278 | 28 | case SystemZ::ST128: |
1279 | 28 | splitMove(MI, SystemZ::STG); |
1280 | 28 | return true; |
1281 | 14.6k | |
1282 | 154 | case SystemZ::LX: |
1283 | 154 | splitMove(MI, SystemZ::LD); |
1284 | 154 | return true; |
1285 | 14.6k | |
1286 | 228 | case SystemZ::STX: |
1287 | 228 | splitMove(MI, SystemZ::STD); |
1288 | 228 | return true; |
1289 | 14.6k | |
1290 | 15 | case SystemZ::LBMux: |
1291 | 15 | expandRXYPseudo(MI, SystemZ::LB, SystemZ::LBH); |
1292 | 15 | return true; |
1293 | 14.6k | |
1294 | 15 | case SystemZ::LHMux: |
1295 | 15 | expandRXYPseudo(MI, SystemZ::LH, SystemZ::LHH); |
1296 | 15 | return true; |
1297 | 14.6k | |
1298 | 35 | case SystemZ::LLCRMux: |
1299 | 35 | expandZExtPseudo(MI, SystemZ::LLCR, 8); |
1300 | 35 | return true; |
1301 | 14.6k | |
1302 | 43 | case SystemZ::LLHRMux: |
1303 | 43 | expandZExtPseudo(MI, SystemZ::LLHR, 16); |
1304 | 43 | return true; |
1305 | 14.6k | |
1306 | 15 | case SystemZ::LLCMux: |
1307 | 15 | expandRXYPseudo(MI, SystemZ::LLC, SystemZ::LLCH); |
1308 | 15 | return true; |
1309 | 14.6k | |
1310 | 12 | case SystemZ::LLHMux: |
1311 | 12 | expandRXYPseudo(MI, SystemZ::LLH, SystemZ::LLHH); |
1312 | 12 | return true; |
1313 | 14.6k | |
1314 | 141 | case SystemZ::LMux: |
1315 | 141 | expandRXYPseudo(MI, SystemZ::L, SystemZ::LFH); |
1316 | 141 | return true; |
1317 | 14.6k | |
1318 | 16 | case SystemZ::LOCMux: |
1319 | 16 | expandLOCPseudo(MI, SystemZ::LOC, SystemZ::LOCFH); |
1320 | 16 | return true; |
1321 | 14.6k | |
1322 | 12 | case SystemZ::LOCHIMux: |
1323 | 12 | expandLOCPseudo(MI, SystemZ::LOCHI, SystemZ::LOCHHI); |
1324 | 12 | return true; |
1325 | 14.6k | |
1326 | 13 | case SystemZ::LOCRMux: |
1327 | 13 | expandLOCRPseudo(MI, SystemZ::LOCR, SystemZ::LOCFHR); |
1328 | 13 | return true; |
1329 | 14.6k | |
1330 | 57 | case SystemZ::STCMux: |
1331 | 57 | expandRXYPseudo(MI, SystemZ::STC, SystemZ::STCH); |
1332 | 57 | return true; |
1333 | 14.6k | |
1334 | 14 | case SystemZ::STHMux: |
1335 | 14 | expandRXYPseudo(MI, SystemZ::STH, SystemZ::STHH); |
1336 | 14 | return true; |
1337 | 14.6k | |
1338 | 201 | case SystemZ::STMux: |
1339 | 201 | expandRXYPseudo(MI, SystemZ::ST, SystemZ::STFH); |
1340 | 201 | return true; |
1341 | 14.6k | |
1342 | 14 | case SystemZ::STOCMux: |
1343 | 14 | expandLOCPseudo(MI, SystemZ::STOC, SystemZ::STOCFH); |
1344 | 14 | return true; |
1345 | 14.6k | |
1346 | 114 | case SystemZ::LHIMux: |
1347 | 114 | expandRIPseudo(MI, SystemZ::LHI, SystemZ::IIHF, true); |
1348 | 114 | return true; |
1349 | 14.6k | |
1350 | 23 | case SystemZ::IIFMux: |
1351 | 23 | expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false); |
1352 | 23 | return true; |
1353 | 14.6k | |
1354 | 2 | case SystemZ::IILMux: |
1355 | 2 | expandRIPseudo(MI, SystemZ::IILL, SystemZ::IIHL, false); |
1356 | 2 | return true; |
1357 | 14.6k | |
1358 | 2 | case SystemZ::IIHMux: |
1359 | 2 | expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false); |
1360 | 2 | return true; |
1361 | 14.6k | |
1362 | 39 | case SystemZ::NIFMux: |
1363 | 39 | expandRIPseudo(MI, SystemZ::NILF, SystemZ::NIHF, false); |
1364 | 39 | return true; |
1365 | 14.6k | |
1366 | 6 | case SystemZ::NILMux: |
1367 | 6 | expandRIPseudo(MI, SystemZ::NILL, SystemZ::NIHL, false); |
1368 | 6 | return true; |
1369 | 14.6k | |
1370 | 5 | case SystemZ::NIHMux: |
1371 | 5 | expandRIPseudo(MI, SystemZ::NILH, SystemZ::NIHH, false); |
1372 | 5 | return true; |
1373 | 14.6k | |
1374 | 2 | case SystemZ::OIFMux: |
1375 | 2 | expandRIPseudo(MI, SystemZ::OILF, SystemZ::OIHF, false); |
1376 | 2 | return true; |
1377 | 14.6k | |
1378 | 2 | case SystemZ::OILMux: |
1379 | 2 | expandRIPseudo(MI, SystemZ::OILL, SystemZ::OIHL, false); |
1380 | 2 | return true; |
1381 | 14.6k | |
1382 | 4 | case SystemZ::OIHMux: |
1383 | 4 | expandRIPseudo(MI, SystemZ::OILH, SystemZ::OIHH, false); |
1384 | 4 | return true; |
1385 | 14.6k | |
1386 | 7 | case SystemZ::XIFMux: |
1387 | 7 | expandRIPseudo(MI, SystemZ::XILF, SystemZ::XIHF, false); |
1388 | 7 | return true; |
1389 | 14.6k | |
1390 | 54 | case SystemZ::TMLMux: |
1391 | 54 | expandRIPseudo(MI, SystemZ::TMLL, SystemZ::TMHL, false); |
1392 | 54 | return true; |
1393 | 14.6k | |
1394 | 6 | case SystemZ::TMHMux: |
1395 | 6 | expandRIPseudo(MI, SystemZ::TMLH, SystemZ::TMHH, false); |
1396 | 6 | return true; |
1397 | 14.6k | |
1398 | 18 | case SystemZ::AHIMux: |
1399 | 18 | expandRIPseudo(MI, SystemZ::AHI, SystemZ::AIH, false); |
1400 | 18 | return true; |
1401 | 14.6k | |
1402 | 9 | case SystemZ::AHIMuxK: |
1403 | 9 | expandRIEPseudo(MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH); |
1404 | 9 | return true; |
1405 | 14.6k | |
1406 | 34 | case SystemZ::AFIMux: |
1407 | 34 | expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false); |
1408 | 34 | return true; |
1409 | 14.6k | |
1410 | 85 | case SystemZ::CHIMux: |
1411 | 85 | expandRIPseudo(MI, SystemZ::CHI, SystemZ::CIH, false); |
1412 | 85 | return true; |
1413 | 14.6k | |
1414 | 5 | case SystemZ::CFIMux: |
1415 | 5 | expandRIPseudo(MI, SystemZ::CFI, SystemZ::CIH, false); |
1416 | 5 | return true; |
1417 | 14.6k | |
1418 | 83 | case SystemZ::CLFIMux: |
1419 | 83 | expandRIPseudo(MI, SystemZ::CLFI, SystemZ::CLIH, false); |
1420 | 83 | return true; |
1421 | 14.6k | |
1422 | 2 | case SystemZ::CMux: |
1423 | 2 | expandRXYPseudo(MI, SystemZ::C, SystemZ::CHF); |
1424 | 2 | return true; |
1425 | 14.6k | |
1426 | 4 | case SystemZ::CLMux: |
1427 | 4 | expandRXYPseudo(MI, SystemZ::CL, SystemZ::CLHF); |
1428 | 4 | return true; |
1429 | 14.6k | |
1430 | 38 | case SystemZ::RISBMux: { |
1431 | 38 | bool DestIsHigh = isHighReg(MI.getOperand(0).getReg()); |
1432 | 38 | bool SrcIsHigh = isHighReg(MI.getOperand(2).getReg()); |
1433 | 38 | if (SrcIsHigh == DestIsHigh) |
1434 | 34 | MI.setDesc(get(DestIsHigh ? 34 SystemZ::RISBHH2 : SystemZ::RISBLL32 )); |
1435 | 4 | else { |
1436 | 4 | MI.setDesc(get(DestIsHigh ? SystemZ::RISBHL2 : SystemZ::RISBLH2 )); |
1437 | 4 | MI.getOperand(5).setImm(MI.getOperand(5).getImm() ^ 32); |
1438 | 4 | } |
1439 | 38 | return true; |
1440 | 14.6k | } |
1441 | 14.6k | |
1442 | 45 | case SystemZ::ADJDYNALLOC: |
1443 | 45 | splitAdjDynAlloc(MI); |
1444 | 45 | return true; |
1445 | 14.6k | |
1446 | 2 | case TargetOpcode::LOAD_STACK_GUARD: |
1447 | 2 | expandLoadStackGuard(&MI); |
1448 | 2 | return true; |
1449 | 14.6k | |
1450 | 13.0k | default: |
1451 | 13.0k | return false; |
1452 | 0 | } |
1453 | 0 | } |
1454 | | |
1455 | 44.4k | unsigned SystemZInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { |
1456 | 44.4k | if (MI.getOpcode() == TargetOpcode::INLINEASM44.4k ) { |
1457 | 253 | const MachineFunction *MF = MI.getParent()->getParent(); |
1458 | 253 | const char *AsmStr = MI.getOperand(0).getSymbolName(); |
1459 | 253 | return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); |
1460 | 253 | } |
1461 | 44.1k | return MI.getDesc().getSize(); |
1462 | 44.1k | } |
1463 | | |
1464 | | SystemZII::Branch |
1465 | 48.2k | SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const { |
1466 | 48.2k | switch (MI.getOpcode()) { |
1467 | 5.80k | case SystemZ::BR: |
1468 | 5.80k | case SystemZ::BI: |
1469 | 5.80k | case SystemZ::J: |
1470 | 5.80k | case SystemZ::JG: |
1471 | 5.80k | return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, |
1472 | 5.80k | SystemZ::CCMASK_ANY, &MI.getOperand(0)); |
1473 | 5.80k | |
1474 | 41.9k | case SystemZ::BRC: |
1475 | 41.9k | case SystemZ::BRCL: |
1476 | 41.9k | return SystemZII::Branch(SystemZII::BranchNormal, MI.getOperand(0).getImm(), |
1477 | 41.9k | MI.getOperand(1).getImm(), &MI.getOperand(2)); |
1478 | 41.9k | |
1479 | 27 | case SystemZ::BRCT: |
1480 | 27 | case SystemZ::BRCTH: |
1481 | 27 | return SystemZII::Branch(SystemZII::BranchCT, SystemZ::CCMASK_ICMP, |
1482 | 27 | SystemZ::CCMASK_CMP_NE, &MI.getOperand(2)); |
1483 | 27 | |
1484 | 8 | case SystemZ::BRCTG: |
1485 | 8 | return SystemZII::Branch(SystemZII::BranchCTG, SystemZ::CCMASK_ICMP, |
1486 | 8 | SystemZ::CCMASK_CMP_NE, &MI.getOperand(2)); |
1487 | 27 | |
1488 | 285 | case SystemZ::CIJ: |
1489 | 285 | case SystemZ::CRJ: |
1490 | 285 | return SystemZII::Branch(SystemZII::BranchC, SystemZ::CCMASK_ICMP, |
1491 | 285 | MI.getOperand(2).getImm(), &MI.getOperand(3)); |
1492 | 285 | |
1493 | 66 | case SystemZ::CLIJ: |
1494 | 66 | case SystemZ::CLRJ: |
1495 | 66 | return SystemZII::Branch(SystemZII::BranchCL, SystemZ::CCMASK_ICMP, |
1496 | 66 | MI.getOperand(2).getImm(), &MI.getOperand(3)); |
1497 | 66 | |
1498 | 84 | case SystemZ::CGIJ: |
1499 | 84 | case SystemZ::CGRJ: |
1500 | 84 | return SystemZII::Branch(SystemZII::BranchCG, SystemZ::CCMASK_ICMP, |
1501 | 84 | MI.getOperand(2).getImm(), &MI.getOperand(3)); |
1502 | 84 | |
1503 | 13 | case SystemZ::CLGIJ: |
1504 | 13 | case SystemZ::CLGRJ: |
1505 | 13 | return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP, |
1506 | 13 | MI.getOperand(2).getImm(), &MI.getOperand(3)); |
1507 | 13 | |
1508 | 0 | default: |
1509 | 0 | llvm_unreachable("Unrecognized branch opcode"); |
1510 | 0 | } |
1511 | 0 | } |
1512 | | |
1513 | | void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, |
1514 | | unsigned &LoadOpcode, |
1515 | 1.41k | unsigned &StoreOpcode) const { |
1516 | 1.41k | if (RC == &SystemZ::GR32BitRegClass || 1.41k RC == &SystemZ::ADDR32BitRegClass1.27k ) { |
1517 | 142 | LoadOpcode = SystemZ::L; |
1518 | 142 | StoreOpcode = SystemZ::ST; |
1519 | 1.41k | } else if (1.27k RC == &SystemZ::GRH32BitRegClass1.27k ) { |
1520 | 0 | LoadOpcode = SystemZ::LFH; |
1521 | 0 | StoreOpcode = SystemZ::STFH; |
1522 | 1.27k | } else if (1.27k RC == &SystemZ::GRX32BitRegClass1.27k ) { |
1523 | 20 | LoadOpcode = SystemZ::LMux; |
1524 | 20 | StoreOpcode = SystemZ::STMux; |
1525 | 1.27k | } else if (1.25k RC == &SystemZ::GR64BitRegClass || |
1526 | 1.25k | RC == &SystemZ::ADDR64BitRegClass1.10k ) { |
1527 | 226 | LoadOpcode = SystemZ::LG; |
1528 | 226 | StoreOpcode = SystemZ::STG; |
1529 | 1.25k | } else if (1.02k RC == &SystemZ::GR128BitRegClass || |
1530 | 1.02k | RC == &SystemZ::ADDR128BitRegClass957 ) { |
1531 | 70 | LoadOpcode = SystemZ::L128; |
1532 | 70 | StoreOpcode = SystemZ::ST128; |
1533 | 1.02k | } else if (957 RC == &SystemZ::FP32BitRegClass957 ) { |
1534 | 25 | LoadOpcode = SystemZ::LE; |
1535 | 25 | StoreOpcode = SystemZ::STE; |
1536 | 957 | } else if (932 RC == &SystemZ::FP64BitRegClass932 ) { |
1537 | 860 | LoadOpcode = SystemZ::LD; |
1538 | 860 | StoreOpcode = SystemZ::STD; |
1539 | 932 | } else if (72 RC == &SystemZ::FP128BitRegClass72 ) { |
1540 | 2 | LoadOpcode = SystemZ::LX; |
1541 | 2 | StoreOpcode = SystemZ::STX; |
1542 | 72 | } else if (70 RC == &SystemZ::VR32BitRegClass70 ) { |
1543 | 30 | LoadOpcode = SystemZ::VL32; |
1544 | 30 | StoreOpcode = SystemZ::VST32; |
1545 | 70 | } else if (40 RC == &SystemZ::VR64BitRegClass40 ) { |
1546 | 30 | LoadOpcode = SystemZ::VL64; |
1547 | 30 | StoreOpcode = SystemZ::VST64; |
1548 | 40 | } else if (10 RC == &SystemZ::VF128BitRegClass || |
1549 | 10 | RC == &SystemZ::VR128BitRegClass10 ) { |
1550 | 10 | LoadOpcode = SystemZ::VL; |
1551 | 10 | StoreOpcode = SystemZ::VST; |
1552 | 10 | } else |
1553 | 0 | llvm_unreachable("Unsupported regclass to load or store"); |
1554 | 1.41k | } |
1555 | | |
1556 | | unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, |
1557 | 6.64k | int64_t Offset) const { |
1558 | 6.64k | const MCInstrDesc &MCID = get(Opcode); |
1559 | 6.64k | int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8142 : Offset6.49k ); |
1560 | 6.64k | if (isUInt<12>(Offset) && 6.64k isUInt<12>(Offset2)6.04k ) { |
1561 | 6.04k | // Get the instruction to use for unsigned 12-bit displacements. |
1562 | 6.04k | int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); |
1563 | 6.04k | if (Disp12Opcode >= 0) |
1564 | 16 | return Disp12Opcode; |
1565 | 6.02k | |
1566 | 6.02k | // All address-related instructions can use unsigned 12-bit |
1567 | 6.02k | // displacements. |
1568 | 6.02k | return Opcode; |
1569 | 6.02k | } |
1570 | 595 | if (595 isInt<20>(Offset) && 595 isInt<20>(Offset2)490 ) { |
1571 | 490 | // Get the instruction to use for signed 20-bit displacements. |
1572 | 490 | int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); |
1573 | 490 | if (Disp20Opcode >= 0) |
1574 | 155 | return Disp20Opcode; |
1575 | 335 | |
1576 | 335 | // Check whether Opcode allows signed 20-bit displacements. |
1577 | 335 | if (335 MCID.TSFlags & SystemZII::Has20BitOffset335 ) |
1578 | 127 | return Opcode; |
1579 | 313 | } |
1580 | 313 | return 0; |
1581 | 313 | } |
1582 | | |
1583 | 100 | unsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const { |
1584 | 100 | switch (Opcode) { |
1585 | 4 | case SystemZ::L: return SystemZ::LT; |
1586 | 1 | case SystemZ::LY: return SystemZ::LT; |
1587 | 3 | case SystemZ::LG: return SystemZ::LTG; |
1588 | 2 | case SystemZ::LGF: return SystemZ::LTGF; |
1589 | 4 | case SystemZ::LR: return SystemZ::LTR; |
1590 | 4 | case SystemZ::LGFR: return SystemZ::LTGFR; |
1591 | 2 | case SystemZ::LGR: return SystemZ::LTGR; |
1592 | 3 | case SystemZ::LER: return SystemZ::LTEBR; |
1593 | 2 | case SystemZ::LDR: return SystemZ::LTDBR; |
1594 | 1 | case SystemZ::LXR: return SystemZ::LTXBR; |
1595 | 0 | case SystemZ::LCDFR: return SystemZ::LCDBR; |
1596 | 4 | case SystemZ::LPDFR: return SystemZ::LPDBR; |
1597 | 0 | case SystemZ::LNDFR: return SystemZ::LNDBR; |
1598 | 2 | case SystemZ::LCDFR_32: return SystemZ::LCEBR; |
1599 | 6 | case SystemZ::LPDFR_32: return SystemZ::LPEBR; |
1600 | 2 | case SystemZ::LNDFR_32: return SystemZ::LNEBR; |
1601 | 100 | // On zEC12 we prefer to use RISBGN. But if there is a chance to |
1602 | 100 | // actually use the condition code, we may turn it back into RISGB. |
1603 | 100 | // Note that RISBG is not really a "load-and-test" instruction, |
1604 | 100 | // but sets the same condition code values, so is OK to use here. |
1605 | 1 | case SystemZ::RISBGN: return SystemZ::RISBG; |
1606 | 59 | default: return 0; |
1607 | 0 | } |
1608 | 0 | } |
1609 | | |
1610 | | // Return true if Mask matches the regexp 0*1+0*, given that zero masks |
1611 | | // have already been filtered out. Store the first set bit in LSB and |
1612 | | // the number of set bits in Length if so. |
1613 | 3.03k | static bool isStringOfOnes(uint64_t Mask, unsigned &LSB, unsigned &Length) { |
1614 | 3.03k | unsigned First = findFirstSet(Mask); |
1615 | 3.03k | uint64_t Top = (Mask >> First) + 1; |
1616 | 3.03k | if ((Top & -Top) == Top3.03k ) { |
1617 | 2.52k | LSB = First; |
1618 | 2.52k | Length = findFirstSet(Top); |
1619 | 2.52k | return true; |
1620 | 2.52k | } |
1621 | 508 | return false; |
1622 | 508 | } |
1623 | | |
1624 | | bool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize, |
1625 | 2.75k | unsigned &Start, unsigned &End) const { |
1626 | 2.75k | // Reject trivial all-zero masks. |
1627 | 2.75k | Mask &= allOnes(BitSize); |
1628 | 2.75k | if (Mask == 0) |
1629 | 0 | return false; |
1630 | 2.75k | |
1631 | 2.75k | // Handle the 1+0+ or 0+1+0* cases. Start then specifies the index of |
1632 | 2.75k | // the msb and End specifies the index of the lsb. |
1633 | 2.75k | unsigned LSB, Length; |
1634 | 2.75k | if (isStringOfOnes(Mask, LSB, Length)2.75k ) { |
1635 | 2.47k | Start = 63 - (LSB + Length - 1); |
1636 | 2.47k | End = 63 - LSB; |
1637 | 2.47k | return true; |
1638 | 2.47k | } |
1639 | 278 | |
1640 | 278 | // Handle the wrap-around 1+0+1+ cases. Start then specifies the msb |
1641 | 278 | // of the low 1s and End specifies the lsb of the high 1s. |
1642 | 278 | if (278 isStringOfOnes(Mask ^ allOnes(BitSize), LSB, Length)278 ) { |
1643 | 48 | assert(LSB > 0 && "Bottom bit must be set"); |
1644 | 48 | assert(LSB + Length < BitSize && "Top bit must be set"); |
1645 | 48 | Start = 63 - (LSB - 1); |
1646 | 48 | End = 63 - (LSB + Length); |
1647 | 48 | return true; |
1648 | 48 | } |
1649 | 230 | |
1650 | 230 | return false; |
1651 | 230 | } |
1652 | | |
1653 | | unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode, |
1654 | | SystemZII::FusedCompareType Type, |
1655 | 1.13k | const MachineInstr *MI) const { |
1656 | 1.13k | switch (Opcode) { |
1657 | 156 | case SystemZ::CHI: |
1658 | 156 | case SystemZ::CGHI: |
1659 | 156 | if (!(MI && 156 isInt<8>(MI->getOperand(1).getImm())156 )) |
1660 | 26 | return 0; |
1661 | 130 | break; |
1662 | 129 | case SystemZ::CLFI: |
1663 | 129 | case SystemZ::CLGFI: |
1664 | 129 | if (!(MI && 129 isUInt<8>(MI->getOperand(1).getImm())129 )) |
1665 | 112 | return 0; |
1666 | 17 | break; |
1667 | 26 | case SystemZ::CL: |
1668 | 26 | case SystemZ::CLG: |
1669 | 26 | if (!STI.hasMiscellaneousExtensions()) |
1670 | 22 | return 0; |
1671 | 4 | if (4 !(MI && 4 MI->getOperand(3).getReg() == 04 )) |
1672 | 2 | return 0; |
1673 | 2 | break; |
1674 | 973 | } |
1675 | 973 | switch (Type) { |
1676 | 500 | case SystemZII::CompareAndBranch: |
1677 | 500 | switch (Opcode) { |
1678 | 77 | case SystemZ::CR: |
1679 | 77 | return SystemZ::CRJ; |
1680 | 23 | case SystemZ::CGR: |
1681 | 23 | return SystemZ::CGRJ; |
1682 | 56 | case SystemZ::CHI: |
1683 | 56 | return SystemZ::CIJ; |
1684 | 35 | case SystemZ::CGHI: |
1685 | 35 | return SystemZ::CGIJ; |
1686 | 33 | case SystemZ::CLR: |
1687 | 33 | return SystemZ::CLRJ; |
1688 | 9 | case SystemZ::CLGR: |
1689 | 9 | return SystemZ::CLGRJ; |
1690 | 7 | case SystemZ::CLFI: |
1691 | 7 | return SystemZ::CLIJ; |
1692 | 2 | case SystemZ::CLGFI: |
1693 | 2 | return SystemZ::CLGIJ; |
1694 | 258 | default: |
1695 | 258 | return 0; |
1696 | 0 | } |
1697 | 439 | case SystemZII::CompareAndReturn: |
1698 | 439 | switch (Opcode) { |
1699 | 1 | case SystemZ::CR: |
1700 | 1 | return SystemZ::CRBReturn; |
1701 | 5 | case SystemZ::CGR: |
1702 | 5 | return SystemZ::CGRBReturn; |
1703 | 25 | case SystemZ::CHI: |
1704 | 25 | return SystemZ::CIBReturn; |
1705 | 5 | case SystemZ::CGHI: |
1706 | 5 | return SystemZ::CGIBReturn; |
1707 | 7 | case SystemZ::CLR: |
1708 | 7 | return SystemZ::CLRBReturn; |
1709 | 9 | case SystemZ::CLGR: |
1710 | 9 | return SystemZ::CLGRBReturn; |
1711 | 3 | case SystemZ::CLFI: |
1712 | 3 | return SystemZ::CLIBReturn; |
1713 | 1 | case SystemZ::CLGFI: |
1714 | 1 | return SystemZ::CLGIBReturn; |
1715 | 383 | default: |
1716 | 383 | return 0; |
1717 | 0 | } |
1718 | 23 | case SystemZII::CompareAndSibcall: |
1719 | 23 | switch (Opcode) { |
1720 | 7 | case SystemZ::CR: |
1721 | 7 | return SystemZ::CRBCall; |
1722 | 1 | case SystemZ::CGR: |
1723 | 1 | return SystemZ::CGRBCall; |
1724 | 6 | case SystemZ::CHI: |
1725 | 6 | return SystemZ::CIBCall; |
1726 | 1 | case SystemZ::CGHI: |
1727 | 1 | return SystemZ::CGIBCall; |
1728 | 1 | case SystemZ::CLR: |
1729 | 1 | return SystemZ::CLRBCall; |
1730 | 1 | case SystemZ::CLGR: |
1731 | 1 | return SystemZ::CLGRBCall; |
1732 | 1 | case SystemZ::CLFI: |
1733 | 1 | return SystemZ::CLIBCall; |
1734 | 1 | case SystemZ::CLGFI: |
1735 | 1 | return SystemZ::CLGIBCall; |
1736 | 4 | default: |
1737 | 4 | return 0; |
1738 | 0 | } |
1739 | 11 | case SystemZII::CompareAndTrap: |
1740 | 11 | switch (Opcode) { |
1741 | 1 | case SystemZ::CR: |
1742 | 1 | return SystemZ::CRT; |
1743 | 1 | case SystemZ::CGR: |
1744 | 1 | return SystemZ::CGRT; |
1745 | 1 | case SystemZ::CHI: |
1746 | 1 | return SystemZ::CIT; |
1747 | 1 | case SystemZ::CGHI: |
1748 | 1 | return SystemZ::CGIT; |
1749 | 1 | case SystemZ::CLR: |
1750 | 1 | return SystemZ::CLRT; |
1751 | 1 | case SystemZ::CLGR: |
1752 | 1 | return SystemZ::CLGRT; |
1753 | 1 | case SystemZ::CLFI: |
1754 | 1 | return SystemZ::CLFIT; |
1755 | 1 | case SystemZ::CLGFI: |
1756 | 1 | return SystemZ::CLGIT; |
1757 | 1 | case SystemZ::CL: |
1758 | 1 | return SystemZ::CLT; |
1759 | 1 | case SystemZ::CLG: |
1760 | 1 | return SystemZ::CLGT; |
1761 | 1 | default: |
1762 | 1 | return 0; |
1763 | 0 | } |
1764 | 0 | } |
1765 | 0 | return 0; |
1766 | 0 | } |
1767 | | |
1768 | 108 | unsigned SystemZInstrInfo::getLoadAndTrap(unsigned Opcode) const { |
1769 | 108 | if (!STI.hasLoadAndTrap()) |
1770 | 74 | return 0; |
1771 | 34 | switch (Opcode) { |
1772 | 5 | case SystemZ::L: |
1773 | 5 | case SystemZ::LY: |
1774 | 5 | return SystemZ::LAT; |
1775 | 5 | case SystemZ::LG: |
1776 | 5 | return SystemZ::LGAT; |
1777 | 4 | case SystemZ::LFH: |
1778 | 4 | return SystemZ::LFHAT; |
1779 | 5 | case SystemZ::LLGF: |
1780 | 5 | return SystemZ::LLGFAT; |
1781 | 4 | case SystemZ::LLGT: |
1782 | 4 | return SystemZ::LLGTAT; |
1783 | 11 | } |
1784 | 11 | return 0; |
1785 | 11 | } |
1786 | | |
1787 | | void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, |
1788 | | MachineBasicBlock::iterator MBBI, |
1789 | 78 | unsigned Reg, uint64_t Value) const { |
1790 | 78 | DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc()78 : DebugLoc()0 ; |
1791 | 78 | unsigned Opcode; |
1792 | 78 | if (isInt<16>(Value)) |
1793 | 20 | Opcode = SystemZ::LGHI; |
1794 | 58 | else if (58 SystemZ::isImmLL(Value)58 ) |
1795 | 0 | Opcode = SystemZ::LLILL; |
1796 | 58 | else if (58 SystemZ::isImmLH(Value)58 ) { |
1797 | 58 | Opcode = SystemZ::LLILH; |
1798 | 58 | Value >>= 16; |
1799 | 58 | } else { |
1800 | 0 | assert(isInt<32>(Value) && "Huge values not handled yet"); |
1801 | 0 | Opcode = SystemZ::LGFI; |
1802 | 0 | } |
1803 | 78 | BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); |
1804 | 78 | } |
1805 | | |
1806 | | bool SystemZInstrInfo:: |
1807 | | areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb, |
1808 | 781 | AliasAnalysis *AA) const { |
1809 | 781 | |
1810 | 781 | if (!MIa.hasOneMemOperand() || 781 !MIb.hasOneMemOperand()778 ) |
1811 | 3 | return false; |
1812 | 778 | |
1813 | 778 | // If mem-operands show that the same address Value is used by both |
1814 | 778 | // instructions, check for non-overlapping offsets and widths. Not |
1815 | 778 | // sure if a register based analysis would be an improvement... |
1816 | 778 | |
1817 | 778 | MachineMemOperand *MMOa = *MIa.memoperands_begin(); |
1818 | 778 | MachineMemOperand *MMOb = *MIb.memoperands_begin(); |
1819 | 778 | const Value *VALa = MMOa->getValue(); |
1820 | 778 | const Value *VALb = MMOb->getValue(); |
1821 | 778 | bool SameVal = (VALa && VALb484 && (VALa == VALb)365 ); |
1822 | 778 | if (!SameVal778 ) { |
1823 | 609 | const PseudoSourceValue *PSVa = MMOa->getPseudoValue(); |
1824 | 609 | const PseudoSourceValue *PSVb = MMOb->getPseudoValue(); |
1825 | 609 | if (PSVa && 609 PSVb248 && (PSVa == PSVb)74 ) |
1826 | 66 | SameVal = true; |
1827 | 609 | } |
1828 | 778 | if (SameVal778 ) { |
1829 | 235 | int OffsetA = MMOa->getOffset(), OffsetB = MMOb->getOffset(); |
1830 | 235 | int WidthA = MMOa->getSize(), WidthB = MMOb->getSize(); |
1831 | 235 | int LowOffset = OffsetA < OffsetB ? OffsetA10 : OffsetB225 ; |
1832 | 235 | int HighOffset = OffsetA < OffsetB ? OffsetB10 : OffsetA225 ; |
1833 | 235 | int LowWidth = (LowOffset == OffsetA) ? WidthA203 : WidthB32 ; |
1834 | 235 | if (LowOffset + LowWidth <= HighOffset) |
1835 | 42 | return true; |
1836 | 736 | } |
1837 | 736 | |
1838 | 736 | return false; |
1839 | 736 | } |