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"
1560431bd7SKazushi (Jam) Marukawa #include "VEMachineFunctionInfo.h"
16064859bdSKazushi (Jam) Marukawa #include "VESubtarget.h"
17064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/STLExtras.h"
18064859bdSKazushi (Jam) Marukawa #include "llvm/ADT/SmallVector.h"
19064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineFrameInfo.h"
20064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineInstrBuilder.h"
21064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineMemOperand.h"
22064859bdSKazushi (Jam) Marukawa #include "llvm/CodeGen/MachineRegisterInfo.h"
23064859bdSKazushi (Jam) Marukawa #include "llvm/Support/CommandLine.h"
24064859bdSKazushi (Jam) Marukawa #include "llvm/Support/Debug.h"
25064859bdSKazushi (Jam) Marukawa #include "llvm/Support/ErrorHandling.h"
26064859bdSKazushi (Jam) Marukawa #include "llvm/Support/TargetRegistry.h"
27064859bdSKazushi (Jam) Marukawa 
28064859bdSKazushi (Jam) Marukawa #define DEBUG_TYPE "ve"
29064859bdSKazushi (Jam) Marukawa 
30064859bdSKazushi (Jam) Marukawa using namespace llvm;
31064859bdSKazushi (Jam) Marukawa 
32064859bdSKazushi (Jam) Marukawa #define GET_INSTRINFO_CTOR_DTOR
33064859bdSKazushi (Jam) Marukawa #include "VEGenInstrInfo.inc"
34064859bdSKazushi (Jam) Marukawa 
35064859bdSKazushi (Jam) Marukawa // Pin the vtable to this file.
36064859bdSKazushi (Jam) Marukawa void VEInstrInfo::anchor() {}
37064859bdSKazushi (Jam) Marukawa 
38064859bdSKazushi (Jam) Marukawa VEInstrInfo::VEInstrInfo(VESubtarget &ST)
39df4cc35eSFangrui Song     : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI() {}
40064859bdSKazushi (Jam) Marukawa 
41fef80a29SKazushi (Jam) Marukawa static bool IsIntegerCC(unsigned CC) { return (CC < VECC::CC_AF); }
42fef80a29SKazushi (Jam) Marukawa 
4328a42dd1SKazushi (Jam) Marukawa static VECC::CondCode GetOppositeBranchCondition(VECC::CondCode 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 
10024215fecSSimon 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,
18524215fecSSimon 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 {
27128a42dd1SKazushi (Jam) Marukawa   VECC::CondCode CC = static_cast<VECC::CondCode>(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 
29907c9f757SKazushi (Jam) Marukawa /// isLoadFromStackSlot - If the specified machine instruction is a direct
30007c9f757SKazushi (Jam) Marukawa /// load from a stack slot, return the virtual or physical register number of
30107c9f757SKazushi (Jam) Marukawa /// the destination along with the FrameIndex of the loaded stack slot.  If
30207c9f757SKazushi (Jam) Marukawa /// not, return 0.  This predicate must return 0 if the instruction has
30307c9f757SKazushi (Jam) Marukawa /// any side effects other than loading from the stack slot.
30407c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
30507c9f757SKazushi (Jam) Marukawa                                           int &FrameIndex) const {
306*e981a46aSKazushi (Jam) Marukawa   if (MI.getOpcode() == VE::LDrii ||    // I64
307*e981a46aSKazushi (Jam) Marukawa       MI.getOpcode() == VE::LDLSXrii || // I32
308*e981a46aSKazushi (Jam) Marukawa       MI.getOpcode() == VE::LDUrii      // F32
309*e981a46aSKazushi (Jam) Marukawa   ) {
31007c9f757SKazushi (Jam) Marukawa     if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
311*e981a46aSKazushi (Jam) Marukawa         MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() &&
312*e981a46aSKazushi (Jam) Marukawa         MI.getOperand(3).getImm() == 0) {
31307c9f757SKazushi (Jam) Marukawa       FrameIndex = MI.getOperand(1).getIndex();
31407c9f757SKazushi (Jam) Marukawa       return MI.getOperand(0).getReg();
31507c9f757SKazushi (Jam) Marukawa     }
31607c9f757SKazushi (Jam) Marukawa   }
31707c9f757SKazushi (Jam) Marukawa   return 0;
31807c9f757SKazushi (Jam) Marukawa }
31907c9f757SKazushi (Jam) Marukawa 
32007c9f757SKazushi (Jam) Marukawa /// isStoreToStackSlot - If the specified machine instruction is a direct
32107c9f757SKazushi (Jam) Marukawa /// store to a stack slot, return the virtual or physical register number of
32207c9f757SKazushi (Jam) Marukawa /// the source reg along with the FrameIndex of the loaded stack slot.  If
32307c9f757SKazushi (Jam) Marukawa /// not, return 0.  This predicate must return 0 if the instruction has
32407c9f757SKazushi (Jam) Marukawa /// any side effects other than storing to the stack slot.
32507c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
32607c9f757SKazushi (Jam) Marukawa                                          int &FrameIndex) const {
327*e981a46aSKazushi (Jam) Marukawa   if (MI.getOpcode() == VE::STrii ||  // I64
328*e981a46aSKazushi (Jam) Marukawa       MI.getOpcode() == VE::STLrii || // I32
329*e981a46aSKazushi (Jam) Marukawa       MI.getOpcode() == VE::STUrii    // F32
330*e981a46aSKazushi (Jam) Marukawa   ) {
33107c9f757SKazushi (Jam) Marukawa     if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
332*e981a46aSKazushi (Jam) Marukawa         MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() &&
333*e981a46aSKazushi (Jam) Marukawa         MI.getOperand(2).getImm() == 0) {
33407c9f757SKazushi (Jam) Marukawa       FrameIndex = MI.getOperand(0).getIndex();
335*e981a46aSKazushi (Jam) Marukawa       return MI.getOperand(3).getReg();
33607c9f757SKazushi (Jam) Marukawa     }
33707c9f757SKazushi (Jam) Marukawa   }
33807c9f757SKazushi (Jam) Marukawa   return 0;
33907c9f757SKazushi (Jam) Marukawa }
34007c9f757SKazushi (Jam) Marukawa 
34107c9f757SKazushi (Jam) Marukawa void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
34207c9f757SKazushi (Jam) Marukawa                                       MachineBasicBlock::iterator I,
34307c9f757SKazushi (Jam) Marukawa                                       Register SrcReg, bool isKill, int FI,
34407c9f757SKazushi (Jam) Marukawa                                       const TargetRegisterClass *RC,
34507c9f757SKazushi (Jam) Marukawa                                       const TargetRegisterInfo *TRI) const {
34607c9f757SKazushi (Jam) Marukawa   DebugLoc DL;
34707c9f757SKazushi (Jam) Marukawa   if (I != MBB.end())
34807c9f757SKazushi (Jam) Marukawa     DL = I->getDebugLoc();
34907c9f757SKazushi (Jam) Marukawa 
35007c9f757SKazushi (Jam) Marukawa   MachineFunction *MF = MBB.getParent();
35107c9f757SKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF->getFrameInfo();
35207c9f757SKazushi (Jam) Marukawa   MachineMemOperand *MMO = MF->getMachineMemOperand(
35307c9f757SKazushi (Jam) Marukawa       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
35407c9f757SKazushi (Jam) Marukawa       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
35507c9f757SKazushi (Jam) Marukawa 
35607c9f757SKazushi (Jam) Marukawa   // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
35707c9f757SKazushi (Jam) Marukawa   if (RC == &VE::I64RegClass) {
358*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STrii))
35907c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
36007c9f757SKazushi (Jam) Marukawa         .addImm(0)
361*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
36207c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
36307c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
36407c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::I32RegClass) {
365*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STLrii))
36607c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
36707c9f757SKazushi (Jam) Marukawa         .addImm(0)
368*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
36907c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
37007c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
37107c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::F32RegClass) {
372*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STUrii))
37307c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
37407c9f757SKazushi (Jam) Marukawa         .addImm(0)
375*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
37607c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
37707c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
37807c9f757SKazushi (Jam) Marukawa   } else
37907c9f757SKazushi (Jam) Marukawa     report_fatal_error("Can't store this register to stack slot");
38007c9f757SKazushi (Jam) Marukawa }
38107c9f757SKazushi (Jam) Marukawa 
38207c9f757SKazushi (Jam) Marukawa void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
38307c9f757SKazushi (Jam) Marukawa                                        MachineBasicBlock::iterator I,
38407c9f757SKazushi (Jam) Marukawa                                        Register DestReg, int FI,
38507c9f757SKazushi (Jam) Marukawa                                        const TargetRegisterClass *RC,
38607c9f757SKazushi (Jam) Marukawa                                        const TargetRegisterInfo *TRI) const {
38707c9f757SKazushi (Jam) Marukawa   DebugLoc DL;
38807c9f757SKazushi (Jam) Marukawa   if (I != MBB.end())
38907c9f757SKazushi (Jam) Marukawa     DL = I->getDebugLoc();
39007c9f757SKazushi (Jam) Marukawa 
39107c9f757SKazushi (Jam) Marukawa   MachineFunction *MF = MBB.getParent();
39207c9f757SKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF->getFrameInfo();
39307c9f757SKazushi (Jam) Marukawa   MachineMemOperand *MMO = MF->getMachineMemOperand(
39407c9f757SKazushi (Jam) Marukawa       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
39507c9f757SKazushi (Jam) Marukawa       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
39607c9f757SKazushi (Jam) Marukawa 
39707c9f757SKazushi (Jam) Marukawa   if (RC == &VE::I64RegClass) {
398*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDrii), DestReg)
39907c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
40007c9f757SKazushi (Jam) Marukawa         .addImm(0)
401*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
40207c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
40307c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::I32RegClass) {
404*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg)
40507c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
40607c9f757SKazushi (Jam) Marukawa         .addImm(0)
407*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
40807c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
40907c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::F32RegClass) {
410*e981a46aSKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg)
41107c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
41207c9f757SKazushi (Jam) Marukawa         .addImm(0)
413*e981a46aSKazushi (Jam) Marukawa         .addImm(0)
41407c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
41507c9f757SKazushi (Jam) Marukawa   } else
41607c9f757SKazushi (Jam) Marukawa     report_fatal_error("Can't load this register from stack slot");
41707c9f757SKazushi (Jam) Marukawa }
41807c9f757SKazushi (Jam) Marukawa 
41960431bd7SKazushi (Jam) Marukawa Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
42060431bd7SKazushi (Jam) Marukawa   VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>();
42160431bd7SKazushi (Jam) Marukawa   Register GlobalBaseReg = VEFI->getGlobalBaseReg();
42260431bd7SKazushi (Jam) Marukawa   if (GlobalBaseReg != 0)
42360431bd7SKazushi (Jam) Marukawa     return GlobalBaseReg;
42460431bd7SKazushi (Jam) Marukawa 
42560431bd7SKazushi (Jam) Marukawa   // We use %s15 (%got) as a global base register
42660431bd7SKazushi (Jam) Marukawa   GlobalBaseReg = VE::SX15;
42760431bd7SKazushi (Jam) Marukawa 
42860431bd7SKazushi (Jam) Marukawa   // Insert a pseudo instruction to set the GlobalBaseReg into the first
42960431bd7SKazushi (Jam) Marukawa   // MBB of the function
43060431bd7SKazushi (Jam) Marukawa   MachineBasicBlock &FirstMBB = MF->front();
43160431bd7SKazushi (Jam) Marukawa   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
43260431bd7SKazushi (Jam) Marukawa   DebugLoc dl;
43360431bd7SKazushi (Jam) Marukawa   BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg);
43460431bd7SKazushi (Jam) Marukawa   VEFI->setGlobalBaseReg(GlobalBaseReg);
43560431bd7SKazushi (Jam) Marukawa   return GlobalBaseReg;
43660431bd7SKazushi (Jam) Marukawa }
43760431bd7SKazushi (Jam) Marukawa 
438064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
439064859bdSKazushi (Jam) Marukawa   switch (MI.getOpcode()) {
440064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK: {
441064859bdSKazushi (Jam) Marukawa     return expandExtendStackPseudo(MI);
442064859bdSKazushi (Jam) Marukawa   }
443064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK_GUARD: {
444064859bdSKazushi (Jam) Marukawa     MI.eraseFromParent(); // The pseudo instruction is gone now.
445064859bdSKazushi (Jam) Marukawa     return true;
446064859bdSKazushi (Jam) Marukawa   }
447064859bdSKazushi (Jam) Marukawa   }
448064859bdSKazushi (Jam) Marukawa   return false;
449064859bdSKazushi (Jam) Marukawa }
450064859bdSKazushi (Jam) Marukawa 
451064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
452064859bdSKazushi (Jam) Marukawa   MachineBasicBlock &MBB = *MI.getParent();
453064859bdSKazushi (Jam) Marukawa   MachineFunction &MF = *MBB.getParent();
454064859bdSKazushi (Jam) Marukawa   const VEInstrInfo &TII =
455064859bdSKazushi (Jam) Marukawa       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
456064859bdSKazushi (Jam) Marukawa   DebugLoc dl = MBB.findDebugLoc(MI);
457064859bdSKazushi (Jam) Marukawa 
458064859bdSKazushi (Jam) Marukawa   // Create following instructions and multiple basic blocks.
459064859bdSKazushi (Jam) Marukawa   //
460064859bdSKazushi (Jam) Marukawa   // thisBB:
461064859bdSKazushi (Jam) Marukawa   //   brge.l.t %sp, %sl, sinkBB
462064859bdSKazushi (Jam) Marukawa   // syscallBB:
463064859bdSKazushi (Jam) Marukawa   //   ld      %s61, 0x18(, %tp)        // load param area
464064859bdSKazushi (Jam) Marukawa   //   or      %s62, 0, %s0             // spill the value of %s0
465064859bdSKazushi (Jam) Marukawa   //   lea     %s63, 0x13b              // syscall # of grow
466064859bdSKazushi (Jam) Marukawa   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
467064859bdSKazushi (Jam) Marukawa   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
468064859bdSKazushi (Jam) Marukawa   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
469064859bdSKazushi (Jam) Marukawa   //   monc                             // call monitor
470064859bdSKazushi (Jam) Marukawa   //   or      %s0, 0, %s62             // restore the value of %s0
471064859bdSKazushi (Jam) Marukawa   // sinkBB:
472064859bdSKazushi (Jam) Marukawa 
473064859bdSKazushi (Jam) Marukawa   // Create new MBB
474064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *BB = &MBB;
475064859bdSKazushi (Jam) Marukawa   const BasicBlock *LLVM_BB = BB->getBasicBlock();
476064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
477064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
478064859bdSKazushi (Jam) Marukawa   MachineFunction::iterator It = ++(BB->getIterator());
479064859bdSKazushi (Jam) Marukawa   MF.insert(It, syscallMBB);
480064859bdSKazushi (Jam) Marukawa   MF.insert(It, sinkMBB);
481064859bdSKazushi (Jam) Marukawa 
482064859bdSKazushi (Jam) Marukawa   // Transfer the remainder of BB and its successor edges to sinkMBB.
483064859bdSKazushi (Jam) Marukawa   sinkMBB->splice(sinkMBB->begin(), BB,
484064859bdSKazushi (Jam) Marukawa                   std::next(std::next(MachineBasicBlock::iterator(MI))),
485064859bdSKazushi (Jam) Marukawa                   BB->end());
486064859bdSKazushi (Jam) Marukawa   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
487064859bdSKazushi (Jam) Marukawa 
488064859bdSKazushi (Jam) Marukawa   // Next, add the true and fallthrough blocks as its successors.
489064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(syscallMBB);
490064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
491064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::BCRLrr))
492064859bdSKazushi (Jam) Marukawa       .addImm(VECC::CC_IGE)
493064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11) // %sp
494064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8)  // %sl
495064859bdSKazushi (Jam) Marukawa       .addMBB(sinkMBB);
496064859bdSKazushi (Jam) Marukawa 
497064859bdSKazushi (Jam) Marukawa   BB = syscallMBB;
498064859bdSKazushi (Jam) Marukawa 
499064859bdSKazushi (Jam) Marukawa   // Update machine-CFG edges
500064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
501064859bdSKazushi (Jam) Marukawa 
502*e981a46aSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61)
503064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX14)
504*e981a46aSKazushi (Jam) Marukawa       .addImm(0)
505064859bdSKazushi (Jam) Marukawa       .addImm(0x18);
506064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
507064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX0)
508064859bdSKazushi (Jam) Marukawa       .addImm(0);
509*e981a46aSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63)
510*e981a46aSKazushi (Jam) Marukawa       .addImm(0)
511*e981a46aSKazushi (Jam) Marukawa       .addImm(0)
512064859bdSKazushi (Jam) Marukawa       .addImm(0x13b);
513064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
514064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
515064859bdSKazushi (Jam) Marukawa       .addImm(0)
516064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX63);
517064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
518064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
519064859bdSKazushi (Jam) Marukawa       .addImm(8)
520064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8);
521064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
522064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
523064859bdSKazushi (Jam) Marukawa       .addImm(16)
524064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11);
525064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::MONC));
526064859bdSKazushi (Jam) Marukawa 
527064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
528064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX62)
529064859bdSKazushi (Jam) Marukawa       .addImm(0);
530064859bdSKazushi (Jam) Marukawa 
531064859bdSKazushi (Jam) Marukawa   MI.eraseFromParent(); // The pseudo instruction is gone now.
532064859bdSKazushi (Jam) Marukawa   return true;
533064859bdSKazushi (Jam) Marukawa }
534