ARMSubtarget.cpp revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===-- ARMSubtarget.cpp - ARM Subtarget Information ----------------------===// 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The LLVM Compiler Infrastructure 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// License. See LICENSE.TXT for details. 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===// 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file implements the ARM specific subclass of TargetSubtargetInfo. 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===// 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ARMSubtarget.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ARMFrameLowering.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ARMISelLowering.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ARMInstrInfo.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ARMJITInfo.h" 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ARMSelectionDAGInfo.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ARMSubtarget.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "Thumb1FrameLowering.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "Thumb1InstrInfo.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "Thumb2InstrInfo.h" 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "llvm/IR/Attributes.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/IR/Function.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/IR/GlobalValue.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/Support/CommandLine.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "llvm/Target/TargetInstrInfo.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/Target/TargetOptions.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using namespace llvm; 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define DEBUG_TYPE "arm-subtarget" 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define GET_SUBTARGETINFO_TARGET_DESC 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define GET_SUBTARGETINFO_CTOR 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ARMGenSubtargetInfo.inc" 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static cl::opt<bool> 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ReserveR9("arm-reserve-r9", cl::Hidden, 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cl::desc("Reserve R9, making it unavailable as GPR")); 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static cl::opt<bool> 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochArmUseMOVT("arm-use-movt", cl::init(true), cl::Hidden); 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static cl::opt<bool> 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)UseFusedMulOps("arm-use-mulops", 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cl::init(true), cl::Hidden); 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochenum AlignMode { 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DefaultAlign, 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) StrictAlign, 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NoStrictAlign 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static cl::opt<AlignMode> 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)Align(cl::desc("Load/store alignment support"), 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cl::Hidden, cl::init(DefaultAlign), 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cl::values( 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) clEnumValN(DefaultAlign, "arm-default-align", 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "Generate unaligned accesses only on hardware/OS " 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "combinations that are known to support them"), 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) clEnumValN(StrictAlign, "arm-strict-align", 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "Disallow all unaligned memory accesses"), 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch clEnumValN(NoStrictAlign, "arm-no-strict-align", 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Allow unaligned memory accesses"), 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) clEnumValEnd)); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum ITMode { 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DefaultIT, 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RestrictedIT, 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NoRestrictedIT 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static cl::opt<ITMode> 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) cl::ZeroOrMore, 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cl::values(clEnumValN(DefaultIT, "arm-default-it", 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "Generate IT block based on arch"), 800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) clEnumValN(RestrictedIT, "arm-restrict-it", 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Disallow deprecated IT based on ARMv8"), 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) clEnumValN(NoRestrictedIT, "arm-no-restrict-it", 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) "Allow IT blocks based on ARMv7"), 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) clEnumValEnd)); 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static std::string computeDataLayout(ARMSubtarget &ST) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string Ret = ""; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ST.isLittle()) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Little endian. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += "e"; 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Big endian. 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += "E"; 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += DataLayout::getManglingComponent(ST.getTargetTriple()); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pointers are 32 bits and aligned to 32 bits. 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += "-p:32:32"; 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // On thumb, i16,i18 and i1 have natural aligment requirements, but we try to 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // align to 32. 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (ST.isThumb()) 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Ret += "-i1:8:32-i8:8:32-i16:16:32"; 1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ABIs other than APCS have 64 bit integers with natural alignment. 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ST.isAPCS_ABI()) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += "-i64:64"; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We have 64 bits floats. The APCS ABI requires them to be aligned to 32 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // bits, others to 64 bits. We always try to align to 64 bits. 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ST.isAPCS_ABI()) 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Ret += "-f64:32:64"; 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 115ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // We have 128 and 64 bit vectors. The APCS ABI aligns them to 32 bits, others 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to 64. We always ty to give them natural alignment. 117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ST.isAPCS_ABI()) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret += "-v64:32:64-v128:32:128"; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Ret += "-v128:64:128"; 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // On thumb and APCS, only try to align aggregates to 32 bits (the default is 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // 64 bits). 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ST.isThumb() || ST.isAPCS_ABI()) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Ret += "-a:0:32"; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Integer registers are 32 bits. 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Ret += "-n32"; 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 130 // The stack is 128 bit aligned on NaCl, 64 bit aligned on AAPCS and 32 bit 131 // aligned everywhere else. 132 if (ST.isTargetNaCl()) 133 Ret += "-S128"; 134 else if (ST.isAAPCS_ABI()) 135 Ret += "-S64"; 136 else 137 Ret += "-S32"; 138 139 return Ret; 140} 141 142/// initializeSubtargetDependencies - Initializes using a CPU and feature string 143/// so that we can use initializer lists for subtarget initialization. 144ARMSubtarget &ARMSubtarget::initializeSubtargetDependencies(StringRef CPU, 145 StringRef FS) { 146 initializeEnvironment(); 147 resetSubtargetFeatures(CPU, FS); 148 return *this; 149} 150 151ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU, 152 const std::string &FS, TargetMachine &TM, 153 bool IsLittle, const TargetOptions &Options) 154 : ARMGenSubtargetInfo(TT, CPU, FS), ARMProcFamily(Others), 155 ARMProcClass(None), stackAlignment(4), CPUString(CPU), IsLittle(IsLittle), 156 TargetTriple(TT), Options(Options), TargetABI(ARM_ABI_UNKNOWN), 157 DL(computeDataLayout(initializeSubtargetDependencies(CPU, FS))), 158 TSInfo(DL), JITInfo(), 159 InstrInfo(isThumb1Only() 160 ? (ARMBaseInstrInfo *)new Thumb1InstrInfo(*this) 161 : !isThumb() 162 ? (ARMBaseInstrInfo *)new ARMInstrInfo(*this) 163 : (ARMBaseInstrInfo *)new Thumb2InstrInfo(*this)), 164 TLInfo(TM), 165 FrameLowering(!isThumb1Only() 166 ? new ARMFrameLowering(*this) 167 : (ARMFrameLowering *)new Thumb1FrameLowering(*this)) {} 168 169void ARMSubtarget::initializeEnvironment() { 170 HasV4TOps = false; 171 HasV5TOps = false; 172 HasV5TEOps = false; 173 HasV6Ops = false; 174 HasV6MOps = false; 175 HasV6T2Ops = false; 176 HasV7Ops = false; 177 HasV8Ops = false; 178 HasVFPv2 = false; 179 HasVFPv3 = false; 180 HasVFPv4 = false; 181 HasFPARMv8 = false; 182 HasNEON = false; 183 UseNEONForSinglePrecisionFP = false; 184 UseMulOps = UseFusedMulOps; 185 SlowFPVMLx = false; 186 HasVMLxForwarding = false; 187 SlowFPBrcc = false; 188 InThumbMode = false; 189 HasThumb2 = false; 190 NoARM = false; 191 PostRAScheduler = false; 192 IsR9Reserved = ReserveR9; 193 UseMovt = false; 194 SupportsTailCall = false; 195 HasFP16 = false; 196 HasD16 = false; 197 HasHardwareDivide = false; 198 HasHardwareDivideInARM = false; 199 HasT2ExtractPack = false; 200 HasDataBarrier = false; 201 Pref32BitThumb = false; 202 AvoidCPSRPartialUpdate = false; 203 AvoidMOVsShifterOperand = false; 204 HasRAS = false; 205 HasMPExtension = false; 206 HasVirtualization = false; 207 FPOnlySP = false; 208 HasPerfMon = false; 209 HasTrustZone = false; 210 HasCrypto = false; 211 HasCRC = false; 212 HasZeroCycleZeroing = false; 213 AllowsUnalignedMem = false; 214 Thumb2DSP = false; 215 UseNaClTrap = false; 216 UnsafeFPMath = false; 217 UseLong64 = false; 218} 219 220void ARMSubtarget::resetSubtargetFeatures(const MachineFunction *MF) { 221 AttributeSet FnAttrs = MF->getFunction()->getAttributes(); 222 Attribute CPUAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 223 "target-cpu"); 224 Attribute FSAttr = FnAttrs.getAttribute(AttributeSet::FunctionIndex, 225 "target-features"); 226 std::string CPU = 227 !CPUAttr.hasAttribute(Attribute::None) ?CPUAttr.getValueAsString() : ""; 228 std::string FS = 229 !FSAttr.hasAttribute(Attribute::None) ? FSAttr.getValueAsString() : ""; 230 if (!FS.empty()) { 231 initializeEnvironment(); 232 resetSubtargetFeatures(CPU, FS); 233 } 234} 235 236void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) { 237 if (CPUString.empty()) { 238 if (isTargetIOS() && TargetTriple.getArchName().endswith("v7s")) 239 // Default to the Swift CPU when targeting armv7s/thumbv7s. 240 CPUString = "swift"; 241 else 242 CPUString = "generic"; 243 } 244 245 // Insert the architecture feature derived from the target triple into the 246 // feature string. This is important for setting features that are implied 247 // based on the architecture version. 248 std::string ArchFS = ARM_MC::ParseARMTriple(TargetTriple.getTriple(), 249 CPUString); 250 if (!FS.empty()) { 251 if (!ArchFS.empty()) 252 ArchFS = ArchFS + "," + FS.str(); 253 else 254 ArchFS = FS; 255 } 256 ParseSubtargetFeatures(CPUString, ArchFS); 257 258 // FIXME: This used enable V6T2 support implicitly for Thumb2 mode. 259 // Assert this for now to make the change obvious. 260 assert(hasV6T2Ops() || !hasThumb2()); 261 262 // Keep a pointer to static instruction cost data for the specified CPU. 263 SchedModel = getSchedModelForCPU(CPUString); 264 265 // Initialize scheduling itinerary for the specified CPU. 266 InstrItins = getInstrItineraryForCPU(CPUString); 267 268 if (TargetABI == ARM_ABI_UNKNOWN) { 269 switch (TargetTriple.getEnvironment()) { 270 case Triple::Android: 271 case Triple::EABI: 272 case Triple::EABIHF: 273 case Triple::GNUEABI: 274 case Triple::GNUEABIHF: 275 TargetABI = ARM_ABI_AAPCS; 276 break; 277 default: 278 if ((isTargetIOS() && isMClass()) || 279 (TargetTriple.isOSBinFormatMachO() && 280 TargetTriple.getOS() == Triple::UnknownOS)) 281 TargetABI = ARM_ABI_AAPCS; 282 else 283 TargetABI = ARM_ABI_APCS; 284 break; 285 } 286 } 287 288 // FIXME: this is invalid for WindowsCE 289 if (isTargetWindows()) { 290 TargetABI = ARM_ABI_AAPCS; 291 NoARM = true; 292 } 293 294 if (isAAPCS_ABI()) 295 stackAlignment = 8; 296 if (isTargetNaCl()) 297 stackAlignment = 16; 298 299 UseMovt = hasV6T2Ops() && ArmUseMOVT; 300 301 if (isTargetMachO()) { 302 IsR9Reserved = ReserveR9 | !HasV6Ops; 303 SupportsTailCall = !isTargetIOS() || !getTargetTriple().isOSVersionLT(5, 0); 304 } else { 305 IsR9Reserved = ReserveR9; 306 SupportsTailCall = !isThumb1Only(); 307 } 308 309 if (!isThumb() || hasThumb2()) 310 PostRAScheduler = true; 311 312 switch (Align) { 313 case DefaultAlign: 314 // Assume pre-ARMv6 doesn't support unaligned accesses. 315 // 316 // ARMv6 may or may not support unaligned accesses depending on the 317 // SCTLR.U bit, which is architecture-specific. We assume ARMv6 318 // Darwin and NetBSD targets support unaligned accesses, and others don't. 319 // 320 // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit 321 // which raises an alignment fault on unaligned accesses. Linux 322 // defaults this bit to 0 and handles it as a system-wide (not 323 // per-process) setting. It is therefore safe to assume that ARMv7+ 324 // Linux targets support unaligned accesses. The same goes for NaCl. 325 // 326 // The above behavior is consistent with GCC. 327 AllowsUnalignedMem = 328 (hasV7Ops() && (isTargetLinux() || isTargetNaCl() || 329 isTargetNetBSD())) || 330 (hasV6Ops() && (isTargetMachO() || isTargetNetBSD())); 331 // The one exception is cortex-m0, which despite being v6, does not 332 // support unaligned accesses. Rather than make the above boolean 333 // expression even more obtuse, just override the value here. 334 if (isThumb1Only() && isMClass()) 335 AllowsUnalignedMem = false; 336 break; 337 case StrictAlign: 338 AllowsUnalignedMem = false; 339 break; 340 case NoStrictAlign: 341 AllowsUnalignedMem = true; 342 break; 343 } 344 345 switch (IT) { 346 case DefaultIT: 347 RestrictIT = hasV8Ops() ? true : false; 348 break; 349 case RestrictedIT: 350 RestrictIT = true; 351 break; 352 case NoRestrictedIT: 353 RestrictIT = false; 354 break; 355 } 356 357 // NEON f32 ops are non-IEEE 754 compliant. Darwin is ok with it by default. 358 uint64_t Bits = getFeatureBits(); 359 if ((Bits & ARM::ProcA5 || Bits & ARM::ProcA8) && // Where this matters 360 (Options.UnsafeFPMath || isTargetDarwin())) 361 UseNEONForSinglePrecisionFP = true; 362} 363 364/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol. 365bool 366ARMSubtarget::GVIsIndirectSymbol(const GlobalValue *GV, 367 Reloc::Model RelocM) const { 368 if (RelocM == Reloc::Static) 369 return false; 370 371 // Materializable GVs (in JIT lazy compilation mode) do not require an extra 372 // load from stub. 373 bool isDecl = GV->hasAvailableExternallyLinkage(); 374 if (GV->isDeclaration() && !GV->isMaterializable()) 375 isDecl = true; 376 377 if (!isTargetMachO()) { 378 // Extra load is needed for all externally visible. 379 if (GV->hasLocalLinkage() || GV->hasHiddenVisibility()) 380 return false; 381 return true; 382 } else { 383 if (RelocM == Reloc::PIC_) { 384 // If this is a strong reference to a definition, it is definitely not 385 // through a stub. 386 if (!isDecl && !GV->isWeakForLinker()) 387 return false; 388 389 // Unless we have a symbol with hidden visibility, we have to go through a 390 // normal $non_lazy_ptr stub because this symbol might be resolved late. 391 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 392 return true; 393 394 // If symbol visibility is hidden, we have a stub for common symbol 395 // references and external declarations. 396 if (isDecl || GV->hasCommonLinkage()) 397 // Hidden $non_lazy_ptr reference. 398 return true; 399 400 return false; 401 } else { 402 // If this is a strong reference to a definition, it is definitely not 403 // through a stub. 404 if (!isDecl && !GV->isWeakForLinker()) 405 return false; 406 407 // Unless we have a symbol with hidden visibility, we have to go through a 408 // normal $non_lazy_ptr stub because this symbol might be resolved late. 409 if (!GV->hasHiddenVisibility()) // Non-hidden $non_lazy_ptr reference. 410 return true; 411 } 412 } 413 414 return false; 415} 416 417unsigned ARMSubtarget::getMispredictionPenalty() const { 418 return SchedModel->MispredictPenalty; 419} 420 421bool ARMSubtarget::hasSinCos() const { 422 return getTargetTriple().getOS() == Triple::IOS && 423 !getTargetTriple().isOSVersionLT(7, 0); 424} 425 426// Enable the PostMachineScheduler if the target selects it instead of 427// PostRAScheduler. Currently only available on the command line via 428// -misched-postra. 429bool ARMSubtarget::enablePostMachineScheduler() const { 430 return PostRAScheduler; 431} 432 433bool ARMSubtarget::enableAtomicExpandLoadLinked() const { 434 return hasAnyDataBarrier() && !isThumb1Only(); 435} 436 437bool ARMSubtarget::enablePostRAScheduler( 438 CodeGenOpt::Level OptLevel, 439 TargetSubtargetInfo::AntiDepBreakMode& Mode, 440 RegClassVector& CriticalPathRCs) const { 441 Mode = TargetSubtargetInfo::ANTIDEP_NONE; 442 return PostRAScheduler && OptLevel >= CodeGenOpt::Default; 443} 444 445bool ARMSubtarget::useMovt(const MachineFunction &MF) const { 446 // NOTE Windows on ARM needs to use mov.w/mov.t pairs to materialise 32-bit 447 // immediates as it is inherently position independent, and may be out of 448 // range otherwise. 449 return UseMovt && (isTargetWindows() || 450 !MF.getFunction()->getAttributes().hasAttribute( 451 AttributeSet::FunctionIndex, Attribute::MinSize)); 452} 453