LLVM 24.0.0git
MipsSubtarget.cpp
Go to the documentation of this file.
1//===-- MipsSubtarget.cpp - Mips Subtarget 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 implements the Mips specific subclass of TargetSubtargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSubtarget.h"
14#include "Mips.h"
15#include "MipsCallLowering.h"
16#include "MipsLegalizerInfo.h"
18#include "MipsRegisterInfo.h"
20#include "MipsTargetMachine.h"
21#include "llvm/IR/Attributes.h"
22#include "llvm/IR/Function.h"
25#include "llvm/Support/Debug.h"
27
28using namespace llvm;
29
31 "mips-compact-branches", cl::init(CB_Optimal),
32 cl::desc("MIPS Specific: Compact branch policy."),
34 "Do not use compact branches if possible."),
35 clEnumValN(CB_Optimal, "optimal",
36 "Use compact branches where appropriate (default)."),
37 clEnumValN(CB_Always, "always",
38 "Always use compact branches if possible.")));
39
40#define DEBUG_TYPE "mips-subtarget"
41
42#define GET_SUBTARGETINFO_TARGET_DESC
43#define GET_SUBTARGETINFO_CTOR
44#include "MipsGenSubtargetInfo.inc"
45
46static cl::opt<bool> Mips16HardFloat("mips16-hard-float", cl::NotHidden,
47 cl::desc("Enable mips16 hard float."),
48 cl::init(false));
49
50static cl::opt<bool>
51 Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden,
52 cl::desc("Enable mips16 constant islands."),
53 cl::init(true));
54
55static cl::opt<bool>
56 GPOpt("mgpopt", cl::Hidden,
57 cl::desc("Enable gp-relative addressing of mips small data items"));
58
59bool MipsSubtarget::DspWarningPrinted = false;
60bool MipsSubtarget::MSAWarningPrinted = false;
61bool MipsSubtarget::VirtWarningPrinted = false;
62bool MipsSubtarget::CRCWarningPrinted = false;
63bool MipsSubtarget::GINVWarningPrinted = false;
64
65void MipsSubtarget::anchor() {}
66
68 StringRef ABIName, bool little,
69 const MipsTargetMachine &TM,
70 MaybeAlign StackAlignOverride)
71 : MipsGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
72 MipsArchVersion(MipsDefault), IsLittle(little), IsSoftFloat(false),
73 IsSingleFloat(false), IsFPXX(false), NoABICalls(false), Abs2008(false),
74 IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false),
75 IsGP64bit(false), HasVFPU(false), HasCnMips(false), HasCnMipsP(false),
76 IsR5900(false), FixR5900(false), HasMips3_32(false), HasMips3_32r2(false),
77 HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false),
78 InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
79 InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), HasDSPR3(false),
80 HasMSA(false), UseTCCInDIV(false), HasSym32(false), HasEVA(false),
81 DisableMadd4(false), HasMT(false), HasCRC(false), HasVirt(false),
82 HasGINV(false), UseIndirectJumpsHazard(false), StrictAlign(false),
83 UseCompactBranches(MipsCompactBranchPolicy != CB_Never),
84 StackAlignOverride(StackAlignOverride), TM(TM),
85 ABI(MipsABIInfo::computeTargetABI(TT, ABIName)),
86 InstrInfo(
88 FrameLowering(MipsFrameLowering::create(*this)),
89 TLInfo(MipsTargetLowering::create(TM, *this)) {
90
91 if (MipsArchVersion == MipsDefault)
92 MipsArchVersion = Mips32;
93
94 // Don't even attempt to generate code for MIPS-V. It has not
95 // been tested and currently exists for the integrated assembler only.
96 if (MipsArchVersion == Mips5)
97 report_fatal_error("Code generation for MIPS-V is not implemented", false);
98
99 // Check if Architecture and ABI are compatible.
100 assert(((!isGP64bit() && isABI_O32()) || isGP64bit()) &&
101 "Invalid Arch & ABI pair.");
102
103 if (hasMSA() && !isFP64bit())
104 report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
105 "See -mattr=+fp64.",
106 false);
107
108 if (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
110 "FPU with 64-bit registers is not available on MIPS32 pre revision 2. "
111 "Use -mcpu=mips32r2 or greater.", false);
112
113 if (!isABI_O32() && !useOddSPReg())
114 report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
115
116 if (IsFPXX && (isABI_N32() || isABI_N64()))
117 report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
118
119 if (hasMips64r6() && InMicroMipsMode)
120 report_fatal_error("microMIPS64R6 is not supported", false);
121
122 if (!isABI_O32() && InMicroMipsMode)
123 report_fatal_error("microMIPS64 is not supported.", false);
124
125 if (UseIndirectJumpsHazard) {
126 if (InMicroMipsMode)
128 "cannot combine indirect jumps with hazard barriers and microMIPS");
129 if (!hasMips32r2())
131 "indirect jumps with hazard barriers requires MIPS32R2 or later");
132 }
133 if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
134 report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
135 "architecture.",
136 false);
137 }
138
139 if (hasMips32r6()) {
140 StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
141
142 assert(isFP64bit());
143 assert(isNaN2008());
145 if (hasDSP())
146 report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
147 }
148
149 if (NoABICalls && TM.isPositionIndependent())
150 report_fatal_error("position-independent code requires '-mabicalls'");
151
152 if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
153 NoABICalls = true;
154
155 // Set UseSmallSection.
156 UseSmallSection = GPOpt;
157 if (!NoABICalls && GPOpt) {
158 errs() << "warning: cannot use small-data accesses for '-mabicalls'"
159 << "\n";
160 UseSmallSection = false;
161 }
162
163 if (hasDSPR2() && !DspWarningPrinted) {
164 if (hasMips64() && !hasMips64r2()) {
165 errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
166 << "greater\n";
167 DspWarningPrinted = true;
168 } else if (hasMips32() && !hasMips32r2()) {
169 errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
170 << "greater\n";
171 DspWarningPrinted = true;
172 }
173 } else if (hasDSP() && !DspWarningPrinted) {
174 if (hasMips64() && !hasMips64r2()) {
175 errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
176 << "greater\n";
177 DspWarningPrinted = true;
178 } else if (hasMips32() && !hasMips32r2()) {
179 errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
180 << "greater\n";
181 DspWarningPrinted = true;
182 }
183 }
184
185 StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
186
187 if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
188 errs() << "warning: the 'msa' ASE requires " << ArchName
189 << " revision 5 or greater\n";
190 MSAWarningPrinted = true;
191 }
192 if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
193 errs() << "warning: the 'virt' ASE requires " << ArchName
194 << " revision 5 or greater\n";
195 VirtWarningPrinted = true;
196 }
197 if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
198 errs() << "warning: the 'crc' ASE requires " << ArchName
199 << " revision 6 or greater\n";
200 CRCWarningPrinted = true;
201 }
202 if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
203 errs() << "warning: the 'ginv' ASE requires " << ArchName
204 << " revision 6 or greater\n";
205 GINVWarningPrinted = true;
206 }
207
208 TSInfo = std::make_unique<MipsSelectionDAGInfo>();
209
211 Legalizer.reset(new MipsLegalizerInfo(*this));
212
213 auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
214 RegBankInfo.reset(RBI);
215 InstSelector.reset(createMipsInstructionSelector(TM, *this, *RBI));
216}
217
219
221 return TM.isPositionIndependent();
222}
223
224/// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
225bool MipsSubtarget::enablePostRAScheduler() const { return true; }
226
227void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
228 CriticalPathRCs.clear();
229 CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
230 : &Mips::GPR32RegClass);
231}
232
236
239 const TargetMachine &TM) {
240 StringRef CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
241
242 // Parse features string.
243 ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
244
245 // O32 uses 32-bit GPRs even when the selected CPU supports a 64-bit ISA.
246 if (isABI_O32())
247 IsGP64bit = false;
248
249 if (InMips16Mode && !IsSoftFloat)
250 InMips16HardFloat = true;
251
252 if (StackAlignOverride)
253 stackAlignment = *StackAlignOverride;
254 else if (isABI_N32() || isABI_N64())
255 stackAlignment = Align(16);
256 else {
257 assert(isABI_O32() && "Unknown ABI for stack alignment!");
258 stackAlignment = Align(8);
259 }
260
261 if ((isABI_N32() || isABI_N64()) && !isGP64bit())
262 reportFatalUsageError("64-bit code requested on a subtarget that doesn't "
263 "support it!");
264
265 return *this;
266}
267
269 LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
270 << "\n");
272}
273
275 return TM.getRelocationModel();
276}
277
278bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
279bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
280bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
281
283 return TSInfo.get();
284}
285
287 return CallLoweringInfo.get();
288}
289
291 return Legalizer.get();
292}
293
295 return RegBankInfo.get();
296}
297
301
302// Libcalls for which no helper is generated. Sorted by name for binary search.
303const RTLIB::LibcallImpl MipsSubtarget::HardFloatLibCalls[34] = {
304 RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3,
305 RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3,
306 RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2,
307 RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi,
308 RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf,
309 RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf,
310 RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2,
311 RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2,
312 RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2,
313 RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2,
314 RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3,
315 RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2,
316 RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc,
317 RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc,
318 RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3,
319 RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2,
320 RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2};
321
323 if (inMips16Mode() && !useSoftFloat()) {
324 for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) {
325 assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
326 "Array not sorted!");
327 RTLIB::Libcall LC =
329 Info.setLibcallImpl(LC, HardFloatLibCalls[I]);
330 }
331 }
332}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the simple types necessary to represent the attributes associated with functions a...
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define I(x, y, z)
Definition MD5.cpp:57
This file describes how to lower LLVM calls to machine code calls.
cl::opt< CompactBranchPolicy > MipsCompactBranchPolicy
This file declares the targeting of the Machinelegalizer class for Mips.
This file declares the targeting of the RegisterBankInfo class for Mips.
static cl::opt< bool > Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden, cl::desc("Enable mips16 constant islands."), cl::init(true))
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
static cl::opt< bool > GPOpt("mgpopt", cl::Hidden, cl::desc("Enable gp-relative addressing of mips small data items"))
cl::opt< CompactBranchPolicy > MipsCompactBranchPolicy("mips-compact-branches", cl::init(CB_Optimal), cl::desc("MIPS Specific: Compact branch policy."), cl::values(clEnumValN(CB_Never, "never", "Do not use compact branches if possible."), clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropriate (default)."), clEnumValN(CB_Always, "always", "Always use compact branches if possible.")))
#define LLVM_DEBUG(...)
Definition Debug.h:119
Tracks which library functions to use for a particular subtarget or function.
bool IsN64() const
Definition MipsABIInfo.h:41
bool IsN32() const
Definition MipsABIInfo.h:40
bool IsO32() const
Definition MipsABIInfo.h:39
This class provides legalization strategies.
This class provides the information for the target register banks.
bool hasMips32r6() const
void initLibcallLoweringInfo(LibcallLoweringInfo &Info) const override
const LegalizerInfo * getLegalizerInfo() const override
static bool useConstantIslands()
bool hasMips64r2() const
bool isFP64bit() const
bool enablePostRAScheduler() const override
This overrides the PostRAScheduler bit in the SchedModel for each CPU.
bool hasMips32r5() const
MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, StringRef ABIName, bool little, const MipsTargetMachine &TM, MaybeAlign StackAlignOverride)
This constructor initializes the data members to match that of the specified triple.
std::unique_ptr< InstructionSelector > InstSelector
bool useSoftFloat() const
bool hasDSPR2() const
bool hasMips64r6() const
bool isNaN2008() const
bool useOddSPReg() const
MipsSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS, const TargetMachine &TM)
const CallLowering * getCallLowering() const override
std::unique_ptr< RegisterBankInfo > RegBankInfo
bool inMips16Mode() const
bool hasMips64() const
~MipsSubtarget() override
bool hasMips32() const
bool hasSym32() const
bool inAbs2008Mode() const
std::unique_ptr< CallLowering > CallLoweringInfo
const MipsRegisterInfo * getRegisterInfo() const override
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
const RegisterBankInfo * getRegBankInfo() const override
static const RTLIB::LibcallImpl HardFloatLibCalls[34]
bool isPositionIndependent() const
bool isGP64bit() const
bool hasMips32r2() const
InstructionSelector * getInstructionSelector() const override
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
const MipsTargetLowering * getTargetLowering() const override
void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override
const MipsABIInfo & getABI() const
Reloc::Model getRelocationModel() const
CodeGenOptLevel getOptLevelToEnablePostRAScheduler() const override
Holds all the information related to register banks.
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Primary interface to the complete machine description for the target machine.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
InstructionSelector * createMipsInstructionSelector(const MipsTargetMachine &, const MipsSubtarget &, const MipsRegisterBankInfo &)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:227
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ CB_Never
The policy 'never' may in some circumstances or for some ISAs not be absolutely adhered to.
@ CB_Always
'always' may in some circumstances may not be absolutely adhered to, there may not be a corresponding...
@ CB_Optimal
Optimal is the default and will produce compact branches when appropriate.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.