Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp
96353 views
1
//===- LoongArchRegisterInfo.cpp - LoongArch 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 LoongArch implementation of the TargetRegisterInfo
10
// class.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "LoongArchRegisterInfo.h"
15
#include "LoongArch.h"
16
#include "LoongArchInstrInfo.h"
17
#include "LoongArchSubtarget.h"
18
#include "MCTargetDesc/LoongArchBaseInfo.h"
19
#include "MCTargetDesc/LoongArchMCTargetDesc.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/Support/ErrorHandling.h"
27
28
using namespace llvm;
29
30
#define GET_REGINFO_TARGET_DESC
31
#include "LoongArchGenRegisterInfo.inc"
32
33
LoongArchRegisterInfo::LoongArchRegisterInfo(unsigned HwMode)
34
: LoongArchGenRegisterInfo(LoongArch::R1, /*DwarfFlavour*/ 0,
35
/*EHFlavor*/ 0,
36
/*PC*/ 0, HwMode) {}
37
38
const MCPhysReg *
39
LoongArchRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
40
auto &Subtarget = MF->getSubtarget<LoongArchSubtarget>();
41
42
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
43
return CSR_NoRegs_SaveList;
44
switch (Subtarget.getTargetABI()) {
45
default:
46
llvm_unreachable("Unrecognized ABI");
47
case LoongArchABI::ABI_ILP32S:
48
case LoongArchABI::ABI_LP64S:
49
return CSR_ILP32S_LP64S_SaveList;
50
case LoongArchABI::ABI_ILP32F:
51
case LoongArchABI::ABI_LP64F:
52
return CSR_ILP32F_LP64F_SaveList;
53
case LoongArchABI::ABI_ILP32D:
54
case LoongArchABI::ABI_LP64D:
55
return CSR_ILP32D_LP64D_SaveList;
56
}
57
}
58
59
const uint32_t *
60
LoongArchRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
61
CallingConv::ID CC) const {
62
auto &Subtarget = MF.getSubtarget<LoongArchSubtarget>();
63
64
if (CC == CallingConv::GHC)
65
return CSR_NoRegs_RegMask;
66
switch (Subtarget.getTargetABI()) {
67
default:
68
llvm_unreachable("Unrecognized ABI");
69
case LoongArchABI::ABI_ILP32S:
70
case LoongArchABI::ABI_LP64S:
71
return CSR_ILP32S_LP64S_RegMask;
72
case LoongArchABI::ABI_ILP32F:
73
case LoongArchABI::ABI_LP64F:
74
return CSR_ILP32F_LP64F_RegMask;
75
case LoongArchABI::ABI_ILP32D:
76
case LoongArchABI::ABI_LP64D:
77
return CSR_ILP32D_LP64D_RegMask;
78
}
79
}
80
81
const uint32_t *LoongArchRegisterInfo::getNoPreservedMask() const {
82
return CSR_NoRegs_RegMask;
83
}
84
85
BitVector
86
LoongArchRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
87
const LoongArchFrameLowering *TFI = getFrameLowering(MF);
88
BitVector Reserved(getNumRegs());
89
90
// Use markSuperRegs to ensure any register aliases are also reserved
91
markSuperRegs(Reserved, LoongArch::R0); // zero
92
markSuperRegs(Reserved, LoongArch::R2); // tp
93
markSuperRegs(Reserved, LoongArch::R3); // sp
94
markSuperRegs(Reserved, LoongArch::R21); // non-allocatable
95
if (TFI->hasFP(MF))
96
markSuperRegs(Reserved, LoongArch::R22); // fp
97
// Reserve the base register if we need to realign the stack and allocate
98
// variable-sized objects at runtime.
99
if (TFI->hasBP(MF))
100
markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp
101
102
assert(checkAllSuperRegsMarked(Reserved));
103
return Reserved;
104
}
105
106
Register
107
LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
108
const TargetFrameLowering *TFI = getFrameLowering(MF);
109
return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3;
110
}
111
112
bool LoongArchRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
113
int SPAdj,
114
unsigned FIOperandNum,
115
RegScavenger *RS) const {
116
// TODO: this implementation is a temporary placeholder which does just
117
// enough to allow other aspects of code generation to be tested.
118
119
assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
120
121
MachineInstr &MI = *II;
122
assert(MI.getOperand(FIOperandNum + 1).isImm() &&
123
"Unexpected FI-consuming insn");
124
125
MachineBasicBlock &MBB = *MI.getParent();
126
MachineFunction &MF = *MI.getParent()->getParent();
127
MachineRegisterInfo &MRI = MF.getRegInfo();
128
const LoongArchSubtarget &STI = MF.getSubtarget<LoongArchSubtarget>();
129
const LoongArchInstrInfo *TII = STI.getInstrInfo();
130
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
131
DebugLoc DL = MI.getDebugLoc();
132
bool IsLA64 = STI.is64Bit();
133
unsigned MIOpc = MI.getOpcode();
134
135
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
136
Register FrameReg;
137
StackOffset Offset =
138
TFI->getFrameIndexReference(MF, FrameIndex, FrameReg) +
139
StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());
140
141
bool FrameRegIsKill = false;
142
143
if (!isInt<12>(Offset.getFixed())) {
144
unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W;
145
unsigned Add = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W;
146
147
// The offset won't fit in an immediate, so use a scratch register instead.
148
// Modify Offset and FrameReg appropriately.
149
Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
150
TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
151
if (MIOpc == Addi) {
152
BuildMI(MBB, II, DL, TII->get(Add), MI.getOperand(0).getReg())
153
.addReg(FrameReg)
154
.addReg(ScratchReg, RegState::Kill);
155
MI.eraseFromParent();
156
return true;
157
}
158
BuildMI(MBB, II, DL, TII->get(Add), ScratchReg)
159
.addReg(FrameReg)
160
.addReg(ScratchReg, RegState::Kill);
161
Offset = StackOffset::getFixed(0);
162
FrameReg = ScratchReg;
163
FrameRegIsKill = true;
164
}
165
166
// Spill CFRs.
167
if (MIOpc == LoongArch::PseudoST_CFR) {
168
Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
169
BuildMI(MBB, II, DL, TII->get(LoongArch::MOVCF2GR), ScratchReg)
170
.add(MI.getOperand(0));
171
BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::ST_D : LoongArch::ST_W))
172
.addReg(ScratchReg, RegState::Kill)
173
.addReg(FrameReg)
174
.addImm(Offset.getFixed());
175
MI.eraseFromParent();
176
return true;
177
}
178
179
// Reload CFRs.
180
if (MIOpc == LoongArch::PseudoLD_CFR) {
181
Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass);
182
BuildMI(MBB, II, DL, TII->get(IsLA64 ? LoongArch::LD_D : LoongArch::LD_W),
183
ScratchReg)
184
.addReg(FrameReg)
185
.addImm(Offset.getFixed());
186
BuildMI(MBB, II, DL, TII->get(LoongArch::MOVGR2CF))
187
.add(MI.getOperand(0))
188
.addReg(ScratchReg, RegState::Kill);
189
MI.eraseFromParent();
190
return true;
191
}
192
193
MI.getOperand(FIOperandNum)
194
.ChangeToRegister(FrameReg, false, false, FrameRegIsKill);
195
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed());
196
return false;
197
}
198
199
bool LoongArchRegisterInfo::canRealignStack(const MachineFunction &MF) const {
200
if (!TargetRegisterInfo::canRealignStack(MF))
201
return false;
202
203
const MachineRegisterInfo *MRI = &MF.getRegInfo();
204
const LoongArchFrameLowering *TFI = getFrameLowering(MF);
205
206
// Stack realignment requires a frame pointer. If we already started
207
// register allocation with frame pointer elimination, it is too late now.
208
if (!MRI->canReserveReg(LoongArch::R22))
209
return false;
210
211
// We may also need a base pointer if there are dynamic allocas or stack
212
// pointer adjustments around calls.
213
if (TFI->hasReservedCallFrame(MF))
214
return true;
215
216
// A base pointer is required and allowed. Check that it isn't too late to
217
// reserve it.
218
return MRI->canReserveReg(LoongArchABI::getBPReg());
219
}
220
221