LLVM  10.0.0svn
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, FS), MipsArchVersion(MipsDefault),
74  IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false),
75  NoABICalls(false), Abs2008(false), IsFP64bit(false), UseOddSPReg(true),
76  IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false),
77  HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
78  HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
79  InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
80  HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
81  Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
82  HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
83  HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false),
84  StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
85  TSInfo(), InstrInfo(MipsInstrInfo::create(
86  initializeSubtargetDependencies(CPU, FS, TM))),
87  FrameLowering(MipsFrameLowering::create(*this)),
88  TLInfo(MipsTargetLowering::create(TM, *this)) {
89 
90  if (MipsArchVersion == MipsDefault)
91  MipsArchVersion = Mips32;
92 
93  // Don't even attempt to generate code for MIPS-I and MIPS-V. They have not
94  // been tested and currently exist for the integrated assembler only.
95  if (MipsArchVersion == Mips1)
96  report_fatal_error("Code generation for MIPS-I is not implemented", false);
97  if (MipsArchVersion == Mips5)
98  report_fatal_error("Code generation for MIPS-V is not implemented", false);
99 
100  // Check if Architecture and ABI are compatible.
101  assert(((!isGP64bit() && isABI_O32()) ||
102  (isGP64bit() && (isABI_N32() || isABI_N64()))) &&
103  "Invalid Arch & ABI pair.");
104 
105  if (hasMSA() && !isFP64bit())
106  report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
107  "See -mattr=+fp64.",
108  false);
109 
110  if (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
112  "FPU with 64-bit registers is not available on MIPS32 pre revision 2. "
113  "Use -mcpu=mips32r2 or greater.");
114 
115  if (!isABI_O32() && !useOddSPReg())
116  report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
117 
118  if (IsFPXX && (isABI_N32() || isABI_N64()))
119  report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
120 
121  if (hasMips64r6() && InMicroMipsMode)
122  report_fatal_error("microMIPS64R6 is not supported", false);
123 
124  if (!isABI_O32() && InMicroMipsMode)
125  report_fatal_error("microMIPS64 is not supported.", false);
126 
127  if (UseIndirectJumpsHazard) {
128  if (InMicroMipsMode)
130  "cannot combine indirect jumps with hazard barriers and microMIPS");
131  if (!hasMips32r2())
133  "indirect jumps with hazard barriers requires MIPS32R2 or later");
134  }
135  if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
136  report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
137  "architecture.",
138  false);
139  }
140 
141  if (hasMips32r6()) {
142  StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
143 
144  assert(isFP64bit());
145  assert(isNaN2008());
147  if (hasDSP())
148  report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
149  }
150 
151  if (NoABICalls && TM.isPositionIndependent())
152  report_fatal_error("position-independent code requires '-mabicalls'");
153 
154  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
155  NoABICalls = true;
156 
157  // Set UseSmallSection.
158  UseSmallSection = GPOpt;
159  if (!NoABICalls && GPOpt) {
160  errs() << "warning: cannot use small-data accesses for '-mabicalls'"
161  << "\n";
162  UseSmallSection = false;
163  }
164 
165  if (hasDSPR2() && !DspWarningPrinted) {
166  if (hasMips64() && !hasMips64r2()) {
167  errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
168  << "greater\n";
169  DspWarningPrinted = true;
170  } else if (hasMips32() && !hasMips32r2()) {
171  errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
172  << "greater\n";
173  DspWarningPrinted = true;
174  }
175  } else if (hasDSP() && !DspWarningPrinted) {
176  if (hasMips64() && !hasMips64r2()) {
177  errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
178  << "greater\n";
179  DspWarningPrinted = true;
180  } else if (hasMips32() && !hasMips32r2()) {
181  errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
182  << "greater\n";
183  DspWarningPrinted = true;
184  }
185  }
186 
187  StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
188 
189  if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
190  errs() << "warning: the 'msa' ASE requires " << ArchName
191  << " revision 5 or greater\n";
192  MSAWarningPrinted = true;
193  }
194  if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
195  errs() << "warning: the 'virt' ASE requires " << ArchName
196  << " revision 5 or greater\n";
197  VirtWarningPrinted = true;
198  }
199  if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
200  errs() << "warning: the 'crc' ASE requires " << ArchName
201  << " revision 6 or greater\n";
202  CRCWarningPrinted = true;
203  }
204  if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
205  errs() << "warning: the 'ginv' ASE requires " << ArchName
206  << " revision 6 or greater\n";
207  GINVWarningPrinted = true;
208  }
209 
211  Legalizer.reset(new MipsLegalizerInfo(*this));
212 
213  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
214  RegBankInfo.reset(RBI);
216  *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
217 }
218 
220  return TM.isPositionIndependent();
221 }
222 
223 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
224 bool MipsSubtarget::enablePostRAScheduler() const { return true; }
225 
226 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
227  CriticalPathRCs.clear();
228  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
229  : &Mips::GPR32RegClass);
230 }
231 
233  return CodeGenOpt::Aggressive;
234 }
235 
238  const TargetMachine &TM) {
239  std::string CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
240 
241  // Parse features string.
242  ParseSubtargetFeatures(CPUName, FS);
243  // Initialize scheduling itinerary for the specified CPU.
244  InstrItins = getInstrItineraryForCPU(CPUName);
245 
246  if (InMips16Mode && !IsSoftFloat)
247  InMips16HardFloat = true;
248 
249  if (StackAlignOverride)
250  stackAlignment = *StackAlignOverride;
251  else if (isABI_N32() || isABI_N64())
252  stackAlignment = Align(16);
253  else {
254  assert(isABI_O32() && "Unknown ABI for stack alignment!");
255  stackAlignment = Align(8);
256  }
257 
258  return *this;
259 }
260 
262  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
263  << "\n");
264  return Mips16ConstantIslands;
265 }
266 
268  return TM.getRelocationModel();
269 }
270 
271 bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
272 bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
273 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
274 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
275 
277  return CallLoweringInfo.get();
278 }
279 
281  return Legalizer.get();
282 }
283 
285  return RegBankInfo.get();
286 }
287 
289  return InstSelector.get();
290 }
const RegisterBankInfo * getRegBankInfo() const override
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
std::unique_ptr< InstructionSelector > InstSelector
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:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override
This file declares the targeting of the Machinelegalizer class for Mips.
bool isABI_O32() const
block Block Frequency true
bool hasMips64() const
bool hasDSPR2() const
Holds all the information related to register banks.
bool hasSym32() const
bool isGP64bit() const
This file contains the simple types necessary to represent the attributes associated with functions a...
bool hasMips32r6() const
bool IsN32() const
Definition: MipsABIInfo.h:42
This class provides legalization strategies.
const MipsABIInfo & getABI() const
bool IsN64() const
Definition: MipsABIInfo.h:43
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.
This file declares the targeting of the RegisterBankInfo class for Mips.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool hasMips32r5() const
InstructionSelector * createMipsInstructionSelector(const MipsTargetMachine &, MipsSubtarget &, MipsRegisterBankInfo &)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
bool hasCRC() const
const LegalizerInfo * getLegalizerInfo() const override
std::unique_ptr< RegisterBankInfo > RegBankInfo
bool hasMips64r2() const
static cl::opt< bool > Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden, cl::desc("Enable mips16 constant islands."), cl::init(true))
const Triple & getTargetTriple() const
StringRef selectMipsCPU(const Triple &TT, StringRef CPU)
Select the Mips CPU for the given triple and cpu name.
bool IsO32() const
Definition: MipsABIInfo.h:41
bool hasMips64r6() const
const MipsABIInfo & getABI() const
bool isABI_N32() const
bool isNaN2008() const
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
std::unique_ptr< CallLowering > CallLoweringInfo
static bool useConstantIslands()
const MipsRegisterInfo * getRegisterInfo() const override
bool isPositionIndependent() const
This struct is a compact representation of a valid (power of two) or undefined (0) alignment...
Definition: Alignment.h:117
bool enablePostRAScheduler() const override
This overrides the PostRAScheduler bit in the SchedModel for each CPU.
bool inAbs2008Mode() const
This class provides the information for the target register banks.
bool hasDSP() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const CallLowering * getCallLowering() const override
const MipsTargetLowering * getTargetLowering() const override
bool hasVirt() const
Provides the logic to select generic machine instructions.
bool hasGINV() const
static cl::opt< bool > GPOpt("mgpopt", cl::Hidden, cl::desc("Enable gp-relative addressing of mips small data items"))
bool isPositionIndependent() const
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)
bool hasMips32() const
bool useOddSPReg() const
bool hasMips32r2() const
This file describes how to lower LLVM calls to machine code calls.
bool isABI_N64() const
CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override
Reloc::Model getRelocationModel() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void ParseSubtargetFeatures(StringRef CPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
InstructionSelector * getInstructionSelector() const override
MipsSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS, const TargetMachine &TM)
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:65
static cl::opt< bool > Mips16HardFloat("mips16-hard-float", cl::NotHidden, cl::desc("Enable mips16 hard float."), cl::init(false))
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
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)
#define LLVM_DEBUG(X)
Definition: Debug.h:122
bool isFP64bit() const
bool hasMSA() const