1 //===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the VE implementation of the TargetRegisterInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "VERegisterInfo.h"
14 #include "VE.h"
15 #include "VESubtarget.h"
16 #include "llvm/ADT/BitVector.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/CodeGen/TargetInstrInfo.h"
23 #include "llvm/IR/Type.h"
24 #include "llvm/Support/CommandLine.h"
25 #include "llvm/Support/ErrorHandling.h"
26 
27 using namespace llvm;
28 
29 #define GET_REGINFO_TARGET_DESC
30 #include "VEGenRegisterInfo.inc"
31 
32 // VE uses %s10 == %lp to keep return address
33 VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
34 
35 const MCPhysReg *
36 VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37   switch (MF->getFunction().getCallingConv()) {
38   default:
39     return CSR_SaveList;
40   case CallingConv::PreserveAll:
41     return CSR_preserve_all_SaveList;
42   }
43 }
44 
45 const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
46                                                      CallingConv::ID CC) const {
47   switch (CC) {
48   default:
49     return CSR_RegMask;
50   case CallingConv::PreserveAll:
51     return CSR_preserve_all_RegMask;
52   }
53 }
54 
55 const uint32_t *VERegisterInfo::getNoPreservedMask() const {
56   return CSR_NoRegs_RegMask;
57 }
58 
59 BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
60   BitVector Reserved(getNumRegs());
61 
62   const Register ReservedRegs[] = {
63       VE::SX8,  // Stack limit
64       VE::SX9,  // Frame pointer
65       VE::SX10, // Link register (return address)
66       VE::SX11, // Stack pointer
67 
68       // FIXME: maybe not need to be reserved
69       VE::SX12, // Outer register
70       VE::SX13, // Id register for dynamic linker
71 
72       VE::SX14, // Thread pointer
73       VE::SX15, // Global offset table register
74       VE::SX16, // Procedure linkage table register
75       VE::SX17, // Linkage-area register
76                 // sx18-sx33 are callee-saved registers
77                 // sx34-sx63 are temporary registers
78   };
79 
80   for (auto R : ReservedRegs)
81     for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
82          ++ItAlias)
83       Reserved.set(*ItAlias);
84 
85   return Reserved;
86 }
87 
88 bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { return false; }
89 
90 const TargetRegisterClass *
91 VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
92                                    unsigned Kind) const {
93   return &VE::I64RegClass;
94 }
95 
96 static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
97                       MachineInstr &MI, const DebugLoc &dl,
98                       unsigned FIOperandNum, int Offset, Register FrameReg) {
99   // Replace frame index with a frame pointer reference directly.
100   // VE has 32 bit offset field, so no need to expand a target instruction.
101   // Directly encode it.
102   MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
103   MI.getOperand(FIOperandNum + 2).ChangeToImmediate(Offset);
104 }
105 
106 void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
107                                          int SPAdj, unsigned FIOperandNum,
108                                          RegScavenger *RS) const {
109   assert(SPAdj == 0 && "Unexpected");
110 
111   MachineInstr &MI = *II;
112   DebugLoc dl = MI.getDebugLoc();
113   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
114   MachineFunction &MF = *MI.getParent()->getParent();
115   const VEFrameLowering *TFI = getFrameLowering(MF);
116 
117   Register FrameReg;
118   int Offset;
119   Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
120 
121   Offset += MI.getOperand(FIOperandNum + 2).getImm();
122 
123   if (MI.getOpcode() == VE::STQrii) {
124     const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
125     Register SrcReg = MI.getOperand(3).getReg();
126     Register SrcHiReg = getSubReg(SrcReg, VE::sub_even);
127     Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd);
128     // VE stores HiReg to 8(addr) and LoReg to 0(addr)
129     MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(VE::STrii))
130                              .addReg(FrameReg)
131                              .addImm(0)
132                              .addImm(0)
133                              .addReg(SrcLoReg);
134     replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg);
135     MI.setDesc(TII.get(VE::STrii));
136     MI.getOperand(3).setReg(SrcHiReg);
137     Offset += 8;
138   } else if (MI.getOpcode() == VE::LDQrii) {
139     const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
140     Register DestReg = MI.getOperand(0).getReg();
141     Register DestHiReg = getSubReg(DestReg, VE::sub_even);
142     Register DestLoReg = getSubReg(DestReg, VE::sub_odd);
143     // VE loads HiReg from 8(addr) and LoReg from 0(addr)
144     MachineInstr *StMI =
145         BuildMI(*MI.getParent(), II, dl, TII.get(VE::LDrii), DestLoReg)
146             .addReg(FrameReg)
147             .addImm(0)
148             .addImm(0);
149     replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg);
150     MI.setDesc(TII.get(VE::LDrii));
151     MI.getOperand(0).setReg(DestHiReg);
152     Offset += 8;
153   }
154 
155   replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
156 }
157 
158 Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
159   return VE::SX9;
160 }
161 
162 // VE has no architectural need for stack realignment support,
163 // except that LLVM unfortunately currently implements overaligned
164 // stack objects by depending upon stack realignment support.
165 // If that ever changes, this can probably be deleted.
166 bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
167   if (!TargetRegisterInfo::canRealignStack(MF))
168     return false;
169 
170   // VE always has a fixed frame pointer register, so don't need to
171   // worry about needing to reserve it. [even if we don't have a frame
172   // pointer for our frame, it still cannot be used for other things,
173   // or register window traps will be SADNESS.]
174 
175   // If there's a reserved call frame, we can use VE to access locals.
176   if (getFrameLowering(MF)->hasReservedCallFrame(MF))
177     return true;
178 
179   // Otherwise, we'd need a base pointer, but those aren't implemented
180   // for VE at the moment.
181 
182   return false;
183 }
184