Home | History | Annotate | Download | only in ARM
      1 //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares the ARM specific subclass of TargetSubtargetInfo.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef ARMSUBTARGET_H
     15 #define ARMSUBTARGET_H
     16 
     17 
     18 #include "ARMFrameLowering.h"
     19 #include "ARMISelLowering.h"
     20 #include "ARMInstrInfo.h"
     21 #include "ARMJITInfo.h"
     22 #include "ARMSelectionDAGInfo.h"
     23 #include "ARMSubtarget.h"
     24 #include "Thumb1FrameLowering.h"
     25 #include "Thumb1InstrInfo.h"
     26 #include "Thumb2InstrInfo.h"
     27 #include "ARMJITInfo.h"
     28 #include "MCTargetDesc/ARMMCTargetDesc.h"
     29 #include "llvm/ADT/Triple.h"
     30 #include "llvm/IR/DataLayout.h"
     31 #include "llvm/MC/MCInstrItineraries.h"
     32 #include "llvm/Target/TargetSubtargetInfo.h"
     33 #include <string>
     34 
     35 #define GET_SUBTARGETINFO_HEADER
     36 #include "ARMGenSubtargetInfo.inc"
     37 
     38 namespace llvm {
     39 class GlobalValue;
     40 class StringRef;
     41 class TargetOptions;
     42 
     43 class ARMSubtarget : public ARMGenSubtargetInfo {
     44 protected:
     45   enum ARMProcFamilyEnum {
     46     Others, CortexA5, CortexA7, CortexA8, CortexA9, CortexA12, CortexA15,
     47     CortexR5, Swift, CortexA53, CortexA57, Krait
     48   };
     49   enum ARMProcClassEnum {
     50     None, AClass, RClass, MClass
     51   };
     52 
     53   /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others.
     54   ARMProcFamilyEnum ARMProcFamily;
     55 
     56   /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass.
     57   ARMProcClassEnum ARMProcClass;
     58 
     59   /// HasV4TOps, HasV5TOps, HasV5TEOps,
     60   /// HasV6Ops, HasV6MOps, HasV6T2Ops, HasV7Ops, HasV8Ops -
     61   /// Specify whether target support specific ARM ISA variants.
     62   bool HasV4TOps;
     63   bool HasV5TOps;
     64   bool HasV5TEOps;
     65   bool HasV6Ops;
     66   bool HasV6MOps;
     67   bool HasV6T2Ops;
     68   bool HasV7Ops;
     69   bool HasV8Ops;
     70 
     71   /// HasVFPv2, HasVFPv3, HasVFPv4, HasFPARMv8, HasNEON - Specify what
     72   /// floating point ISAs are supported.
     73   bool HasVFPv2;
     74   bool HasVFPv3;
     75   bool HasVFPv4;
     76   bool HasFPARMv8;
     77   bool HasNEON;
     78 
     79   /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been
     80   /// specified. Use the method useNEONForSinglePrecisionFP() to
     81   /// determine if NEON should actually be used.
     82   bool UseNEONForSinglePrecisionFP;
     83 
     84   /// UseMulOps - True if non-microcoded fused integer multiply-add and
     85   /// multiply-subtract instructions should be used.
     86   bool UseMulOps;
     87 
     88   /// SlowFPVMLx - If the VFP2 / NEON instructions are available, indicates
     89   /// whether the FP VML[AS] instructions are slow (if so, don't use them).
     90   bool SlowFPVMLx;
     91 
     92   /// HasVMLxForwarding - If true, NEON has special multiplier accumulator
     93   /// forwarding to allow mul + mla being issued back to back.
     94   bool HasVMLxForwarding;
     95 
     96   /// SlowFPBrcc - True if floating point compare + branch is slow.
     97   bool SlowFPBrcc;
     98 
     99   /// InThumbMode - True if compiling for Thumb, false for ARM.
    100   bool InThumbMode;
    101 
    102   /// HasThumb2 - True if Thumb2 instructions are supported.
    103   bool HasThumb2;
    104 
    105   /// NoARM - True if subtarget does not support ARM mode execution.
    106   bool NoARM;
    107 
    108   /// PostRAScheduler - True if using post-register-allocation scheduler.
    109   bool PostRAScheduler;
    110 
    111   /// IsR9Reserved - True if R9 is a not available as general purpose register.
    112   bool IsR9Reserved;
    113 
    114   /// UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit
    115   /// imms (including global addresses).
    116   bool UseMovt;
    117 
    118   /// SupportsTailCall - True if the OS supports tail call. The dynamic linker
    119   /// must be able to synthesize call stubs for interworking between ARM and
    120   /// Thumb.
    121   bool SupportsTailCall;
    122 
    123   /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF
    124   /// only so far)
    125   bool HasFP16;
    126 
    127   /// HasD16 - True if subtarget is limited to 16 double precision
    128   /// FP registers for VFPv3.
    129   bool HasD16;
    130 
    131   /// HasHardwareDivide - True if subtarget supports [su]div
    132   bool HasHardwareDivide;
    133 
    134   /// HasHardwareDivideInARM - True if subtarget supports [su]div in ARM mode
    135   bool HasHardwareDivideInARM;
    136 
    137   /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack
    138   /// instructions.
    139   bool HasT2ExtractPack;
    140 
    141   /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier
    142   /// instructions.
    143   bool HasDataBarrier;
    144 
    145   /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions
    146   /// over 16-bit ones.
    147   bool Pref32BitThumb;
    148 
    149   /// AvoidCPSRPartialUpdate - If true, codegen would avoid using instructions
    150   /// that partially update CPSR and add false dependency on the previous
    151   /// CPSR setting instruction.
    152   bool AvoidCPSRPartialUpdate;
    153 
    154   /// AvoidMOVsShifterOperand - If true, codegen should avoid using flag setting
    155   /// movs with shifter operand (i.e. asr, lsl, lsr).
    156   bool AvoidMOVsShifterOperand;
    157 
    158   /// HasRAS - Some processors perform return stack prediction. CodeGen should
    159   /// avoid issue "normal" call instructions to callees which do not return.
    160   bool HasRAS;
    161 
    162   /// HasMPExtension - True if the subtarget supports Multiprocessing
    163   /// extension (ARMv7 only).
    164   bool HasMPExtension;
    165 
    166   /// HasVirtualization - True if the subtarget supports the Virtualization
    167   /// extension.
    168   bool HasVirtualization;
    169 
    170   /// FPOnlySP - If true, the floating point unit only supports single
    171   /// precision.
    172   bool FPOnlySP;
    173 
    174   /// If true, the processor supports the Performance Monitor Extensions. These
    175   /// include a generic cycle-counter as well as more fine-grained (often
    176   /// implementation-specific) events.
    177   bool HasPerfMon;
    178 
    179   /// HasTrustZone - if true, processor supports TrustZone security extensions
    180   bool HasTrustZone;
    181 
    182   /// HasCrypto - if true, processor supports Cryptography extensions
    183   bool HasCrypto;
    184 
    185   /// HasCRC - if true, processor supports CRC instructions
    186   bool HasCRC;
    187 
    188   /// If true, the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are
    189   /// particularly effective at zeroing a VFP register.
    190   bool HasZeroCycleZeroing;
    191 
    192   /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory
    193   /// accesses for some types.  For details, see
    194   /// ARMTargetLowering::allowsUnalignedMemoryAccesses().
    195   bool AllowsUnalignedMem;
    196 
    197   /// RestrictIT - If true, the subtarget disallows generation of deprecated IT
    198   ///  blocks to conform to ARMv8 rule.
    199   bool RestrictIT;
    200 
    201   /// Thumb2DSP - If true, the subtarget supports the v7 DSP (saturating arith
    202   /// and such) instructions in Thumb2 code.
    203   bool Thumb2DSP;
    204 
    205   /// NaCl TRAP instruction is generated instead of the regular TRAP.
    206   bool UseNaClTrap;
    207 
    208   /// Force long to be a 64-bit type (RenderScript-specific)
    209   bool UseLong64;
    210 
    211   /// Target machine allowed unsafe FP math (such as use of NEON fp)
    212   bool UnsafeFPMath;
    213 
    214   /// stackAlignment - The minimum alignment known to hold of the stack frame on
    215   /// entry to the function and which must be maintained by every function.
    216   unsigned stackAlignment;
    217 
    218   /// CPUString - String name of used CPU.
    219   std::string CPUString;
    220 
    221   /// IsLittle - The target is Little Endian
    222   bool IsLittle;
    223 
    224   /// TargetTriple - What processor and OS we're targeting.
    225   Triple TargetTriple;
    226 
    227   /// SchedModel - Processor specific instruction costs.
    228   const MCSchedModel *SchedModel;
    229 
    230   /// Selected instruction itineraries (one entry per itinerary class.)
    231   InstrItineraryData InstrItins;
    232 
    233   /// Options passed via command line that could influence the target
    234   const TargetOptions &Options;
    235 
    236  public:
    237   enum {
    238     ARM_ABI_UNKNOWN,
    239     ARM_ABI_APCS,
    240     ARM_ABI_AAPCS // ARM EABI
    241   } TargetABI;
    242 
    243   /// This constructor initializes the data members to match that
    244   /// of the specified triple.
    245   ///
    246   ARMSubtarget(const std::string &TT, const std::string &CPU,
    247                const std::string &FS, TargetMachine &TM, bool IsLittle,
    248                const TargetOptions &Options);
    249 
    250   /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
    251   /// that still makes it profitable to inline the call.
    252   unsigned getMaxInlineSizeThreshold() const {
    253     return 64;
    254   }
    255   /// ParseSubtargetFeatures - Parses features string setting specified
    256   /// subtarget options.  Definition of function is auto generated by tblgen.
    257   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
    258 
    259   /// \brief Reset the features for the ARM target.
    260   void resetSubtargetFeatures(const MachineFunction *MF) override;
    261 
    262   /// initializeSubtargetDependencies - Initializes using a CPU and feature string
    263   /// so that we can use initializer lists for subtarget initialization.
    264   ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
    265 
    266   const DataLayout *getDataLayout() const { return &DL; }
    267   const ARMSelectionDAGInfo *getSelectionDAGInfo() const { return &TSInfo; }
    268   ARMJITInfo *getJITInfo() { return &JITInfo; }
    269   const ARMBaseInstrInfo *getInstrInfo() const { return InstrInfo.get(); }
    270   const ARMTargetLowering *getTargetLowering() const { return &TLInfo; }
    271   const ARMFrameLowering *getFrameLowering() const { return FrameLowering.get(); }
    272   const ARMBaseRegisterInfo *getRegisterInfo() const {
    273     return &InstrInfo->getRegisterInfo();
    274   }
    275 
    276 private:
    277   const DataLayout DL;
    278   ARMSelectionDAGInfo TSInfo;
    279   ARMJITInfo JITInfo;
    280   // Either Thumb1InstrInfo or Thumb2InstrInfo.
    281   std::unique_ptr<ARMBaseInstrInfo> InstrInfo;
    282   ARMTargetLowering   TLInfo;
    283   // Either Thumb1FrameLowering or ARMFrameLowering.
    284   std::unique_ptr<ARMFrameLowering> FrameLowering;
    285 
    286   void initializeEnvironment();
    287   void resetSubtargetFeatures(StringRef CPU, StringRef FS);
    288 public:
    289   void computeIssueWidth();
    290 
    291   bool hasV4TOps()  const { return HasV4TOps;  }
    292   bool hasV5TOps()  const { return HasV5TOps;  }
    293   bool hasV5TEOps() const { return HasV5TEOps; }
    294   bool hasV6Ops()   const { return HasV6Ops;   }
    295   bool hasV6MOps()  const { return HasV6MOps;  }
    296   bool hasV6T2Ops() const { return HasV6T2Ops; }
    297   bool hasV7Ops()   const { return HasV7Ops;  }
    298   bool hasV8Ops()   const { return HasV8Ops;  }
    299 
    300   bool isCortexA5() const { return ARMProcFamily == CortexA5; }
    301   bool isCortexA7() const { return ARMProcFamily == CortexA7; }
    302   bool isCortexA8() const { return ARMProcFamily == CortexA8; }
    303   bool isCortexA9() const { return ARMProcFamily == CortexA9; }
    304   bool isCortexA15() const { return ARMProcFamily == CortexA15; }
    305   bool isSwift()    const { return ARMProcFamily == Swift; }
    306   bool isCortexM3() const { return CPUString == "cortex-m3"; }
    307   bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); }
    308   bool isCortexR5() const { return ARMProcFamily == CortexR5; }
    309   bool isKrait() const { return ARMProcFamily == Krait; }
    310 
    311   bool hasARMOps() const { return !NoARM; }
    312 
    313   bool hasVFP2() const { return HasVFPv2; }
    314   bool hasVFP3() const { return HasVFPv3; }
    315   bool hasVFP4() const { return HasVFPv4; }
    316   bool hasFPARMv8() const { return HasFPARMv8; }
    317   bool hasNEON() const { return HasNEON;  }
    318   bool hasCrypto() const { return HasCrypto; }
    319   bool hasCRC() const { return HasCRC; }
    320   bool hasVirtualization() const { return HasVirtualization; }
    321   bool useNEONForSinglePrecisionFP() const {
    322     return hasNEON() && UseNEONForSinglePrecisionFP; }
    323 
    324   bool hasDivide() const { return HasHardwareDivide; }
    325   bool hasDivideInARMMode() const { return HasHardwareDivideInARM; }
    326   bool hasT2ExtractPack() const { return HasT2ExtractPack; }
    327   bool hasDataBarrier() const { return HasDataBarrier; }
    328   bool hasAnyDataBarrier() const {
    329     return HasDataBarrier || (hasV6Ops() && !isThumb());
    330   }
    331   bool useMulOps() const { return UseMulOps; }
    332   bool useFPVMLx() const { return !SlowFPVMLx; }
    333   bool hasVMLxForwarding() const { return HasVMLxForwarding; }
    334   bool isFPBrccSlow() const { return SlowFPBrcc; }
    335   bool isFPOnlySP() const { return FPOnlySP; }
    336   bool hasPerfMon() const { return HasPerfMon; }
    337   bool hasTrustZone() const { return HasTrustZone; }
    338   bool hasZeroCycleZeroing() const { return HasZeroCycleZeroing; }
    339   bool prefers32BitThumb() const { return Pref32BitThumb; }
    340   bool avoidCPSRPartialUpdate() const { return AvoidCPSRPartialUpdate; }
    341   bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }
    342   bool hasRAS() const { return HasRAS; }
    343   bool hasMPExtension() const { return HasMPExtension; }
    344   bool hasThumb2DSP() const { return Thumb2DSP; }
    345   bool useNaClTrap() const { return UseNaClTrap; }
    346 
    347   bool hasFP16() const { return HasFP16; }
    348   bool hasD16() const { return HasD16; }
    349 
    350   const Triple &getTargetTriple() const { return TargetTriple; }
    351 
    352   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
    353   bool isTargetIOS() const { return TargetTriple.isiOS(); }
    354   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
    355   bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
    356   bool isTargetNetBSD() const { return TargetTriple.getOS() == Triple::NetBSD; }
    357   bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
    358 
    359   bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
    360   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
    361   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
    362 
    363   // ARM EABI is the bare-metal EABI described in ARM ABI documents and
    364   // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
    365   // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
    366   // even for GNUEABI, so we can make a distinction here and still conform to
    367   // the EABI on GNU (and Android) mode. This requires change in Clang, too.
    368   // FIXME: The Darwin exception is temporary, while we move users to
    369   // "*-*-*-macho" triples as quickly as possible.
    370   bool isTargetAEABI() const {
    371     return (TargetTriple.getEnvironment() == Triple::EABI ||
    372             TargetTriple.getEnvironment() == Triple::EABIHF) &&
    373            !isTargetDarwin() && !isTargetWindows();
    374   }
    375 
    376   // ARM Targets that support EHABI exception handling standard
    377   // Darwin uses SjLj. Other targets might need more checks.
    378   bool isTargetEHABICompatible() const {
    379     return (TargetTriple.getEnvironment() == Triple::EABI ||
    380             TargetTriple.getEnvironment() == Triple::GNUEABI ||
    381             TargetTriple.getEnvironment() == Triple::EABIHF ||
    382             TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
    383             TargetTriple.getEnvironment() == Triple::Android) &&
    384            !isTargetDarwin() && !isTargetWindows();
    385   }
    386 
    387   bool isTargetHardFloat() const {
    388     // FIXME: this is invalid for WindowsCE
    389     return TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
    390            TargetTriple.getEnvironment() == Triple::EABIHF ||
    391            isTargetWindows();
    392   }
    393   bool isTargetAndroid() const {
    394     return TargetTriple.getEnvironment() == Triple::Android;
    395   }
    396 
    397   bool isAPCS_ABI() const {
    398     assert(TargetABI != ARM_ABI_UNKNOWN);
    399     return TargetABI == ARM_ABI_APCS;
    400   }
    401   bool isAAPCS_ABI() const {
    402     assert(TargetABI != ARM_ABI_UNKNOWN);
    403     return TargetABI == ARM_ABI_AAPCS;
    404   }
    405 
    406   bool isThumb() const { return InThumbMode; }
    407   bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
    408   bool isThumb2() const { return InThumbMode && HasThumb2; }
    409   bool hasThumb2() const { return HasThumb2; }
    410   bool isMClass() const { return ARMProcClass == MClass; }
    411   bool isRClass() const { return ARMProcClass == RClass; }
    412   bool isAClass() const { return ARMProcClass == AClass; }
    413 
    414   bool isR9Reserved() const { return IsR9Reserved; }
    415 
    416   bool useMovt(const MachineFunction &MF) const;
    417 
    418   bool supportsTailCall() const { return SupportsTailCall; }
    419 
    420   bool allowsUnalignedMem() const { return AllowsUnalignedMem; }
    421 
    422   bool restrictIT() const { return RestrictIT; }
    423 
    424   const std::string & getCPUString() const { return CPUString; }
    425 
    426   bool isLittle() const { return IsLittle; }
    427 
    428   unsigned getMispredictionPenalty() const;
    429 
    430   /// This function returns true if the target has sincos() routine in its
    431   /// compiler runtime or math libraries.
    432   bool hasSinCos() const;
    433 
    434   /// True for some subtargets at > -O0.
    435   bool enablePostMachineScheduler() const;
    436 
    437   /// enablePostRAScheduler - True at 'More' optimization.
    438   bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
    439                              TargetSubtargetInfo::AntiDepBreakMode& Mode,
    440                              RegClassVector& CriticalPathRCs) const override;
    441 
    442   // enableAtomicExpandLoadLinked - True if we need to expand our atomics.
    443   bool enableAtomicExpandLoadLinked() const override;
    444 
    445   /// getInstrItins - Return the instruction itineraies based on subtarget
    446   /// selection.
    447   const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
    448 
    449   /// getStackAlignment - Returns the minimum alignment known to hold of the
    450   /// stack frame on entry to the function and which must be maintained by every
    451   /// function for this subtarget.
    452   unsigned getStackAlignment() const { return stackAlignment; }
    453 
    454   /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect
    455   /// symbol.
    456   bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const;
    457 };
    458 } // End llvm namespace
    459 
    460 #endif  // ARMSUBTARGET_H
    461