ARMSubtarget.cpp revision 5cdc3a949af0cef7f2163f8a7acbf3049c226321
1a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===-- ARMSubtarget.cpp - ARM Subtarget Information ------------*- C++ -*-===//
2a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
3a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//                     The LLVM Compiler Infrastructure
4a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
8a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===----------------------------------------------------------------------===//
9a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
10a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// This file implements the ARM specific subclass of TargetSubtarget.
11a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//
12a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===----------------------------------------------------------------------===//
13a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
14a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMSubtarget.h"
15a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMGenSubtarget.inc"
16e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng#include "llvm/GlobalValue.h"
170eebf653a7b2978e7761f8d068b6fbec22aea0f6Anton Korobeynikov#include "llvm/Target/TargetOptions.h"
1854fc124d72512d65d62565cabcd85c7b07496513Bob Wilson#include "llvm/Support/CommandLine.h"
19c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin#include "llvm/ADT/SmallVector.h"
20a8e2989ece6dc46df59b0768184028257f913843Evan Chengusing namespace llvm;
21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2254fc124d72512d65d62565cabcd85c7b07496513Bob Wilsonstatic cl::opt<bool>
2354fc124d72512d65d62565cabcd85c7b07496513Bob WilsonReserveR9("arm-reserve-r9", cl::Hidden,
2454fc124d72512d65d62565cabcd85c7b07496513Bob Wilson          cl::desc("Reserve R9, making it unavailable as GPR"));
259843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwinstatic cl::opt<bool>
269843a93e830e76f96e9a997b3002624a28ca5aa6David GoodwinUseNEONFP("arm-use-neon-fp",
279843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin          cl::desc("Use NEON for single-precision FP"),
289843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin          cl::init(false), cl::Hidden);
2954fc124d72512d65d62565cabcd85c7b07496513Bob Wilson
305cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikovstatic cl::opt<bool>
315cdc3a949af0cef7f2163f8a7acbf3049c226321Anton KorobeynikovUseMOVT("arm-use-movt",
325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        cl::init(true), cl::Hidden);
335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
343be03406c9c3b2075d5ae416499af2f15f703d6fDaniel DunbarARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
35d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng                           bool isT)
361a3771e30e48b9cc21ccdc79fc9cf37ec4104b17Evan Cheng  : ARMArchVersion(V4T)
376d7d2aa38a247426e2ccf53e3c6ad0315c9a4d8cAnton Korobeynikov  , ARMFPUType(None)
389843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin  , UseNEONForSinglePrecisionFP(UseNEONFP)
39d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng  , IsThumb(isT)
4070459bef9ccd73b3a2a44fdd62f2509861112745Anton Korobeynikov  , ThumbMode(Thumb1)
410dad89fa94536284d51f60868326294b725a0c61David Goodwin  , PostRAScheduler(false)
4254fc124d72512d65d62565cabcd85c7b07496513Bob Wilson  , IsR9Reserved(ReserveR9)
435cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  , UseMovt(UseMOVT)
443630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio  , stackAlignment(4)
4541a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov  , CPUString("generic")
463630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio  , TargetType(isELF) // Default to ELF unless otherwise specified.
473630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio  , TargetABI(ARM_ABI_APCS) {
480eebf653a7b2978e7761f8d068b6fbec22aea0f6Anton Korobeynikov  // default to soft float ABI
490eebf653a7b2978e7761f8d068b6fbec22aea0f6Anton Korobeynikov  if (FloatABIType == FloatABI::Default)
500eebf653a7b2978e7761f8d068b6fbec22aea0f6Anton Korobeynikov    FloatABIType = FloatABI::Soft;
510eebf653a7b2978e7761f8d068b6fbec22aea0f6Anton Korobeynikov
52a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Determine default and user specified characteristics
53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Parse features string.
5541a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov  CPUString = ParseSubtargetFeatures(FS, CPUString);
56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
57a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Set the boolean corresponding to the current target triple, or the default
58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // if one cannot be determined, to true.
594b1747430a2d67702958b95d6776396734f184a0Evan Cheng  unsigned Len = TT.length();
608c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng  unsigned Idx = 0;
61d4022c3fbb0705abdc8eddc3ee4a5059f5ef8094Anton Korobeynikov
628c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng  if (Len >= 5 && TT.substr(0, 4) == "armv")
638c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng    Idx = 4;
649170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson  else if (Len >= 6 && TT.substr(0, 5) == "thumb") {
6570459bef9ccd73b3a2a44fdd62f2509861112745Anton Korobeynikov    IsThumb = true;
668c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng    if (Len >= 7 && TT[5] == 'v')
678c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng      Idx = 6;
688c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng  }
698c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng  if (Idx) {
708c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng    unsigned SubVer = TT[Idx];
718c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng    if (SubVer > '4' && SubVer <= '9') {
729170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson      if (SubVer >= '7') {
73d4022c3fbb0705abdc8eddc3ee4a5059f5ef8094Anton Korobeynikov        ARMArchVersion = V7A;
749170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson      } else if (SubVer == '6') {
758c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng        ARMArchVersion = V6;
769170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson        if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
779170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson          ARMArchVersion = V6T2;
789170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson      } else if (SubVer == '5') {
798c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng        ARMArchVersion = V5T;
808c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng        if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e')
818c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng          ARMArchVersion = V5TE;
824b1747430a2d67702958b95d6776396734f184a0Evan Cheng      }
839170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson      if (ARMArchVersion >= V6T2)
849170ab6685fcd820c6274e761b8c3a71f25ae074Bob Wilson        ThumbMode = Thumb2;
854b1747430a2d67702958b95d6776396734f184a0Evan Cheng    }
864b1747430a2d67702958b95d6776396734f184a0Evan Cheng  }
874b1747430a2d67702958b95d6776396734f184a0Evan Cheng
88b620724e614c6594e7b269b6ea7d8483947ea944Evan Cheng  // Thumb2 implies at least V6T2.
89b620724e614c6594e7b269b6ea7d8483947ea944Evan Cheng  if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2)
90b620724e614c6594e7b269b6ea7d8483947ea944Evan Cheng    ARMArchVersion = V6T2;
91b620724e614c6594e7b269b6ea7d8483947ea944Evan Cheng
928c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng  if (Len >= 10) {
931a3771e30e48b9cc21ccdc79fc9cf37ec4104b17Evan Cheng    if (TT.find("-darwin") != std::string::npos)
948c6b991635ff589fbe4b8db013bcc1d2ef57a0e0Evan Cheng      // arm-darwin
951a3771e30e48b9cc21ccdc79fc9cf37ec4104b17Evan Cheng      TargetType = isDarwin;
96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
97a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
983630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio  if (TT.find("eabi") != std::string::npos)
993630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio    TargetABI = ARM_ABI_AAPCS;
1003630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio
1013630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio  if (isAAPCS_ABI())
1023630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio    stackAlignment = 8;
1033630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio
104cd828618b8c6ec58df94aec0f5546f009f2fd0d5Evan Cheng  if (isTargetDarwin())
10554fc124d72512d65d62565cabcd85c7b07496513Bob Wilson    IsR9Reserved = ReserveR9 | (ARMArchVersion < V6);
106471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin
107d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng  if (!isThumb() || hasThumb2())
108d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng    PostRAScheduler = true;
109d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng
110471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin  // Set CPU specific features.
111471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin  if (CPUString == "cortex-a8") {
112b46aea10324263dd63492fc5c1d54800e980c8f8Evan Cheng    // On Cortex-a8, it's faster to perform some single-precision FP
113fee0c1074c68a61d15899fb8cb31f1902fa9e509Evan Cheng    // operations with NEON instructions.
1149843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin    if (UseNEONFP.getPosition() == 0)
1159843a93e830e76f96e9a997b3002624a28ca5aa6David Goodwin      UseNEONForSinglePrecisionFP = true;
116471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin  }
117834b08af8d3d8fc6c76ac6ca40674565689e8d7fBob Wilson  HasBranchTargetBuffer = (CPUString == "cortex-a8" ||
118834b08af8d3d8fc6c76ac6ca40674565689e8d7fBob Wilson                           CPUString == "cortex-a9");
119a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
120e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng
121e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol.
12263476a80404125e5196b6c09113c1d4796da0604Evan Chengbool
12363476a80404125e5196b6c09113c1d4796da0604Evan ChengARMSubtarget::GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) const {
12463476a80404125e5196b6c09113c1d4796da0604Evan Cheng  if (RelocM == Reloc::Static)
125e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng    return false;
12663476a80404125e5196b6c09113c1d4796da0604Evan Cheng
12763476a80404125e5196b6c09113c1d4796da0604Evan Cheng  // GV with ghost linkage (in JIT lazy compilation mode) do not require an
12863476a80404125e5196b6c09113c1d4796da0604Evan Cheng  // extra load from stub.
12963476a80404125e5196b6c09113c1d4796da0604Evan Cheng  bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
13063476a80404125e5196b6c09113c1d4796da0604Evan Cheng
13163476a80404125e5196b6c09113c1d4796da0604Evan Cheng  if (!isTargetDarwin()) {
13263476a80404125e5196b6c09113c1d4796da0604Evan Cheng    // Extra load is needed for all externally visible.
13363476a80404125e5196b6c09113c1d4796da0604Evan Cheng    if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
13463476a80404125e5196b6c09113c1d4796da0604Evan Cheng      return false;
13563476a80404125e5196b6c09113c1d4796da0604Evan Cheng    return true;
13663476a80404125e5196b6c09113c1d4796da0604Evan Cheng  } else {
13763476a80404125e5196b6c09113c1d4796da0604Evan Cheng    if (RelocM == Reloc::PIC_) {
13863476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // If this is a strong reference to a definition, it is definitely not
13963476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // through a stub.
14063476a80404125e5196b6c09113c1d4796da0604Evan Cheng      if (!isDecl && !GV->isWeakForLinker())
14163476a80404125e5196b6c09113c1d4796da0604Evan Cheng        return false;
14263476a80404125e5196b6c09113c1d4796da0604Evan Cheng
14363476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // Unless we have a symbol with hidden visibility, we have to go through a
14463476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // normal $non_lazy_ptr stub because this symbol might be resolved late.
14563476a80404125e5196b6c09113c1d4796da0604Evan Cheng      if (!GV->hasHiddenVisibility())  // Non-hidden $non_lazy_ptr reference.
14663476a80404125e5196b6c09113c1d4796da0604Evan Cheng        return true;
14763476a80404125e5196b6c09113c1d4796da0604Evan Cheng
14863476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // If symbol visibility is hidden, we have a stub for common symbol
14963476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // references and external declarations.
15063476a80404125e5196b6c09113c1d4796da0604Evan Cheng      if (isDecl || GV->hasCommonLinkage())
15163476a80404125e5196b6c09113c1d4796da0604Evan Cheng        // Hidden $non_lazy_ptr reference.
15263476a80404125e5196b6c09113c1d4796da0604Evan Cheng        return true;
15363476a80404125e5196b6c09113c1d4796da0604Evan Cheng
15463476a80404125e5196b6c09113c1d4796da0604Evan Cheng      return false;
15563476a80404125e5196b6c09113c1d4796da0604Evan Cheng    } else {
15663476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // If this is a strong reference to a definition, it is definitely not
15763476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // through a stub.
15863476a80404125e5196b6c09113c1d4796da0604Evan Cheng      if (!isDecl && !GV->isWeakForLinker())
15963476a80404125e5196b6c09113c1d4796da0604Evan Cheng        return false;
16063476a80404125e5196b6c09113c1d4796da0604Evan Cheng
16163476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // Unless we have a symbol with hidden visibility, we have to go through a
16263476a80404125e5196b6c09113c1d4796da0604Evan Cheng      // normal $non_lazy_ptr stub because this symbol might be resolved late.
16363476a80404125e5196b6c09113c1d4796da0604Evan Cheng      if (!GV->hasHiddenVisibility())  // Non-hidden $non_lazy_ptr reference.
16463476a80404125e5196b6c09113c1d4796da0604Evan Cheng        return true;
16563476a80404125e5196b6c09113c1d4796da0604Evan Cheng    }
16663476a80404125e5196b6c09113c1d4796da0604Evan Cheng  }
16763476a80404125e5196b6c09113c1d4796da0604Evan Cheng
16863476a80404125e5196b6c09113c1d4796da0604Evan Cheng  return false;
169e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng}
170c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin
171c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwinbool ARMSubtarget::enablePostRAScheduler(
172c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin           CodeGenOpt::Level OptLevel,
173c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin           TargetSubtarget::AntiDepBreakMode& Mode,
17487d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin           RegClassVector& CriticalPathRCs) const {
175c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin  Mode = TargetSubtarget::ANTIDEP_CRITICAL;
17687d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin  CriticalPathRCs.clear();
17787d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin  CriticalPathRCs.push_back(&ARM::GPRRegClass);
178c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin  return PostRAScheduler && OptLevel >= CodeGenOpt::Default;
179c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin}
180