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::LDrii ||    // I64
307       MI.getOpcode() == VE::LDLSXrii || // I32
308       MI.getOpcode() == VE::LDUrii      // F32
309   ) {
310     if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
311         MI.getOperand(2).getImm() == 0 && MI.getOperand(3).isImm() &&
312         MI.getOperand(3).getImm() == 0) {
313       FrameIndex = MI.getOperand(1).getIndex();
314       return MI.getOperand(0).getReg();
315     }
316   }
317   return 0;
318 }
319 
320 /// isStoreToStackSlot - If the specified machine instruction is a direct
321 /// store to a stack slot, return the virtual or physical register number of
322 /// the source reg along with the FrameIndex of the loaded stack slot.  If
323 /// not, return 0.  This predicate must return 0 if the instruction has
324 /// any side effects other than storing to the stack slot.
325 unsigned VEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
326                                          int &FrameIndex) const {
327   if (MI.getOpcode() == VE::STrii ||  // I64
328       MI.getOpcode() == VE::STLrii || // I32
329       MI.getOpcode() == VE::STUrii    // F32
330   ) {
331     if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
332         MI.getOperand(1).getImm() == 0 && MI.getOperand(2).isImm() &&
333         MI.getOperand(2).getImm() == 0) {
334       FrameIndex = MI.getOperand(0).getIndex();
335       return MI.getOperand(3).getReg();
336     }
337   }
338   return 0;
339 }
340 
341 void VEInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
342                                       MachineBasicBlock::iterator I,
343                                       Register SrcReg, bool isKill, int FI,
344                                       const TargetRegisterClass *RC,
345                                       const TargetRegisterInfo *TRI) const {
346   DebugLoc DL;
347   if (I != MBB.end())
348     DL = I->getDebugLoc();
349 
350   MachineFunction *MF = MBB.getParent();
351   const MachineFrameInfo &MFI = MF->getFrameInfo();
352   MachineMemOperand *MMO = MF->getMachineMemOperand(
353       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,
354       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
355 
356   // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
357   if (RC == &VE::I64RegClass) {
358     BuildMI(MBB, I, DL, get(VE::STrii))
359         .addFrameIndex(FI)
360         .addImm(0)
361         .addImm(0)
362         .addReg(SrcReg, getKillRegState(isKill))
363         .addMemOperand(MMO);
364   } else if (RC == &VE::I32RegClass) {
365     BuildMI(MBB, I, DL, get(VE::STLrii))
366         .addFrameIndex(FI)
367         .addImm(0)
368         .addImm(0)
369         .addReg(SrcReg, getKillRegState(isKill))
370         .addMemOperand(MMO);
371   } else if (RC == &VE::F32RegClass) {
372     BuildMI(MBB, I, DL, get(VE::STUrii))
373         .addFrameIndex(FI)
374         .addImm(0)
375         .addImm(0)
376         .addReg(SrcReg, getKillRegState(isKill))
377         .addMemOperand(MMO);
378   } else
379     report_fatal_error("Can't store this register to stack slot");
380 }
381 
382 void VEInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
383                                        MachineBasicBlock::iterator I,
384                                        Register DestReg, int FI,
385                                        const TargetRegisterClass *RC,
386                                        const TargetRegisterInfo *TRI) const {
387   DebugLoc DL;
388   if (I != MBB.end())
389     DL = I->getDebugLoc();
390 
391   MachineFunction *MF = MBB.getParent();
392   const MachineFrameInfo &MFI = MF->getFrameInfo();
393   MachineMemOperand *MMO = MF->getMachineMemOperand(
394       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
395       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
396 
397   if (RC == &VE::I64RegClass) {
398     BuildMI(MBB, I, DL, get(VE::LDrii), DestReg)
399         .addFrameIndex(FI)
400         .addImm(0)
401         .addImm(0)
402         .addMemOperand(MMO);
403   } else if (RC == &VE::I32RegClass) {
404     BuildMI(MBB, I, DL, get(VE::LDLSXrii), DestReg)
405         .addFrameIndex(FI)
406         .addImm(0)
407         .addImm(0)
408         .addMemOperand(MMO);
409   } else if (RC == &VE::F32RegClass) {
410     BuildMI(MBB, I, DL, get(VE::LDUrii), DestReg)
411         .addFrameIndex(FI)
412         .addImm(0)
413         .addImm(0)
414         .addMemOperand(MMO);
415   } else
416     report_fatal_error("Can't load this register from stack slot");
417 }
418 
419 Register VEInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
420   VEMachineFunctionInfo *VEFI = MF->getInfo<VEMachineFunctionInfo>();
421   Register GlobalBaseReg = VEFI->getGlobalBaseReg();
422   if (GlobalBaseReg != 0)
423     return GlobalBaseReg;
424 
425   // We use %s15 (%got) as a global base register
426   GlobalBaseReg = VE::SX15;
427 
428   // Insert a pseudo instruction to set the GlobalBaseReg into the first
429   // MBB of the function
430   MachineBasicBlock &FirstMBB = MF->front();
431   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
432   DebugLoc dl;
433   BuildMI(FirstMBB, MBBI, dl, get(VE::GETGOT), GlobalBaseReg);
434   VEFI->setGlobalBaseReg(GlobalBaseReg);
435   return GlobalBaseReg;
436 }
437 
438 bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
439   switch (MI.getOpcode()) {
440   case VE::EXTEND_STACK: {
441     return expandExtendStackPseudo(MI);
442   }
443   case VE::EXTEND_STACK_GUARD: {
444     MI.eraseFromParent(); // The pseudo instruction is gone now.
445     return true;
446   }
447   }
448   return false;
449 }
450 
451 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
452   MachineBasicBlock &MBB = *MI.getParent();
453   MachineFunction &MF = *MBB.getParent();
454   const VEInstrInfo &TII =
455       *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
456   DebugLoc dl = MBB.findDebugLoc(MI);
457 
458   // Create following instructions and multiple basic blocks.
459   //
460   // thisBB:
461   //   brge.l.t %sp, %sl, sinkBB
462   // syscallBB:
463   //   ld      %s61, 0x18(, %tp)        // load param area
464   //   or      %s62, 0, %s0             // spill the value of %s0
465   //   lea     %s63, 0x13b              // syscall # of grow
466   //   shm.l   %s63, 0x0(%s61)          // store syscall # at addr:0
467   //   shm.l   %sl, 0x8(%s61)           // store old limit at addr:8
468   //   shm.l   %sp, 0x10(%s61)          // store new limit at addr:16
469   //   monc                             // call monitor
470   //   or      %s0, 0, %s62             // restore the value of %s0
471   // sinkBB:
472 
473   // Create new MBB
474   MachineBasicBlock *BB = &MBB;
475   const BasicBlock *LLVM_BB = BB->getBasicBlock();
476   MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
477   MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
478   MachineFunction::iterator It = ++(BB->getIterator());
479   MF.insert(It, syscallMBB);
480   MF.insert(It, sinkMBB);
481 
482   // Transfer the remainder of BB and its successor edges to sinkMBB.
483   sinkMBB->splice(sinkMBB->begin(), BB,
484                   std::next(std::next(MachineBasicBlock::iterator(MI))),
485                   BB->end());
486   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
487 
488   // Next, add the true and fallthrough blocks as its successors.
489   BB->addSuccessor(syscallMBB);
490   BB->addSuccessor(sinkMBB);
491   BuildMI(BB, dl, TII.get(VE::BCRLrr))
492       .addImm(VECC::CC_IGE)
493       .addReg(VE::SX11) // %sp
494       .addReg(VE::SX8)  // %sl
495       .addMBB(sinkMBB);
496 
497   BB = syscallMBB;
498 
499   // Update machine-CFG edges
500   BB->addSuccessor(sinkMBB);
501 
502   BuildMI(BB, dl, TII.get(VE::LDrii), VE::SX61)
503       .addReg(VE::SX14)
504       .addImm(0)
505       .addImm(0x18);
506   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
507       .addReg(VE::SX0)
508       .addImm(0);
509   BuildMI(BB, dl, TII.get(VE::LEAzii), VE::SX63)
510       .addImm(0)
511       .addImm(0)
512       .addImm(0x13b);
513   BuildMI(BB, dl, TII.get(VE::SHMri))
514       .addReg(VE::SX61)
515       .addImm(0)
516       .addReg(VE::SX63);
517   BuildMI(BB, dl, TII.get(VE::SHMri))
518       .addReg(VE::SX61)
519       .addImm(8)
520       .addReg(VE::SX8);
521   BuildMI(BB, dl, TII.get(VE::SHMri))
522       .addReg(VE::SX61)
523       .addImm(16)
524       .addReg(VE::SX11);
525   BuildMI(BB, dl, TII.get(VE::MONC));
526 
527   BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
528       .addReg(VE::SX62)
529       .addImm(0);
530 
531   MI.eraseFromParent(); // The pseudo instruction is gone now.
532   return true;
533 }
534