MipsSubtarget.cpp revision 360784
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"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/TargetRegistry.h"
26#include "llvm/Support/raw_ostream.h"
27
28using 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//
38static 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
44static 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
49static cl::opt<bool> Mips16HardFloat("mips16-hard-float", cl::NotHidden,
50                                     cl::desc("Enable mips16 hard float."),
51                                     cl::init(false));
52
53static cl::opt<bool>
54    Mips16ConstantIslands("mips16-constant-islands", cl::NotHidden,
55                          cl::desc("Enable mips16 constant islands."),
56                          cl::init(true));
57
58static cl::opt<bool>
59    GPOpt("mgpopt", cl::Hidden,
60          cl::desc("Enable gp-relative addressing of mips small data items"));
61
62bool MipsSubtarget::DspWarningPrinted = false;
63bool MipsSubtarget::MSAWarningPrinted = false;
64bool MipsSubtarget::VirtWarningPrinted = false;
65bool MipsSubtarget::CRCWarningPrinted = false;
66bool MipsSubtarget::GINVWarningPrinted = false;
67
68void MipsSubtarget::anchor() {}
69
70MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
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      HasCnMipsP(false), HasMips3_32(false), HasMips3_32r2(false),
78      HasMips4_32(false), HasMips4_32r2(false), HasMips5_32r2(false),
79      InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
80      InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), HasDSPR3(false),
81      AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false),
82      UseTCCInDIV(false), HasSym32(false), HasEVA(false), DisableMadd4(false),
83      HasMT(false), HasCRC(false), HasVirt(false), HasGINV(false),
84      UseIndirectJumpsHazard(false), 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 (isFP64bit() && !hasMips64() && hasMips32() && !hasMips32r2())
112    report_fatal_error(
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)
130      report_fatal_error(
131          "cannot combine indirect jumps with hazard barriers and microMIPS");
132    if (!hasMips32r2())
133      report_fatal_error(
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());
147    assert(inAbs2008Mode());
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
211  CallLoweringInfo.reset(new MipsCallLowering(*getTargetLowering()));
212  Legalizer.reset(new MipsLegalizerInfo(*this));
213
214  auto *RBI = new MipsRegisterBankInfo(*getRegisterInfo());
215  RegBankInfo.reset(RBI);
216  InstSelector.reset(createMipsInstructionSelector(
217      *static_cast<const MipsTargetMachine *>(&TM), *this, *RBI));
218}
219
220bool MipsSubtarget::isPositionIndependent() const {
221  return TM.isPositionIndependent();
222}
223
224/// This overrides the PostRAScheduler bit in the SchedModel for any CPU.
225bool MipsSubtarget::enablePostRAScheduler() const { return true; }
226
227void MipsSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
228  CriticalPathRCs.clear();
229  CriticalPathRCs.push_back(isGP64bit() ? &Mips::GPR64RegClass
230                                        : &Mips::GPR32RegClass);
231}
232
233CodeGenOpt::Level MipsSubtarget::getOptLevelToEnablePostRAScheduler() const {
234  return CodeGenOpt::Aggressive;
235}
236
237MipsSubtarget &
238MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
239                                               const TargetMachine &TM) {
240  std::string CPUName = MIPS_MC::selectMipsCPU(TM.getTargetTriple(), CPU);
241
242  // Parse features string.
243  ParseSubtargetFeatures(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
266bool MipsSubtarget::useConstantIslands() {
267  LLVM_DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands
268                    << "\n");
269  return Mips16ConstantIslands;
270}
271
272Reloc::Model MipsSubtarget::getRelocationModel() const {
273  return TM.getRelocationModel();
274}
275
276bool MipsSubtarget::isABI_N64() const { return getABI().IsN64(); }
277bool MipsSubtarget::isABI_N32() const { return getABI().IsN32(); }
278bool MipsSubtarget::isABI_O32() const { return getABI().IsO32(); }
279const MipsABIInfo &MipsSubtarget::getABI() const { return TM.getABI(); }
280
281const CallLowering *MipsSubtarget::getCallLowering() const {
282  return CallLoweringInfo.get();
283}
284
285const LegalizerInfo *MipsSubtarget::getLegalizerInfo() const {
286  return Legalizer.get();
287}
288
289const RegisterBankInfo *MipsSubtarget::getRegBankInfo() const {
290  return RegBankInfo.get();
291}
292
293InstructionSelector *MipsSubtarget::getInstructionSelector() const {
294  return InstSelector.get();
295}
296