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
35namespace llvm {
36class StringRef;
37
38namespace PPC {
39  // -m directive values.
40enum {
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_PWR_FUTURE,
65  DIR_64
66};
67}
68
69class GlobalValue;
70
71class PPCSubtarget : public PPCGenSubtargetInfo {
72public:
73  enum POPCNTDKind {
74    POPCNTD_Unavailable,
75    POPCNTD_Slow,
76    POPCNTD_Fast
77  };
78
79protected:
80  /// TargetTriple - What processor and OS we're targeting.
81  Triple TargetTriple;
82
83  /// stackAlignment - The minimum alignment known to hold of the stack frame on
84  /// entry to the function and which must be maintained by every function.
85  Align StackAlignment;
86
87  /// Selected instruction itineraries (one entry per itinerary class.)
88  InstrItineraryData InstrItins;
89
90// Bool members corresponding to the SubtargetFeatures defined in tablegen.
91#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
92  bool ATTRIBUTE = DEFAULT;
93#include "PPCGenSubtargetInfo.inc"
94
95  /// Which cpu directive was used.
96  unsigned CPUDirective;
97
98  bool IsPPC64;
99  bool IsLittleEndian;
100
101  POPCNTDKind HasPOPCNTD;
102
103  const PPCTargetMachine &TM;
104  PPCFrameLowering FrameLowering;
105  PPCInstrInfo InstrInfo;
106  PPCTargetLowering TLInfo;
107  SelectionDAGTargetInfo TSInfo;
108
109  /// GlobalISel related APIs.
110  std::unique_ptr<CallLowering> CallLoweringInfo;
111  std::unique_ptr<LegalizerInfo> Legalizer;
112  std::unique_ptr<RegisterBankInfo> RegBankInfo;
113  std::unique_ptr<InstructionSelector> InstSelector;
114
115public:
116  /// This constructor initializes the data members to match that
117  /// of the specified triple.
118  ///
119  PPCSubtarget(const Triple &TT, const std::string &CPU,
120               const std::string &TuneCPU, const std::string &FS,
121               const PPCTargetMachine &TM);
122
123  /// ParseSubtargetFeatures - Parses features string setting specified
124  /// subtarget options.  Definition of function is auto generated by tblgen.
125  void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
126
127  /// getStackAlignment - Returns the minimum alignment known to hold of the
128  /// stack frame on entry to the function and which must be maintained by every
129  /// function for this subtarget.
130  Align getStackAlignment() const { return StackAlignment; }
131
132  /// getCPUDirective - Returns the -m directive specified for the cpu.
133  ///
134  unsigned getCPUDirective() const { return CPUDirective; }
135
136  /// getInstrItins - Return the instruction itineraries based on subtarget
137  /// selection.
138  const InstrItineraryData *getInstrItineraryData() const override {
139    return &InstrItins;
140  }
141
142  const PPCFrameLowering *getFrameLowering() const override {
143    return &FrameLowering;
144  }
145  const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; }
146  const PPCTargetLowering *getTargetLowering() const override {
147    return &TLInfo;
148  }
149  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
150    return &TSInfo;
151  }
152  const PPCRegisterInfo *getRegisterInfo() const override {
153    return &getInstrInfo()->getRegisterInfo();
154  }
155  const PPCTargetMachine &getTargetMachine() const { return TM; }
156
157  /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU,  and
158  /// feature string so that we can use initializer lists for subtarget
159  /// initialization.
160  PPCSubtarget &initializeSubtargetDependencies(StringRef CPU,
161                                                StringRef TuneCPU,
162                                                StringRef FS);
163
164private:
165  void initializeEnvironment();
166  void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
167
168public:
169  /// isPPC64 - Return true if we are generating code for 64-bit pointer mode.
170  ///
171  bool isPPC64() const;
172
173  // useSoftFloat - Return true if soft-float option is turned on.
174  bool useSoftFloat() const {
175    if (isAIXABI() && !HasHardFloat)
176      report_fatal_error("soft-float is not yet supported on AIX.");
177    return !HasHardFloat;
178  }
179
180  // isLittleEndian - True if generating little-endian code
181  bool isLittleEndian() const { return IsLittleEndian; }
182
183// Getters for SubtargetFeatures defined in tablegen.
184#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
185  bool GETTER() const { return ATTRIBUTE; }
186#include "PPCGenSubtargetInfo.inc"
187
188  Align getPlatformStackAlignment() const {
189    return Align(16);
190  }
191
192  unsigned  getRedZoneSize() const {
193    if (isPPC64())
194      // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved)
195      return 288;
196
197    // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs);
198    // PPC32 SVR4ABI has no redzone.
199    return isAIXABI() ? 220 : 0;
200  }
201
202  bool needsSwapsForVSXMemOps() const {
203    return hasVSX() && isLittleEndian() && !hasP9Vector();
204  }
205
206  POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; }
207
208  const Triple &getTargetTriple() const { return TargetTriple; }
209
210  bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
211  bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
212  bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
213
214  bool isAIXABI() const { return TargetTriple.isOSAIX(); }
215  bool isSVR4ABI() const { return !isAIXABI(); }
216  bool isELFv2ABI() const;
217
218  bool is64BitELFABI() const { return  isSVR4ABI() && isPPC64(); }
219  bool is32BitELFABI() const { return  isSVR4ABI() && !isPPC64(); }
220  bool isUsingPCRelativeCalls() const;
221
222  /// Originally, this function return hasISEL(). Now we always enable it,
223  /// but may expand the ISEL instruction later.
224  bool enableEarlyIfConversion() const override { return true; }
225
226  /// Scheduling customization.
227  bool enableMachineScheduler() const override;
228  /// Pipeliner customization.
229  bool enableMachinePipeliner() const override;
230  /// Machine Pipeliner customization
231  bool useDFAforSMS() const override;
232  /// This overrides the PostRAScheduler bit in the SchedModel for each CPU.
233  bool enablePostRAScheduler() const override;
234  AntiDepBreakMode getAntiDepBreakMode() const override;
235  void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override;
236
237  void overrideSchedPolicy(MachineSchedPolicy &Policy,
238                           unsigned NumRegionInstrs) const override;
239  bool useAA() const override;
240
241  bool enableSubRegLiveness() const override;
242
243  bool enableSpillageCopyElimination() const override { return true; }
244
245  /// True if the GV will be accessed via an indirect symbol.
246  bool isGVIndirectSymbol(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-bit
251    // 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 consistent
296  // 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  // GlobalISEL
306  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 namespace
312
313#endif
314