SPUInstrInfo.cpp revision 600f171486708734e2b9c9c617528cfc51c16850
1//===- SPUInstrInfo.cpp - Cell SPU 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 Cell SPU implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SPURegisterNames.h"
15#include "SPUInstrInfo.h"
16#include "SPUInstrBuilder.h"
17#include "SPUTargetMachine.h"
18#include "SPUGenInstrInfo.inc"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/Support/Debug.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/raw_ostream.h"
23
24using namespace llvm;
25
26namespace {
27  //! Predicate for an unconditional branch instruction
28  inline bool isUncondBranch(const MachineInstr *I) {
29    unsigned opc = I->getOpcode();
30
31    return (opc == SPU::BR
32            || opc == SPU::BRA
33            || opc == SPU::BI);
34  }
35
36  //! Predicate for a conditional branch instruction
37  inline bool isCondBranch(const MachineInstr *I) {
38    unsigned opc = I->getOpcode();
39
40    return (opc == SPU::BRNZr32
41            || opc == SPU::BRNZv4i32
42            || opc == SPU::BRZr32
43            || opc == SPU::BRZv4i32
44            || opc == SPU::BRHNZr16
45            || opc == SPU::BRHNZv8i16
46            || opc == SPU::BRHZr16
47            || opc == SPU::BRHZv8i16);
48  }
49}
50
51SPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm)
52  : TargetInstrInfoImpl(SPUInsts, sizeof(SPUInsts)/sizeof(SPUInsts[0])),
53    TM(tm),
54    RI(*TM.getSubtargetImpl(), *this)
55{ /* NOP */ }
56
57bool
58SPUInstrInfo::isMoveInstr(const MachineInstr& MI,
59                          unsigned& sourceReg,
60                          unsigned& destReg,
61                          unsigned& SrcSR, unsigned& DstSR) const {
62  SrcSR = DstSR = 0;  // No sub-registers.
63
64  switch (MI.getOpcode()) {
65  default:
66    break;
67  case SPU::ORIv4i32:
68  case SPU::ORIr32:
69  case SPU::ORHIv8i16:
70  case SPU::ORHIr16:
71  case SPU::ORHIi8i16:
72  case SPU::ORBIv16i8:
73  case SPU::ORBIr8:
74  case SPU::ORIi16i32:
75  case SPU::ORIi8i32:
76  case SPU::AHIvec:
77  case SPU::AHIr16:
78  case SPU::AIv4i32:
79    assert(MI.getNumOperands() == 3 &&
80           MI.getOperand(0).isReg() &&
81           MI.getOperand(1).isReg() &&
82           MI.getOperand(2).isImm() &&
83           "invalid SPU ORI/ORHI/ORBI/AHI/AI/SFI/SFHI instruction!");
84    if (MI.getOperand(2).getImm() == 0) {
85      sourceReg = MI.getOperand(1).getReg();
86      destReg = MI.getOperand(0).getReg();
87      return true;
88    }
89    break;
90  case SPU::AIr32:
91    assert(MI.getNumOperands() == 3 &&
92           "wrong number of operands to AIr32");
93    if (MI.getOperand(0).isReg() &&
94        MI.getOperand(1).isReg() &&
95        (MI.getOperand(2).isImm() &&
96         MI.getOperand(2).getImm() == 0)) {
97      sourceReg = MI.getOperand(1).getReg();
98      destReg = MI.getOperand(0).getReg();
99      return true;
100    }
101    break;
102  case SPU::LRr8:
103  case SPU::LRr16:
104  case SPU::LRr32:
105  case SPU::LRf32:
106  case SPU::LRr64:
107  case SPU::LRf64:
108  case SPU::LRr128:
109  case SPU::LRv16i8:
110  case SPU::LRv8i16:
111  case SPU::LRv4i32:
112  case SPU::LRv4f32:
113  case SPU::LRv2i64:
114  case SPU::LRv2f64:
115  case SPU::ORv16i8_i8:
116  case SPU::ORv8i16_i16:
117  case SPU::ORv4i32_i32:
118  case SPU::ORv2i64_i64:
119  case SPU::ORv4f32_f32:
120  case SPU::ORv2f64_f64:
121  case SPU::ORi8_v16i8:
122  case SPU::ORi16_v8i16:
123  case SPU::ORi32_v4i32:
124  case SPU::ORi64_v2i64:
125  case SPU::ORf32_v4f32:
126  case SPU::ORf64_v2f64:
127/*
128  case SPU::ORi128_r64:
129  case SPU::ORi128_f64:
130  case SPU::ORi128_r32:
131  case SPU::ORi128_f32:
132  case SPU::ORi128_r16:
133  case SPU::ORi128_r8:
134*/
135  case SPU::ORi128_vec:
136/*
137  case SPU::ORr64_i128:
138  case SPU::ORf64_i128:
139  case SPU::ORr32_i128:
140  case SPU::ORf32_i128:
141  case SPU::ORr16_i128:
142  case SPU::ORr8_i128:
143*/
144  case SPU::ORvec_i128:
145/*
146  case SPU::ORr16_r32:
147  case SPU::ORr8_r32:
148  case SPU::ORf32_r32:
149  case SPU::ORr32_f32:
150  case SPU::ORr32_r16:
151  case SPU::ORr32_r8:
152  case SPU::ORr16_r64:
153  case SPU::ORr8_r64:
154  case SPU::ORr64_r16:
155  case SPU::ORr64_r8:
156*/
157  case SPU::ORr64_r32:
158  case SPU::ORr32_r64:
159  case SPU::ORf32_r32:
160  case SPU::ORr32_f32:
161  case SPU::ORf64_r64:
162  case SPU::ORr64_f64: {
163    assert(MI.getNumOperands() == 2 &&
164           MI.getOperand(0).isReg() &&
165           MI.getOperand(1).isReg() &&
166           "invalid SPU OR<type>_<vec> or LR instruction!");
167      sourceReg = MI.getOperand(1).getReg();
168      destReg = MI.getOperand(0).getReg();
169      return true;
170    break;
171  }
172  case SPU::ORv16i8:
173  case SPU::ORv8i16:
174  case SPU::ORv4i32:
175  case SPU::ORv2i64:
176  case SPU::ORr8:
177  case SPU::ORr16:
178  case SPU::ORr32:
179  case SPU::ORr64:
180  case SPU::ORr128:
181  case SPU::ORf32:
182  case SPU::ORf64:
183    assert(MI.getNumOperands() == 3 &&
184           MI.getOperand(0).isReg() &&
185           MI.getOperand(1).isReg() &&
186           MI.getOperand(2).isReg() &&
187           "invalid SPU OR(vec|r32|r64|gprc) instruction!");
188    if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
189      sourceReg = MI.getOperand(1).getReg();
190      destReg = MI.getOperand(0).getReg();
191      return true;
192    }
193    break;
194  }
195
196  return false;
197}
198
199unsigned
200SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
201                                  int &FrameIndex) const {
202  switch (MI->getOpcode()) {
203  default: break;
204  case SPU::LQDv16i8:
205  case SPU::LQDv8i16:
206  case SPU::LQDv4i32:
207  case SPU::LQDv4f32:
208  case SPU::LQDv2f64:
209  case SPU::LQDr128:
210  case SPU::LQDr64:
211  case SPU::LQDr32:
212  case SPU::LQDr16: {
213    const MachineOperand MOp1 = MI->getOperand(1);
214    const MachineOperand MOp2 = MI->getOperand(2);
215    if (MOp1.isImm() && MOp2.isFI()) {
216      FrameIndex = MOp2.getIndex();
217      return MI->getOperand(0).getReg();
218    }
219    break;
220  }
221  }
222  return 0;
223}
224
225unsigned
226SPUInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
227                                 int &FrameIndex) const {
228  switch (MI->getOpcode()) {
229  default: break;
230  case SPU::STQDv16i8:
231  case SPU::STQDv8i16:
232  case SPU::STQDv4i32:
233  case SPU::STQDv4f32:
234  case SPU::STQDv2f64:
235  case SPU::STQDr128:
236  case SPU::STQDr64:
237  case SPU::STQDr32:
238  case SPU::STQDr16:
239  case SPU::STQDr8: {
240    const MachineOperand MOp1 = MI->getOperand(1);
241    const MachineOperand MOp2 = MI->getOperand(2);
242    if (MOp1.isImm() && MOp2.isFI()) {
243      FrameIndex = MOp2.getIndex();
244      return MI->getOperand(0).getReg();
245    }
246    break;
247  }
248  }
249  return 0;
250}
251
252void SPUInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
253                               MachineBasicBlock::iterator I, DebugLoc DL,
254                               unsigned DestReg, unsigned SrcReg,
255                               bool KillSrc) const
256{
257  // We support cross register class moves for our aliases, such as R3 in any
258  // reg class to any other reg class containing R3.  This is required because
259  // we instruction select bitconvert i64 -> f64 as a noop for example, so our
260  // types have no specific meaning.
261
262  BuildMI(MBB, I, DL, get(SPU::LRr128), DestReg)
263    .addReg(SrcReg, getKillRegState(KillSrc));
264}
265
266void
267SPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
268                                  MachineBasicBlock::iterator MI,
269                                  unsigned SrcReg, bool isKill, int FrameIdx,
270                                  const TargetRegisterClass *RC,
271                                  const TargetRegisterInfo *TRI) const
272{
273  unsigned opc;
274  bool isValidFrameIdx = (FrameIdx < SPUFrameInfo::maxFrameOffset());
275  if (RC == SPU::GPRCRegisterClass) {
276    opc = (isValidFrameIdx ? SPU::STQDr128 : SPU::STQXr128);
277  } else if (RC == SPU::R64CRegisterClass) {
278    opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64);
279  } else if (RC == SPU::R64FPRegisterClass) {
280    opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64);
281  } else if (RC == SPU::R32CRegisterClass) {
282    opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32);
283  } else if (RC == SPU::R32FPRegisterClass) {
284    opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32);
285  } else if (RC == SPU::R16CRegisterClass) {
286    opc = (isValidFrameIdx ? SPU::STQDr16 : SPU::STQXr16);
287  } else if (RC == SPU::R8CRegisterClass) {
288    opc = (isValidFrameIdx ? SPU::STQDr8 : SPU::STQXr8);
289  } else if (RC == SPU::VECREGRegisterClass) {
290    opc = (isValidFrameIdx) ? SPU::STQDv16i8 : SPU::STQXv16i8;
291  } else {
292    llvm_unreachable("Unknown regclass!");
293  }
294
295  DebugLoc DL;
296  if (MI != MBB.end()) DL = MI->getDebugLoc();
297  addFrameReference(BuildMI(MBB, MI, DL, get(opc))
298                    .addReg(SrcReg, getKillRegState(isKill)), FrameIdx);
299}
300
301void
302SPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
303                                   MachineBasicBlock::iterator MI,
304                                   unsigned DestReg, int FrameIdx,
305                                   const TargetRegisterClass *RC,
306                                   const TargetRegisterInfo *TRI) const
307{
308  unsigned opc;
309  bool isValidFrameIdx = (FrameIdx < SPUFrameInfo::maxFrameOffset());
310  if (RC == SPU::GPRCRegisterClass) {
311    opc = (isValidFrameIdx ? SPU::LQDr128 : SPU::LQXr128);
312  } else if (RC == SPU::R64CRegisterClass) {
313    opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64);
314  } else if (RC == SPU::R64FPRegisterClass) {
315    opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64);
316  } else if (RC == SPU::R32CRegisterClass) {
317    opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32);
318  } else if (RC == SPU::R32FPRegisterClass) {
319    opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32);
320  } else if (RC == SPU::R16CRegisterClass) {
321    opc = (isValidFrameIdx ? SPU::LQDr16 : SPU::LQXr16);
322  } else if (RC == SPU::R8CRegisterClass) {
323    opc = (isValidFrameIdx ? SPU::LQDr8 : SPU::LQXr8);
324  } else if (RC == SPU::VECREGRegisterClass) {
325    opc = (isValidFrameIdx) ? SPU::LQDv16i8 : SPU::LQXv16i8;
326  } else {
327    llvm_unreachable("Unknown regclass in loadRegFromStackSlot!");
328  }
329
330  DebugLoc DL;
331  if (MI != MBB.end()) DL = MI->getDebugLoc();
332  addFrameReference(BuildMI(MBB, MI, DL, get(opc), DestReg), FrameIdx);
333}
334
335//! Branch analysis
336/*!
337  \note This code was kiped from PPC. There may be more branch analysis for
338  CellSPU than what's currently done here.
339 */
340bool
341SPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
342                            MachineBasicBlock *&FBB,
343                            SmallVectorImpl<MachineOperand> &Cond,
344                            bool AllowModify) const {
345  // If the block has no terminators, it just falls into the block after it.
346  MachineBasicBlock::iterator I = MBB.end();
347  if (I == MBB.begin())
348    return false;
349  --I;
350  while (I->isDebugValue()) {
351    if (I == MBB.begin())
352      return false;
353    --I;
354  }
355  if (!isUnpredicatedTerminator(I))
356    return false;
357
358  // Get the last instruction in the block.
359  MachineInstr *LastInst = I;
360
361  // If there is only one terminator instruction, process it.
362  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
363    if (isUncondBranch(LastInst)) {
364      // Check for jump tables
365      if (!LastInst->getOperand(0).isMBB())
366        return true;
367      TBB = LastInst->getOperand(0).getMBB();
368      return false;
369    } else if (isCondBranch(LastInst)) {
370      // Block ends with fall-through condbranch.
371      TBB = LastInst->getOperand(1).getMBB();
372      DEBUG(errs() << "Pushing LastInst:               ");
373      DEBUG(LastInst->dump());
374      Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
375      Cond.push_back(LastInst->getOperand(0));
376      return false;
377    }
378    // Otherwise, don't know what this is.
379    return true;
380  }
381
382  // Get the instruction before it if it's a terminator.
383  MachineInstr *SecondLastInst = I;
384
385  // If there are three terminators, we don't know what sort of block this is.
386  if (SecondLastInst && I != MBB.begin() &&
387      isUnpredicatedTerminator(--I))
388    return true;
389
390  // If the block ends with a conditional and unconditional branch, handle it.
391  if (isCondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
392    TBB =  SecondLastInst->getOperand(1).getMBB();
393    DEBUG(errs() << "Pushing SecondLastInst:         ");
394    DEBUG(SecondLastInst->dump());
395    Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
396    Cond.push_back(SecondLastInst->getOperand(0));
397    FBB = LastInst->getOperand(0).getMBB();
398    return false;
399  }
400
401  // If the block ends with two unconditional branches, handle it.  The second
402  // one is not executed, so remove it.
403  if (isUncondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
404    TBB = SecondLastInst->getOperand(0).getMBB();
405    I = LastInst;
406    if (AllowModify)
407      I->eraseFromParent();
408    return false;
409  }
410
411  // Otherwise, can't handle this.
412  return true;
413}
414
415unsigned
416SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
417  MachineBasicBlock::iterator I = MBB.end();
418  if (I == MBB.begin())
419    return 0;
420  --I;
421  while (I->isDebugValue()) {
422    if (I == MBB.begin())
423      return 0;
424    --I;
425  }
426  if (!isCondBranch(I) && !isUncondBranch(I))
427    return 0;
428
429  // Remove the first branch.
430  DEBUG(errs() << "Removing branch:                ");
431  DEBUG(I->dump());
432  I->eraseFromParent();
433  I = MBB.end();
434  if (I == MBB.begin())
435    return 1;
436
437  --I;
438  if (!(isCondBranch(I) || isUncondBranch(I)))
439    return 1;
440
441  // Remove the second branch.
442  DEBUG(errs() << "Removing second branch:         ");
443  DEBUG(I->dump());
444  I->eraseFromParent();
445  return 2;
446}
447
448unsigned
449SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
450                           MachineBasicBlock *FBB,
451                           const SmallVectorImpl<MachineOperand> &Cond,
452                           DebugLoc DL) const {
453  // Shouldn't be a fall through.
454  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
455  assert((Cond.size() == 2 || Cond.size() == 0) &&
456         "SPU branch conditions have two components!");
457
458  // One-way branch.
459  if (FBB == 0) {
460    if (Cond.empty()) {
461      // Unconditional branch
462      MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(SPU::BR));
463      MIB.addMBB(TBB);
464
465      DEBUG(errs() << "Inserted one-way uncond branch: ");
466      DEBUG((*MIB).dump());
467    } else {
468      // Conditional branch
469      MachineInstrBuilder  MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
470      MIB.addReg(Cond[1].getReg()).addMBB(TBB);
471
472      DEBUG(errs() << "Inserted one-way cond branch:   ");
473      DEBUG((*MIB).dump());
474    }
475    return 1;
476  } else {
477    MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
478    MachineInstrBuilder MIB2 = BuildMI(&MBB, DL, get(SPU::BR));
479
480    // Two-way Conditional Branch.
481    MIB.addReg(Cond[1].getReg()).addMBB(TBB);
482    MIB2.addMBB(FBB);
483
484    DEBUG(errs() << "Inserted conditional branch:    ");
485    DEBUG((*MIB).dump());
486    DEBUG(errs() << "part 2: ");
487    DEBUG((*MIB2).dump());
488   return 2;
489  }
490}
491
492//! Reverses a branch's condition, returning false on success.
493bool
494SPUInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
495  const {
496  // Pretty brainless way of inverting the condition, but it works, considering
497  // there are only two conditions...
498  static struct {
499    unsigned Opc;               //! The incoming opcode
500    unsigned RevCondOpc;        //! The reversed condition opcode
501  } revconds[] = {
502    { SPU::BRNZr32, SPU::BRZr32 },
503    { SPU::BRNZv4i32, SPU::BRZv4i32 },
504    { SPU::BRZr32, SPU::BRNZr32 },
505    { SPU::BRZv4i32, SPU::BRNZv4i32 },
506    { SPU::BRHNZr16, SPU::BRHZr16 },
507    { SPU::BRHNZv8i16, SPU::BRHZv8i16 },
508    { SPU::BRHZr16, SPU::BRHNZr16 },
509    { SPU::BRHZv8i16, SPU::BRHNZv8i16 }
510  };
511
512  unsigned Opc = unsigned(Cond[0].getImm());
513  // Pretty dull mapping between the two conditions that SPU can generate:
514  for (int i = sizeof(revconds)/sizeof(revconds[0]) - 1; i >= 0; --i) {
515    if (revconds[i].Opc == Opc) {
516      Cond[0].setImm(revconds[i].RevCondOpc);
517      return false;
518    }
519  }
520
521  return true;
522}
523