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