diff options
author | 2020-09-16 23:26:52 +0000 | |
---|---|---|
committer | 2020-09-29 13:32:59 +0000 | |
commit | 9636062c4d4839bbb2fd979ee56b2f38d8615f1e (patch) | |
tree | 2562080e05eed8104de13707c092aacb3556d572 | |
parent | e2a9bb7175517c18ab0899ad54c730b272d9883c (diff) |
Integrate cpu_features external library
Test: art_runtime_tests --no_isolate "--gtest_filter=InstructionSetFeaturesTest.*"
Test: Run `InstructionSetFeaturesTest` on device (Pixel 3) with this
command:
atest --all-abi ArtGtestsTargetInstallApex -- \
--test-arg com.android.tradefed.testtype.GTest:native-test-flag:"--gtest_filter=*InstructionSetFeaturesTest*"
Bug: 128901000
Change-Id: I49375eff2a28444af941610b750b3316bf18c7a7
-rw-r--r-- | runtime/Android.bp | 3 | ||||
-rw-r--r-- | runtime/arch/arm/instruction_set_features_arm.cc | 22 | ||||
-rw-r--r-- | runtime/arch/arm/instruction_set_features_arm.h | 3 | ||||
-rw-r--r-- | runtime/arch/arm64/instruction_set_features_arm64.cc | 24 | ||||
-rw-r--r-- | runtime/arch/arm64/instruction_set_features_arm64.h | 3 | ||||
-rw-r--r-- | runtime/arch/instruction_set_features.cc | 19 | ||||
-rw-r--r-- | runtime/arch/instruction_set_features.h | 3 | ||||
-rw-r--r-- | runtime/arch/instruction_set_features_test.cc | 14 | ||||
-rw-r--r-- | runtime/arch/x86/instruction_set_features_x86.cc | 26 | ||||
-rw-r--r-- | runtime/arch/x86/instruction_set_features_x86.h | 3 | ||||
-rw-r--r-- | runtime/arch/x86_64/instruction_set_features_x86_64.h | 5 |
11 files changed, 125 insertions, 0 deletions
diff --git a/runtime/Android.bp b/runtime/Android.bp index f800726bff..2340cdb7e7 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -414,6 +414,9 @@ libart_cc_defaults { "jni_platform_headers", "libnativehelper_header_only", ], + whole_static_libs: [ + "libcpu_features", + ], shared_libs: [ "libartpalette", "libbacktrace", diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc index b01f5198d1..43c66f8596 100644 --- a/runtime/arch/arm/instruction_set_features_arm.cc +++ b/runtime/arch/arm/instruction_set_features_arm.cc @@ -29,6 +29,15 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include <cpu_features_macros.h> + +#ifdef CPU_FEATURES_ARCH_ARM +// This header can only be included on ARM targets, +// as determined by cpu_features own define. +#include <cpuinfo_arm.h> +#endif + + #if defined(__arm__) extern "C" bool artCheckForArmSdivInstruction(); extern "C" bool artCheckForArmv8AInstructions(); @@ -267,6 +276,19 @@ ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromAssembly() { has_armv8a)); } +ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromCpuFeatures() { +#ifdef CPU_FEATURES_ARCH_ARM + auto info = cpu_features::GetArmInfo(); + auto features = info.features; + return ArmFeaturesUniquePtr(new ArmInstructionSetFeatures(features.idiva, + features.lpae, + info.architecture == 8)); +#else + UNIMPLEMENTED(WARNING); + return FromCppDefines(); +#endif +} + bool ArmInstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { if (InstructionSet::kArm != other->GetInstructionSet()) { return false; diff --git a/runtime/arch/arm/instruction_set_features_arm.h b/runtime/arch/arm/instruction_set_features_arm.h index d964148900..613ed14ed9 100644 --- a/runtime/arch/arm/instruction_set_features_arm.h +++ b/runtime/arch/arm/instruction_set_features_arm.h @@ -47,6 +47,9 @@ class ArmInstructionSetFeatures final : public InstructionSetFeatures { // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. static ArmFeaturesUniquePtr FromAssembly(); + // Use external cpu_features library. + static ArmFeaturesUniquePtr FromCpuFeatures(); + bool Equals(const InstructionSetFeatures* other) const override; bool HasAtLeast(const InstructionSetFeatures* other) const override; diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc index 17369e82a6..1e779f5083 100644 --- a/runtime/arch/arm64/instruction_set_features_arm64.cc +++ b/runtime/arch/arm64/instruction_set_features_arm64.cc @@ -30,6 +30,14 @@ #include "base/stl_util.h" +#include <cpu_features_macros.h> + +#ifdef CPU_FEATURES_ARCH_AARCH64 +// This header can only be included on aarch64 targets, +// as determined by cpu_features own define. +#include <cpuinfo_aarch64.h> +#endif + namespace art { using android::base::StringPrintf; @@ -245,6 +253,22 @@ Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromAssembly() { return FromCppDefines(); } +Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromCpuFeatures() { +#ifdef CPU_FEATURES_ARCH_AARCH64 + auto features = cpu_features::GetAarch64Info().features; + return Arm64FeaturesUniquePtr(new Arm64InstructionSetFeatures(false, + false, + features.crc32, + features.atomics, + features.fphp, + features.asimddp, + features.sve)); +#else + UNIMPLEMENTED(WARNING); + return FromCppDefines(); +#endif +} + bool Arm64InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { if (InstructionSet::kArm64 != other->GetInstructionSet()) { return false; diff --git a/runtime/arch/arm64/instruction_set_features_arm64.h b/runtime/arch/arm64/instruction_set_features_arm64.h index d3c127a4fe..dd1c4948fa 100644 --- a/runtime/arch/arm64/instruction_set_features_arm64.h +++ b/runtime/arch/arm64/instruction_set_features_arm64.h @@ -47,6 +47,9 @@ class Arm64InstructionSetFeatures final : public InstructionSetFeatures { // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. static Arm64FeaturesUniquePtr FromAssembly(); + // Use external cpu_features library. + static Arm64FeaturesUniquePtr FromCpuFeatures(); + bool Equals(const InstructionSetFeatures* other) const override; // Note that newer CPUs do not have a53 erratum 835769 and 843419, diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc index 2581f6e6fb..ec1e340245 100644 --- a/runtime/arch/instruction_set_features.cc +++ b/runtime/arch/instruction_set_features.cc @@ -166,6 +166,25 @@ std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromAssemb UNREACHABLE(); } +std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::FromCpuFeatures() { + switch (kRuntimeISA) { + case InstructionSet::kArm: + case InstructionSet::kThumb2: + return ArmInstructionSetFeatures::FromCpuFeatures(); + case InstructionSet::kArm64: + return Arm64InstructionSetFeatures::FromCpuFeatures(); + case InstructionSet::kX86: + return X86InstructionSetFeatures::FromCpuFeatures(); + case InstructionSet::kX86_64: + return X86_64InstructionSetFeatures::FromCpuFeatures(); + + default: + break; + } + UNIMPLEMENTED(FATAL) << kRuntimeISA; + UNREACHABLE(); +} + std::unique_ptr<const InstructionSetFeatures> InstructionSetFeatures::AddFeaturesFromString( const std::string& feature_list, /* out */ std::string* error_msg) const { std::vector<std::string> features; diff --git a/runtime/arch/instruction_set_features.h b/runtime/arch/instruction_set_features.h index 78ce580ac2..b80d36f153 100644 --- a/runtime/arch/instruction_set_features.h +++ b/runtime/arch/instruction_set_features.h @@ -71,6 +71,9 @@ class InstructionSetFeatures { // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. static std::unique_ptr<const InstructionSetFeatures> FromAssembly(); + // Use external cpu_features library. + static std::unique_ptr<const InstructionSetFeatures> FromCpuFeatures(); + // Parse a string of the form "div,-atomic_ldrd_strd" adding and removing these features to // create a new InstructionSetFeatures. std::unique_ptr<const InstructionSetFeatures> AddFeaturesFromString( diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc index 62657cf724..82b8242cfe 100644 --- a/runtime/arch/instruction_set_features_test.cc +++ b/runtime/arch/instruction_set_features_test.cc @@ -176,6 +176,20 @@ TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) { << "\nFeatures from build: " << *instruction_set_features.get(); } +TEST(InstructionSetFeaturesTest, FeaturestFromCpuFeatures) { + // Take the default set of instruction features from the build. + std::unique_ptr<const InstructionSetFeatures> instruction_set_features( + InstructionSetFeatures::FromCppDefines()); + + // Check we get the same instruction set features using the cpu_features library + std::unique_ptr<const InstructionSetFeatures> library_features( + InstructionSetFeatures::FromCpuFeatures()); + + EXPECT_TRUE(library_features->HasAtLeast(instruction_set_features.get())) + << "Library features: " << *library_features.get() + << "\nFeatures from build: " << *instruction_set_features.get(); +} + TEST(InstructionSetFeaturesTest, FeaturesFromRuntimeDetection) { if (!InstructionSetFeatures::IsRuntimeDetectionSupported()) { EXPECT_EQ(InstructionSetFeatures::FromRuntimeDetection(), nullptr); diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc index 858c3201c4..d2dbe1dde3 100644 --- a/runtime/arch/x86/instruction_set_features_x86.cc +++ b/runtime/arch/x86/instruction_set_features_x86.cc @@ -25,6 +25,14 @@ #include "arch/x86_64/instruction_set_features_x86_64.h" +#include <cpu_features_macros.h> + +#ifdef CPU_FEATURES_ARCH_X86 +// This header can only be included on x86 targets, +// as determined by cpu_features own define. +#include <cpuinfo_x86.h> +#endif + namespace art { using android::base::StringPrintf; @@ -238,6 +246,24 @@ X86FeaturesUniquePtr X86InstructionSetFeatures::FromAssembly(bool x86_64) { return FromCppDefines(x86_64); } + +X86FeaturesUniquePtr X86InstructionSetFeatures::FromCpuFeatures(bool x86_64) { +#ifdef CPU_FEATURES_ARCH_X86 + cpu_features::X86Features features = cpu_features::GetX86Info().features; + return Create(x86_64, + features.ssse3, + features.sse4_1, + features.sse4_2, + features.avx, + features.avx2, + features.popcnt); +#else + UNIMPLEMENTED(WARNING); + return FromCppDefines(x86_64); +#endif +} + + bool X86InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const { if (GetInstructionSet() != other->GetInstructionSet()) { return false; diff --git a/runtime/arch/x86/instruction_set_features_x86.h b/runtime/arch/x86/instruction_set_features_x86.h index bf1b60640c..1a8ebb55b4 100644 --- a/runtime/arch/x86/instruction_set_features_x86.h +++ b/runtime/arch/x86/instruction_set_features_x86.h @@ -69,6 +69,9 @@ class X86InstructionSetFeatures : public InstructionSetFeatures { // InstructionSetFeatures. This works around kernel bugs in AT_HWCAP and /proc/cpuinfo. static X86FeaturesUniquePtr FromAssembly(bool x86_64 = false); + // Use external cpu_features library. + static X86FeaturesUniquePtr FromCpuFeatures(bool x86_64 = false); + bool Equals(const InstructionSetFeatures* other) const override; bool HasAtLeast(const InstructionSetFeatures* other) const override; diff --git a/runtime/arch/x86_64/instruction_set_features_x86_64.h b/runtime/arch/x86_64/instruction_set_features_x86_64.h index 76258fa5d4..9b90365c41 100644 --- a/runtime/arch/x86_64/instruction_set_features_x86_64.h +++ b/runtime/arch/x86_64/instruction_set_features_x86_64.h @@ -59,6 +59,11 @@ class X86_64InstructionSetFeatures final : public X86InstructionSetFeatures { return Convert(X86InstructionSetFeatures::FromAssembly(true)); } + // Use external cpu_features library. + static X86_64FeaturesUniquePtr FromCpuFeatures() { + return Convert(X86InstructionSetFeatures::FromCpuFeatures(true)); + } + InstructionSet GetInstructionSet() const override { return InstructionSet::kX86_64; } |