xref: /llvm-project/llvm/lib/Target/PowerPC/PPCSubtarget.h (revision 03847f19f2e462a339e1afa1093f253ec8a23765)
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