9488defc0afe8ff9d5b92e4242c593765649c12c
[oota-llvm.git] / lib / Target / SystemZ / SystemZInstrInfo.cpp
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 "SystemZ.h"
15 #include "SystemZInstrBuilder.h"
16 #include "SystemZInstrInfo.h"
17 #include "SystemZMachineFunctionInfo.h"
18 #include "SystemZTargetMachine.h"
19 #include "SystemZGenInstrInfo.inc"
20 #include "llvm/Function.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/PseudoSourceValue.h"
25 #include "llvm/Support/ErrorHandling.h"
26 using namespace llvm;
27
28 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
29   : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)),
30     RI(tm, *this), TM(tm) {
31 }
32
33 /// isGVStub - Return true if the GV requires an extra load to get the
34 /// real address.
35 static inline bool isGVStub(GlobalValue *GV, SystemZTargetMachine &TM) {
36   return TM.getSubtarget<SystemZSubtarget>().GVRequiresExtraLoad(GV, TM, false);
37 }
38
39 void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
40                                           MachineBasicBlock::iterator MI,
41                                     unsigned SrcReg, bool isKill, int FrameIdx,
42                                            const TargetRegisterClass *RC,
43                                            const TargetRegisterInfo *TRI) const {
44   DebugLoc DL;
45   if (MI != MBB.end()) DL = MI->getDebugLoc();
46
47   unsigned Opc = 0;
48   if (RC == &SystemZ::GR32RegClass ||
49       RC == &SystemZ::ADDR32RegClass)
50     Opc = SystemZ::MOV32mr;
51   else if (RC == &SystemZ::GR64RegClass ||
52            RC == &SystemZ::ADDR64RegClass) {
53     Opc = SystemZ::MOV64mr;
54   } else if (RC == &SystemZ::FP32RegClass) {
55     Opc = SystemZ::FMOV32mr;
56   } else if (RC == &SystemZ::FP64RegClass) {
57     Opc = SystemZ::FMOV64mr;
58   } else if (RC == &SystemZ::GR64PRegClass) {
59     Opc = SystemZ::MOV64Pmr;
60   } else if (RC == &SystemZ::GR128RegClass) {
61     Opc = SystemZ::MOV128mr;
62   } else
63     llvm_unreachable("Unsupported regclass to store");
64
65   addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx)
66     .addReg(SrcReg, getKillRegState(isKill));
67 }
68
69 void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
70                                            MachineBasicBlock::iterator MI,
71                                            unsigned DestReg, int FrameIdx,
72                                             const TargetRegisterClass *RC,
73                                             const TargetRegisterInfo *TRI) const{
74   DebugLoc DL;
75   if (MI != MBB.end()) DL = MI->getDebugLoc();
76
77   unsigned Opc = 0;
78   if (RC == &SystemZ::GR32RegClass ||
79       RC == &SystemZ::ADDR32RegClass)
80     Opc = SystemZ::MOV32rm;
81   else if (RC == &SystemZ::GR64RegClass ||
82            RC == &SystemZ::ADDR64RegClass) {
83     Opc = SystemZ::MOV64rm;
84   } else if (RC == &SystemZ::FP32RegClass) {
85     Opc = SystemZ::FMOV32rm;
86   } else if (RC == &SystemZ::FP64RegClass) {
87     Opc = SystemZ::FMOV64rm;
88   } else if (RC == &SystemZ::GR64PRegClass) {
89     Opc = SystemZ::MOV64Prm;
90   } else if (RC == &SystemZ::GR128RegClass) {
91     Opc = SystemZ::MOV128rm;
92   } else
93     llvm_unreachable("Unsupported regclass to load");
94
95   addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx);
96 }
97
98 void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
99                                    MachineBasicBlock::iterator I, DebugLoc DL,
100                                    unsigned DestReg, unsigned SrcReg,
101                                    bool KillSrc) const {
102   unsigned Opc;
103   if (SystemZ::GR64RegClass.contains(DestReg, SrcReg))
104     Opc = SystemZ::MOV64rr;
105   else if (SystemZ::GR32RegClass.contains(DestReg, SrcReg))
106     Opc = SystemZ::MOV32rr;
107   else if (SystemZ::GR64PRegClass.contains(DestReg, SrcReg))
108     Opc = SystemZ::MOV64rrP;
109   else if (SystemZ::GR128RegClass.contains(DestReg, SrcReg))
110     Opc = SystemZ::MOV128rr;
111   else if (SystemZ::FP32RegClass.contains(DestReg, SrcReg))
112     Opc = SystemZ::FMOV32rr;
113   else if (SystemZ::FP64RegClass.contains(DestReg, SrcReg))
114     Opc = SystemZ::FMOV64rr;
115   else
116     llvm_unreachable("Impossible reg-to-reg copy");
117
118   BuildMI(MBB, I, DL, get(Opc), DestReg)
119     .addReg(SrcReg, getKillRegState(KillSrc));
120 }
121
122 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
123                                                int &FrameIndex) const {
124   switch (MI->getOpcode()) {
125   default: break;
126   case SystemZ::MOV32rm:
127   case SystemZ::MOV32rmy:
128   case SystemZ::MOV64rm:
129   case SystemZ::MOVSX32rm8:
130   case SystemZ::MOVSX32rm16y:
131   case SystemZ::MOVSX64rm8:
132   case SystemZ::MOVSX64rm16:
133   case SystemZ::MOVSX64rm32:
134   case SystemZ::MOVZX32rm8:
135   case SystemZ::MOVZX32rm16:
136   case SystemZ::MOVZX64rm8:
137   case SystemZ::MOVZX64rm16:
138   case SystemZ::MOVZX64rm32:
139   case SystemZ::FMOV32rm:
140   case SystemZ::FMOV32rmy:
141   case SystemZ::FMOV64rm:
142   case SystemZ::FMOV64rmy:
143   case SystemZ::MOV64Prm:
144   case SystemZ::MOV64Prmy:
145   case SystemZ::MOV128rm:
146     if (MI->getOperand(1).isFI() &&
147         MI->getOperand(2).isImm() && MI->getOperand(3).isReg() &&
148         MI->getOperand(2).getImm() == 0 && MI->getOperand(3).getReg() == 0) {
149       FrameIndex = MI->getOperand(1).getIndex();
150       return MI->getOperand(0).getReg();
151     }
152     break;
153   }
154   return 0;
155 }
156
157 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
158                                               int &FrameIndex) const {
159   switch (MI->getOpcode()) {
160   default: break;
161   case SystemZ::MOV32mr:
162   case SystemZ::MOV32mry:
163   case SystemZ::MOV64mr:
164   case SystemZ::MOV32m8r:
165   case SystemZ::MOV32m8ry:
166   case SystemZ::MOV32m16r:
167   case SystemZ::MOV32m16ry:
168   case SystemZ::MOV64m8r:
169   case SystemZ::MOV64m8ry:
170   case SystemZ::MOV64m16r:
171   case SystemZ::MOV64m16ry:
172   case SystemZ::MOV64m32r:
173   case SystemZ::MOV64m32ry:
174   case SystemZ::FMOV32mr:
175   case SystemZ::FMOV32mry:
176   case SystemZ::FMOV64mr:
177   case SystemZ::FMOV64mry:
178   case SystemZ::MOV64Pmr:
179   case SystemZ::MOV64Pmry:
180   case SystemZ::MOV128mr:
181     if (MI->getOperand(0).isFI() &&
182         MI->getOperand(1).isImm() && MI->getOperand(2).isReg() &&
183         MI->getOperand(1).getImm() == 0 && MI->getOperand(2).getReg() == 0) {
184       FrameIndex = MI->getOperand(0).getIndex();
185       return MI->getOperand(3).getReg();
186     }
187     break;
188   }
189   return 0;
190 }
191
192 bool SystemZInstrInfo::
193 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
194   assert(Cond.size() == 1 && "Invalid Xbranch condition!");
195
196   SystemZCC::CondCodes CC = static_cast<SystemZCC::CondCodes>(Cond[0].getImm());
197   Cond[0].setImm(getOppositeCondition(CC));
198   return false;
199 }
200
201 bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
202   const MCInstrDesc &MCID = MI->getDesc();
203   if (!MCID.isTerminator()) return false;
204
205   // Conditional branch is a special case.
206   if (MCID.isBranch() && !MCID.isBarrier())
207     return true;
208   if (!MCID.isPredicable())
209     return true;
210   return !isPredicated(MI);
211 }
212
213 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
214                                      MachineBasicBlock *&TBB,
215                                      MachineBasicBlock *&FBB,
216                                      SmallVectorImpl<MachineOperand> &Cond,
217                                      bool AllowModify) const {
218   // Start from the bottom of the block and work up, examining the
219   // terminator instructions.
220   MachineBasicBlock::iterator I = MBB.end();
221   while (I != MBB.begin()) {
222     --I;
223     if (I->isDebugValue())
224       continue;
225     // Working from the bottom, when we see a non-terminator
226     // instruction, we're done.
227     if (!isUnpredicatedTerminator(I))
228       break;
229
230     // A terminator that isn't a branch can't easily be handled
231     // by this analysis.
232     if (!I->getDesc().isBranch())
233       return true;
234
235     // Handle unconditional branches.
236     if (I->getOpcode() == SystemZ::JMP) {
237       if (!AllowModify) {
238         TBB = I->getOperand(0).getMBB();
239         continue;
240       }
241
242       // If the block has any instructions after a JMP, delete them.
243       while (llvm::next(I) != MBB.end())
244         llvm::next(I)->eraseFromParent();
245       Cond.clear();
246       FBB = 0;
247
248       // Delete the JMP if it's equivalent to a fall-through.
249       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
250         TBB = 0;
251         I->eraseFromParent();
252         I = MBB.end();
253         continue;
254       }
255
256       // TBB is used to indicate the unconditinal destination.
257       TBB = I->getOperand(0).getMBB();
258       continue;
259     }
260
261     // Handle conditional branches.
262     SystemZCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
263     if (BranchCode == SystemZCC::INVALID)
264       return true;  // Can't handle indirect branch.
265
266     // Working from the bottom, handle the first conditional branch.
267     if (Cond.empty()) {
268       FBB = TBB;
269       TBB = I->getOperand(0).getMBB();
270       Cond.push_back(MachineOperand::CreateImm(BranchCode));
271       continue;
272     }
273
274     // Handle subsequent conditional branches. Only handle the case where all
275     // conditional branches branch to the same destination.
276     assert(Cond.size() == 1);
277     assert(TBB);
278
279     // Only handle the case where all conditional branches branch to
280     // the same destination.
281     if (TBB != I->getOperand(0).getMBB())
282       return true;
283
284     SystemZCC::CondCodes OldBranchCode = (SystemZCC::CondCodes)Cond[0].getImm();
285     // If the conditions are the same, we can leave them alone.
286     if (OldBranchCode == BranchCode)
287       continue;
288
289     return true;
290   }
291
292   return false;
293 }
294
295 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
296   MachineBasicBlock::iterator I = MBB.end();
297   unsigned Count = 0;
298
299   while (I != MBB.begin()) {
300     --I;
301     if (I->isDebugValue())
302       continue;
303     if (I->getOpcode() != SystemZ::JMP &&
304         getCondFromBranchOpc(I->getOpcode()) == SystemZCC::INVALID)
305       break;
306     // Remove the branch.
307     I->eraseFromParent();
308     I = MBB.end();
309     ++Count;
310   }
311
312   return Count;
313 }
314
315 unsigned
316 SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
317                                MachineBasicBlock *FBB,
318                                const SmallVectorImpl<MachineOperand> &Cond,
319                                DebugLoc DL) const {
320   // Shouldn't be a fall through.
321   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
322   assert((Cond.size() == 1 || Cond.size() == 0) &&
323          "SystemZ branch conditions have one component!");
324
325   if (Cond.empty()) {
326     // Unconditional branch?
327     assert(!FBB && "Unconditional branch with multiple successors!");
328     BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(TBB);
329     return 1;
330   }
331
332   // Conditional branch.
333   unsigned Count = 0;
334   SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
335   BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
336   ++Count;
337
338   if (FBB) {
339     // Two-way Conditional branch. Insert the second branch.
340     BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(FBB);
341     ++Count;
342   }
343   return Count;
344 }
345
346 const MCInstrDesc&
347 SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const {
348   switch (CC) {
349   default:
350    llvm_unreachable("Unknown condition code!");
351   case SystemZCC::O:   return get(SystemZ::JO);
352   case SystemZCC::H:   return get(SystemZ::JH);
353   case SystemZCC::NLE: return get(SystemZ::JNLE);
354   case SystemZCC::L:   return get(SystemZ::JL);
355   case SystemZCC::NHE: return get(SystemZ::JNHE);
356   case SystemZCC::LH:  return get(SystemZ::JLH);
357   case SystemZCC::NE:  return get(SystemZ::JNE);
358   case SystemZCC::E:   return get(SystemZ::JE);
359   case SystemZCC::NLH: return get(SystemZ::JNLH);
360   case SystemZCC::HE:  return get(SystemZ::JHE);
361   case SystemZCC::NL:  return get(SystemZ::JNL);
362   case SystemZCC::LE:  return get(SystemZ::JLE);
363   case SystemZCC::NH:  return get(SystemZ::JNH);
364   case SystemZCC::NO:  return get(SystemZ::JNO);
365   }
366 }
367
368 SystemZCC::CondCodes
369 SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
370   switch (Opc) {
371   default:            return SystemZCC::INVALID;
372   case SystemZ::JO:   return SystemZCC::O;
373   case SystemZ::JH:   return SystemZCC::H;
374   case SystemZ::JNLE: return SystemZCC::NLE;
375   case SystemZ::JL:   return SystemZCC::L;
376   case SystemZ::JNHE: return SystemZCC::NHE;
377   case SystemZ::JLH:  return SystemZCC::LH;
378   case SystemZ::JNE:  return SystemZCC::NE;
379   case SystemZ::JE:   return SystemZCC::E;
380   case SystemZ::JNLH: return SystemZCC::NLH;
381   case SystemZ::JHE:  return SystemZCC::HE;
382   case SystemZ::JNL:  return SystemZCC::NL;
383   case SystemZ::JLE:  return SystemZCC::LE;
384   case SystemZ::JNH:  return SystemZCC::NH;
385   case SystemZ::JNO:  return SystemZCC::NO;
386   }
387 }
388
389 SystemZCC::CondCodes
390 SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC) const {
391   switch (CC) {
392   default:
393     llvm_unreachable("Invalid condition!");
394   case SystemZCC::O:   return SystemZCC::NO;
395   case SystemZCC::H:   return SystemZCC::NH;
396   case SystemZCC::NLE: return SystemZCC::LE;
397   case SystemZCC::L:   return SystemZCC::NL;
398   case SystemZCC::NHE: return SystemZCC::HE;
399   case SystemZCC::LH:  return SystemZCC::NLH;
400   case SystemZCC::NE:  return SystemZCC::E;
401   case SystemZCC::E:   return SystemZCC::NE;
402   case SystemZCC::NLH: return SystemZCC::LH;
403   case SystemZCC::HE:  return SystemZCC::NHE;
404   case SystemZCC::NL:  return SystemZCC::L;
405   case SystemZCC::LE:  return SystemZCC::NLE;
406   case SystemZCC::NH:  return SystemZCC::H;
407   case SystemZCC::NO:  return SystemZCC::O;
408   }
409 }
410
411 const MCInstrDesc&
412 SystemZInstrInfo::getLongDispOpc(unsigned Opc) const {
413   switch (Opc) {
414   default:
415     llvm_unreachable("Don't have long disp version of this instruction");
416   case SystemZ::MOV32mr:   return get(SystemZ::MOV32mry);
417   case SystemZ::MOV32rm:   return get(SystemZ::MOV32rmy);
418   case SystemZ::MOVSX32rm16: return get(SystemZ::MOVSX32rm16y);
419   case SystemZ::MOV32m8r:  return get(SystemZ::MOV32m8ry);
420   case SystemZ::MOV32m16r: return get(SystemZ::MOV32m16ry);
421   case SystemZ::MOV64m8r:  return get(SystemZ::MOV64m8ry);
422   case SystemZ::MOV64m16r: return get(SystemZ::MOV64m16ry);
423   case SystemZ::MOV64m32r: return get(SystemZ::MOV64m32ry);
424   case SystemZ::MOV8mi:    return get(SystemZ::MOV8miy);
425   case SystemZ::MUL32rm:   return get(SystemZ::MUL32rmy);
426   case SystemZ::CMP32rm:   return get(SystemZ::CMP32rmy);
427   case SystemZ::UCMP32rm:  return get(SystemZ::UCMP32rmy);
428   case SystemZ::FMOV32mr:  return get(SystemZ::FMOV32mry);
429   case SystemZ::FMOV64mr:  return get(SystemZ::FMOV64mry);
430   case SystemZ::FMOV32rm:  return get(SystemZ::FMOV32rmy);
431   case SystemZ::FMOV64rm:  return get(SystemZ::FMOV64rmy);
432   case SystemZ::MOV64Pmr:  return get(SystemZ::MOV64Pmry);
433   case SystemZ::MOV64Prm:  return get(SystemZ::MOV64Prmy);
434   }
435 }