1 //===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the VE implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "VEInstrInfo.h"
15 #include "VESubtarget.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineMemOperand.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/TargetRegistry.h"
27 #define DEBUG_TYPE "ve"
31 #define GET_INSTRINFO_CTOR_DTOR
32 #include "VEGenInstrInfo.inc"
34 // Pin the vtable to this file.
35 void VEInstrInfo::anchor() {}
37 VEInstrInfo::VEInstrInfo(VESubtarget &ST)
38 : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(),
41 bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
42 switch (MI.getOpcode()) {
43 case VE::EXTEND_STACK: {
44 return expandExtendStackPseudo(MI);
46 case VE::EXTEND_STACK_GUARD: {
47 MI.eraseFromParent(); // The pseudo instruction is gone now.
54 bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
55 MachineBasicBlock &MBB = *MI.getParent();
56 MachineFunction &MF = *MBB.getParent();
57 const VEInstrInfo &TII =
58 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
59 DebugLoc dl = MBB.findDebugLoc(MI);
61 // Create following instructions and multiple basic blocks.
64 // brge.l.t %sp, %sl, sinkBB
66 // ld %s61, 0x18(, %tp) // load param area
67 // or %s62, 0, %s0 // spill the value of %s0
68 // lea %s63, 0x13b // syscall # of grow
69 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0
70 // shm.l %sl, 0x8(%s61) // store old limit at addr:8
71 // shm.l %sp, 0x10(%s61) // store new limit at addr:16
72 // monc // call monitor
73 // or %s0, 0, %s62 // restore the value of %s0
77 MachineBasicBlock *BB = &MBB;
78 const BasicBlock *LLVM_BB = BB->getBasicBlock();
79 MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
80 MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
81 MachineFunction::iterator It = ++(BB->getIterator());
82 MF.insert(It, syscallMBB);
83 MF.insert(It, sinkMBB);
85 // Transfer the remainder of BB and its successor edges to sinkMBB.
86 sinkMBB->splice(sinkMBB->begin(), BB,
87 std::next(std::next(MachineBasicBlock::iterator(MI))),
89 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
91 // Next, add the true and fallthrough blocks as its successors.
92 BB->addSuccessor(syscallMBB);
93 BB->addSuccessor(sinkMBB);
94 BuildMI(BB, dl, TII.get(VE::BCRLrr))
96 .addReg(VE::SX11) // %sp
97 .addReg(VE::SX8) // %sl
102 // Update machine-CFG edges
103 BB->addSuccessor(sinkMBB);
105 BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61)
108 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
111 BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63)
113 BuildMI(BB, dl, TII.get(VE::SHMri))
117 BuildMI(BB, dl, TII.get(VE::SHMri))
121 BuildMI(BB, dl, TII.get(VE::SHMri))
125 BuildMI(BB, dl, TII.get(VE::MONC));
127 BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
131 MI.eraseFromParent(); // The pseudo instruction is gone now.