xref: /openbsd-src/gnu/llvm/llvm/lib/Target/PowerPC/PPCSubtarget.h (revision a96b36398fcfb4953e8190127da8bf074c7552f1)
109467b48Spatrick //===-- PPCSubtarget.h - Define Subtarget for the PPC ----------*- C++ -*--===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file declares the PowerPC specific subclass of TargetSubtargetInfo.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #ifndef LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H
1409467b48Spatrick #define LLVM_LIB_TARGET_POWERPC_PPCSUBTARGET_H
1509467b48Spatrick 
1609467b48Spatrick #include "PPCFrameLowering.h"
1709467b48Spatrick #include "PPCISelLowering.h"
1809467b48Spatrick #include "PPCInstrInfo.h"
1909467b48Spatrick #include "llvm/ADT/Triple.h"
20a0747c9fSpatrick #include "llvm/CodeGen/GlobalISel/CallLowering.h"
21a0747c9fSpatrick #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
22*a96b3639Srobert #include "llvm/CodeGen/RegisterBankInfo.h"
2309467b48Spatrick #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
2409467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
2509467b48Spatrick #include "llvm/IR/DataLayout.h"
2609467b48Spatrick #include "llvm/MC/MCInstrItineraries.h"
2709467b48Spatrick #include <string>
2809467b48Spatrick 
2909467b48Spatrick #define GET_SUBTARGETINFO_HEADER
3009467b48Spatrick #include "PPCGenSubtargetInfo.inc"
3109467b48Spatrick 
3209467b48Spatrick // GCC #defines PPC on Linux but we use it as our namespace name
3309467b48Spatrick #undef PPC
3409467b48Spatrick 
3509467b48Spatrick namespace llvm {
3609467b48Spatrick class StringRef;
3709467b48Spatrick 
3809467b48Spatrick namespace PPC {
3909467b48Spatrick   // -m directive values.
4009467b48Spatrick enum {
4109467b48Spatrick   DIR_NONE,
4209467b48Spatrick   DIR_32,
4309467b48Spatrick   DIR_440,
4409467b48Spatrick   DIR_601,
4509467b48Spatrick   DIR_602,
4609467b48Spatrick   DIR_603,
4709467b48Spatrick   DIR_7400,
4809467b48Spatrick   DIR_750,
4909467b48Spatrick   DIR_970,
5009467b48Spatrick   DIR_A2,
5109467b48Spatrick   DIR_E500,
5209467b48Spatrick   DIR_E500mc,
5309467b48Spatrick   DIR_E5500,
5409467b48Spatrick   DIR_PWR3,
5509467b48Spatrick   DIR_PWR4,
5609467b48Spatrick   DIR_PWR5,
5709467b48Spatrick   DIR_PWR5X,
5809467b48Spatrick   DIR_PWR6,
5909467b48Spatrick   DIR_PWR6X,
6009467b48Spatrick   DIR_PWR7,
6109467b48Spatrick   DIR_PWR8,
6209467b48Spatrick   DIR_PWR9,
63adae0cfdSpatrick   DIR_PWR10,
6409467b48Spatrick   DIR_PWR_FUTURE,
6509467b48Spatrick   DIR_64
6609467b48Spatrick };
6709467b48Spatrick }
6809467b48Spatrick 
6909467b48Spatrick class GlobalValue;
7009467b48Spatrick 
7109467b48Spatrick class PPCSubtarget : public PPCGenSubtargetInfo {
7209467b48Spatrick public:
7309467b48Spatrick   enum POPCNTDKind {
7409467b48Spatrick     POPCNTD_Unavailable,
7509467b48Spatrick     POPCNTD_Slow,
7609467b48Spatrick     POPCNTD_Fast
7709467b48Spatrick   };
7809467b48Spatrick 
7909467b48Spatrick protected:
8009467b48Spatrick   /// TargetTriple - What processor and OS we're targeting.
8109467b48Spatrick   Triple TargetTriple;
8209467b48Spatrick 
8309467b48Spatrick   /// stackAlignment - The minimum alignment known to hold of the stack frame on
8409467b48Spatrick   /// entry to the function and which must be maintained by every function.
8509467b48Spatrick   Align StackAlignment;
8609467b48Spatrick 
8709467b48Spatrick   /// Selected instruction itineraries (one entry per itinerary class.)
8809467b48Spatrick   InstrItineraryData InstrItins;
8909467b48Spatrick 
90*a96b3639Srobert // Bool members corresponding to the SubtargetFeatures defined in tablegen.
91*a96b3639Srobert #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
92*a96b3639Srobert   bool ATTRIBUTE = DEFAULT;
93*a96b3639Srobert #include "PPCGenSubtargetInfo.inc"
94*a96b3639Srobert 
9509467b48Spatrick   /// Which cpu directive was used.
9609467b48Spatrick   unsigned CPUDirective;
9709467b48Spatrick 
9809467b48Spatrick   bool IsPPC64;
9909467b48Spatrick   bool IsLittleEndian;
10009467b48Spatrick 
10109467b48Spatrick   POPCNTDKind HasPOPCNTD;
10209467b48Spatrick 
10309467b48Spatrick   const PPCTargetMachine &TM;
10409467b48Spatrick   PPCFrameLowering FrameLowering;
10509467b48Spatrick   PPCInstrInfo InstrInfo;
10609467b48Spatrick   PPCTargetLowering TLInfo;
10709467b48Spatrick   SelectionDAGTargetInfo TSInfo;
10809467b48Spatrick 
109a0747c9fSpatrick   /// GlobalISel related APIs.
110a0747c9fSpatrick   std::unique_ptr<CallLowering> CallLoweringInfo;
111a0747c9fSpatrick   std::unique_ptr<LegalizerInfo> Legalizer;
112a0747c9fSpatrick   std::unique_ptr<RegisterBankInfo> RegBankInfo;
113a0747c9fSpatrick   std::unique_ptr<InstructionSelector> InstSelector;
114a0747c9fSpatrick 
11509467b48Spatrick public:
11609467b48Spatrick   /// This constructor initializes the data members to match that
11709467b48Spatrick   /// of the specified triple.
11809467b48Spatrick   ///
119*a96b3639Srobert   PPCSubtarget(const Triple &TT, const std::string &CPU,
120*a96b3639Srobert                const std::string &TuneCPU, const std::string &FS,
12109467b48Spatrick                const PPCTargetMachine &TM);
12209467b48Spatrick 
12309467b48Spatrick   /// ParseSubtargetFeatures - Parses features string setting specified
12409467b48Spatrick   /// subtarget options.  Definition of function is auto generated by tblgen.
125a0747c9fSpatrick   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
12609467b48Spatrick 
12709467b48Spatrick   /// getStackAlignment - Returns the minimum alignment known to hold of the
12809467b48Spatrick   /// stack frame on entry to the function and which must be maintained by every
12909467b48Spatrick   /// function for this subtarget.
getStackAlignment()13009467b48Spatrick   Align getStackAlignment() const { return StackAlignment; }
13109467b48Spatrick 
13209467b48Spatrick   /// getCPUDirective - Returns the -m directive specified for the cpu.
13309467b48Spatrick   ///
getCPUDirective()13409467b48Spatrick   unsigned getCPUDirective() const { return CPUDirective; }
13509467b48Spatrick 
13609467b48Spatrick   /// getInstrItins - Return the instruction itineraries based on subtarget
13709467b48Spatrick   /// selection.
getInstrItineraryData()13809467b48Spatrick   const InstrItineraryData *getInstrItineraryData() const override {
13909467b48Spatrick     return &InstrItins;
14009467b48Spatrick   }
14109467b48Spatrick 
getFrameLowering()14209467b48Spatrick   const PPCFrameLowering *getFrameLowering() const override {
14309467b48Spatrick     return &FrameLowering;
14409467b48Spatrick   }
getInstrInfo()14509467b48Spatrick   const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; }
getTargetLowering()14609467b48Spatrick   const PPCTargetLowering *getTargetLowering() const override {
14709467b48Spatrick     return &TLInfo;
14809467b48Spatrick   }
getSelectionDAGInfo()14909467b48Spatrick   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
15009467b48Spatrick     return &TSInfo;
15109467b48Spatrick   }
getRegisterInfo()15209467b48Spatrick   const PPCRegisterInfo *getRegisterInfo() const override {
15309467b48Spatrick     return &getInstrInfo()->getRegisterInfo();
15409467b48Spatrick   }
getTargetMachine()15509467b48Spatrick   const PPCTargetMachine &getTargetMachine() const { return TM; }
15609467b48Spatrick 
157*a96b3639Srobert   /// initializeSubtargetDependencies - Initializes using a CPU, a TuneCPU,  and
158*a96b3639Srobert   /// feature string so that we can use initializer lists for subtarget
159*a96b3639Srobert   /// initialization.
160*a96b3639Srobert   PPCSubtarget &initializeSubtargetDependencies(StringRef CPU,
161*a96b3639Srobert                                                 StringRef TuneCPU,
162*a96b3639Srobert                                                 StringRef FS);
16309467b48Spatrick 
16409467b48Spatrick private:
16509467b48Spatrick   void initializeEnvironment();
166*a96b3639Srobert   void initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
16709467b48Spatrick 
16809467b48Spatrick public:
16909467b48Spatrick   /// isPPC64 - Return true if we are generating code for 64-bit pointer mode.
17009467b48Spatrick   ///
17109467b48Spatrick   bool isPPC64() const;
17209467b48Spatrick 
17309467b48Spatrick   // useSoftFloat - Return true if soft-float option is turned on.
useSoftFloat()17409467b48Spatrick   bool useSoftFloat() const {
17509467b48Spatrick     if (isAIXABI() && !HasHardFloat)
17609467b48Spatrick       report_fatal_error("soft-float is not yet supported on AIX.");
17709467b48Spatrick     return !HasHardFloat;
17809467b48Spatrick   }
17909467b48Spatrick 
18009467b48Spatrick   // isLittleEndian - True if generating little-endian code
isLittleEndian()18109467b48Spatrick   bool isLittleEndian() const { return IsLittleEndian; }
18209467b48Spatrick 
183*a96b3639Srobert // Getters for SubtargetFeatures defined in tablegen.
184*a96b3639Srobert #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER)                    \
185*a96b3639Srobert   bool GETTER() const { return ATTRIBUTE; }
186*a96b3639Srobert #include "PPCGenSubtargetInfo.inc"
18709467b48Spatrick 
getPlatformStackAlignment()18809467b48Spatrick   Align getPlatformStackAlignment() const {
18909467b48Spatrick     return Align(16);
19009467b48Spatrick   }
19109467b48Spatrick 
getRedZoneSize()19209467b48Spatrick   unsigned  getRedZoneSize() const {
193adae0cfdSpatrick     if (isPPC64())
194adae0cfdSpatrick       // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved)
195adae0cfdSpatrick       return 288;
196adae0cfdSpatrick 
197adae0cfdSpatrick     // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs);
198adae0cfdSpatrick     // PPC32 SVR4ABI has no redzone.
199adae0cfdSpatrick     return isAIXABI() ? 220 : 0;
20009467b48Spatrick   }
20109467b48Spatrick 
needsSwapsForVSXMemOps()20209467b48Spatrick   bool needsSwapsForVSXMemOps() const {
20309467b48Spatrick     return hasVSX() && isLittleEndian() && !hasP9Vector();
20409467b48Spatrick   }
20509467b48Spatrick 
hasPOPCNTD()20609467b48Spatrick   POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; }
20709467b48Spatrick 
getTargetTriple()20809467b48Spatrick   const Triple &getTargetTriple() const { return TargetTriple; }
20909467b48Spatrick 
isTargetELF()21009467b48Spatrick   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
isTargetMachO()21109467b48Spatrick   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
isTargetLinux()21209467b48Spatrick   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
21309467b48Spatrick 
isAIXABI()21409467b48Spatrick   bool isAIXABI() const { return TargetTriple.isOSAIX(); }
isSVR4ABI()215adae0cfdSpatrick   bool isSVR4ABI() const { return !isAIXABI(); }
21609467b48Spatrick   bool isELFv2ABI() const;
21709467b48Spatrick 
is64BitELFABI()21809467b48Spatrick   bool is64BitELFABI() const { return  isSVR4ABI() && isPPC64(); }
is32BitELFABI()21909467b48Spatrick   bool is32BitELFABI() const { return  isSVR4ABI() && !isPPC64(); }
220adae0cfdSpatrick   bool isUsingPCRelativeCalls() const;
22109467b48Spatrick 
22209467b48Spatrick   /// Originally, this function return hasISEL(). Now we always enable it,
22309467b48Spatrick   /// but may expand the ISEL instruction later.
enableEarlyIfConversion()22409467b48Spatrick   bool enableEarlyIfConversion() const override { return true; }
22509467b48Spatrick 
22609467b48Spatrick   /// Scheduling customization.
22709467b48Spatrick   bool enableMachineScheduler() const override;
22809467b48Spatrick   /// Pipeliner customization.
22909467b48Spatrick   bool enableMachinePipeliner() const override;
23009467b48Spatrick   /// Machine Pipeliner customization
23109467b48Spatrick   bool useDFAforSMS() const override;
23209467b48Spatrick   /// This overrides the PostRAScheduler bit in the SchedModel for each CPU.
23309467b48Spatrick   bool enablePostRAScheduler() const override;
23409467b48Spatrick   AntiDepBreakMode getAntiDepBreakMode() const override;
23509467b48Spatrick   void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override;
23609467b48Spatrick 
23709467b48Spatrick   void overrideSchedPolicy(MachineSchedPolicy &Policy,
23809467b48Spatrick                            unsigned NumRegionInstrs) const override;
23909467b48Spatrick   bool useAA() const override;
24009467b48Spatrick 
24109467b48Spatrick   bool enableSubRegLiveness() const override;
24209467b48Spatrick 
24309467b48Spatrick   /// True if the GV will be accessed via an indirect symbol.
24409467b48Spatrick   bool isGVIndirectSymbol(const GlobalValue *GV) const;
24509467b48Spatrick 
24609467b48Spatrick   /// True if the ABI is descriptor based.
usesFunctionDescriptors()24709467b48Spatrick   bool usesFunctionDescriptors() const {
24809467b48Spatrick     // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit
24909467b48Spatrick     // v1 ABI uses descriptors.
25009467b48Spatrick     return isAIXABI() || (is64BitELFABI() && !isELFv2ABI());
25109467b48Spatrick   }
25209467b48Spatrick 
descriptorTOCAnchorOffset()25309467b48Spatrick   unsigned descriptorTOCAnchorOffset() const {
25409467b48Spatrick     assert(usesFunctionDescriptors() &&
25509467b48Spatrick            "Should only be called when the target uses descriptors.");
25609467b48Spatrick     return IsPPC64 ? 8 : 4;
25709467b48Spatrick   }
25809467b48Spatrick 
descriptorEnvironmentPointerOffset()25909467b48Spatrick   unsigned descriptorEnvironmentPointerOffset() const {
26009467b48Spatrick     assert(usesFunctionDescriptors() &&
26109467b48Spatrick            "Should only be called when the target uses descriptors.");
26209467b48Spatrick     return IsPPC64 ? 16 : 8;
26309467b48Spatrick   }
26409467b48Spatrick 
getEnvironmentPointerRegister()26509467b48Spatrick   MCRegister getEnvironmentPointerRegister() const {
26609467b48Spatrick     assert(usesFunctionDescriptors() &&
26709467b48Spatrick            "Should only be called when the target uses descriptors.");
26809467b48Spatrick      return IsPPC64 ? PPC::X11 : PPC::R11;
26909467b48Spatrick   }
27009467b48Spatrick 
getTOCPointerRegister()27109467b48Spatrick   MCRegister getTOCPointerRegister() const {
27209467b48Spatrick     assert((is64BitELFABI() || isAIXABI()) &&
27309467b48Spatrick            "Should only be called when the target is a TOC based ABI.");
27409467b48Spatrick     return IsPPC64 ? PPC::X2 : PPC::R2;
27509467b48Spatrick   }
27609467b48Spatrick 
getStackPointerRegister()27709467b48Spatrick   MCRegister getStackPointerRegister() const {
27809467b48Spatrick     return IsPPC64 ? PPC::X1 : PPC::R1;
27909467b48Spatrick   }
28009467b48Spatrick 
isXRaySupported()28109467b48Spatrick   bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; }
282adae0cfdSpatrick 
isPredictableSelectIsExpensive()283adae0cfdSpatrick   bool isPredictableSelectIsExpensive() const {
284adae0cfdSpatrick     return PredictableSelectIsExpensive;
285adae0cfdSpatrick   }
286a0747c9fSpatrick 
287a0747c9fSpatrick   // Select allocation orders of GPRC and G8RC. It should be strictly consistent
288a0747c9fSpatrick   // with corresponding AltOrders in PPCRegisterInfo.td.
getGPRAllocationOrderIdx()289a0747c9fSpatrick   unsigned getGPRAllocationOrderIdx() const {
290a0747c9fSpatrick     if (is64BitELFABI())
291a0747c9fSpatrick       return 1;
292a0747c9fSpatrick     if (isAIXABI())
293a0747c9fSpatrick       return 2;
294a0747c9fSpatrick     return 0;
295a0747c9fSpatrick   }
296a0747c9fSpatrick 
297a0747c9fSpatrick   // GlobalISEL
298a0747c9fSpatrick   const CallLowering *getCallLowering() const override;
299a0747c9fSpatrick   const RegisterBankInfo *getRegBankInfo() const override;
300a0747c9fSpatrick   const LegalizerInfo *getLegalizerInfo() const override;
301a0747c9fSpatrick   InstructionSelector *getInstructionSelector() const override;
30209467b48Spatrick };
30309467b48Spatrick } // End llvm namespace
30409467b48Spatrick 
30509467b48Spatrick #endif
306