ARMSubtarget.cpp revision 94ca42ff0407d71bacc41de4032d8dbe6358d33d
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// 105b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng// This file implements the ARM specific subclass of TargetSubtargetInfo. 11a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// 12a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//===----------------------------------------------------------------------===// 13a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 14a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMSubtarget.h" 15b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h" 16e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng#include "llvm/GlobalValue.h" 175b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng#include "llvm/Target/TargetSubtargetInfo.h" 1854fc124d72512d65d62565cabcd85c7b07496513Bob Wilson#include "llvm/Support/CommandLine.h" 19c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin#include "llvm/ADT/SmallVector.h" 2094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#define GET_SUBTARGETINFO_CTOR 2294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#define GET_SUBTARGETINFO_MC_DESC 2394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#define GET_SUBTARGETINFO_TARGET_DESC 24385e930d55f3ecd3c9538823dfa5896a12461845Evan Cheng#include "ARMGenSubtargetInfo.inc" 2594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 26a8e2989ece6dc46df59b0768184028257f913843Evan Chengusing namespace llvm; 27a8e2989ece6dc46df59b0768184028257f913843Evan Cheng 2854fc124d72512d65d62565cabcd85c7b07496513Bob Wilsonstatic cl::opt<bool> 2954fc124d72512d65d62565cabcd85c7b07496513Bob WilsonReserveR9("arm-reserve-r9", cl::Hidden, 3054fc124d72512d65d62565cabcd85c7b07496513Bob Wilson cl::desc("Reserve R9, making it unavailable as GPR")); 3154fc124d72512d65d62565cabcd85c7b07496513Bob Wilson 325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikovstatic cl::opt<bool> 3353519f015e3e84e9f57b677cc8724805a6009b73Evan ChengDarwinUseMOVT("arm-darwin-use-movt", cl::init(true), cl::Hidden); 345cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov 3502aba73a9ec04d0de9424422249af3948ca9573aBob Wilsonstatic cl::opt<bool> 3602aba73a9ec04d0de9424422249af3948ca9573aBob WilsonStrictAlign("arm-strict-align", cl::Hidden, 3702aba73a9ec04d0de9424422249af3948ca9573aBob Wilson cl::desc("Disallow all unaligned memory accesses")); 3802aba73a9ec04d0de9424422249af3948ca9573aBob Wilson 39276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan ChengARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, 4094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng const std::string &FS) 4194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng : ARMGenSubtargetInfo() 4294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng , ARMArchVersion(V4) 433ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1Evan Cheng , ARMProcFamily(Others) 446d7d2aa38a247426e2ccf53e3c6ad0315c9a4d8cAnton Korobeynikov , ARMFPUType(None) 457ec7a0e96b34fedf11445c1dde27a4fac8e8a1a7Jim Grosbach , UseNEONForSinglePrecisionFP(false) 4648575f6ea7d5cd21ab29ca370f58fcf9ca31400bEvan Cheng , SlowFPVMLx(false) 470e3ee43ea058a35ab5ce69cceafd316d49eaad34Benjamin Kramer , HasVMLxForwarding(false) 489de1ac267e197d40cec7a14041f2bf69498536c9Evan Cheng , SlowFPBrcc(false) 4994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng , IsThumb(false) 5094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng , HasThumb2(false) 517b4d31176efe6894bcfaa05257dd5783acda5ddcEvan Cheng , NoARM(false) 520dad89fa94536284d51f60868326294b725a0c61David Goodwin , PostRAScheduler(false) 5354fc124d72512d65d62565cabcd85c7b07496513Bob Wilson , IsR9Reserved(ReserveR9) 545de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng , UseMovt(false) 55631379e79c0971c5bac13629b8caf8912ed4c35cAnton Korobeynikov , HasFP16(false) 5677f42b52781b6923924a93b8ab338d183887a592Bob Wilson , HasD16(false) 5729402132f3e890a2771818f44987ede213297431Jim Grosbach , HasHardwareDivide(false) 5829402132f3e890a2771818f44987ede213297431Jim Grosbach , HasT2ExtractPack(false) 5911db068721d44fd5f9b0c2a3a4c90f813d2eae9cEvan Cheng , HasDataBarrier(false) 609de1ac267e197d40cec7a14041f2bf69498536c9Evan Cheng , Pref32BitThumb(false) 615dde893c2bac9e1569c38429f756c1d723e8edf2Bob Wilson , AvoidCPSRPartialUpdate(false) 62dfed19fe2c34c1209108afa58e8ab014ffd894e2Evan Cheng , HasMPExtension(false) 63fcba5e6b645df89ae6b93911fe0f80b08fa6b44cJim Grosbach , FPOnlySP(false) 6402aba73a9ec04d0de9424422249af3948ca9573aBob Wilson , AllowsUnalignedMem(false) 65a7603982dbf9e240ecc7ed6eddcd1cdb868107acJim Grosbach , Thumb2DSP(false) 663630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio , stackAlignment(4) 67276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng , CPUString(CPU) 68b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng , TargetTriple(TT) 693630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio , TargetABI(ARM_ABI_APCS) { 70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng // Determine default and user specified characteristics 71276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng if (CPUString.empty()) 72276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng CPUString = "generic"; 734b1747430a2d67702958b95d6776396734f184a0Evan Cheng 743630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio if (TT.find("eabi") != std::string::npos) 753630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio TargetABI = ARM_ABI_AAPCS; 763630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio 774cc446bc400b2ff58af81c91f5e145b81d6beb26Evan Cheng // Insert the architecture feature derived from the target triple into the 784cc446bc400b2ff58af81c91f5e145b81d6beb26Evan Cheng // feature string. This is important for setting features that are implied 794cc446bc400b2ff58af81c91f5e145b81d6beb26Evan Cheng // based on the architecture version. 8094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng std::string ArchFS = ARM_MC::ParseARMTriple(TT, IsThumb); 8194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (!FS.empty()) { 8294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (!ArchFS.empty()) 8394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ArchFS = ArchFS + "," + FS; 8494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng else 8594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ArchFS = FS; 8694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 8794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 8894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ParseSubtargetFeatures(ArchFS, CPUString); 8994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 9094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // Thumb2 implies at least V6T2. FIXME: Fix tests to explicitly specify a 9194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // ARM version or CPU and then remove this. 9294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (ARMArchVersion < V6T2 && hasThumb2()) 9394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchVersion = V6T2; 9466f6c79450a93d979128d8702c83841c8f715dc8Bob Wilson 9594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng // Initialize scheduling itinerary for the specified CPU. 9694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng InstrItins = getInstrItineraryForCPU(CPUString); 9794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 982da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // After parsing Itineraries, set ItinData.IssueWidth. 992da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick computeIssueWidth(); 1002da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 1013630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio if (isAAPCS_ABI()) 1023630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio stackAlignment = 8; 1033630e78db9268dbe81a9369a33e49b857804f2ecLauro Ramos Venancio 1045de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng if (!isTargetDarwin()) 1055de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng UseMovt = hasV6T2Ops(); 1065de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng else { 10754fc124d72512d65d62565cabcd85c7b07496513Bob Wilson IsR9Reserved = ReserveR9 | (ARMArchVersion < V6); 10853519f015e3e84e9f57b677cc8724805a6009b73Evan Cheng UseMovt = DarwinUseMOVT && hasV6T2Ops(); 1095de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng } 110471850ab84301dd47cab2bf8d694fcb5766c1169David Goodwin 111d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng if (!isThumb() || hasThumb2()) 112d3dd50fec00fbbb76edbfaff4d613f1248d21c9eEvan Cheng PostRAScheduler = true; 11302aba73a9ec04d0de9424422249af3948ca9573aBob Wilson 11402aba73a9ec04d0de9424422249af3948ca9573aBob Wilson // v6+ may or may not support unaligned mem access depending on the system 11502aba73a9ec04d0de9424422249af3948ca9573aBob Wilson // configuration. 11602aba73a9ec04d0de9424422249af3948ca9573aBob Wilson if (!StrictAlign && hasV6Ops() && isTargetDarwin()) 11702aba73a9ec04d0de9424422249af3948ca9573aBob Wilson AllowsUnalignedMem = true; 118a8e2989ece6dc46df59b0768184028257f913843Evan Cheng} 119e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng 120e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. 12163476a80404125e5196b6c09113c1d4796da0604Evan Chengbool 12246510a73e977273ec67747eb34cbdb43f815e451Dan GohmanARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV, 12346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman Reloc::Model RelocM) const { 12463476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (RelocM == Reloc::Static) 125e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng return false; 12663476a80404125e5196b6c09113c1d4796da0604Evan Cheng 127f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin // Materializable GVs (in JIT lazy compilation mode) do not require an extra 128f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin // load from stub. 129af05c69ba024b1838ae6f1071d6fd0f9fe33999fEvan Cheng bool isDecl = GV->hasAvailableExternallyLinkage(); 130af05c69ba024b1838ae6f1071d6fd0f9fe33999fEvan Cheng if (GV->isDeclaration() && !GV->isMaterializable()) 131af05c69ba024b1838ae6f1071d6fd0f9fe33999fEvan Cheng isDecl = true; 13263476a80404125e5196b6c09113c1d4796da0604Evan Cheng 13363476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (!isTargetDarwin()) { 13463476a80404125e5196b6c09113c1d4796da0604Evan Cheng // Extra load is needed for all externally visible. 13563476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) 13663476a80404125e5196b6c09113c1d4796da0604Evan Cheng return false; 13763476a80404125e5196b6c09113c1d4796da0604Evan Cheng return true; 13863476a80404125e5196b6c09113c1d4796da0604Evan Cheng } else { 13963476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (RelocM == Reloc::PIC_) { 14063476a80404125e5196b6c09113c1d4796da0604Evan Cheng // If this is a strong reference to a definition, it is definitely not 14163476a80404125e5196b6c09113c1d4796da0604Evan Cheng // through a stub. 14263476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (!isDecl && !GV->isWeakForLinker()) 14363476a80404125e5196b6c09113c1d4796da0604Evan Cheng return false; 14463476a80404125e5196b6c09113c1d4796da0604Evan Cheng 14563476a80404125e5196b6c09113c1d4796da0604Evan Cheng // Unless we have a symbol with hidden visibility, we have to go through a 14663476a80404125e5196b6c09113c1d4796da0604Evan Cheng // normal $non_lazy_ptr stub because this symbol might be resolved late. 14763476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 14863476a80404125e5196b6c09113c1d4796da0604Evan Cheng return true; 14963476a80404125e5196b6c09113c1d4796da0604Evan Cheng 15063476a80404125e5196b6c09113c1d4796da0604Evan Cheng // If symbol visibility is hidden, we have a stub for common symbol 15163476a80404125e5196b6c09113c1d4796da0604Evan Cheng // references and external declarations. 15263476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (isDecl || GV->hasCommonLinkage()) 15363476a80404125e5196b6c09113c1d4796da0604Evan Cheng // Hidden $non_lazy_ptr reference. 15463476a80404125e5196b6c09113c1d4796da0604Evan Cheng return true; 15563476a80404125e5196b6c09113c1d4796da0604Evan Cheng 15663476a80404125e5196b6c09113c1d4796da0604Evan Cheng return false; 15763476a80404125e5196b6c09113c1d4796da0604Evan Cheng } else { 15863476a80404125e5196b6c09113c1d4796da0604Evan Cheng // If this is a strong reference to a definition, it is definitely not 15963476a80404125e5196b6c09113c1d4796da0604Evan Cheng // through a stub. 16063476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (!isDecl && !GV->isWeakForLinker()) 16163476a80404125e5196b6c09113c1d4796da0604Evan Cheng return false; 1626e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 16363476a80404125e5196b6c09113c1d4796da0604Evan Cheng // Unless we have a symbol with hidden visibility, we have to go through a 16463476a80404125e5196b6c09113c1d4796da0604Evan Cheng // normal $non_lazy_ptr stub because this symbol might be resolved late. 16563476a80404125e5196b6c09113c1d4796da0604Evan Cheng if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 16663476a80404125e5196b6c09113c1d4796da0604Evan Cheng return true; 16763476a80404125e5196b6c09113c1d4796da0604Evan Cheng } 16863476a80404125e5196b6c09113c1d4796da0604Evan Cheng } 16963476a80404125e5196b6c09113c1d4796da0604Evan Cheng 17063476a80404125e5196b6c09113c1d4796da0604Evan Cheng return false; 171e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng} 172c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin 173654d5440a477b1f6c89b051107e041a331f78e27Owen Andersonunsigned ARMSubtarget::getMispredictionPenalty() const { 174654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson // If we have a reasonable estimate of the pipeline depth, then we can 175654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson // estimate the penalty of a misprediction based on that. 176654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson if (isCortexA8()) 177654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson return 13; 178654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson else if (isCortexA9()) 179654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson return 8; 1806e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick 181654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson // Otherwise, just return a sensible default. 182654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson return 10; 183654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson} 184654d5440a477b1f6c89b051107e041a331f78e27Owen Anderson 1852da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trickvoid ARMSubtarget::computeIssueWidth() { 1862da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick unsigned allStage1Units = 0; 1872da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick for (const InstrItinerary *itin = InstrItins.Itineraries; 1882da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick itin->FirstStage != ~0U; ++itin) { 1892da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick const InstrStage *IS = InstrItins.Stages + itin->FirstStage; 1902da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick allStage1Units |= IS->getUnits(); 1912da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick } 1922da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick InstrItins.IssueWidth = 0; 1932da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick while (allStage1Units) { 1942da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick ++InstrItins.IssueWidth; 1952da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick // clear the lowest bit 1962da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick allStage1Units ^= allStage1Units & ~(allStage1Units - 1); 1972da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick } 1986018deefe823598a3bbe03de9af354d269ae2130Andrew Trick assert(InstrItins.IssueWidth <= 2 && "itinerary bug, too many stage 1 units"); 1992da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick} 2002da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick 201c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwinbool ARMSubtarget::enablePostRAScheduler( 202c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin CodeGenOpt::Level OptLevel, 2035b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng TargetSubtargetInfo::AntiDepBreakMode& Mode, 20487d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin RegClassVector& CriticalPathRCs) const { 2055b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL; 20687d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin CriticalPathRCs.clear(); 20787d21b92fc42f6b3bd8567a83fc5b5191c1205e5David Goodwin CriticalPathRCs.push_back(&ARM::GPRRegClass); 208c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin return PostRAScheduler && OptLevel >= CodeGenOpt::Default; 209c2e8a7e8d2ab156afaa8ab0d0317dd9ee3db7d30David Goodwin} 210