Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
96353 views
1
//===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//
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 Lanai implementation of the TargetRegisterInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiRegisterInfo.h"
14
#include "LanaiAluCode.h"
15
#include "LanaiCondCode.h"
16
#include "LanaiFrameLowering.h"
17
#include "LanaiInstrInfo.h"
18
#include "llvm/ADT/BitVector.h"
19
#include "llvm/ADT/STLExtras.h"
20
#include "llvm/CodeGen/MachineFrameInfo.h"
21
#include "llvm/CodeGen/MachineFunction.h"
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/RegisterScavenging.h"
24
#include "llvm/CodeGen/TargetFrameLowering.h"
25
#include "llvm/CodeGen/TargetInstrInfo.h"
26
#include "llvm/IR/Function.h"
27
#include "llvm/IR/Type.h"
28
#include "llvm/Support/ErrorHandling.h"
29
30
#define GET_REGINFO_TARGET_DESC
31
#include "LanaiGenRegisterInfo.inc"
32
33
using namespace llvm;
34
35
LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {}
36
37
const uint16_t *
38
LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const {
39
return CSR_SaveList;
40
}
41
42
BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
43
BitVector Reserved(getNumRegs());
44
45
Reserved.set(Lanai::R0);
46
Reserved.set(Lanai::R1);
47
Reserved.set(Lanai::PC);
48
Reserved.set(Lanai::R2);
49
Reserved.set(Lanai::SP);
50
Reserved.set(Lanai::R4);
51
Reserved.set(Lanai::FP);
52
Reserved.set(Lanai::R5);
53
Reserved.set(Lanai::RR1);
54
Reserved.set(Lanai::R10);
55
Reserved.set(Lanai::RR2);
56
Reserved.set(Lanai::R11);
57
Reserved.set(Lanai::RCA);
58
Reserved.set(Lanai::R15);
59
if (hasBasePointer(MF))
60
Reserved.set(getBaseRegister());
61
return Reserved;
62
}
63
64
bool LanaiRegisterInfo::requiresRegisterScavenging(
65
const MachineFunction & /*MF*/) const {
66
return true;
67
}
68
69
static bool isALUArithLoOpcode(unsigned Opcode) {
70
switch (Opcode) {
71
case Lanai::ADD_I_LO:
72
case Lanai::SUB_I_LO:
73
case Lanai::ADD_F_I_LO:
74
case Lanai::SUB_F_I_LO:
75
case Lanai::ADDC_I_LO:
76
case Lanai::SUBB_I_LO:
77
case Lanai::ADDC_F_I_LO:
78
case Lanai::SUBB_F_I_LO:
79
return true;
80
default:
81
return false;
82
}
83
}
84
85
static unsigned getOppositeALULoOpcode(unsigned Opcode) {
86
switch (Opcode) {
87
case Lanai::ADD_I_LO:
88
return Lanai::SUB_I_LO;
89
case Lanai::SUB_I_LO:
90
return Lanai::ADD_I_LO;
91
case Lanai::ADD_F_I_LO:
92
return Lanai::SUB_F_I_LO;
93
case Lanai::SUB_F_I_LO:
94
return Lanai::ADD_F_I_LO;
95
case Lanai::ADDC_I_LO:
96
return Lanai::SUBB_I_LO;
97
case Lanai::SUBB_I_LO:
98
return Lanai::ADDC_I_LO;
99
case Lanai::ADDC_F_I_LO:
100
return Lanai::SUBB_F_I_LO;
101
case Lanai::SUBB_F_I_LO:
102
return Lanai::ADDC_F_I_LO;
103
default:
104
llvm_unreachable("Invalid ALU lo opcode");
105
}
106
}
107
108
static unsigned getRRMOpcodeVariant(unsigned Opcode) {
109
switch (Opcode) {
110
case Lanai::LDBs_RI:
111
return Lanai::LDBs_RR;
112
case Lanai::LDBz_RI:
113
return Lanai::LDBz_RR;
114
case Lanai::LDHs_RI:
115
return Lanai::LDHs_RR;
116
case Lanai::LDHz_RI:
117
return Lanai::LDHz_RR;
118
case Lanai::LDW_RI:
119
return Lanai::LDW_RR;
120
case Lanai::STB_RI:
121
return Lanai::STB_RR;
122
case Lanai::STH_RI:
123
return Lanai::STH_RR;
124
case Lanai::SW_RI:
125
return Lanai::SW_RR;
126
default:
127
llvm_unreachable("Opcode has no RRM variant");
128
}
129
}
130
131
bool LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
132
int SPAdj, unsigned FIOperandNum,
133
RegScavenger *RS) const {
134
assert(SPAdj == 0 && "Unexpected");
135
136
MachineInstr &MI = *II;
137
MachineFunction &MF = *MI.getParent()->getParent();
138
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
139
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
140
bool HasFP = TFI->hasFP(MF);
141
DebugLoc DL = MI.getDebugLoc();
142
143
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
144
145
int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
146
MI.getOperand(FIOperandNum + 1).getImm();
147
148
// Addressable stack objects are addressed using neg. offsets from fp
149
// or pos. offsets from sp/basepointer
150
if (!HasFP || (hasStackRealignment(MF) && FrameIndex >= 0))
151
Offset += MF.getFrameInfo().getStackSize();
152
153
Register FrameReg = getFrameRegister(MF);
154
if (FrameIndex >= 0) {
155
if (hasBasePointer(MF))
156
FrameReg = getBaseRegister();
157
else if (hasStackRealignment(MF))
158
FrameReg = Lanai::SP;
159
}
160
161
// Replace frame index with a frame pointer reference.
162
// If the offset is small enough to fit in the immediate field, directly
163
// encode it.
164
// Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence.
165
if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) ||
166
!isInt<16>(Offset)) {
167
assert(RS && "Register scavenging must be on");
168
Register Reg = RS->FindUnusedReg(&Lanai::GPRRegClass);
169
if (!Reg)
170
Reg = RS->scavengeRegisterBackwards(Lanai::GPRRegClass, II, false, SPAdj);
171
assert(Reg && "Register scavenger failed");
172
173
bool HasNegOffset = false;
174
// ALU ops have unsigned immediate values. If the Offset is negative, we
175
// negate it here and reverse the opcode later.
176
if (Offset < 0) {
177
HasNegOffset = true;
178
Offset = -Offset;
179
}
180
181
if (!isInt<16>(Offset)) {
182
// Reg = hi(offset) | lo(offset)
183
BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg)
184
.addImm(static_cast<uint32_t>(Offset) >> 16);
185
BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg)
186
.addReg(Reg)
187
.addImm(Offset & 0xffffU);
188
} else {
189
// Reg = mov(offset)
190
BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
191
.addImm(0)
192
.addImm(Offset);
193
}
194
// Reg = FrameReg OP Reg
195
if (MI.getOpcode() == Lanai::ADD_I_LO) {
196
BuildMI(*MI.getParent(), II, DL,
197
HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
198
MI.getOperand(0).getReg())
199
.addReg(FrameReg)
200
.addReg(Reg)
201
.addImm(LPCC::ICC_T);
202
MI.eraseFromParent();
203
return true;
204
}
205
if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
206
MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
207
if (HasNegOffset) {
208
// Change the ALU op (operand 3) from LPAC::ADD (the default) to
209
// LPAC::SUB with the already negated offset.
210
assert((MI.getOperand(3).getImm() == LPAC::ADD) &&
211
"Unexpected ALU op in RRM instruction");
212
MI.getOperand(3).setImm(LPAC::SUB);
213
}
214
} else
215
llvm_unreachable("Unexpected opcode in frame index operation");
216
217
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
218
MI.getOperand(FIOperandNum + 1)
219
.ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
220
/*isKill=*/true);
221
return false;
222
}
223
224
// ALU arithmetic ops take unsigned immediates. If the offset is negative,
225
// we replace the instruction with one that inverts the opcode and negates
226
// the immediate.
227
if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) {
228
unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode());
229
// We know this is an ALU op, so we know the operands are as follows:
230
// 0: destination register
231
// 1: source register (frame register)
232
// 2: immediate
233
BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
234
MI.getOperand(0).getReg())
235
.addReg(FrameReg)
236
.addImm(-Offset);
237
MI.eraseFromParent();
238
return true;
239
}
240
241
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
242
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
243
return false;
244
}
245
246
bool LanaiRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
247
const MachineFrameInfo &MFI = MF.getFrameInfo();
248
// When we need stack realignment and there are dynamic allocas, we can't
249
// reference off of the stack pointer, so we reserve a base pointer.
250
if (hasStackRealignment(MF) && MFI.hasVarSizedObjects())
251
return true;
252
253
return false;
254
}
255
256
unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
257
258
Register
259
LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const {
260
return Lanai::FP;
261
}
262
263
Register LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
264
265
const uint32_t *
266
LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,
267
CallingConv::ID /*CC*/) const {
268
return CSR_RegMask;
269
}
270
271