#ifndef LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H
#define LLVM_LIB_TARGET_MIPS_MIPSSUBTARGET_H
#include "MCTargetDesc/MipsABIInfo.h"
#include "MipsFrameLowering.h"
#include "MipsISelLowering.h"
#include "MipsInstrInfo.h"
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/RegisterBankInfo.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
#include "MipsGenSubtargetInfo.inc"
namespace llvm {
class StringRef;
class MipsTargetMachine;
class MipsSubtarget : public MipsGenSubtargetInfo {
virtual void anchor();
enum MipsArchEnum {
MipsDefault,
Mips1, Mips2, Mips32, Mips32r2, Mips32r3, Mips32r5, Mips32r6, Mips32Max,
Mips3, Mips4, Mips5, Mips64, Mips64r2, Mips64r3, Mips64r5, Mips64r6
};
enum class CPU { P5600 };
static bool DspWarningPrinted;
static bool MSAWarningPrinted;
static bool CRCWarningPrinted;
static bool GINVWarningPrinted;
static bool MIPS1WarningPrinted;
static bool VirtWarningPrinted;
MipsArchEnum MipsArchVersion;
CPU ProcImpl;
bool IsLittle;
bool IsSoftFloat;
bool IsSingleFloat;
bool IsFPXX;
bool NoABICalls;
bool Abs2008;
bool IsFP64bit;
bool UseOddSPReg;
bool IsNaN2008bit;
bool IsGP64bit;
bool IsPTR64bit;
bool HasVFPU;
bool HasCnMips;
bool HasCnMipsP;
bool IsLinux;
bool UseSmallSection;
bool HasMips3_32;
bool HasMips3_32r2;
bool HasMips4_32;
bool HasMips4_32r2;
bool HasMips5_32r2;
bool InMips16Mode;
bool InMips16HardFloat;
bool InMicroMipsMode;
bool HasDSP, HasDSPR2, HasDSPR3;
bool Has3D;
bool AllowMixed16_32;
bool Os16;
bool HasMSA;
bool UseTCCInDIV;
bool HasSym32;
bool HasEVA;
bool DisableMadd4;
bool HasMT;
bool HasCRC;
bool HasVirt;
bool HasGINV;
bool UseIndirectJumpsHazard;
bool UseLongCalls = false;
bool UseXGOT = false;
Align stackAlignment;
MaybeAlign StackAlignOverride;
InstrItineraryData InstrItins;
enum {NoOverride, Mips16Override, NoMips16Override} OverrideMode;
const MipsTargetMachine &TM;
Triple TargetTriple;
const SelectionDAGTargetInfo TSInfo;
std::unique_ptr<const MipsInstrInfo> InstrInfo;
std::unique_ptr<const MipsFrameLowering> FrameLowering;
std::unique_ptr<const MipsTargetLowering> TLInfo;
public:
bool isPositionIndependent() const;
bool enablePostRAScheduler() const override;
void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override;
CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const override;
bool isABI_N64() const;
bool isABI_N32() const;
bool isABI_O32() const;
const MipsABIInfo &getABI() const;
bool isABI_FPXX() const { return isABI_O32() && IsFPXX; }
MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, bool little,
const MipsTargetMachine &TM, MaybeAlign StackAlignOverride);
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
bool hasMips1() const { return MipsArchVersion >= Mips1; }
bool hasMips2() const { return MipsArchVersion >= Mips2; }
bool hasMips3() const { return MipsArchVersion >= Mips3; }
bool hasMips4() const { return MipsArchVersion >= Mips4; }
bool hasMips5() const { return MipsArchVersion >= Mips5; }
bool hasMips4_32() const { return HasMips4_32; }
bool hasMips4_32r2() const { return HasMips4_32r2; }
bool hasMips32() const {
return (MipsArchVersion >= Mips32 && MipsArchVersion < Mips32Max) ||
hasMips64();
}
bool hasMips32r2() const {
return (MipsArchVersion >= Mips32r2 && MipsArchVersion < Mips32Max) ||
hasMips64r2();
}
bool hasMips32r3() const {
return (MipsArchVersion >= Mips32r3 && MipsArchVersion < Mips32Max) ||
hasMips64r2();
}
bool hasMips32r5() const {
return (MipsArchVersion >= Mips32r5 && MipsArchVersion < Mips32Max) ||
hasMips64r5();
}
bool hasMips32r6() const {
return (MipsArchVersion >= Mips32r6 && MipsArchVersion < Mips32Max) ||
hasMips64r6();
}
bool hasMips64() const { return MipsArchVersion >= Mips64; }
bool hasMips64r2() const { return MipsArchVersion >= Mips64r2; }
bool hasMips64r3() const { return MipsArchVersion >= Mips64r3; }
bool hasMips64r5() const { return MipsArchVersion >= Mips64r5; }
bool hasMips64r6() const { return MipsArchVersion >= Mips64r6; }
bool hasCnMips() const { return HasCnMips; }
bool hasCnMipsP() const { return HasCnMipsP; }
bool isLittle() const { return IsLittle; }
bool isABICalls() const { return !NoABICalls; }
bool isFPXX() const { return IsFPXX; }
bool isFP64bit() const { return IsFP64bit; }
bool useOddSPReg() const { return UseOddSPReg; }
bool noOddSPReg() const { return !UseOddSPReg; }
bool isNaN2008() const { return IsNaN2008bit; }
bool inAbs2008Mode() const { return Abs2008; }
bool isGP64bit() const { return IsGP64bit; }
bool isGP32bit() const { return !IsGP64bit; }
unsigned getGPRSizeInBytes() const { return isGP64bit() ? 8 : 4; }
bool isPTR64bit() const { return IsPTR64bit; }
bool isPTR32bit() const { return !IsPTR64bit; }
bool hasSym32() const {
return (HasSym32 && isABI_N64()) || isABI_N32() || isABI_O32();
}
bool isSingleFloat() const { return IsSingleFloat; }
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
bool hasVFPU() const { return HasVFPU; }
bool inMips16Mode() const { return InMips16Mode; }
bool inMips16ModeDefault() const {
return InMips16Mode;
}
bool inMips16HardFloat() const {
return inMips16Mode() && InMips16HardFloat;
}
bool inMicroMipsMode() const { return InMicroMipsMode && !InMips16Mode; }
bool inMicroMips32r6Mode() const {
return inMicroMipsMode() && hasMips32r6();
}
bool hasDSP() const { return HasDSP; }
bool hasDSPR2() const { return HasDSPR2; }
bool hasDSPR3() const { return HasDSPR3; }
bool has3D() const { return Has3D; }
bool hasMSA() const { return HasMSA; }
bool disableMadd4() const { return DisableMadd4; }
bool hasEVA() const { return HasEVA; }
bool hasMT() const { return HasMT; }
bool hasCRC() const { return HasCRC; }
bool hasVirt() const { return HasVirt; }
bool hasGINV() const { return HasGINV; }
bool useIndirectJumpsHazard() const {
return UseIndirectJumpsHazard && hasMips32r2();
}
bool useSmallSection() const { return UseSmallSection; }
bool hasStandardEncoding() const { return !InMips16Mode && !InMicroMipsMode; }
bool useSoftFloat() const { return IsSoftFloat; }
bool useLongCalls() const { return UseLongCalls; }
bool useXGOT() const { return UseXGOT; }
bool enableLongBranchPass() const {
return hasStandardEncoding() || inMicroMipsMode() || allowMixed16_32();
}
bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); }
bool hasMTHC1() const { return hasMips32r2(); }
bool allowMixed16_32() const { return inMips16ModeDefault() |
AllowMixed16_32; }
bool os16() const { return Os16; }
bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
bool isXRaySupported() const override { return true; }
static bool useConstantIslands();
Align getStackAlignment() const { return stackAlignment; }
Reloc::Model getRelocationModel() const;
MipsSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS,
const TargetMachine &TM);
bool systemSupportsUnalignedAccess() const { return hasMips32r6(); }
void setHelperClassesMips16();
void setHelperClassesMipsSE();
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
return &TSInfo;
}
const MipsInstrInfo *getInstrInfo() const override { return InstrInfo.get(); }
const TargetFrameLowering *getFrameLowering() const override {
return FrameLowering.get();
}
const MipsRegisterInfo *getRegisterInfo() const override {
return &InstrInfo->getRegisterInfo();
}
const MipsTargetLowering *getTargetLowering() const override {
return TLInfo.get();
}
const InstrItineraryData *getInstrItineraryData() const override {
return &InstrItins;
}
protected:
std::unique_ptr<CallLowering> CallLoweringInfo;
std::unique_ptr<LegalizerInfo> Legalizer;
std::unique_ptr<RegisterBankInfo> RegBankInfo;
std::unique_ptr<InstructionSelector> InstSelector;
public:
const CallLowering *getCallLowering() const override;
const LegalizerInfo *getLegalizerInfo() const override;
const RegisterBankInfo *getRegBankInfo() const override;
InstructionSelector *getInstructionSelector() const override;
};
}
#endif