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