|  | //===----------------------------------------------------------------------===// | 
|  | // ARM Subtarget state. | 
|  | // | 
|  |  | 
|  | // True if compiling for Thumb, false for ARM. | 
|  | def ModeThumb             : SubtargetFeature<"thumb-mode", "IsThumb", | 
|  | "true", "Thumb mode">; | 
|  |  | 
|  | // True if we're using software floating point features. | 
|  | def ModeSoftFloat         : SubtargetFeature<"soft-float","UseSoftFloat", | 
|  | "true", "Use software floating " | 
|  | "point features.">; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // ARM Subtarget features. | 
|  | // | 
|  |  | 
|  | // This is currently only used by AArch64, but is required here because ARM and | 
|  | // AArch64 share a tablegen backend for TargetParser. | 
|  | class Extension< | 
|  | string TargetFeatureName,            // String used for -target-feature. | 
|  | string Spelling,                     // The XYZ in HasXYZ and AEK_XYZ. | 
|  | string Desc,                         // Description. | 
|  | list<SubtargetFeature> Implies = []  // List of dependent features. | 
|  | > : SubtargetFeature<TargetFeatureName, "Has" # Spelling, "true", Desc, Implies> | 
|  | { | 
|  | string ArchExtKindSpelling = "AEK_" # Spelling; // ArchExtKind enum name. | 
|  | } | 
|  |  | 
|  | // Floating Point, HW Division and Neon Support | 
|  |  | 
|  | // FP loads/stores/moves, shared between VFP and MVE (even in the integer-only | 
|  | // version). | 
|  | def FeatureFPRegs         : SubtargetFeature<"fpregs", "HasFPRegs", "true", | 
|  | "Enable FP registers">; | 
|  |  | 
|  | // 16-bit FP loads/stores/moves, shared between VFP (with the v8.2A FP16 | 
|  | // extension) and MVE (even in the integer-only version). | 
|  | def FeatureFPRegs16       : SubtargetFeature<"fpregs16", "HasFPRegs16", "true", | 
|  | "Enable 16-bit FP registers", | 
|  | [FeatureFPRegs]>; | 
|  |  | 
|  | def FeatureFPRegs64       : SubtargetFeature<"fpregs64", "HasFPRegs64", "true", | 
|  | "Enable 64-bit FP registers", | 
|  | [FeatureFPRegs]>; | 
|  |  | 
|  | // True if the floating point unit supports double precision. | 
|  | def FeatureFP64           : SubtargetFeature<"fp64", "HasFP64", "true", | 
|  | "Floating point unit supports " | 
|  | "double precision", | 
|  | [FeatureFPRegs64]>; | 
|  |  | 
|  | // True if subtarget has the full 32 double precision FP registers for VFPv3. | 
|  | def FeatureD32            : SubtargetFeature<"d32", "HasD32", "true", | 
|  | "Extend FP to 32 double registers">; | 
|  |  | 
|  | /// Versions of the VFP flags restricted to single precision, or to | 
|  | /// 16 d-registers, or both. | 
|  | multiclass VFPver<string name, string query, string description, | 
|  | list<SubtargetFeature> prev, | 
|  | list<SubtargetFeature> otherimplies, | 
|  | list<SubtargetFeature> vfp2prev = []> { | 
|  | def _D16_SP: SubtargetFeature< | 
|  | name#"d16sp", query#"D16SP", "true", | 
|  | description#" with only 16 d-registers and no double precision", | 
|  | !foreach(v, prev, !cast<SubtargetFeature>(v # "_D16_SP")) # | 
|  | !foreach(v, vfp2prev, !cast<SubtargetFeature>(v # "_SP")) # | 
|  | otherimplies>; | 
|  | def _SP: SubtargetFeature< | 
|  | name#"sp", query#"SP", "true", | 
|  | description#" with no double precision", | 
|  | !foreach(v, prev, !cast<SubtargetFeature>(v # "_SP")) # | 
|  | otherimplies # [FeatureD32, !cast<SubtargetFeature>(NAME # "_D16_SP")]>; | 
|  | def _D16: SubtargetFeature< | 
|  | name#"d16", query#"D16", "true", | 
|  | description#" with only 16 d-registers", | 
|  | !foreach(v, prev, !cast<SubtargetFeature>(v # "_D16")) # | 
|  | vfp2prev # | 
|  | otherimplies # [FeatureFP64, !cast<SubtargetFeature>(NAME # "_D16_SP")]>; | 
|  | def "": SubtargetFeature< | 
|  | name, query, "true", description, | 
|  | prev # otherimplies # [ | 
|  | !cast<SubtargetFeature>(NAME # "_D16"), | 
|  | !cast<SubtargetFeature>(NAME # "_SP")]>; | 
|  | } | 
|  |  | 
|  | def FeatureVFP2_SP        : SubtargetFeature<"vfp2sp", "HasVFPv2SP", "true", | 
|  | "Enable VFP2 instructions with " | 
|  | "no double precision", | 
|  | [FeatureFPRegs]>; | 
|  |  | 
|  | def FeatureVFP2           : SubtargetFeature<"vfp2", "HasVFPv2", "true", | 
|  | "Enable VFP2 instructions", | 
|  | [FeatureFP64, FeatureVFP2_SP]>; | 
|  |  | 
|  | defm FeatureVFP3: VFPver<"vfp3", "HasVFPv3", "Enable VFP3 instructions", | 
|  | [], [], [FeatureVFP2]>; | 
|  |  | 
|  | def FeatureNEON           : SubtargetFeature<"neon", "HasNEON", "true", | 
|  | "Enable NEON instructions", | 
|  | [FeatureVFP3]>; | 
|  |  | 
|  | // True if subtarget supports half-precision FP conversions. | 
|  | def FeatureFP16           : SubtargetFeature<"fp16", "HasFP16", "true", | 
|  | "Enable half-precision " | 
|  | "floating point">; | 
|  |  | 
|  | defm FeatureVFP4: VFPver<"vfp4", "HasVFPv4", "Enable VFP4 instructions", | 
|  | [FeatureVFP3], [FeatureFP16]>; | 
|  |  | 
|  | defm FeatureFPARMv8: VFPver<"fp-armv8", "HasFPARMv8", "Enable ARMv8 FP", | 
|  | [FeatureVFP4], []>; | 
|  |  | 
|  | // True if subtarget supports half-precision FP operations. | 
|  | def FeatureFullFP16       : SubtargetFeature<"fullfp16", "HasFullFP16", "true", | 
|  | "Enable full half-precision " | 
|  | "floating point", | 
|  | [FeatureFPARMv8_D16_SP, FeatureFPRegs16]>; | 
|  |  | 
|  | // True if subtarget supports half-precision FP fml operations. | 
|  | def FeatureFP16FML        : SubtargetFeature<"fp16fml", "HasFP16FML", "true", | 
|  | "Enable full half-precision " | 
|  | "floating point fml instructions", | 
|  | [FeatureFullFP16]>; | 
|  |  | 
|  | // True if subtarget supports [su]div in Thumb mode. | 
|  | def FeatureHWDivThumb     : SubtargetFeature<"hwdiv", | 
|  | "HasDivideInThumbMode", "true", | 
|  | "Enable divide instructions in Thumb">; | 
|  |  | 
|  | // True if subtarget supports [su]div in ARM mode. | 
|  | def FeatureHWDivARM       : SubtargetFeature<"hwdiv-arm", | 
|  | "HasDivideInARMMode", "true", | 
|  | "Enable divide instructions in ARM mode">; | 
|  |  | 
|  | // Atomic Support | 
|  |  | 
|  | // True if the subtarget supports DMB / DSB data barrier instructions. | 
|  | def FeatureDB             : SubtargetFeature<"db", "HasDataBarrier", "true", | 
|  | "Has data barrier (dmb/dsb) instructions">; | 
|  |  | 
|  | // True if the subtarget supports CLREX instructions. | 
|  | def FeatureV7Clrex        : SubtargetFeature<"v7clrex", "HasV7Clrex", "true", | 
|  | "Has v7 clrex instruction">; | 
|  |  | 
|  | // True if the subtarget supports DFB data barrier instruction. | 
|  | def FeatureDFB  : SubtargetFeature<"dfb", "HasFullDataBarrier", "true", | 
|  | "Has full data barrier (dfb) instruction">; | 
|  |  | 
|  | // True if the subtarget supports v8 atomics (LDA/LDAEX etc) instructions. | 
|  | def FeatureAcquireRelease : SubtargetFeature<"acquire-release", | 
|  | "HasAcquireRelease", "true", | 
|  | "Has v8 acquire/release (lda/ldaex " | 
|  | " etc) instructions">; | 
|  |  | 
|  |  | 
|  | // True if floating point compare + branch is slow. | 
|  | def FeatureSlowFPBrcc     : SubtargetFeature<"slow-fp-brcc", "IsFPBrccSlow", "true", | 
|  | "FP compare + branch is slow">; | 
|  |  | 
|  | // True if the processor supports the Performance Monitor Extensions. These | 
|  | // include a generic cycle-counter as well as more fine-grained (often | 
|  | // implementation-specific) events. | 
|  | def FeaturePerfMon        : SubtargetFeature<"perfmon", "HasPerfMon", "true", | 
|  | "Enable support for Performance " | 
|  | "Monitor extensions">; | 
|  |  | 
|  |  | 
|  | // TrustZone Security Extensions | 
|  |  | 
|  | // True if processor supports TrustZone security extensions. | 
|  | def FeatureTrustZone      : SubtargetFeature<"trustzone", "HasTrustZone", "true", | 
|  | "Enable support for TrustZone " | 
|  | "security extensions">; | 
|  |  | 
|  | // True if processor supports ARMv8-M Security Extensions. | 
|  | def Feature8MSecExt       : SubtargetFeature<"8msecext", "Has8MSecExt", "true", | 
|  | "Enable support for ARMv8-M " | 
|  | "Security Extensions">; | 
|  |  | 
|  | // True if processor supports SHA1 and SHA256. | 
|  | def FeatureSHA2           : SubtargetFeature<"sha2", "HasSHA2", "true", | 
|  | "Enable SHA1 and SHA256 support", [FeatureNEON]>; | 
|  |  | 
|  | def FeatureAES            : SubtargetFeature<"aes", "HasAES", "true", | 
|  | "Enable AES support", [FeatureNEON]>; | 
|  |  | 
|  | // True if processor supports Cryptography extensions. | 
|  | def FeatureCrypto         : SubtargetFeature<"crypto", "HasCrypto", "true", | 
|  | "Enable support for " | 
|  | "Cryptography extensions", | 
|  | [FeatureNEON, FeatureSHA2, FeatureAES]>; | 
|  |  | 
|  | // True if processor supports CRC instructions. | 
|  | def FeatureCRC            : SubtargetFeature<"crc", "HasCRC", "true", | 
|  | "Enable support for CRC instructions">; | 
|  |  | 
|  | // True if the ARMv8.2A dot product instructions are supported. | 
|  | def FeatureDotProd        : SubtargetFeature<"dotprod", "HasDotProd", "true", | 
|  | "Enable support for dot product instructions", | 
|  | [FeatureNEON]>; | 
|  |  | 
|  | // True if the processor supports RAS extensions. | 
|  | // Not to be confused with FeatureHasRetAddrStack (return address stack). | 
|  | def FeatureRAS            : SubtargetFeature<"ras", "HasRAS", "true", | 
|  | "Enable Reliability, Availability " | 
|  | "and Serviceability extensions">; | 
|  |  | 
|  | // Fast computation of non-negative address offsets. | 
|  | // True if processor does positive address offset computation faster. | 
|  | def FeatureFPAO           : SubtargetFeature<"fpao", "HasFPAO", "true", | 
|  | "Enable fast computation of " | 
|  | "positive address offsets">; | 
|  |  | 
|  | // Fast execution of AES crypto operations. | 
|  | // True if processor executes back to back AES instruction pairs faster. | 
|  | def FeatureFuseAES        : SubtargetFeature<"fuse-aes", "HasFuseAES", "true", | 
|  | "CPU fuses AES crypto operations">; | 
|  |  | 
|  | // Fast execution of bottom and top halves of literal generation. | 
|  | // True if processor executes back to back bottom and top halves of literal generation faster. | 
|  | def FeatureFuseLiterals   : SubtargetFeature<"fuse-literals", "HasFuseLiterals", "true", | 
|  | "CPU fuses literal generation operations">; | 
|  |  | 
|  | // Choice of hardware register to use as the thread pointer, if any. | 
|  | def FeatureReadTpTPIDRURW :  SubtargetFeature<"read-tp-tpidrurw", "IsReadTPTPIDRURW", "true", | 
|  | "Reading thread pointer from TPIDRURW register">; | 
|  | def FeatureReadTpTPIDRURO :  SubtargetFeature<"read-tp-tpidruro", "IsReadTPTPIDRURO", "true", | 
|  | "Reading thread pointer from TPIDRURO register">; | 
|  | def FeatureReadTpTPIDRPRW :  SubtargetFeature<"read-tp-tpidrprw", "IsReadTPTPIDRPRW", "true", | 
|  | "Reading thread pointer from TPIDRPRW register">; | 
|  |  | 
|  | // Cyclone can zero VFP registers in 0 cycles. | 
|  | // True if the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are | 
|  | // particularly effective at zeroing a VFP register. | 
|  | def FeatureZCZeroing      : SubtargetFeature<"zcz", "HasZeroCycleZeroing", "true", | 
|  | "Has zero-cycle zeroing instructions">; | 
|  |  | 
|  | // Whether it is profitable to unpredicate certain instructions during if-conversion. | 
|  | // True if if conversion may decide to leave some instructions unpredicated. | 
|  | def FeatureProfUnpredicate : SubtargetFeature<"prof-unpr", | 
|  | "IsProfitableToUnpredicate", "true", | 
|  | "Is profitable to unpredicate">; | 
|  |  | 
|  | // Some targets (e.g. Swift) have microcoded VGETLNi32. | 
|  | // True if VMOV will be favored over VGETLNi32. | 
|  | def FeatureSlowVGETLNi32  : SubtargetFeature<"slow-vgetlni32", | 
|  | "HasSlowVGETLNi32", "true", | 
|  | "Has slow VGETLNi32 - prefer VMOV">; | 
|  |  | 
|  | // Some targets (e.g. Swift) have microcoded VDUP32. | 
|  | // True if VMOV will be favored over VDUP. | 
|  | def FeatureSlowVDUP32     : SubtargetFeature<"slow-vdup32", "HasSlowVDUP32", | 
|  | "true", | 
|  | "Has slow VDUP32 - prefer VMOV">; | 
|  |  | 
|  | // Some targets (e.g. Cortex-A9) prefer VMOVSR to VMOVDRR even when using NEON | 
|  | // for scalar FP, as this allows more effective execution domain optimization. | 
|  | // True if VMOVSR will be favored over VMOVDRR. | 
|  | def FeaturePreferVMOVSR   : SubtargetFeature<"prefer-vmovsr", "PreferVMOVSR", | 
|  | "true", "Prefer VMOVSR">; | 
|  |  | 
|  | // Swift has ISHST barriers compatible with Atomic Release semantics but weaker | 
|  | // than ISH. | 
|  | // True if ISHST barriers will be used for Release semantics. | 
|  | def FeaturePrefISHSTBarrier : SubtargetFeature<"prefer-ishst", "PreferISHSTBarriers", | 
|  | "true", "Prefer ISHST barriers">; | 
|  |  | 
|  | // Some targets (e.g. Cortex-A9) have muxed AGU and NEON/FPU. | 
|  | // True if the AGU and NEON/FPU units are multiplexed. | 
|  | def FeatureMuxedUnits     : SubtargetFeature<"muxed-units", "HasMuxedUnits", | 
|  | "true", | 
|  | "Has muxed AGU and NEON/FPU">; | 
|  |  | 
|  | // Whether VLDM/VSTM starting with odd register number need more microops | 
|  | // than single VLDRS. | 
|  | // True if a VLDM/VSTM starting with an odd register number is considered to | 
|  | // take more microops than single VLDRS/VSTRS. | 
|  | def FeatureSlowOddRegister : SubtargetFeature<"slow-odd-reg", "HasSlowOddRegister", | 
|  | "true", "VLDM/VSTM starting " | 
|  | "with an odd register is slow">; | 
|  |  | 
|  | // Some targets have a renaming dependency when loading into D subregisters. | 
|  | // True if loading into a D subregister will be penalized. | 
|  | def FeatureSlowLoadDSubreg : SubtargetFeature<"slow-load-D-subreg", | 
|  | "HasSlowLoadDSubregister", "true", | 
|  | "Loading into D subregs is slow">; | 
|  |  | 
|  | // True if use a wider stride when allocating VFP registers. | 
|  | def FeatureUseWideStrideVFP : SubtargetFeature<"wide-stride-vfp", | 
|  | "UseWideStrideVFP", "true", | 
|  | "Use a wide stride when allocating VFP registers">; | 
|  |  | 
|  | // Some targets (e.g. Cortex-A15) never want VMOVS to be widened to VMOVD. | 
|  | // True if VMOVS will never be widened to VMOVD. | 
|  | def FeatureDontWidenVMOVS : SubtargetFeature<"dont-widen-vmovs", | 
|  | "DontWidenVMOVS", "true", | 
|  | "Don't widen VMOVS to VMOVD">; | 
|  |  | 
|  | // Some targets (e.g. Cortex-A15) prefer to avoid mixing operations on different | 
|  | // VFP register widths. | 
|  | // True if splat a register between VFP and NEON instructions. | 
|  | def FeatureSplatVFPToNeon : SubtargetFeature<"splat-vfp-neon", | 
|  | "UseSplatVFPToNeon", "true", | 
|  | "Splat register from VFP to NEON", | 
|  | [FeatureDontWidenVMOVS]>; | 
|  |  | 
|  | // Whether or not it is profitable to expand VFP/NEON MLA/MLS instructions. | 
|  | // True if run the MLx expansion pass. | 
|  | def FeatureExpandMLx      : SubtargetFeature<"expand-fp-mlx", | 
|  | "ExpandMLx", "true", | 
|  | "Expand VFP/NEON MLA/MLS instructions">; | 
|  |  | 
|  | // Some targets have special RAW hazards for VFP/NEON VMLA/VMLS. | 
|  | // True if VFP/NEON VMLA/VMLS have special RAW hazards. | 
|  | def FeatureHasVMLxHazards : SubtargetFeature<"vmlx-hazards", "HasVMLxHazards", | 
|  | "true", "Has VMLx hazards">; | 
|  |  | 
|  | // Some targets (e.g. Cortex-A9) want to convert VMOVRS, VMOVSR and VMOVS from | 
|  | // VFP to NEON, as an execution domain optimization. | 
|  | // True if VMOVRS, VMOVSR and VMOVS will be converted from VFP to NEON. | 
|  | def FeatureNEONForFPMovs  : SubtargetFeature<"neon-fpmovs", | 
|  | "UseNEONForFPMovs", "true", | 
|  | "Convert VMOVSR, VMOVRS, " | 
|  | "VMOVS to NEON">; | 
|  |  | 
|  | // Some processors benefit from using NEON instructions for scalar | 
|  | // single-precision FP operations. This affects instruction selection and should | 
|  | // only be enabled if the handling of denormals is not important. | 
|  | // Use the method useNEONForSinglePrecisionFP() to determine if NEON should actually be used. | 
|  | def FeatureNEONForFP      : SubtargetFeature<"neonfp", | 
|  | "HasNEONForFP", | 
|  | "true", | 
|  | "Use NEON for single precision FP">; | 
|  |  | 
|  | // On some processors, VLDn instructions that access unaligned data take one | 
|  | // extra cycle. Take that into account when computing operand latencies. | 
|  | // True if VLDn instructions take an extra cycle for unaligned accesses. | 
|  | def FeatureCheckVLDnAlign : SubtargetFeature<"vldn-align", "CheckVLDnAccessAlignment", | 
|  | "true", | 
|  | "Check for VLDn unaligned access">; | 
|  |  | 
|  | // Some processors have a nonpipelined VFP coprocessor. | 
|  | // True if VFP instructions are not pipelined. | 
|  | def FeatureNonpipelinedVFP : SubtargetFeature<"nonpipelined-vfp", | 
|  | "NonpipelinedVFP", "true", | 
|  | "VFP instructions are not pipelined">; | 
|  |  | 
|  | // Some processors have FP multiply-accumulate instructions that don't | 
|  | // play nicely with other VFP / NEON instructions, and it's generally better | 
|  | // to just not use them. | 
|  | // If the VFP2 / NEON instructions are available, indicates | 
|  | // whether the FP VML[AS] instructions are slow (if so, don't use them). | 
|  | def FeatureHasSlowFPVMLx  : SubtargetFeature<"slowfpvmlx", "SlowFPVMLx", "true", | 
|  | "Disable VFP / NEON MAC instructions">; | 
|  |  | 
|  | // VFPv4 added VFMA instructions that can similarly be fast or slow. | 
|  | // If the VFP4 / NEON instructions are available, indicates | 
|  | // whether the FP VFM[AS] instructions are slow (if so, don't use them). | 
|  | def FeatureHasSlowFPVFMx  : SubtargetFeature<"slowfpvfmx", "SlowFPVFMx", "true", | 
|  | "Disable VFP / NEON FMA instructions">; | 
|  |  | 
|  | // Cortex-A8 / A9 Advanced SIMD has multiplier accumulator forwarding. | 
|  | /// True if NEON has special multiplier accumulator | 
|  | /// forwarding to allow mul + mla being issued back to back. | 
|  | def FeatureVMLxForwarding : SubtargetFeature<"vmlx-forwarding", | 
|  | "HasVMLxForwarding", "true", | 
|  | "Has multiplier accumulator forwarding">; | 
|  |  | 
|  | // Disable 32-bit to 16-bit narrowing for experimentation. | 
|  | // True if codegen would prefer 32-bit Thumb instructions over 16-bit ones. | 
|  | def FeaturePref32BitThumb : SubtargetFeature<"32bit", "Prefers32BitThumb", "true", | 
|  | "Prefer 32-bit Thumb instrs">; | 
|  |  | 
|  | def FeaturePreferBranchAlign32 : SubtargetFeature<"loop-align", "PreferBranchLogAlignment","2", | 
|  | "Prefer 32-bit alignment for branch targets">; | 
|  |  | 
|  | def FeaturePreferBranchAlign64 : SubtargetFeature<"branch-align-64", "PreferBranchLogAlignment","3", | 
|  | "Prefer 64-bit alignment for branch targets">; | 
|  |  | 
|  | def FeatureMVEVectorCostFactor1 : SubtargetFeature<"mve1beat", "MVEVectorCostFactor", "4", | 
|  | "Model MVE instructions as a 1 beat per tick architecture">; | 
|  |  | 
|  | def FeatureMVEVectorCostFactor2 : SubtargetFeature<"mve2beat", "MVEVectorCostFactor", "2", | 
|  | "Model MVE instructions as a 2 beats per tick architecture">; | 
|  |  | 
|  | def FeatureMVEVectorCostFactor4 : SubtargetFeature<"mve4beat", "MVEVectorCostFactor", "1", | 
|  | "Model MVE instructions as a 4 beats per tick architecture">; | 
|  |  | 
|  | /// Some instructions update CPSR partially, which can add false dependency for | 
|  | /// out-of-order implementation, e.g. Cortex-A9, unless each individual bit is | 
|  | /// mapped to a separate physical register. Avoid partial CPSR update for these | 
|  | /// processors. | 
|  | /// True if codegen would avoid using instructions | 
|  | /// that partially update CPSR and add false dependency on the previous | 
|  | /// CPSR setting instruction. | 
|  | def FeatureAvoidPartialCPSR : SubtargetFeature<"avoid-partial-cpsr", | 
|  | "AvoidCPSRPartialUpdate", "true", | 
|  | "Avoid CPSR partial update for OOO execution">; | 
|  |  | 
|  | /// FeatureAvoidMULS - If true, codegen would avoid using the MULS instruction, | 
|  | /// prefering the thumb2 MUL which doesn't set flags. | 
|  | def FeatureAvoidMULS : SubtargetFeature<"avoid-muls", | 
|  | "AvoidMULS", "true", | 
|  | "Avoid MULS instructions for M class cores">; | 
|  |  | 
|  |  | 
|  | /// Disable +1 predication cost for instructions updating CPSR. | 
|  | /// Enabled for Cortex-A57. | 
|  | /// True if disable +1 predication cost for instructions updating CPSR. Enabled for Cortex-A57. | 
|  | def FeatureCheapPredicableCPSR : SubtargetFeature<"cheap-predicable-cpsr", | 
|  | "CheapPredicableCPSRDef", | 
|  | "true", | 
|  | "Disable +1 predication cost for instructions updating CPSR">; | 
|  |  | 
|  | // True if codegen should avoid using flag setting movs with shifter operand (i.e. asr, lsl, lsr). | 
|  | def FeatureAvoidMOVsShOp  : SubtargetFeature<"avoid-movs-shop", | 
|  | "AvoidMOVsShifterOperand", "true", | 
|  | "Avoid movs instructions with " | 
|  | "shifter operand">; | 
|  |  | 
|  | // Some processors perform return stack prediction. CodeGen should avoid issue | 
|  | // "normal" call instructions to callees which do not return. | 
|  | def FeatureHasRetAddrStack : SubtargetFeature<"ret-addr-stack", | 
|  | "HasRetAddrStack", "true", | 
|  | "Has return address stack">; | 
|  |  | 
|  | // Some processors have no branch predictor, which changes the expected cost of | 
|  | // taking a branch which affects the choice of whether to use predicated | 
|  | // instructions. | 
|  | // True if the subtarget has a branch predictor. Having | 
|  | // a branch predictor or not changes the expected cost of taking a branch | 
|  | // which affects the choice of whether to use predicated instructions. | 
|  | def FeatureHasNoBranchPredictor : SubtargetFeature<"no-branch-predictor", | 
|  | "HasBranchPredictor", "false", | 
|  | "Has no branch predictor">; | 
|  |  | 
|  | /// DSP extension. | 
|  | /// True if the subtarget supports the DSP (saturating arith and such) instructions. | 
|  | def FeatureDSP            : SubtargetFeature<"dsp", "HasDSP", "true", | 
|  | "Supports DSP instructions in " | 
|  | "ARM and/or Thumb2">; | 
|  |  | 
|  | // True if the subtarget supports Multiprocessing extension (ARMv7 only). | 
|  | def FeatureMP             : SubtargetFeature<"mp", "HasMPExtension", "true", | 
|  | "Supports Multiprocessing extension">; | 
|  |  | 
|  | // Virtualization extension - requires HW divide (ARMv7-AR ARMARM - 4.4.8). | 
|  | def FeatureVirtualization : SubtargetFeature<"virtualization", | 
|  | "HasVirtualization", "true", | 
|  | "Supports Virtualization extension", | 
|  | [FeatureHWDivThumb, FeatureHWDivARM]>; | 
|  |  | 
|  | // True if the subtarget disallows unaligned memory | 
|  | // accesses for some types.  For details, see | 
|  | // ARMTargetLowering::allowsMisalignedMemoryAccesses(). | 
|  | def FeatureStrictAlign    : SubtargetFeature<"strict-align", | 
|  | "StrictAlign", "true", | 
|  | "Disallow all unaligned memory " | 
|  | "access">; | 
|  |  | 
|  | // Generate calls via indirect call instructions. | 
|  | def FeatureLongCalls      : SubtargetFeature<"long-calls", "GenLongCalls", "true", | 
|  | "Generate calls via indirect call " | 
|  | "instructions">; | 
|  |  | 
|  | // Generate code that does not contain data access to code sections. | 
|  | def FeatureExecuteOnly    : SubtargetFeature<"execute-only", | 
|  | "GenExecuteOnly", "true", | 
|  | "Enable the generation of " | 
|  | "execute only code.">; | 
|  |  | 
|  | // True if R9 is not available as a general purpose register. | 
|  | def FeatureReserveR9      : SubtargetFeature<"reserve-r9", "ReserveR9", "true", | 
|  | "Reserve R9, making it unavailable" | 
|  | " as GPR">; | 
|  |  | 
|  | // True if MOVT / MOVW pairs are not used for materialization of | 
|  | // 32-bit imms (including global addresses). | 
|  | def FeatureNoMovt         : SubtargetFeature<"no-movt", "NoMovt", "true", | 
|  | "Don't use movt/movw pairs for " | 
|  | "32-bit imms">; | 
|  |  | 
|  | /// Implicitly convert an instruction to a different one if its immediates | 
|  | /// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1. | 
|  | def FeatureNoNegativeImmediates | 
|  | : SubtargetFeature<"no-neg-immediates", | 
|  | "NegativeImmediates", "false", | 
|  | "Convert immediates and instructions " | 
|  | "to their negated or complemented " | 
|  | "equivalent when the immediate does " | 
|  | "not fit in the encoding.">; | 
|  |  | 
|  | // Use the MachineScheduler for instruction scheduling for the subtarget. | 
|  | def FeatureUseMISched: SubtargetFeature<"use-misched", "UseMISched", "true", | 
|  | "Use the MachineScheduler">; | 
|  |  | 
|  | // Use the MachinePipeliner for instruction scheduling for the subtarget. | 
|  | def FeatureUseMIPipeliner: SubtargetFeature<"use-mipipeliner", "UseMIPipeliner", "true", | 
|  | "Use the MachinePipeliner">; | 
|  |  | 
|  | // False if scheduling should happen again after register allocation. | 
|  | def FeatureNoPostRASched : SubtargetFeature<"disable-postra-scheduler", | 
|  | "DisablePostRAScheduler", "true", | 
|  | "Don't schedule again after register allocation">; | 
|  |  | 
|  | // Armv8.5-A extensions | 
|  |  | 
|  | // Has speculation barrier. | 
|  | def FeatureSB       : SubtargetFeature<"sb", "HasSB", "true", | 
|  | "Enable v8.5a Speculation Barrier" >; | 
|  |  | 
|  | // Armv8.6-A extensions | 
|  |  | 
|  | // True if subtarget supports BFloat16 floating point operations. | 
|  | def FeatureBF16     : SubtargetFeature<"bf16", "HasBF16", "true", | 
|  | "Enable support for BFloat16 instructions",  [FeatureNEON]>; | 
|  |  | 
|  | // True if subtarget supports 8-bit integer matrix multiply. | 
|  | def FeatureMatMulInt8 : SubtargetFeature<"i8mm", "HasMatMulInt8", | 
|  | "true", "Enable Matrix Multiply Int8 Extension", [FeatureNEON]>; | 
|  |  | 
|  | // Armv8.1-M extensions | 
|  |  | 
|  | // True if the processor supports the Low Overhead Branch extension. | 
|  | def FeatureLOB            : SubtargetFeature<"lob", "HasLOB", "true", | 
|  | "Enable Low Overhead Branch " | 
|  | "extensions">; | 
|  |  | 
|  | // Mitigate against the cve-2021-35465 security vulnurability. | 
|  | def FeatureFixCMSE_CVE_2021_35465 : SubtargetFeature<"fix-cmse-cve-2021-35465", | 
|  | "FixCMSE_CVE_2021_35465", "true", | 
|  | "Mitigate against the cve-2021-35465 " | 
|  | "security vulnurability">; | 
|  |  | 
|  | def FeaturePACBTI         : SubtargetFeature<"pacbti", "HasPACBTI", "true", | 
|  | "Enable Pointer Authentication and Branch " | 
|  | "Target Identification">; | 
|  |  | 
|  | /// Don't place a BTI instruction after return-twice constructs (setjmp). | 
|  | def FeatureNoBTIAtReturnTwice : SubtargetFeature<"no-bti-at-return-twice", | 
|  | "NoBTIAtReturnTwice", "true", | 
|  | "Don't place a BTI instruction " | 
|  | "after a return-twice">; | 
|  |  | 
|  | // Armv8.9-A/Armv9.4-A 2022 Architecture Extensions | 
|  | def FeatureCLRBHB : SubtargetFeature<"clrbhb", "HasCLRBHB", "true", | 
|  | "Enable Clear BHB instruction">; | 
|  |  | 
|  |  | 
|  | def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098", | 
|  | "FixCortexA57AES1742098", "true", | 
|  | "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">; | 
|  |  | 
|  | // If frame pointers are in use, they must follow the AAPCS definition, which | 
|  | // always uses R11 as the frame pointer. If this is not set, we can use R7 as | 
|  | // the frame pointer for Thumb1-only code, which is more efficient, but less | 
|  | // compatible. Note that this feature does not control whether frame pointers | 
|  | // are emitted, that is controlled by the "frame-pointer" function attribute. | 
|  | def FeatureAAPCSFrameChain : SubtargetFeature<"aapcs-frame-chain", | 
|  | "CreateAAPCSFrameChain", "true", | 
|  | "Create an AAPCS compliant frame chain">; | 
|  |  | 
|  | // Assume that lock-free 32-bit atomics are available, even if the target | 
|  | // and operating system combination would not usually provide them. The user | 
|  | // is responsible for providing any necessary __sync implementations. Code | 
|  | // built with this feature is not ABI-compatible with code built without this | 
|  | // feature, if atomic variables are exposed across the ABI boundary. | 
|  | def FeatureAtomics32 : SubtargetFeature< | 
|  | "atomics-32", "HasForced32BitAtomics", "true", | 
|  | "Assume that lock-free 32-bit atomics are available">; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // ARM architecture class | 
|  | // | 
|  |  | 
|  | // A-series ISA | 
|  | def FeatureAClass : SubtargetFeature<"aclass", "ARMProcClass", "AClass", | 
|  | "Is application profile ('A' series)">; | 
|  |  | 
|  | // R-series ISA | 
|  | def FeatureRClass : SubtargetFeature<"rclass", "ARMProcClass", "RClass", | 
|  | "Is realtime profile ('R' series)">; | 
|  |  | 
|  | // M-series ISA | 
|  | def FeatureMClass : SubtargetFeature<"mclass", "ARMProcClass", "MClass", | 
|  | "Is microcontroller profile ('M' series)">; | 
|  |  | 
|  | // True if Thumb2 instructions are supported. | 
|  | def FeatureThumb2 : SubtargetFeature<"thumb2", "HasThumb2", "true", | 
|  | "Enable Thumb2 instructions">; | 
|  |  | 
|  | // True if subtarget does not support ARM mode execution. | 
|  | def FeatureNoARM  : SubtargetFeature<"noarm", "NoARM", "true", | 
|  | "Does not support ARM mode execution">; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // ARM ISAa. | 
|  | // | 
|  | // Specify whether target support specific ARM ISA variants. | 
|  |  | 
|  | def HasV4TOps   : SubtargetFeature<"v4t", "HasV4TOps", "true", | 
|  | "Support ARM v4T instructions">; | 
|  |  | 
|  | def HasV5TOps   : SubtargetFeature<"v5t", "HasV5TOps", "true", | 
|  | "Support ARM v5T instructions", | 
|  | [HasV4TOps]>; | 
|  |  | 
|  | def HasV5TEOps  : SubtargetFeature<"v5te", "HasV5TEOps", "true", | 
|  | "Support ARM v5TE, v5TEj, and " | 
|  | "v5TExp instructions", | 
|  | [HasV5TOps]>; | 
|  |  | 
|  | def HasV6Ops    : SubtargetFeature<"v6", "HasV6Ops", "true", | 
|  | "Support ARM v6 instructions", | 
|  | [HasV5TEOps]>; | 
|  |  | 
|  | def HasV6MOps   : SubtargetFeature<"v6m", "HasV6MOps", "true", | 
|  | "Support ARM v6M instructions", | 
|  | [HasV6Ops]>; | 
|  |  | 
|  | def HasV8MBaselineOps : SubtargetFeature<"v8m", "HasV8MBaselineOps", "true", | 
|  | "Support ARM v8M Baseline instructions", | 
|  | [HasV6MOps]>; | 
|  |  | 
|  | def HasV6KOps   : SubtargetFeature<"v6k", "HasV6KOps", "true", | 
|  | "Support ARM v6k instructions", | 
|  | [HasV6Ops]>; | 
|  |  | 
|  | def HasV6T2Ops  : SubtargetFeature<"v6t2", "HasV6T2Ops", "true", | 
|  | "Support ARM v6t2 instructions", | 
|  | [HasV8MBaselineOps, HasV6KOps, FeatureThumb2]>; | 
|  |  | 
|  | def HasV7Ops    : SubtargetFeature<"v7", "HasV7Ops", "true", | 
|  | "Support ARM v7 instructions", | 
|  | [HasV6T2Ops, FeatureV7Clrex]>; | 
|  |  | 
|  | def HasV8MMainlineOps : | 
|  | SubtargetFeature<"v8m.main", "HasV8MMainlineOps", "true", | 
|  | "Support ARM v8M Mainline instructions", | 
|  | [HasV7Ops]>; | 
|  |  | 
|  | def HasV8Ops    : SubtargetFeature<"v8", "HasV8Ops", "true", | 
|  | "Support ARM v8 instructions", | 
|  | [HasV7Ops, FeaturePerfMon, FeatureAcquireRelease]>; | 
|  |  | 
|  | def HasV8_1aOps : SubtargetFeature<"v8.1a", "HasV8_1aOps", "true", | 
|  | "Support ARM v8.1a instructions", | 
|  | [HasV8Ops]>; | 
|  |  | 
|  | def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true", | 
|  | "Support ARM v8.2a instructions", | 
|  | [HasV8_1aOps]>; | 
|  |  | 
|  | def HasV8_3aOps   : SubtargetFeature<"v8.3a", "HasV8_3aOps", "true", | 
|  | "Support ARM v8.3a instructions", | 
|  | [HasV8_2aOps]>; | 
|  |  | 
|  | def HasV8_4aOps   : SubtargetFeature<"v8.4a", "HasV8_4aOps", "true", | 
|  | "Support ARM v8.4a instructions", | 
|  | [HasV8_3aOps, FeatureDotProd]>; | 
|  |  | 
|  | def HasV8_5aOps   : SubtargetFeature<"v8.5a", "HasV8_5aOps", "true", | 
|  | "Support ARM v8.5a instructions", | 
|  | [HasV8_4aOps, FeatureSB]>; | 
|  |  | 
|  | def HasV8_6aOps   : SubtargetFeature<"v8.6a", "HasV8_6aOps", "true", | 
|  | "Support ARM v8.6a instructions", | 
|  | [HasV8_5aOps, FeatureBF16, | 
|  | FeatureMatMulInt8]>; | 
|  |  | 
|  | def HasV8_7aOps   : SubtargetFeature<"v8.7a", "HasV8_7aOps", "true", | 
|  | "Support ARM v8.7a instructions", | 
|  | [HasV8_6aOps]>; | 
|  |  | 
|  | def HasV8_8aOps   : SubtargetFeature<"v8.8a", "HasV8_8aOps", "true", | 
|  | "Support ARM v8.8a instructions", | 
|  | [HasV8_7aOps]>; | 
|  |  | 
|  | def HasV8_9aOps   : SubtargetFeature<"v8.9a", "HasV8_9aOps", "true", | 
|  | "Support ARM v8.9a instructions", | 
|  | [HasV8_8aOps, FeatureCLRBHB]>; | 
|  |  | 
|  | def HasV9_0aOps   : SubtargetFeature<"v9a", "HasV9_0aOps", "true", | 
|  | "Support ARM v9a instructions", | 
|  | [HasV8_5aOps]>; | 
|  |  | 
|  | def HasV9_1aOps   : SubtargetFeature<"v9.1a", "HasV9_1aOps", "true", | 
|  | "Support ARM v9.1a instructions", | 
|  | [HasV8_6aOps, HasV9_0aOps]>; | 
|  |  | 
|  | def HasV9_2aOps   : SubtargetFeature<"v9.2a", "HasV9_2aOps", "true", | 
|  | "Support ARM v9.2a instructions", | 
|  | [HasV8_7aOps, HasV9_1aOps]>; | 
|  |  | 
|  | def HasV9_3aOps   : SubtargetFeature<"v9.3a", "HasV9_3aOps", "true", | 
|  | "Support ARM v9.3a instructions", | 
|  | [HasV8_8aOps, HasV9_2aOps]>; | 
|  |  | 
|  | def HasV9_4aOps   : SubtargetFeature<"v9.4a", "HasV9_4aOps", "true", | 
|  | "Support ARM v9.4a instructions", | 
|  | [HasV8_9aOps, HasV9_3aOps]>; | 
|  |  | 
|  | // Armv9.5-A is a v9-only architecture. From v9.5-A onwards there's no mapping | 
|  | // to an equivalent v8.x version. | 
|  | def HasV9_5aOps   : SubtargetFeature<"v9.5a", "HasV9_5aOps", "true", | 
|  | "Support ARM v9.5a instructions", | 
|  | [HasV9_4aOps]>; | 
|  |  | 
|  | // Armv9.6-A is a v9-only architecture. | 
|  | def HasV9_6aOps   : SubtargetFeature<"v9.6a", "HasV9_6aOps", "true", | 
|  | "Support ARM v9.6a instructions", | 
|  | [HasV9_5aOps]>; | 
|  |  | 
|  | // Armv9.7-A is a v9-only architecture. | 
|  | def HasV9_7aOps   : SubtargetFeature<"v9.7a", "HasV9_7aOps", "true", | 
|  | "Support ARM v9.7a instructions", | 
|  | [HasV9_6aOps]>; | 
|  |  | 
|  | def HasV8_1MMainlineOps : SubtargetFeature< | 
|  | "v8.1m.main", "HasV8_1MMainlineOps", "true", | 
|  | "Support ARM v8-1M Mainline instructions", | 
|  | [HasV8MMainlineOps]>; | 
|  | def HasMVEIntegerOps : SubtargetFeature< | 
|  | "mve", "HasMVEIntegerOps", "true", | 
|  | "Support M-Class Vector Extension with integer ops", | 
|  | [HasV8_1MMainlineOps, FeatureDSP, FeatureFPRegs16, FeatureFPRegs64]>; | 
|  | def HasMVEFloatOps : SubtargetFeature< | 
|  | "mve.fp", "HasMVEFloatOps", "true", | 
|  | "Support M-Class Vector Extension with integer and floating ops", | 
|  | [HasMVEIntegerOps, FeatureFPARMv8_D16_SP, FeatureFullFP16]>; | 
|  |  | 
|  | def HasCDEOps : SubtargetFeature<"cde", "HasCDEOps", "true", | 
|  | "Support CDE instructions", | 
|  | [HasV8MMainlineOps]>; | 
|  |  | 
|  | foreach i = {0-7} in | 
|  | def FeatureCoprocCDE#i : SubtargetFeature<"cdecp"#i, | 
|  | "CoprocCDE["#i#"]", "true", | 
|  | "Coprocessor "#i#" ISA is CDEv1", | 
|  | [HasCDEOps]>; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Control codegen mitigation against Straight Line Speculation vulnerability. | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | /// Harden against Straight Line Speculation for Returns and Indirect Branches. | 
|  | def FeatureHardenSlsRetBr : SubtargetFeature<"harden-sls-retbr", | 
|  | "HardenSlsRetBr", "true", | 
|  | "Harden against straight line speculation across RETurn and BranchRegister " | 
|  | "instructions">; | 
|  | /// Harden against Straight Line Speculation for indirect calls. | 
|  | def FeatureHardenSlsBlr : SubtargetFeature<"harden-sls-blr", | 
|  | "HardenSlsBlr", "true", | 
|  | "Harden against straight line speculation across indirect calls">; | 
|  | /// Generate thunk code for SLS mitigation in the normal text section. | 
|  | def FeatureHardenSlsNoComdat : SubtargetFeature<"harden-sls-nocomdat", | 
|  | "HardenSlsNoComdat", "true", | 
|  | "Generate thunk code for SLS mitigation in the normal text section">; | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Endianness of instruction encodings in memory. | 
|  | // | 
|  | // In the current Arm architecture, this is usually little-endian regardless of | 
|  | // data endianness. But before Armv7 it was typical for instruction endianness | 
|  | // to match data endianness, so that a big-endian system was consistently big- | 
|  | // endian. And Armv7-R can be configured to use big-endian instructions. | 
|  | // | 
|  | // Additionally, even when targeting Armv7-A, big-endian instructions can be | 
|  | // found in relocatable object files, because the Arm ABI specifies that the | 
|  | // linker byte-reverses them depending on the target architecture. | 
|  | // | 
|  | // So we have a feature here to indicate that instructions are stored big- | 
|  | // endian, which you can set when instantiating an MCDisassembler. | 
|  | def ModeBigEndianInstructions : SubtargetFeature<"big-endian-instructions", | 
|  | "BigEndianInstructions", "true", | 
|  | "Expect instructions to be stored big-endian.">; | 
|  |  |