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_arm.h"
18
19#include "gtest/gtest.h"
20
21namespace art {
22
23TEST(ArmInstructionSetFeaturesTest, ArmFeaturesFromVariant) {
24  // Build features for a 32-bit ARM krait processor.
25  std::string error_msg;
26  std::unique_ptr<const InstructionSetFeatures> krait_features(
27      InstructionSetFeatures::FromVariant(kArm, "krait", &error_msg));
28  ASSERT_TRUE(krait_features.get() != nullptr) << error_msg;
29
30  ASSERT_EQ(krait_features->GetInstructionSet(), kArm);
31  EXPECT_TRUE(krait_features->Equals(krait_features.get()));
32  EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
33  EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
34  EXPECT_STREQ("smp,div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
35  EXPECT_EQ(krait_features->AsBitmap(), 7U);
36
37  // Build features for a 32-bit ARM denver processor.
38  std::unique_ptr<const InstructionSetFeatures> denver_features(
39      InstructionSetFeatures::FromVariant(kArm, "denver", &error_msg));
40  ASSERT_TRUE(denver_features.get() != nullptr) << error_msg;
41
42  EXPECT_TRUE(denver_features->Equals(denver_features.get()));
43  EXPECT_TRUE(denver_features->Equals(krait_features.get()));
44  EXPECT_TRUE(krait_features->Equals(denver_features.get()));
45  EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
46  EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
47  EXPECT_STREQ("smp,div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
48  EXPECT_EQ(denver_features->AsBitmap(), 7U);
49
50  // Build features for a 32-bit ARMv7 processor.
51  std::unique_ptr<const InstructionSetFeatures> arm7_features(
52      InstructionSetFeatures::FromVariant(kArm, "arm7", &error_msg));
53  ASSERT_TRUE(arm7_features.get() != nullptr) << error_msg;
54
55  EXPECT_TRUE(arm7_features->Equals(arm7_features.get()));
56  EXPECT_FALSE(arm7_features->Equals(krait_features.get()));
57  EXPECT_FALSE(krait_features->Equals(arm7_features.get()));
58  EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
59  EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
60  EXPECT_STREQ("smp,-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
61  EXPECT_EQ(arm7_features->AsBitmap(), 1U);
62
63  // ARM6 is not a supported architecture variant.
64  std::unique_ptr<const InstructionSetFeatures> arm6_features(
65      InstructionSetFeatures::FromVariant(kArm, "arm6", &error_msg));
66  EXPECT_TRUE(arm6_features.get() == nullptr);
67  EXPECT_NE(error_msg.size(), 0U);
68}
69
70TEST(ArmInstructionSetFeaturesTest, ArmAddFeaturesFromString) {
71  std::string error_msg;
72  std::unique_ptr<const InstructionSetFeatures> base_features(
73      InstructionSetFeatures::FromVariant(kArm, "arm7", &error_msg));
74  ASSERT_TRUE(base_features.get() != nullptr) << error_msg;
75
76  // Build features for a 32-bit ARM with LPAE and div processor.
77  std::unique_ptr<const InstructionSetFeatures> krait_features(
78      base_features->AddFeaturesFromString("atomic_ldrd_strd,div", &error_msg));
79  ASSERT_TRUE(krait_features.get() != nullptr) << error_msg;
80
81  ASSERT_EQ(krait_features->GetInstructionSet(), kArm);
82  EXPECT_TRUE(krait_features->Equals(krait_features.get()));
83  EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
84  EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
85  EXPECT_STREQ("smp,div,atomic_ldrd_strd", krait_features->GetFeatureString().c_str());
86  EXPECT_EQ(krait_features->AsBitmap(), 7U);
87
88  // Build features for a 32-bit ARM processor with LPAE and div flipped.
89  std::unique_ptr<const InstructionSetFeatures> denver_features(
90      base_features->AddFeaturesFromString("div,atomic_ldrd_strd", &error_msg));
91  ASSERT_TRUE(denver_features.get() != nullptr) << error_msg;
92
93  EXPECT_TRUE(denver_features->Equals(denver_features.get()));
94  EXPECT_TRUE(denver_features->Equals(krait_features.get()));
95  EXPECT_TRUE(krait_features->Equals(denver_features.get()));
96  EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
97  EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
98  EXPECT_STREQ("smp,div,atomic_ldrd_strd", denver_features->GetFeatureString().c_str());
99  EXPECT_EQ(denver_features->AsBitmap(), 7U);
100
101  // Build features for a 32-bit default ARM processor.
102  std::unique_ptr<const InstructionSetFeatures> arm7_features(
103      base_features->AddFeaturesFromString("default", &error_msg));
104  ASSERT_TRUE(arm7_features.get() != nullptr) << error_msg;
105
106  EXPECT_TRUE(arm7_features->Equals(arm7_features.get()));
107  EXPECT_FALSE(arm7_features->Equals(krait_features.get()));
108  EXPECT_FALSE(krait_features->Equals(arm7_features.get()));
109  EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasDivideInstruction());
110  EXPECT_FALSE(arm7_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd());
111  EXPECT_STREQ("smp,-div,-atomic_ldrd_strd", arm7_features->GetFeatureString().c_str());
112  EXPECT_EQ(arm7_features->AsBitmap(), 1U);
113}
114
115}  // namespace art
116