[SystemZ] Immediate compare-and-branch support
[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 "SystemZInstrInfo.h"
15 #include "SystemZInstrBuilder.h"
16 #include "llvm/Target/TargetMachine.h"
17
18 #define GET_INSTRINFO_CTOR
19 #define GET_INSTRMAP_INFO
20 #include "SystemZGenInstrInfo.inc"
21
22 using namespace llvm;
23
24 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
25   : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP),
26     RI(tm, *this) {
27 }
28
29 // MI is a 128-bit load or store.  Split it into two 64-bit loads or stores,
30 // each having the opcode given by NewOpcode.
31 void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI,
32                                  unsigned NewOpcode) const {
33   MachineBasicBlock *MBB = MI->getParent();
34   MachineFunction &MF = *MBB->getParent();
35
36   // Get two load or store instructions.  Use the original instruction for one
37   // of them (arbitarily the second here) and create a clone for the other.
38   MachineInstr *EarlierMI = MF.CloneMachineInstr(MI);
39   MBB->insert(MI, EarlierMI);
40
41   // Set up the two 64-bit registers.
42   MachineOperand &HighRegOp = EarlierMI->getOperand(0);
43   MachineOperand &LowRegOp = MI->getOperand(0);
44   HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_high));
45   LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_low));
46
47   // The address in the first (high) instruction is already correct.
48   // Adjust the offset in the second (low) instruction.
49   MachineOperand &HighOffsetOp = EarlierMI->getOperand(2);
50   MachineOperand &LowOffsetOp = MI->getOperand(2);
51   LowOffsetOp.setImm(LowOffsetOp.getImm() + 8);
52
53   // Set the opcodes.
54   unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm());
55   unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm());
56   assert(HighOpcode && LowOpcode && "Both offsets should be in range");
57
58   EarlierMI->setDesc(get(HighOpcode));
59   MI->setDesc(get(LowOpcode));
60 }
61
62 // Split ADJDYNALLOC instruction MI.
63 void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const {
64   MachineBasicBlock *MBB = MI->getParent();
65   MachineFunction &MF = *MBB->getParent();
66   MachineFrameInfo *MFFrame = MF.getFrameInfo();
67   MachineOperand &OffsetMO = MI->getOperand(2);
68
69   uint64_t Offset = (MFFrame->getMaxCallFrameSize() +
70                      SystemZMC::CallFrameSize +
71                      OffsetMO.getImm());
72   unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset);
73   assert(NewOpcode && "No support for huge argument lists yet");
74   MI->setDesc(get(NewOpcode));
75   OffsetMO.setImm(Offset);
76 }
77
78 // If MI is a simple load or store for a frame object, return the register
79 // it loads or stores and set FrameIndex to the index of the frame object.
80 // Return 0 otherwise.
81 //
82 // Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
83 static int isSimpleMove(const MachineInstr *MI, int &FrameIndex, int Flag) {
84   const MCInstrDesc &MCID = MI->getDesc();
85   if ((MCID.TSFlags & Flag) &&
86       MI->getOperand(1).isFI() &&
87       MI->getOperand(2).getImm() == 0 &&
88       MI->getOperand(3).getReg() == 0) {
89     FrameIndex = MI->getOperand(1).getIndex();
90     return MI->getOperand(0).getReg();
91   }
92   return 0;
93 }
94
95 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
96                                                int &FrameIndex) const {
97   return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad);
98 }
99
100 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
101                                               int &FrameIndex) const {
102   return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore);
103 }
104
105 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
106                                      MachineBasicBlock *&TBB,
107                                      MachineBasicBlock *&FBB,
108                                      SmallVectorImpl<MachineOperand> &Cond,
109                                      bool AllowModify) const {
110   // Most of the code and comments here are boilerplate.
111
112   // Start from the bottom of the block and work up, examining the
113   // terminator instructions.
114   MachineBasicBlock::iterator I = MBB.end();
115   while (I != MBB.begin()) {
116     --I;
117     if (I->isDebugValue())
118       continue;
119
120     // Working from the bottom, when we see a non-terminator instruction, we're
121     // done.
122     if (!isUnpredicatedTerminator(I))
123       break;
124
125     // A terminator that isn't a branch can't easily be handled by this
126     // analysis.
127     if (!I->isBranch())
128       return true;
129
130     // Can't handle indirect branches.
131     SystemZII::Branch Branch(getBranchInfo(I));
132     if (!Branch.Target->isMBB())
133       return true;
134
135     // Punt on compound branches.
136     if (Branch.Type != SystemZII::BranchNormal)
137       return true;
138
139     if (Branch.CCMask == SystemZ::CCMASK_ANY) {
140       // Handle unconditional branches.
141       if (!AllowModify) {
142         TBB = Branch.Target->getMBB();
143         continue;
144       }
145
146       // If the block has any instructions after a JMP, delete them.
147       while (llvm::next(I) != MBB.end())
148         llvm::next(I)->eraseFromParent();
149
150       Cond.clear();
151       FBB = 0;
152
153       // Delete the JMP if it's equivalent to a fall-through.
154       if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) {
155         TBB = 0;
156         I->eraseFromParent();
157         I = MBB.end();
158         continue;
159       }
160
161       // TBB is used to indicate the unconditinal destination.
162       TBB = Branch.Target->getMBB();
163       continue;
164     }
165
166     // Working from the bottom, handle the first conditional branch.
167     if (Cond.empty()) {
168       // FIXME: add X86-style branch swap
169       FBB = TBB;
170       TBB = Branch.Target->getMBB();
171       Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
172       continue;
173     }
174
175     // Handle subsequent conditional branches.
176     assert(Cond.size() == 1);
177     assert(TBB);
178
179     // Only handle the case where all conditional branches branch to the same
180     // destination.
181     if (TBB != Branch.Target->getMBB())
182       return true;
183
184     // If the conditions are the same, we can leave them alone.
185     unsigned OldCond = Cond[0].getImm();
186     if (OldCond == Branch.CCMask)
187       continue;
188
189     // FIXME: Try combining conditions like X86 does.  Should be easy on Z!
190   }
191
192   return false;
193 }
194
195 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
196   // Most of the code and comments here are boilerplate.
197   MachineBasicBlock::iterator I = MBB.end();
198   unsigned Count = 0;
199
200   while (I != MBB.begin()) {
201     --I;
202     if (I->isDebugValue())
203       continue;
204     if (!I->isBranch())
205       break;
206     if (!getBranchInfo(I).Target->isMBB())
207       break;
208     // Remove the branch.
209     I->eraseFromParent();
210     I = MBB.end();
211     ++Count;
212   }
213
214   return Count;
215 }
216
217 unsigned
218 SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
219                                MachineBasicBlock *FBB,
220                                const SmallVectorImpl<MachineOperand> &Cond,
221                                DebugLoc DL) const {
222   // In this function we output 32-bit branches, which should always
223   // have enough range.  They can be shortened and relaxed by later code
224   // in the pipeline, if desired.
225
226   // Shouldn't be a fall through.
227   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
228   assert((Cond.size() == 1 || Cond.size() == 0) &&
229          "SystemZ branch conditions have one component!");
230
231   if (Cond.empty()) {
232     // Unconditional branch?
233     assert(!FBB && "Unconditional branch with multiple successors!");
234     BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB);
235     return 1;
236   }
237
238   // Conditional branch.
239   unsigned Count = 0;
240   unsigned CC = Cond[0].getImm();
241   BuildMI(&MBB, DL, get(SystemZ::BRC)).addImm(CC).addMBB(TBB);
242   ++Count;
243
244   if (FBB) {
245     // Two-way Conditional branch. Insert the second branch.
246     BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB);
247     ++Count;
248   }
249   return Count;
250 }
251
252 void
253 SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
254                               MachineBasicBlock::iterator MBBI, DebugLoc DL,
255                               unsigned DestReg, unsigned SrcReg,
256                               bool KillSrc) const {
257   // Split 128-bit GPR moves into two 64-bit moves.  This handles ADDR128 too.
258   if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) {
259     copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_high),
260                 RI.getSubReg(SrcReg, SystemZ::subreg_high), KillSrc);
261     copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_low),
262                 RI.getSubReg(SrcReg, SystemZ::subreg_low), KillSrc);
263     return;
264   }
265
266   // Everything else needs only one instruction.
267   unsigned Opcode;
268   if (SystemZ::GR32BitRegClass.contains(DestReg, SrcReg))
269     Opcode = SystemZ::LR;
270   else if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg))
271     Opcode = SystemZ::LGR;
272   else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg))
273     Opcode = SystemZ::LER;
274   else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg))
275     Opcode = SystemZ::LDR;
276   else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg))
277     Opcode = SystemZ::LXR;
278   else
279     llvm_unreachable("Impossible reg-to-reg copy");
280
281   BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
282     .addReg(SrcReg, getKillRegState(KillSrc));
283 }
284
285 void
286 SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
287                                       MachineBasicBlock::iterator MBBI,
288                                       unsigned SrcReg, bool isKill,
289                                       int FrameIdx,
290                                       const TargetRegisterClass *RC,
291                                       const TargetRegisterInfo *TRI) const {
292   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
293
294   // Callers may expect a single instruction, so keep 128-bit moves
295   // together for now and lower them after register allocation.
296   unsigned LoadOpcode, StoreOpcode;
297   getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
298   addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode))
299                     .addReg(SrcReg, getKillRegState(isKill)), FrameIdx);
300 }
301
302 void
303 SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
304                                        MachineBasicBlock::iterator MBBI,
305                                        unsigned DestReg, int FrameIdx,
306                                        const TargetRegisterClass *RC,
307                                        const TargetRegisterInfo *TRI) const {
308   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
309
310   // Callers may expect a single instruction, so keep 128-bit moves
311   // together for now and lower them after register allocation.
312   unsigned LoadOpcode, StoreOpcode;
313   getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
314   addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg),
315                     FrameIdx);
316 }
317
318 bool
319 SystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
320   switch (MI->getOpcode()) {
321   case SystemZ::L128:
322     splitMove(MI, SystemZ::LG);
323     return true;
324
325   case SystemZ::ST128:
326     splitMove(MI, SystemZ::STG);
327     return true;
328
329   case SystemZ::LX:
330     splitMove(MI, SystemZ::LD);
331     return true;
332
333   case SystemZ::STX:
334     splitMove(MI, SystemZ::STD);
335     return true;
336
337   case SystemZ::ADJDYNALLOC:
338     splitAdjDynAlloc(MI);
339     return true;
340
341   default:
342     return false;
343   }
344 }
345
346 bool SystemZInstrInfo::
347 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
348   assert(Cond.size() == 1 && "Invalid branch condition!");
349   Cond[0].setImm(Cond[0].getImm() ^ SystemZ::CCMASK_ANY);
350   return false;
351 }
352
353 uint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const {
354   if (MI->getOpcode() == TargetOpcode::INLINEASM) {
355     const MachineFunction *MF = MI->getParent()->getParent();
356     const char *AsmStr = MI->getOperand(0).getSymbolName();
357     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
358   }
359   return MI->getDesc().getSize();
360 }
361
362 SystemZII::Branch
363 SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const {
364   switch (MI->getOpcode()) {
365   case SystemZ::BR:
366   case SystemZ::J:
367   case SystemZ::JG:
368     return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY,
369                              &MI->getOperand(0));
370
371   case SystemZ::BRC:
372   case SystemZ::BRCL:
373     return SystemZII::Branch(SystemZII::BranchNormal,
374                              MI->getOperand(0).getImm(), &MI->getOperand(1));
375
376   case SystemZ::CIJ:
377   case SystemZ::CRJ:
378     return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(),
379                              &MI->getOperand(3));
380
381   case SystemZ::CGIJ:
382   case SystemZ::CGRJ:
383     return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(),
384                              &MI->getOperand(3));
385
386   default:
387     llvm_unreachable("Unrecognized branch opcode");
388   }
389 }
390
391 void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
392                                            unsigned &LoadOpcode,
393                                            unsigned &StoreOpcode) const {
394   if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
395     LoadOpcode = SystemZ::L;
396     StoreOpcode = SystemZ::ST32;
397   } else if (RC == &SystemZ::GR64BitRegClass ||
398              RC == &SystemZ::ADDR64BitRegClass) {
399     LoadOpcode = SystemZ::LG;
400     StoreOpcode = SystemZ::STG;
401   } else if (RC == &SystemZ::GR128BitRegClass ||
402              RC == &SystemZ::ADDR128BitRegClass) {
403     LoadOpcode = SystemZ::L128;
404     StoreOpcode = SystemZ::ST128;
405   } else if (RC == &SystemZ::FP32BitRegClass) {
406     LoadOpcode = SystemZ::LE;
407     StoreOpcode = SystemZ::STE;
408   } else if (RC == &SystemZ::FP64BitRegClass) {
409     LoadOpcode = SystemZ::LD;
410     StoreOpcode = SystemZ::STD;
411   } else if (RC == &SystemZ::FP128BitRegClass) {
412     LoadOpcode = SystemZ::LX;
413     StoreOpcode = SystemZ::STX;
414   } else
415     llvm_unreachable("Unsupported regclass to load or store");
416 }
417
418 unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode,
419                                               int64_t Offset) const {
420   const MCInstrDesc &MCID = get(Opcode);
421   int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset);
422   if (isUInt<12>(Offset) && isUInt<12>(Offset2)) {
423     // Get the instruction to use for unsigned 12-bit displacements.
424     int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
425     if (Disp12Opcode >= 0)
426       return Disp12Opcode;
427
428     // All address-related instructions can use unsigned 12-bit
429     // displacements.
430     return Opcode;
431   }
432   if (isInt<20>(Offset) && isInt<20>(Offset2)) {
433     // Get the instruction to use for signed 20-bit displacements.
434     int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
435     if (Disp20Opcode >= 0)
436       return Disp20Opcode;
437
438     // Check whether Opcode allows signed 20-bit displacements.
439     if (MCID.TSFlags & SystemZII::Has20BitOffset)
440       return Opcode;
441   }
442   return 0;
443 }
444
445 unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode,
446                                                const MachineInstr *MI) const {
447   switch (Opcode) {
448   case SystemZ::CR:
449     return SystemZ::CRJ;
450   case SystemZ::CGR:
451     return SystemZ::CGRJ;
452   case SystemZ::CHI:
453     return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0;
454   case SystemZ::CGHI:
455     return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0;
456   default:
457     return 0;
458   }
459 }
460
461 void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
462                                      MachineBasicBlock::iterator MBBI,
463                                      unsigned Reg, uint64_t Value) const {
464   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
465   unsigned Opcode;
466   if (isInt<16>(Value))
467     Opcode = SystemZ::LGHI;
468   else if (SystemZ::isImmLL(Value))
469     Opcode = SystemZ::LLILL;
470   else if (SystemZ::isImmLH(Value)) {
471     Opcode = SystemZ::LLILH;
472     Value >>= 16;
473   } else {
474     assert(isInt<32>(Value) && "Huge values not handled yet");
475     Opcode = SystemZ::LGFI;
476   }
477   BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
478 }