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