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