1//===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the VE implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "VEInstrInfo.h"
14#include "VE.h"
15#include "VEMachineFunctionInfo.h"
16#include "VESubtarget.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/CodeGen/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineMemOperand.h"
22#include "llvm/CodeGen/MachineRegisterInfo.h"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/ErrorHandling.h"
26#include "llvm/Support/TargetRegistry.h"
27
28#define DEBUG_TYPE "ve-instr-info"
29
30using namespace llvm;
31
32#define GET_INSTRINFO_CTOR_DTOR
33#include "VEGenInstrInfo.inc"
34
35// Pin the vtable to this file.
36void VEInstrInfo::anchor() {}
37
38VEInstrInfo::VEInstrInfo(VESubtarget &ST)
39    : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI() {}
40
41static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); }
42
43static VECC::CondCode GetOppositeBranchCondition(VECC::CondCode CC) {
44  switch (CC) {
45  case VECC::CC_IG:
46    return VECC::CC_ILE;
47  case VECC::CC_IL:
48    return VECC::CC_IGE;
49  case VECC::CC_INE:
50    return VECC::CC_IEQ;
51  case VECC::CC_IEQ:
52    return VECC::CC_INE;
53  case VECC::CC_IGE:
54    return VECC::CC_IL;
55  case VECC::CC_ILE:
56    return VECC::CC_IG;
57  case VECC::CC_AF:
58    return VECC::CC_AT;
59  case VECC::CC_G:
60    return VECC::CC_LENAN;
61  case VECC::CC_L:
62    return VECC::CC_GENAN;
63  case VECC::CC_NE:
64    return VECC::CC_EQNAN;
65  case VECC::CC_EQ:
66    return VECC::CC_NENAN;
67  case VECC::CC_GE:
68    return VECC::CC_LNAN;
69  case VECC::CC_LE:
70    return VECC::CC_GNAN;
71  case VECC::CC_NUM:
72    return VECC::CC_NAN;
73  case VECC::CC_NAN:
74    return VECC::CC_NUM;
75  case VECC::CC_GNAN:
76    return VECC::CC_LE;
77  case VECC::CC_LNAN:
78    return VECC::CC_GE;
79  case VECC::CC_NENAN:
80    return VECC::CC_EQ;
81  case VECC::CC_EQNAN:
82    return VECC::CC_NE;
83  case VECC::CC_GENAN:
84    return VECC::CC_L;
85  case VECC::CC_LENAN:
86    return VECC::CC_G;
87  case VECC::CC_AT:
88    return VECC::CC_AF;
89  case VECC::UNKNOWN:
90    return VECC::UNKNOWN;
91  }
92  llvm_unreachable("Invalid cond code");
93}
94
95// Treat br.l [BRCF AT] as unconditional branch
96static bool isUncondBranchOpcode(int Opc) {
97  return Opc == VE::BRCFLa    || Opc == VE::BRCFWa    ||
98         Opc == VE::BRCFLa_nt || Opc == VE::BRCFWa_nt ||
99         Opc == VE::BRCFLa_t  || Opc == VE::BRCFWa_t  ||
100         Opc == VE::BRCFDa    || Opc == VE::BRCFSa    ||
101         Opc == VE::BRCFDa_nt || Opc == VE::BRCFSa_nt ||
102         Opc == VE::BRCFDa_t  || Opc == VE::BRCFSa_t;
103}
104
105static bool isCondBranchOpcode(int Opc) {
106  return Opc == VE::BRCFLrr    || Opc == VE::BRCFLir    ||
107         Opc == VE::BRCFLrr_nt || Opc == VE::BRCFLir_nt ||
108         Opc == VE::BRCFLrr_t  || Opc == VE::BRCFLir_t  ||
109         Opc == VE::BRCFWrr    || Opc == VE::BRCFWir    ||
110         Opc == VE::BRCFWrr_nt || Opc == VE::BRCFWir_nt ||
111         Opc == VE::BRCFWrr_t  || Opc == VE::BRCFWir_t  ||
112         Opc == VE::BRCFDrr    || Opc == VE::BRCFDir    ||
113         Opc == VE::BRCFDrr_nt || Opc == VE::BRCFDir_nt ||
114         Opc == VE::BRCFDrr_t  || Opc == VE::BRCFDir_t  ||
115         Opc == VE::BRCFSrr    || Opc == VE::BRCFSir    ||
116         Opc == VE::BRCFSrr_nt || Opc == VE::BRCFSir_nt ||
117         Opc == VE::BRCFSrr_t  || Opc == VE::BRCFSir_t;
118}
119
120static bool isIndirectBranchOpcode(int Opc) {
121  return Opc == VE::BCFLari    || Opc == VE::BCFLari    ||
122         Opc == VE::BCFLari_nt || Opc == VE::BCFLari_nt ||
123         Opc == VE::BCFLari_t  || Opc == VE::BCFLari_t  ||
124         Opc == VE::BCFLari    || Opc == VE::BCFLari    ||
125         Opc == VE::BCFLari_nt || Opc == VE::BCFLari_nt ||
126         Opc == VE::BCFLari_t  || Opc == VE::BCFLari_t;
127}
128
129static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
130                            SmallVectorImpl<MachineOperand> &Cond) {
131  Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm()));
132  Cond.push_back(LastInst->getOperand(1));
133  Cond.push_back(LastInst->getOperand(2));
134  Target = LastInst->getOperand(3).getMBB();
135}
136
137bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
138                                MachineBasicBlock *&FBB,
139                                SmallVectorImpl<MachineOperand> &Cond,
140                                bool AllowModify) const {
141  MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
142  if (I == MBB.end())
143    return false;
144
145  if (!isUnpredicatedTerminator(*I))
146    return false;
147
148  // Get the last instruction in the block.
149  MachineInstr *LastInst = &*I;
150  unsigned LastOpc = LastInst->getOpcode();
151
152  // If there is only one terminator instruction, process it.
153  if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
154    if (isUncondBranchOpcode(LastOpc)) {
155      TBB = LastInst->getOperand(0).getMBB();
156      return false;
157    }
158    if (isCondBranchOpcode(LastOpc)) {
159      // Block ends with fall-through condbranch.
160      parseCondBranch(LastInst, TBB, Cond);
161      return false;
162    }
163    return true; // Can't handle indirect branch.
164  }
165
166  // Get the instruction before it if it is a terminator.
167  MachineInstr *SecondLastInst = &*I;
168  unsigned SecondLastOpc = SecondLastInst->getOpcode();
169
170  // If AllowModify is true and the block ends with two or more unconditional
171  // branches, delete all but the first unconditional branch.
172  if (AllowModify && isUncondBranchOpcode(LastOpc)) {
173    while (isUncondBranchOpcode(SecondLastOpc)) {
174      LastInst->eraseFromParent();
175      LastInst = SecondLastInst;
176      LastOpc = LastInst->getOpcode();
177      if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
178        // Return now the only terminator is an unconditional branch.
179        TBB = LastInst->getOperand(0).getMBB();
180        return false;
181      }
182      SecondLastInst = &*I;
183      SecondLastOpc = SecondLastInst->getOpcode();
184    }
185  }
186
187  // If there are three terminators, we don't know what sort of block this is.
188  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
189    return true;
190
191  // If the block ends with a B and a Bcc, handle it.
192  if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
193    parseCondBranch(SecondLastInst, TBB, Cond);
194    FBB = LastInst->getOperand(0).getMBB();
195    return false;
196  }
197
198  // If the block ends with two unconditional branches, handle it.  The second
199  // one is not executed.
200  if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
201    TBB = SecondLastInst->getOperand(0).getMBB();
202    return false;
203  }
204
205  // ...likewise if it ends with an indirect branch followed by an unconditional
206  // branch.
207  if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
208    I = LastInst;
209    if (AllowModify)
210      I->eraseFromParent();
211    return true;
212  }
213
214  // Otherwise, can't handle this.
215  return true;
216}
217
218unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB,
219                                   MachineBasicBlock *TBB,
220                                   MachineBasicBlock *FBB,
221                                   ArrayRef<MachineOperand> Cond,
222                                   const DebugLoc &DL, int *BytesAdded) const {
223  assert(TBB && "insertBranch must not be told to insert a fallthrough");
224  assert((Cond.size() == 3 || Cond.size() == 0) &&
225         "VE branch conditions should have three component!");
226  assert(!BytesAdded && "code size not handled");
227  if (Cond.empty()) {
228    // Uncondition branch
229    assert(!FBB && "Unconditional branch with multiple successors!");
230    BuildMI(&MBB, DL, get(VE::BRCFLa_t))
231        .addMBB(TBB);
232    return 1;
233  }
234
235  // Conditional branch
236  //   (BRCFir CC sy sz addr)
237  assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented");
238
239  unsigned opc[2];
240  const TargetRegisterInfo *TRI = &getRegisterInfo();
241  MachineFunction *MF = MBB.getParent();
242  const MachineRegisterInfo &MRI = MF->getRegInfo();
243  unsigned Reg = Cond[2].getReg();
244  if (IsIntegerCC(Cond[0].getImm())) {
245    if (TRI->getRegSizeInBits(Reg, MRI) == 32) {
246      opc[0] = VE::BRCFWir;
247      opc[1] = VE::BRCFWrr;
248    } else {
249      opc[0] = VE::BRCFLir;
250      opc[1] = VE::BRCFLrr;
251    }
252  } else {
253    if (TRI->getRegSizeInBits(Reg, MRI) == 32) {
254      opc[0] = VE::BRCFSir;
255      opc[1] = VE::BRCFSrr;
256    } else {
257      opc[0] = VE::BRCFDir;
258      opc[1] = VE::BRCFDrr;
259    }
260  }
261  if (Cond[1].isImm()) {
262      BuildMI(&MBB, DL, get(opc[0]))
263          .add(Cond[0]) // condition code
264          .add(Cond[1]) // lhs
265          .add(Cond[2]) // rhs
266          .addMBB(TBB);
267  } else {
268      BuildMI(&MBB, DL, get(opc[1]))
269          .add(Cond[0])
270          .add(Cond[1])
271          .add(Cond[2])
272          .addMBB(TBB);
273  }
274
275  if (!FBB)
276    return 1;
277
278  BuildMI(&MBB, DL, get(VE::BRCFLa_t))
279      .addMBB(FBB);
280  return 2;
281}
282
283unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB,
284                                   int *BytesRemoved) const {
285  assert(!BytesRemoved && "code size not handled");
286
287  MachineBasicBlock::iterator I = MBB.end();
288  unsigned Count = 0;
289  while (I != MBB.begin()) {
290    --I;
291
292    if (I->isDebugValue())
293      continue;
294
295    if (!isUncondBranchOpcode(I->getOpcode()) &&
296        !isCondBranchOpcode(I->getOpcode()))
297      break; // Not a branch
298
299    I->eraseFromParent();
300    I = MBB.end();
301    ++Count;
302  }
303  return Count;
304}
305
306bool VEInstrInfo::reverseBranchCondition(
307    SmallVectorImpl<MachineOperand> &Cond) const {
308  VECC::CondCode CC = static_cast<VECC::CondCode>(Cond[0].getImm());
309  Cond[0].setImm(GetOppositeBranchCondition(CC));
310  return false;
311}
312
313static bool IsAliasOfSX(Register Reg) {
314  return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) ||
315         VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) ||
316         VE::F32RegClass.contains(Reg);
317}
318
319void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
320                              MachineBasicBlock::iterator I, const DebugLoc &DL,
321                              MCRegister DestReg, MCRegister SrcReg,
322                              bool KillSrc) const {
323
324  if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) {
325    BuildMI(MBB, I, DL, get(VE::ORri), DestReg)
326        .addReg(SrcReg, getKillRegState(KillSrc))
327        .addImm(0);
328  } else {
329    const TargetRegisterInfo *TRI = &getRegisterInfo();
330    dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI)
331           << " to " << printReg(DestReg, TRI) << "\n";
332    llvm_unreachable("Impossible reg-to-reg copy");
333  }
334}
335
336/// isLoadFromStackSlot - If the specified machine instruction is a direct
337/// load from a stack slot, return the virtual or physical register number of
338/// the destination along with the FrameIndex of the loaded stack slot.  If
339/// not, return 0.  This predicate must return 0 if the instruction has
340/// any side effects other than loading from the stack slot.
341unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
342                                          int &FrameIndex) const {
343  if (MI.getOpcode() == VE::LDrii ||    // I64
344      MI.getOpcode() == VE::LDLSXrii || // I32
345      MI.getOpcode() == VE::LDUrii      // F32
346  ) {
347    if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
348        MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() &&
349        MI.getOperand(3).getImm() == 0) {
350      FrameIndex = MI.getOperand(1).getIndex();
351      return MI.getOperand(0).getReg();
352    }
353  }
354  return 0;
355}
356
357/// isStoreToStackSlot - If the specified machine instruction is a direct
358/// store to a stack slot, return the virtual or physical register number of
359/// the source reg along with the FrameIndex of the loaded stack slot.  If
360/// not, return 0.  This predicate must return 0 if the instruction has
361/// any side effects other than storing to the stack slot.
362unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
363                                         int &FrameIndex) const {
364  if (MI.getOpcode() == VE::STrii ||  // I64
365      MI.getOpcode() == VE::STLrii || // I32
366      MI.getOpcode() == VE::STUrii    // F32
367  ) {
368    if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
369        MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() &&
370        MI.getOperand(2).getImm() == 0) {
371      FrameIndex = MI.getOperand(0).getIndex();
372      return MI.getOperand(3).getReg();
373    }
374  }
375  return 0;
376}
377
378void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
379                                      MachineBasicBlock::iterator I,
380                                      Register SrcReg, bool isKill, int FI,
381                                      const TargetRegisterClass *RC,
382                                      const TargetRegisterInfo *TRI) const {
383  DebugLoc DL;
384  if (I != MBB.end())
385    DL = I->getDebugLoc();
386
387  MachineFunction *MF = MBB.getParent();
388  const MachineFrameInfo &MFI = MF->getFrameInfo();
389  MachineMemOperand *MMO = MF->getMachineMemOperand(
390      MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
391      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
392
393  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
394  if (RC == &VE::I64RegClass) {
395    BuildMI(MBB, I, DL, get(VE::STrii))
396        .addFrameIndex(FI)
397        .addImm(0)
398        .addImm(0)
399        .addReg(SrcReg, getKillRegState(isKill))
400        .addMemOperand(MMO);
401  } else if (RC == &VE::I32RegClass) {
402    BuildMI(MBB, I, DL, get(VE::STLrii))
403        .addFrameIndex(FI)
404        .addImm(0)
405        .addImm(0)
406        .addReg(SrcReg, getKillRegState(isKill))
407        .addMemOperand(MMO);
408  } else if (RC == &VE::F32RegClass) {
409    BuildMI(MBB, I, DL, get(VE::STUrii))
410        .addFrameIndex(FI)
411        .addImm(0)
412        .addImm(0)
413        .addReg(SrcReg, getKillRegState(isKill))
414        .addMemOperand(MMO);
415  } else
416    report_fatal_error("Can't store this register to stack slot");
417}
418
419void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
420                                       MachineBasicBlock::iterator I,
421                                       Register DestReg, int FI,
422                                       const TargetRegisterClass *RC,
423                                       const TargetRegisterInfo *TRI) const {
424  DebugLoc DL;
425  if (I != MBB.end())
426    DL = I->getDebugLoc();
427
428  MachineFunction *MF = MBB.getParent();
429  const MachineFrameInfo &MFI = MF->getFrameInfo();
430  MachineMemOperand *MMO = MF->getMachineMemOperand(
431      MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
432      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
433
434  if (RC == &VE::I64RegClass) {
435    BuildMI(MBB, I, DL, get(VE::LDrii), DestReg)
436        .addFrameIndex(FI)
437        .addImm(0)
438        .addImm(0)
439        .addMemOperand(MMO);
440  } else if (RC == &VE::I32RegClass) {
441    BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg)
442        .addFrameIndex(FI)
443        .addImm(0)
444        .addImm(0)
445        .addMemOperand(MMO);
446  } else if (RC == &VE::F32RegClass) {
447    BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg)
448        .addFrameIndex(FI)
449        .addImm(0)
450        .addImm(0)
451        .addMemOperand(MMO);
452  } else
453    report_fatal_error("Can't load this register from stack slot");
454}
455
456Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
457  VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>();
458  Register GlobalBaseReg = VEFI->getGlobalBaseReg();
459  if (GlobalBaseReg != 0)
460    return GlobalBaseReg;
461
462  // We use %s15 (%got) as a global base register
463  GlobalBaseReg = VE::SX15;
464
465  // Insert a pseudo instruction to set the GlobalBaseReg into the first
466  // MBB of the function
467  MachineBasicBlock &FirstMBB = MF->front();
468  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
469  DebugLoc dl;
470  BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg);
471  VEFI->setGlobalBaseReg(GlobalBaseReg);
472  return GlobalBaseReg;
473}
474
475bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
476  switch (MI.getOpcode()) {
477  case VE::EXTEND_STACK: {
478    return expandExtendStackPseudo(MI);
479  }
480  case VE::EXTEND_STACK_GUARD: {
481    MI.eraseFromParent(); // The pseudo instruction is gone now.
482    return true;
483  }
484  case VE::GETSTACKTOP: {
485    return expandGetStackTopPseudo(MI);
486  }
487  }
488  return false;
489}
490
491bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
492  MachineBasicBlock &MBB = *MI.getParent();
493  MachineFunction &MF = *MBB.getParent();
494  const VESubtarget &STI = MF.getSubtarget<VESubtarget>();
495  const VEInstrInfo &TII = *STI.getInstrInfo();
496  DebugLoc dl = MBB.findDebugLoc(MI);
497
498  // Create following instructions and multiple basic blocks.
499  //
500  // thisBB:
501  //   brge.l.t %sp, %sl, sinkBB
502  // syscallBB:
503  //   ld      %s61, 0x18(, %tp)        // load param area
504  //   or      %s62, 0, %s0             // spill the value of %s0
505  //   lea     %s63, 0x13b              // syscall # of grow
506  //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
507  //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
508  //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
509  //   monc                             // call monitor
510  //   or      %s0, 0, %s62             // restore the value of %s0
511  // sinkBB:
512
513  // Create new MBB
514  MachineBasicBlock *BB = &MBB;
515  const BasicBlock *LLVM_BB = BB->getBasicBlock();
516  MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
517  MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
518  MachineFunction::iterator It = ++(BB->getIterator());
519  MF.insert(It, syscallMBB);
520  MF.insert(It, sinkMBB);
521
522  // Transfer the remainder of BB and its successor edges to sinkMBB.
523  sinkMBB->splice(sinkMBB->begin(), BB,
524                  std::next(std::next(MachineBasicBlock::iterator(MI))),
525                  BB->end());
526  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
527
528  // Next, add the true and fallthrough blocks as its successors.
529  BB->addSuccessor(syscallMBB);
530  BB->addSuccessor(sinkMBB);
531  BuildMI(BB, dl, TII.get(VE::BRCFLrr_t))
532      .addImm(VECC::CC_IGE)
533      .addReg(VE::SX11) // %sp
534      .addReg(VE::SX8)  // %sl
535      .addMBB(sinkMBB);
536
537  BB = syscallMBB;
538
539  // Update machine-CFG edges
540  BB->addSuccessor(sinkMBB);
541
542  BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61)
543      .addReg(VE::SX14)
544      .addImm(0)
545      .addImm(0x18);
546  BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
547      .addReg(VE::SX0)
548      .addImm(0);
549  BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63)
550      .addImm(0)
551      .addImm(0)
552      .addImm(0x13b);
553  BuildMI(BB, dl, TII.get(VE::SHMLri))
554      .addReg(VE::SX61)
555      .addImm(0)
556      .addReg(VE::SX63);
557  BuildMI(BB, dl, TII.get(VE::SHMLri))
558      .addReg(VE::SX61)
559      .addImm(8)
560      .addReg(VE::SX8);
561  BuildMI(BB, dl, TII.get(VE::SHMLri))
562      .addReg(VE::SX61)
563      .addImm(16)
564      .addReg(VE::SX11);
565  BuildMI(BB, dl, TII.get(VE::MONC));
566
567  BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
568      .addReg(VE::SX62)
569      .addImm(0);
570
571  MI.eraseFromParent(); // The pseudo instruction is gone now.
572  return true;
573}
574
575bool VEInstrInfo::expandGetStackTopPseudo(MachineInstr &MI) const {
576  MachineBasicBlock *MBB = MI.getParent();
577  MachineFunction &MF = *MBB->getParent();
578  const VESubtarget &STI = MF.getSubtarget<VESubtarget>();
579  const VEInstrInfo &TII = *STI.getInstrInfo();
580  DebugLoc DL = MBB->findDebugLoc(MI);
581
582  // Create following instruction
583  //
584  //   dst = %sp + target specific frame + the size of parameter area
585
586  const MachineFrameInfo &MFI = MF.getFrameInfo();
587  const VEFrameLowering &TFL = *STI.getFrameLowering();
588
589  // The VE ABI requires a reserved 176 bytes area at the top
590  // of stack as described in VESubtarget.cpp.  So, we adjust it here.
591  unsigned NumBytes = STI.getAdjustedFrameSize(0);
592
593  // Also adds the size of parameter area.
594  if (MFI.adjustsStack() && TFL.hasReservedCallFrame(MF))
595    NumBytes += MFI.getMaxCallFrameSize();
596
597  BuildMI(*MBB, MI, DL, TII.get(VE::LEArii))
598      .addDef(MI.getOperand(0).getReg())
599      .addReg(VE::SX11)
600      .addImm(0)
601      .addImm(NumBytes);
602
603  MI.eraseFromParent(); // The pseudo instruction is gone now.
604  return true;
605}
606