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
30#define DEBUG_TYPE "mips-subtarget"
31
32#define GET_SUBTARGETINFO_TARGET_DESC
33#define GET_SUBTARGETINFO_CTOR
34#include "MipsGenSubtargetInfo.inc"
35
36#define OPTIONS_STRUCT_DEFS
37#include "MipsOptions.inc"
38
39bool MipsSubtarget::DspWarningPrinted = false;
40bool MipsSubtarget::MSAWarningPrinted = false;
41bool MipsSubtarget::VirtWarningPrinted = false;
42bool MipsSubtarget::CRCWarningPrinted = false;
43bool MipsSubtarget::GINVWarningPrinted = false;
44
45void MipsSubtarget::anchor() {}
46
48 StringRef ABIName, bool little,
49 const MipsTargetMachine &TM,
50 MaybeAlign StackAlignOverride)
51 : MipsGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
52 CLOpts(TM.getCLOpts()), MCCLOpts(TM.getMCCLOpts()),
53 MipsArchVersion(MipsDefault), IsLittle(little), IsSoftFloat(false),
54 IsSingleFloat(false), IsFPXX(false), NoABICalls(false), Abs2008(false),
55 IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false),
56 IsGP64bit(false), HasVFPU(false), HasCnMips(false), HasCnMipsP(false),
57 IsR5900(false), FixR5900(false), HasMips3_32(false), HasMips3_32r2(false),
58 HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false),
59 InMips16Mode(false), InMips16HardFloat(CLOpts.mips16_hard_float),
60 InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), HasDSPR3(false),
61 HasMSA(false), UseTCCInDIV(false), HasSym32(false), HasEVA(false),
62 DisableMadd4(false), HasMT(false), HasCRC(false), HasVirt(false),
63 HasGINV(false), UseIndirectJumpsHazard(false), StrictAlign(false),
64 UseCompactBranches(CLOpts.compact_branches != CompactBranchPolicy::Never),
65 StackAlignOverride(StackAlignOverride), TM(TM),
66 ABI(MipsABIInfo::computeTargetABI(TT, ABIName)),
67 InstrInfo(
69 FrameLowering(MipsFrameLowering::create(*this)),
70 TLInfo(MipsTargetLowering::create(TM, *this)) {
71
72 if (MipsArchVersion == MipsDefault)
73 MipsArchVersion = Mips32;
74
75 // Don't even attempt to generate code for MIPS-V. It has not
76 // been tested and currently exists for the integrated assembler only.
77 if (MipsArchVersion == Mips5)
78 report_fatal_error("Code generation for MIPS-V is not implemented", false);
79
80 // Check if Architecture and ABI are compatible.
81 assert(((!isGP64bit() && isABI_O32()) || isGP64bit()) &&
82 "Invalid Arch & ABI pair.");
83
84 if (hasMSA() && !isFP64bit())
85 report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
86 "See -mattr=+fp64.",
87 false);
88
89 if (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
91 "FPU with 64-bit registers is not available on MIPS32 pre revision 2. "
92 "Use -mcpu=mips32r2 or greater.", false);
93
94 if (!isABI_O32() && !useOddSPReg())
95 report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
96
97 if (IsFPXX && (isABI_N32() || isABI_N64()))
98 report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
99
100 if (hasMips64r6() && InMicroMipsMode)
101 report_fatal_error("microMIPS64R6 is not supported", false);
102
103 if (!isABI_O32() && InMicroMipsMode)
104 report_fatal_error("microMIPS64 is not supported.", false);
105
106 if (UseIndirectJumpsHazard) {
107 if (InMicroMipsMode)
109 "cannot combine indirect jumps with hazard barriers and microMIPS");
110 if (!hasMips32r2())
112 "indirect jumps with hazard barriers requires MIPS32R2 or later");
113 }
114 if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
115 report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
116 "architecture.",
117 false);
118 }
119
120 if (hasMips32r6()) {
121 StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
122
123 assert(isFP64bit());
124 assert(isNaN2008());
126 if (hasDSP())
127 report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
128 }
129
130 if (NoABICalls && TM.isPositionIndependent())
131 report_fatal_error("position-independent code requires '-mabicalls'");
132
133 if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
134 NoABICalls = true;
135
136 // Set UseSmallSection.
137 UseSmallSection = CLOpts.mgpopt;
138 if (!NoABICalls && CLOpts.mgpopt) {
139 errs() << "warning: cannot use small-data accesses for '-mabicalls'"
140 << "\n";
141 UseSmallSection = false;
142 }
143
144 if (hasDSPR2() && !DspWarningPrinted) {
145 if (hasMips64() && !hasMips64r2()) {
146 errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
147 << "greater\n";
148 DspWarningPrinted = true;
149 } else if (hasMips32() && !hasMips32r2()) {
150 errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
151 << "greater\n";
152 DspWarningPrinted = true;
153 }
154 } else if (hasDSP() && !DspWarningPrinted) {
155 if (hasMips64() && !hasMips64r2()) {
156 errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
157 << "greater\n";
158 DspWarningPrinted = true;
159 } else if (hasMips32() && !hasMips32r2()) {
160 errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
161 << "greater\n";
162 DspWarningPrinted = true;
163 }
164 }
165
166 StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
167
168 if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
169 errs() << "warning: the 'msa' ASE requires " << ArchName
170 << " revision 5 or greater\n";
171 MSAWarningPrinted = true;
172 }
173 if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
174 errs() << "warning: the 'virt' ASE requires " << ArchName
175 << " revision 5 or greater\n";
176 VirtWarningPrinted = true;
177 }
178 if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
179 errs() << "warning: the 'crc' ASE requires " << ArchName
180 << " revision 6 or greater\n";
181 CRCWarningPrinted = true;
182 }
183 if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
184 errs() << "warning: the 'ginv' ASE requires " << ArchName
185 << " revision 6 or greater\n";
186 GINVWarningPrinted = true;
187 }
188
189 TSInfo = std::make_unique<MipsSelectionDAGInfo>();
190
192 Legalizer.reset(new MipsLegalizerInfo(*this));
193
194 auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
195 RegBankInfo.reset(RBI);
196 InstSelector.reset(createMipsInstructionSelector(TM, *this, *RBI));
197}
198
200
202 return TM.isPositionIndependent();
203}
204
205/// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
206bool MipsSubtarget::enablePostRAScheduler() const { return true; }
207
208void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
209 CriticalPathRCs.clear();
210 CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
211 : &Mips::GPR32RegClass);
212}
213
217
220 const TargetMachine &TM) {
221 StringRef CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
222
223 // Parse features string.
224 ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
225
226 // O32 uses 32-bit GPRs even when the selected CPU supports a 64-bit ISA.
227 if (isABI_O32())
228 IsGP64bit = false;
229
230 if (InMips16Mode && !IsSoftFloat)
231 InMips16HardFloat = true;
232
233 if (StackAlignOverride)
234 stackAlignment = *StackAlignOverride;
235 else if (isABI_N32() || isABI_N64())
236 stackAlignment = Align(16);
237 else {
238 assert(isABI_O32() && "Unknown ABI for stack alignment!");
239 stackAlignment = Align(8);
240 }
241
242 if ((isABI_N32() || isABI_N64()) && !isGP64bit())
243 reportFatalUsageError("64-bit code requested on a subtarget that doesn't "
244 "support it!");
245
246 return *this;
247}
248
250 LLVM_DEBUG(dbgs() << "use constant islands " << CLOpts.mips16_constant_islands
251 << "\n");
252 return CLOpts.mips16_constant_islands;
253}
254
256 return TM.getRelocationModel();
257}
258
259bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
260bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
261bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
262
264 return TSInfo.get();
265}
266
268 return CallLoweringInfo.get();
269}
270
272 return Legalizer.get();
273}
274
276 return RegBankInfo.get();
277}
278
282
283// Libcalls for which no helper is generated. Sorted by name for binary search.
284const RTLIB::LibcallImpl MipsSubtarget::HardFloatLibCalls[34] = {
285 RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3,
286 RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3,
287 RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2,
288 RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi,
289 RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf,
290 RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf,
291 RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2,
292 RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2,
293 RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2,
294 RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2,
295 RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3,
296 RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2,
297 RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc,
298 RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc,
299 RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3,
300 RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2,
301 RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2};
302
304 if (inMips16Mode() && !useSoftFloat()) {
305 for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) {
306 assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
307 "Array not sorted!");
308 RTLIB::Libcall LC =
310 Info.setLibcallImpl(LC, HardFloatLibCalls[I]);
311 }
312 }
313}
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 I(x, y, z)
Definition MD5.cpp:57
This file describes how to lower LLVM calls to machine code calls.
This file declares the targeting of the Machinelegalizer class for Mips.
This file declares the targeting of the RegisterBankInfo class for Mips.
#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
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
const MipsOptions & getCLOpts() 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
bool useConstantIslands() const
Reloc::Model getRelocationModel() const
const MipsMCOptions & getMCCLOpts() 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.
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.
CompactBranchPolicy
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:111
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.