X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMSubtarget.h;h=aefd130b9a8cc1fb98fadfc0f290c686e8d1dffe;hb=5d42c567c901508e80ab10ddba1bb30a5007d742;hp=88ceaef7b660a95178ee439da4dbad7ac2a6cc79;hpb=3630e78db9268dbe81a9369a33e49b857804f2ec;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 88ceaef7b66..aefd130b9a8 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Evan Cheng and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,39 +14,113 @@ #ifndef ARMSUBTARGET_H #define ARMSUBTARGET_H +#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtarget.h" +#include "ARMBaseRegisterInfo.h" #include namespace llvm { -class Module; +class GlobalValue; class ARMSubtarget : public TargetSubtarget { protected: enum ARMArchEnum { - V4T, V5T, V5TE, V6 + V4, V4T, V5T, V5TE, V6, V6M, V6T2, V7A, V7M }; - /// ARMArchVersion - ARM architecture vecrsion: V4T (base), V5T, V5TE, - /// and V6. + enum ARMProcFamilyEnum { + Others, CortexA8, CortexA9 + }; + + enum ARMFPEnum { + None, VFPv2, VFPv3, NEON + }; + + enum ThumbTypeEnum { + Thumb1, + Thumb2 + }; + + /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE, + /// V6, V6T2, V7A, V7M. ARMArchEnum ARMArchVersion; - /// HasVFP2 - True if the processor supports Vector Floating Point (VFP) V2 - /// instructions. - bool HasVFP2; + /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others. + ARMProcFamilyEnum ARMProcFamily; + + /// ARMFPUType - Floating Point Unit type. + ARMFPEnum ARMFPUType; + + /// UseNEONForSinglePrecisionFP - if the NEONFP attribute has been + /// specified. Use the method useNEONForSinglePrecisionFP() to + /// determine if NEON should actually be used. + bool UseNEONForSinglePrecisionFP; + + /// SlowVMLx - If the VFP2 instructions are available, indicates whether + /// the VML[AS] instructions are slow (if so, don't use them). + bool SlowVMLx; + + /// SlowFPBrcc - True if floating point compare + branch is slow. + bool SlowFPBrcc; /// IsThumb - True if we are in thumb mode, false if in ARM mode. bool IsThumb; - /// UseThumbBacktraces - True if we use thumb style backtraces. - bool UseThumbBacktraces; + /// ThumbMode - Indicates supported Thumb version. + ThumbTypeEnum ThumbMode; + + /// NoARM - True if subtarget does not support ARM mode execution. + bool NoARM; + + /// PostRAScheduler - True if using post-register-allocation scheduler. + bool PostRAScheduler; /// IsR9Reserved - True if R9 is a not available as general purpose register. bool IsR9Reserved; + /// UseMovt - True if MOVT / MOVW pairs are used for materialization of 32-bit + /// imms (including global addresses). + bool UseMovt; + + /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF + /// only so far) + bool HasFP16; + + /// HasHardwareDivide - True if subtarget supports [su]div + bool HasHardwareDivide; + + /// HasT2ExtractPack - True if subtarget supports thumb2 extract/pack + /// instructions. + bool HasT2ExtractPack; + + /// HasDataBarrier - True if the subtarget supports DMB / DSB data barrier + /// instructions. + bool HasDataBarrier; + + /// Pref32BitThumb - If true, codegen would prefer 32-bit Thumb instructions + /// over 16-bit ones. + bool Pref32BitThumb; + + /// FPOnlySP - If true, the floating point unit only supports single + /// precision. + bool FPOnlySP; + + /// AllowsUnalignedMem - If true, the subtarget allows unaligned memory + /// accesses for some types. For details, see + /// ARMTargetLowering::allowsUnalignedMemoryAccesses(). + bool AllowsUnalignedMem; + /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned stackAlignment; + /// CPUString - String name of used CPU. + std::string CPUString; + + /// Selected instruction itineraries (one entry per itinerary class.) + InstrItineraryData InstrItins; + public: enum { isELF, isDarwin @@ -58,21 +132,49 @@ protected: } TargetABI; /// This constructor initializes the data members to match that - /// of the specified module. + /// of the specified triple. /// - ARMSubtarget(const Module &M, const std::string &FS); - - /// ParseSubtargetFeatures - Parses features string setting specified + ARMSubtarget(const std::string &TT, const std::string &FS, bool isThumb); + + /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size + /// that still makes it profitable to inline the call. + unsigned getMaxInlineSizeThreshold() const { + // FIXME: For now, we don't lower memcpy's to loads / stores for Thumb1. + // Change this once Thumb1 ldmia / stmia support is added. + return isThumb1Only() ? 0 : 64; + } + /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. - void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); + std::string ParseSubtargetFeatures(const std::string &FS, + const std::string &CPU); - bool hasV4TOps() const { return ARMArchVersion >= V4T; } - bool hasV5TOps() const { return ARMArchVersion >= V5T; } + bool hasV4TOps() const { return ARMArchVersion >= V4T; } + bool hasV5TOps() const { return ARMArchVersion >= V5T; } bool hasV5TEOps() const { return ARMArchVersion >= V5TE; } - bool hasV6Ops() const { return ARMArchVersion >= V6; } + bool hasV6Ops() const { return ARMArchVersion >= V6; } + bool hasV6T2Ops() const { return ARMArchVersion >= V6T2; } + bool hasV7Ops() const { return ARMArchVersion >= V7A; } + + bool isCortexA8() const { return ARMProcFamily == CortexA8; } + bool isCortexA9() const { return ARMProcFamily == CortexA9; } + + bool hasARMOps() const { return !NoARM; } + + bool hasVFP2() const { return ARMFPUType >= VFPv2; } + bool hasVFP3() const { return ARMFPUType >= VFPv3; } + bool hasNEON() const { return ARMFPUType >= NEON; } + bool useNEONForSinglePrecisionFP() const { + return hasNEON() && UseNEONForSinglePrecisionFP; } + bool hasDivide() const { return HasHardwareDivide; } + bool hasT2ExtractPack() const { return HasT2ExtractPack; } + bool hasDataBarrier() const { return HasDataBarrier; } + bool useVMLx() const {return hasVFP2() && !SlowVMLx; } + bool isFPBrccSlow() const { return SlowFPBrcc; } + bool isFPOnlySP() const { return FPOnlySP; } + bool prefers32BitThumb() const { return Pref32BitThumb; } + + bool hasFP16() const { return HasFP16; } - bool hasVFP2() const { return HasVFP2; } - bool isTargetDarwin() const { return TargetType == isDarwin; } bool isTargetELF() const { return TargetType == isELF; } @@ -80,14 +182,60 @@ protected: bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; } bool isThumb() const { return IsThumb; } + bool isThumb1Only() const { return IsThumb && (ThumbMode == Thumb1); } + bool isThumb2() const { return IsThumb && (ThumbMode == Thumb2); } + bool hasThumb2() const { return ThumbMode >= Thumb2; } - bool useThumbBacktraces() const { return UseThumbBacktraces; } bool isR9Reserved() const { return IsR9Reserved; } + bool useMovt() const { return UseMovt && hasV6T2Ops(); } + + bool allowsUnalignedMem() const { return AllowsUnalignedMem; } + + const std::string & getCPUString() const { return CPUString; } + + unsigned getMispredictionPenalty() const; + + /// enablePostRAScheduler - True at 'More' optimization. + bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, + TargetSubtarget::AntiDepBreakMode& Mode, + RegClassVector& CriticalPathRCs) const; + + /// getInstrItins - Return the instruction itineraies based on subtarget + /// selection. + const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } + /// getStackAlignment - Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every /// function for this subtarget. unsigned getStackAlignment() const { return stackAlignment; } + + /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect + /// symbol. + bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const; + + /// getDataLayout() - returns the ARM/Thumb specific TargetLayout string + std::string getDataLayout() const { + if (isThumb()) { + if (isAPCS_ABI()) { + return std::string("e-p:32:32-f64:32:32-i64:32:32-" + "i16:16:32-i8:8:32-i1:8:32-" + "v128:32:128-v64:32:64-a:0:32-n32"); + } else { + return std::string("e-p:32:32-f64:64:64-i64:64:64-" + "i16:16:32-i8:8:32-i1:8:32-" + "v128:64:128-v64:64:64-a:0:32-n32"); + } + } else { + if (isAPCS_ABI()) { + return std::string("e-p:32:32-f64:32:32-i64:32:32-" + "v128:32:128-v64:32:64-n32"); + } else { + return std::string("e-p:32:32-f64:64:64-i64:64:64-" + "v128:64:128-v64:64:64-n32"); + } + } + } }; } // End llvm namespace