diff options
| -rw-r--r-- | runtime/arch/instruction_set_features.cc | 6 | ||||
| -rw-r--r-- | runtime/arch/instruction_set_features.h | 2 | ||||
| -rw-r--r-- | runtime/arch/x86/instruction_set_features_x86.cc | 35 | ||||
| -rw-r--r-- | runtime/arch/x86/instruction_set_features_x86_test.cc | 36 |
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 |