ART: Add support for "silvermont" variant
The variant is already supported in the build system and wired up
for the Nexus Player (fugu). The values are copied from the build
system and correspond to documentation in, e.g.,
http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
chapter 15, section 1.1.
Change-Id: I9facaa9d5b8bae3d98cf48f2969d02d11ebfe0e4
diff --git a/runtime/arch/instruction_set_features.cc b/runtime/arch/instruction_set_features.cc
index db4b0b1..898f83a 100644
--- a/runtime/arch/instruction_set_features.cc
+++ b/runtime/arch/instruction_set_features.cc
@@ -288,10 +288,10 @@
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 e4513ef..d10ae21 100644
--- a/runtime/arch/instruction_set_features.h
+++ b/runtime/arch/instruction_set_features.h
@@ -103,7 +103,7 @@
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 a12773d..4e58d5e 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 d231beb..25a406b 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 @@
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