//===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares the PowerPC specific subclass of TargetSubtargetInfo. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H #define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H #include "PPCFrameLowering.h" #include "PPCISelLowering.h" #include "PPCInstrInfo.h" #include "llvm/ADT/Triple.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCInstrItineraries.h" #include #define GET_SUBTARGETINFO_HEADER #include "PPCGenSubtargetInfo.inc" // GCC #defines PPC on Linux but we use it as our namespace name #undef PPC namespace llvm { class StringRef; namespace PPC { // -m directive values. enum { DIR_NONE, DIR_32, DIR_440, DIR_601, DIR_602, DIR_603, DIR_7400, DIR_750, DIR_970, DIR_A2, DIR_E500, DIR_E500mc, DIR_E5500, DIR_PWR3, DIR_PWR4, DIR_PWR5, DIR_PWR5X, DIR_PWR6, DIR_PWR6X, DIR_PWR7, DIR_PWR8, DIR_PWR9, DIR_64 }; } class GlobalValue; class TargetMachine; class PPCSubtarget : public PPCGenSubtargetInfo { public: enum POPCNTDKind { POPCNTD_Unavailable, POPCNTD_Slow, POPCNTD_Fast }; protected: /// TargetTriple - What processor and OS we're targeting. Triple TargetTriple; /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned StackAlignment; /// Selected instruction itineraries (one entry per itinerary class.) InstrItineraryData InstrItins; /// Which cpu directive was used. unsigned DarwinDirective; /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool HasMFOCRF; bool Has64BitSupport; bool Use64BitRegs; bool UseCRBits; bool HasHardFloat; bool IsPPC64; bool HasAltivec; bool HasFPU; bool HasSPE; bool HasQPX; bool HasVSX; bool HasP8Vector; bool HasP8Altivec; bool HasP8Crypto; bool HasP9Vector; bool HasP9Altivec; bool HasFCPSGN; bool HasFSQRT; bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES; bool HasRecipPrec; bool HasSTFIWX; bool HasLFIWAX; bool HasFPRND; bool HasFPCVT; bool HasISEL; bool HasBPERMD; bool HasExtDiv; bool HasCMPB; bool HasLDBRX; bool IsBookE; bool HasOnlyMSYNC; bool IsE500; bool IsPPC4xx; bool IsPPC6xx; bool FeatureMFTB; bool DeprecatedDST; bool HasLazyResolverStubs; bool IsLittleEndian; bool HasICBT; bool HasInvariantFunctionDescriptors; bool HasPartwordAtomics; bool HasDirectMove; bool HasHTM; bool HasFusion; bool HasFloat128; bool IsISA3_0; bool UseLongCalls; bool SecurePlt; POPCNTDKind HasPOPCNTD; /// When targeting QPX running a stock PPC64 Linux kernel where the stack /// alignment has not been changed, we need to keep the 16-byte alignment /// of the stack. bool IsQPXStackUnaligned; const PPCTargetMachine &TM; PPCFrameLowering FrameLowering; PPCInstrInfo InstrInfo; PPCTargetLowering TLInfo; SelectionDAGTargetInfo TSInfo; public: /// This constructor initializes the data members to match that /// of the specified triple. /// PPCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, const PPCTargetMachine &TM); /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); /// getStackAlignment - Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every /// function for this subtarget. unsigned getStackAlignment() const { return StackAlignment; } /// getDarwinDirective - Returns the -m directive specified for the cpu. /// unsigned getDarwinDirective() const { return DarwinDirective; } /// getInstrItins - Return the instruction itineraries based on subtarget /// selection. const InstrItineraryData *getInstrItineraryData() const override { return &InstrItins; } const PPCFrameLowering *getFrameLowering() const override { return &FrameLowering; } const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } const PPCTargetLowering *getTargetLowering() const override { return &TLInfo; } const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { return &TSInfo; } const PPCRegisterInfo *getRegisterInfo() const override { return &getInstrInfo()->getRegisterInfo(); } const PPCTargetMachine &getTargetMachine() const { return TM; } /// initializeSubtargetDependencies - Initializes using a CPU and feature string /// so that we can use initializer lists for subtarget initialization. PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); private: void initializeEnvironment(); void initSubtargetFeatures(StringRef CPU, StringRef FS); public: /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. /// bool isPPC64() const; /// has64BitSupport - Return true if the selected CPU supports 64-bit /// instructions, regardless of whether we are in 32-bit or 64-bit mode. bool has64BitSupport() const { return Has64BitSupport; } // useSoftFloat - Return true if soft-float option is turned on. bool useSoftFloat() const { return !HasHardFloat; } /// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit /// registers in 32-bit mode when possible. This can only true if /// has64BitSupport() returns true. bool use64BitRegs() const { return Use64BitRegs; } /// useCRBits - Return true if we should store and manipulate i1 values in /// the individual condition register bits. bool useCRBits() const { return UseCRBits; } /// hasLazyResolverStub - Return true if accesses to the specified global have /// to go through a dyld lazy resolution stub. This means that an extra load /// is required to get the address of the global. bool hasLazyResolverStub(const GlobalValue *GV) const; // isLittleEndian - True if generating little-endian code bool isLittleEndian() const { return IsLittleEndian; } // Specific obvious features. bool hasFCPSGN() const { return HasFCPSGN; } bool hasFSQRT() const { return HasFSQRT; } bool hasFRE() const { return HasFRE; } bool hasFRES() const { return HasFRES; } bool hasFRSQRTE() const { return HasFRSQRTE; } bool hasFRSQRTES() const { return HasFRSQRTES; } bool hasRecipPrec() const { return HasRecipPrec; } bool hasSTFIWX() const { return HasSTFIWX; } bool hasLFIWAX() const { return HasLFIWAX; } bool hasFPRND() const { return HasFPRND; } bool hasFPCVT() const { return HasFPCVT; } bool hasAltivec() const { return HasAltivec; } bool hasSPE() const { return HasSPE; } bool hasFPU() const { return HasFPU; } bool hasQPX() const { return HasQPX; } bool hasVSX() const { return HasVSX; } bool hasP8Vector() const { return HasP8Vector; } bool hasP8Altivec() const { return HasP8Altivec; } bool hasP8Crypto() const { return HasP8Crypto; } bool hasP9Vector() const { return HasP9Vector; } bool hasP9Altivec() const { return HasP9Altivec; } bool hasMFOCRF() const { return HasMFOCRF; } bool hasISEL() const { return HasISEL; } bool hasBPERMD() const { return HasBPERMD; } bool hasExtDiv() const { return HasExtDiv; } bool hasCMPB() const { return HasCMPB; } bool hasLDBRX() const { return HasLDBRX; } bool isBookE() const { return IsBookE; } bool hasOnlyMSYNC() const { return HasOnlyMSYNC; } bool isPPC4xx() const { return IsPPC4xx; } bool isPPC6xx() const { return IsPPC6xx; } bool isSecurePlt() const {return SecurePlt; } bool isE500() const { return IsE500; } bool isFeatureMFTB() const { return FeatureMFTB; } bool isDeprecatedDST() const { return DeprecatedDST; } bool hasICBT() const { return HasICBT; } bool hasInvariantFunctionDescriptors() const { return HasInvariantFunctionDescriptors; } bool hasPartwordAtomics() const { return HasPartwordAtomics; } bool hasDirectMove() const { return HasDirectMove; } bool isQPXStackUnaligned() const { return IsQPXStackUnaligned; } unsigned getPlatformStackAlignment() const { if ((hasQPX() || isBGQ()) && !isQPXStackUnaligned()) return 32; return 16; } // DarwinABI has a 224-byte red zone. PPC32 SVR4ABI(Non-DarwinABI) has no // red zone and PPC64 SVR4ABI has a 288-byte red zone. unsigned getRedZoneSize() const { return isDarwinABI() ? 224 : (isPPC64() ? 288 : 0); } bool hasHTM() const { return HasHTM; } bool hasFusion() const { return HasFusion; } bool hasFloat128() const { return HasFloat128; } bool isISA3_0() const { return IsISA3_0; } bool useLongCalls() const { return UseLongCalls; } bool needsSwapsForVSXMemOps() const { return hasVSX() && isLittleEndian() && !hasP9Vector(); } POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } const Triple &getTargetTriple() const { return TargetTriple; } /// isDarwin - True if this is any darwin platform. bool isDarwin() const { return TargetTriple.isMacOSX(); } /// isBGQ - True if this is a BG/Q platform. bool isBGQ() const { return TargetTriple.getVendor() == Triple::BGQ; } bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } bool isTargetLinux() const { return TargetTriple.isOSLinux(); } bool isDarwinABI() const { return isTargetMachO() || isDarwin(); } bool isSVR4ABI() const { return !isDarwinABI(); } bool isELFv2ABI() const; /// Originally, this function return hasISEL(). Now we always enable it, /// but may expand the ISEL instruction later. bool enableEarlyIfConversion() const override { return true; } // Scheduling customization. bool enableMachineScheduler() const override; // This overrides the PostRAScheduler bit in the SchedModel for each CPU. bool enablePostRAScheduler() const override; AntiDepBreakMode getAntiDepBreakMode() const override; void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override; bool useAA() const override; bool enableSubRegLiveness() const override; /// classifyGlobalReference - Classify a global variable reference for the /// current subtarget accourding to how we should reference it. unsigned char classifyGlobalReference(const GlobalValue *GV) const; bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } }; } // End llvm namespace #endif