LLVM  15.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"
17 #include "MipsMachineFunction.h"
18 #include "MipsRegisterBankInfo.h"
19 #include "MipsRegisterInfo.h"
20 #include "MipsTargetMachine.h"
21 #include "llvm/IR/Attributes.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/Debug.h"
27 
28 using 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 // FIXME: Maybe this should be on by default when Mips16 is specified
37 //
38 static cl::opt<bool>
39  Mixed16_32("mips-mixed-16-32", cl::init(false),
40  cl::desc("Allow for a mixture of Mips16 "
41  "and Mips32 code in a single output file"),
42  cl::Hidden);
43 
44 static cl::opt<bool> Mips_Os16("mips-os16", cl::init(false),
45  cl::desc("Compile all functions that don't use "
46  "floating point as Mips 16"),
47  cl::Hidden);
48 
49 static cl::opt<bool> Mips16HardFloat("mips16-hard-float", cl::NotHidden,
50  cl::desc("Enable mips16 hard float."),
51  cl::init(false));
52 
53 static cl::opt<bool>
54  Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden,
55  cl::desc("Enable mips16 constant islands."),
56  cl::init(true));
57 
58 static cl::opt<bool>
59  GPOpt("mgpopt", cl::Hidden,
60  cl::desc("Enable gp-relative addressing of mips small data items"));
61 
62 bool MipsSubtarget::DspWarningPrinted = false;
63 bool MipsSubtarget::MSAWarningPrinted = false;
64 bool MipsSubtarget::VirtWarningPrinted = false;
65 bool MipsSubtarget::CRCWarningPrinted = false;
66 bool MipsSubtarget::GINVWarningPrinted = false;
67 bool MipsSubtarget::MIPS1WarningPrinted = false;
68 
69 void MipsSubtarget::anchor() {}
70 
72  bool little, const MipsTargetMachine &TM,
73  MaybeAlign StackAlignOverride)
74  : MipsGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
75  MipsArchVersion(MipsDefault), IsLittle(little), IsSoftFloat(false),
76  IsSingleFloat(false), IsFPXX(false), NoABICalls(false), Abs2008(false),
77  IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false),
78  IsGP64bit(false), HasVFPU(false), HasCnMips(false), HasCnMipsP(false),
79  HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
80  HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
81  InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
82  HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 || Mips_Os16),
83  Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
84  HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
85  HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false),
86  StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
87  TSInfo(), InstrInfo(MipsInstrInfo::create(
88  initializeSubtargetDependencies(CPU, FS, TM))),
89  FrameLowering(MipsFrameLowering::create(*this)),
90  TLInfo(MipsTargetLowering::create(TM, *this)) {
91 
92  if (MipsArchVersion == MipsDefault)
93  MipsArchVersion = Mips32;
94 
95  // MIPS-I has not been tested.
96  if (MipsArchVersion == Mips1 && !MIPS1WarningPrinted) {
97  errs() << "warning: MIPS-I support is experimental\n";
98  MIPS1WarningPrinted = true;
99  }
100 
101  // Don't even attempt to generate code for MIPS-V. It has not
102  // been tested and currently exists for the integrated assembler only.
103  if (MipsArchVersion == Mips5)
104  report_fatal_error("Code generation for MIPS-V is not implemented", false);
105 
106  // Check if Architecture and ABI are compatible.
107  assert(((!isGP64bit() && isABI_O32()) ||
108  (isGP64bit() && (isABI_N32() || isABI_N64()))) &&
109  "Invalid Arch & ABI pair.");
110 
111  if (hasMSA() && !isFP64bit())
112  report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
113  "See -mattr=+fp64.",
114  false);
115 
116  if (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
118  "FPU with 64-bit registers is not available on MIPS32 pre revision 2. "
119  "Use -mcpu=mips32r2 or greater.");
120 
121  if (!isABI_O32() && !useOddSPReg())
122  report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
123 
124  if (IsFPXX && (isABI_N32() || isABI_N64()))
125  report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
126 
127  if (hasMips64r6() && InMicroMipsMode)
128  report_fatal_error("microMIPS64R6 is not supported", false);
129 
130  if (!isABI_O32() && InMicroMipsMode)
131  report_fatal_error("microMIPS64 is not supported.", false);
132 
133  if (UseIndirectJumpsHazard) {
134  if (InMicroMipsMode)
136  "cannot combine indirect jumps with hazard barriers and microMIPS");
137  if (!hasMips32r2())
139  "indirect jumps with hazard barriers requires MIPS32R2 or later");
140  }
141  if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
142  report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
143  "architecture.",
144  false);
145  }
146 
147  if (hasMips32r6()) {
148  StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
149 
150  assert(isFP64bit());
151  assert(isNaN2008());
153  if (hasDSP())
154  report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
155  }
156 
157  if (NoABICalls && TM.isPositionIndependent())
158  report_fatal_error("position-independent code requires '-mabicalls'");
159 
160  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
161  NoABICalls = true;
162 
163  // Set UseSmallSection.
164  UseSmallSection = GPOpt;
165  if (!NoABICalls && GPOpt) {
166  errs() << "warning: cannot use small-data accesses for '-mabicalls'"
167  << "\n";
168  UseSmallSection = false;
169  }
170 
171  if (hasDSPR2() && !DspWarningPrinted) {
172  if (hasMips64() && !hasMips64r2()) {
173  errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
174  << "greater\n";
175  DspWarningPrinted = true;
176  } else if (hasMips32() && !hasMips32r2()) {
177  errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
178  << "greater\n";
179  DspWarningPrinted = true;
180  }
181  } else if (hasDSP() && !DspWarningPrinted) {
182  if (hasMips64() && !hasMips64r2()) {
183  errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
184  << "greater\n";
185  DspWarningPrinted = true;
186  } else if (hasMips32() && !hasMips32r2()) {
187  errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
188  << "greater\n";
189  DspWarningPrinted = true;
190  }
191  }
192 
193  StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
194 
195  if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
196  errs() << "warning: the 'msa' ASE requires " << ArchName
197  << " revision 5 or greater\n";
198  MSAWarningPrinted = true;
199  }
200  if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
201  errs() << "warning: the 'virt' ASE requires " << ArchName
202  << " revision 5 or greater\n";
203  VirtWarningPrinted = true;
204  }
205  if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
206  errs() << "warning: the 'crc' ASE requires " << ArchName
207  << " revision 6 or greater\n";
208  CRCWarningPrinted = true;
209  }
210  if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
211  errs() << "warning: the 'ginv' ASE requires " << ArchName
212  << " revision 6 or greater\n";
213  GINVWarningPrinted = true;
214  }
215 
217  Legalizer.reset(new MipsLegalizerInfo(*this));
218 
219  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
220  RegBankInfo.reset(RBI);
222  *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
223 }
224 
226  return TM.isPositionIndependent();
227 }
228 
229 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
230 bool MipsSubtarget::enablePostRAScheduler() const { return true; }
231 
232 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
233  CriticalPathRCs.clear();
234  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
235  : &Mips::GPR32RegClass);
236 }
237 
239  return CodeGenOpt::Aggressive;
240 }
241 
244  const TargetMachine &TM) {
245  StringRef CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
246 
247  // Parse features string.
248  ParseSubtargetFeatures(CPUName, /*TuneCPU*/ CPUName, FS);
249  // Initialize scheduling itinerary for the specified CPU.
250  InstrItins = getInstrItineraryForCPU(CPUName);
251 
252  if (InMips16Mode && !IsSoftFloat)
253  InMips16HardFloat = true;
254 
255  if (StackAlignOverride)
256  stackAlignment = *StackAlignOverride;
257  else if (isABI_N32() || isABI_N64())
258  stackAlignment = Align(16);
259  else {
260  assert(isABI_O32() && "Unknown ABI for stack alignment!");
261  stackAlignment = Align(8);
262  }
263 
264  if ((isABI_N32() || isABI_N64()) && !isGP64bit())
265  report_fatal_error("64-bit code requested on a subtarget that doesn't "
266  "support it!");
267 
268  return *this;
269 }
270 
272  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
273  << "\n");
274  return Mips16ConstantIslands;
275 }
276 
278  return TM.getRelocationModel();
279 }
280 
281 bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
282 bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
283 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
284 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
285 
287  return CallLoweringInfo.get();
288 }
289 
291  return Legalizer.get();
292 }
293 
295  return RegBankInfo.get();
296 }
297 
299  return InstSelector.get();
300 }
MipsGenSubtargetInfo
llvm::MipsABIInfo::IsN64
bool IsN64() const
Definition: MipsABIInfo.h:42
llvm::MipsTargetMachine
Definition: MipsTargetMachine.h:27
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MipsSubtarget::inAbs2008Mode
bool inAbs2008Mode() const
Definition: MipsSubtarget.h:291
llvm::MipsTargetMachine::getABI
const MipsABIInfo & getABI() const
Definition: MipsTargetMachine.h:75
llvm::MipsSubtarget::hasMips32r2
bool hasMips32r2() const
Definition: MipsSubtarget.h:259
llvm::MipsABIInfo
Definition: MipsABIInfo.h:22
MipsLegalizerInfo.h
llvm::MipsSubtarget::isPositionIndependent
bool isPositionIndependent() const
Definition: MipsSubtarget.cpp:225
llvm::MipsSubtarget::hasMips64r6
bool hasMips64r6() const
Definition: MipsSubtarget.h:279
llvm::MipsSubtarget::getABI
const MipsABIInfo & getABI() const
Definition: MipsSubtarget.cpp:284
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
llvm::MipsSubtarget::getCallLowering
const CallLowering * getCallLowering() const override
Definition: MipsSubtarget.cpp:286
llvm::MipsSubtarget::hasMips64
bool hasMips64() const
Definition: MipsSubtarget.h:275
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1909
llvm::TargetMachine::getRelocationModel
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
Definition: TargetMachine.cpp:68
llvm::MipsSubtarget::hasSym32
bool hasSym32() const
Definition: MipsSubtarget.h:297
llvm::MipsSubtarget::useOddSPReg
bool useOddSPReg() const
Definition: MipsSubtarget.h:288
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
MipsTargetMachine.h
llvm::MipsSubtarget::isNaN2008
bool isNaN2008() const
Definition: MipsSubtarget.h:290
llvm::MipsSubtarget::useConstantIslands
static bool useConstantIslands()
Definition: MipsSubtarget.cpp:271
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::Reloc::Model
Model
Definition: CodeGen.h:22
llvm::MipsSubtarget::initializeSubtargetDependencies
MipsSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS, const TargetMachine &TM)
Definition: MipsSubtarget.cpp:243
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MipsSubtarget::getRegisterInfo
const MipsRegisterInfo * getRegisterInfo() const override
Definition: MipsSubtarget.h:389
CommandLine.h
MipsCallLowering.h
llvm::support::little
@ little
Definition: Endian.h:27
llvm::Legalizer
Definition: Legalizer.h:36
llvm::cl::NotHidden
@ NotHidden
Definition: CommandLine.h:138
Mips.h
false
Definition: StackSlotColoring.cpp:141
llvm::MipsSubtarget::getRegBankInfo
const RegisterBankInfo * getRegBankInfo() const override
Definition: MipsSubtarget.cpp:294
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:109
llvm::MipsInstrInfo
Definition: MipsInstrInfo.h:41
MipsRegisterInfo.h
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::MipsSubtarget::hasMips32r5
bool hasMips32r5() const
Definition: MipsSubtarget.h:267
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::MipsSubtarget::hasCRC
bool hasCRC() const
Definition: MipsSubtarget.h:326
GPOpt
static cl::opt< bool > GPOpt("mgpopt", cl::Hidden, cl::desc("Enable gp-relative addressing of mips small data items"))
llvm::TargetMachine::isPositionIndependent
bool isPositionIndependent() const
Definition: TargetMachine.cpp:41
llvm::MipsSubtarget::hasMips32
bool hasMips32() const
Definition: MipsSubtarget.h:255
llvm::cl::opt< bool >
MipsRegisterBankInfo.h
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
llvm::MipsSubtarget::RegBankInfo
std::unique_ptr< RegisterBankInfo > RegBankInfo
Definition: MipsSubtarget.h:403
llvm::InstructionSelector
Provides the logic to select generic machine instructions.
Definition: InstructionSelector.h:424
llvm::MipsSubtarget::hasMips32r6
bool hasMips32r6() const
Definition: MipsSubtarget.h:271
llvm::MipsSubtarget::getOptLevelToEnablePostRAScheduler
CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override
Definition: MipsSubtarget.cpp:238
Mips16ConstantIslands
static cl::opt< bool > Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden, cl::desc("Enable mips16 constant islands."), cl::init(true))
llvm::MipsSubtarget::isABI_N32
bool isABI_N32() const
Definition: MipsSubtarget.cpp:282
llvm::MipsCallLowering
Definition: MipsCallLowering.h:23
MipsMachineFunction.h
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::X86AS::FS
@ FS
Definition: X86.h:192
llvm::MipsSubtarget::isABI_N64
bool isABI_N64() const
Definition: MipsSubtarget.cpp:281
llvm::CodeGenOpt::Aggressive
@ Aggressive
Definition: CodeGen.h:56
Mips_Os16
static cl::opt< bool > Mips_Os16("mips-os16", cl::init(false), cl::desc("Compile all functions that don't use " "floating point as Mips 16"), cl::Hidden)
llvm::MipsSubtarget::hasDSP
bool hasDSP() const
Definition: MipsSubtarget.h:318
llvm::MSP430Attrs::ISA
ISA
Definition: MSP430Attributes.h:36
Mips16HardFloat
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm::MipsSubtarget::getTargetLowering
const MipsTargetLowering * getTargetLowering() const override
Definition: MipsSubtarget.h:392
Mixed16_32
static cl::opt< bool > Mixed16_32("mips-mixed-16-32", cl::init(false), cl::desc("Allow for a mixture of Mips16 " "and Mips32 code in a single output file"), cl::Hidden)
llvm::MipsSubtarget::hasDSPR2
bool hasDSPR2() const
Definition: MipsSubtarget.h:319
llvm::MipsSubtarget::InstSelector
std::unique_ptr< InstructionSelector > InstSelector
Definition: MipsSubtarget.h:404
llvm::MipsSubtarget::getLegalizerInfo
const LegalizerInfo * getLegalizerInfo() const override
Definition: MipsSubtarget.cpp:290
llvm::MipsFrameLowering
Definition: MipsFrameLowering.h:22
llvm::CodeGenOpt::Level
Level
Definition: CodeGen.h:52
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::MipsSubtarget::ParseSubtargetFeatures
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
llvm::MipsTargetLowering
Definition: MipsISelLowering.h:264
llvm::MipsSubtarget::hasVirt
bool hasVirt() const
Definition: MipsSubtarget.h:327
llvm::MipsSubtarget::enablePostRAScheduler
bool enablePostRAScheduler() const override
This overrides the PostRAScheduler bit in the SchedModel for each CPU.
Definition: MipsSubtarget.cpp:230
llvm::MipsSubtarget::hasMSA
bool hasMSA() const
Definition: MipsSubtarget.h:322
Attributes.h
llvm::MipsSubtarget::isGP64bit
bool isGP64bit() const
Definition: MipsSubtarget.h:292
llvm::createMipsInstructionSelector
InstructionSelector * createMipsInstructionSelector(const MipsTargetMachine &, MipsSubtarget &, MipsRegisterBankInfo &)
Definition: MipsInstructionSelector.cpp:935
llvm::MipsLegalizerInfo
This class provides legalization strategies.
Definition: MipsLegalizerInfo.h:24
llvm::MipsSubtarget::isABI_O32
bool isABI_O32() const
Definition: MipsSubtarget.cpp:283
Function.h
llvm::MipsABIInfo::IsN32
bool IsN32() const
Definition: MipsABIInfo.h:41
llvm::MipsRegisterBankInfo
This class provides the information for the target register banks.
Definition: MipsRegisterBankInfo.h:31
llvm::MipsSubtarget::CallLoweringInfo
std::unique_ptr< CallLowering > CallLoweringInfo
Definition: MipsSubtarget.h:401
llvm::MIPS_MC::selectMipsCPU
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
Definition: MipsMCTargetDesc.cpp:48
llvm::MipsABIInfo::IsO32
bool IsO32() const
Definition: MipsABIInfo.h:40
MipsSubtarget.h
llvm::MipsSubtarget::isFP64bit
bool isFP64bit() const
Definition: MipsSubtarget.h:287
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1180
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MipsSubtarget::MipsSubtarget
MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little, const MipsTargetMachine &TM, MaybeAlign StackAlignOverride)
This constructor initializes the data members to match that of the specified triple.
Definition: MipsSubtarget.cpp:71
llvm::MipsSubtarget::getCriticalPathRCs
void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override
Definition: MipsSubtarget.cpp:232
llvm::cl::desc
Definition: CommandLine.h:405
llvm::MipsSubtarget::getRelocationModel
Reloc::Model getRelocationModel() const
Definition: MipsSubtarget.cpp:277
raw_ostream.h
TargetRegistry.h
llvm::CallLowering
Definition: CallLowering.h:44
llvm::MipsSubtarget::hasMips64r2
bool hasMips64r2() const
Definition: MipsSubtarget.h:276
llvm::MipsSubtarget::getInstructionSelector
InstructionSelector * getInstructionSelector() const override
Definition: MipsSubtarget.cpp:298
Debug.h
llvm::MipsSubtarget::hasGINV
bool hasGINV() const
Definition: MipsSubtarget.h:328