| //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file contains the VE implementation of the TargetInstrInfo class. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "VEInstrInfo.h" | |
| #include "VE.h" | |
| #include "VESubtarget.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/ADT/SmallVector.h" | |
| #include "llvm/CodeGen/MachineFrameInfo.h" | |
| #include "llvm/CodeGen/MachineInstrBuilder.h" | |
| #include "llvm/CodeGen/MachineMemOperand.h" | |
| #include "llvm/CodeGen/MachineRegisterInfo.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #include "llvm/Support/Debug.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| #include "llvm/Support/TargetRegistry.h" | |
| #define DEBUG_TYPE "ve" | |
| using namespace llvm; | |
| #define GET_INSTRINFO_CTOR_DTOR | |
| #include "VEGenInstrInfo.inc" | |
| // Pin the vtable to this file. | |
| void VEInstrInfo::anchor() {} | |
| VEInstrInfo::VEInstrInfo(VESubtarget &ST) | |
| : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(), | |
| Subtarget(ST) {} | |
| bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { | |
| switch (MI.getOpcode()) { | |
| case VE::EXTEND_STACK: { | |
| return expandExtendStackPseudo(MI); | |
| } | |
| case VE::EXTEND_STACK_GUARD: { | |
| MI.eraseFromParent(); // The pseudo instruction is gone now. | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const { | |
| MachineBasicBlock &MBB = *MI.getParent(); | |
| MachineFunction &MF = *MBB.getParent(); | |
| const VEInstrInfo &TII = | |
| *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); | |
| DebugLoc dl = MBB.findDebugLoc(MI); | |
| // Create following instructions and multiple basic blocks. | |
| // | |
| // thisBB: | |
| // brge.l.t %sp, %sl, sinkBB | |
| // syscallBB: | |
| // ld %s61, 0x18(, %tp) // load param area | |
| // or %s62, 0, %s0 // spill the value of %s0 | |
| // lea %s63, 0x13b // syscall # of grow | |
| // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 | |
| // shm.l %sl, 0x8(%s61) // store old limit at addr:8 | |
| // shm.l %sp, 0x10(%s61) // store new limit at addr:16 | |
| // monc // call monitor | |
| // or %s0, 0, %s62 // restore the value of %s0 | |
| // sinkBB: | |
| // Create new MBB | |
| MachineBasicBlock *BB = &MBB; | |
| const BasicBlock *LLVM_BB = BB->getBasicBlock(); | |
| MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB); | |
| MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB); | |
| MachineFunction::iterator It = ++(BB->getIterator()); | |
| MF.insert(It, syscallMBB); | |
| MF.insert(It, sinkMBB); | |
| // Transfer the remainder of BB and its successor edges to sinkMBB. | |
| sinkMBB->splice(sinkMBB->begin(), BB, | |
| std::next(std::next(MachineBasicBlock::iterator(MI))), | |
| BB->end()); | |
| sinkMBB->transferSuccessorsAndUpdatePHIs(BB); | |
| // Next, add the true and fallthrough blocks as its successors. | |
| BB->addSuccessor(syscallMBB); | |
| BB->addSuccessor(sinkMBB); | |
| BuildMI(BB, dl, TII.get(VE::BCRLrr)) | |
| .addImm(VECC::CC_IGE) | |
| .addReg(VE::SX11) // %sp | |
| .addReg(VE::SX8) // %sl | |
| .addMBB(sinkMBB); | |
| BB = syscallMBB; | |
| // Update machine-CFG edges | |
| BB->addSuccessor(sinkMBB); | |
| BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61) | |
| .addReg(VE::SX14) | |
| .addImm(0x18); | |
| BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62) | |
| .addReg(VE::SX0) | |
| .addImm(0); | |
| BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63) | |
| .addImm(0x13b); | |
| BuildMI(BB, dl, TII.get(VE::SHMri)) | |
| .addReg(VE::SX61) | |
| .addImm(0) | |
| .addReg(VE::SX63); | |
| BuildMI(BB, dl, TII.get(VE::SHMri)) | |
| .addReg(VE::SX61) | |
| .addImm(8) | |
| .addReg(VE::SX8); | |
| BuildMI(BB, dl, TII.get(VE::SHMri)) | |
| .addReg(VE::SX61) | |
| .addImm(16) | |
| .addReg(VE::SX11); | |
| BuildMI(BB, dl, TII.get(VE::MONC)); | |
| BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0) | |
| .addReg(VE::SX62) | |
| .addImm(0); | |
| MI.eraseFromParent(); // The pseudo instruction is gone now. | |
| return true; | |
| } |