LLVM  13.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 "MipsMachineFunction.h"
16 #include "MipsRegisterInfo.h"
17 #include "MipsTargetMachine.h"
18 #include "MipsCallLowering.h"
19 #include "MipsLegalizerInfo.h"
20 #include "MipsRegisterBankInfo.h"
21 #include "llvm/IR/Attributes.h"
22 #include "llvm/IR/Function.h"
24 #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 
68 void MipsSubtarget::anchor() {}
69 
71  bool little, const MipsTargetMachine &TM,
72  MaybeAlign StackAlignOverride)
73  : MipsGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
74  MipsArchVersion(MipsDefault), IsLittle(little), IsSoftFloat(false),
75  IsSingleFloat(false), IsFPXX(false), NoABICalls(false), Abs2008(false),
76  IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false),
77  IsGP64bit(false), HasVFPU(false), HasCnMips(false), HasCnMipsP(false),
78  HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
79  HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
80  InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
81  HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
82  Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
83  HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
84  HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false),
85  StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
86  TSInfo(), InstrInfo(MipsInstrInfo::create(
87  initializeSubtargetDependencies(CPU, FS, TM))),
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-I and MIPS-V. They have not
95  // been tested and currently exist for the integrated assembler only.
96  if (MipsArchVersion == Mips1)
97  report_fatal_error("Code generation for MIPS-I is not implemented", false);
98  if (MipsArchVersion == Mips5)
99  report_fatal_error("Code generation for MIPS-V is not implemented", false);
100 
101  // Check if Architecture and ABI are compatible.
102  assert(((!isGP64bit() && isABI_O32()) ||
103  (isGP64bit() && (isABI_N32() || isABI_N64()))) &&
104  "Invalid Arch & ABI pair.");
105 
106  if (hasMSA() && !isFP64bit())
107  report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
108  "See -mattr=+fp64.",
109  false);
110 
111  if (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
113  "FPU with 64-bit registers is not available on MIPS32 pre revision 2. "
114  "Use -mcpu=mips32r2 or greater.");
115 
116  if (!isABI_O32() && !useOddSPReg())
117  report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
118 
119  if (IsFPXX && (isABI_N32() || isABI_N64()))
120  report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
121 
122  if (hasMips64r6() && InMicroMipsMode)
123  report_fatal_error("microMIPS64R6 is not supported", false);
124 
125  if (!isABI_O32() && InMicroMipsMode)
126  report_fatal_error("microMIPS64 is not supported.", false);
127 
128  if (UseIndirectJumpsHazard) {
129  if (InMicroMipsMode)
131  "cannot combine indirect jumps with hazard barriers and microMIPS");
132  if (!hasMips32r2())
134  "indirect jumps with hazard barriers requires MIPS32R2 or later");
135  }
136  if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
137  report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
138  "architecture.",
139  false);
140  }
141 
142  if (hasMips32r6()) {
143  StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
144 
145  assert(isFP64bit());
146  assert(isNaN2008());
148  if (hasDSP())
149  report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
150  }
151 
152  if (NoABICalls && TM.isPositionIndependent())
153  report_fatal_error("position-independent code requires '-mabicalls'");
154 
155  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
156  NoABICalls = true;
157 
158  // Set UseSmallSection.
159  UseSmallSection = GPOpt;
160  if (!NoABICalls && GPOpt) {
161  errs() << "warning: cannot use small-data accesses for '-mabicalls'"
162  << "\n";
163  UseSmallSection = false;
164  }
165 
166  if (hasDSPR2() && !DspWarningPrinted) {
167  if (hasMips64() && !hasMips64r2()) {
168  errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
169  << "greater\n";
170  DspWarningPrinted = true;
171  } else if (hasMips32() && !hasMips32r2()) {
172  errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
173  << "greater\n";
174  DspWarningPrinted = true;
175  }
176  } else if (hasDSP() && !DspWarningPrinted) {
177  if (hasMips64() && !hasMips64r2()) {
178  errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
179  << "greater\n";
180  DspWarningPrinted = true;
181  } else if (hasMips32() && !hasMips32r2()) {
182  errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
183  << "greater\n";
184  DspWarningPrinted = true;
185  }
186  }
187 
188  StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
189 
190  if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
191  errs() << "warning: the 'msa' ASE requires " << ArchName
192  << " revision 5 or greater\n";
193  MSAWarningPrinted = true;
194  }
195  if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
196  errs() << "warning: the 'virt' ASE requires " << ArchName
197  << " revision 5 or greater\n";
198  VirtWarningPrinted = true;
199  }
200  if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
201  errs() << "warning: the 'crc' ASE requires " << ArchName
202  << " revision 6 or greater\n";
203  CRCWarningPrinted = true;
204  }
205  if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
206  errs() << "warning: the 'ginv' ASE requires " << ArchName
207  << " revision 6 or greater\n";
208  GINVWarningPrinted = true;
209  }
210 
212  Legalizer.reset(new MipsLegalizerInfo(*this));
213 
214  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
215  RegBankInfo.reset(RBI);
217  *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
218 }
219 
221  return TM.isPositionIndependent();
222 }
223 
224 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
225 bool MipsSubtarget::enablePostRAScheduler() const { return true; }
226 
227 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
228  CriticalPathRCs.clear();
229  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
230  : &Mips::GPR32RegClass);
231 }
232 
234  return CodeGenOpt::Aggressive;
235 }
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  // Initialize scheduling itinerary for the specified CPU.
245  InstrItins = getInstrItineraryForCPU(CPUName);
246 
247  if (InMips16Mode && !IsSoftFloat)
248  InMips16HardFloat = true;
249 
250  if (StackAlignOverride)
251  stackAlignment = *StackAlignOverride;
252  else if (isABI_N32() || isABI_N64())
253  stackAlignment = Align(16);
254  else {
255  assert(isABI_O32() && "Unknown ABI for stack alignment!");
256  stackAlignment = Align(8);
257  }
258 
259  if ((isABI_N32() || isABI_N64()) && !isGP64bit())
260  report_fatal_error("64-bit code requested on a subtarget that doesn't "
261  "support it!");
262 
263  return *this;
264 }
265 
267  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
268  << "\n");
269  return Mips16ConstantIslands;
270 }
271 
273  return TM.getRelocationModel();
274 }
275 
276 bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
277 bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
278 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
279 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
280 
282  return CallLoweringInfo.get();
283 }
284 
286  return Legalizer.get();
287 }
288 
290  return RegBankInfo.get();
291 }
292 
294  return InstSelector.get();
295 }
MipsGenSubtargetInfo
llvm::MipsABIInfo::IsN64
bool IsN64() const
Definition: MipsABIInfo.h:42
llvm::MipsTargetMachine
Definition: MipsTargetMachine.h:27
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
llvm::MipsSubtarget::inAbs2008Mode
bool inAbs2008Mode() const
Definition: MipsSubtarget.h:288
llvm::MipsTargetMachine::getABI
const MipsABIInfo & getABI() const
Definition: MipsTargetMachine.h:75
llvm::SystemZISD::TM
@ TM
Definition: SystemZISelLowering.h:65
llvm::MipsSubtarget::hasMips32r2
bool hasMips32r2() const
Definition: MipsSubtarget.h:256
llvm::MipsABIInfo
Definition: MipsABIInfo.h:22
MipsLegalizerInfo.h
llvm::MipsSubtarget::isPositionIndependent
bool isPositionIndependent() const
Definition: MipsSubtarget.cpp:220
llvm::MipsSubtarget::hasMips64r6
bool hasMips64r6() const
Definition: MipsSubtarget.h:276
llvm::MipsSubtarget::getABI
const MipsABIInfo & getABI() const
Definition: MipsSubtarget.cpp:279
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::MipsSubtarget::getCallLowering
const CallLowering * getCallLowering() const override
Definition: MipsSubtarget.cpp:281
llvm::MipsSubtarget::hasMips64
bool hasMips64() const
Definition: MipsSubtarget.h:272
llvm::TargetMachine::getRelocationModel
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
Definition: TargetMachine.cpp:70
llvm::MipsSubtarget::hasSym32
bool hasSym32() const
Definition: MipsSubtarget.h:294
llvm::MipsSubtarget::useOddSPReg
bool useOddSPReg() const
Definition: MipsSubtarget.h:285
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:894
MipsTargetMachine.h
llvm::MipsSubtarget::isNaN2008
bool isNaN2008() const
Definition: MipsSubtarget.h:287
llvm::MipsSubtarget::useConstantIslands
static bool useConstantIslands()
Definition: MipsSubtarget.cpp:266
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
llvm::Reloc::Model
Model
Definition: CodeGen.h:22
llvm::MipsSubtarget::initializeSubtargetDependencies
MipsSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS, const TargetMachine &TM)
Definition: MipsSubtarget.cpp:238
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
llvm::MipsSubtarget::getRegisterInfo
const MipsRegisterInfo * getRegisterInfo() const override
Definition: MipsSubtarget.h:386
CommandLine.h
MipsCallLowering.h
llvm::support::little
@ little
Definition: Endian.h:27
llvm::Legalizer
Definition: Legalizer.h:31
llvm::cl::NotHidden
@ NotHidden
Definition: CommandLine.h:139
Mips.h
llvm::X86AS::FS
@ FS
Definition: X86.h:182
false
Definition: StackSlotColoring.cpp:142
llvm::MipsSubtarget::getRegBankInfo
const RegisterBankInfo * getRegBankInfo() const override
Definition: MipsSubtarget.cpp:289
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:119
llvm::MipsInstrInfo
Definition: MipsInstrInfo.h:41
MipsRegisterInfo.h
llvm::report_fatal_error
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::MipsSubtarget::hasMips32r5
bool hasMips32r5() const
Definition: MipsSubtarget.h:264
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::MipsSubtarget::hasCRC
bool hasCRC() const
Definition: MipsSubtarget.h:323
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:44
llvm::MipsSubtarget::hasMips32
bool hasMips32() const
Definition: MipsSubtarget.h:252
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:400
llvm::InstructionSelector
Provides the logic to select generic machine instructions.
Definition: InstructionSelector.h:413
llvm::MipsSubtarget::hasMips32r6
bool hasMips32r6() const
Definition: MipsSubtarget.h:268
llvm::MipsSubtarget::getOptLevelToEnablePostRAScheduler
CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override
Definition: MipsSubtarget.cpp:233
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:277
llvm::MipsCallLowering
Definition: MipsCallLowering.h:24
MipsMachineFunction.h
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:440
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::MipsSubtarget::isABI_N64
bool isABI_N64() const
Definition: MipsSubtarget.cpp:276
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:315
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:57
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm::MipsSubtarget::getTargetLowering
const MipsTargetLowering * getTargetLowering() const override
Definition: MipsSubtarget.h:389
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:316
llvm::MipsSubtarget::InstSelector
std::unique_ptr< InstructionSelector > InstSelector
Definition: MipsSubtarget.h:401
llvm::MipsSubtarget::getLegalizerInfo
const LegalizerInfo * getLegalizerInfo() const override
Definition: MipsSubtarget.cpp:285
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:261
llvm::MipsSubtarget::hasVirt
bool hasVirt() const
Definition: MipsSubtarget.h:324
llvm::MipsSubtarget::enablePostRAScheduler
bool enablePostRAScheduler() const override
This overrides the PostRAScheduler bit in the SchedModel for each CPU.
Definition: MipsSubtarget.cpp:225
llvm::MipsSubtarget::hasMSA
bool hasMSA() const
Definition: MipsSubtarget.h:319
Attributes.h
llvm::MipsSubtarget::isGP64bit
bool isGP64bit() const
Definition: MipsSubtarget.h:289
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:278
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:398
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:284
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1041
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:70
llvm::MipsSubtarget::getCriticalPathRCs
void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override
Definition: MipsSubtarget.cpp:227
llvm::cl::desc
Definition: CommandLine.h:411
llvm::MipsSubtarget::getRelocationModel
Reloc::Model getRelocationModel() const
Definition: MipsSubtarget.cpp:272
raw_ostream.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1833
TargetRegistry.h
llvm::CallLowering
Definition: CallLowering.h:42
llvm::MipsSubtarget::hasMips64r2
bool hasMips64r2() const
Definition: MipsSubtarget.h:273
llvm::MipsSubtarget::getInstructionSelector
InstructionSelector * getInstructionSelector() const override
Definition: MipsSubtarget.cpp:293
Debug.h
llvm::MipsSubtarget::hasGINV
bool hasGINV() const
Definition: MipsSubtarget.h:325