10b57cec5SDimitry Andric //===-- MipsSubtarget.h - Define Subtarget for the Mips ---------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares the Mips specific subclass of TargetSubtargetInfo. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h" 170b57cec5SDimitry Andric #include "MipsFrameLowering.h" 180b57cec5SDimitry Andric #include "MipsISelLowering.h" 190b57cec5SDimitry Andric #include "MipsInstrInfo.h" 2081ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 2181ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 2281ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 2381ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 260b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h" 280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER 310b57cec5SDimitry Andric #include "MipsGenSubtargetInfo.inc" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric namespace llvm { 340b57cec5SDimitry Andric class StringRef; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric class MipsTargetMachine; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric class MipsSubtarget : public MipsGenSubtargetInfo { 390b57cec5SDimitry Andric virtual void anchor(); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric enum MipsArchEnum { 420b57cec5SDimitry Andric MipsDefault, 430b57cec5SDimitry Andric Mips1, Mips2, Mips32, Mips32r2, Mips32r3, Mips32r5, Mips32r6, Mips32Max, 440b57cec5SDimitry Andric Mips3, Mips4, Mips5, Mips64, Mips64r2, Mips64r3, Mips64r5, Mips64r6 450b57cec5SDimitry Andric }; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric enum class CPU { P5600 }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // Used to avoid printing dsp warnings multiple times. 500b57cec5SDimitry Andric static bool DspWarningPrinted; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric // Used to avoid printing msa warnings multiple times. 530b57cec5SDimitry Andric static bool MSAWarningPrinted; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric // Used to avoid printing crc warnings multiple times. 560b57cec5SDimitry Andric static bool CRCWarningPrinted; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric // Used to avoid printing ginv warnings multiple times. 590b57cec5SDimitry Andric static bool GINVWarningPrinted; 600b57cec5SDimitry Andric 6181ad6265SDimitry Andric // Used to avoid printing Mips1 warnings multiple times. 6281ad6265SDimitry Andric static bool MIPS1WarningPrinted; 6381ad6265SDimitry Andric 640b57cec5SDimitry Andric // Used to avoid printing virt warnings multiple times. 650b57cec5SDimitry Andric static bool VirtWarningPrinted; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // Mips architecture version 680b57cec5SDimitry Andric MipsArchEnum MipsArchVersion; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // Processor implementation (unused but required to exist by 710b57cec5SDimitry Andric // tablegen-erated code). 720b57cec5SDimitry Andric CPU ProcImpl; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // IsLittle - The target is Little Endian 750b57cec5SDimitry Andric bool IsLittle; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // IsSoftFloat - The target does not support any floating point instructions. 780b57cec5SDimitry Andric bool IsSoftFloat; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric // IsSingleFloat - The target only supports single precision float 810b57cec5SDimitry Andric // point operations. This enable the target to use all 32 32-bit 820b57cec5SDimitry Andric // floating point registers instead of only using even ones. 830b57cec5SDimitry Andric bool IsSingleFloat; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric // IsFPXX - MIPS O32 modeless ABI. 860b57cec5SDimitry Andric bool IsFPXX; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // NoABICalls - Disable SVR4-style position-independent code. 890b57cec5SDimitry Andric bool NoABICalls; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric // Abs2008 - Use IEEE 754-2008 abs.fmt instruction. 920b57cec5SDimitry Andric bool Abs2008; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // IsFP64bit - The target processor has 64-bit floating point registers. 950b57cec5SDimitry Andric bool IsFP64bit; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric /// Are odd single-precision registers permitted? 980b57cec5SDimitry Andric /// This corresponds to -modd-spreg and -mno-odd-spreg 990b57cec5SDimitry Andric bool UseOddSPReg; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // IsNan2008 - IEEE 754-2008 NaN encoding. 1020b57cec5SDimitry Andric bool IsNaN2008bit; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // IsGP64bit - General-purpose registers are 64 bits wide 1050b57cec5SDimitry Andric bool IsGP64bit; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric // IsPTR64bit - Pointers are 64 bit wide 1080b57cec5SDimitry Andric bool IsPTR64bit; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric // HasVFPU - Processor has a vector floating point unit. 1110b57cec5SDimitry Andric bool HasVFPU; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // CPU supports cnMIPS (Cavium Networks Octeon CPU). 1140b57cec5SDimitry Andric bool HasCnMips; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // CPU supports cnMIPSP (Cavium Networks Octeon+ CPU). 1170b57cec5SDimitry Andric bool HasCnMipsP; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric // isLinux - Target system is Linux. Is false we consider ELFOS for now. 1200b57cec5SDimitry Andric bool IsLinux; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric // UseSmallSection - Small section is used. 1230b57cec5SDimitry Andric bool UseSmallSection; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// Features related to the presence of specific instructions. 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // HasMips3_32 - The subset of MIPS-III instructions added to MIPS32 1280b57cec5SDimitry Andric bool HasMips3_32; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // HasMips3_32r2 - The subset of MIPS-III instructions added to MIPS32r2 1310b57cec5SDimitry Andric bool HasMips3_32r2; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric // HasMips4_32 - Has the subset of MIPS-IV present in MIPS32 1340b57cec5SDimitry Andric bool HasMips4_32; 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric // HasMips4_32r2 - Has the subset of MIPS-IV present in MIPS32r2 1370b57cec5SDimitry Andric bool HasMips4_32r2; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric // HasMips5_32r2 - Has the subset of MIPS-V present in MIPS32r2 1400b57cec5SDimitry Andric bool HasMips5_32r2; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric // InMips16 -- can process Mips16 instructions 1430b57cec5SDimitry Andric bool InMips16Mode; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric // Mips16 hard float 1460b57cec5SDimitry Andric bool InMips16HardFloat; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric // InMicroMips -- can process MicroMips instructions 1490b57cec5SDimitry Andric bool InMicroMipsMode; 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric // HasDSP, HasDSPR2, HasDSPR3 -- supports DSP ASE. 1520b57cec5SDimitry Andric bool HasDSP, HasDSPR2, HasDSPR3; 1530b57cec5SDimitry Andric 1545ffd83dbSDimitry Andric // Has3D -- Supports Mips3D ASE. 1555ffd83dbSDimitry Andric bool Has3D; 1565ffd83dbSDimitry Andric 1570b57cec5SDimitry Andric // Allow mixed Mips16 and Mips32 in one source file 1580b57cec5SDimitry Andric bool AllowMixed16_32; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric // Optimize for space by compiling all functions as Mips 16 unless 1610b57cec5SDimitry Andric // it needs floating point. Functions needing floating point are 1620b57cec5SDimitry Andric // compiled as Mips32 1630b57cec5SDimitry Andric bool Os16; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // HasMSA -- supports MSA ASE. 1660b57cec5SDimitry Andric bool HasMSA; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // UseTCCInDIV -- Enables the use of trapping in the assembler. 1690b57cec5SDimitry Andric bool UseTCCInDIV; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric // Sym32 -- On Mips64 symbols are 32 bits. 1720b57cec5SDimitry Andric bool HasSym32; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // HasEVA -- supports EVA ASE. 1750b57cec5SDimitry Andric bool HasEVA; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric // nomadd4 - disables generation of 4-operand madd.s, madd.d and 1780b57cec5SDimitry Andric // related instructions. 1790b57cec5SDimitry Andric bool DisableMadd4; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric // HasMT -- support MT ASE. 1820b57cec5SDimitry Andric bool HasMT; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric // HasCRC -- supports R6 CRC ASE 1850b57cec5SDimitry Andric bool HasCRC; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric // HasVirt -- supports Virtualization ASE 1880b57cec5SDimitry Andric bool HasVirt; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // HasGINV -- supports R6 Global INValidate ASE 1910b57cec5SDimitry Andric bool HasGINV; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric // Use hazard variants of the jump register instructions for indirect 1940b57cec5SDimitry Andric // function calls and jump tables. 1950b57cec5SDimitry Andric bool UseIndirectJumpsHazard; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric // Disable use of the `jal` instruction. 1980b57cec5SDimitry Andric bool UseLongCalls = false; 1990b57cec5SDimitry Andric 2008bcb0991SDimitry Andric // Assume 32-bit GOT. 2018bcb0991SDimitry Andric bool UseXGOT = false; 2028bcb0991SDimitry Andric 203*0fca6ea1SDimitry Andric // Disable unaligned load store for r6. 204*0fca6ea1SDimitry Andric bool StrictAlign; 205*0fca6ea1SDimitry Andric 2060b57cec5SDimitry Andric /// The minimum alignment known to hold of the stack frame on 2070b57cec5SDimitry Andric /// entry to the function and which must be maintained by every function. 2088bcb0991SDimitry Andric Align stackAlignment; 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// The overridden stack alignment. 2118bcb0991SDimitry Andric MaybeAlign StackAlignOverride; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric InstrItineraryData InstrItins; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric // We can override the determination of whether we are in mips16 mode 2160b57cec5SDimitry Andric // as from the command line 2170b57cec5SDimitry Andric enum {NoOverride, Mips16Override, NoMips16Override} OverrideMode; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric const MipsTargetMachine &TM; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric Triple TargetTriple; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric const SelectionDAGTargetInfo TSInfo; 2240b57cec5SDimitry Andric std::unique_ptr<const MipsInstrInfo> InstrInfo; 2250b57cec5SDimitry Andric std::unique_ptr<const MipsFrameLowering> FrameLowering; 2260b57cec5SDimitry Andric std::unique_ptr<const MipsTargetLowering> TLInfo; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric public: 2290b57cec5SDimitry Andric bool isPositionIndependent() const; 2300b57cec5SDimitry Andric /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 2310b57cec5SDimitry Andric bool enablePostRAScheduler() const override; 2320b57cec5SDimitry Andric void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 2335f757f3fSDimitry Andric CodeGenOptLevel getOptLevelToEnablePostRAScheduler() const override; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric bool isABI_N64() const; 2360b57cec5SDimitry Andric bool isABI_N32() const; 2370b57cec5SDimitry Andric bool isABI_O32() const; 2380b57cec5SDimitry Andric const MipsABIInfo &getABI() const; 2390b57cec5SDimitry Andric bool isABI_FPXX() const { return isABI_O32() && IsFPXX; } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric /// This constructor initializes the data members to match that 2420b57cec5SDimitry Andric /// of the specified triple. 2430b57cec5SDimitry Andric MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little, 2448bcb0991SDimitry Andric const MipsTargetMachine &TM, MaybeAlign StackAlignOverride); 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric /// ParseSubtargetFeatures - Parses features string setting specified 2470b57cec5SDimitry Andric /// subtarget options. Definition of function is auto generated by tblgen. 248e8d8bef9SDimitry Andric void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric bool hasMips1() const { return MipsArchVersion >= Mips1; } 2510b57cec5SDimitry Andric bool hasMips2() const { return MipsArchVersion >= Mips2; } 2520b57cec5SDimitry Andric bool hasMips3() const { return MipsArchVersion >= Mips3; } 2530b57cec5SDimitry Andric bool hasMips4() const { return MipsArchVersion >= Mips4; } 2540b57cec5SDimitry Andric bool hasMips5() const { return MipsArchVersion >= Mips5; } 2550b57cec5SDimitry Andric bool hasMips4_32() const { return HasMips4_32; } 2560b57cec5SDimitry Andric bool hasMips4_32r2() const { return HasMips4_32r2; } 2570b57cec5SDimitry Andric bool hasMips32() const { 2580b57cec5SDimitry Andric return (MipsArchVersion >= Mips32 && MipsArchVersion < Mips32Max) || 2590b57cec5SDimitry Andric hasMips64(); 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric bool hasMips32r2() const { 2620b57cec5SDimitry Andric return (MipsArchVersion >= Mips32r2 && MipsArchVersion < Mips32Max) || 2630b57cec5SDimitry Andric hasMips64r2(); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric bool hasMips32r3() const { 2660b57cec5SDimitry Andric return (MipsArchVersion >= Mips32r3 && MipsArchVersion < Mips32Max) || 2670b57cec5SDimitry Andric hasMips64r2(); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric bool hasMips32r5() const { 2700b57cec5SDimitry Andric return (MipsArchVersion >= Mips32r5 && MipsArchVersion < Mips32Max) || 2710b57cec5SDimitry Andric hasMips64r5(); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric bool hasMips32r6() const { 2740b57cec5SDimitry Andric return (MipsArchVersion >= Mips32r6 && MipsArchVersion < Mips32Max) || 2750b57cec5SDimitry Andric hasMips64r6(); 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric bool hasMips64() const { return MipsArchVersion >= Mips64; } 2780b57cec5SDimitry Andric bool hasMips64r2() const { return MipsArchVersion >= Mips64r2; } 2790b57cec5SDimitry Andric bool hasMips64r3() const { return MipsArchVersion >= Mips64r3; } 2800b57cec5SDimitry Andric bool hasMips64r5() const { return MipsArchVersion >= Mips64r5; } 2810b57cec5SDimitry Andric bool hasMips64r6() const { return MipsArchVersion >= Mips64r6; } 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric bool hasCnMips() const { return HasCnMips; } 2840b57cec5SDimitry Andric bool hasCnMipsP() const { return HasCnMipsP; } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric bool isLittle() const { return IsLittle; } 2870b57cec5SDimitry Andric bool isABICalls() const { return !NoABICalls; } 2880b57cec5SDimitry Andric bool isFPXX() const { return IsFPXX; } 2890b57cec5SDimitry Andric bool isFP64bit() const { return IsFP64bit; } 2900b57cec5SDimitry Andric bool useOddSPReg() const { return UseOddSPReg; } 2910b57cec5SDimitry Andric bool noOddSPReg() const { return !UseOddSPReg; } 2920b57cec5SDimitry Andric bool isNaN2008() const { return IsNaN2008bit; } 2930b57cec5SDimitry Andric bool inAbs2008Mode() const { return Abs2008; } 2940b57cec5SDimitry Andric bool isGP64bit() const { return IsGP64bit; } 2950b57cec5SDimitry Andric bool isGP32bit() const { return !IsGP64bit; } 2960b57cec5SDimitry Andric unsigned getGPRSizeInBytes() const { return isGP64bit() ? 8 : 4; } 2970b57cec5SDimitry Andric bool isPTR64bit() const { return IsPTR64bit; } 2980b57cec5SDimitry Andric bool isPTR32bit() const { return !IsPTR64bit; } 2990b57cec5SDimitry Andric bool hasSym32() const { 3000b57cec5SDimitry Andric return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32(); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric bool isSingleFloat() const { return IsSingleFloat; } 3030b57cec5SDimitry Andric bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 3040b57cec5SDimitry Andric bool hasVFPU() const { return HasVFPU; } 3050b57cec5SDimitry Andric bool inMips16Mode() const { return InMips16Mode; } 3060b57cec5SDimitry Andric bool inMips16ModeDefault() const { 3070b57cec5SDimitry Andric return InMips16Mode; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric // Hard float for mips16 means essentially to compile as soft float 3100b57cec5SDimitry Andric // but to use a runtime library for soft float that is written with 3110b57cec5SDimitry Andric // native mips32 floating point instructions (those runtime routines 3120b57cec5SDimitry Andric // run in mips32 hard float mode). 3130b57cec5SDimitry Andric bool inMips16HardFloat() const { 3140b57cec5SDimitry Andric return inMips16Mode() && InMips16HardFloat; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric bool inMicroMipsMode() const { return InMicroMipsMode && !InMips16Mode; } 3170b57cec5SDimitry Andric bool inMicroMips32r6Mode() const { 3180b57cec5SDimitry Andric return inMicroMipsMode() && hasMips32r6(); 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric bool hasDSP() const { return HasDSP; } 3210b57cec5SDimitry Andric bool hasDSPR2() const { return HasDSPR2; } 3220b57cec5SDimitry Andric bool hasDSPR3() const { return HasDSPR3; } 3235ffd83dbSDimitry Andric bool has3D() const { return Has3D; } 3240b57cec5SDimitry Andric bool hasMSA() const { return HasMSA; } 3250b57cec5SDimitry Andric bool disableMadd4() const { return DisableMadd4; } 3260b57cec5SDimitry Andric bool hasEVA() const { return HasEVA; } 3270b57cec5SDimitry Andric bool hasMT() const { return HasMT; } 3280b57cec5SDimitry Andric bool hasCRC() const { return HasCRC; } 3290b57cec5SDimitry Andric bool hasVirt() const { return HasVirt; } 3300b57cec5SDimitry Andric bool hasGINV() const { return HasGINV; } 3310b57cec5SDimitry Andric bool useIndirectJumpsHazard() const { 3320b57cec5SDimitry Andric return UseIndirectJumpsHazard && hasMips32r2(); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric bool useSmallSection() const { return UseSmallSection; } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric bool hasStandardEncoding() const { return !InMips16Mode && !InMicroMipsMode; } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric bool useSoftFloat() const { return IsSoftFloat; } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric bool useLongCalls() const { return UseLongCalls; } 3410b57cec5SDimitry Andric 3428bcb0991SDimitry Andric bool useXGOT() const { return UseXGOT; } 3438bcb0991SDimitry Andric 3440b57cec5SDimitry Andric bool enableLongBranchPass() const { 3450b57cec5SDimitry Andric return hasStandardEncoding() || inMicroMipsMode() || allowMixed16_32(); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// Features related to the presence of specific instructions. 3490b57cec5SDimitry Andric bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); } 3500b57cec5SDimitry Andric bool hasMTHC1() const { return hasMips32r2(); } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric bool allowMixed16_32() const { return inMips16ModeDefault() | 3530b57cec5SDimitry Andric AllowMixed16_32; } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric bool os16() const { return Os16; } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric bool isXRaySupported() const override { return true; } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric // for now constant islands are on for the whole compilation unit but we only 3620b57cec5SDimitry Andric // really use them if in addition we are in mips16 mode 3630b57cec5SDimitry Andric static bool useConstantIslands(); 3640b57cec5SDimitry Andric 3658bcb0991SDimitry Andric Align getStackAlignment() const { return stackAlignment; } 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric // Grab relocation model 3680b57cec5SDimitry Andric Reloc::Model getRelocationModel() const; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric MipsSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS, 3710b57cec5SDimitry Andric const TargetMachine &TM); 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric /// Does the system support unaligned memory access. 3740b57cec5SDimitry Andric /// 3750b57cec5SDimitry Andric /// MIPS32r6/MIPS64r6 require full unaligned access support but does not 3760b57cec5SDimitry Andric /// specify which component of the system provides it. Hardware, software, and 3770b57cec5SDimitry Andric /// hybrid implementations are all valid. 378*0fca6ea1SDimitry Andric bool systemSupportsUnalignedAccess() const { 379*0fca6ea1SDimitry Andric return hasMips32r6() && !StrictAlign; 380*0fca6ea1SDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric // Set helper classes 3830b57cec5SDimitry Andric void setHelperClassesMips16(); 3840b57cec5SDimitry Andric void setHelperClassesMipsSE(); 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 3870b57cec5SDimitry Andric return &TSInfo; 3880b57cec5SDimitry Andric } 3890b57cec5SDimitry Andric const MipsInstrInfo *getInstrInfo() const override { return InstrInfo.get(); } 3900b57cec5SDimitry Andric const TargetFrameLowering *getFrameLowering() const override { 3910b57cec5SDimitry Andric return FrameLowering.get(); 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric const MipsRegisterInfo *getRegisterInfo() const override { 3940b57cec5SDimitry Andric return &InstrInfo->getRegisterInfo(); 3950b57cec5SDimitry Andric } 3960b57cec5SDimitry Andric const MipsTargetLowering *getTargetLowering() const override { 3970b57cec5SDimitry Andric return TLInfo.get(); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric const InstrItineraryData *getInstrItineraryData() const override { 4000b57cec5SDimitry Andric return &InstrItins; 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric protected: 4040b57cec5SDimitry Andric // GlobalISel related APIs. 4050b57cec5SDimitry Andric std::unique_ptr<CallLowering> CallLoweringInfo; 4060b57cec5SDimitry Andric std::unique_ptr<LegalizerInfo> Legalizer; 4070b57cec5SDimitry Andric std::unique_ptr<RegisterBankInfo> RegBankInfo; 4080b57cec5SDimitry Andric std::unique_ptr<InstructionSelector> InstSelector; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric public: 4110b57cec5SDimitry Andric const CallLowering *getCallLowering() const override; 4120b57cec5SDimitry Andric const LegalizerInfo *getLegalizerInfo() const override; 4130b57cec5SDimitry Andric const RegisterBankInfo *getRegBankInfo() const override; 4148bcb0991SDimitry Andric InstructionSelector *getInstructionSelector() const override; 4150b57cec5SDimitry Andric }; 4160b57cec5SDimitry Andric } // End llvm namespace 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric #endif 419