LLVM  9.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  unsigned 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),
85  TM(TM), TargetTriple(TT), TSInfo(),
86  InstrInfo(
87  MipsInstrInfo::create(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 (!isABI_O32() && !useOddSPReg())
112  report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
113 
114  if (IsFPXX && (isABI_N32() || isABI_N64()))
115  report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
116 
117  if (hasMips64r6() && InMicroMipsMode)
118  report_fatal_error("microMIPS64R6 is not supported", false);
119 
120  if (!isABI_O32() && InMicroMipsMode)
121  report_fatal_error("microMIPS64 is not supported.", false);
122 
123  if (UseIndirectJumpsHazard) {
124  if (InMicroMipsMode)
126  "cannot combine indirect jumps with hazard barriers and microMIPS");
127  if (!hasMips32r2())
129  "indirect jumps with hazard barriers requires MIPS32R2 or later");
130  }
131  if (inAbs2008Mode() && hasMips32() && !hasMips32r2()) {
132  report_fatal_error("IEEE 754-2008 abs.fmt is not supported for the given "
133  "architecture.",
134  false);
135  }
136 
137  if (hasMips32r6()) {
138  StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
139 
140  assert(isFP64bit());
141  assert(isNaN2008());
143  if (hasDSP())
144  report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
145  }
146 
147  if (NoABICalls && TM.isPositionIndependent())
148  report_fatal_error("position-independent code requires '-mabicalls'");
149 
150  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
151  NoABICalls = true;
152 
153  // Set UseSmallSection.
154  UseSmallSection = GPOpt;
155  if (!NoABICalls && GPOpt) {
156  errs() << "warning: cannot use small-data accesses for '-mabicalls'"
157  << "\n";
158  UseSmallSection = false;
159  }
160 
161  if (hasDSPR2() && !DspWarningPrinted) {
162  if (hasMips64() && !hasMips64r2()) {
163  errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
164  << "greater\n";
165  DspWarningPrinted = true;
166  } else if (hasMips32() && !hasMips32r2()) {
167  errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
168  << "greater\n";
169  DspWarningPrinted = true;
170  }
171  } else if (hasDSP() && !DspWarningPrinted) {
172  if (hasMips64() && !hasMips64r2()) {
173  errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
174  << "greater\n";
175  DspWarningPrinted = true;
176  } else if (hasMips32() && !hasMips32r2()) {
177  errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
178  << "greater\n";
179  DspWarningPrinted = true;
180  }
181  }
182 
183  StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
184 
185  if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
186  errs() << "warning: the 'msa' ASE requires " << ArchName
187  << " revision 5 or greater\n";
188  MSAWarningPrinted = true;
189  }
190  if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
191  errs() << "warning: the 'virt' ASE requires " << ArchName
192  << " revision 5 or greater\n";
193  VirtWarningPrinted = true;
194  }
195  if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
196  errs() << "warning: the 'crc' ASE requires " << ArchName
197  << " revision 6 or greater\n";
198  CRCWarningPrinted = true;
199  }
200  if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
201  errs() << "warning: the 'ginv' ASE requires " << ArchName
202  << " revision 6 or greater\n";
203  GINVWarningPrinted = true;
204  }
205 
207  Legalizer.reset(new MipsLegalizerInfo(*this));
208 
209  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
210  RegBankInfo.reset(RBI);
212  *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
213 }
214 
216  return TM.isPositionIndependent();
217 }
218 
219 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
220 bool MipsSubtarget::enablePostRAScheduler() const { return true; }
221 
222 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
223  CriticalPathRCs.clear();
224  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
225  : &Mips::GPR32RegClass);
226 }
227 
229  return CodeGenOpt::Aggressive;
230 }
231 
234  const TargetMachine &TM) {
235  std::string CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
236 
237  // Parse features string.
238  ParseSubtargetFeatures(CPUName, FS);
239  // Initialize scheduling itinerary for the specified CPU.
240  InstrItins = getInstrItineraryForCPU(CPUName);
241 
242  if (InMips16Mode && !IsSoftFloat)
243  InMips16HardFloat = true;
244 
245  if (StackAlignOverride)
246  stackAlignment = StackAlignOverride;
247  else if (isABI_N32() || isABI_N64())
248  stackAlignment = 16;
249  else {
250  assert(isABI_O32() && "Unknown ABI for stack alignment!");
251  stackAlignment = 8;
252  }
253 
254  return *this;
255 }
256 
258  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
259  << "\n");
260  return Mips16ConstantIslands;
261 }
262 
264  return TM.getRelocationModel();
265 }
266 
267 bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
268 bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
269 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
270 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
271 
273  return CallLoweringInfo.get();
274 }
275 
277  return Legalizer.get();
278 }
279 
281  return RegBankInfo.get();
282 }
283 
285  return InstSelector.get();
286 }
const RegisterBankInfo * getRegBankInfo() const override
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
MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little, const MipsTargetMachine &TM, unsigned StackAlignOverride)
This constructor initializes the data members to match that of the specified triple.
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
const InstructionSelector * getInstructionSelector() const override
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
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
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.
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