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