X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMSubtarget.cpp;h=c6f266b0753100b6ea9a6d7075bf0f8fa7dd69f0;hb=7a10ab7d6f50b59580cc8ab1eb52d562e81f28d8;hp=9e55cd870031b4154a0ac2bf45eda8bf945a0e31;hpb=bd17bc96bf54cc58d91c2d20964c6c5e28bffa57;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 9e55cd87003..c6f266b0753 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -13,6 +13,7 @@ #include "ARMSubtarget.h" #include "ARMGenSubtarget.inc" +#include "ARMBaseRegisterInfo.h" #include "llvm/GlobalValue.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" @@ -24,38 +25,54 @@ ReserveR9("arm-reserve-r9", cl::Hidden, cl::desc("Reserve R9, making it unavailable as GPR")); static cl::opt -UseMOVT("arm-use-movt", - cl::init(true), cl::Hidden); +DarwinUseMOVT("arm-darwin-use-movt", cl::init(true), cl::Hidden); + +static cl::opt +StrictAlign("arm-strict-align", cl::Hidden, + cl::desc("Disallow all unaligned memory accesses")); ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, bool isT) : ARMArchVersion(V4) + , ARMProcFamily(Others) , ARMFPUType(None) , UseNEONForSinglePrecisionFP(false) - , SlowVMLx(false) + , SlowFPVMLx(false) + , HasVMLxForwarding(false) + , SlowFPBrcc(false) , IsThumb(isT) , ThumbMode(Thumb1) + , NoARM(false) , PostRAScheduler(false) , IsR9Reserved(ReserveR9) - , UseMovt(UseMOVT) + , UseMovt(false) , HasFP16(false) + , HasD16(false) + , HasHardwareDivide(false) + , HasT2ExtractPack(false) + , HasDataBarrier(false) + , Pref32BitThumb(false) + , AvoidCPSRPartialUpdate(false) + , HasMPExtension(false) + , FPOnlySP(false) + , AllowsUnalignedMem(false) , stackAlignment(4) , CPUString("generic") - , TargetType(isELF) // Default to ELF unless otherwise specified. + , TargetTriple(TT) , TargetABI(ARM_ABI_APCS) { - // default to soft float ABI + // Default to soft float ABI if (FloatABIType == FloatABI::Default) FloatABIType = FloatABI::Soft; // Determine default and user specified characteristics - // Parse features string. - CPUString = ParseSubtargetFeatures(FS, CPUString); - // When no arch is specified either by CPU or by attributes, make the default // ARMv4T. - if (CPUString == "generic" && (FS.empty() || FS == "generic")) + const char *ARMArchFeature = ""; + if (CPUString == "generic" && (FS.empty() || FS == "generic")) { ARMArchVersion = V4T; + ARMArchFeature = ",+v4t"; + } // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. @@ -73,56 +90,92 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, unsigned SubVer = TT[Idx]; if (SubVer >= '7' && SubVer <= '9') { ARMArchVersion = V7A; + ARMArchFeature = ",+v7a"; + if (Len >= Idx+2 && TT[Idx+1] == 'm') { + ARMArchVersion = V7M; + ARMArchFeature = ",+v7m"; + } } else if (SubVer == '6') { ARMArchVersion = V6; - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') + ARMArchFeature = ",+v6"; + if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') { ARMArchVersion = V6T2; + ARMArchFeature = ",+v6t2"; + } } else if (SubVer == '5') { ARMArchVersion = V5T; - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') + ARMArchFeature = ",+v5t"; + if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') { ARMArchVersion = V5TE; + ARMArchFeature = ",+v5te"; + } } else if (SubVer == '4') { - if (Len >= Idx+2 && TT[Idx+1] == 't') + if (Len >= Idx+2 && TT[Idx+1] == 't') { ARMArchVersion = V4T; - else + ARMArchFeature = ",+v4t"; + } else { ARMArchVersion = V4; + ARMArchFeature = ""; + } } } + if (TT.find("eabi") != std::string::npos) + TargetABI = ARM_ABI_AAPCS; + + // Parse features string. If the first entry in FS (the CPU) is missing, + // insert the architecture feature derived from the target triple. This is + // important for setting features that are implied based on the architecture + // version. + std::string FSWithArch; + if (FS.empty()) + FSWithArch = std::string(ARMArchFeature); + else if (FS.find(',') == 0) + FSWithArch = std::string(ARMArchFeature) + FS; + else + FSWithArch = FS; + CPUString = ParseSubtargetFeatures(FSWithArch, CPUString); + + // After parsing Itineraries, set ItinData.IssueWidth. + computeIssueWidth(); + // Thumb2 implies at least V6T2. if (ARMArchVersion >= V6T2) ThumbMode = Thumb2; else if (ThumbMode >= Thumb2) ARMArchVersion = V6T2; - if (Len >= 10) { - if (TT.find("-darwin") != std::string::npos) - // arm-darwin - TargetType = isDarwin; - } - - if (TT.find("eabi") != std::string::npos) - TargetABI = ARM_ABI_AAPCS; - if (isAAPCS_ABI()) stackAlignment = 8; - if (isTargetDarwin()) + if (!isTargetDarwin()) + UseMovt = hasV6T2Ops(); + else { IsR9Reserved = ReserveR9 | (ARMArchVersion < V6); + UseMovt = DarwinUseMOVT && hasV6T2Ops(); + } if (!isThumb() || hasThumb2()) PostRAScheduler = true; + + // v6+ may or may not support unaligned mem access depending on the system + // configuration. + if (!StrictAlign && hasV6Ops() && isTargetDarwin()) + AllowsUnalignedMem = true; } /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. bool -ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const { +ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV, + Reloc::Model RelocM) const { if (RelocM == Reloc::Static) return false; // Materializable GVs (in JIT lazy compilation mode) do not require an extra // load from stub. - bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); + bool isDecl = GV->hasAvailableExternallyLinkage(); + if (GV->isDeclaration() && !GV->isMaterializable()) + isDecl = true; if (!isTargetDarwin()) { // Extra load is needed for all externally visible. @@ -153,7 +206,7 @@ ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const { // through a stub. if (!isDecl && !GV->isWeakForLinker()) return false; - + // Unless we have a symbol with hidden visibility, we have to go through a // normal $non_lazy_ptr stub because this symbol might be resolved late. if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. @@ -164,6 +217,34 @@ ARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const { return false; } +unsigned ARMSubtarget::getMispredictionPenalty() const { + // If we have a reasonable estimate of the pipeline depth, then we can + // estimate the penalty of a misprediction based on that. + if (isCortexA8()) + return 13; + else if (isCortexA9()) + return 8; + + // Otherwise, just return a sensible default. + return 10; +} + +void ARMSubtarget::computeIssueWidth() { + unsigned allStage1Units = 0; + for (const InstrItinerary *itin = InstrItins.Itineraries; + itin->FirstStage != ~0U; ++itin) { + const InstrStage *IS = InstrItins.Stages + itin->FirstStage; + allStage1Units |= IS->getUnits(); + } + InstrItins.IssueWidth = 0; + while (allStage1Units) { + ++InstrItins.IssueWidth; + // clear the lowest bit + allStage1Units ^= allStage1Units & ~(allStage1Units - 1); + } + assert(InstrItins.IssueWidth <= 2 && "itinerary bug, too many stage 1 units"); +} + bool ARMSubtarget::enablePostRAScheduler( CodeGenOpt::Level OptLevel, TargetSubtarget::AntiDepBreakMode& Mode,