LLVM  8.0.1
MipsSubtarget.cpp
Go to the documentation of this file.
1 //===-- MipsSubtarget.cpp - Mips Subtarget Information --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Mips specific subclass of TargetSubtargetInfo.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsSubtarget.h"
15 #include "Mips.h"
16 #include "MipsMachineFunction.h"
17 #include "MipsRegisterInfo.h"
18 #include "MipsTargetMachine.h"
19 #include "MipsCallLowering.h"
20 #include "MipsLegalizerInfo.h"
21 #include "MipsRegisterBankInfo.h"
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/IR/Function.h"
25 #include "llvm/Support/Debug.h"
28 
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "mips-subtarget"
32 
33 #define GET_SUBTARGETINFO_TARGET_DESC
34 #define GET_SUBTARGETINFO_CTOR
35 #include "MipsGenSubtargetInfo.inc"
36 
37 // FIXME: Maybe this should be on by default when Mips16 is specified
38 //
39 static cl::opt<bool>
40  Mixed16_32("mips-mixed-16-32", cl::init(false),
41  cl::desc("Allow for a mixture of Mips16 "
42  "and Mips32 code in a single output file"),
43  cl::Hidden);
44 
45 static cl::opt<bool> Mips_Os16("mips-os16", cl::init(false),
46  cl::desc("Compile all functions that don't use "
47  "floating point as Mips 16"),
48  cl::Hidden);
49 
50 static cl::opt<bool> Mips16HardFloat("mips16-hard-float", cl::NotHidden,
51  cl::desc("Enable mips16 hard float."),
52  cl::init(false));
53 
54 static cl::opt<bool>
55  Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden,
56  cl::desc("Enable mips16 constant islands."),
57  cl::init(true));
58 
59 static cl::opt<bool>
60  GPOpt("mgpopt", cl::Hidden,
61  cl::desc("Enable gp-relative addressing of mips small data items"));
62 
63 bool MipsSubtarget::DspWarningPrinted = false;
64 bool MipsSubtarget::MSAWarningPrinted = false;
65 bool MipsSubtarget::VirtWarningPrinted = false;
66 bool MipsSubtarget::CRCWarningPrinted = false;
67 bool MipsSubtarget::GINVWarningPrinted = false;
68 
69 void MipsSubtarget::anchor() {}
70 
72  bool little, const MipsTargetMachine &TM,
73  unsigned StackAlignOverride)
74  : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault),
75  IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false),
76  NoABICalls(false), IsFP64bit(false), UseOddSPReg(true),
77  IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(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),
86  TM(TM), TargetTriple(TT), TSInfo(),
87  InstrInfo(
88  MipsInstrInfo::create(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  // Don't even attempt to generate code for MIPS-I and MIPS-V. They have not
96  // been tested and currently exist for the integrated assembler only.
97  if (MipsArchVersion == Mips1)
98  report_fatal_error("Code generation for MIPS-I is not implemented", false);
99  if (MipsArchVersion == Mips5)
100  report_fatal_error("Code generation for MIPS-V is not implemented", false);
101 
102  // Check if Architecture and ABI are compatible.
103  assert(((!isGP64bit() && isABI_O32()) ||
104  (isGP64bit() && (isABI_N32() || isABI_N64()))) &&
105  "Invalid Arch & ABI pair.");
106 
107  if (hasMSA() && !isFP64bit())
108  report_fatal_error("MSA requires a 64-bit FPU register file (FR=1 mode). "
109  "See -mattr=+fp64.",
110  false);
111 
112  if (!isABI_O32() && !useOddSPReg())
113  report_fatal_error("-mattr=+nooddspreg requires the O32 ABI.", false);
114 
115  if (IsFPXX && (isABI_N32() || isABI_N64()))
116  report_fatal_error("FPXX is not permitted for the N32/N64 ABI's.", false);
117 
118  if (hasMips64r6() && InMicroMipsMode)
119  report_fatal_error("microMIPS64R6 is not supported", false);
120 
121  if (!isABI_O32() && InMicroMipsMode)
122  report_fatal_error("microMIPS64 is not supported.", false);
123 
124  if (UseIndirectJumpsHazard) {
125  if (InMicroMipsMode)
127  "cannot combine indirect jumps with hazard barriers and microMIPS");
128  if (!hasMips32r2())
130  "indirect jumps with hazard barriers requires MIPS32R2 or later");
131  }
132  if (hasMips32r6()) {
133  StringRef ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
134 
135  assert(isFP64bit());
136  assert(isNaN2008());
137  if (hasDSP())
138  report_fatal_error(ISA + " is not compatible with the DSP ASE", false);
139  }
140 
141  if (NoABICalls && TM.isPositionIndependent())
142  report_fatal_error("position-independent code requires '-mabicalls'");
143 
144  if (isABI_N64() && !TM.isPositionIndependent() && !hasSym32())
145  NoABICalls = true;
146 
147  // Set UseSmallSection.
148  UseSmallSection = GPOpt;
149  if (!NoABICalls && GPOpt) {
150  errs() << "warning: cannot use small-data accesses for '-mabicalls'"
151  << "\n";
152  UseSmallSection = false;
153  }
154 
155  if (hasDSPR2() && !DspWarningPrinted) {
156  if (hasMips64() && !hasMips64r2()) {
157  errs() << "warning: the 'dspr2' ASE requires MIPS64 revision 2 or "
158  << "greater\n";
159  DspWarningPrinted = true;
160  } else if (hasMips32() && !hasMips32r2()) {
161  errs() << "warning: the 'dspr2' ASE requires MIPS32 revision 2 or "
162  << "greater\n";
163  DspWarningPrinted = true;
164  }
165  } else if (hasDSP() && !DspWarningPrinted) {
166  if (hasMips64() && !hasMips64r2()) {
167  errs() << "warning: the 'dsp' ASE requires MIPS64 revision 2 or "
168  << "greater\n";
169  DspWarningPrinted = true;
170  } else if (hasMips32() && !hasMips32r2()) {
171  errs() << "warning: the 'dsp' ASE requires MIPS32 revision 2 or "
172  << "greater\n";
173  DspWarningPrinted = true;
174  }
175  }
176 
177  StringRef ArchName = hasMips64() ? "MIPS64" : "MIPS32";
178 
179  if (!hasMips32r5() && hasMSA() && !MSAWarningPrinted) {
180  errs() << "warning: the 'msa' ASE requires " << ArchName
181  << " revision 5 or greater\n";
182  MSAWarningPrinted = true;
183  }
184  if (!hasMips32r5() && hasVirt() && !VirtWarningPrinted) {
185  errs() << "warning: the 'virt' ASE requires " << ArchName
186  << " revision 5 or greater\n";
187  VirtWarningPrinted = true;
188  }
189  if (!hasMips32r6() && hasCRC() && !CRCWarningPrinted) {
190  errs() << "warning: the 'crc' ASE requires " << ArchName
191  << " revision 6 or greater\n";
192  CRCWarningPrinted = true;
193  }
194  if (!hasMips32r6() && hasGINV() && !GINVWarningPrinted) {
195  errs() << "warning: the 'ginv' ASE requires " << ArchName
196  << " revision 6 or greater\n";
197  GINVWarningPrinted = true;
198  }
199 
201  Legalizer.reset(new MipsLegalizerInfo(*this));
202 
203  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
204  RegBankInfo.reset(RBI);
206  *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
207 }
208 
210  return TM.isPositionIndependent();
211 }
212 
213 /// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
214 bool MipsSubtarget::enablePostRAScheduler() const { return true; }
215 
216 void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
217  CriticalPathRCs.clear();
218  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
219  : &Mips::GPR32RegClass);
220 }
221 
223  return CodeGenOpt::Aggressive;
224 }
225 
228  const TargetMachine &TM) {
229  std::string CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
230 
231  // Parse features string.
232  ParseSubtargetFeatures(CPUName, FS);
233  // Initialize scheduling itinerary for the specified CPU.
234  InstrItins = getInstrItineraryForCPU(CPUName);
235 
236  if (InMips16Mode && !IsSoftFloat)
237  InMips16HardFloat = true;
238 
239  if (StackAlignOverride)
240  stackAlignment = StackAlignOverride;
241  else if (isABI_N32() || isABI_N64())
242  stackAlignment = 16;
243  else {
244  assert(isABI_O32() && "Unknown ABI for stack alignment!");
245  stackAlignment = 8;
246  }
247 
248  return *this;
249 }
250 
252  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
253  << "\n");
254  return Mips16ConstantIslands;
255 }
256 
258  return TM.getRelocationModel();
259 }
260 
261 bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
262 bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
263 bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
264 const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
265 
267  return CallLoweringInfo.get();
268 }
269 
271  return Legalizer.get();
272 }
273 
275  return RegBankInfo.get();
276 }
277 
279  return InstSelector.get();
280 }
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:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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:43
This class provides legalization strategies.
const MipsABIInfo & getABI() const
bool IsN64() const
Definition: MipsABIInfo.h:44
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:423
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:42
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:44
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.
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:133
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:59
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:49
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:123
bool isFP64bit() const
bool hasMSA() const