xref: /aosp_15_r20/art/runtime/arch/instruction_set_features_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include <array>
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
20*795d594fSAndroid Build Coastguard Worker #include "instruction_set_features.h"
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
25*795d594fSAndroid Build Coastguard Worker #include <android-base/properties.h>
26*795d594fSAndroid Build Coastguard Worker #endif
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
29*795d594fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker #if defined(__aarch64__)
TEST(InstructionSetFeaturesTest,DISABLED_FeaturesFromSystemPropertyVariant)38*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) {
39*795d594fSAndroid Build Coastguard Worker   LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
40*795d594fSAndroid Build Coastguard Worker #else
41*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) {
42*795d594fSAndroid Build Coastguard Worker #endif
43*795d594fSAndroid Build Coastguard Worker   if (kIsTargetBuild) {
44*795d594fSAndroid Build Coastguard Worker     // atest differs in build-time and run-time features.
45*795d594fSAndroid Build Coastguard Worker     TEST_DISABLED_FOR_X86();
46*795d594fSAndroid Build Coastguard Worker     TEST_DISABLED_FOR_X86_64();
47*795d594fSAndroid Build Coastguard Worker   }
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
50*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
51*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
52*795d594fSAndroid Build Coastguard Worker 
53*795d594fSAndroid Build Coastguard Worker   // Read the variant property.
54*795d594fSAndroid Build Coastguard Worker   std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA));
55*795d594fSAndroid Build Coastguard Worker   std::string dex2oat_isa_variant = android::base::GetProperty(key, "");
56*795d594fSAndroid Build Coastguard Worker   if (!dex2oat_isa_variant.empty()) {
57*795d594fSAndroid Build Coastguard Worker     // Use features from property to build InstructionSetFeatures and check against build's
58*795d594fSAndroid Build Coastguard Worker     // features.
59*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
60*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<const InstructionSetFeatures> property_features(
61*795d594fSAndroid Build Coastguard Worker         InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
62*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get()))
65*795d594fSAndroid Build Coastguard Worker       << "System property features: " << *property_features.get()
66*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
67*795d594fSAndroid Build Coastguard Worker   }
68*795d594fSAndroid Build Coastguard Worker }
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker #if defined(__aarch64__)
71*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) {
72*795d594fSAndroid Build Coastguard Worker   LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
73*795d594fSAndroid Build Coastguard Worker #else
74*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) {
75*795d594fSAndroid Build Coastguard Worker #endif
76*795d594fSAndroid Build Coastguard Worker   if (kIsTargetBuild) {
77*795d594fSAndroid Build Coastguard Worker     // atest differs in build-time and run-time features.
78*795d594fSAndroid Build Coastguard Worker     TEST_DISABLED_FOR_X86();
79*795d594fSAndroid Build Coastguard Worker     TEST_DISABLED_FOR_X86_64();
80*795d594fSAndroid Build Coastguard Worker   }
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
83*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
84*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker   // Read the variant property.
87*795d594fSAndroid Build Coastguard Worker   std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant",
88*795d594fSAndroid Build Coastguard Worker                                          GetInstructionSetString(kRuntimeISA));
89*795d594fSAndroid Build Coastguard Worker   std::string dex2oat_isa_variant = android::base::GetProperty(variant_key, "");
90*795d594fSAndroid Build Coastguard Worker   if (!dex2oat_isa_variant.empty()) {
91*795d594fSAndroid Build Coastguard Worker     // Read the features property.
92*795d594fSAndroid Build Coastguard Worker     std::string features_key = StringPrintf("dalvik.vm.isa.%s.features",
93*795d594fSAndroid Build Coastguard Worker                                             GetInstructionSetString(kRuntimeISA));
94*795d594fSAndroid Build Coastguard Worker     std::string dex2oat_isa_features = android::base::GetProperty(features_key, "");
95*795d594fSAndroid Build Coastguard Worker     if (!dex2oat_isa_features.empty()) {
96*795d594fSAndroid Build Coastguard Worker       // Use features from property to build InstructionSetFeatures and check against build's
97*795d594fSAndroid Build Coastguard Worker       // features.
98*795d594fSAndroid Build Coastguard Worker       std::string error_msg;
99*795d594fSAndroid Build Coastguard Worker       std::unique_ptr<const InstructionSetFeatures> base_features(
100*795d594fSAndroid Build Coastguard Worker           InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
101*795d594fSAndroid Build Coastguard Worker       ASSERT_TRUE(base_features.get() != nullptr) << error_msg;
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker       std::unique_ptr<const InstructionSetFeatures> property_features(
104*795d594fSAndroid Build Coastguard Worker           base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg));
105*795d594fSAndroid Build Coastguard Worker       ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker       EXPECT_TRUE(property_features->HasAtLeast(instruction_set_features.get()))
108*795d594fSAndroid Build Coastguard Worker       << "System property features: " << *property_features.get()
109*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
110*795d594fSAndroid Build Coastguard Worker     }
111*795d594fSAndroid Build Coastguard Worker   }
112*795d594fSAndroid Build Coastguard Worker }
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker #if defined(__arm__)
115*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromCpuInfo) {
116*795d594fSAndroid Build Coastguard Worker   LOG(WARNING) << "Test disabled due to buggy ARM kernels";
117*795d594fSAndroid Build Coastguard Worker #else
118*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromCpuInfo) {
119*795d594fSAndroid Build Coastguard Worker #endif
120*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
121*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
122*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   // Check we get the same instruction set features using /proc/cpuinfo.
125*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpuinfo_features(
126*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCpuInfo());
127*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(cpuinfo_features->HasAtLeast(instruction_set_features.get()))
128*795d594fSAndroid Build Coastguard Worker       << "CPU Info features: " << *cpuinfo_features.get()
129*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
130*795d594fSAndroid Build Coastguard Worker }
131*795d594fSAndroid Build Coastguard Worker #endif
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker #ifndef ART_TARGET_ANDROID
134*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, HostFeaturesFromCppDefines) {
135*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
136*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> default_features(
137*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg));
138*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(error_msg.empty());
139*795d594fSAndroid Build Coastguard Worker 
140*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_features(
141*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
142*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(cpp_features->HasAtLeast(default_features.get()))
143*795d594fSAndroid Build Coastguard Worker       << "Default variant features: " << *default_features.get()
144*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *cpp_features.get();
145*795d594fSAndroid Build Coastguard Worker }
146*795d594fSAndroid Build Coastguard Worker #endif
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker #if defined(__arm__)
149*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromHwcap) {
150*795d594fSAndroid Build Coastguard Worker   LOG(WARNING) << "Test disabled due to buggy ARM kernels";
151*795d594fSAndroid Build Coastguard Worker #else
152*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromHwcap) {
153*795d594fSAndroid Build Coastguard Worker #endif
154*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
155*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
156*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker   // Check we get the same instruction set features using AT_HWCAP.
159*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> hwcap_features(
160*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromHwcap());
161*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(hwcap_features->HasAtLeast(instruction_set_features.get()))
162*795d594fSAndroid Build Coastguard Worker       << "Hwcap features: " << *hwcap_features.get()
163*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
164*795d594fSAndroid Build Coastguard Worker }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) {
167*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
168*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
169*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker   // Check we get the same instruction set features using assembly tests.
172*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> assembly_features(
173*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromAssembly());
174*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(assembly_features->HasAtLeast(instruction_set_features.get()))
175*795d594fSAndroid Build Coastguard Worker       << "Assembly features: " << *assembly_features.get()
176*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturestFromCpuFeatures) {
180*795d594fSAndroid Build Coastguard Worker   // Take the default set of instruction features from the build.
181*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
182*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker   // Check we get the same instruction set features using the cpu_features library
185*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> library_features(
186*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCpuFeatures());
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(library_features->HasAtLeast(instruction_set_features.get()))
189*795d594fSAndroid Build Coastguard Worker       << "Library features: " << *library_features.get()
190*795d594fSAndroid Build Coastguard Worker       << "\nFeatures from build: " << *instruction_set_features.get();
191*795d594fSAndroid Build Coastguard Worker }
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, FeaturesFromRuntimeDetection) {
194*795d594fSAndroid Build Coastguard Worker   if (!InstructionSetFeatures::IsRuntimeDetectionSupported()) {
195*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(InstructionSetFeatures::FromRuntimeDetection(), nullptr);
196*795d594fSAndroid Build Coastguard Worker   }
197*795d594fSAndroid Build Coastguard Worker }
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker // The instruction set feature string must not contain 'default' together with
200*795d594fSAndroid Build Coastguard Worker // other feature names.
201*795d594fSAndroid Build Coastguard Worker //
202*795d594fSAndroid Build Coastguard Worker // Test that InstructionSetFeatures::AddFeaturesFromString returns nullptr and
203*795d594fSAndroid Build Coastguard Worker // an error is reported when the value 'default' is specified together
204*795d594fSAndroid Build Coastguard Worker // with other feature names in an instruction set feature string.
205*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, AddFeaturesFromStringWithDefaultAndOtherNames) {
206*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
207*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
208*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> invalid_feature_strings = {
209*795d594fSAndroid Build Coastguard Worker     "a,default",
210*795d594fSAndroid Build Coastguard Worker     "default,a",
211*795d594fSAndroid Build Coastguard Worker     "a,default,b",
212*795d594fSAndroid Build Coastguard Worker     "a,b,default",
213*795d594fSAndroid Build Coastguard Worker     "default,a,b,c",
214*795d594fSAndroid Build Coastguard Worker     "a,b,default,c,d",
215*795d594fSAndroid Build Coastguard Worker     "a, default ",
216*795d594fSAndroid Build Coastguard Worker     " default , a",
217*795d594fSAndroid Build Coastguard Worker     "a, default , b",
218*795d594fSAndroid Build Coastguard Worker     "default,runtime"
219*795d594fSAndroid Build Coastguard Worker   };
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker   for (const std::string& invalid_feature_string : invalid_feature_strings) {
222*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
223*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
224*795d594fSAndroid Build Coastguard Worker               nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
225*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(error_msg,
226*795d594fSAndroid Build Coastguard Worker               "Specific instruction set feature(s) cannot be used when 'default' is used.");
227*795d594fSAndroid Build Coastguard Worker   }
228*795d594fSAndroid Build Coastguard Worker }
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker // The instruction set feature string must not contain 'runtime' together with
231*795d594fSAndroid Build Coastguard Worker // other feature names.
232*795d594fSAndroid Build Coastguard Worker //
233*795d594fSAndroid Build Coastguard Worker // Test that InstructionSetFeatures::AddFeaturesFromString returns nullptr and
234*795d594fSAndroid Build Coastguard Worker // an error is reported when the value 'runtime' is specified together
235*795d594fSAndroid Build Coastguard Worker // with other feature names in an instruction set feature string.
236*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, AddFeaturesFromStringWithRuntimeAndOtherNames) {
237*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
238*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
239*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> invalid_feature_strings = {
240*795d594fSAndroid Build Coastguard Worker     "a,runtime",
241*795d594fSAndroid Build Coastguard Worker     "runtime,a",
242*795d594fSAndroid Build Coastguard Worker     "a,runtime,b",
243*795d594fSAndroid Build Coastguard Worker     "a,b,runtime",
244*795d594fSAndroid Build Coastguard Worker     "runtime,a,b,c",
245*795d594fSAndroid Build Coastguard Worker     "a,b,runtime,c,d",
246*795d594fSAndroid Build Coastguard Worker     "a, runtime ",
247*795d594fSAndroid Build Coastguard Worker     " runtime , a",
248*795d594fSAndroid Build Coastguard Worker     "a, runtime , b",
249*795d594fSAndroid Build Coastguard Worker     "runtime,default"
250*795d594fSAndroid Build Coastguard Worker   };
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   for (const std::string& invalid_feature_string : invalid_feature_strings) {
253*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
254*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
255*795d594fSAndroid Build Coastguard Worker               nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
256*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(error_msg,
257*795d594fSAndroid Build Coastguard Worker               "Specific instruction set feature(s) cannot be used when 'runtime' is used.");
258*795d594fSAndroid Build Coastguard Worker   }
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker // Spaces and multiple commas are ignores in a instruction set feature string.
262*795d594fSAndroid Build Coastguard Worker //
263*795d594fSAndroid Build Coastguard Worker // Test that a use of spaces and multiple commas with 'default' and 'runtime'
264*795d594fSAndroid Build Coastguard Worker // does not cause errors.
265*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, AddFeaturesFromValidStringContainingDefaultOrRuntime) {
266*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
267*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
268*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> valid_feature_strings = {
269*795d594fSAndroid Build Coastguard Worker     "default",
270*795d594fSAndroid Build Coastguard Worker     ",,,default",
271*795d594fSAndroid Build Coastguard Worker     "default,,,,",
272*795d594fSAndroid Build Coastguard Worker     ",,,default,,,,",
273*795d594fSAndroid Build Coastguard Worker     "default, , , ",
274*795d594fSAndroid Build Coastguard Worker     " , , ,default",
275*795d594fSAndroid Build Coastguard Worker     " , , ,default, , , ",
276*795d594fSAndroid Build Coastguard Worker     " default , , , ",
277*795d594fSAndroid Build Coastguard Worker     ",,,runtime",
278*795d594fSAndroid Build Coastguard Worker     "runtime,,,,",
279*795d594fSAndroid Build Coastguard Worker     ",,,runtime,,,,",
280*795d594fSAndroid Build Coastguard Worker     "runtime, , , ",
281*795d594fSAndroid Build Coastguard Worker     " , , ,runtime",
282*795d594fSAndroid Build Coastguard Worker     " , , ,runtime, , , ",
283*795d594fSAndroid Build Coastguard Worker     " runtime , , , "
284*795d594fSAndroid Build Coastguard Worker   };
285*795d594fSAndroid Build Coastguard Worker   for (const std::string& valid_feature_string : valid_feature_strings) {
286*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
287*795d594fSAndroid Build Coastguard Worker     EXPECT_NE(cpp_defined_features->AddFeaturesFromString(valid_feature_string, &error_msg),
288*795d594fSAndroid Build Coastguard Worker               nullptr) << " Valid feature string: '" << valid_feature_string << "'";
289*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(error_msg.empty()) << error_msg;
290*795d594fSAndroid Build Coastguard Worker   }
291*795d594fSAndroid Build Coastguard Worker }
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker // Spaces and multiple commas are ignores in a instruction set feature string.
294*795d594fSAndroid Build Coastguard Worker //
295*795d594fSAndroid Build Coastguard Worker // Test that a use of spaces and multiple commas without any feature names
296*795d594fSAndroid Build Coastguard Worker // causes errors.
297*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, AddFeaturesFromInvalidStringWithoutFeatureNames) {
298*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
299*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
300*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> invalid_feature_strings = {
301*795d594fSAndroid Build Coastguard Worker     " ",
302*795d594fSAndroid Build Coastguard Worker     "       ",
303*795d594fSAndroid Build Coastguard Worker     ",",
304*795d594fSAndroid Build Coastguard Worker     ",,",
305*795d594fSAndroid Build Coastguard Worker     " , , ,,,,,,",
306*795d594fSAndroid Build Coastguard Worker     "\t",
307*795d594fSAndroid Build Coastguard Worker     "  \t     ",
308*795d594fSAndroid Build Coastguard Worker     ",",
309*795d594fSAndroid Build Coastguard Worker     ",,",
310*795d594fSAndroid Build Coastguard Worker     " , , ,,,,,,"
311*795d594fSAndroid Build Coastguard Worker   };
312*795d594fSAndroid Build Coastguard Worker   for (const std::string& invalid_feature_string : invalid_feature_strings) {
313*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
314*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(cpp_defined_features->AddFeaturesFromString(invalid_feature_string, &error_msg),
315*795d594fSAndroid Build Coastguard Worker               nullptr) << " Invalid feature string: '" << invalid_feature_string << "'";
316*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(error_msg, "No instruction set features specified");
317*795d594fSAndroid Build Coastguard Worker   }
318*795d594fSAndroid Build Coastguard Worker }
319*795d594fSAndroid Build Coastguard Worker 
320*795d594fSAndroid Build Coastguard Worker TEST(InstructionSetFeaturesTest, AddFeaturesFromStringRuntime) {
321*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const InstructionSetFeatures> cpp_defined_features(
322*795d594fSAndroid Build Coastguard Worker       InstructionSetFeatures::FromCppDefines());
323*795d594fSAndroid Build Coastguard Worker   std::string error_msg;
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker   const std::unique_ptr<const InstructionSetFeatures> features =
326*795d594fSAndroid Build Coastguard Worker       cpp_defined_features->AddFeaturesFromString("runtime", &error_msg);
327*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(features, nullptr);
328*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(error_msg.empty()) << error_msg;
329*795d594fSAndroid Build Coastguard Worker   if (!InstructionSetFeatures::IsRuntimeDetectionSupported()) {
330*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(features->Equals(cpp_defined_features.get()));
331*795d594fSAndroid Build Coastguard Worker   }
332*795d594fSAndroid Build Coastguard Worker }
333*795d594fSAndroid Build Coastguard Worker 
334*795d594fSAndroid Build Coastguard Worker }  // namespace art
335