1064859bdSKazushi (Jam) Marukawa //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===//
2064859bdSKazushi (Jam) Marukawa //
3064859bdSKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4064859bdSKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information.
5064859bdSKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6064859bdSKazushi (Jam) Marukawa //
7064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
8064859bdSKazushi (Jam) Marukawa //
9064859bdSKazushi (Jam) Marukawa // This file contains the VE implementation of the TargetInstrInfo class.
10064859bdSKazushi (Jam) Marukawa //
11064859bdSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===//
12064859bdSKazushi (Jam) Marukawa 
13064859bdSKazushi (Jam) Marukawa #include "VEInstrInfo.h"
14064859bdSKazushi (Jam) Marukawa #include "VE.h"
15064859bdSKazushi (Jam) Marukawa #include "VESubtarget.h"
16064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/STLExtras.h"
17064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/SmallVector.h"
18064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFrameInfo.h"
19064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstrBuilder.h"
20064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineMemOperand.h"
21064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineRegisterInfo.h"
22064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h"
23064859bdSKazushi (Jam) Marukawa #include "llvm/Support/Debug.h"
24064859bdSKazushi (Jam) Marukawa #include "llvm/Support/ErrorHandling.h"
25064859bdSKazushi (Jam) Marukawa #include "llvm/Support/TargetRegistry.h"
26064859bdSKazushi (Jam) Marukawa 
27064859bdSKazushi (Jam) Marukawa #define DEBUG_TYPE "ve"
28064859bdSKazushi (Jam) Marukawa 
29064859bdSKazushi (Jam) Marukawa using namespace llvm;
30064859bdSKazushi (Jam) Marukawa 
31064859bdSKazushi (Jam) Marukawa #define GET_INSTRINFO_CTOR_DTOR
32064859bdSKazushi (Jam) Marukawa #include "VEGenInstrInfo.inc"
33064859bdSKazushi (Jam) Marukawa 
34064859bdSKazushi (Jam) Marukawa // Pin the vtable to this file.
35064859bdSKazushi (Jam) Marukawa void VEInstrInfo::anchor() {}
36064859bdSKazushi (Jam) Marukawa 
37064859bdSKazushi (Jam) Marukawa VEInstrInfo::VEInstrInfo(VESubtarget &ST)
38064859bdSKazushi (Jam) Marukawa     : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(),
39064859bdSKazushi (Jam) Marukawa       Subtarget(ST) {}
40064859bdSKazushi (Jam) Marukawa 
41*fef80a29SKazushi (Jam) Marukawa static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); }
42*fef80a29SKazushi (Jam) Marukawa 
43*fef80a29SKazushi (Jam) Marukawa static VECC::CondCodes GetOppositeBranchCondition(VECC::CondCodes CC) {
44*fef80a29SKazushi (Jam) Marukawa   switch(CC) {
45*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_IG:     return VECC::CC_ILE;
46*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_IL:     return VECC::CC_IGE;
47*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_INE:    return VECC::CC_IEQ;
48*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_IEQ:    return VECC::CC_INE;
49*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_IGE:    return VECC::CC_IL;
50*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_ILE:    return VECC::CC_IG;
51*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_AF:     return VECC::CC_AT;
52*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_G:      return VECC::CC_LENAN;
53*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_L:      return VECC::CC_GENAN;
54*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_NE:     return VECC::CC_EQNAN;
55*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_EQ:     return VECC::CC_NENAN;
56*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_GE:     return VECC::CC_LNAN;
57*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_LE:     return VECC::CC_GNAN;
58*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_NUM:    return VECC::CC_NAN;
59*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_NAN:    return VECC::CC_NUM;
60*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_GNAN:   return VECC::CC_LE;
61*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_LNAN:   return VECC::CC_GE;
62*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_NENAN:  return VECC::CC_EQ;
63*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_EQNAN:  return VECC::CC_NE;
64*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_GENAN:  return VECC::CC_L;
65*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_LENAN:  return VECC::CC_G;
66*fef80a29SKazushi (Jam) Marukawa   case VECC::CC_AT:     return VECC::CC_AF;
67*fef80a29SKazushi (Jam) Marukawa   }
68*fef80a29SKazushi (Jam) Marukawa   llvm_unreachable("Invalid cond code");
69*fef80a29SKazushi (Jam) Marukawa }
70*fef80a29SKazushi (Jam) Marukawa 
71*fef80a29SKazushi (Jam) Marukawa // Treat br.l [BCR AT] as unconditional branch
72*fef80a29SKazushi (Jam) Marukawa static bool isUncondBranchOpcode(int Opc) {
73*fef80a29SKazushi (Jam) Marukawa   return Opc == VE::BCRLa || Opc == VE::BCRWa ||
74*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRDa || Opc == VE::BCRSa;
75*fef80a29SKazushi (Jam) Marukawa }
76*fef80a29SKazushi (Jam) Marukawa 
77*fef80a29SKazushi (Jam) Marukawa static bool isCondBranchOpcode(int Opc) {
78*fef80a29SKazushi (Jam) Marukawa   return Opc == VE::BCRLrr  || Opc == VE::BCRLir  ||
79*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRLrm0 || Opc == VE::BCRLrm1 ||
80*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRLim0 || Opc == VE::BCRLim1 ||
81*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRWrr  || Opc == VE::BCRWir  ||
82*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRWrm0 || Opc == VE::BCRWrm1 ||
83*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRWim0 || Opc == VE::BCRWim1 ||
84*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRDrr  || Opc == VE::BCRDir  ||
85*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRDrm0 || Opc == VE::BCRDrm1 ||
86*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRDim0 || Opc == VE::BCRDim1 ||
87*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRSrr  || Opc == VE::BCRSir  ||
88*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRSrm0 || Opc == VE::BCRSrm1 ||
89*fef80a29SKazushi (Jam) Marukawa          Opc == VE::BCRSim0 || Opc == VE::BCRSim1;
90*fef80a29SKazushi (Jam) Marukawa }
91*fef80a29SKazushi (Jam) Marukawa 
92*fef80a29SKazushi (Jam) Marukawa static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
93*fef80a29SKazushi (Jam) Marukawa                             SmallVectorImpl<MachineOperand> &Cond) {
94*fef80a29SKazushi (Jam) Marukawa   Cond.push_back(MachineOperand::CreateImm(LastInst->getOperand(0).getImm()));
95*fef80a29SKazushi (Jam) Marukawa   Cond.push_back(LastInst->getOperand(1));
96*fef80a29SKazushi (Jam) Marukawa   Cond.push_back(LastInst->getOperand(2));
97*fef80a29SKazushi (Jam) Marukawa   Target = LastInst->getOperand(3).getMBB();
98*fef80a29SKazushi (Jam) Marukawa }
99*fef80a29SKazushi (Jam) Marukawa 
100*fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
101*fef80a29SKazushi (Jam) Marukawa                                    MachineBasicBlock *&TBB,
102*fef80a29SKazushi (Jam) Marukawa                                    MachineBasicBlock *&FBB,
103*fef80a29SKazushi (Jam) Marukawa                                    SmallVectorImpl<MachineOperand> &Cond,
104*fef80a29SKazushi (Jam) Marukawa                                    bool AllowModify) const {
105*fef80a29SKazushi (Jam) Marukawa   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
106*fef80a29SKazushi (Jam) Marukawa   if (I == MBB.end())
107*fef80a29SKazushi (Jam) Marukawa     return false;
108*fef80a29SKazushi (Jam) Marukawa 
109*fef80a29SKazushi (Jam) Marukawa   if (!isUnpredicatedTerminator(*I))
110*fef80a29SKazushi (Jam) Marukawa     return false;
111*fef80a29SKazushi (Jam) Marukawa 
112*fef80a29SKazushi (Jam) Marukawa   // Get the last instruction in the block.
113*fef80a29SKazushi (Jam) Marukawa   MachineInstr *LastInst = &*I;
114*fef80a29SKazushi (Jam) Marukawa   unsigned LastOpc = LastInst->getOpcode();
115*fef80a29SKazushi (Jam) Marukawa 
116*fef80a29SKazushi (Jam) Marukawa   // If there is only one terminator instruction, process it.
117*fef80a29SKazushi (Jam) Marukawa   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
118*fef80a29SKazushi (Jam) Marukawa     if (isUncondBranchOpcode(LastOpc)) {
119*fef80a29SKazushi (Jam) Marukawa       TBB = LastInst->getOperand(0).getMBB();
120*fef80a29SKazushi (Jam) Marukawa       return false;
121*fef80a29SKazushi (Jam) Marukawa     }
122*fef80a29SKazushi (Jam) Marukawa     if (isCondBranchOpcode(LastOpc)) {
123*fef80a29SKazushi (Jam) Marukawa       // Block ends with fall-through condbranch.
124*fef80a29SKazushi (Jam) Marukawa       parseCondBranch(LastInst, TBB, Cond);
125*fef80a29SKazushi (Jam) Marukawa       return false;
126*fef80a29SKazushi (Jam) Marukawa     }
127*fef80a29SKazushi (Jam) Marukawa     return true; // Can't handle indirect branch.
128*fef80a29SKazushi (Jam) Marukawa   }
129*fef80a29SKazushi (Jam) Marukawa 
130*fef80a29SKazushi (Jam) Marukawa   // Get the instruction before it if it is a terminator.
131*fef80a29SKazushi (Jam) Marukawa   MachineInstr *SecondLastInst = &*I;
132*fef80a29SKazushi (Jam) Marukawa   unsigned SecondLastOpc = SecondLastInst->getOpcode();
133*fef80a29SKazushi (Jam) Marukawa 
134*fef80a29SKazushi (Jam) Marukawa   // If AllowModify is true and the block ends with two or more unconditional
135*fef80a29SKazushi (Jam) Marukawa   // branches, delete all but the first unconditional branch.
136*fef80a29SKazushi (Jam) Marukawa   if (AllowModify && isUncondBranchOpcode(LastOpc)) {
137*fef80a29SKazushi (Jam) Marukawa     while (isUncondBranchOpcode(SecondLastOpc)) {
138*fef80a29SKazushi (Jam) Marukawa       LastInst->eraseFromParent();
139*fef80a29SKazushi (Jam) Marukawa       LastInst = SecondLastInst;
140*fef80a29SKazushi (Jam) Marukawa       LastOpc = LastInst->getOpcode();
141*fef80a29SKazushi (Jam) Marukawa       if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
142*fef80a29SKazushi (Jam) Marukawa         // Return now the only terminator is an unconditional branch.
143*fef80a29SKazushi (Jam) Marukawa         TBB = LastInst->getOperand(0).getMBB();
144*fef80a29SKazushi (Jam) Marukawa         return false;
145*fef80a29SKazushi (Jam) Marukawa       }
146*fef80a29SKazushi (Jam) Marukawa       SecondLastInst = &*I;
147*fef80a29SKazushi (Jam) Marukawa       SecondLastOpc = SecondLastInst->getOpcode();
148*fef80a29SKazushi (Jam) Marukawa     }
149*fef80a29SKazushi (Jam) Marukawa   }
150*fef80a29SKazushi (Jam) Marukawa 
151*fef80a29SKazushi (Jam) Marukawa   // If there are three terminators, we don't know what sort of block this is.
152*fef80a29SKazushi (Jam) Marukawa   if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
153*fef80a29SKazushi (Jam) Marukawa     return true;
154*fef80a29SKazushi (Jam) Marukawa 
155*fef80a29SKazushi (Jam) Marukawa   // If the block ends with a B and a Bcc, handle it.
156*fef80a29SKazushi (Jam) Marukawa   if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
157*fef80a29SKazushi (Jam) Marukawa     parseCondBranch(SecondLastInst, TBB, Cond);
158*fef80a29SKazushi (Jam) Marukawa     FBB = LastInst->getOperand(0).getMBB();
159*fef80a29SKazushi (Jam) Marukawa     return false;
160*fef80a29SKazushi (Jam) Marukawa   }
161*fef80a29SKazushi (Jam) Marukawa 
162*fef80a29SKazushi (Jam) Marukawa   // If the block ends with two unconditional branches, handle it.  The second
163*fef80a29SKazushi (Jam) Marukawa   // one is not executed.
164*fef80a29SKazushi (Jam) Marukawa   if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
165*fef80a29SKazushi (Jam) Marukawa     TBB = SecondLastInst->getOperand(0).getMBB();
166*fef80a29SKazushi (Jam) Marukawa     return false;
167*fef80a29SKazushi (Jam) Marukawa   }
168*fef80a29SKazushi (Jam) Marukawa 
169*fef80a29SKazushi (Jam) Marukawa   // TODO ...likewise if it ends with an indirect branch followed by an unconditional
170*fef80a29SKazushi (Jam) Marukawa   // branch.
171*fef80a29SKazushi (Jam) Marukawa   // if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
172*fef80a29SKazushi (Jam) Marukawa   //   I = LastInst;
173*fef80a29SKazushi (Jam) Marukawa   //   if (AllowModify)
174*fef80a29SKazushi (Jam) Marukawa   //     I->eraseFromParent();
175*fef80a29SKazushi (Jam) Marukawa   //   return true;
176*fef80a29SKazushi (Jam) Marukawa   // }
177*fef80a29SKazushi (Jam) Marukawa 
178*fef80a29SKazushi (Jam) Marukawa   // Otherwise, can't handle this.
179*fef80a29SKazushi (Jam) Marukawa   return true;
180*fef80a29SKazushi (Jam) Marukawa }
181*fef80a29SKazushi (Jam) Marukawa 
182*fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::insertBranch(MachineBasicBlock &MBB,
183*fef80a29SKazushi (Jam) Marukawa                                       MachineBasicBlock *TBB,
184*fef80a29SKazushi (Jam) Marukawa                                       MachineBasicBlock *FBB,
185*fef80a29SKazushi (Jam) Marukawa                                       ArrayRef<MachineOperand> Cond,
186*fef80a29SKazushi (Jam) Marukawa                                       const DebugLoc &DL,
187*fef80a29SKazushi (Jam) Marukawa                                       int *BytesAdded) const {
188*fef80a29SKazushi (Jam) Marukawa   assert(TBB && "insertBranch must not be told to insert a fallthrough");
189*fef80a29SKazushi (Jam) Marukawa   assert((Cond.size() == 3 || Cond.size() == 0) &&
190*fef80a29SKazushi (Jam) Marukawa          "VE branch conditions should have three component!");
191*fef80a29SKazushi (Jam) Marukawa   assert(!BytesAdded && "code size not handled");
192*fef80a29SKazushi (Jam) Marukawa   if (Cond.empty()) {
193*fef80a29SKazushi (Jam) Marukawa     // Uncondition branch
194*fef80a29SKazushi (Jam) Marukawa     assert(!FBB && "Unconditional branch with multiple successors!");
195*fef80a29SKazushi (Jam) Marukawa     BuildMI(&MBB, DL, get(VE::BCRLa))
196*fef80a29SKazushi (Jam) Marukawa         .addMBB(TBB);
197*fef80a29SKazushi (Jam) Marukawa     return 1;
198*fef80a29SKazushi (Jam) Marukawa   }
199*fef80a29SKazushi (Jam) Marukawa 
200*fef80a29SKazushi (Jam) Marukawa   // Conditional branch
201*fef80a29SKazushi (Jam) Marukawa   //   (BCRir CC sy sz addr)
202*fef80a29SKazushi (Jam) Marukawa   assert(Cond[0].isImm() && Cond[2].isReg() && "not implemented");
203*fef80a29SKazushi (Jam) Marukawa 
204*fef80a29SKazushi (Jam) Marukawa   unsigned opc[2];
205*fef80a29SKazushi (Jam) Marukawa   const TargetRegisterInfo *TRI = &getRegisterInfo();
206*fef80a29SKazushi (Jam) Marukawa   MachineFunction *MF = MBB.getParent();
207*fef80a29SKazushi (Jam) Marukawa   const MachineRegisterInfo &MRI = MF->getRegInfo();
208*fef80a29SKazushi (Jam) Marukawa   unsigned Reg = Cond[2].getReg();
209*fef80a29SKazushi (Jam) Marukawa   if (IsIntegerCC(Cond[0].getImm())) {
210*fef80a29SKazushi (Jam) Marukawa     if (TRI->getRegSizeInBits(Reg, MRI) == 32) {
211*fef80a29SKazushi (Jam) Marukawa       opc[0] = VE::BCRWir;
212*fef80a29SKazushi (Jam) Marukawa       opc[1] = VE::BCRWrr;
213*fef80a29SKazushi (Jam) Marukawa     } else {
214*fef80a29SKazushi (Jam) Marukawa       opc[0] = VE::BCRLir;
215*fef80a29SKazushi (Jam) Marukawa       opc[1] = VE::BCRLrr;
216*fef80a29SKazushi (Jam) Marukawa     }
217*fef80a29SKazushi (Jam) Marukawa   } else {
218*fef80a29SKazushi (Jam) Marukawa     if (TRI->getRegSizeInBits(Reg, MRI) == 32) {
219*fef80a29SKazushi (Jam) Marukawa       opc[0] = VE::BCRSir;
220*fef80a29SKazushi (Jam) Marukawa       opc[1] = VE::BCRSrr;
221*fef80a29SKazushi (Jam) Marukawa     } else {
222*fef80a29SKazushi (Jam) Marukawa       opc[0] = VE::BCRDir;
223*fef80a29SKazushi (Jam) Marukawa       opc[1] = VE::BCRDrr;
224*fef80a29SKazushi (Jam) Marukawa     }
225*fef80a29SKazushi (Jam) Marukawa   }
226*fef80a29SKazushi (Jam) Marukawa   if (Cond[1].isImm()) {
227*fef80a29SKazushi (Jam) Marukawa       BuildMI(&MBB, DL, get(opc[0]))
228*fef80a29SKazushi (Jam) Marukawa           .add(Cond[0]) // condition code
229*fef80a29SKazushi (Jam) Marukawa           .add(Cond[1]) // lhs
230*fef80a29SKazushi (Jam) Marukawa           .add(Cond[2]) // rhs
231*fef80a29SKazushi (Jam) Marukawa           .addMBB(TBB);
232*fef80a29SKazushi (Jam) Marukawa   } else {
233*fef80a29SKazushi (Jam) Marukawa       BuildMI(&MBB, DL, get(opc[1]))
234*fef80a29SKazushi (Jam) Marukawa           .add(Cond[0])
235*fef80a29SKazushi (Jam) Marukawa           .add(Cond[1])
236*fef80a29SKazushi (Jam) Marukawa           .add(Cond[2])
237*fef80a29SKazushi (Jam) Marukawa           .addMBB(TBB);
238*fef80a29SKazushi (Jam) Marukawa   }
239*fef80a29SKazushi (Jam) Marukawa 
240*fef80a29SKazushi (Jam) Marukawa   if (!FBB)
241*fef80a29SKazushi (Jam) Marukawa     return 1;
242*fef80a29SKazushi (Jam) Marukawa 
243*fef80a29SKazushi (Jam) Marukawa   BuildMI(&MBB, DL, get(VE::BCRLa))
244*fef80a29SKazushi (Jam) Marukawa       .addMBB(FBB);
245*fef80a29SKazushi (Jam) Marukawa   return 2;
246*fef80a29SKazushi (Jam) Marukawa }
247*fef80a29SKazushi (Jam) Marukawa 
248*fef80a29SKazushi (Jam) Marukawa unsigned VEInstrInfo::removeBranch(MachineBasicBlock &MBB,
249*fef80a29SKazushi (Jam) Marukawa                                    int *BytesRemoved) const {
250*fef80a29SKazushi (Jam) Marukawa   assert(!BytesRemoved && "code size not handled");
251*fef80a29SKazushi (Jam) Marukawa 
252*fef80a29SKazushi (Jam) Marukawa   MachineBasicBlock::iterator I = MBB.end();
253*fef80a29SKazushi (Jam) Marukawa   unsigned Count = 0;
254*fef80a29SKazushi (Jam) Marukawa   while (I != MBB.begin()) {
255*fef80a29SKazushi (Jam) Marukawa     --I;
256*fef80a29SKazushi (Jam) Marukawa 
257*fef80a29SKazushi (Jam) Marukawa     if (I->isDebugValue())
258*fef80a29SKazushi (Jam) Marukawa       continue;
259*fef80a29SKazushi (Jam) Marukawa 
260*fef80a29SKazushi (Jam) Marukawa     if (!isUncondBranchOpcode(I->getOpcode()) &&
261*fef80a29SKazushi (Jam) Marukawa         !isCondBranchOpcode(I->getOpcode()))
262*fef80a29SKazushi (Jam) Marukawa       break; // Not a branch
263*fef80a29SKazushi (Jam) Marukawa 
264*fef80a29SKazushi (Jam) Marukawa     I->eraseFromParent();
265*fef80a29SKazushi (Jam) Marukawa     I = MBB.end();
266*fef80a29SKazushi (Jam) Marukawa     ++Count;
267*fef80a29SKazushi (Jam) Marukawa   }
268*fef80a29SKazushi (Jam) Marukawa   return Count;
269*fef80a29SKazushi (Jam) Marukawa }
270*fef80a29SKazushi (Jam) Marukawa 
271*fef80a29SKazushi (Jam) Marukawa bool VEInstrInfo::reverseBranchCondition(
272*fef80a29SKazushi (Jam) Marukawa     SmallVectorImpl<MachineOperand> &Cond) const {
273*fef80a29SKazushi (Jam) Marukawa   VECC::CondCodes CC = static_cast<VECC::CondCodes>(Cond[0].getImm());
274*fef80a29SKazushi (Jam) Marukawa   Cond[0].setImm(GetOppositeBranchCondition(CC));
275*fef80a29SKazushi (Jam) Marukawa   return false;
276*fef80a29SKazushi (Jam) Marukawa }
277*fef80a29SKazushi (Jam) Marukawa 
2783a906a9fSKazushi (Jam) Marukawa static bool IsAliasOfSX(Register Reg) {
2793a906a9fSKazushi (Jam) Marukawa   return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) ||
2803a906a9fSKazushi (Jam) Marukawa          VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) ||
2813a906a9fSKazushi (Jam) Marukawa          VE::F32RegClass.contains(Reg);
2823a906a9fSKazushi (Jam) Marukawa }
2833a906a9fSKazushi (Jam) Marukawa 
284773ae62fSKazushi (Jam) Marukawa void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
285773ae62fSKazushi (Jam) Marukawa                               MachineBasicBlock::iterator I, const DebugLoc &DL,
286773ae62fSKazushi (Jam) Marukawa                               MCRegister DestReg, MCRegister SrcReg,
287773ae62fSKazushi (Jam) Marukawa                               bool KillSrc) const {
288773ae62fSKazushi (Jam) Marukawa 
2893a906a9fSKazushi (Jam) Marukawa   if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) {
290773ae62fSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::ORri), DestReg)
291773ae62fSKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(KillSrc))
292773ae62fSKazushi (Jam) Marukawa         .addImm(0);
293773ae62fSKazushi (Jam) Marukawa   } else {
294773ae62fSKazushi (Jam) Marukawa     const TargetRegisterInfo *TRI = &getRegisterInfo();
295773ae62fSKazushi (Jam) Marukawa     dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI)
296773ae62fSKazushi (Jam) Marukawa            << " to " << printReg(DestReg, TRI) << "\n";
297773ae62fSKazushi (Jam) Marukawa     llvm_unreachable("Impossible reg-to-reg copy");
298773ae62fSKazushi (Jam) Marukawa   }
299773ae62fSKazushi (Jam) Marukawa }
300773ae62fSKazushi (Jam) Marukawa 
301064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
302064859bdSKazushi (Jam) Marukawa   switch (MI.getOpcode()) {
303064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK: {
304064859bdSKazushi (Jam) Marukawa     return expandExtendStackPseudo(MI);
305064859bdSKazushi (Jam) Marukawa   }
306064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK_GUARD: {
307064859bdSKazushi (Jam) Marukawa     MI.eraseFromParent(); // The pseudo instruction is gone now.
308064859bdSKazushi (Jam) Marukawa     return true;
309064859bdSKazushi (Jam) Marukawa   }
310064859bdSKazushi (Jam) Marukawa   }
311064859bdSKazushi (Jam) Marukawa   return false;
312064859bdSKazushi (Jam) Marukawa }
313064859bdSKazushi (Jam) Marukawa 
314064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
315064859bdSKazushi (Jam) Marukawa   MachineBasicBlock &MBB = *MI.getParent();
316064859bdSKazushi (Jam) Marukawa   MachineFunction &MF = *MBB.getParent();
317064859bdSKazushi (Jam) Marukawa   const VEInstrInfo &TII =
318064859bdSKazushi (Jam) Marukawa       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
319064859bdSKazushi (Jam) Marukawa   DebugLoc dl = MBB.findDebugLoc(MI);
320064859bdSKazushi (Jam) Marukawa 
321064859bdSKazushi (Jam) Marukawa   // Create following instructions and multiple basic blocks.
322064859bdSKazushi (Jam) Marukawa   //
323064859bdSKazushi (Jam) Marukawa   // thisBB:
324064859bdSKazushi (Jam) Marukawa   //   brge.l.t %sp, %sl, sinkBB
325064859bdSKazushi (Jam) Marukawa   // syscallBB:
326064859bdSKazushi (Jam) Marukawa   //   ld      %s61, 0x18(, %tp)        // load param area
327064859bdSKazushi (Jam) Marukawa   //   or      %s62, 0, %s0             // spill the value of %s0
328064859bdSKazushi (Jam) Marukawa   //   lea     %s63, 0x13b              // syscall # of grow
329064859bdSKazushi (Jam) Marukawa   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
330064859bdSKazushi (Jam) Marukawa   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
331064859bdSKazushi (Jam) Marukawa   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
332064859bdSKazushi (Jam) Marukawa   //   monc                             // call monitor
333064859bdSKazushi (Jam) Marukawa   //   or      %s0, 0, %s62             // restore the value of %s0
334064859bdSKazushi (Jam) Marukawa   // sinkBB:
335064859bdSKazushi (Jam) Marukawa 
336064859bdSKazushi (Jam) Marukawa   // Create new MBB
337064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *BB = &MBB;
338064859bdSKazushi (Jam) Marukawa   const BasicBlock *LLVM_BB = BB->getBasicBlock();
339064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
340064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
341064859bdSKazushi (Jam) Marukawa   MachineFunction::iterator It = ++(BB->getIterator());
342064859bdSKazushi (Jam) Marukawa   MF.insert(It, syscallMBB);
343064859bdSKazushi (Jam) Marukawa   MF.insert(It, sinkMBB);
344064859bdSKazushi (Jam) Marukawa 
345064859bdSKazushi (Jam) Marukawa   // Transfer the remainder of BB and its successor edges to sinkMBB.
346064859bdSKazushi (Jam) Marukawa   sinkMBB->splice(sinkMBB->begin(), BB,
347064859bdSKazushi (Jam) Marukawa                   std::next(std::next(MachineBasicBlock::iterator(MI))),
348064859bdSKazushi (Jam) Marukawa                   BB->end());
349064859bdSKazushi (Jam) Marukawa   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
350064859bdSKazushi (Jam) Marukawa 
351064859bdSKazushi (Jam) Marukawa   // Next, add the true and fallthrough blocks as its successors.
352064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(syscallMBB);
353064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
354064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::BCRLrr))
355064859bdSKazushi (Jam) Marukawa       .addImm(VECC::CC_IGE)
356064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11) // %sp
357064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8)  // %sl
358064859bdSKazushi (Jam) Marukawa       .addMBB(sinkMBB);
359064859bdSKazushi (Jam) Marukawa 
360064859bdSKazushi (Jam) Marukawa   BB = syscallMBB;
361064859bdSKazushi (Jam) Marukawa 
362064859bdSKazushi (Jam) Marukawa   // Update machine-CFG edges
363064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
364064859bdSKazushi (Jam) Marukawa 
365064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61)
366064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX14)
367064859bdSKazushi (Jam) Marukawa       .addImm(0x18);
368064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
369064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX0)
370064859bdSKazushi (Jam) Marukawa       .addImm(0);
371064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63)
372064859bdSKazushi (Jam) Marukawa       .addImm(0x13b);
373064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
374064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
375064859bdSKazushi (Jam) Marukawa       .addImm(0)
376064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX63);
377064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
378064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
379064859bdSKazushi (Jam) Marukawa       .addImm(8)
380064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8);
381064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
382064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
383064859bdSKazushi (Jam) Marukawa       .addImm(16)
384064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11);
385064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::MONC));
386064859bdSKazushi (Jam) Marukawa 
387064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
388064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX62)
389064859bdSKazushi (Jam) Marukawa       .addImm(0);
390064859bdSKazushi (Jam) Marukawa 
391064859bdSKazushi (Jam) Marukawa   MI.eraseFromParent(); // The pseudo instruction is gone now.
392064859bdSKazushi (Jam) Marukawa   return true;
393064859bdSKazushi (Jam) Marukawa }
394