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/TargetSubtargetInfo.h" 23 #include "llvm/IR/DataLayout.h" 24 #include "llvm/MC/MCInstrItineraries.h" 25 #include "llvm/TargetParser/Triple.h" 26 #include <string> 27 28 #define GET_SUBTARGETINFO_HEADER 29 #include "PPCGenSubtargetInfo.inc" 30 31 // GCC #defines PPC on Linux but we use it as our namespace name 32 #undef PPC 33 34 namespace llvm { 35 class SelectionDAGTargetInfo; 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 109 // SelectionDAGISel related APIs. 110 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo; 111 112 /// GlobalISel related APIs. 113 std::unique_ptr<CallLowering> CallLoweringInfo; 114 std::unique_ptr<LegalizerInfo> Legalizer; 115 std::unique_ptr<RegisterBankInfo> RegBankInfo; 116 std::unique_ptr<InstructionSelector> InstSelector; 117 118 public: 119 /// This constructor initializes the data members to match that 120 /// of the specified triple. 121 /// 122 PPCSubtarget(const Triple &TT, const std::string &CPU, 123 const std::string &TuneCPU, const std::string &FS, 124 const PPCTargetMachine &TM); 125 126 ~PPCSubtarget() override; 127 128 /// ParseSubtargetFeatures - Parses features string setting specified 129 /// subtarget options. Definition of function is auto generated by tblgen. 130 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 131 132 /// getStackAlignment - Returns the minimum alignment known to hold of the 133 /// stack frame on entry to the function and which must be maintained by every 134 /// function for this subtarget. 135 Align getStackAlignment() const { return StackAlignment; } 136 137 /// getCPUDirective - Returns the -m directive specified for the cpu. 138 /// 139 unsigned getCPUDirective() const { return CPUDirective; } 140 141 /// getInstrItins - Return the instruction itineraries based on subtarget 142 /// selection. 143 const InstrItineraryData *getInstrItineraryData() const override { 144 return &InstrItins; 145 } 146 147 const PPCFrameLowering *getFrameLowering() const override { 148 return &FrameLowering; 149 } 150 const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; } 151 const PPCTargetLowering *getTargetLowering() const override { 152 return &TLInfo; 153 } 154 155 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override; 156 157 const PPCRegisterInfo *getRegisterInfo() const override { 158 return &getInstrInfo()->getRegisterInfo(); 159 } 160 const PPCTargetMachine &getTargetMachine() const { return TM; } 161 162 /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU, and 163 /// feature string so that we can use initializer lists for subtarget 164 /// initialization. 165 PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, 166 StringRef TuneCPU, 167 StringRef FS); 168 169 private: 170 void initializeEnvironment(); 171 void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 172 173 public: 174 /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. 175 /// 176 bool isPPC64() const; 177 178 // useSoftFloat - Return true if soft-float option is turned on. 179 bool useSoftFloat() const { 180 if (isAIXABI() && !HasHardFloat) 181 report_fatal_error("soft-float is not yet supported on AIX."); 182 return !HasHardFloat; 183 } 184 185 // isLittleEndian - True if generating little-endian code 186 bool isLittleEndian() const { return IsLittleEndian; } 187 188 // Getters for SubtargetFeatures defined in tablegen. 189 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 190 bool GETTER() const { return ATTRIBUTE; } 191 #include "PPCGenSubtargetInfo.inc" 192 193 Align getPlatformStackAlignment() const { 194 return Align(16); 195 } 196 197 unsigned getRedZoneSize() const { 198 if (isPPC64()) 199 // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved) 200 return 288; 201 202 // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs); 203 // PPC32 SVR4ABI has no redzone. 204 return isAIXABI() ? 220 : 0; 205 } 206 207 bool needsSwapsForVSXMemOps() const { 208 return hasVSX() && isLittleEndian() && !hasP9Vector(); 209 } 210 211 POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; } 212 213 const Triple &getTargetTriple() const { return TargetTriple; } 214 215 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 216 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 217 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 218 219 bool isAIXABI() const { return TargetTriple.isOSAIX(); } 220 bool isSVR4ABI() const { return !isAIXABI(); } 221 bool isELFv2ABI() const; 222 223 bool is64BitELFABI() const { return isSVR4ABI() && isPPC64(); } 224 bool is32BitELFABI() const { return isSVR4ABI() && !isPPC64(); } 225 bool isUsingPCRelativeCalls() const; 226 227 /// Originally, this function return hasISEL(). Now we always enable it, 228 /// but may expand the ISEL instruction later. 229 bool enableEarlyIfConversion() const override { return true; } 230 231 /// Scheduling customization. 232 bool enableMachineScheduler() const override; 233 /// Pipeliner customization. 234 bool enableMachinePipeliner() const override; 235 /// Machine Pipeliner customization 236 bool useDFAforSMS() const override; 237 /// This overrides the PostRAScheduler bit in the SchedModel for each CPU. 238 bool enablePostRAScheduler() const override; 239 AntiDepBreakMode getAntiDepBreakMode() const override; 240 void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override; 241 242 void overrideSchedPolicy(MachineSchedPolicy &Policy, 243 unsigned NumRegionInstrs) const override; 244 bool useAA() const override; 245 246 bool enableSubRegLiveness() const override; 247 248 bool enableSpillageCopyElimination() const override { return true; } 249 250 /// True if the GV will be accessed via an indirect symbol. 251 bool isGVIndirectSymbol(const GlobalValue *GV) const; 252 253 MVT getScalarIntVT() const { return isPPC64() ? MVT::i64 : MVT::i32; } 254 255 /// Calculates the effective code model for argument GV. 256 CodeModel::Model getCodeModel(const TargetMachine &TM, 257 const GlobalValue *GV) const; 258 259 /// True if the ABI is descriptor based. 260 bool usesFunctionDescriptors() const { 261 // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit 262 // v1 ABI uses descriptors. 263 return isAIXABI() || (is64BitELFABI() && !isELFv2ABI()); 264 } 265 266 unsigned descriptorTOCAnchorOffset() const { 267 assert(usesFunctionDescriptors() && 268 "Should only be called when the target uses descriptors."); 269 return IsPPC64 ? 8 : 4; 270 } 271 272 unsigned descriptorEnvironmentPointerOffset() const { 273 assert(usesFunctionDescriptors() && 274 "Should only be called when the target uses descriptors."); 275 return IsPPC64 ? 16 : 8; 276 } 277 278 MCRegister getEnvironmentPointerRegister() const { 279 assert(usesFunctionDescriptors() && 280 "Should only be called when the target uses descriptors."); 281 return IsPPC64 ? PPC::X11 : PPC::R11; 282 } 283 284 MCRegister getTOCPointerRegister() const { 285 assert((is64BitELFABI() || isAIXABI()) && 286 "Should only be called when the target is a TOC based ABI."); 287 return IsPPC64 ? PPC::X2 : PPC::R2; 288 } 289 290 MCRegister getThreadPointerRegister() const { 291 assert((is64BitELFABI() || isAIXABI()) && 292 "Should only be called for targets with a thread pointer register."); 293 return IsPPC64 ? PPC::X13 : PPC::R13; 294 } 295 296 MCRegister getStackPointerRegister() const { 297 return IsPPC64 ? PPC::X1 : PPC::R1; 298 } 299 300 bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; } 301 302 bool isPredictableSelectIsExpensive() const { 303 return PredictableSelectIsExpensive; 304 } 305 306 // Select allocation orders of GPRC and G8RC. It should be strictly consistent 307 // with corresponding AltOrders in PPCRegisterInfo.td. 308 unsigned getGPRAllocationOrderIdx() const { 309 if (is64BitELFABI()) 310 return 1; 311 if (isAIXABI()) 312 return 2; 313 return 0; 314 } 315 316 // GlobalISEL 317 const CallLowering *getCallLowering() const override; 318 const RegisterBankInfo *getRegBankInfo() const override; 319 const LegalizerInfo *getLegalizerInfo() const override; 320 InstructionSelector *getInstructionSelector() const override; 321 }; 322 } // End llvm namespace 323 324 #endif 325