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