10b57cec5SDimitry Andric //===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares the PowerPC specific subclass of TargetSubtargetInfo. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "PPCFrameLowering.h" 170b57cec5SDimitry Andric #include "PPCISelLowering.h" 180b57cec5SDimitry Andric #include "PPCInstrInfo.h" 19e8d8bef9SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 20e8d8bef9SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 2181ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 240b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h" 2606c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 270b57cec5SDimitry Andric #include <string> 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER 300b57cec5SDimitry Andric #include "PPCGenSubtargetInfo.inc" 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // GCC #defines PPC on Linux but we use it as our namespace name 330b57cec5SDimitry Andric #undef PPC 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace llvm { 360b57cec5SDimitry Andric class StringRef; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric namespace PPC { 390b57cec5SDimitry Andric // -m directive values. 400b57cec5SDimitry Andric enum { 410b57cec5SDimitry Andric DIR_NONE, 420b57cec5SDimitry Andric DIR_32, 430b57cec5SDimitry Andric DIR_440, 440b57cec5SDimitry Andric DIR_601, 450b57cec5SDimitry Andric DIR_602, 460b57cec5SDimitry Andric DIR_603, 470b57cec5SDimitry Andric DIR_7400, 480b57cec5SDimitry Andric DIR_750, 490b57cec5SDimitry Andric DIR_970, 500b57cec5SDimitry Andric DIR_A2, 510b57cec5SDimitry Andric DIR_E500, 520b57cec5SDimitry Andric DIR_E500mc, 530b57cec5SDimitry Andric DIR_E5500, 540b57cec5SDimitry Andric DIR_PWR3, 550b57cec5SDimitry Andric DIR_PWR4, 560b57cec5SDimitry Andric DIR_PWR5, 570b57cec5SDimitry Andric DIR_PWR5X, 580b57cec5SDimitry Andric DIR_PWR6, 590b57cec5SDimitry Andric DIR_PWR6X, 600b57cec5SDimitry Andric DIR_PWR7, 610b57cec5SDimitry Andric DIR_PWR8, 620b57cec5SDimitry Andric DIR_PWR9, 635ffd83dbSDimitry Andric DIR_PWR10, 64*36b606aeSDimitry Andric DIR_PWR11, 65480093f4SDimitry Andric DIR_PWR_FUTURE, 660b57cec5SDimitry Andric DIR_64 670b57cec5SDimitry Andric }; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric class GlobalValue; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric class PPCSubtarget : public PPCGenSubtargetInfo { 730b57cec5SDimitry Andric public: 740b57cec5SDimitry Andric enum POPCNTDKind { 750b57cec5SDimitry Andric POPCNTD_Unavailable, 760b57cec5SDimitry Andric POPCNTD_Slow, 770b57cec5SDimitry Andric POPCNTD_Fast 780b57cec5SDimitry Andric }; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric protected: 810b57cec5SDimitry Andric /// TargetTriple - What processor and OS we're targeting. 820b57cec5SDimitry Andric Triple TargetTriple; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// stackAlignment - The minimum alignment known to hold of the stack frame on 850b57cec5SDimitry Andric /// entry to the function and which must be maintained by every function. 868bcb0991SDimitry Andric Align StackAlignment; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric /// Selected instruction itineraries (one entry per itinerary class.) 890b57cec5SDimitry Andric InstrItineraryData InstrItins; 900b57cec5SDimitry Andric 91bdd1243dSDimitry Andric // Bool members corresponding to the SubtargetFeatures defined in tablegen. 92bdd1243dSDimitry Andric #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 93bdd1243dSDimitry Andric bool ATTRIBUTE = DEFAULT; 94bdd1243dSDimitry Andric #include "PPCGenSubtargetInfo.inc" 95bdd1243dSDimitry Andric 960b57cec5SDimitry Andric /// Which cpu directive was used. 97480093f4SDimitry Andric unsigned CPUDirective; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric bool IsPPC64; 1000b57cec5SDimitry Andric bool IsLittleEndian; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric POPCNTDKind HasPOPCNTD; 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric const PPCTargetMachine &TM; 1050b57cec5SDimitry Andric PPCFrameLowering FrameLowering; 1060b57cec5SDimitry Andric PPCInstrInfo InstrInfo; 1070b57cec5SDimitry Andric PPCTargetLowering TLInfo; 1080b57cec5SDimitry Andric SelectionDAGTargetInfo TSInfo; 1090b57cec5SDimitry Andric 110e8d8bef9SDimitry Andric /// GlobalISel related APIs. 111e8d8bef9SDimitry Andric std::unique_ptr<CallLowering> CallLoweringInfo; 112e8d8bef9SDimitry Andric std::unique_ptr<LegalizerInfo> Legalizer; 113e8d8bef9SDimitry Andric std::unique_ptr<RegisterBankInfo> RegBankInfo; 114e8d8bef9SDimitry Andric std::unique_ptr<InstructionSelector> InstSelector; 115e8d8bef9SDimitry Andric 1160b57cec5SDimitry Andric public: 1170b57cec5SDimitry Andric /// This constructor initializes the data members to match that 1180b57cec5SDimitry Andric /// of the specified triple. 1190b57cec5SDimitry Andric /// 120bdd1243dSDimitry Andric PPCSubtarget(const Triple &TT, const std::string &CPU, 121bdd1243dSDimitry Andric const std::string &TuneCPU, const std::string &FS, 1220b57cec5SDimitry Andric const PPCTargetMachine &TM); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric /// ParseSubtargetFeatures - Parses features string setting specified 1250b57cec5SDimitry Andric /// subtarget options. Definition of function is auto generated by tblgen. 126e8d8bef9SDimitry Andric void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// getStackAlignment - Returns the minimum alignment known to hold of the 1290b57cec5SDimitry Andric /// stack frame on entry to the function and which must be maintained by every 1300b57cec5SDimitry Andric /// function for this subtarget. 1318bcb0991SDimitry Andric Align getStackAlignment() const { return StackAlignment; } 1320b57cec5SDimitry Andric 133480093f4SDimitry Andric /// getCPUDirective - Returns the -m directive specified for the cpu. 1340b57cec5SDimitry Andric /// 135480093f4SDimitry Andric unsigned getCPUDirective() const { return CPUDirective; } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric /// getInstrItins - Return the instruction itineraries based on subtarget 1380b57cec5SDimitry Andric /// selection. 1390b57cec5SDimitry Andric const InstrItineraryData *getInstrItineraryData() const override { 1400b57cec5SDimitry Andric return &InstrItins; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric const PPCFrameLowering *getFrameLowering() const override { 1440b57cec5SDimitry Andric return &FrameLowering; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } 1470b57cec5SDimitry Andric const PPCTargetLowering *getTargetLowering() const override { 1480b57cec5SDimitry Andric return &TLInfo; 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 1510b57cec5SDimitry Andric return &TSInfo; 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric const PPCRegisterInfo *getRegisterInfo() const override { 1540b57cec5SDimitry Andric return &getInstrInfo()->getRegisterInfo(); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric const PPCTargetMachine &getTargetMachine() const { return TM; } 1570b57cec5SDimitry Andric 158bdd1243dSDimitry Andric /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU, and 159bdd1243dSDimitry Andric /// feature string so that we can use initializer lists for subtarget 160bdd1243dSDimitry Andric /// initialization. 161bdd1243dSDimitry Andric PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, 162bdd1243dSDimitry Andric StringRef TuneCPU, 163bdd1243dSDimitry Andric StringRef FS); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric private: 1660b57cec5SDimitry Andric void initializeEnvironment(); 167bdd1243dSDimitry Andric void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric public: 1700b57cec5SDimitry Andric /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. 1710b57cec5SDimitry Andric /// 1720b57cec5SDimitry Andric bool isPPC64() const; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // useSoftFloat - Return true if soft-float option is turned on. 1758bcb0991SDimitry Andric bool useSoftFloat() const { 1768bcb0991SDimitry Andric if (isAIXABI() && !HasHardFloat) 1778bcb0991SDimitry Andric report_fatal_error("soft-float is not yet supported on AIX."); 1788bcb0991SDimitry Andric return !HasHardFloat; 1798bcb0991SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric // isLittleEndian - True if generating little-endian code 1820b57cec5SDimitry Andric bool isLittleEndian() const { return IsLittleEndian; } 1830b57cec5SDimitry Andric 184bdd1243dSDimitry Andric // Getters for SubtargetFeatures defined in tablegen. 185bdd1243dSDimitry Andric #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 186bdd1243dSDimitry Andric bool GETTER() const { return ATTRIBUTE; } 187bdd1243dSDimitry Andric #include "PPCGenSubtargetInfo.inc" 1880b57cec5SDimitry Andric 1898bcb0991SDimitry Andric Align getPlatformStackAlignment() const { 1908bcb0991SDimitry Andric return Align(16); 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric unsigned getRedZoneSize() const { 1945ffd83dbSDimitry Andric if (isPPC64()) 1955ffd83dbSDimitry Andric // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved) 1965ffd83dbSDimitry Andric return 288; 1975ffd83dbSDimitry Andric 1985ffd83dbSDimitry Andric // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs); 1995ffd83dbSDimitry Andric // PPC32 SVR4ABI has no redzone. 2005ffd83dbSDimitry Andric return isAIXABI() ? 220 : 0; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric bool needsSwapsForVSXMemOps() const { 2040b57cec5SDimitry Andric return hasVSX() && isLittleEndian() && !hasP9Vector(); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric const Triple &getTargetTriple() const { return TargetTriple; } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 2120b57cec5SDimitry Andric bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 2130b57cec5SDimitry Andric bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool isAIXABI() const { return TargetTriple.isOSAIX(); } 2165ffd83dbSDimitry Andric bool isSVR4ABI() const { return !isAIXABI(); } 2170b57cec5SDimitry Andric bool isELFv2ABI() const; 2180b57cec5SDimitry Andric 2198bcb0991SDimitry Andric bool is64BitELFABI() const { return isSVR4ABI() && isPPC64(); } 2208bcb0991SDimitry Andric bool is32BitELFABI() const { return isSVR4ABI() && !isPPC64(); } 2215ffd83dbSDimitry Andric bool isUsingPCRelativeCalls() const; 2228bcb0991SDimitry Andric 2230b57cec5SDimitry Andric /// Originally, this function return hasISEL(). Now we always enable it, 2240b57cec5SDimitry Andric /// but may expand the ISEL instruction later. 2250b57cec5SDimitry Andric bool enableEarlyIfConversion() const override { return true; } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric /// Scheduling customization. 2280b57cec5SDimitry Andric bool enableMachineScheduler() const override; 2290b57cec5SDimitry Andric /// Pipeliner customization. 2300b57cec5SDimitry Andric bool enableMachinePipeliner() const override; 2310b57cec5SDimitry Andric /// Machine Pipeliner customization 2320b57cec5SDimitry Andric bool useDFAforSMS() const override; 2330b57cec5SDimitry Andric /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 2340b57cec5SDimitry Andric bool enablePostRAScheduler() const override; 2350b57cec5SDimitry Andric AntiDepBreakMode getAntiDepBreakMode() const override; 2360b57cec5SDimitry Andric void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric void overrideSchedPolicy(MachineSchedPolicy &Policy, 2390b57cec5SDimitry Andric unsigned NumRegionInstrs) const override; 2400b57cec5SDimitry Andric bool useAA() const override; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric bool enableSubRegLiveness() const override; 2430b57cec5SDimitry Andric 24406c3fb27SDimitry Andric bool enableSpillageCopyElimination() const override { return true; } 24506c3fb27SDimitry Andric 2468bcb0991SDimitry Andric /// True if the GV will be accessed via an indirect symbol. 2478bcb0991SDimitry Andric bool isGVIndirectSymbol(const GlobalValue *GV) const; 2480b57cec5SDimitry Andric 2490fca6ea1SDimitry Andric /// Calculates the effective code model for argument GV. 2500fca6ea1SDimitry Andric CodeModel::Model getCodeModel(const TargetMachine &TM, 2510fca6ea1SDimitry Andric const GlobalValue *GV) const; 2520fca6ea1SDimitry Andric 253480093f4SDimitry Andric /// True if the ABI is descriptor based. 254480093f4SDimitry Andric bool usesFunctionDescriptors() const { 255480093f4SDimitry Andric // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit 256480093f4SDimitry Andric // v1 ABI uses descriptors. 257480093f4SDimitry Andric return isAIXABI() || (is64BitELFABI() && !isELFv2ABI()); 258480093f4SDimitry Andric } 259480093f4SDimitry Andric 260480093f4SDimitry Andric unsigned descriptorTOCAnchorOffset() const { 261480093f4SDimitry Andric assert(usesFunctionDescriptors() && 262480093f4SDimitry Andric "Should only be called when the target uses descriptors."); 263480093f4SDimitry Andric return IsPPC64 ? 8 : 4; 264480093f4SDimitry Andric } 265480093f4SDimitry Andric 266480093f4SDimitry Andric unsigned descriptorEnvironmentPointerOffset() const { 267480093f4SDimitry Andric assert(usesFunctionDescriptors() && 268480093f4SDimitry Andric "Should only be called when the target uses descriptors."); 269480093f4SDimitry Andric return IsPPC64 ? 16 : 8; 270480093f4SDimitry Andric } 271480093f4SDimitry Andric 272480093f4SDimitry Andric MCRegister getEnvironmentPointerRegister() const { 273480093f4SDimitry Andric assert(usesFunctionDescriptors() && 274480093f4SDimitry Andric "Should only be called when the target uses descriptors."); 275480093f4SDimitry Andric return IsPPC64 ? PPC::X11 : PPC::R11; 276480093f4SDimitry Andric } 277480093f4SDimitry Andric 278480093f4SDimitry Andric MCRegister getTOCPointerRegister() const { 279480093f4SDimitry Andric assert((is64BitELFABI() || isAIXABI()) && 280480093f4SDimitry Andric "Should only be called when the target is a TOC based ABI."); 281480093f4SDimitry Andric return IsPPC64 ? PPC::X2 : PPC::R2; 282480093f4SDimitry Andric } 283480093f4SDimitry Andric 28406c3fb27SDimitry Andric MCRegister getThreadPointerRegister() const { 28506c3fb27SDimitry Andric assert((is64BitELFABI() || isAIXABI()) && 28606c3fb27SDimitry Andric "Should only be called for targets with a thread pointer register."); 28706c3fb27SDimitry Andric return IsPPC64 ? PPC::X13 : PPC::R13; 28806c3fb27SDimitry Andric } 28906c3fb27SDimitry Andric 290480093f4SDimitry Andric MCRegister getStackPointerRegister() const { 291480093f4SDimitry Andric return IsPPC64 ? PPC::X1 : PPC::R1; 292480093f4SDimitry Andric } 293480093f4SDimitry Andric 2940b57cec5SDimitry Andric bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } 2955ffd83dbSDimitry Andric 2965ffd83dbSDimitry Andric bool isPredictableSelectIsExpensive() const { 2975ffd83dbSDimitry Andric return PredictableSelectIsExpensive; 2985ffd83dbSDimitry Andric } 299e8d8bef9SDimitry Andric 300fe6060f1SDimitry Andric // Select allocation orders of GPRC and G8RC. It should be strictly consistent 301fe6060f1SDimitry Andric // with corresponding AltOrders in PPCRegisterInfo.td. 302fe6060f1SDimitry Andric unsigned getGPRAllocationOrderIdx() const { 303fe6060f1SDimitry Andric if (is64BitELFABI()) 304fe6060f1SDimitry Andric return 1; 305fe6060f1SDimitry Andric if (isAIXABI()) 306fe6060f1SDimitry Andric return 2; 307fe6060f1SDimitry Andric return 0; 308fe6060f1SDimitry Andric } 309fe6060f1SDimitry Andric 310e8d8bef9SDimitry Andric // GlobalISEL 311e8d8bef9SDimitry Andric const CallLowering *getCallLowering() const override; 312e8d8bef9SDimitry Andric const RegisterBankInfo *getRegBankInfo() const override; 313e8d8bef9SDimitry Andric const LegalizerInfo *getLegalizerInfo() const override; 314e8d8bef9SDimitry Andric InstructionSelector *getInstructionSelector() const override; 3150b57cec5SDimitry Andric }; 3160b57cec5SDimitry Andric } // End llvm namespace 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric #endif 319