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 
21 namespace art {
22 
TEST(ArmInstructionSetFeaturesTest,ArmFeaturesFromVariant)23 TEST(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 
TEST(ArmInstructionSetFeaturesTest,ArmAddFeaturesFromString)70 TEST(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