xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.h (revision 36b606ae6aa4b24061096ba18582e0a08ccd5dba)
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