1356843Sdim//===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===// 2356843Sdim// 3356843Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4356843Sdim// See https://llvm.org/LICENSE.txt for license information. 5356843Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6356843Sdim// 7356843Sdim//===----------------------------------------------------------------------===// 8356843Sdim// 9356843Sdim// This file contains the VE implementation of the TargetInstrInfo class. 10356843Sdim// 11356843Sdim//===----------------------------------------------------------------------===// 12356843Sdim 13356843Sdim#include "VEInstrInfo.h" 14356843Sdim#include "VE.h" 15356843Sdim#include "VESubtarget.h" 16356843Sdim#include "llvm/ADT/STLExtras.h" 17356843Sdim#include "llvm/ADT/SmallVector.h" 18356843Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 19356843Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 20356843Sdim#include "llvm/CodeGen/MachineMemOperand.h" 21356843Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 22356843Sdim#include "llvm/Support/CommandLine.h" 23356843Sdim#include "llvm/Support/Debug.h" 24356843Sdim#include "llvm/Support/ErrorHandling.h" 25356843Sdim#include "llvm/Support/TargetRegistry.h" 26356843Sdim 27356843Sdim#define DEBUG_TYPE "ve" 28356843Sdim 29356843Sdimusing namespace llvm; 30356843Sdim 31356843Sdim#define GET_INSTRINFO_CTOR_DTOR 32356843Sdim#include "VEGenInstrInfo.inc" 33356843Sdim 34356843Sdim// Pin the vtable to this file. 35356843Sdimvoid VEInstrInfo::anchor() {} 36356843Sdim 37356843SdimVEInstrInfo::VEInstrInfo(VESubtarget &ST) 38356843Sdim : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), 39356843Sdim Subtarget(ST) {} 40356843Sdim 41356843Sdimbool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 42356843Sdim switch (MI.getOpcode()) { 43356843Sdim case VE::EXTEND_STACK: { 44356843Sdim return expandExtendStackPseudo(MI); 45356843Sdim } 46356843Sdim case VE::EXTEND_STACK_GUARD: { 47356843Sdim MI.eraseFromParent(); // The pseudo instruction is gone now. 48356843Sdim return true; 49356843Sdim } 50356843Sdim } 51356843Sdim return false; 52356843Sdim} 53356843Sdim 54356843Sdimbool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { 55356843Sdim MachineBasicBlock &MBB = *MI.getParent(); 56356843Sdim MachineFunction &MF = *MBB.getParent(); 57356843Sdim const VEInstrInfo &TII = 58356843Sdim *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 59356843Sdim DebugLoc dl = MBB.findDebugLoc(MI); 60356843Sdim 61356843Sdim // Create following instructions and multiple basic blocks. 62356843Sdim // 63356843Sdim // thisBB: 64356843Sdim // brge.l.t %sp, %sl, sinkBB 65356843Sdim // syscallBB: 66356843Sdim // ld %s61, 0x18(, %tp) // load param area 67356843Sdim // or %s62, 0, %s0 // spill the value of %s0 68356843Sdim // lea %s63, 0x13b // syscall # of grow 69356843Sdim // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 70356843Sdim // shm.l %sl, 0x8(%s61) // store old limit at addr:8 71356843Sdim // shm.l %sp, 0x10(%s61) // store new limit at addr:16 72356843Sdim // monc // call monitor 73356843Sdim // or %s0, 0, %s62 // restore the value of %s0 74356843Sdim // sinkBB: 75356843Sdim 76356843Sdim // Create new MBB 77356843Sdim MachineBasicBlock *BB = &MBB; 78356843Sdim const BasicBlock *LLVM_BB = BB->getBasicBlock(); 79356843Sdim MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); 80356843Sdim MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); 81356843Sdim MachineFunction::iterator It = ++(BB->getIterator()); 82356843Sdim MF.insert(It, syscallMBB); 83356843Sdim MF.insert(It, sinkMBB); 84356843Sdim 85356843Sdim // Transfer the remainder of BB and its successor edges to sinkMBB. 86356843Sdim sinkMBB->splice(sinkMBB->begin(), BB, 87356843Sdim std::next(std::next(MachineBasicBlock::iterator(MI))), 88356843Sdim BB->end()); 89356843Sdim sinkMBB->transferSuccessorsAndUpdatePHIs(BB); 90356843Sdim 91356843Sdim // Next, add the true and fallthrough blocks as its successors. 92356843Sdim BB->addSuccessor(syscallMBB); 93356843Sdim BB->addSuccessor(sinkMBB); 94356843Sdim BuildMI(BB, dl, TII.get(VE::BCRLrr)) 95356843Sdim .addImm(VECC::CC_IGE) 96356843Sdim .addReg(VE::SX11) // %sp 97356843Sdim .addReg(VE::SX8) // %sl 98356843Sdim .addMBB(sinkMBB); 99356843Sdim 100356843Sdim BB = syscallMBB; 101356843Sdim 102356843Sdim // Update machine-CFG edges 103356843Sdim BB->addSuccessor(sinkMBB); 104356843Sdim 105356843Sdim BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) 106356843Sdim .addReg(VE::SX14) 107356843Sdim .addImm(0x18); 108356843Sdim BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) 109356843Sdim .addReg(VE::SX0) 110356843Sdim .addImm(0); 111356843Sdim BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) 112356843Sdim .addImm(0x13b); 113356843Sdim BuildMI(BB, dl, TII.get(VE::SHMri)) 114356843Sdim .addReg(VE::SX61) 115356843Sdim .addImm(0) 116356843Sdim .addReg(VE::SX63); 117356843Sdim BuildMI(BB, dl, TII.get(VE::SHMri)) 118356843Sdim .addReg(VE::SX61) 119356843Sdim .addImm(8) 120356843Sdim .addReg(VE::SX8); 121356843Sdim BuildMI(BB, dl, TII.get(VE::SHMri)) 122356843Sdim .addReg(VE::SX61) 123356843Sdim .addImm(16) 124356843Sdim .addReg(VE::SX11); 125356843Sdim BuildMI(BB, dl, TII.get(VE::MONC)); 126356843Sdim 127356843Sdim BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) 128356843Sdim .addReg(VE::SX62) 129356843Sdim .addImm(0); 130356843Sdim 131356843Sdim MI.eraseFromParent(); // The pseudo instruction is gone now. 132356843Sdim return true; 133356843Sdim} 134