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 HAVE_ANDROID_OS
22 #include "cutils/properties.h"
23 #endif
24 
25 #include "base/stringprintf.h"
26 
27 namespace art {
28 
29 #ifdef HAVE_ANDROID_OS
30 #if defined(__aarch64__)
TEST(InstructionSetFeaturesTest,DISABLED_FeaturesFromSystemPropertyVariant)31 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) {
32   LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
33 #else
34 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) {
35 #endif
36   // Take the default set of instruction features from the build.
37   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
38       InstructionSetFeatures::FromCppDefines());
39 
40   // Read the variant property.
41   std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA));
42   char dex2oat_isa_variant[PROPERTY_VALUE_MAX];
43   if (property_get(key.c_str(), dex2oat_isa_variant, nullptr) > 0) {
44     // Use features from property to build InstructionSetFeatures and check against build's
45     // features.
46     std::string error_msg;
47     std::unique_ptr<const InstructionSetFeatures> property_features(
48         InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
49     ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
50 
51     EXPECT_TRUE(property_features->Equals(instruction_set_features.get()))
52       << "System property features: " << *property_features.get()
53       << "\nFeatures from build: " << *instruction_set_features.get();
54   }
55 }
56 
57 #if defined(__aarch64__)
58 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) {
59   LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
60 #else
61 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) {
62 #endif
63   // Take the default set of instruction features from the build.
64   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
65       InstructionSetFeatures::FromCppDefines());
66 
67   // Read the variant property.
68   std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant",
69                                          GetInstructionSetString(kRuntimeISA));
70   char dex2oat_isa_variant[PROPERTY_VALUE_MAX];
71   if (property_get(variant_key.c_str(), dex2oat_isa_variant, nullptr) > 0) {
72     // Read the features property.
73     std::string features_key = StringPrintf("dalvik.vm.isa.%s.features",
74                                             GetInstructionSetString(kRuntimeISA));
75     char dex2oat_isa_features[PROPERTY_VALUE_MAX];
76     if (property_get(features_key.c_str(), dex2oat_isa_features, nullptr) > 0) {
77       // Use features from property to build InstructionSetFeatures and check against build's
78       // features.
79       std::string error_msg;
80       std::unique_ptr<const InstructionSetFeatures> base_features(
81           InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
82       ASSERT_TRUE(base_features.get() != nullptr) << error_msg;
83 
84       std::unique_ptr<const InstructionSetFeatures> property_features(
85           base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg));
86       ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
87 
88       EXPECT_TRUE(property_features->Equals(instruction_set_features.get()))
89       << "System property features: " << *property_features.get()
90       << "\nFeatures from build: " << *instruction_set_features.get();
91     }
92   }
93 }
94 
95 #if defined(__arm__)
96 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromCpuInfo) {
97   LOG(WARNING) << "Test disabled due to buggy ARM kernels";
98 #else
99 TEST(InstructionSetFeaturesTest, FeaturesFromCpuInfo) {
100 #endif
101   // Take the default set of instruction features from the build.
102   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
103       InstructionSetFeatures::FromCppDefines());
104 
105   // Check we get the same instruction set features using /proc/cpuinfo.
106   std::unique_ptr<const InstructionSetFeatures> cpuinfo_features(
107       InstructionSetFeatures::FromCpuInfo());
108   EXPECT_TRUE(cpuinfo_features->Equals(instruction_set_features.get()))
109       << "CPU Info features: " << *cpuinfo_features.get()
110       << "\nFeatures from build: " << *instruction_set_features.get();
111 }
112 #endif
113 
114 #ifndef HAVE_ANDROID_OS
115 TEST(InstructionSetFeaturesTest, HostFeaturesFromCppDefines) {
116   std::string error_msg;
117   std::unique_ptr<const InstructionSetFeatures> default_features(
118       InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg));
119   ASSERT_TRUE(error_msg.empty());
120 
121   std::unique_ptr<const InstructionSetFeatures> cpp_features(
122       InstructionSetFeatures::FromCppDefines());
123   EXPECT_TRUE(default_features->Equals(cpp_features.get()))
124       << "Default variant features: " << *default_features.get()
125       << "\nFeatures from build: " << *cpp_features.get();
126 }
127 #endif
128 
129 #if defined(__arm__)
130 TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromHwcap) {
131   LOG(WARNING) << "Test disabled due to buggy ARM kernels";
132 #else
133 TEST(InstructionSetFeaturesTest, FeaturesFromHwcap) {
134 #endif
135   // Take the default set of instruction features from the build.
136   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
137       InstructionSetFeatures::FromCppDefines());
138 
139   // Check we get the same instruction set features using AT_HWCAP.
140   std::unique_ptr<const InstructionSetFeatures> hwcap_features(
141       InstructionSetFeatures::FromHwcap());
142   EXPECT_TRUE(hwcap_features->Equals(instruction_set_features.get()))
143       << "Hwcap features: " << *hwcap_features.get()
144       << "\nFeatures from build: " << *instruction_set_features.get();
145 }
146 
147 TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) {
148   // Take the default set of instruction features from the build.
149   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
150       InstructionSetFeatures::FromCppDefines());
151 
152   // Check we get the same instruction set features using assembly tests.
153   std::unique_ptr<const InstructionSetFeatures> assembly_features(
154       InstructionSetFeatures::FromAssembly());
155   EXPECT_TRUE(assembly_features->Equals(instruction_set_features.get()))
156       << "Assembly features: " << *assembly_features.get()
157       << "\nFeatures from build: " << *instruction_set_features.get();
158 }
159 
160 }  // namespace art
161