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 "VESubtarget.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineMemOperand.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Support/Debug.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/TargetRegistry.h" 26 27 #define DEBUG_TYPE "ve" 28 29 using namespace llvm; 30 31 #define GET_INSTRINFO_CTOR_DTOR 32 #include "VEGenInstrInfo.inc" 33 34 // Pin the vtable to this file. 35 void VEInstrInfo::anchor() {} 36 37 VEInstrInfo::VEInstrInfo(VESubtarget &ST) 38 : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), 39 Subtarget(ST) {} 40 41 static bool IsAliasOfSX(Register Reg) { 42 return VE::I8RegClass.contains(Reg) || VE::I16RegClass.contains(Reg) || 43 VE::I32RegClass.contains(Reg) || VE::I64RegClass.contains(Reg) || 44 VE::F32RegClass.contains(Reg); 45 } 46 47 void VEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 48 MachineBasicBlock::iterator I, const DebugLoc &DL, 49 MCRegister DestReg, MCRegister SrcReg, 50 bool KillSrc) const { 51 52 if (IsAliasOfSX(SrcReg) && IsAliasOfSX(DestReg)) { 53 BuildMI(MBB, I, DL, get(VE::ORri), DestReg) 54 .addReg(SrcReg, getKillRegState(KillSrc)) 55 .addImm(0); 56 } else { 57 const TargetRegisterInfo *TRI = &getRegisterInfo(); 58 dbgs() << "Impossible reg-to-reg copy from " << printReg(SrcReg, TRI) 59 << " to " << printReg(DestReg, TRI) << "\n"; 60 llvm_unreachable("Impossible reg-to-reg copy"); 61 } 62 } 63 64 bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 65 switch (MI.getOpcode()) { 66 case VE::EXTEND_STACK: { 67 return expandExtendStackPseudo(MI); 68 } 69 case VE::EXTEND_STACK_GUARD: { 70 MI.eraseFromParent(); // The pseudo instruction is gone now. 71 return true; 72 } 73 } 74 return false; 75 } 76 77 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 78 MachineBasicBlock &MBB = *MI.getParent(); 79 MachineFunction &MF = *MBB.getParent(); 80 const VEInstrInfo &TII = 81 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 82 DebugLoc dl = MBB.findDebugLoc(MI); 83 84 // Create following instructions and multiple basic blocks. 85 // 86 // thisBB: 87 // brge.l.t %sp, %sl, sinkBB 88 // syscallBB: 89 // ld %s61, 0x18(, %tp) // load param area 90 // or %s62, 0, %s0 // spill the value of %s0 91 // lea %s63, 0x13b // syscall # of grow 92 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 93 // shm.l %sl, 0x8(%s61) // store old limit at addr:8 94 // shm.l %sp, 0x10(%s61) // store new limit at addr:16 95 // monc // call monitor 96 // or %s0, 0, %s62 // restore the value of %s0 97 // sinkBB: 98 99 // Create new MBB 100 MachineBasicBlock *BB = &MBB; 101 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 102 MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 103 MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 104 MachineFunction::iterator It = ++(BB->getIterator()); 105 MF.insert(It, syscallMBB); 106 MF.insert(It, sinkMBB); 107 108 // Transfer the remainder of BB and its successor edges to sinkMBB. 109 sinkMBB->splice(sinkMBB->begin(), BB, 110 std::next(std::next(MachineBasicBlock::iterator(MI))), 111 BB->end()); 112 sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 113 114 // Next, add the true and fallthrough blocks as its successors. 115 BB->addSuccessor(syscallMBB); 116 BB->addSuccessor(sinkMBB); 117 BuildMI(BB, dl, TII.get(VE::BCRLrr)) 118 .addImm(VECC::CC_IGE) 119 .addReg(VE::SX11) // %sp 120 .addReg(VE::SX8) // %sl 121 .addMBB(sinkMBB); 122 123 BB = syscallMBB; 124 125 // Update machine-CFG edges 126 BB->addSuccessor(sinkMBB); 127 128 BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 129 .addReg(VE::SX14) 130 .addImm(0x18); 131 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 132 .addReg(VE::SX0) 133 .addImm(0); 134 BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 135 .addImm(0x13b); 136 BuildMI(BB, dl, TII.get(VE::SHMri)) 137 .addReg(VE::SX61) 138 .addImm(0) 139 .addReg(VE::SX63); 140 BuildMI(BB, dl, TII.get(VE::SHMri)) 141 .addReg(VE::SX61) 142 .addImm(8) 143 .addReg(VE::SX8); 144 BuildMI(BB, dl, TII.get(VE::SHMri)) 145 .addReg(VE::SX61) 146 .addImm(16) 147 .addReg(VE::SX11); 148 BuildMI(BB, dl, TII.get(VE::MONC)); 149 150 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 151 .addReg(VE::SX62) 152 .addImm(0); 153 154 MI.eraseFromParent(); // The pseudo instruction is gone now. 155 return true; 156 } 157