summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Daniil Riazanovskiy <riazanovskiy@google.com> 2020-09-16 23:26:52 +0000
committer Roland Levillain <rpl@google.com> 2020-09-29 13:32:59 +0000
commit9636062c4d4839bbb2fd979ee56b2f38d8615f1e (patch)
tree2562080e05eed8104de13707c092aacb3556d572
parente2a9bb7175517c18ab0899ad54c730b272d9883c (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.bp3
-rw-r--r--runtime/arch/arm/instruction_set_features_arm.cc22
-rw-r--r--runtime/arch/arm/instruction_set_features_arm.h3
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.cc24
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.h3
-rw-r--r--runtime/arch/instruction_set_features.cc19
-rw-r--r--runtime/arch/instruction_set_features.h3
-rw-r--r--runtime/arch/instruction_set_features_test.cc14
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.cc26
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.h3
-rw-r--r--runtime/arch/x86_64/instruction_set_features_x86_64.h5
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;
}