xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VERegisterInfo.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1480093f4SDimitry Andric //===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric //
9480093f4SDimitry Andric // This file contains the VE implementation of the TargetRegisterInfo class.
10480093f4SDimitry Andric //
11480093f4SDimitry Andric //===----------------------------------------------------------------------===//
12480093f4SDimitry Andric 
13480093f4SDimitry Andric #include "VERegisterInfo.h"
14480093f4SDimitry Andric #include "VE.h"
15480093f4SDimitry Andric #include "VESubtarget.h"
16480093f4SDimitry Andric #include "llvm/ADT/BitVector.h"
17480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h"
18480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
19480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
20480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
21480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
22480093f4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
23480093f4SDimitry Andric #include "llvm/IR/Type.h"
24480093f4SDimitry Andric #include "llvm/Support/CommandLine.h"
25480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h"
26480093f4SDimitry Andric 
27480093f4SDimitry Andric using namespace llvm;
28480093f4SDimitry Andric 
29480093f4SDimitry Andric #define GET_REGINFO_TARGET_DESC
30480093f4SDimitry Andric #include "VEGenRegisterInfo.inc"
31480093f4SDimitry Andric 
32480093f4SDimitry Andric // VE uses %s10 == %lp to keep return address
33480093f4SDimitry Andric VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
34480093f4SDimitry Andric 
35480093f4SDimitry Andric const MCPhysReg *
36480093f4SDimitry Andric VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37*5ffd83dbSDimitry Andric   switch (MF->getFunction().getCallingConv()) {
38*5ffd83dbSDimitry Andric   default:
39480093f4SDimitry Andric     return CSR_SaveList;
40*5ffd83dbSDimitry Andric   case CallingConv::PreserveAll:
41*5ffd83dbSDimitry Andric     return CSR_preserve_all_SaveList;
42*5ffd83dbSDimitry Andric   }
43480093f4SDimitry Andric }
44480093f4SDimitry Andric 
45480093f4SDimitry Andric const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
46480093f4SDimitry Andric                                                      CallingConv::ID CC) const {
47*5ffd83dbSDimitry Andric   switch (CC) {
48*5ffd83dbSDimitry Andric   default:
49480093f4SDimitry Andric     return CSR_RegMask;
50*5ffd83dbSDimitry Andric   case CallingConv::PreserveAll:
51*5ffd83dbSDimitry Andric     return CSR_preserve_all_RegMask;
52*5ffd83dbSDimitry Andric   }
53480093f4SDimitry Andric }
54480093f4SDimitry Andric 
55480093f4SDimitry Andric const uint32_t *VERegisterInfo::getNoPreservedMask() const {
56480093f4SDimitry Andric   return CSR_NoRegs_RegMask;
57480093f4SDimitry Andric }
58480093f4SDimitry Andric 
59480093f4SDimitry Andric BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
60480093f4SDimitry Andric   BitVector Reserved(getNumRegs());
61480093f4SDimitry Andric 
62*5ffd83dbSDimitry Andric   const Register ReservedRegs[] = {
63*5ffd83dbSDimitry Andric       VE::SX8,  // Stack limit
64*5ffd83dbSDimitry Andric       VE::SX9,  // Frame pointer
65*5ffd83dbSDimitry Andric       VE::SX10, // Link register (return address)
66*5ffd83dbSDimitry Andric       VE::SX11, // Stack pointer
67480093f4SDimitry Andric 
68*5ffd83dbSDimitry Andric       // FIXME: maybe not need to be reserved
69*5ffd83dbSDimitry Andric       VE::SX12, // Outer register
70*5ffd83dbSDimitry Andric       VE::SX13, // Id register for dynamic linker
71480093f4SDimitry Andric 
72*5ffd83dbSDimitry Andric       VE::SX14, // Thread pointer
73*5ffd83dbSDimitry Andric       VE::SX15, // Global offset table register
74*5ffd83dbSDimitry Andric       VE::SX16, // Procedure linkage table register
75*5ffd83dbSDimitry Andric       VE::SX17, // Linkage-area register
76480093f4SDimitry Andric                 // sx18-sx33 are callee-saved registers
77480093f4SDimitry Andric                 // sx34-sx63 are temporary registers
78*5ffd83dbSDimitry Andric   };
79*5ffd83dbSDimitry Andric 
80*5ffd83dbSDimitry Andric   for (auto R : ReservedRegs)
81*5ffd83dbSDimitry Andric     for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
82*5ffd83dbSDimitry Andric          ++ItAlias)
83*5ffd83dbSDimitry Andric       Reserved.set(*ItAlias);
84480093f4SDimitry Andric 
85480093f4SDimitry Andric   return Reserved;
86480093f4SDimitry Andric }
87480093f4SDimitry Andric 
88*5ffd83dbSDimitry Andric bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { return false; }
89480093f4SDimitry Andric 
90480093f4SDimitry Andric const TargetRegisterClass *
91480093f4SDimitry Andric VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
92480093f4SDimitry Andric                                    unsigned Kind) const {
93480093f4SDimitry Andric   return &VE::I64RegClass;
94480093f4SDimitry Andric }
95480093f4SDimitry Andric 
96480093f4SDimitry Andric static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
97480093f4SDimitry Andric                       MachineInstr &MI, const DebugLoc &dl,
98*5ffd83dbSDimitry Andric                       unsigned FIOperandNum, int Offset, Register FrameReg) {
99480093f4SDimitry Andric   // Replace frame index with a frame pointer reference directly.
100480093f4SDimitry Andric   // VE has 32 bit offset field, so no need to expand a target instruction.
101480093f4SDimitry Andric   // Directly encode it.
102*5ffd83dbSDimitry Andric   MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
103*5ffd83dbSDimitry Andric   MI.getOperand(FIOperandNum + 2).ChangeToImmediate(Offset);
104480093f4SDimitry Andric }
105480093f4SDimitry Andric 
106480093f4SDimitry Andric void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
107480093f4SDimitry Andric                                          int SPAdj, unsigned FIOperandNum,
108480093f4SDimitry Andric                                          RegScavenger *RS) const {
109480093f4SDimitry Andric   assert(SPAdj == 0 && "Unexpected");
110480093f4SDimitry Andric 
111480093f4SDimitry Andric   MachineInstr &MI = *II;
112480093f4SDimitry Andric   DebugLoc dl = MI.getDebugLoc();
113480093f4SDimitry Andric   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
114480093f4SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
115480093f4SDimitry Andric   const VEFrameLowering *TFI = getFrameLowering(MF);
116480093f4SDimitry Andric 
117*5ffd83dbSDimitry Andric   Register FrameReg;
118480093f4SDimitry Andric   int Offset;
119480093f4SDimitry Andric   Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
120480093f4SDimitry Andric 
121*5ffd83dbSDimitry Andric   Offset += MI.getOperand(FIOperandNum + 2).getImm();
122480093f4SDimitry Andric 
123480093f4SDimitry Andric   replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
124480093f4SDimitry Andric }
125480093f4SDimitry Andric 
126480093f4SDimitry Andric Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
127480093f4SDimitry Andric   return VE::SX9;
128480093f4SDimitry Andric }
129480093f4SDimitry Andric 
130480093f4SDimitry Andric // VE has no architectural need for stack realignment support,
131480093f4SDimitry Andric // except that LLVM unfortunately currently implements overaligned
132480093f4SDimitry Andric // stack objects by depending upon stack realignment support.
133480093f4SDimitry Andric // If that ever changes, this can probably be deleted.
134480093f4SDimitry Andric bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
135480093f4SDimitry Andric   if (!TargetRegisterInfo::canRealignStack(MF))
136480093f4SDimitry Andric     return false;
137480093f4SDimitry Andric 
138480093f4SDimitry Andric   // VE always has a fixed frame pointer register, so don't need to
139480093f4SDimitry Andric   // worry about needing to reserve it. [even if we don't have a frame
140480093f4SDimitry Andric   // pointer for our frame, it still cannot be used for other things,
141480093f4SDimitry Andric   // or register window traps will be SADNESS.]
142480093f4SDimitry Andric 
143480093f4SDimitry Andric   // If there's a reserved call frame, we can use VE to access locals.
144480093f4SDimitry Andric   if (getFrameLowering(MF)->hasReservedCallFrame(MF))
145480093f4SDimitry Andric     return true;
146480093f4SDimitry Andric 
147480093f4SDimitry Andric   // Otherwise, we'd need a base pointer, but those aren't implemented
148480093f4SDimitry Andric   // for VE at the moment.
149480093f4SDimitry Andric 
150480093f4SDimitry Andric   return false;
151480093f4SDimitry Andric }
152