1 //===-- ARMSubtarget.h - Define Subtarget for the ARM ----------*- C++ -*--===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares the ARM specific subclass of TargetSubtargetInfo. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H 14 #define LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H 15 16 #include "ARMBaseInstrInfo.h" 17 #include "ARMBaseRegisterInfo.h" 18 #include "ARMConstantPoolValue.h" 19 #include "ARMFrameLowering.h" 20 #include "ARMISelLowering.h" 21 #include "ARMMachineFunctionInfo.h" 22 #include "ARMSelectionDAGInfo.h" 23 #include "llvm/ADT/Triple.h" 24 #include "llvm/Analysis/TargetTransformInfo.h" 25 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 26 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 27 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 28 #include "llvm/CodeGen/MachineFunction.h" 29 #include "llvm/CodeGen/RegisterBankInfo.h" 30 #include "llvm/CodeGen/TargetSubtargetInfo.h" 31 #include "llvm/MC/MCInstrItineraries.h" 32 #include "llvm/MC/MCSchedule.h" 33 #include "llvm/Target/TargetMachine.h" 34 #include "llvm/Target/TargetOptions.h" 35 #include <memory> 36 #include <string> 37 38 #define GET_SUBTARGETINFO_HEADER 39 #include "ARMGenSubtargetInfo.inc" 40 41 namespace llvm { 42 43 class ARMBaseTargetMachine; 44 class GlobalValue; 45 class StringRef; 46 47 class ARMSubtarget : public ARMGenSubtargetInfo { 48 protected: 49 enum ARMProcFamilyEnum { 50 Others, 51 52 CortexA12, 53 CortexA15, 54 CortexA17, 55 CortexA32, 56 CortexA35, 57 CortexA5, 58 CortexA53, 59 CortexA55, 60 CortexA57, 61 CortexA7, 62 CortexA72, 63 CortexA73, 64 CortexA75, 65 CortexA76, 66 CortexA77, 67 CortexA78, 68 CortexA78C, 69 CortexA710, 70 CortexA8, 71 CortexA9, 72 CortexM3, 73 CortexM7, 74 CortexR4, 75 CortexR4F, 76 CortexR5, 77 CortexR52, 78 CortexR7, 79 CortexX1, 80 CortexX1C, 81 Exynos, 82 Krait, 83 Kryo, 84 NeoverseN1, 85 NeoverseN2, 86 NeoverseV1, 87 Swift 88 }; 89 enum ARMProcClassEnum { 90 None, 91 92 AClass, 93 MClass, 94 RClass 95 }; 96 enum ARMArchEnum { 97 ARMv2, 98 ARMv2a, 99 ARMv3, 100 ARMv3m, 101 ARMv4, 102 ARMv4t, 103 ARMv5, 104 ARMv5t, 105 ARMv5te, 106 ARMv5tej, 107 ARMv6, 108 ARMv6k, 109 ARMv6kz, 110 ARMv6m, 111 ARMv6sm, 112 ARMv6t2, 113 ARMv7a, 114 ARMv7em, 115 ARMv7m, 116 ARMv7r, 117 ARMv7ve, 118 ARMv81a, 119 ARMv82a, 120 ARMv83a, 121 ARMv84a, 122 ARMv85a, 123 ARMv86a, 124 ARMv87a, 125 ARMv88a, 126 ARMv8a, 127 ARMv8mBaseline, 128 ARMv8mMainline, 129 ARMv8r, 130 ARMv81mMainline, 131 ARMv9a, 132 ARMv91a, 133 ARMv92a, 134 ARMv93a, 135 }; 136 137 public: 138 /// What kind of timing do load multiple/store multiple instructions have. 139 enum ARMLdStMultipleTiming { 140 /// Can load/store 2 registers/cycle. 141 DoubleIssue, 142 /// Can load/store 2 registers/cycle, but needs an extra cycle if the access 143 /// is not 64-bit aligned. 144 DoubleIssueCheckUnalignedAccess, 145 /// Can load/store 1 register/cycle. 146 SingleIssue, 147 /// Can load/store 1 register/cycle, but needs an extra cycle for address 148 /// computation and potentially also for register writeback. 149 SingleIssuePlusExtras, 150 }; 151 152 protected: 153 // Bool members corresponding to the SubtargetFeatures defined in tablegen 154 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 155 bool ATTRIBUTE = DEFAULT; 156 #include "ARMGenSubtargetInfo.inc" 157 158 /// ARMProcFamily - ARM processor family: Cortex-A8, Cortex-A9, and others. 159 ARMProcFamilyEnum ARMProcFamily = Others; 160 161 /// ARMProcClass - ARM processor class: None, AClass, RClass or MClass. 162 ARMProcClassEnum ARMProcClass = None; 163 164 /// ARMArch - ARM architecture 165 ARMArchEnum ARMArch = ARMv4t; 166 167 /// UseMulOps - True if non-microcoded fused integer multiply-add and 168 /// multiply-subtract instructions should be used. 169 bool UseMulOps = false; 170 171 /// SupportsTailCall - True if the OS supports tail call. The dynamic linker 172 /// must be able to synthesize call stubs for interworking between ARM and 173 /// Thumb. 174 bool SupportsTailCall = false; 175 176 /// RestrictIT - If true, the subtarget disallows generation of complex IT 177 /// blocks. 178 bool RestrictIT = false; 179 180 /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS). 181 bool UseSjLjEH = false; 182 183 /// stackAlignment - The minimum alignment known to hold of the stack frame on 184 /// entry to the function and which must be maintained by every function. 185 Align stackAlignment = Align(4); 186 187 /// CPUString - String name of used CPU. 188 std::string CPUString; 189 190 unsigned MaxInterleaveFactor = 1; 191 192 /// Clearance before partial register updates (in number of instructions) 193 unsigned PartialUpdateClearance = 0; 194 195 /// What kind of timing do load multiple/store multiple have (double issue, 196 /// single issue etc). 197 ARMLdStMultipleTiming LdStMultipleTiming = SingleIssue; 198 199 /// The adjustment that we need to apply to get the operand latency from the 200 /// operand cycle returned by the itinerary data for pre-ISel operands. 201 int PreISelOperandLatencyAdjustment = 2; 202 203 /// What alignment is preferred for loop bodies, in log2(bytes). 204 unsigned PrefLoopLogAlignment = 0; 205 206 /// The cost factor for MVE instructions, representing the multiple beats an 207 // instruction can take. The default is 2, (set in initSubtargetFeatures so 208 // that we can use subtarget features less than 2). 209 unsigned MVEVectorCostFactor = 0; 210 211 /// OptMinSize - True if we're optimising for minimum code size, equal to 212 /// the function attribute. 213 bool OptMinSize = false; 214 215 /// IsLittle - The target is Little Endian 216 bool IsLittle; 217 218 /// TargetTriple - What processor and OS we're targeting. 219 Triple TargetTriple; 220 221 /// SchedModel - Processor specific instruction costs. 222 MCSchedModel SchedModel; 223 224 /// Selected instruction itineraries (one entry per itinerary class.) 225 InstrItineraryData InstrItins; 226 227 /// Options passed via command line that could influence the target 228 const TargetOptions &Options; 229 230 const ARMBaseTargetMachine &TM; 231 232 public: 233 /// This constructor initializes the data members to match that 234 /// of the specified triple. 235 /// 236 ARMSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS, 237 const ARMBaseTargetMachine &TM, bool IsLittle, 238 bool MinSize = false); 239 240 /// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size 241 /// that still makes it profitable to inline the call. 242 unsigned getMaxInlineSizeThreshold() const { 243 return 64; 244 } 245 246 /// getMaxMemcpyTPInlineSizeThreshold - Returns the maximum size 247 /// that still makes it profitable to inline a llvm.memcpy as a Tail 248 /// Predicated loop. 249 /// This threshold should only be used for constant size inputs. 250 unsigned getMaxMemcpyTPInlineSizeThreshold() const { return 128; } 251 252 /// ParseSubtargetFeatures - Parses features string setting specified 253 /// subtarget options. Definition of function is auto generated by tblgen. 254 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 255 256 /// initializeSubtargetDependencies - Initializes using a CPU and feature string 257 /// so that we can use initializer lists for subtarget initialization. 258 ARMSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); 259 260 const ARMSelectionDAGInfo *getSelectionDAGInfo() const override { 261 return &TSInfo; 262 } 263 264 const ARMBaseInstrInfo *getInstrInfo() const override { 265 return InstrInfo.get(); 266 } 267 268 const ARMTargetLowering *getTargetLowering() const override { 269 return &TLInfo; 270 } 271 272 const ARMFrameLowering *getFrameLowering() const override { 273 return FrameLowering.get(); 274 } 275 276 const ARMBaseRegisterInfo *getRegisterInfo() const override { 277 return &InstrInfo->getRegisterInfo(); 278 } 279 280 const CallLowering *getCallLowering() const override; 281 InstructionSelector *getInstructionSelector() const override; 282 const LegalizerInfo *getLegalizerInfo() const override; 283 const RegisterBankInfo *getRegBankInfo() const override; 284 285 private: 286 ARMSelectionDAGInfo TSInfo; 287 // Either Thumb1FrameLowering or ARMFrameLowering. 288 std::unique_ptr<ARMFrameLowering> FrameLowering; 289 // Either Thumb1InstrInfo or Thumb2InstrInfo. 290 std::unique_ptr<ARMBaseInstrInfo> InstrInfo; 291 ARMTargetLowering TLInfo; 292 293 /// GlobalISel related APIs. 294 std::unique_ptr<CallLowering> CallLoweringInfo; 295 std::unique_ptr<InstructionSelector> InstSelector; 296 std::unique_ptr<LegalizerInfo> Legalizer; 297 std::unique_ptr<RegisterBankInfo> RegBankInfo; 298 299 void initializeEnvironment(); 300 void initSubtargetFeatures(StringRef CPU, StringRef FS); 301 ARMFrameLowering *initializeFrameLowering(StringRef CPU, StringRef FS); 302 303 std::bitset<8> CoprocCDE = {}; 304 public: 305 // Getters for SubtargetFeatures defined in tablegen 306 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 307 bool GETTER() const { return ATTRIBUTE; } 308 #include "ARMGenSubtargetInfo.inc" 309 310 void computeIssueWidth(); 311 312 /// @{ 313 /// These functions are obsolete, please consider adding subtarget features 314 /// or properties instead of calling them. 315 bool isCortexA5() const { return ARMProcFamily == CortexA5; } 316 bool isCortexA7() const { return ARMProcFamily == CortexA7; } 317 bool isCortexA8() const { return ARMProcFamily == CortexA8; } 318 bool isCortexA9() const { return ARMProcFamily == CortexA9; } 319 bool isCortexA15() const { return ARMProcFamily == CortexA15; } 320 bool isSwift() const { return ARMProcFamily == Swift; } 321 bool isCortexM3() const { return ARMProcFamily == CortexM3; } 322 bool isCortexM7() const { return ARMProcFamily == CortexM7; } 323 bool isLikeA9() const { return isCortexA9() || isCortexA15() || isKrait(); } 324 bool isCortexR5() const { return ARMProcFamily == CortexR5; } 325 bool isKrait() const { return ARMProcFamily == Krait; } 326 /// @} 327 328 bool hasARMOps() const { return !NoARM; } 329 330 bool useNEONForSinglePrecisionFP() const { 331 return hasNEON() && hasNEONForFP(); 332 } 333 334 bool hasVFP2Base() const { return hasVFPv2SP(); } 335 bool hasVFP3Base() const { return hasVFPv3D16SP(); } 336 bool hasVFP4Base() const { return hasVFPv4D16SP(); } 337 bool hasFPARMv8Base() const { return hasFPARMv8D16SP(); } 338 339 bool hasAnyDataBarrier() const { 340 return HasDataBarrier || (hasV6Ops() && !isThumb()); 341 } 342 343 bool useMulOps() const { return UseMulOps; } 344 bool useFPVMLx() const { return !SlowFPVMLx; } 345 bool useFPVFMx() const { 346 return !isTargetDarwin() && hasVFP4Base() && !SlowFPVFMx; 347 } 348 bool useFPVFMx16() const { return useFPVFMx() && hasFullFP16(); } 349 bool useFPVFMx64() const { return useFPVFMx() && hasFP64(); } 350 bool useSjLjEH() const { return UseSjLjEH; } 351 bool hasBaseDSP() const { 352 if (isThumb()) 353 return hasDSP(); 354 else 355 return hasV5TEOps(); 356 } 357 358 /// Return true if the CPU supports any kind of instruction fusion. 359 bool hasFusion() const { return hasFuseAES() || hasFuseLiterals(); } 360 361 const Triple &getTargetTriple() const { return TargetTriple; } 362 363 bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); } 364 bool isTargetIOS() const { return TargetTriple.isiOS(); } 365 bool isTargetWatchOS() const { return TargetTriple.isWatchOS(); } 366 bool isTargetWatchABI() const { return TargetTriple.isWatchABI(); } 367 bool isTargetDriverKit() const { return TargetTriple.isDriverKit(); } 368 bool isTargetLinux() const { return TargetTriple.isOSLinux(); } 369 bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } 370 bool isTargetNetBSD() const { return TargetTriple.isOSNetBSD(); } 371 bool isTargetWindows() const { return TargetTriple.isOSWindows(); } 372 373 bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); } 374 bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 375 bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); } 376 377 // ARM EABI is the bare-metal EABI described in ARM ABI documents and 378 // can be accessed via -target arm-none-eabi. This is NOT GNUEABI. 379 // FIXME: Add a flag for bare-metal for that target and set Triple::EABI 380 // even for GNUEABI, so we can make a distinction here and still conform to 381 // the EABI on GNU (and Android) mode. This requires change in Clang, too. 382 // FIXME: The Darwin exception is temporary, while we move users to 383 // "*-*-*-macho" triples as quickly as possible. 384 bool isTargetAEABI() const { 385 return (TargetTriple.getEnvironment() == Triple::EABI || 386 TargetTriple.getEnvironment() == Triple::EABIHF) && 387 !isTargetDarwin() && !isTargetWindows(); 388 } 389 bool isTargetGNUAEABI() const { 390 return (TargetTriple.getEnvironment() == Triple::GNUEABI || 391 TargetTriple.getEnvironment() == Triple::GNUEABIHF) && 392 !isTargetDarwin() && !isTargetWindows(); 393 } 394 bool isTargetMuslAEABI() const { 395 return (TargetTriple.getEnvironment() == Triple::MuslEABI || 396 TargetTriple.getEnvironment() == Triple::MuslEABIHF) && 397 !isTargetDarwin() && !isTargetWindows(); 398 } 399 400 // ARM Targets that support EHABI exception handling standard 401 // Darwin uses SjLj. Other targets might need more checks. 402 bool isTargetEHABICompatible() const { 403 return TargetTriple.isTargetEHABICompatible(); 404 } 405 406 bool isTargetHardFloat() const; 407 408 bool isTargetAndroid() const { return TargetTriple.isAndroid(); } 409 410 bool isXRaySupported() const override; 411 412 bool isAPCS_ABI() const; 413 bool isAAPCS_ABI() const; 414 bool isAAPCS16_ABI() const; 415 416 bool isROPI() const; 417 bool isRWPI() const; 418 419 bool useMachineScheduler() const { return UseMISched; } 420 bool useMachinePipeliner() const { return UseMIPipeliner; } 421 bool hasMinSize() const { return OptMinSize; } 422 bool isThumb1Only() const { return isThumb() && !hasThumb2(); } 423 bool isThumb2() const { return isThumb() && hasThumb2(); } 424 bool isMClass() const { return ARMProcClass == MClass; } 425 bool isRClass() const { return ARMProcClass == RClass; } 426 bool isAClass() const { return ARMProcClass == AClass; } 427 428 bool isR9Reserved() const { 429 return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9; 430 } 431 432 MCPhysReg getFramePointerReg() const { 433 if (isTargetDarwin() || 434 (!isTargetWindows() && isThumb() && !createAAPCSFrameChain())) 435 return ARM::R7; 436 return ARM::R11; 437 } 438 439 /// Returns true if the frame setup is split into two separate pushes (first 440 /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent 441 /// to lr. This is always required on Thumb1-only targets, as the push and 442 /// pop instructions can't access the high registers. 443 bool splitFramePushPop(const MachineFunction &MF) const { 444 if (MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress()) 445 return true; 446 return (getFramePointerReg() == ARM::R7 && 447 MF.getTarget().Options.DisableFramePointerElim(MF)) || 448 isThumb1Only(); 449 } 450 451 bool splitFramePointerPush(const MachineFunction &MF) const; 452 453 bool useStride4VFPs() const; 454 455 bool useMovt() const; 456 457 bool supportsTailCall() const { return SupportsTailCall; } 458 459 bool allowsUnalignedMem() const { return !StrictAlign; } 460 461 bool restrictIT() const { return RestrictIT; } 462 463 const std::string & getCPUString() const { return CPUString; } 464 465 bool isLittle() const { return IsLittle; } 466 467 unsigned getMispredictionPenalty() const; 468 469 /// Returns true if machine scheduler should be enabled. 470 bool enableMachineScheduler() const override; 471 472 /// Returns true if machine pipeliner should be enabled. 473 bool enableMachinePipeliner() const override; 474 bool useDFAforSMS() const override; 475 476 /// True for some subtargets at > -O0. 477 bool enablePostRAScheduler() const override; 478 479 /// True for some subtargets at > -O0. 480 bool enablePostRAMachineScheduler() const override; 481 482 /// Check whether this subtarget wants to use subregister liveness. 483 bool enableSubRegLiveness() const override; 484 485 /// Enable use of alias analysis during code generation (during MI 486 /// scheduling, DAGCombine, etc.). 487 bool useAA() const override { return true; } 488 489 /// getInstrItins - Return the instruction itineraries based on subtarget 490 /// selection. 491 const InstrItineraryData *getInstrItineraryData() const override { 492 return &InstrItins; 493 } 494 495 /// getStackAlignment - Returns the minimum alignment known to hold of the 496 /// stack frame on entry to the function and which must be maintained by every 497 /// function for this subtarget. 498 Align getStackAlignment() const { return stackAlignment; } 499 500 unsigned getMaxInterleaveFactor() const { return MaxInterleaveFactor; } 501 502 unsigned getPartialUpdateClearance() const { return PartialUpdateClearance; } 503 504 ARMLdStMultipleTiming getLdStMultipleTiming() const { 505 return LdStMultipleTiming; 506 } 507 508 int getPreISelOperandLatencyAdjustment() const { 509 return PreISelOperandLatencyAdjustment; 510 } 511 512 /// True if the GV will be accessed via an indirect symbol. 513 bool isGVIndirectSymbol(const GlobalValue *GV) const; 514 515 /// Returns the constant pool modifier needed to access the GV. 516 bool isGVInGOT(const GlobalValue *GV) const; 517 518 /// True if fast-isel is used. 519 bool useFastISel() const; 520 521 /// Returns the correct return opcode for the current feature set. 522 /// Use BX if available to allow mixing thumb/arm code, but fall back 523 /// to plain mov pc,lr on ARMv4. 524 unsigned getReturnOpcode() const { 525 if (isThumb()) 526 return ARM::tBX_RET; 527 if (hasV4TOps()) 528 return ARM::BX_RET; 529 return ARM::MOVPCLR; 530 } 531 532 /// Allow movt+movw for PIC global address calculation. 533 /// ELF does not have GOT relocations for movt+movw. 534 /// ROPI does not use GOT. 535 bool allowPositionIndependentMovt() const { 536 return isROPI() || !isTargetELF(); 537 } 538 539 unsigned getPrefLoopLogAlignment() const { return PrefLoopLogAlignment; } 540 541 unsigned 542 getMVEVectorCostFactor(TargetTransformInfo::TargetCostKind CostKind) const { 543 if (CostKind == TargetTransformInfo::TCK_CodeSize) 544 return 1; 545 return MVEVectorCostFactor; 546 } 547 548 bool ignoreCSRForAllocationOrder(const MachineFunction &MF, 549 unsigned PhysReg) const override; 550 unsigned getGPRAllocationOrder(const MachineFunction &MF) const; 551 }; 552 553 } // end namespace llvm 554 555 #endif // LLVM_LIB_TARGET_ARM_ARMSUBTARGET_H 556