1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "instruction_set_features.h" 18 19 #include <gtest/gtest.h> 20 21 #ifdef ART_TARGET_ANDROID 22 #include "android-base/properties.h" 23 #endif 24 25 #include "android-base/stringprintf.h" 26 27 #include "base/logging.h" 28 29 namespace art { 30 31 using android::base::StringPrintf; 32 33 #ifdef ART_TARGET_ANDROID 34 #if defined(__aarch64__) 35 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) { 36 LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769"; 37 #else 38 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) { 39 #endif 40 // Take the default set of instruction features from the build. 41 std::unique_ptr<const InstructionSetFeatures> instruction_set_features( 42 InstructionSetFeatures::FromCppDefines()); 43 44 // Read the variant property. 45 std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA)); 46 std::string dex2oat_isa_variant = android::base::GetProperty(key, ""); 47 if (!dex2oat_isa_variant.empty()) { 48 // Use features from property to build InstructionSetFeatures and check against build's 49 // features. 50 std::string error_msg; 51 std::unique_ptr<const InstructionSetFeatures> property_features( 52 InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg)); 53 ASSERT_TRUE(property_features.get() != nullptr) << error_msg; 54 55 EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get())) 56 << "System property features: " << *property_features.get() 57 << "\nFeatures from build: " << *instruction_set_features.get(); 58 } 59 } 60 61 #if defined(__aarch64__) 62 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) { 63 LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769"; 64 #else 65 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) { 66 #endif 67 // Take the default set of instruction features from the build. 68 std::unique_ptr<const InstructionSetFeatures> instruction_set_features( 69 InstructionSetFeatures::FromCppDefines()); 70 71 // Read the variant property. 72 std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant", 73 GetInstructionSetString(kRuntimeISA)); 74 std::string dex2oat_isa_variant = android::base::GetProperty(variant_key, ""); 75 if (!dex2oat_isa_variant.empty()) { 76 // Read the features property. 77 std::string features_key = StringPrintf("dalvik.vm.isa.%s.features", 78 GetInstructionSetString(kRuntimeISA)); 79 std::string dex2oat_isa_features = android::base::GetProperty(features_key, ""); 80 if (!dex2oat_isa_features.empty()) { 81 // Use features from property to build InstructionSetFeatures and check against build's 82 // features. 83 std::string error_msg; 84 std::unique_ptr<const InstructionSetFeatures> base_features( 85 InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg)); 86 ASSERT_TRUE(base_features.get() != nullptr) << error_msg; 87 88 std::unique_ptr<const InstructionSetFeatures> property_features( 89 base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg)); 90 ASSERT_TRUE(property_features.get() != nullptr) << error_msg; 91 92 EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get())) 93 << "System property features: " << *property_features.get() 94 << "\nFeatures from build: " << *instruction_set_features.get(); 95 } 96 } 97 } 98 99 #if defined(__arm__) 100 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromCpuInfo) { 101 LOG(WARNING) << "Test disabled due to buggy ARM kernels"; 102 #else 103 TEST(InstructionSetFeaturesTest, FeaturesFromCpuInfo) { 104 #endif 105 // Take the default set of instruction features from the build. 106 std::unique_ptr<const InstructionSetFeatures> instruction_set_features( 107 InstructionSetFeatures::FromCppDefines()); 108 109 // Check we get the same instruction set features using /proc/cpuinfo. 110 std::unique_ptr<const InstructionSetFeatures> cpuinfo_features( 111 InstructionSetFeatures::FromCpuInfo()); 112 EXPECT_TRUE(cpuinfo_features->HasAtLeast(instruction_set_features.get())) 113 << "CPU Info features: " << *cpuinfo_features.get() 114 << "\nFeatures from build: " << *instruction_set_features.get(); 115 } 116 #endif 117 118 #ifndef ART_TARGET_ANDROID 119 TEST(InstructionSetFeaturesTest, HostFeaturesFromCppDefines) { 120 std::string error_msg; 121 std::unique_ptr<const InstructionSetFeatures> default_features( 122 InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg)); 123 ASSERT_TRUE(error_msg.empty()); 124 125 std::unique_ptr<const InstructionSetFeatures> cpp_features( 126 InstructionSetFeatures::FromCppDefines()); 127 EXPECT_TRUE(cpp_features->HasAtLeast(default_features.get())) 128 << "Default variant features: " << *default_features.get() 129 << "\nFeatures from build: " << *cpp_features.get(); 130 } 131 #endif 132 133 #if defined(__arm__) 134 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromHwcap) { 135 LOG(WARNING) << "Test disabled due to buggy ARM kernels"; 136 #else 137 TEST(InstructionSetFeaturesTest, FeaturesFromHwcap) { 138 #endif 139 // Take the default set of instruction features from the build. 140 std::unique_ptr<const InstructionSetFeatures> instruction_set_features( 141 InstructionSetFeatures::FromCppDefines()); 142 143 // Check we get the same instruction set features using AT_HWCAP. 144 std::unique_ptr<const InstructionSetFeatures> hwcap_features( 145 InstructionSetFeatures::FromHwcap()); 146 EXPECT_TRUE(hwcap_features->HasAtLeast(instruction_set_features.get())) 147 << "Hwcap features: " << *hwcap_features.get() 148 << "\nFeatures from build: " << *instruction_set_features.get(); 149 } 150 151 TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) { 152 // Take the default set of instruction features from the build. 153 std::unique_ptr<const InstructionSetFeatures> instruction_set_features( 154 InstructionSetFeatures::FromCppDefines()); 155 156 // Check we get the same instruction set features using assembly tests. 157 std::unique_ptr<const InstructionSetFeatures> assembly_features( 158 InstructionSetFeatures::FromAssembly()); 159 EXPECT_TRUE(assembly_features->HasAtLeast(instruction_set_features.get())) 160 << "Assembly features: " << *assembly_features.get() 161 << "\nFeatures from build: " << *instruction_set_features.get(); 162 } 163 164 } // namespace art 165