1*480093f4SDimitry Andric //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===// 2*480093f4SDimitry Andric // 3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*480093f4SDimitry Andric // 7*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8*480093f4SDimitry Andric // 9*480093f4SDimitry Andric // This file contains the VE implementation of the TargetInstrInfo class. 10*480093f4SDimitry Andric // 11*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 12*480093f4SDimitry Andric 13*480093f4SDimitry Andric #include "VEInstrInfo.h" 14*480093f4SDimitry Andric #include "VE.h" 15*480093f4SDimitry Andric #include "VESubtarget.h" 16*480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h" 17*480093f4SDimitry Andric #include "llvm/ADT/SmallVector.h" 18*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 19*480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 20*480093f4SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 21*480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 22*480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 23*480093f4SDimitry Andric #include "llvm/Support/Debug.h" 24*480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 25*480093f4SDimitry Andric #include "llvm/Support/TargetRegistry.h" 26*480093f4SDimitry Andric 27*480093f4SDimitry Andric #define DEBUG_TYPE "ve" 28*480093f4SDimitry Andric 29*480093f4SDimitry Andric using namespace llvm; 30*480093f4SDimitry Andric 31*480093f4SDimitry Andric #define GET_INSTRINFO_CTOR_DTOR 32*480093f4SDimitry Andric #include "VEGenInstrInfo.inc" 33*480093f4SDimitry Andric 34*480093f4SDimitry Andric // Pin the vtable to this file. 35*480093f4SDimitry Andric void VEInstrInfo::anchor() {} 36*480093f4SDimitry Andric 37*480093f4SDimitry Andric VEInstrInfo::VEInstrInfo(VESubtarget &ST) 38*480093f4SDimitry Andric : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), 39*480093f4SDimitry Andric Subtarget(ST) {} 40*480093f4SDimitry Andric 41*480093f4SDimitry Andric bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 42*480093f4SDimitry Andric switch (MI.getOpcode()) { 43*480093f4SDimitry Andric case VE::EXTEND_STACK: { 44*480093f4SDimitry Andric return expandExtendStackPseudo(MI); 45*480093f4SDimitry Andric } 46*480093f4SDimitry Andric case VE::EXTEND_STACK_GUARD: { 47*480093f4SDimitry Andric MI.eraseFromParent(); // The pseudo instruction is gone now. 48*480093f4SDimitry Andric return true; 49*480093f4SDimitry Andric } 50*480093f4SDimitry Andric } 51*480093f4SDimitry Andric return false; 52*480093f4SDimitry Andric } 53*480093f4SDimitry Andric 54*480093f4SDimitry Andric bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 55*480093f4SDimitry Andric MachineBasicBlock &MBB = *MI.getParent(); 56*480093f4SDimitry Andric MachineFunction &MF = *MBB.getParent(); 57*480093f4SDimitry Andric const VEInstrInfo &TII = 58*480093f4SDimitry Andric *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 59*480093f4SDimitry Andric DebugLoc dl = MBB.findDebugLoc(MI); 60*480093f4SDimitry Andric 61*480093f4SDimitry Andric // Create following instructions and multiple basic blocks. 62*480093f4SDimitry Andric // 63*480093f4SDimitry Andric // thisBB: 64*480093f4SDimitry Andric // brge.l.t %sp, %sl, sinkBB 65*480093f4SDimitry Andric // syscallBB: 66*480093f4SDimitry Andric // ld %s61, 0x18(, %tp) // load param area 67*480093f4SDimitry Andric // or %s62, 0, %s0 // spill the value of %s0 68*480093f4SDimitry Andric // lea %s63, 0x13b // syscall # of grow 69*480093f4SDimitry Andric // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 70*480093f4SDimitry Andric // shm.l %sl, 0x8(%s61) // store old limit at addr:8 71*480093f4SDimitry Andric // shm.l %sp, 0x10(%s61) // store new limit at addr:16 72*480093f4SDimitry Andric // monc // call monitor 73*480093f4SDimitry Andric // or %s0, 0, %s62 // restore the value of %s0 74*480093f4SDimitry Andric // sinkBB: 75*480093f4SDimitry Andric 76*480093f4SDimitry Andric // Create new MBB 77*480093f4SDimitry Andric MachineBasicBlock *BB = &MBB; 78*480093f4SDimitry Andric const BasicBlock *LLVM_BB = BB->getBasicBlock(); 79*480093f4SDimitry Andric MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 80*480093f4SDimitry Andric MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 81*480093f4SDimitry Andric MachineFunction::iterator It = ++(BB->getIterator()); 82*480093f4SDimitry Andric MF.insert(It, syscallMBB); 83*480093f4SDimitry Andric MF.insert(It, sinkMBB); 84*480093f4SDimitry Andric 85*480093f4SDimitry Andric // Transfer the remainder of BB and its successor edges to sinkMBB. 86*480093f4SDimitry Andric sinkMBB->splice(sinkMBB->begin(), BB, 87*480093f4SDimitry Andric std::next(std::next(MachineBasicBlock::iterator(MI))), 88*480093f4SDimitry Andric BB->end()); 89*480093f4SDimitry Andric sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 90*480093f4SDimitry Andric 91*480093f4SDimitry Andric // Next, add the true and fallthrough blocks as its successors. 92*480093f4SDimitry Andric BB->addSuccessor(syscallMBB); 93*480093f4SDimitry Andric BB->addSuccessor(sinkMBB); 94*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::BCRLrr)) 95*480093f4SDimitry Andric .addImm(VECC::CC_IGE) 96*480093f4SDimitry Andric .addReg(VE::SX11) // %sp 97*480093f4SDimitry Andric .addReg(VE::SX8) // %sl 98*480093f4SDimitry Andric .addMBB(sinkMBB); 99*480093f4SDimitry Andric 100*480093f4SDimitry Andric BB = syscallMBB; 101*480093f4SDimitry Andric 102*480093f4SDimitry Andric // Update machine-CFG edges 103*480093f4SDimitry Andric BB->addSuccessor(sinkMBB); 104*480093f4SDimitry Andric 105*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 106*480093f4SDimitry Andric .addReg(VE::SX14) 107*480093f4SDimitry Andric .addImm(0x18); 108*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 109*480093f4SDimitry Andric .addReg(VE::SX0) 110*480093f4SDimitry Andric .addImm(0); 111*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 112*480093f4SDimitry Andric .addImm(0x13b); 113*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::SHMri)) 114*480093f4SDimitry Andric .addReg(VE::SX61) 115*480093f4SDimitry Andric .addImm(0) 116*480093f4SDimitry Andric .addReg(VE::SX63); 117*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::SHMri)) 118*480093f4SDimitry Andric .addReg(VE::SX61) 119*480093f4SDimitry Andric .addImm(8) 120*480093f4SDimitry Andric .addReg(VE::SX8); 121*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::SHMri)) 122*480093f4SDimitry Andric .addReg(VE::SX61) 123*480093f4SDimitry Andric .addImm(16) 124*480093f4SDimitry Andric .addReg(VE::SX11); 125*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::MONC)); 126*480093f4SDimitry Andric 127*480093f4SDimitry Andric BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 128*480093f4SDimitry Andric .addReg(VE::SX62) 129*480093f4SDimitry Andric .addImm(0); 130*480093f4SDimitry Andric 131*480093f4SDimitry Andric MI.eraseFromParent(); // The pseudo instruction is gone now. 132*480093f4SDimitry Andric return true; 133*480093f4SDimitry Andric } 134