summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/arch/instruction_set_features.cc6
-rw-r--r--runtime/arch/instruction_set_features.h2
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.cc35
-rw-r--r--runtime/arch/x86/instruction_set_features_x86_test.cc36
4 files changed, 69 insertions, 10 deletions
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index db4b0b14ce..898f83a8d8 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -288,10 +288,10 @@ const X86_64InstructionSetFeatures* InstructionSetFeatures::AsX86_64InstructionS
return down_cast<const X86_64InstructionSetFeatures*>(this);
}
-bool InstructionSetFeatures::FindVariantInArray(const char* variants[], size_t num_variants,
+bool InstructionSetFeatures::FindVariantInArray(const char* const variants[], size_t num_variants,
const std::string& variant) {
- const char** begin = variants;
- const char** end = begin + num_variants;
+ const char* const * begin = variants;
+ const char* const * end = begin + num_variants;
return std::find(begin, end, variant) != end;
}
diff --git a/runtime/arch/instruction_set_features.h b/runtime/arch/instruction_set_features.h
index e4513ef272..d10ae21ae3 100644
--- a/runtime/arch/instruction_set_features.h
+++ b/runtime/arch/instruction_set_features.h
@@ -103,7 +103,7 @@ class InstructionSetFeatures {
explicit InstructionSetFeatures(bool smp) : smp_(smp) {}
// Returns true if variant appears in the array variants.
- static bool FindVariantInArray(const char* variants[], size_t num_variants,
+ static bool FindVariantInArray(const char* const variants[], size_t num_variants,
const std::string& variant);
// Add architecture specific features in sub-classes.
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index a12773dc9c..4e58d5e4ea 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -25,20 +25,43 @@
namespace art {
+// Feature-support arrays.
+
+static constexpr const char* x86_known_variants[] = {
+ "atom",
+ "silvermont",
+};
+
+static constexpr const char* x86_variants_with_ssse3[] = {
+ "atom",
+ "silvermont",
+};
+
+static constexpr const char* x86_variants_with_sse4_1[] = {
+ "silvermont",
+};
+
+static constexpr const char* x86_variants_with_sse4_2[] = {
+ "silvermont",
+};
+
const X86InstructionSetFeatures* X86InstructionSetFeatures::FromVariant(
const std::string& variant ATTRIBUTE_UNUSED, std::string* error_msg ATTRIBUTE_UNUSED,
bool x86_64) {
- bool known_variant = false;
bool smp = true; // Conservative default.
- static const char* x86_variants_with_ssse3[] = {
- "atom"
- };
bool has_SSSE3 = FindVariantInArray(x86_variants_with_ssse3, arraysize(x86_variants_with_ssse3),
variant);
- bool has_SSE4_1 = false;
- bool has_SSE4_2 = false;
+ bool has_SSE4_1 = FindVariantInArray(x86_variants_with_sse4_1,
+ arraysize(x86_variants_with_sse4_1),
+ variant);
+ bool has_SSE4_2 = FindVariantInArray(x86_variants_with_sse4_2,
+ arraysize(x86_variants_with_sse4_2),
+ variant);
bool has_AVX = false;
bool has_AVX2 = false;
+
+ bool known_variant = FindVariantInArray(x86_known_variants, arraysize(x86_known_variants),
+ variant);
if (!known_variant && variant != "default") {
std::ostringstream os;
LOG(WARNING) << "Unexpected CPU variant for X86 using defaults: " << variant;
diff --git a/runtime/arch/x86/instruction_set_features_x86_test.cc b/runtime/arch/x86/instruction_set_features_x86_test.cc
index d231beb40d..25a406b25a 100644
--- a/runtime/arch/x86/instruction_set_features_x86_test.cc
+++ b/runtime/arch/x86/instruction_set_features_x86_test.cc
@@ -67,4 +67,40 @@ TEST(X86InstructionSetFeaturesTest, X86FeaturesFromAtomVariant) {
EXPECT_FALSE(x86_features->Equals(x86_default_features.get()));
}
+TEST(X86InstructionSetFeaturesTest, X86FeaturesFromSilvermontVariant) {
+ // Build features for a 32-bit x86 silvermont processor.
+ std::string error_msg;
+ std::unique_ptr<const InstructionSetFeatures> x86_features(
+ InstructionSetFeatures::FromVariant(kX86, "silvermont", &error_msg));
+ ASSERT_TRUE(x86_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_features->GetInstructionSet(), kX86);
+ EXPECT_TRUE(x86_features->Equals(x86_features.get()));
+ EXPECT_STREQ("smp,ssse3,sse4.1,sse4.2,-avx,-avx2", x86_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_features->AsBitmap(), 15U);
+
+ // Build features for a 32-bit x86 default processor.
+ std::unique_ptr<const InstructionSetFeatures> x86_default_features(
+ InstructionSetFeatures::FromVariant(kX86, "default", &error_msg));
+ ASSERT_TRUE(x86_default_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_default_features->GetInstructionSet(), kX86);
+ EXPECT_TRUE(x86_default_features->Equals(x86_default_features.get()));
+ EXPECT_STREQ("smp,-ssse3,-sse4.1,-sse4.2,-avx,-avx2",
+ x86_default_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_default_features->AsBitmap(), 1U);
+
+ // Build features for a 64-bit x86-64 silvermont processor.
+ std::unique_ptr<const InstructionSetFeatures> x86_64_features(
+ InstructionSetFeatures::FromVariant(kX86_64, "silvermont", &error_msg));
+ ASSERT_TRUE(x86_64_features.get() != nullptr) << error_msg;
+ EXPECT_EQ(x86_64_features->GetInstructionSet(), kX86_64);
+ EXPECT_TRUE(x86_64_features->Equals(x86_64_features.get()));
+ EXPECT_STREQ("smp,ssse3,sse4.1,sse4.2,-avx,-avx2",
+ x86_64_features->GetFeatureString().c_str());
+ EXPECT_EQ(x86_64_features->AsBitmap(), 15U);
+
+ EXPECT_FALSE(x86_64_features->Equals(x86_features.get()));
+ EXPECT_FALSE(x86_64_features->Equals(x86_default_features.get()));
+ EXPECT_FALSE(x86_features->Equals(x86_default_features.get()));
+}
+
} // namespace art