Home | History | Annotate | Line # | Download | only in PowerPC
      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/ADT/Triple.h"
     20 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
     21 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
     22 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
     23 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
     24 #include "llvm/CodeGen/TargetSubtargetInfo.h"
     25 #include "llvm/IR/DataLayout.h"
     26 #include "llvm/MC/MCInstrItineraries.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_PWR_FUTURE,
     65   DIR_64
     66 };
     67 }
     68 
     69 class GlobalValue;
     70 
     71 class PPCSubtarget : public PPCGenSubtargetInfo {
     72 public:
     73   enum POPCNTDKind {
     74     POPCNTD_Unavailable,
     75     POPCNTD_Slow,
     76     POPCNTD_Fast
     77   };
     78 
     79 protected:
     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   /// Which cpu directive was used.
     91   unsigned CPUDirective;
     92 
     93   /// Used by the ISel to turn in optimizations for POWER4-derived architectures
     94   bool HasMFOCRF;
     95   bool Has64BitSupport;
     96   bool Use64BitRegs;
     97   bool UseCRBits;
     98   bool HasHardFloat;
     99   bool IsPPC64;
    100   bool HasAltivec;
    101   bool HasFPU;
    102   bool HasSPE;
    103   bool HasEFPU2;
    104   bool HasVSX;
    105   bool NeedsTwoConstNR;
    106   bool HasP8Vector;
    107   bool HasP8Altivec;
    108   bool HasP8Crypto;
    109   bool HasP9Vector;
    110   bool HasP9Altivec;
    111   bool HasP10Vector;
    112   bool HasPrefixInstrs;
    113   bool HasPCRelativeMemops;
    114   bool HasMMA;
    115   bool HasROPProtect;
    116   bool HasPrivileged;
    117   bool HasFCPSGN;
    118   bool HasFSQRT;
    119   bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES;
    120   bool HasRecipPrec;
    121   bool HasSTFIWX;
    122   bool HasLFIWAX;
    123   bool HasFPRND;
    124   bool HasFPCVT;
    125   bool HasISEL;
    126   bool HasBPERMD;
    127   bool HasExtDiv;
    128   bool HasCMPB;
    129   bool HasLDBRX;
    130   bool IsBookE;
    131   bool HasOnlyMSYNC;
    132   bool IsE500;
    133   bool IsPPC4xx;
    134   bool IsPPC6xx;
    135   bool FeatureMFTB;
    136   bool AllowsUnalignedFPAccess;
    137   bool DeprecatedDST;
    138   bool IsLittleEndian;
    139   bool HasICBT;
    140   bool HasInvariantFunctionDescriptors;
    141   bool HasPartwordAtomics;
    142   bool HasDirectMove;
    143   bool HasHTM;
    144   bool HasFloat128;
    145   bool HasFusion;
    146   bool HasStoreFusion;
    147   bool HasAddiLoadFusion;
    148   bool HasAddisLoadFusion;
    149   bool IsISA3_0;
    150   bool IsISA3_1;
    151   bool UseLongCalls;
    152   bool SecurePlt;
    153   bool VectorsUseTwoUnits;
    154   bool UsePPCPreRASchedStrategy;
    155   bool UsePPCPostRASchedStrategy;
    156   bool PairedVectorMemops;
    157   bool PredictableSelectIsExpensive;
    158   bool HasModernAIXAs;
    159   bool IsAIX;
    160 
    161   POPCNTDKind HasPOPCNTD;
    162 
    163   const PPCTargetMachine &TM;
    164   PPCFrameLowering FrameLowering;
    165   PPCInstrInfo InstrInfo;
    166   PPCTargetLowering TLInfo;
    167   SelectionDAGTargetInfo TSInfo;
    168 
    169   /// GlobalISel related APIs.
    170   std::unique_ptr<CallLowering> CallLoweringInfo;
    171   std::unique_ptr<LegalizerInfo> Legalizer;
    172   std::unique_ptr<RegisterBankInfo> RegBankInfo;
    173   std::unique_ptr<InstructionSelector> InstSelector;
    174 
    175 public:
    176   /// This constructor initializes the data members to match that
    177   /// of the specified triple.
    178   ///
    179   PPCSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
    180                const PPCTargetMachine &TM);
    181 
    182   /// ParseSubtargetFeatures - Parses features string setting specified
    183   /// subtarget options.  Definition of function is auto generated by tblgen.
    184   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
    185 
    186   /// getStackAlignment - Returns the minimum alignment known to hold of the
    187   /// stack frame on entry to the function and which must be maintained by every
    188   /// function for this subtarget.
    189   Align getStackAlignment() const { return StackAlignment; }
    190 
    191   /// getCPUDirective - Returns the -m directive specified for the cpu.
    192   ///
    193   unsigned getCPUDirective() const { return CPUDirective; }
    194 
    195   /// getInstrItins - Return the instruction itineraries based on subtarget
    196   /// selection.
    197   const InstrItineraryData *getInstrItineraryData() const override {
    198     return &InstrItins;
    199   }
    200 
    201   const PPCFrameLowering *getFrameLowering() const override {
    202     return &FrameLowering;
    203   }
    204   const PPCInstrInfo *getInstrInfo() const override { return &InstrInfo; }
    205   const PPCTargetLowering *getTargetLowering() const override {
    206     return &TLInfo;
    207   }
    208   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
    209     return &TSInfo;
    210   }
    211   const PPCRegisterInfo *getRegisterInfo() const override {
    212     return &getInstrInfo()->getRegisterInfo();
    213   }
    214   const PPCTargetMachine &getTargetMachine() const { return TM; }
    215 
    216   /// initializeSubtargetDependencies - Initializes using a CPU and feature string
    217   /// so that we can use initializer lists for subtarget initialization.
    218   PPCSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
    219 
    220 private:
    221   void initializeEnvironment();
    222   void initSubtargetFeatures(StringRef CPU, StringRef FS);
    223 
    224 public:
    225   /// isPPC64 - Return true if we are generating code for 64-bit pointer mode.
    226   ///
    227   bool isPPC64() const;
    228 
    229   /// has64BitSupport - Return true if the selected CPU supports 64-bit
    230   /// instructions, regardless of whether we are in 32-bit or 64-bit mode.
    231   bool has64BitSupport() const { return Has64BitSupport; }
    232   // useSoftFloat - Return true if soft-float option is turned on.
    233   bool useSoftFloat() const {
    234     if (isAIXABI() && !HasHardFloat)
    235       report_fatal_error("soft-float is not yet supported on AIX.");
    236     return !HasHardFloat;
    237   }
    238 
    239   /// use64BitRegs - Return true if in 64-bit mode or if we should use 64-bit
    240   /// registers in 32-bit mode when possible.  This can only true if
    241   /// has64BitSupport() returns true.
    242   bool use64BitRegs() const { return Use64BitRegs; }
    243 
    244   /// useCRBits - Return true if we should store and manipulate i1 values in
    245   /// the individual condition register bits.
    246   bool useCRBits() const { return UseCRBits; }
    247 
    248   // isLittleEndian - True if generating little-endian code
    249   bool isLittleEndian() const { return IsLittleEndian; }
    250 
    251   // Specific obvious features.
    252   bool hasFCPSGN() const { return HasFCPSGN; }
    253   bool hasFSQRT() const { return HasFSQRT; }
    254   bool hasFRE() const { return HasFRE; }
    255   bool hasFRES() const { return HasFRES; }
    256   bool hasFRSQRTE() const { return HasFRSQRTE; }
    257   bool hasFRSQRTES() const { return HasFRSQRTES; }
    258   bool hasRecipPrec() const { return HasRecipPrec; }
    259   bool hasSTFIWX() const { return HasSTFIWX; }
    260   bool hasLFIWAX() const { return HasLFIWAX; }
    261   bool hasFPRND() const { return HasFPRND; }
    262   bool hasFPCVT() const { return HasFPCVT; }
    263   bool hasAltivec() const { return HasAltivec; }
    264   bool hasSPE() const { return HasSPE; }
    265   bool hasEFPU2() const { return HasEFPU2; }
    266   bool hasFPU() const { return HasFPU; }
    267   bool hasVSX() const { return HasVSX; }
    268   bool needsTwoConstNR() const { return NeedsTwoConstNR; }
    269   bool hasP8Vector() const { return HasP8Vector; }
    270   bool hasP8Altivec() const { return HasP8Altivec; }
    271   bool hasP8Crypto() const { return HasP8Crypto; }
    272   bool hasP9Vector() const { return HasP9Vector; }
    273   bool hasP9Altivec() const { return HasP9Altivec; }
    274   bool hasP10Vector() const { return HasP10Vector; }
    275   bool hasPrefixInstrs() const { return HasPrefixInstrs; }
    276   bool hasPCRelativeMemops() const { return HasPCRelativeMemops; }
    277   bool hasMMA() const { return HasMMA; }
    278   bool hasROPProtect() const { return HasROPProtect; }
    279   bool hasPrivileged() const { return HasPrivileged; }
    280   bool pairedVectorMemops() const { return PairedVectorMemops; }
    281   bool hasMFOCRF() const { return HasMFOCRF; }
    282   bool hasISEL() const { return HasISEL; }
    283   bool hasBPERMD() const { return HasBPERMD; }
    284   bool hasExtDiv() const { return HasExtDiv; }
    285   bool hasCMPB() const { return HasCMPB; }
    286   bool hasLDBRX() const { return HasLDBRX; }
    287   bool isBookE() const { return IsBookE; }
    288   bool hasOnlyMSYNC() const { return HasOnlyMSYNC; }
    289   bool isPPC4xx() const { return IsPPC4xx; }
    290   bool isPPC6xx() const { return IsPPC6xx; }
    291   bool isSecurePlt() const {return SecurePlt; }
    292   bool vectorsUseTwoUnits() const {return VectorsUseTwoUnits; }
    293   bool isE500() const { return IsE500; }
    294   bool isFeatureMFTB() const { return FeatureMFTB; }
    295   bool allowsUnalignedFPAccess() const { return AllowsUnalignedFPAccess; }
    296   bool isDeprecatedDST() const { return DeprecatedDST; }
    297   bool hasICBT() const { return HasICBT; }
    298   bool hasInvariantFunctionDescriptors() const {
    299     return HasInvariantFunctionDescriptors;
    300   }
    301   bool usePPCPreRASchedStrategy() const { return UsePPCPreRASchedStrategy; }
    302   bool usePPCPostRASchedStrategy() const { return UsePPCPostRASchedStrategy; }
    303   bool hasPartwordAtomics() const { return HasPartwordAtomics; }
    304   bool hasDirectMove() const { return HasDirectMove; }
    305 
    306   Align getPlatformStackAlignment() const {
    307     return Align(16);
    308   }
    309 
    310   unsigned  getRedZoneSize() const {
    311     if (isPPC64())
    312       // 288 bytes = 18*8 (FPRs) + 18*8 (GPRs, GPR13 reserved)
    313       return 288;
    314 
    315     // AIX PPC32: 220 bytes = 18*8 (FPRs) + 19*4 (GPRs);
    316     // PPC32 SVR4ABI has no redzone.
    317     return isAIXABI() ? 220 : 0;
    318   }
    319 
    320   bool hasHTM() const { return HasHTM; }
    321   bool hasFloat128() const { return HasFloat128; }
    322   bool isISA3_0() const { return IsISA3_0; }
    323   bool isISA3_1() const { return IsISA3_1; }
    324   bool useLongCalls() const { return UseLongCalls; }
    325   bool hasFusion() const { return HasFusion; }
    326   bool hasStoreFusion() const { return HasStoreFusion; }
    327   bool hasAddiLoadFusion() const { return HasAddiLoadFusion; }
    328   bool hasAddisLoadFusion() const { return HasAddisLoadFusion; }
    329   bool needsSwapsForVSXMemOps() const {
    330     return hasVSX() && isLittleEndian() && !hasP9Vector();
    331   }
    332 
    333   POPCNTDKind hasPOPCNTD() const { return HasPOPCNTD; }
    334 
    335   const Triple &getTargetTriple() const { return TargetTriple; }
    336 
    337   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
    338   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
    339   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
    340 
    341   bool isAIXABI() const { return TargetTriple.isOSAIX(); }
    342   bool isSVR4ABI() const { return !isAIXABI(); }
    343   bool isELFv2ABI() const;
    344 
    345   bool is64BitELFABI() const { return  isSVR4ABI() && isPPC64(); }
    346   bool is32BitELFABI() const { return  isSVR4ABI() && !isPPC64(); }
    347   bool isUsingPCRelativeCalls() const;
    348 
    349   /// Originally, this function return hasISEL(). Now we always enable it,
    350   /// but may expand the ISEL instruction later.
    351   bool enableEarlyIfConversion() const override { return true; }
    352 
    353   /// Scheduling customization.
    354   bool enableMachineScheduler() const override;
    355   /// Pipeliner customization.
    356   bool enableMachinePipeliner() const override;
    357   /// Machine Pipeliner customization
    358   bool useDFAforSMS() const override;
    359   /// This overrides the PostRAScheduler bit in the SchedModel for each CPU.
    360   bool enablePostRAScheduler() const override;
    361   AntiDepBreakMode getAntiDepBreakMode() const override;
    362   void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const override;
    363 
    364   void overrideSchedPolicy(MachineSchedPolicy &Policy,
    365                            unsigned NumRegionInstrs) const override;
    366   bool useAA() const override;
    367 
    368   bool enableSubRegLiveness() const override;
    369 
    370   /// True if the GV will be accessed via an indirect symbol.
    371   bool isGVIndirectSymbol(const GlobalValue *GV) const;
    372 
    373   /// True if the ABI is descriptor based.
    374   bool usesFunctionDescriptors() const {
    375     // Both 32-bit and 64-bit AIX are descriptor based. For ELF only the 64-bit
    376     // v1 ABI uses descriptors.
    377     return isAIXABI() || (is64BitELFABI() && !isELFv2ABI());
    378   }
    379 
    380   unsigned descriptorTOCAnchorOffset() const {
    381     assert(usesFunctionDescriptors() &&
    382            "Should only be called when the target uses descriptors.");
    383     return IsPPC64 ? 8 : 4;
    384   }
    385 
    386   unsigned descriptorEnvironmentPointerOffset() const {
    387     assert(usesFunctionDescriptors() &&
    388            "Should only be called when the target uses descriptors.");
    389     return IsPPC64 ? 16 : 8;
    390   }
    391 
    392   MCRegister getEnvironmentPointerRegister() const {
    393     assert(usesFunctionDescriptors() &&
    394            "Should only be called when the target uses descriptors.");
    395      return IsPPC64 ? PPC::X11 : PPC::R11;
    396   }
    397 
    398   MCRegister getTOCPointerRegister() const {
    399     assert((is64BitELFABI() || isAIXABI()) &&
    400            "Should only be called when the target is a TOC based ABI.");
    401     return IsPPC64 ? PPC::X2 : PPC::R2;
    402   }
    403 
    404   MCRegister getStackPointerRegister() const {
    405     return IsPPC64 ? PPC::X1 : PPC::R1;
    406   }
    407 
    408   bool isXRaySupported() const override { return IsPPC64 && IsLittleEndian; }
    409 
    410   bool isPredictableSelectIsExpensive() const {
    411     return PredictableSelectIsExpensive;
    412   }
    413 
    414   // GlobalISEL
    415   const CallLowering *getCallLowering() const override;
    416   const RegisterBankInfo *getRegBankInfo() const override;
    417   const LegalizerInfo *getLegalizerInfo() const override;
    418   InstructionSelector *getInstructionSelector() const override;
    419 };
    420 } // End llvm namespace
    421 
    422 #endif
    423