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