1234353Sdim//===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9224145Sdim// This file declares the PowerPC specific subclass of TargetSubtargetInfo. 10193323Sed// 11193323Sed//===----------------------------------------------------------------------===// 12193323Sed 13280031Sdim#ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 14280031Sdim#define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 15193323Sed 16276479Sdim#include "PPCFrameLowering.h" 17280031Sdim#include "PPCISelLowering.h" 18276479Sdim#include "PPCInstrInfo.h" 19249423Sdim#include "llvm/ADT/Triple.h" 20309124Sdim#include "llvm/CodeGen/SelectionDAGTargetInfo.h" 21327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 22276479Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/MC/MCInstrItineraries.h" 24193323Sed#include <string> 25193323Sed 26224145Sdim#define GET_SUBTARGETINFO_HEADER 27224145Sdim#include "PPCGenSubtargetInfo.inc" 28224145Sdim 29193323Sed// GCC #defines PPC on Linux but we use it as our namespace name 30193323Sed#undef PPC 31193323Sed 32193323Sednamespace llvm { 33224145Sdimclass StringRef; 34193323Sed 35193323Sednamespace PPC { 36193323Sed // -m directive values. 37193323Sed enum { 38193323Sed DIR_NONE, 39193323Sed DIR_32, 40243830Sdim DIR_440, 41243830Sdim DIR_601, 42243830Sdim DIR_602, 43243830Sdim DIR_603, 44193323Sed DIR_7400, 45243830Sdim DIR_750, 46243830Sdim DIR_970, 47234353Sdim DIR_A2, 48341825Sdim DIR_E500, 49243830Sdim DIR_E500mc, 50243830Sdim DIR_E5500, 51249423Sdim DIR_PWR3, 52249423Sdim DIR_PWR4, 53249423Sdim DIR_PWR5, 54249423Sdim DIR_PWR5X, 55239462Sdim DIR_PWR6, 56249423Sdim DIR_PWR6X, 57239462Sdim DIR_PWR7, 58276479Sdim DIR_PWR8, 59309124Sdim DIR_PWR9, 60360784Sdim DIR_PWR_FUTURE, 61243830Sdim DIR_64 62193323Sed }; 63193323Sed} 64193323Sed 65193323Sedclass GlobalValue; 66193323Sedclass TargetMachine; 67243830Sdim 68224145Sdimclass PPCSubtarget : public PPCGenSubtargetInfo { 69309124Sdimpublic: 70309124Sdim enum POPCNTDKind { 71309124Sdim POPCNTD_Unavailable, 72309124Sdim POPCNTD_Slow, 73309124Sdim POPCNTD_Fast 74309124Sdim }; 75309124Sdim 76193323Sedprotected: 77280031Sdim /// TargetTriple - What processor and OS we're targeting. 78280031Sdim Triple TargetTriple; 79280031Sdim 80193323Sed /// stackAlignment - The minimum alignment known to hold of the stack frame on 81193323Sed /// entry to the function and which must be maintained by every function. 82360784Sdim Align StackAlignment; 83243830Sdim 84193323Sed /// Selected instruction itineraries (one entry per itinerary class.) 85193323Sed InstrItineraryData InstrItins; 86243830Sdim 87193323Sed /// Which cpu directive was used. 88360784Sdim unsigned CPUDirective; 89193323Sed 90193323Sed /// Used by the ISel to turn in optimizations for POWER4-derived architectures 91239462Sdim bool HasMFOCRF; 92193323Sed bool Has64BitSupport; 93193323Sed bool Use64BitRegs; 94276479Sdim bool UseCRBits; 95309149Sdim bool HasHardFloat; 96193323Sed bool IsPPC64; 97193323Sed bool HasAltivec; 98341825Sdim bool HasFPU; 99280031Sdim bool HasSPE; 100249423Sdim bool HasQPX; 101261991Sdim bool HasVSX; 102353358Sdim bool NeedsTwoConstNR; 103280031Sdim bool HasP8Vector; 104288943Sdim bool HasP8Altivec; 105288943Sdim bool HasP8Crypto; 106309124Sdim bool HasP9Vector; 107309124Sdim bool HasP9Altivec; 108261991Sdim bool HasFCPSGN; 109193323Sed bool HasFSQRT; 110249423Sdim bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES; 111249423Sdim bool HasRecipPrec; 112193323Sed bool HasSTFIWX; 113249423Sdim bool HasLFIWAX; 114249423Sdim bool HasFPRND; 115249423Sdim bool HasFPCVT; 116239462Sdim bool HasISEL; 117288943Sdim bool HasBPERMD; 118288943Sdim bool HasExtDiv; 119280031Sdim bool HasCMPB; 120249423Sdim bool HasLDBRX; 121234353Sdim bool IsBookE; 122280031Sdim bool HasOnlyMSYNC; 123280031Sdim bool IsE500; 124280031Sdim bool IsPPC4xx; 125280031Sdim bool IsPPC6xx; 126288943Sdim bool FeatureMFTB; 127363496Sdim bool AllowsUnalignedFPAccess; 128261991Sdim bool DeprecatedDST; 129193323Sed bool HasLazyResolverStubs; 130261991Sdim bool IsLittleEndian; 131288943Sdim bool HasICBT; 132288943Sdim bool HasInvariantFunctionDescriptors; 133288943Sdim bool HasPartwordAtomics; 134288943Sdim bool HasDirectMove; 135288943Sdim bool HasHTM; 136296417Sdim bool HasFloat128; 137309124Sdim bool IsISA3_0; 138309124Sdim bool UseLongCalls; 139341825Sdim bool SecurePlt; 140353358Sdim bool VectorsUseTwoUnits; 141353358Sdim bool UsePPCPreRASchedStrategy; 142353358Sdim bool UsePPCPostRASchedStrategy; 143243830Sdim 144309124Sdim POPCNTDKind HasPOPCNTD; 145309124Sdim 146288943Sdim /// When targeting QPX running a stock PPC64 Linux kernel where the stack 147288943Sdim /// alignment has not been changed, we need to keep the 16-byte alignment 148288943Sdim /// of the stack. 149288943Sdim bool IsQPXStackUnaligned; 150221345Sdim 151288943Sdim const PPCTargetMachine &TM; 152276479Sdim PPCFrameLowering FrameLowering; 153276479Sdim PPCInstrInfo InstrInfo; 154276479Sdim PPCTargetLowering TLInfo; 155309124Sdim SelectionDAGTargetInfo TSInfo; 156276479Sdim 157193323Sedpublic: 158193323Sed /// This constructor initializes the data members to match that 159198090Srdivacky /// of the specified triple. 160193323Sed /// 161288943Sdim PPCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, 162288943Sdim const PPCTargetMachine &TM); 163243830Sdim 164243830Sdim /// ParseSubtargetFeatures - Parses features string setting specified 165193323Sed /// subtarget options. Definition of function is auto generated by tblgen. 166224145Sdim void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 167243830Sdim 168193323Sed /// getStackAlignment - Returns the minimum alignment known to hold of the 169193323Sed /// stack frame on entry to the function and which must be maintained by every 170193323Sed /// function for this subtarget. 171360784Sdim Align getStackAlignment() const { return StackAlignment; } 172243830Sdim 173193323Sed /// getDarwinDirective - Returns the -m directive specified for the cpu. 174360784Sdim unsigned getDarwinDirective() const { return CPUDirective; } 175360784Sdim 176360784Sdim /// getCPUDirective - Returns the -m directive specified for the cpu. 177193323Sed /// 178360784Sdim unsigned getCPUDirective() const { return CPUDirective; } 179243830Sdim 180276479Sdim /// getInstrItins - Return the instruction itineraries based on subtarget 181193323Sed /// selection. 182280031Sdim const InstrItineraryData *getInstrItineraryData() const override { 183280031Sdim return &InstrItins; 184280031Sdim } 185193323Sed 186280031Sdim const PPCFrameLowering *getFrameLowering() const override { 187280031Sdim return &FrameLowering; 188280031Sdim } 189280031Sdim const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } 190280031Sdim const PPCTargetLowering *getTargetLowering() const override { 191280031Sdim return &TLInfo; 192280031Sdim } 193309124Sdim const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 194280031Sdim return &TSInfo; 195280031Sdim } 196280031Sdim const PPCRegisterInfo *getRegisterInfo() const override { 197280031Sdim return &getInstrInfo()->getRegisterInfo(); 198280031Sdim } 199288943Sdim const PPCTargetMachine &getTargetMachine() const { return TM; } 200276479Sdim 201276479Sdim /// initializeSubtargetDependencies - Initializes using a CPU and feature string 202276479Sdim /// so that we can use initializer lists for subtarget initialization. 203276479Sdim PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 204276479Sdim 205261991Sdimprivate: 206261991Sdim void initializeEnvironment(); 207280031Sdim void initSubtargetFeatures(StringRef CPU, StringRef FS); 208261991Sdim 209261991Sdimpublic: 210193323Sed /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. 211193323Sed /// 212288943Sdim bool isPPC64() const; 213243830Sdim 214193323Sed /// has64BitSupport - Return true if the selected CPU supports 64-bit 215193323Sed /// instructions, regardless of whether we are in 32-bit or 64-bit mode. 216193323Sed bool has64BitSupport() const { return Has64BitSupport; } 217296417Sdim // useSoftFloat - Return true if soft-float option is turned on. 218360784Sdim bool useSoftFloat() const { 219360784Sdim if (isAIXABI() && !HasHardFloat) 220360784Sdim report_fatal_error("soft-float is not yet supported on AIX."); 221360784Sdim return !HasHardFloat; 222360784Sdim } 223243830Sdim 224193323Sed /// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit 225193323Sed /// registers in 32-bit mode when possible. This can only true if 226193323Sed /// has64BitSupport() returns true. 227193323Sed bool use64BitRegs() const { return Use64BitRegs; } 228243830Sdim 229276479Sdim /// useCRBits - Return true if we should store and manipulate i1 values in 230276479Sdim /// the individual condition register bits. 231276479Sdim bool useCRBits() const { return UseCRBits; } 232276479Sdim 233193323Sed /// hasLazyResolverStub - Return true if accesses to the specified global have 234193323Sed /// to go through a dyld lazy resolution stub. This means that an extra load 235193323Sed /// is required to get the address of the global. 236288943Sdim bool hasLazyResolverStub(const GlobalValue *GV) const; 237243830Sdim 238261991Sdim // isLittleEndian - True if generating little-endian code 239261991Sdim bool isLittleEndian() const { return IsLittleEndian; } 240261991Sdim 241193323Sed // Specific obvious features. 242261991Sdim bool hasFCPSGN() const { return HasFCPSGN; } 243193323Sed bool hasFSQRT() const { return HasFSQRT; } 244249423Sdim bool hasFRE() const { return HasFRE; } 245249423Sdim bool hasFRES() const { return HasFRES; } 246249423Sdim bool hasFRSQRTE() const { return HasFRSQRTE; } 247249423Sdim bool hasFRSQRTES() const { return HasFRSQRTES; } 248249423Sdim bool hasRecipPrec() const { return HasRecipPrec; } 249193323Sed bool hasSTFIWX() const { return HasSTFIWX; } 250249423Sdim bool hasLFIWAX() const { return HasLFIWAX; } 251249423Sdim bool hasFPRND() const { return HasFPRND; } 252249423Sdim bool hasFPCVT() const { return HasFPCVT; } 253193323Sed bool hasAltivec() const { return HasAltivec; } 254280031Sdim bool hasSPE() const { return HasSPE; } 255341825Sdim bool hasFPU() const { return HasFPU; } 256249423Sdim bool hasQPX() const { return HasQPX; } 257276479Sdim bool hasVSX() const { return HasVSX; } 258353358Sdim bool needsTwoConstNR() const { return NeedsTwoConstNR; } 259280031Sdim bool hasP8Vector() const { return HasP8Vector; } 260288943Sdim bool hasP8Altivec() const { return HasP8Altivec; } 261288943Sdim bool hasP8Crypto() const { return HasP8Crypto; } 262309124Sdim bool hasP9Vector() const { return HasP9Vector; } 263309124Sdim bool hasP9Altivec() const { return HasP9Altivec; } 264239462Sdim bool hasMFOCRF() const { return HasMFOCRF; } 265239462Sdim bool hasISEL() const { return HasISEL; } 266288943Sdim bool hasBPERMD() const { return HasBPERMD; } 267288943Sdim bool hasExtDiv() const { return HasExtDiv; } 268280031Sdim bool hasCMPB() const { return HasCMPB; } 269249423Sdim bool hasLDBRX() const { return HasLDBRX; } 270234353Sdim bool isBookE() const { return IsBookE; } 271280031Sdim bool hasOnlyMSYNC() const { return HasOnlyMSYNC; } 272280031Sdim bool isPPC4xx() const { return IsPPC4xx; } 273280031Sdim bool isPPC6xx() const { return IsPPC6xx; } 274341825Sdim bool isSecurePlt() const {return SecurePlt; } 275353358Sdim bool vectorsUseTwoUnits() const {return VectorsUseTwoUnits; } 276280031Sdim bool isE500() const { return IsE500; } 277288943Sdim bool isFeatureMFTB() const { return FeatureMFTB; } 278363496Sdim bool allowsUnalignedFPAccess() const { return AllowsUnalignedFPAccess; } 279261991Sdim bool isDeprecatedDST() const { return DeprecatedDST; } 280288943Sdim bool hasICBT() const { return HasICBT; } 281288943Sdim bool hasInvariantFunctionDescriptors() const { 282288943Sdim return HasInvariantFunctionDescriptors; 283288943Sdim } 284353358Sdim bool usePPCPreRASchedStrategy() const { return UsePPCPreRASchedStrategy; } 285353358Sdim bool usePPCPostRASchedStrategy() const { return UsePPCPostRASchedStrategy; } 286288943Sdim bool hasPartwordAtomics() const { return HasPartwordAtomics; } 287288943Sdim bool hasDirectMove() const { return HasDirectMove; } 288193323Sed 289288943Sdim bool isQPXStackUnaligned() const { return IsQPXStackUnaligned; } 290360784Sdim Align getPlatformStackAlignment() const { 291288943Sdim if ((hasQPX() || isBGQ()) && !isQPXStackUnaligned()) 292360784Sdim return Align(32); 293288943Sdim 294360784Sdim return Align(16); 295288943Sdim } 296321369Sdim 297321369Sdim // DarwinABI has a 224-byte red zone. PPC32 SVR4ABI(Non-DarwinABI) has no 298321369Sdim // red zone and PPC64 SVR4ABI has a 288-byte red zone. 299321369Sdim unsigned getRedZoneSize() const { 300321369Sdim return isDarwinABI() ? 224 : (isPPC64() ? 288 : 0); 301321369Sdim } 302321369Sdim 303288943Sdim bool hasHTM() const { return HasHTM; } 304296417Sdim bool hasFloat128() const { return HasFloat128; } 305309124Sdim bool isISA3_0() const { return IsISA3_0; } 306309124Sdim bool useLongCalls() const { return UseLongCalls; } 307314564Sdim bool needsSwapsForVSXMemOps() const { 308314564Sdim return hasVSX() && isLittleEndian() && !hasP9Vector(); 309314564Sdim } 310288943Sdim 311309124Sdim POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } 312309124Sdim 313221345Sdim const Triple &getTargetTriple() const { return TargetTriple; } 314221345Sdim 315193323Sed /// isDarwin - True if this is any darwin platform. 316221345Sdim bool isDarwin() const { return TargetTriple.isMacOSX(); } 317249423Sdim /// isBGQ - True if this is a BG/Q platform. 318249423Sdim bool isBGQ() const { return TargetTriple.getVendor() == Triple::BGQ; } 319193323Sed 320270147Srdivacky bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 321276479Sdim bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 322309124Sdim bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 323270147Srdivacky 324288943Sdim bool isDarwinABI() const { return isTargetMachO() || isDarwin(); } 325353358Sdim bool isAIXABI() const { return TargetTriple.isOSAIX(); } 326353358Sdim bool isSVR4ABI() const { return !isDarwinABI() && !isAIXABI(); } 327288943Sdim bool isELFv2ABI() const; 328193323Sed 329360784Sdim bool is64BitELFABI() const { return isSVR4ABI() && isPPC64(); } 330360784Sdim bool is32BitELFABI() const { return isSVR4ABI() && !isPPC64(); } 331360784Sdim 332321369Sdim /// Originally, this function return hasISEL(). Now we always enable it, 333321369Sdim /// but may expand the ISEL instruction later. 334321369Sdim bool enableEarlyIfConversion() const override { return true; } 335261991Sdim 336353358Sdim /// Scheduling customization. 337276479Sdim bool enableMachineScheduler() const override; 338353358Sdim /// Pipeliner customization. 339353358Sdim bool enableMachinePipeliner() const override; 340353358Sdim /// Machine Pipeliner customization 341353358Sdim bool useDFAforSMS() const override; 342353358Sdim /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 343288943Sdim bool enablePostRAScheduler() const override; 344276479Sdim AntiDepBreakMode getAntiDepBreakMode() const override; 345276479Sdim void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 346276479Sdim 347261991Sdim void overrideSchedPolicy(MachineSchedPolicy &Policy, 348276479Sdim unsigned NumRegionInstrs) const override; 349276479Sdim bool useAA() const override; 350280031Sdim 351280031Sdim bool enableSubRegLiveness() const override; 352296417Sdim 353360784Sdim /// True if the GV will be accessed via an indirect symbol. 354360784Sdim bool isGVIndirectSymbol(const GlobalValue *GV) const; 355321369Sdim 356360784Sdim /// True if the ABI is descriptor based. 357360784Sdim bool usesFunctionDescriptors() const { 358360784Sdim // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit 359360784Sdim // v1 ABI uses descriptors. 360360784Sdim return isAIXABI() || (is64BitELFABI() && !isELFv2ABI()); 361360784Sdim } 362360784Sdim 363360784Sdim unsigned descriptorTOCAnchorOffset() const { 364360784Sdim assert(usesFunctionDescriptors() && 365360784Sdim "Should only be called when the target uses descriptors."); 366360784Sdim return IsPPC64 ? 8 : 4; 367360784Sdim } 368360784Sdim 369360784Sdim unsigned descriptorEnvironmentPointerOffset() const { 370360784Sdim assert(usesFunctionDescriptors() && 371360784Sdim "Should only be called when the target uses descriptors."); 372360784Sdim return IsPPC64 ? 16 : 8; 373360784Sdim } 374360784Sdim 375360784Sdim MCRegister getEnvironmentPointerRegister() const { 376360784Sdim assert(usesFunctionDescriptors() && 377360784Sdim "Should only be called when the target uses descriptors."); 378360784Sdim return IsPPC64 ? PPC::X11 : PPC::R11; 379360784Sdim } 380360784Sdim 381360784Sdim MCRegister getTOCPointerRegister() const { 382360784Sdim assert((is64BitELFABI() || isAIXABI()) && 383360784Sdim "Should only be called when the target is a TOC based ABI."); 384360784Sdim return IsPPC64 ? PPC::X2 : PPC::R2; 385360784Sdim } 386360784Sdim 387360784Sdim MCRegister getStackPointerRegister() const { 388360784Sdim return IsPPC64 ? PPC::X1 : PPC::R1; 389360784Sdim } 390360784Sdim 391321369Sdim bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } 392193323Sed}; 393193323Sed} // End llvm namespace 394193323Sed 395193323Sed#endif 396