summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/VE/VEInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/VE/VEInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/VE/VEInstrInfo.cpp133
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;
+}