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