xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsSubtarget.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- MipsSubtarget.h - Define Subtarget for the Mips ---------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file declares the Mips specific subclass of TargetSubtargetInfo.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H
14*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h"
17*0b57cec5SDimitry Andric #include "MipsFrameLowering.h"
18*0b57cec5SDimitry Andric #include "MipsISelLowering.h"
19*0b57cec5SDimitry Andric #include "MipsInstrInfo.h"
20*0b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
21*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
22*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h"
23*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
24*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
25*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
26*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
27*0b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h"
28*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
29*0b57cec5SDimitry Andric #include <string>
30*0b57cec5SDimitry Andric 
31*0b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER
32*0b57cec5SDimitry Andric #include "MipsGenSubtargetInfo.inc"
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric namespace llvm {
35*0b57cec5SDimitry Andric class StringRef;
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric class MipsTargetMachine;
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric class MipsSubtarget : public MipsGenSubtargetInfo {
40*0b57cec5SDimitry Andric   virtual void anchor();
41*0b57cec5SDimitry Andric 
42*0b57cec5SDimitry Andric   enum MipsArchEnum {
43*0b57cec5SDimitry Andric     MipsDefault,
44*0b57cec5SDimitry Andric     Mips1, Mips2, Mips32, Mips32r2, Mips32r3, Mips32r5, Mips32r6, Mips32Max,
45*0b57cec5SDimitry Andric     Mips3, Mips4, Mips5, Mips64, Mips64r2, Mips64r3, Mips64r5, Mips64r6
46*0b57cec5SDimitry Andric   };
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric   enum class CPU { P5600 };
49*0b57cec5SDimitry Andric 
50*0b57cec5SDimitry Andric   // Used to avoid printing dsp warnings multiple times.
51*0b57cec5SDimitry Andric   static bool DspWarningPrinted;
52*0b57cec5SDimitry Andric 
53*0b57cec5SDimitry Andric   // Used to avoid printing msa warnings multiple times.
54*0b57cec5SDimitry Andric   static bool MSAWarningPrinted;
55*0b57cec5SDimitry Andric 
56*0b57cec5SDimitry Andric   // Used to avoid printing crc warnings multiple times.
57*0b57cec5SDimitry Andric   static bool CRCWarningPrinted;
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric   // Used to avoid printing ginv warnings multiple times.
60*0b57cec5SDimitry Andric   static bool GINVWarningPrinted;
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   // Used to avoid printing virt warnings multiple times.
63*0b57cec5SDimitry Andric   static bool VirtWarningPrinted;
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric   // Mips architecture version
66*0b57cec5SDimitry Andric   MipsArchEnum MipsArchVersion;
67*0b57cec5SDimitry Andric 
68*0b57cec5SDimitry Andric   // Processor implementation (unused but required to exist by
69*0b57cec5SDimitry Andric   // tablegen-erated code).
70*0b57cec5SDimitry Andric   CPU ProcImpl;
71*0b57cec5SDimitry Andric 
72*0b57cec5SDimitry Andric   // IsLittle - The target is Little Endian
73*0b57cec5SDimitry Andric   bool IsLittle;
74*0b57cec5SDimitry Andric 
75*0b57cec5SDimitry Andric   // IsSoftFloat - The target does not support any floating point instructions.
76*0b57cec5SDimitry Andric   bool IsSoftFloat;
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric   // IsSingleFloat - The target only supports single precision float
79*0b57cec5SDimitry Andric   // point operations. This enable the target to use all 32 32-bit
80*0b57cec5SDimitry Andric   // floating point registers instead of only using even ones.
81*0b57cec5SDimitry Andric   bool IsSingleFloat;
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric   // IsFPXX - MIPS O32 modeless ABI.
84*0b57cec5SDimitry Andric   bool IsFPXX;
85*0b57cec5SDimitry Andric 
86*0b57cec5SDimitry Andric   // NoABICalls - Disable SVR4-style position-independent code.
87*0b57cec5SDimitry Andric   bool NoABICalls;
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric   // Abs2008 - Use IEEE 754-2008 abs.fmt instruction.
90*0b57cec5SDimitry Andric   bool Abs2008;
91*0b57cec5SDimitry Andric 
92*0b57cec5SDimitry Andric   // IsFP64bit - The target processor has 64-bit floating point registers.
93*0b57cec5SDimitry Andric   bool IsFP64bit;
94*0b57cec5SDimitry Andric 
95*0b57cec5SDimitry Andric   /// Are odd single-precision registers permitted?
96*0b57cec5SDimitry Andric   /// This corresponds to -modd-spreg and -mno-odd-spreg
97*0b57cec5SDimitry Andric   bool UseOddSPReg;
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric   // IsNan2008 - IEEE 754-2008 NaN encoding.
100*0b57cec5SDimitry Andric   bool IsNaN2008bit;
101*0b57cec5SDimitry Andric 
102*0b57cec5SDimitry Andric   // IsGP64bit - General-purpose registers are 64 bits wide
103*0b57cec5SDimitry Andric   bool IsGP64bit;
104*0b57cec5SDimitry Andric 
105*0b57cec5SDimitry Andric   // IsPTR64bit - Pointers are 64 bit wide
106*0b57cec5SDimitry Andric   bool IsPTR64bit;
107*0b57cec5SDimitry Andric 
108*0b57cec5SDimitry Andric   // HasVFPU - Processor has a vector floating point unit.
109*0b57cec5SDimitry Andric   bool HasVFPU;
110*0b57cec5SDimitry Andric 
111*0b57cec5SDimitry Andric   // CPU supports cnMIPS (Cavium Networks Octeon CPU).
112*0b57cec5SDimitry Andric   bool HasCnMips;
113*0b57cec5SDimitry Andric 
114*0b57cec5SDimitry Andric   // CPU supports cnMIPSP (Cavium Networks Octeon+ CPU).
115*0b57cec5SDimitry Andric   bool HasCnMipsP;
116*0b57cec5SDimitry Andric 
117*0b57cec5SDimitry Andric   // isLinux - Target system is Linux. Is false we consider ELFOS for now.
118*0b57cec5SDimitry Andric   bool IsLinux;
119*0b57cec5SDimitry Andric 
120*0b57cec5SDimitry Andric   // UseSmallSection - Small section is used.
121*0b57cec5SDimitry Andric   bool UseSmallSection;
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric   /// Features related to the presence of specific instructions.
124*0b57cec5SDimitry Andric 
125*0b57cec5SDimitry Andric   // HasMips3_32 - The subset of MIPS-III instructions added to MIPS32
126*0b57cec5SDimitry Andric   bool HasMips3_32;
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric   // HasMips3_32r2 - The subset of MIPS-III instructions added to MIPS32r2
129*0b57cec5SDimitry Andric   bool HasMips3_32r2;
130*0b57cec5SDimitry Andric 
131*0b57cec5SDimitry Andric   // HasMips4_32 - Has the subset of MIPS-IV present in MIPS32
132*0b57cec5SDimitry Andric   bool HasMips4_32;
133*0b57cec5SDimitry Andric 
134*0b57cec5SDimitry Andric   // HasMips4_32r2 - Has the subset of MIPS-IV present in MIPS32r2
135*0b57cec5SDimitry Andric   bool HasMips4_32r2;
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric   // HasMips5_32r2 - Has the subset of MIPS-V present in MIPS32r2
138*0b57cec5SDimitry Andric   bool HasMips5_32r2;
139*0b57cec5SDimitry Andric 
140*0b57cec5SDimitry Andric   // InMips16 -- can process Mips16 instructions
141*0b57cec5SDimitry Andric   bool InMips16Mode;
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric   // Mips16 hard float
144*0b57cec5SDimitry Andric   bool InMips16HardFloat;
145*0b57cec5SDimitry Andric 
146*0b57cec5SDimitry Andric   // InMicroMips -- can process MicroMips instructions
147*0b57cec5SDimitry Andric   bool InMicroMipsMode;
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric   // HasDSP, HasDSPR2, HasDSPR3 -- supports DSP ASE.
150*0b57cec5SDimitry Andric   bool HasDSP, HasDSPR2, HasDSPR3;
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric   // Allow mixed Mips16 and Mips32 in one source file
153*0b57cec5SDimitry Andric   bool AllowMixed16_32;
154*0b57cec5SDimitry Andric 
155*0b57cec5SDimitry Andric   // Optimize for space by compiling all functions as Mips 16 unless
156*0b57cec5SDimitry Andric   // it needs floating point. Functions needing floating point are
157*0b57cec5SDimitry Andric   // compiled as Mips32
158*0b57cec5SDimitry Andric   bool Os16;
159*0b57cec5SDimitry Andric 
160*0b57cec5SDimitry Andric   // HasMSA -- supports MSA ASE.
161*0b57cec5SDimitry Andric   bool HasMSA;
162*0b57cec5SDimitry Andric 
163*0b57cec5SDimitry Andric   // UseTCCInDIV -- Enables the use of trapping in the assembler.
164*0b57cec5SDimitry Andric   bool UseTCCInDIV;
165*0b57cec5SDimitry Andric 
166*0b57cec5SDimitry Andric   // Sym32 -- On Mips64 symbols are 32 bits.
167*0b57cec5SDimitry Andric   bool HasSym32;
168*0b57cec5SDimitry Andric 
169*0b57cec5SDimitry Andric   // HasEVA -- supports EVA ASE.
170*0b57cec5SDimitry Andric   bool HasEVA;
171*0b57cec5SDimitry Andric 
172*0b57cec5SDimitry Andric   // nomadd4 - disables generation of 4-operand madd.s, madd.d and
173*0b57cec5SDimitry Andric   // related instructions.
174*0b57cec5SDimitry Andric   bool DisableMadd4;
175*0b57cec5SDimitry Andric 
176*0b57cec5SDimitry Andric   // HasMT -- support MT ASE.
177*0b57cec5SDimitry Andric   bool HasMT;
178*0b57cec5SDimitry Andric 
179*0b57cec5SDimitry Andric   // HasCRC -- supports R6 CRC ASE
180*0b57cec5SDimitry Andric   bool HasCRC;
181*0b57cec5SDimitry Andric 
182*0b57cec5SDimitry Andric   // HasVirt -- supports Virtualization ASE
183*0b57cec5SDimitry Andric   bool HasVirt;
184*0b57cec5SDimitry Andric 
185*0b57cec5SDimitry Andric   // HasGINV -- supports R6 Global INValidate ASE
186*0b57cec5SDimitry Andric   bool HasGINV;
187*0b57cec5SDimitry Andric 
188*0b57cec5SDimitry Andric   // Use hazard variants of the jump register instructions for indirect
189*0b57cec5SDimitry Andric   // function calls and jump tables.
190*0b57cec5SDimitry Andric   bool UseIndirectJumpsHazard;
191*0b57cec5SDimitry Andric 
192*0b57cec5SDimitry Andric   // Disable use of the `jal` instruction.
193*0b57cec5SDimitry Andric   bool UseLongCalls = false;
194*0b57cec5SDimitry Andric 
195*0b57cec5SDimitry Andric   /// The minimum alignment known to hold of the stack frame on
196*0b57cec5SDimitry Andric   /// entry to the function and which must be maintained by every function.
197*0b57cec5SDimitry Andric   unsigned stackAlignment;
198*0b57cec5SDimitry Andric 
199*0b57cec5SDimitry Andric   /// The overridden stack alignment.
200*0b57cec5SDimitry Andric   unsigned StackAlignOverride;
201*0b57cec5SDimitry Andric 
202*0b57cec5SDimitry Andric   InstrItineraryData InstrItins;
203*0b57cec5SDimitry Andric 
204*0b57cec5SDimitry Andric   // We can override the determination of whether we are in mips16 mode
205*0b57cec5SDimitry Andric   // as from the command line
206*0b57cec5SDimitry Andric   enum {NoOverride, Mips16Override, NoMips16Override} OverrideMode;
207*0b57cec5SDimitry Andric 
208*0b57cec5SDimitry Andric   const MipsTargetMachine &TM;
209*0b57cec5SDimitry Andric 
210*0b57cec5SDimitry Andric   Triple TargetTriple;
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   const SelectionDAGTargetInfo TSInfo;
213*0b57cec5SDimitry Andric   std::unique_ptr<const MipsInstrInfo> InstrInfo;
214*0b57cec5SDimitry Andric   std::unique_ptr<const MipsFrameLowering> FrameLowering;
215*0b57cec5SDimitry Andric   std::unique_ptr<const MipsTargetLowering> TLInfo;
216*0b57cec5SDimitry Andric 
217*0b57cec5SDimitry Andric public:
218*0b57cec5SDimitry Andric   bool isPositionIndependent() const;
219*0b57cec5SDimitry Andric   /// This overrides the PostRAScheduler bit in the SchedModel for each CPU.
220*0b57cec5SDimitry Andric   bool enablePostRAScheduler() const override;
221*0b57cec5SDimitry Andric   void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override;
222*0b57cec5SDimitry Andric   CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override;
223*0b57cec5SDimitry Andric 
224*0b57cec5SDimitry Andric   bool isABI_N64() const;
225*0b57cec5SDimitry Andric   bool isABI_N32() const;
226*0b57cec5SDimitry Andric   bool isABI_O32() const;
227*0b57cec5SDimitry Andric   const MipsABIInfo &getABI() const;
228*0b57cec5SDimitry Andric   bool isABI_FPXX() const { return isABI_O32() && IsFPXX; }
229*0b57cec5SDimitry Andric 
230*0b57cec5SDimitry Andric   /// This constructor initializes the data members to match that
231*0b57cec5SDimitry Andric   /// of the specified triple.
232*0b57cec5SDimitry Andric   MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little,
233*0b57cec5SDimitry Andric                 const MipsTargetMachine &TM, unsigned StackAlignOverride);
234*0b57cec5SDimitry Andric 
235*0b57cec5SDimitry Andric   /// ParseSubtargetFeatures - Parses features string setting specified
236*0b57cec5SDimitry Andric   /// subtarget options.  Definition of function is auto generated by tblgen.
237*0b57cec5SDimitry Andric   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
238*0b57cec5SDimitry Andric 
239*0b57cec5SDimitry Andric   bool hasMips1() const { return MipsArchVersion >= Mips1; }
240*0b57cec5SDimitry Andric   bool hasMips2() const { return MipsArchVersion >= Mips2; }
241*0b57cec5SDimitry Andric   bool hasMips3() const { return MipsArchVersion >= Mips3; }
242*0b57cec5SDimitry Andric   bool hasMips4() const { return MipsArchVersion >= Mips4; }
243*0b57cec5SDimitry Andric   bool hasMips5() const { return MipsArchVersion >= Mips5; }
244*0b57cec5SDimitry Andric   bool hasMips4_32() const { return HasMips4_32; }
245*0b57cec5SDimitry Andric   bool hasMips4_32r2() const { return HasMips4_32r2; }
246*0b57cec5SDimitry Andric   bool hasMips32() const {
247*0b57cec5SDimitry Andric     return (MipsArchVersion >= Mips32 && MipsArchVersion < Mips32Max) ||
248*0b57cec5SDimitry Andric            hasMips64();
249*0b57cec5SDimitry Andric   }
250*0b57cec5SDimitry Andric   bool hasMips32r2() const {
251*0b57cec5SDimitry Andric     return (MipsArchVersion >= Mips32r2 && MipsArchVersion < Mips32Max) ||
252*0b57cec5SDimitry Andric            hasMips64r2();
253*0b57cec5SDimitry Andric   }
254*0b57cec5SDimitry Andric   bool hasMips32r3() const {
255*0b57cec5SDimitry Andric     return (MipsArchVersion >= Mips32r3 && MipsArchVersion < Mips32Max) ||
256*0b57cec5SDimitry Andric            hasMips64r2();
257*0b57cec5SDimitry Andric   }
258*0b57cec5SDimitry Andric   bool hasMips32r5() const {
259*0b57cec5SDimitry Andric     return (MipsArchVersion >= Mips32r5 && MipsArchVersion < Mips32Max) ||
260*0b57cec5SDimitry Andric            hasMips64r5();
261*0b57cec5SDimitry Andric   }
262*0b57cec5SDimitry Andric   bool hasMips32r6() const {
263*0b57cec5SDimitry Andric     return (MipsArchVersion >= Mips32r6 && MipsArchVersion < Mips32Max) ||
264*0b57cec5SDimitry Andric            hasMips64r6();
265*0b57cec5SDimitry Andric   }
266*0b57cec5SDimitry Andric   bool hasMips64() const { return MipsArchVersion >= Mips64; }
267*0b57cec5SDimitry Andric   bool hasMips64r2() const { return MipsArchVersion >= Mips64r2; }
268*0b57cec5SDimitry Andric   bool hasMips64r3() const { return MipsArchVersion >= Mips64r3; }
269*0b57cec5SDimitry Andric   bool hasMips64r5() const { return MipsArchVersion >= Mips64r5; }
270*0b57cec5SDimitry Andric   bool hasMips64r6() const { return MipsArchVersion >= Mips64r6; }
271*0b57cec5SDimitry Andric 
272*0b57cec5SDimitry Andric   bool hasCnMips() const { return HasCnMips; }
273*0b57cec5SDimitry Andric   bool hasCnMipsP() const { return HasCnMipsP; }
274*0b57cec5SDimitry Andric 
275*0b57cec5SDimitry Andric   bool isLittle() const { return IsLittle; }
276*0b57cec5SDimitry Andric   bool isABICalls() const { return !NoABICalls; }
277*0b57cec5SDimitry Andric   bool isFPXX() const { return IsFPXX; }
278*0b57cec5SDimitry Andric   bool isFP64bit() const { return IsFP64bit; }
279*0b57cec5SDimitry Andric   bool useOddSPReg() const { return UseOddSPReg; }
280*0b57cec5SDimitry Andric   bool noOddSPReg() const { return !UseOddSPReg; }
281*0b57cec5SDimitry Andric   bool isNaN2008() const { return IsNaN2008bit; }
282*0b57cec5SDimitry Andric   bool inAbs2008Mode() const { return Abs2008; }
283*0b57cec5SDimitry Andric   bool isGP64bit() const { return IsGP64bit; }
284*0b57cec5SDimitry Andric   bool isGP32bit() const { return !IsGP64bit; }
285*0b57cec5SDimitry Andric   unsigned getGPRSizeInBytes() const { return isGP64bit() ? 8 : 4; }
286*0b57cec5SDimitry Andric   bool isPTR64bit() const { return IsPTR64bit; }
287*0b57cec5SDimitry Andric   bool isPTR32bit() const { return !IsPTR64bit; }
288*0b57cec5SDimitry Andric   bool hasSym32() const {
289*0b57cec5SDimitry Andric     return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32();
290*0b57cec5SDimitry Andric   }
291*0b57cec5SDimitry Andric   bool isSingleFloat() const { return IsSingleFloat; }
292*0b57cec5SDimitry Andric   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
293*0b57cec5SDimitry Andric   bool hasVFPU() const { return HasVFPU; }
294*0b57cec5SDimitry Andric   bool inMips16Mode() const { return InMips16Mode; }
295*0b57cec5SDimitry Andric   bool inMips16ModeDefault() const {
296*0b57cec5SDimitry Andric     return InMips16Mode;
297*0b57cec5SDimitry Andric   }
298*0b57cec5SDimitry Andric   // Hard float for mips16 means essentially to compile as soft float
299*0b57cec5SDimitry Andric   // but to use a runtime library for soft float that is written with
300*0b57cec5SDimitry Andric   // native mips32 floating point instructions (those runtime routines
301*0b57cec5SDimitry Andric   // run in mips32 hard float mode).
302*0b57cec5SDimitry Andric   bool inMips16HardFloat() const {
303*0b57cec5SDimitry Andric     return inMips16Mode() && InMips16HardFloat;
304*0b57cec5SDimitry Andric   }
305*0b57cec5SDimitry Andric   bool inMicroMipsMode() const { return InMicroMipsMode && !InMips16Mode; }
306*0b57cec5SDimitry Andric   bool inMicroMips32r6Mode() const {
307*0b57cec5SDimitry Andric     return inMicroMipsMode() && hasMips32r6();
308*0b57cec5SDimitry Andric   }
309*0b57cec5SDimitry Andric   bool hasDSP() const { return HasDSP; }
310*0b57cec5SDimitry Andric   bool hasDSPR2() const { return HasDSPR2; }
311*0b57cec5SDimitry Andric   bool hasDSPR3() const { return HasDSPR3; }
312*0b57cec5SDimitry Andric   bool hasMSA() const { return HasMSA; }
313*0b57cec5SDimitry Andric   bool disableMadd4() const { return DisableMadd4; }
314*0b57cec5SDimitry Andric   bool hasEVA() const { return HasEVA; }
315*0b57cec5SDimitry Andric   bool hasMT() const { return HasMT; }
316*0b57cec5SDimitry Andric   bool hasCRC() const { return HasCRC; }
317*0b57cec5SDimitry Andric   bool hasVirt() const { return HasVirt; }
318*0b57cec5SDimitry Andric   bool hasGINV() const { return HasGINV; }
319*0b57cec5SDimitry Andric   bool useIndirectJumpsHazard() const {
320*0b57cec5SDimitry Andric     return UseIndirectJumpsHazard && hasMips32r2();
321*0b57cec5SDimitry Andric   }
322*0b57cec5SDimitry Andric   bool useSmallSection() const { return UseSmallSection; }
323*0b57cec5SDimitry Andric 
324*0b57cec5SDimitry Andric   bool hasStandardEncoding() const { return !InMips16Mode && !InMicroMipsMode; }
325*0b57cec5SDimitry Andric 
326*0b57cec5SDimitry Andric   bool useSoftFloat() const { return IsSoftFloat; }
327*0b57cec5SDimitry Andric 
328*0b57cec5SDimitry Andric   bool useLongCalls() const { return UseLongCalls; }
329*0b57cec5SDimitry Andric 
330*0b57cec5SDimitry Andric   bool enableLongBranchPass() const {
331*0b57cec5SDimitry Andric     return hasStandardEncoding() || inMicroMipsMode() || allowMixed16_32();
332*0b57cec5SDimitry Andric   }
333*0b57cec5SDimitry Andric 
334*0b57cec5SDimitry Andric   /// Features related to the presence of specific instructions.
335*0b57cec5SDimitry Andric   bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); }
336*0b57cec5SDimitry Andric   bool hasMTHC1() const { return hasMips32r2(); }
337*0b57cec5SDimitry Andric 
338*0b57cec5SDimitry Andric   bool allowMixed16_32() const { return inMips16ModeDefault() |
339*0b57cec5SDimitry Andric                                         AllowMixed16_32; }
340*0b57cec5SDimitry Andric 
341*0b57cec5SDimitry Andric   bool os16() const { return Os16; }
342*0b57cec5SDimitry Andric 
343*0b57cec5SDimitry Andric   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
344*0b57cec5SDimitry Andric 
345*0b57cec5SDimitry Andric   bool isXRaySupported() const override { return true; }
346*0b57cec5SDimitry Andric 
347*0b57cec5SDimitry Andric   // for now constant islands are on for the whole compilation unit but we only
348*0b57cec5SDimitry Andric   // really use them if in addition we are in mips16 mode
349*0b57cec5SDimitry Andric   static bool useConstantIslands();
350*0b57cec5SDimitry Andric 
351*0b57cec5SDimitry Andric   unsigned getStackAlignment() const { return stackAlignment; }
352*0b57cec5SDimitry Andric 
353*0b57cec5SDimitry Andric   // Grab relocation model
354*0b57cec5SDimitry Andric   Reloc::Model getRelocationModel() const;
355*0b57cec5SDimitry Andric 
356*0b57cec5SDimitry Andric   MipsSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS,
357*0b57cec5SDimitry Andric                                                  const TargetMachine &TM);
358*0b57cec5SDimitry Andric 
359*0b57cec5SDimitry Andric   /// Does the system support unaligned memory access.
360*0b57cec5SDimitry Andric   ///
361*0b57cec5SDimitry Andric   /// MIPS32r6/MIPS64r6 require full unaligned access support but does not
362*0b57cec5SDimitry Andric   /// specify which component of the system provides it. Hardware, software, and
363*0b57cec5SDimitry Andric   /// hybrid implementations are all valid.
364*0b57cec5SDimitry Andric   bool systemSupportsUnalignedAccess() const { return hasMips32r6(); }
365*0b57cec5SDimitry Andric 
366*0b57cec5SDimitry Andric   // Set helper classes
367*0b57cec5SDimitry Andric   void setHelperClassesMips16();
368*0b57cec5SDimitry Andric   void setHelperClassesMipsSE();
369*0b57cec5SDimitry Andric 
370*0b57cec5SDimitry Andric   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
371*0b57cec5SDimitry Andric     return &TSInfo;
372*0b57cec5SDimitry Andric   }
373*0b57cec5SDimitry Andric   const MipsInstrInfo *getInstrInfo() const override { return InstrInfo.get(); }
374*0b57cec5SDimitry Andric   const TargetFrameLowering *getFrameLowering() const override {
375*0b57cec5SDimitry Andric     return FrameLowering.get();
376*0b57cec5SDimitry Andric   }
377*0b57cec5SDimitry Andric   const MipsRegisterInfo *getRegisterInfo() const override {
378*0b57cec5SDimitry Andric     return &InstrInfo->getRegisterInfo();
379*0b57cec5SDimitry Andric   }
380*0b57cec5SDimitry Andric   const MipsTargetLowering *getTargetLowering() const override {
381*0b57cec5SDimitry Andric     return TLInfo.get();
382*0b57cec5SDimitry Andric   }
383*0b57cec5SDimitry Andric   const InstrItineraryData *getInstrItineraryData() const override {
384*0b57cec5SDimitry Andric     return &InstrItins;
385*0b57cec5SDimitry Andric   }
386*0b57cec5SDimitry Andric 
387*0b57cec5SDimitry Andric protected:
388*0b57cec5SDimitry Andric   // GlobalISel related APIs.
389*0b57cec5SDimitry Andric   std::unique_ptr<CallLowering> CallLoweringInfo;
390*0b57cec5SDimitry Andric   std::unique_ptr<LegalizerInfo> Legalizer;
391*0b57cec5SDimitry Andric   std::unique_ptr<RegisterBankInfo> RegBankInfo;
392*0b57cec5SDimitry Andric   std::unique_ptr<InstructionSelector> InstSelector;
393*0b57cec5SDimitry Andric 
394*0b57cec5SDimitry Andric public:
395*0b57cec5SDimitry Andric   const CallLowering *getCallLowering() const override;
396*0b57cec5SDimitry Andric   const LegalizerInfo *getLegalizerInfo() const override;
397*0b57cec5SDimitry Andric   const RegisterBankInfo *getRegBankInfo() const override;
398*0b57cec5SDimitry Andric   const InstructionSelector *getInstructionSelector() const override;
399*0b57cec5SDimitry Andric };
400*0b57cec5SDimitry Andric } // End llvm namespace
401*0b57cec5SDimitry Andric 
402*0b57cec5SDimitry Andric #endif
403