1 //===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares the PowerPC specific subclass of TargetSubtargetInfo. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 14 #define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H 15 16 #include "PPCFrameLowering.h" 17 #include "PPCISelLowering.h" 18 #include "PPCInstrInfo.h" 19 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 20 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 21 #include "llvm/CodeGen/RegisterBankInfo.h" 22 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 23 #include "llvm/CodeGen/TargetSubtargetInfo.h" 24 #include "llvm/IR/DataLayout.h" 25 #include "llvm/MC/MCInstrItineraries.h" 26 #include "llvm/TargetParser/Triple.h" 27 #include <string> 28 29 #define GET_SUBTARGETINFO_HEADER 30 #include "PPCGenSubtargetInfo.inc" 31 32 // GCC #defines PPC on Linux but we use it as our namespace name 33 #undef PPC 34 35 namespace llvm { 36 class StringRef; 37 38 namespace PPC { 39 // -m directive values. 40 enum { 41 DIR_NONE, 42 DIR_32, 43 DIR_440, 44 DIR_601, 45 DIR_602, 46 DIR_603, 47 DIR_7400, 48 DIR_750, 49 DIR_970, 50 DIR_A2, 51 DIR_E500, 52 DIR_E500mc, 53 DIR_E5500, 54 DIR_PWR3, 55 DIR_PWR4, 56 DIR_PWR5, 57 DIR_PWR5X, 58 DIR_PWR6, 59 DIR_PWR6X, 60 DIR_PWR7, 61 DIR_PWR8, 62 DIR_PWR9, 63 DIR_PWR10, 64 DIR_PWR11, 65 DIR_PWR_FUTURE, 66 DIR_64 67 }; 68 } 69 70 class GlobalValue; 71 72 class PPCSubtarget : public PPCGenSubtargetInfo { 73 public: 74 enum POPCNTDKind { 75 POPCNTD_Unavailable, 76 POPCNTD_Slow, 77 POPCNTD_Fast 78 }; 79 80 protected: 81 /// TargetTriple - What processor and OS we're targeting. 82 Triple TargetTriple; 83 84 /// stackAlignment - The minimum alignment known to hold of the stack frame on 85 /// entry to the function and which must be maintained by every function. 86 Align StackAlignment; 87 88 /// Selected instruction itineraries (one entry per itinerary class.) 89 InstrItineraryData InstrItins; 90 91 // Bool members corresponding to the SubtargetFeatures defined in tablegen. 92 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 93 bool ATTRIBUTE = DEFAULT; 94 #include "PPCGenSubtargetInfo.inc" 95 96 /// Which cpu directive was used. 97 unsigned CPUDirective; 98 99 bool IsPPC64; 100 bool IsLittleEndian; 101 102 POPCNTDKind HasPOPCNTD; 103 104 const PPCTargetMachine &TM; 105 PPCFrameLowering FrameLowering; 106 PPCInstrInfo InstrInfo; 107 PPCTargetLowering TLInfo; 108 SelectionDAGTargetInfo TSInfo; 109 110 /// GlobalISel related APIs. 111 std::unique_ptr<CallLowering> CallLoweringInfo; 112 std::unique_ptr<LegalizerInfo> Legalizer; 113 std::unique_ptr<RegisterBankInfo> RegBankInfo; 114 std::unique_ptr<InstructionSelector> InstSelector; 115 116 public: 117 /// This constructor initializes the data members to match that 118 /// of the specified triple. 119 /// 120 PPCSubtarget(const Triple &TT, const std::string &CPU, 121 const std::string &TuneCPU, const std::string &FS, 122 const PPCTargetMachine &TM); 123 124 /// ParseSubtargetFeatures - Parses features string setting specified 125 /// subtarget options. Definition of function is auto generated by tblgen. 126 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 127 128 /// getStackAlignment - Returns the minimum alignment known to hold of the 129 /// stack frame on entry to the function and which must be maintained by every 130 /// function for this subtarget. getStackAlignment()131 Align getStackAlignment() const { return StackAlignment; } 132 133 /// getCPUDirective - Returns the -m directive specified for the cpu. 134 /// getCPUDirective()135 unsigned getCPUDirective() const { return CPUDirective; } 136 137 /// getInstrItins - Return the instruction itineraries based on subtarget 138 /// selection. getInstrItineraryData()139 const InstrItineraryData *getInstrItineraryData() const override { 140 return &InstrItins; 141 } 142 getFrameLowering()143 const PPCFrameLowering *getFrameLowering() const override { 144 return &FrameLowering; 145 } getInstrInfo()146 const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } getTargetLowering()147 const PPCTargetLowering *getTargetLowering() const override { 148 return &TLInfo; 149 } getSelectionDAGInfo()150 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 151 return &TSInfo; 152 } getRegisterInfo()153 const PPCRegisterInfo *getRegisterInfo() const override { 154 return &getInstrInfo()->getRegisterInfo(); 155 } getTargetMachine()156 const PPCTargetMachine &getTargetMachine() const { return TM; } 157 158 /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU, and 159 /// feature string so that we can use initializer lists for subtarget 160 /// initialization. 161 PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, 162 StringRef TuneCPU, 163 StringRef FS); 164 165 private: 166 void initializeEnvironment(); 167 void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 168 169 public: 170 /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. 171 /// 172 bool isPPC64() const; 173 174 // useSoftFloat - Return true if soft-float option is turned on. useSoftFloat()175 bool useSoftFloat() const { 176 if (isAIXABI() && !HasHardFloat) 177 report_fatal_error("soft-float is not yet supported on AIX."); 178 return !HasHardFloat; 179 } 180 181 // isLittleEndian - True if generating little-endian code isLittleEndian()182 bool isLittleEndian() const { return IsLittleEndian; } 183 184 // Getters for SubtargetFeatures defined in tablegen. 185 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 186 bool GETTER() const { return ATTRIBUTE; } 187 #include "PPCGenSubtargetInfo.inc" 188 getPlatformStackAlignment()189 Align getPlatformStackAlignment() const { 190 return Align(16); 191 } 192 getRedZoneSize()193 unsigned getRedZoneSize() const { 194 if (isPPC64()) 195 // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved) 196 return 288; 197 198 // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs); 199 // PPC32 SVR4ABI has no redzone. 200 return isAIXABI() ? 220 : 0; 201 } 202 needsSwapsForVSXMemOps()203 bool needsSwapsForVSXMemOps() const { 204 return hasVSX() && isLittleEndian() && !hasP9Vector(); 205 } 206 hasPOPCNTD()207 POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } 208 getTargetTriple()209 const Triple &getTargetTriple() const { return TargetTriple; } 210 isTargetELF()211 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } isTargetMachO()212 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } isTargetLinux()213 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 214 isAIXABI()215 bool isAIXABI() const { return TargetTriple.isOSAIX(); } isSVR4ABI()216 bool isSVR4ABI() const { return !isAIXABI(); } 217 bool isELFv2ABI() const; 218 is64BitELFABI()219 bool is64BitELFABI() const { return isSVR4ABI() && isPPC64(); } is32BitELFABI()220 bool is32BitELFABI() const { return isSVR4ABI() && !isPPC64(); } 221 bool isUsingPCRelativeCalls() const; 222 223 /// Originally, this function return hasISEL(). Now we always enable it, 224 /// but may expand the ISEL instruction later. enableEarlyIfConversion()225 bool enableEarlyIfConversion() const override { return true; } 226 227 /// Scheduling customization. 228 bool enableMachineScheduler() const override; 229 /// Pipeliner customization. 230 bool enableMachinePipeliner() const override; 231 /// Machine Pipeliner customization 232 bool useDFAforSMS() const override; 233 /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 234 bool enablePostRAScheduler() const override; 235 AntiDepBreakMode getAntiDepBreakMode() const override; 236 void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 237 238 void overrideSchedPolicy(MachineSchedPolicy &Policy, 239 unsigned NumRegionInstrs) const override; 240 bool useAA() const override; 241 242 bool enableSubRegLiveness() const override; 243 enableSpillageCopyElimination()244 bool enableSpillageCopyElimination() const override { return true; } 245 246 /// True if the GV will be accessed via an indirect symbol. 247 bool isGVIndirectSymbol(const GlobalValue *GV) const; 248 249 /// Calculates the effective code model for argument GV. 250 CodeModel::Model getCodeModel(const TargetMachine &TM, 251 const GlobalValue *GV) const; 252 253 /// True if the ABI is descriptor based. usesFunctionDescriptors()254 bool usesFunctionDescriptors() const { 255 // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit 256 // v1 ABI uses descriptors. 257 return isAIXABI() || (is64BitELFABI() && !isELFv2ABI()); 258 } 259 descriptorTOCAnchorOffset()260 unsigned descriptorTOCAnchorOffset() const { 261 assert(usesFunctionDescriptors() && 262 "Should only be called when the target uses descriptors."); 263 return IsPPC64 ? 8 : 4; 264 } 265 descriptorEnvironmentPointerOffset()266 unsigned descriptorEnvironmentPointerOffset() const { 267 assert(usesFunctionDescriptors() && 268 "Should only be called when the target uses descriptors."); 269 return IsPPC64 ? 16 : 8; 270 } 271 getEnvironmentPointerRegister()272 MCRegister getEnvironmentPointerRegister() const { 273 assert(usesFunctionDescriptors() && 274 "Should only be called when the target uses descriptors."); 275 return IsPPC64 ? PPC::X11 : PPC::R11; 276 } 277 getTOCPointerRegister()278 MCRegister getTOCPointerRegister() const { 279 assert((is64BitELFABI() || isAIXABI()) && 280 "Should only be called when the target is a TOC based ABI."); 281 return IsPPC64 ? PPC::X2 : PPC::R2; 282 } 283 getThreadPointerRegister()284 MCRegister getThreadPointerRegister() const { 285 assert((is64BitELFABI() || isAIXABI()) && 286 "Should only be called for targets with a thread pointer register."); 287 return IsPPC64 ? PPC::X13 : PPC::R13; 288 } 289 getStackPointerRegister()290 MCRegister getStackPointerRegister() const { 291 return IsPPC64 ? PPC::X1 : PPC::R1; 292 } 293 isXRaySupported()294 bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } 295 isPredictableSelectIsExpensive()296 bool isPredictableSelectIsExpensive() const { 297 return PredictableSelectIsExpensive; 298 } 299 300 // Select allocation orders of GPRC and G8RC. It should be strictly consistent 301 // with corresponding AltOrders in PPCRegisterInfo.td. getGPRAllocationOrderIdx()302 unsigned getGPRAllocationOrderIdx() const { 303 if (is64BitELFABI()) 304 return 1; 305 if (isAIXABI()) 306 return 2; 307 return 0; 308 } 309 310 // GlobalISEL 311 const CallLowering *getCallLowering() const override; 312 const RegisterBankInfo *getRegBankInfo() const override; 313 const LegalizerInfo *getLegalizerInfo() const override; 314 InstructionSelector *getInstructionSelector() const override; 315 }; 316 } // End llvm namespace 317 318 #endif 319