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/Debug.h"
26 #include "llvm/Support/ErrorHandling.h"
27
28 using namespace llvm;
29
30 #define GET_REGINFO_TARGET_DESC
31 #include "VEGenRegisterInfo.inc"
32
33 // VE uses %s10 == %lp to keep return address
34 VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
35
36 const MCPhysReg *
37 VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
38 switch (MF->getFunction().getCallingConv()) {
39 case CallingConv::Fast:
40 // Being explicit (same as standard CC).
41 default:
42 return CSR_SaveList;
43 case CallingConv::PreserveAll:
44 return CSR_preserve_all_SaveList;
isValidVersion(v, fully_qualified=False)45 }
46 }
47
48 const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
49 CallingConv::ID CC) const {
50 switch (CC) {
51 case CallingConv::Fast:
52 // Being explicit (same as standard CC).
53 default:
54 return CSR_RegMask;
55 case CallingConv::PreserveAll:
56 return CSR_preserve_all_RegMask;
57 }
58 }
59
60 const uint32_t *VERegisterInfo::getNoPreservedMask() const {
61 return CSR_NoRegs_RegMask;
normalizeVersion(v)62 }
63
64 BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
65 BitVector Reserved(getNumRegs());
66
67 const Register ReservedRegs[] = {
68 VE::SX8, // Stack limit
69 VE::SX9, // Frame pointer
70 VE::SX10, // Link register (return address)
71 VE::SX11, // Stack pointer
72
73 // FIXME: maybe not need to be reserved
74 VE::SX12, // Outer register
75 VE::SX13, // Id register for dynamic linker
76
77 VE::SX14, // Thread pointer
78 VE::SX15, // Global offset table register
79 VE::SX16, // Procedure linkage table register
80 VE::SX17, // Linkage-area register
81 // sx18-sx33 are callee-saved registers
82 // sx34-sx63 are temporary registers
83 };
84
85 for (auto R : ReservedRegs)
86 for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
87 ++ItAlias)
88 Reserved.set(*ItAlias);
89
90 // Reserve constant registers.
91 Reserved.set(VE::VM0);
92 Reserved.set(VE::VMP0);
93
94 return Reserved;
95 }
96
97 bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
98 switch (PhysReg) {
99 case VE::VM0:
100 case VE::VMP0:
101 return true;
102 default:
103 return false;
104 }
105 }
106
107 const TargetRegisterClass *
108 VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
109 unsigned Kind) const {
110 return &VE::I64RegClass;
111 }
112
113 static unsigned offsetToDisp(MachineInstr &MI) {
114 // Default offset in instruction's operands (reg+reg+imm).
115 unsigned OffDisp = 2;
116
117 #define RRCAS_multi_cases(NAME) NAME##rir : case NAME##rii
118
119 {
120 using namespace llvm::VE;
121 switch (MI.getOpcode()) {
122 case RRCAS_multi_cases(TS1AML):
123 case RRCAS_multi_cases(TS1AMW):
124 case RRCAS_multi_cases(CASL):
125 case RRCAS_multi_cases(CASW):
126 // These instructions use AS format (reg+imm).
127 OffDisp = 1;
128 break;
129 }
130 }
131 #undef RRCAS_multi_cases
132
133 return OffDisp;
134 }
135
136 static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
137 MachineInstr &MI, const DebugLoc &dl,
138 unsigned FIOperandNum, int Offset, Register FrameReg) {
139 // Replace frame index with a frame pointer reference directly.
140 // VE has 32 bit offset field, so no need to expand a target instruction.
141 // Directly encode it.
142 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
143 MI.getOperand(FIOperandNum + offsetToDisp(MI)).ChangeToImmediate(Offset);
144 }
145
146 void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
147 int SPAdj, unsigned FIOperandNum,
148 RegScavenger *RS) const {
149 assert(SPAdj == 0 && "Unexpected");
150
151 MachineInstr &MI = *II;
152 DebugLoc dl = MI.getDebugLoc();
153 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
154 MachineFunction &MF = *MI.getParent()->getParent();
155 const VEFrameLowering *TFI = getFrameLowering(MF);
156
157 Register FrameReg;
158 int Offset;
159 Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed();
160
161 Offset += MI.getOperand(FIOperandNum + offsetToDisp(MI)).getImm();
162
163 if (MI.getOpcode() == VE::STQrii) {
164 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
165 Register SrcReg = MI.getOperand(3).getReg();
166 Register SrcHiReg = getSubReg(SrcReg, VE::sub_even);
167 Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd);
168 // VE stores HiReg to 8(addr) and LoReg to 0(addr)
169 MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(VE::STrii))
170 .addReg(FrameReg)
171 .addImm(0)
172 .addImm(0)
173 .addReg(SrcLoReg);
174 replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg);
175 MI.setDesc(TII.get(VE::STrii));
176 MI.getOperand(3).setReg(SrcHiReg);
177 Offset += 8;
178 } else if (MI.getOpcode() == VE::LDQrii) {
179 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
180 Register DestReg = MI.getOperand(0).getReg();
181 Register DestHiReg = getSubReg(DestReg, VE::sub_even);
182 Register DestLoReg = getSubReg(DestReg, VE::sub_odd);
183 // VE loads HiReg from 8(addr) and LoReg from 0(addr)
184 MachineInstr *StMI =
185 BuildMI(*MI.getParent(), II, dl, TII.get(VE::LDrii), DestLoReg)
186 .addReg(FrameReg)
187 .addImm(0)
188 .addImm(0);
189 replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg);
190 MI.setDesc(TII.get(VE::LDrii));
191 MI.getOperand(0).setReg(DestHiReg);
192 Offset += 8;
193 }
194
195 replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
196 }
197
198 Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
199 return VE::SX9;
200 }
201