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 
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 {
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 
299*07c9f757SKazushi (Jam) Marukawa /// isLoadFromStackSlot - If the specified machine instruction is a direct
300*07c9f757SKazushi (Jam) Marukawa /// load from a stack slot, return the virtual or physical register number of
301*07c9f757SKazushi (Jam) Marukawa /// the destination along with the FrameIndex of the loaded stack slot.  If
302*07c9f757SKazushi (Jam) Marukawa /// not, return 0.  This predicate must return 0 if the instruction has
303*07c9f757SKazushi (Jam) Marukawa /// any side effects other than loading from the stack slot.
304*07c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
305*07c9f757SKazushi (Jam) Marukawa                                           int &FrameIndex) const {
306*07c9f757SKazushi (Jam) Marukawa   if (MI.getOpcode() == VE::LDSri || MI.getOpcode() == VE::LDLri ||
307*07c9f757SKazushi (Jam) Marukawa       MI.getOpcode() == VE::LDUri) {
308*07c9f757SKazushi (Jam) Marukawa     if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
309*07c9f757SKazushi (Jam) Marukawa         MI.getOperand(2).getImm() == 0) {
310*07c9f757SKazushi (Jam) Marukawa       FrameIndex = MI.getOperand(1).getIndex();
311*07c9f757SKazushi (Jam) Marukawa       return MI.getOperand(0).getReg();
312*07c9f757SKazushi (Jam) Marukawa     }
313*07c9f757SKazushi (Jam) Marukawa   }
314*07c9f757SKazushi (Jam) Marukawa   return 0;
315*07c9f757SKazushi (Jam) Marukawa }
316*07c9f757SKazushi (Jam) Marukawa 
317*07c9f757SKazushi (Jam) Marukawa /// isStoreToStackSlot - If the specified machine instruction is a direct
318*07c9f757SKazushi (Jam) Marukawa /// store to a stack slot, return the virtual or physical register number of
319*07c9f757SKazushi (Jam) Marukawa /// the source reg along with the FrameIndex of the loaded stack slot.  If
320*07c9f757SKazushi (Jam) Marukawa /// not, return 0.  This predicate must return 0 if the instruction has
321*07c9f757SKazushi (Jam) Marukawa /// any side effects other than storing to the stack slot.
322*07c9f757SKazushi (Jam) Marukawa unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
323*07c9f757SKazushi (Jam) Marukawa                                          int &FrameIndex) const {
324*07c9f757SKazushi (Jam) Marukawa   if (MI.getOpcode() == VE::STSri || MI.getOpcode() == VE::STLri ||
325*07c9f757SKazushi (Jam) Marukawa       MI.getOpcode() == VE::STUri) {
326*07c9f757SKazushi (Jam) Marukawa     if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
327*07c9f757SKazushi (Jam) Marukawa         MI.getOperand(1).getImm() == 0) {
328*07c9f757SKazushi (Jam) Marukawa       FrameIndex = MI.getOperand(0).getIndex();
329*07c9f757SKazushi (Jam) Marukawa       return MI.getOperand(2).getReg();
330*07c9f757SKazushi (Jam) Marukawa     }
331*07c9f757SKazushi (Jam) Marukawa   }
332*07c9f757SKazushi (Jam) Marukawa   return 0;
333*07c9f757SKazushi (Jam) Marukawa }
334*07c9f757SKazushi (Jam) Marukawa 
335*07c9f757SKazushi (Jam) Marukawa void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
336*07c9f757SKazushi (Jam) Marukawa                                       MachineBasicBlock::iterator I,
337*07c9f757SKazushi (Jam) Marukawa                                       Register SrcReg, bool isKill, int FI,
338*07c9f757SKazushi (Jam) Marukawa                                       const TargetRegisterClass *RC,
339*07c9f757SKazushi (Jam) Marukawa                                       const TargetRegisterInfo *TRI) const {
340*07c9f757SKazushi (Jam) Marukawa   DebugLoc DL;
341*07c9f757SKazushi (Jam) Marukawa   if (I != MBB.end())
342*07c9f757SKazushi (Jam) Marukawa     DL = I->getDebugLoc();
343*07c9f757SKazushi (Jam) Marukawa 
344*07c9f757SKazushi (Jam) Marukawa   MachineFunction *MF = MBB.getParent();
345*07c9f757SKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF->getFrameInfo();
346*07c9f757SKazushi (Jam) Marukawa   MachineMemOperand *MMO = MF->getMachineMemOperand(
347*07c9f757SKazushi (Jam) Marukawa       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
348*07c9f757SKazushi (Jam) Marukawa       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
349*07c9f757SKazushi (Jam) Marukawa 
350*07c9f757SKazushi (Jam) Marukawa   // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
351*07c9f757SKazushi (Jam) Marukawa   if (RC == &VE::I64RegClass) {
352*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STSri))
353*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
354*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
355*07c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
356*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
357*07c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::I32RegClass) {
358*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STLri))
359*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
360*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
361*07c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
362*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
363*07c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::F32RegClass) {
364*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::STUri))
365*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
366*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
367*07c9f757SKazushi (Jam) Marukawa         .addReg(SrcReg, getKillRegState(isKill))
368*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
369*07c9f757SKazushi (Jam) Marukawa   } else
370*07c9f757SKazushi (Jam) Marukawa     report_fatal_error("Can't store this register to stack slot");
371*07c9f757SKazushi (Jam) Marukawa }
372*07c9f757SKazushi (Jam) Marukawa 
373*07c9f757SKazushi (Jam) Marukawa void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
374*07c9f757SKazushi (Jam) Marukawa                                        MachineBasicBlock::iterator I,
375*07c9f757SKazushi (Jam) Marukawa                                        Register DestReg, int FI,
376*07c9f757SKazushi (Jam) Marukawa                                        const TargetRegisterClass *RC,
377*07c9f757SKazushi (Jam) Marukawa                                        const TargetRegisterInfo *TRI) const {
378*07c9f757SKazushi (Jam) Marukawa   DebugLoc DL;
379*07c9f757SKazushi (Jam) Marukawa   if (I != MBB.end())
380*07c9f757SKazushi (Jam) Marukawa     DL = I->getDebugLoc();
381*07c9f757SKazushi (Jam) Marukawa 
382*07c9f757SKazushi (Jam) Marukawa   MachineFunction *MF = MBB.getParent();
383*07c9f757SKazushi (Jam) Marukawa   const MachineFrameInfo &MFI = MF->getFrameInfo();
384*07c9f757SKazushi (Jam) Marukawa   MachineMemOperand *MMO = MF->getMachineMemOperand(
385*07c9f757SKazushi (Jam) Marukawa       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
386*07c9f757SKazushi (Jam) Marukawa       MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
387*07c9f757SKazushi (Jam) Marukawa 
388*07c9f757SKazushi (Jam) Marukawa   if (RC == &VE::I64RegClass) {
389*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDSri), DestReg)
390*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
391*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
392*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
393*07c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::I32RegClass) {
394*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDLri), DestReg)
395*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
396*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
397*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
398*07c9f757SKazushi (Jam) Marukawa   } else if (RC == &VE::F32RegClass) {
399*07c9f757SKazushi (Jam) Marukawa     BuildMI(MBB, I, DL, get(VE::LDUri), DestReg)
400*07c9f757SKazushi (Jam) Marukawa         .addFrameIndex(FI)
401*07c9f757SKazushi (Jam) Marukawa         .addImm(0)
402*07c9f757SKazushi (Jam) Marukawa         .addMemOperand(MMO);
403*07c9f757SKazushi (Jam) Marukawa   } else
404*07c9f757SKazushi (Jam) Marukawa     report_fatal_error("Can't load this register from stack slot");
405*07c9f757SKazushi (Jam) Marukawa }
406*07c9f757SKazushi (Jam) Marukawa 
407064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
408064859bdSKazushi (Jam) Marukawa   switch (MI.getOpcode()) {
409064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK: {
410064859bdSKazushi (Jam) Marukawa     return expandExtendStackPseudo(MI);
411064859bdSKazushi (Jam) Marukawa   }
412064859bdSKazushi (Jam) Marukawa   case VE::EXTEND_STACK_GUARD: {
413064859bdSKazushi (Jam) Marukawa     MI.eraseFromParent(); // The pseudo instruction is gone now.
414064859bdSKazushi (Jam) Marukawa     return true;
415064859bdSKazushi (Jam) Marukawa   }
416064859bdSKazushi (Jam) Marukawa   }
417064859bdSKazushi (Jam) Marukawa   return false;
418064859bdSKazushi (Jam) Marukawa }
419064859bdSKazushi (Jam) Marukawa 
420064859bdSKazushi (Jam) Marukawa bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
421064859bdSKazushi (Jam) Marukawa   MachineBasicBlock &MBB = *MI.getParent();
422064859bdSKazushi (Jam) Marukawa   MachineFunction &MF = *MBB.getParent();
423064859bdSKazushi (Jam) Marukawa   const VEInstrInfo &TII =
424064859bdSKazushi (Jam) Marukawa       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
425064859bdSKazushi (Jam) Marukawa   DebugLoc dl = MBB.findDebugLoc(MI);
426064859bdSKazushi (Jam) Marukawa 
427064859bdSKazushi (Jam) Marukawa   // Create following instructions and multiple basic blocks.
428064859bdSKazushi (Jam) Marukawa   //
429064859bdSKazushi (Jam) Marukawa   // thisBB:
430064859bdSKazushi (Jam) Marukawa   //   brge.l.t %sp, %sl, sinkBB
431064859bdSKazushi (Jam) Marukawa   // syscallBB:
432064859bdSKazushi (Jam) Marukawa   //   ld      %s61, 0x18(, %tp)        // load param area
433064859bdSKazushi (Jam) Marukawa   //   or      %s62, 0, %s0             // spill the value of %s0
434064859bdSKazushi (Jam) Marukawa   //   lea     %s63, 0x13b              // syscall # of grow
435064859bdSKazushi (Jam) Marukawa   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
436064859bdSKazushi (Jam) Marukawa   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
437064859bdSKazushi (Jam) Marukawa   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
438064859bdSKazushi (Jam) Marukawa   //   monc                             // call monitor
439064859bdSKazushi (Jam) Marukawa   //   or      %s0, 0, %s62             // restore the value of %s0
440064859bdSKazushi (Jam) Marukawa   // sinkBB:
441064859bdSKazushi (Jam) Marukawa 
442064859bdSKazushi (Jam) Marukawa   // Create new MBB
443064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *BB = &MBB;
444064859bdSKazushi (Jam) Marukawa   const BasicBlock *LLVM_BB = BB->getBasicBlock();
445064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
446064859bdSKazushi (Jam) Marukawa   MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
447064859bdSKazushi (Jam) Marukawa   MachineFunction::iterator It = ++(BB->getIterator());
448064859bdSKazushi (Jam) Marukawa   MF.insert(It, syscallMBB);
449064859bdSKazushi (Jam) Marukawa   MF.insert(It, sinkMBB);
450064859bdSKazushi (Jam) Marukawa 
451064859bdSKazushi (Jam) Marukawa   // Transfer the remainder of BB and its successor edges to sinkMBB.
452064859bdSKazushi (Jam) Marukawa   sinkMBB->splice(sinkMBB->begin(), BB,
453064859bdSKazushi (Jam) Marukawa                   std::next(std::next(MachineBasicBlock::iterator(MI))),
454064859bdSKazushi (Jam) Marukawa                   BB->end());
455064859bdSKazushi (Jam) Marukawa   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
456064859bdSKazushi (Jam) Marukawa 
457064859bdSKazushi (Jam) Marukawa   // Next, add the true and fallthrough blocks as its successors.
458064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(syscallMBB);
459064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
460064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::BCRLrr))
461064859bdSKazushi (Jam) Marukawa       .addImm(VECC::CC_IGE)
462064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11) // %sp
463064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8)  // %sl
464064859bdSKazushi (Jam) Marukawa       .addMBB(sinkMBB);
465064859bdSKazushi (Jam) Marukawa 
466064859bdSKazushi (Jam) Marukawa   BB = syscallMBB;
467064859bdSKazushi (Jam) Marukawa 
468064859bdSKazushi (Jam) Marukawa   // Update machine-CFG edges
469064859bdSKazushi (Jam) Marukawa   BB->addSuccessor(sinkMBB);
470064859bdSKazushi (Jam) Marukawa 
471064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61)
472064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX14)
473064859bdSKazushi (Jam) Marukawa       .addImm(0x18);
474064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
475064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX0)
476064859bdSKazushi (Jam) Marukawa       .addImm(0);
477064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63)
478064859bdSKazushi (Jam) Marukawa       .addImm(0x13b);
479064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
480064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
481064859bdSKazushi (Jam) Marukawa       .addImm(0)
482064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX63);
483064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
484064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
485064859bdSKazushi (Jam) Marukawa       .addImm(8)
486064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX8);
487064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::SHMri))
488064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX61)
489064859bdSKazushi (Jam) Marukawa       .addImm(16)
490064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX11);
491064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::MONC));
492064859bdSKazushi (Jam) Marukawa 
493064859bdSKazushi (Jam) Marukawa   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
494064859bdSKazushi (Jam) Marukawa       .addReg(VE::SX62)
495064859bdSKazushi (Jam) Marukawa       .addImm(0);
496064859bdSKazushi (Jam) Marukawa 
497064859bdSKazushi (Jam) Marukawa   MI.eraseFromParent(); // The pseudo instruction is gone now.
498064859bdSKazushi (Jam) Marukawa   return true;
499064859bdSKazushi (Jam) Marukawa }
500