xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VERegisterInfo.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
1*480093f4SDimitry Andric //===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
2*480093f4SDimitry Andric //
3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*480093f4SDimitry Andric //
7*480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8*480093f4SDimitry Andric //
9*480093f4SDimitry Andric // This file contains the VE implementation of the TargetRegisterInfo class.
10*480093f4SDimitry Andric //
11*480093f4SDimitry Andric //===----------------------------------------------------------------------===//
12*480093f4SDimitry Andric 
13*480093f4SDimitry Andric #include "VERegisterInfo.h"
14*480093f4SDimitry Andric #include "VE.h"
15*480093f4SDimitry Andric #include "VESubtarget.h"
16*480093f4SDimitry Andric #include "llvm/ADT/BitVector.h"
17*480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h"
18*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
19*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
20*480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
21*480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
22*480093f4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
23*480093f4SDimitry Andric #include "llvm/IR/Type.h"
24*480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
25*480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h"
26*480093f4SDimitry Andric 
27*480093f4SDimitry Andric using namespace llvm;
28*480093f4SDimitry Andric 
29*480093f4SDimitry Andric #define GET_REGINFO_TARGET_DESC
30*480093f4SDimitry Andric #include "VEGenRegisterInfo.inc"
31*480093f4SDimitry Andric 
32*480093f4SDimitry Andric // VE uses %s10 == %lp to keep return address
33*480093f4SDimitry Andric VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
34*480093f4SDimitry Andric 
35*480093f4SDimitry Andric const MCPhysReg *
36*480093f4SDimitry Andric VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37*480093f4SDimitry Andric   return CSR_SaveList;
38*480093f4SDimitry Andric }
39*480093f4SDimitry Andric 
40*480093f4SDimitry Andric const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
41*480093f4SDimitry Andric                                                      CallingConv::ID CC) const {
42*480093f4SDimitry Andric   return CSR_RegMask;
43*480093f4SDimitry Andric }
44*480093f4SDimitry Andric 
45*480093f4SDimitry Andric const uint32_t *VERegisterInfo::getNoPreservedMask() const {
46*480093f4SDimitry Andric   return CSR_NoRegs_RegMask;
47*480093f4SDimitry Andric }
48*480093f4SDimitry Andric 
49*480093f4SDimitry Andric BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
50*480093f4SDimitry Andric   BitVector Reserved(getNumRegs());
51*480093f4SDimitry Andric   Reserved.set(VE::SX8);  // stack limit
52*480093f4SDimitry Andric   Reserved.set(VE::SX9);  // frame pointer
53*480093f4SDimitry Andric   Reserved.set(VE::SX10); // link register (return address)
54*480093f4SDimitry Andric   Reserved.set(VE::SX11); // stack pointer
55*480093f4SDimitry Andric 
56*480093f4SDimitry Andric   Reserved.set(VE::SX12); // outer register
57*480093f4SDimitry Andric   Reserved.set(VE::SX13); // id register for dynamic linker
58*480093f4SDimitry Andric 
59*480093f4SDimitry Andric   Reserved.set(VE::SX14); // thread pointer
60*480093f4SDimitry Andric   Reserved.set(VE::SX15); // global offset table register
61*480093f4SDimitry Andric   Reserved.set(VE::SX16); // procedure linkage table register
62*480093f4SDimitry Andric   Reserved.set(VE::SX17); // linkage-area register
63*480093f4SDimitry Andric 
64*480093f4SDimitry Andric   // sx18-sx33 are callee-saved registers
65*480093f4SDimitry Andric   // sx34-sx63 are temporary registers
66*480093f4SDimitry Andric 
67*480093f4SDimitry Andric   return Reserved;
68*480093f4SDimitry Andric }
69*480093f4SDimitry Andric 
70*480093f4SDimitry Andric bool VERegisterInfo::isConstantPhysReg(unsigned PhysReg) const { return false; }
71*480093f4SDimitry Andric 
72*480093f4SDimitry Andric const TargetRegisterClass *
73*480093f4SDimitry Andric VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
74*480093f4SDimitry Andric                                    unsigned Kind) const {
75*480093f4SDimitry Andric   return &VE::I64RegClass;
76*480093f4SDimitry Andric }
77*480093f4SDimitry Andric 
78*480093f4SDimitry Andric static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
79*480093f4SDimitry Andric                       MachineInstr &MI, const DebugLoc &dl,
80*480093f4SDimitry Andric                       unsigned FIOperandNum, int Offset, unsigned FramePtr) {
81*480093f4SDimitry Andric   // Replace frame index with a frame pointer reference directly.
82*480093f4SDimitry Andric   // VE has 32 bit offset field, so no need to expand a target instruction.
83*480093f4SDimitry Andric   // Directly encode it.
84*480093f4SDimitry Andric   MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
85*480093f4SDimitry Andric   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
86*480093f4SDimitry Andric }
87*480093f4SDimitry Andric 
88*480093f4SDimitry Andric void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
89*480093f4SDimitry Andric                                          int SPAdj, unsigned FIOperandNum,
90*480093f4SDimitry Andric                                          RegScavenger *RS) const {
91*480093f4SDimitry Andric   assert(SPAdj == 0 && "Unexpected");
92*480093f4SDimitry Andric 
93*480093f4SDimitry Andric   MachineInstr &MI = *II;
94*480093f4SDimitry Andric   DebugLoc dl = MI.getDebugLoc();
95*480093f4SDimitry Andric   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
96*480093f4SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
97*480093f4SDimitry Andric   const VEFrameLowering *TFI = getFrameLowering(MF);
98*480093f4SDimitry Andric 
99*480093f4SDimitry Andric   unsigned FrameReg;
100*480093f4SDimitry Andric   int Offset;
101*480093f4SDimitry Andric   Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
102*480093f4SDimitry Andric 
103*480093f4SDimitry Andric   Offset += MI.getOperand(FIOperandNum + 1).getImm();
104*480093f4SDimitry Andric 
105*480093f4SDimitry Andric   replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
106*480093f4SDimitry Andric }
107*480093f4SDimitry Andric 
108*480093f4SDimitry Andric Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
109*480093f4SDimitry Andric   return VE::SX9;
110*480093f4SDimitry Andric }
111*480093f4SDimitry Andric 
112*480093f4SDimitry Andric // VE has no architectural need for stack realignment support,
113*480093f4SDimitry Andric // except that LLVM unfortunately currently implements overaligned
114*480093f4SDimitry Andric // stack objects by depending upon stack realignment support.
115*480093f4SDimitry Andric // If that ever changes, this can probably be deleted.
116*480093f4SDimitry Andric bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
117*480093f4SDimitry Andric   if (!TargetRegisterInfo::canRealignStack(MF))
118*480093f4SDimitry Andric     return false;
119*480093f4SDimitry Andric 
120*480093f4SDimitry Andric   // VE always has a fixed frame pointer register, so don't need to
121*480093f4SDimitry Andric   // worry about needing to reserve it. [even if we don't have a frame
122*480093f4SDimitry Andric   // pointer for our frame, it still cannot be used for other things,
123*480093f4SDimitry Andric   // or register window traps will be SADNESS.]
124*480093f4SDimitry Andric 
125*480093f4SDimitry Andric   // If there's a reserved call frame, we can use VE to access locals.
126*480093f4SDimitry Andric   if (getFrameLowering(MF)->hasReservedCallFrame(MF))
127*480093f4SDimitry Andric     return true;
128*480093f4SDimitry Andric 
129*480093f4SDimitry Andric   // Otherwise, we'd need a base pointer, but those aren't implemented
130*480093f4SDimitry Andric   // for VE at the moment.
131*480093f4SDimitry Andric 
132*480093f4SDimitry Andric   return false;
133*480093f4SDimitry Andric }
134