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