109467b48Spatrick //===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file declares the PowerPC specific subclass of TargetSubtargetInfo. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 1409467b48Spatrick #define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 1509467b48Spatrick 1609467b48Spatrick #include "PPCFrameLowering.h" 1709467b48Spatrick #include "PPCISelLowering.h" 1809467b48Spatrick #include "PPCInstrInfo.h" 1909467b48Spatrick #include "llvm/ADT/Triple.h" 20a0747c9fSpatrick #include "llvm/CodeGen/GlobalISel/CallLowering.h" 21a0747c9fSpatrick #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 22*a96b3639Srobert #include "llvm/CodeGen/RegisterBankInfo.h" 2309467b48Spatrick #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 2409467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h" 2509467b48Spatrick #include "llvm/IR/DataLayout.h" 2609467b48Spatrick #include "llvm/MC/MCInstrItineraries.h" 2709467b48Spatrick #include <string> 2809467b48Spatrick 2909467b48Spatrick #define GET_SUBTARGETINFO_HEADER 3009467b48Spatrick #include "PPCGenSubtargetInfo.inc" 3109467b48Spatrick 3209467b48Spatrick // GCC #defines PPC on Linux but we use it as our namespace name 3309467b48Spatrick #undef PPC 3409467b48Spatrick 3509467b48Spatrick namespace llvm { 3609467b48Spatrick class StringRef; 3709467b48Spatrick 3809467b48Spatrick namespace PPC { 3909467b48Spatrick // -m directive values. 4009467b48Spatrick enum { 4109467b48Spatrick DIR_NONE, 4209467b48Spatrick DIR_32, 4309467b48Spatrick DIR_440, 4409467b48Spatrick DIR_601, 4509467b48Spatrick DIR_602, 4609467b48Spatrick DIR_603, 4709467b48Spatrick DIR_7400, 4809467b48Spatrick DIR_750, 4909467b48Spatrick DIR_970, 5009467b48Spatrick DIR_A2, 5109467b48Spatrick DIR_E500, 5209467b48Spatrick DIR_E500mc, 5309467b48Spatrick DIR_E5500, 5409467b48Spatrick DIR_PWR3, 5509467b48Spatrick DIR_PWR4, 5609467b48Spatrick DIR_PWR5, 5709467b48Spatrick DIR_PWR5X, 5809467b48Spatrick DIR_PWR6, 5909467b48Spatrick DIR_PWR6X, 6009467b48Spatrick DIR_PWR7, 6109467b48Spatrick DIR_PWR8, 6209467b48Spatrick DIR_PWR9, 63adae0cfdSpatrick DIR_PWR10, 6409467b48Spatrick DIR_PWR_FUTURE, 6509467b48Spatrick DIR_64 6609467b48Spatrick }; 6709467b48Spatrick } 6809467b48Spatrick 6909467b48Spatrick class GlobalValue; 7009467b48Spatrick 7109467b48Spatrick class PPCSubtarget : public PPCGenSubtargetInfo { 7209467b48Spatrick public: 7309467b48Spatrick enum POPCNTDKind { 7409467b48Spatrick POPCNTD_Unavailable, 7509467b48Spatrick POPCNTD_Slow, 7609467b48Spatrick POPCNTD_Fast 7709467b48Spatrick }; 7809467b48Spatrick 7909467b48Spatrick protected: 8009467b48Spatrick /// TargetTriple - What processor and OS we're targeting. 8109467b48Spatrick Triple TargetTriple; 8209467b48Spatrick 8309467b48Spatrick /// stackAlignment - The minimum alignment known to hold of the stack frame on 8409467b48Spatrick /// entry to the function and which must be maintained by every function. 8509467b48Spatrick Align StackAlignment; 8609467b48Spatrick 8709467b48Spatrick /// Selected instruction itineraries (one entry per itinerary class.) 8809467b48Spatrick InstrItineraryData InstrItins; 8909467b48Spatrick 90*a96b3639Srobert // Bool members corresponding to the SubtargetFeatures defined in tablegen. 91*a96b3639Srobert #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 92*a96b3639Srobert bool ATTRIBUTE = DEFAULT; 93*a96b3639Srobert #include "PPCGenSubtargetInfo.inc" 94*a96b3639Srobert 9509467b48Spatrick /// Which cpu directive was used. 9609467b48Spatrick unsigned CPUDirective; 9709467b48Spatrick 9809467b48Spatrick bool IsPPC64; 9909467b48Spatrick bool IsLittleEndian; 10009467b48Spatrick 10109467b48Spatrick POPCNTDKind HasPOPCNTD; 10209467b48Spatrick 10309467b48Spatrick const PPCTargetMachine &TM; 10409467b48Spatrick PPCFrameLowering FrameLowering; 10509467b48Spatrick PPCInstrInfo InstrInfo; 10609467b48Spatrick PPCTargetLowering TLInfo; 10709467b48Spatrick SelectionDAGTargetInfo TSInfo; 10809467b48Spatrick 109a0747c9fSpatrick /// GlobalISel related APIs. 110a0747c9fSpatrick std::unique_ptr<CallLowering> CallLoweringInfo; 111a0747c9fSpatrick std::unique_ptr<LegalizerInfo> Legalizer; 112a0747c9fSpatrick std::unique_ptr<RegisterBankInfo> RegBankInfo; 113a0747c9fSpatrick std::unique_ptr<InstructionSelector> InstSelector; 114a0747c9fSpatrick 11509467b48Spatrick public: 11609467b48Spatrick /// This constructor initializes the data members to match that 11709467b48Spatrick /// of the specified triple. 11809467b48Spatrick /// 119*a96b3639Srobert PPCSubtarget(const Triple &TT, const std::string &CPU, 120*a96b3639Srobert const std::string &TuneCPU, const std::string &FS, 12109467b48Spatrick const PPCTargetMachine &TM); 12209467b48Spatrick 12309467b48Spatrick /// ParseSubtargetFeatures - Parses features string setting specified 12409467b48Spatrick /// subtarget options. Definition of function is auto generated by tblgen. 125a0747c9fSpatrick void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 12609467b48Spatrick 12709467b48Spatrick /// getStackAlignment - Returns the minimum alignment known to hold of the 12809467b48Spatrick /// stack frame on entry to the function and which must be maintained by every 12909467b48Spatrick /// function for this subtarget. getStackAlignment()13009467b48Spatrick Align getStackAlignment() const { return StackAlignment; } 13109467b48Spatrick 13209467b48Spatrick /// getCPUDirective - Returns the -m directive specified for the cpu. 13309467b48Spatrick /// getCPUDirective()13409467b48Spatrick unsigned getCPUDirective() const { return CPUDirective; } 13509467b48Spatrick 13609467b48Spatrick /// getInstrItins - Return the instruction itineraries based on subtarget 13709467b48Spatrick /// selection. getInstrItineraryData()13809467b48Spatrick const InstrItineraryData *getInstrItineraryData() const override { 13909467b48Spatrick return &InstrItins; 14009467b48Spatrick } 14109467b48Spatrick getFrameLowering()14209467b48Spatrick const PPCFrameLowering *getFrameLowering() const override { 14309467b48Spatrick return &FrameLowering; 14409467b48Spatrick } getInstrInfo()14509467b48Spatrick const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } getTargetLowering()14609467b48Spatrick const PPCTargetLowering *getTargetLowering() const override { 14709467b48Spatrick return &TLInfo; 14809467b48Spatrick } getSelectionDAGInfo()14909467b48Spatrick const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 15009467b48Spatrick return &TSInfo; 15109467b48Spatrick } getRegisterInfo()15209467b48Spatrick const PPCRegisterInfo *getRegisterInfo() const override { 15309467b48Spatrick return &getInstrInfo()->getRegisterInfo(); 15409467b48Spatrick } getTargetMachine()15509467b48Spatrick const PPCTargetMachine &getTargetMachine() const { return TM; } 15609467b48Spatrick 157*a96b3639Srobert /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU, and 158*a96b3639Srobert /// feature string so that we can use initializer lists for subtarget 159*a96b3639Srobert /// initialization. 160*a96b3639Srobert PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, 161*a96b3639Srobert StringRef TuneCPU, 162*a96b3639Srobert StringRef FS); 16309467b48Spatrick 16409467b48Spatrick private: 16509467b48Spatrick void initializeEnvironment(); 166*a96b3639Srobert void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 16709467b48Spatrick 16809467b48Spatrick public: 16909467b48Spatrick /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. 17009467b48Spatrick /// 17109467b48Spatrick bool isPPC64() const; 17209467b48Spatrick 17309467b48Spatrick // useSoftFloat - Return true if soft-float option is turned on. useSoftFloat()17409467b48Spatrick bool useSoftFloat() const { 17509467b48Spatrick if (isAIXABI() && !HasHardFloat) 17609467b48Spatrick report_fatal_error("soft-float is not yet supported on AIX."); 17709467b48Spatrick return !HasHardFloat; 17809467b48Spatrick } 17909467b48Spatrick 18009467b48Spatrick // isLittleEndian - True if generating little-endian code isLittleEndian()18109467b48Spatrick bool isLittleEndian() const { return IsLittleEndian; } 18209467b48Spatrick 183*a96b3639Srobert // Getters for SubtargetFeatures defined in tablegen. 184*a96b3639Srobert #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 185*a96b3639Srobert bool GETTER() const { return ATTRIBUTE; } 186*a96b3639Srobert #include "PPCGenSubtargetInfo.inc" 18709467b48Spatrick getPlatformStackAlignment()18809467b48Spatrick Align getPlatformStackAlignment() const { 18909467b48Spatrick return Align(16); 19009467b48Spatrick } 19109467b48Spatrick getRedZoneSize()19209467b48Spatrick unsigned getRedZoneSize() const { 193adae0cfdSpatrick if (isPPC64()) 194adae0cfdSpatrick // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved) 195adae0cfdSpatrick return 288; 196adae0cfdSpatrick 197adae0cfdSpatrick // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs); 198adae0cfdSpatrick // PPC32 SVR4ABI has no redzone. 199adae0cfdSpatrick return isAIXABI() ? 220 : 0; 20009467b48Spatrick } 20109467b48Spatrick needsSwapsForVSXMemOps()20209467b48Spatrick bool needsSwapsForVSXMemOps() const { 20309467b48Spatrick return hasVSX() && isLittleEndian() && !hasP9Vector(); 20409467b48Spatrick } 20509467b48Spatrick hasPOPCNTD()20609467b48Spatrick POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } 20709467b48Spatrick getTargetTriple()20809467b48Spatrick const Triple &getTargetTriple() const { return TargetTriple; } 20909467b48Spatrick isTargetELF()21009467b48Spatrick bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } isTargetMachO()21109467b48Spatrick bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } isTargetLinux()21209467b48Spatrick bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 21309467b48Spatrick isAIXABI()21409467b48Spatrick bool isAIXABI() const { return TargetTriple.isOSAIX(); } isSVR4ABI()215adae0cfdSpatrick bool isSVR4ABI() const { return !isAIXABI(); } 21609467b48Spatrick bool isELFv2ABI() const; 21709467b48Spatrick is64BitELFABI()21809467b48Spatrick bool is64BitELFABI() const { return isSVR4ABI() && isPPC64(); } is32BitELFABI()21909467b48Spatrick bool is32BitELFABI() const { return isSVR4ABI() && !isPPC64(); } 220adae0cfdSpatrick bool isUsingPCRelativeCalls() const; 22109467b48Spatrick 22209467b48Spatrick /// Originally, this function return hasISEL(). Now we always enable it, 22309467b48Spatrick /// but may expand the ISEL instruction later. enableEarlyIfConversion()22409467b48Spatrick bool enableEarlyIfConversion() const override { return true; } 22509467b48Spatrick 22609467b48Spatrick /// Scheduling customization. 22709467b48Spatrick bool enableMachineScheduler() const override; 22809467b48Spatrick /// Pipeliner customization. 22909467b48Spatrick bool enableMachinePipeliner() const override; 23009467b48Spatrick /// Machine Pipeliner customization 23109467b48Spatrick bool useDFAforSMS() const override; 23209467b48Spatrick /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 23309467b48Spatrick bool enablePostRAScheduler() const override; 23409467b48Spatrick AntiDepBreakMode getAntiDepBreakMode() const override; 23509467b48Spatrick void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 23609467b48Spatrick 23709467b48Spatrick void overrideSchedPolicy(MachineSchedPolicy &Policy, 23809467b48Spatrick unsigned NumRegionInstrs) const override; 23909467b48Spatrick bool useAA() const override; 24009467b48Spatrick 24109467b48Spatrick bool enableSubRegLiveness() const override; 24209467b48Spatrick 24309467b48Spatrick /// True if the GV will be accessed via an indirect symbol. 24409467b48Spatrick bool isGVIndirectSymbol(const GlobalValue *GV) const; 24509467b48Spatrick 24609467b48Spatrick /// True if the ABI is descriptor based. usesFunctionDescriptors()24709467b48Spatrick bool usesFunctionDescriptors() const { 24809467b48Spatrick // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit 24909467b48Spatrick // v1 ABI uses descriptors. 25009467b48Spatrick return isAIXABI() || (is64BitELFABI() && !isELFv2ABI()); 25109467b48Spatrick } 25209467b48Spatrick descriptorTOCAnchorOffset()25309467b48Spatrick unsigned descriptorTOCAnchorOffset() const { 25409467b48Spatrick assert(usesFunctionDescriptors() && 25509467b48Spatrick "Should only be called when the target uses descriptors."); 25609467b48Spatrick return IsPPC64 ? 8 : 4; 25709467b48Spatrick } 25809467b48Spatrick descriptorEnvironmentPointerOffset()25909467b48Spatrick unsigned descriptorEnvironmentPointerOffset() const { 26009467b48Spatrick assert(usesFunctionDescriptors() && 26109467b48Spatrick "Should only be called when the target uses descriptors."); 26209467b48Spatrick return IsPPC64 ? 16 : 8; 26309467b48Spatrick } 26409467b48Spatrick getEnvironmentPointerRegister()26509467b48Spatrick MCRegister getEnvironmentPointerRegister() const { 26609467b48Spatrick assert(usesFunctionDescriptors() && 26709467b48Spatrick "Should only be called when the target uses descriptors."); 26809467b48Spatrick return IsPPC64 ? PPC::X11 : PPC::R11; 26909467b48Spatrick } 27009467b48Spatrick getTOCPointerRegister()27109467b48Spatrick MCRegister getTOCPointerRegister() const { 27209467b48Spatrick assert((is64BitELFABI() || isAIXABI()) && 27309467b48Spatrick "Should only be called when the target is a TOC based ABI."); 27409467b48Spatrick return IsPPC64 ? PPC::X2 : PPC::R2; 27509467b48Spatrick } 27609467b48Spatrick getStackPointerRegister()27709467b48Spatrick MCRegister getStackPointerRegister() const { 27809467b48Spatrick return IsPPC64 ? PPC::X1 : PPC::R1; 27909467b48Spatrick } 28009467b48Spatrick isXRaySupported()28109467b48Spatrick bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } 282adae0cfdSpatrick isPredictableSelectIsExpensive()283adae0cfdSpatrick bool isPredictableSelectIsExpensive() const { 284adae0cfdSpatrick return PredictableSelectIsExpensive; 285adae0cfdSpatrick } 286a0747c9fSpatrick 287a0747c9fSpatrick // Select allocation orders of GPRC and G8RC. It should be strictly consistent 288a0747c9fSpatrick // with corresponding AltOrders in PPCRegisterInfo.td. getGPRAllocationOrderIdx()289a0747c9fSpatrick unsigned getGPRAllocationOrderIdx() const { 290a0747c9fSpatrick if (is64BitELFABI()) 291a0747c9fSpatrick return 1; 292a0747c9fSpatrick if (isAIXABI()) 293a0747c9fSpatrick return 2; 294a0747c9fSpatrick return 0; 295a0747c9fSpatrick } 296a0747c9fSpatrick 297a0747c9fSpatrick // GlobalISEL 298a0747c9fSpatrick const CallLowering *getCallLowering() const override; 299a0747c9fSpatrick const RegisterBankInfo *getRegBankInfo() const override; 300a0747c9fSpatrick const LegalizerInfo *getLegalizerInfo() const override; 301a0747c9fSpatrick InstructionSelector *getInstructionSelector() const override; 30209467b48Spatrick }; 30309467b48Spatrick } // End llvm namespace 30409467b48Spatrick 30509467b48Spatrick #endif 306