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