1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_ARCH_ARM64_INSTRUCTION_SET_FEATURES_ARM64_H_ 18 #define ART_RUNTIME_ARCH_ARM64_INSTRUCTION_SET_FEATURES_ARM64_H_ 19 20 #include "arch/instruction_set_features.h" 21 #include "base/macros.h" 22 23 namespace art HIDDEN { 24 25 // SVE is currently not enabled. 26 static constexpr bool kArm64AllowSVE = false; 27 28 class Arm64InstructionSetFeatures; 29 using Arm64FeaturesUniquePtr = std::unique_ptr<const Arm64InstructionSetFeatures>; 30 31 // Instruction set features relevant to the ARM64 architecture. 32 class Arm64InstructionSetFeatures final : public InstructionSetFeatures { 33 public: 34 // Process a CPU variant string like "krait" or "cortex-a15" and create InstructionSetFeatures. 35 static Arm64FeaturesUniquePtr FromVariant(const std::string& variant, std::string* error_msg); 36 37 // Parse a bitmap and create an InstructionSetFeatures. 38 static Arm64FeaturesUniquePtr FromBitmap(uint32_t bitmap); 39 40 // Turn C pre-processor #defines into the equivalent instruction set features. 41 static Arm64FeaturesUniquePtr FromCppDefines(); 42 43 // Process /proc/cpuinfo and use kRuntimeISA to produce InstructionSetFeatures. 44 static Arm64FeaturesUniquePtr FromCpuInfo(); 45 46 // Process the auxiliary vector AT_HWCAP entry and use kRuntimeISA to produce 47 // InstructionSetFeatures. 48 static Arm64FeaturesUniquePtr FromHwcap(); 49 50 // Use assembly tests of the current runtime (ie kRuntimeISA) to determine the 51 // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. 52 static Arm64FeaturesUniquePtr FromAssembly(); 53 54 // Use external cpu_features library. 55 static Arm64FeaturesUniquePtr FromCpuFeatures(); 56 57 // Return a new set of instruction set features, intersecting `this` features 58 // with hardware capabilities. 59 Arm64FeaturesUniquePtr IntersectWithHwcap() const; 60 61 bool Equals(const InstructionSetFeatures* other) const override; 62 63 // Note that newer CPUs do not have a53 erratum 835769 and 843419, 64 // so the two a53 fix features (fix_cortex_a53_835769 and fix_cortex_a53_843419) 65 // are not tested for HasAtLeast. 66 bool HasAtLeast(const InstructionSetFeatures* other) const override; 67 GetInstructionSet()68 InstructionSet GetInstructionSet() const override { 69 return InstructionSet::kArm64; 70 } 71 72 uint32_t AsBitmap() const override; 73 74 // Return a string of the form "a53" or "none". 75 std::string GetFeatureString() const override; 76 77 // Generate code addressing Cortex-A53 erratum 835769? NeedFixCortexA53_835769()78 bool NeedFixCortexA53_835769() const { 79 return fix_cortex_a53_835769_; 80 } 81 82 // Generate code addressing Cortex-A53 erratum 843419? NeedFixCortexA53_843419()83 bool NeedFixCortexA53_843419() const { 84 return fix_cortex_a53_843419_; 85 } 86 HasCRC()87 bool HasCRC() const { 88 return has_crc_; 89 } 90 HasLSE()91 bool HasLSE() const { 92 return has_lse_; 93 } 94 HasFP16()95 bool HasFP16() const { 96 return has_fp16_; 97 } 98 99 // Are Dot Product instructions (UDOT/SDOT) available? HasDotProd()100 bool HasDotProd() const { 101 return has_dotprod_; 102 } 103 HasSVE()104 bool HasSVE() const { 105 return kArm64AllowSVE && has_sve_; 106 } 107 GetSVEVectorLength()108 size_t GetSVEVectorLength() const { 109 // TODO: support SVE vector length detection. 110 return kArm64DefaultSVEVectorLength; 111 } 112 ~Arm64InstructionSetFeatures()113 virtual ~Arm64InstructionSetFeatures() {} 114 115 protected: 116 // Parse a vector of the form "a53" adding these to a new ArmInstructionSetFeatures. 117 std::unique_ptr<const InstructionSetFeatures> 118 AddFeaturesFromSplitString(const std::vector<std::string>& features, 119 std::string* error_msg) const override; 120 121 std::unique_ptr<const InstructionSetFeatures> 122 AddRuntimeDetectedFeatures(const InstructionSetFeatures *features) const override; 123 124 private: Arm64InstructionSetFeatures(bool needs_a53_835769_fix,bool needs_a53_843419_fix,bool has_crc,bool has_lse,bool has_fp16,bool has_dotprod,bool has_sve)125 Arm64InstructionSetFeatures(bool needs_a53_835769_fix, 126 bool needs_a53_843419_fix, 127 bool has_crc, 128 bool has_lse, 129 bool has_fp16, 130 bool has_dotprod, 131 bool has_sve) 132 : InstructionSetFeatures(), 133 fix_cortex_a53_835769_(needs_a53_835769_fix), 134 fix_cortex_a53_843419_(needs_a53_843419_fix), 135 has_crc_(has_crc), 136 has_lse_(has_lse), 137 has_fp16_(has_fp16), 138 has_dotprod_(has_dotprod), 139 has_sve_(has_sve) { 140 } 141 142 // Bitmap positions for encoding features as a bitmap. 143 enum { 144 kA53Bitfield = 1 << 0, 145 kCRCBitField = 1 << 1, 146 kLSEBitField = 1 << 2, 147 kFP16BitField = 1 << 3, 148 kDotProdBitField = 1 << 4, 149 kSVEBitField = 1 << 5, 150 }; 151 152 const bool fix_cortex_a53_835769_; 153 const bool fix_cortex_a53_843419_; 154 const bool has_crc_; // optional in ARMv8.0, mandatory in ARMv8.1. 155 const bool has_lse_; // ARMv8.1 Large System Extensions. 156 const bool has_fp16_; // ARMv8.2 FP16 extensions. 157 const bool has_dotprod_; // optional in ARMv8.2, mandatory in ARMv8.4. 158 const bool has_sve_; // optional in ARMv8.2. 159 160 DISALLOW_COPY_AND_ASSIGN(Arm64InstructionSetFeatures); 161 }; 162 163 } // namespace art 164 165 #endif // ART_RUNTIME_ARCH_ARM64_INSTRUCTION_SET_FEATURES_ARM64_H_ 166