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