diff options
Diffstat (limited to 'llvm/lib/Target/VE/VEInstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/VE/VEInstrInfo.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/llvm/lib/Target/VE/VEInstrInfo.cpp b/llvm/lib/Target/VE/VEInstrInfo.cpp new file mode 100644 index 000000000000..bc382dcef7c3 --- /dev/null +++ b/llvm/lib/Target/VE/VEInstrInfo.cpp @@ -0,0 +1,133 @@ +//===-- 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; +} |