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 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(InstructionSet::kArm, "krait", &error_msg)); 28 ASSERT_TRUE(krait_features.get() != nullptr) << error_msg; 29 30 ASSERT_EQ(krait_features->GetInstructionSet(), InstructionSet::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("div,atomic_ldrd_strd,-armv8a", krait_features->GetFeatureString().c_str()); 35 EXPECT_EQ(krait_features->AsBitmap(), 3U); 36 37 // Build features for a 32-bit ARM kryo processor. 38 std::unique_ptr<const InstructionSetFeatures> kryo_features( 39 InstructionSetFeatures::FromVariant(InstructionSet::kArm, "kryo", &error_msg)); 40 ASSERT_TRUE(kryo_features.get() != nullptr) << error_msg; 41 42 ASSERT_EQ(kryo_features->GetInstructionSet(), InstructionSet::kArm); 43 EXPECT_TRUE(kryo_features->Equals(kryo_features.get())); 44 EXPECT_TRUE(kryo_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 45 EXPECT_TRUE(kryo_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 46 EXPECT_STREQ("div,atomic_ldrd_strd,armv8a", kryo_features->GetFeatureString().c_str()); 47 EXPECT_EQ(kryo_features->AsBitmap(), 7U); 48 49 // Build features for a 32-bit ARM denver processor. 50 std::unique_ptr<const InstructionSetFeatures> denver_features( 51 InstructionSetFeatures::FromVariant(InstructionSet::kArm, "denver", &error_msg)); 52 ASSERT_TRUE(denver_features.get() != nullptr) << error_msg; 53 54 EXPECT_TRUE(denver_features->Equals(denver_features.get())); 55 EXPECT_TRUE(denver_features->HasAtLeast(krait_features.get())); 56 EXPECT_FALSE(krait_features->Equals(denver_features.get())); 57 EXPECT_FALSE(krait_features->HasAtLeast(denver_features.get())); 58 EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 59 EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 60 EXPECT_STREQ("div,atomic_ldrd_strd,armv8a", denver_features->GetFeatureString().c_str()); 61 EXPECT_EQ(denver_features->AsBitmap(), 7U); 62 63 // Build features for a 32-bit ARMv7 processor. 64 std::unique_ptr<const InstructionSetFeatures> generic_features( 65 InstructionSetFeatures::FromVariant(InstructionSet::kArm, "generic", &error_msg)); 66 ASSERT_TRUE(generic_features.get() != nullptr) << error_msg; 67 68 EXPECT_TRUE(generic_features->Equals(generic_features.get())); 69 EXPECT_FALSE(generic_features->Equals(krait_features.get())); 70 EXPECT_FALSE(krait_features->Equals(generic_features.get())); 71 EXPECT_FALSE(generic_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 72 EXPECT_FALSE(generic_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 73 EXPECT_STREQ("-div,-atomic_ldrd_strd,-armv8a", generic_features->GetFeatureString().c_str()); 74 EXPECT_EQ(generic_features->AsBitmap(), 0U); 75 76 // ARM6 is not a supported architecture variant. 77 std::unique_ptr<const InstructionSetFeatures> arm6_features( 78 InstructionSetFeatures::FromVariant(InstructionSet::kArm, "arm6", &error_msg)); 79 EXPECT_TRUE(arm6_features.get() == nullptr); 80 EXPECT_NE(error_msg.size(), 0U); 81 } 82 83 TEST(ArmInstructionSetFeaturesTest, ArmAddFeaturesFromString) { 84 std::string error_msg; 85 std::unique_ptr<const InstructionSetFeatures> base_features( 86 InstructionSetFeatures::FromVariant(InstructionSet::kArm, "generic", &error_msg)); 87 ASSERT_TRUE(base_features.get() != nullptr) << error_msg; 88 89 // Build features for a 32-bit ARM with LPAE and div processor. 90 std::unique_ptr<const InstructionSetFeatures> krait_features( 91 base_features->AddFeaturesFromString("atomic_ldrd_strd,div", &error_msg)); 92 ASSERT_TRUE(krait_features.get() != nullptr) << error_msg; 93 94 ASSERT_EQ(krait_features->GetInstructionSet(), InstructionSet::kArm); 95 EXPECT_TRUE(krait_features->Equals(krait_features.get())); 96 EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 97 EXPECT_TRUE(krait_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 98 EXPECT_STREQ("div,atomic_ldrd_strd,-armv8a", krait_features->GetFeatureString().c_str()); 99 EXPECT_EQ(krait_features->AsBitmap(), 3U); 100 101 // Build features for a 32-bit ARM with LPAE and div processor. 102 std::unique_ptr<const InstructionSetFeatures> kryo_features( 103 base_features->AddFeaturesFromString("atomic_ldrd_strd,div", &error_msg)); 104 ASSERT_TRUE(kryo_features.get() != nullptr) << error_msg; 105 106 ASSERT_EQ(kryo_features->GetInstructionSet(), InstructionSet::kArm); 107 EXPECT_TRUE(kryo_features->Equals(krait_features.get())); 108 EXPECT_TRUE(kryo_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 109 EXPECT_TRUE(kryo_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 110 EXPECT_STREQ("div,atomic_ldrd_strd,-armv8a", kryo_features->GetFeatureString().c_str()); 111 EXPECT_EQ(kryo_features->AsBitmap(), 3U); 112 113 // Build features for a 32-bit ARM processor with LPAE and div flipped. 114 std::unique_ptr<const InstructionSetFeatures> denver_features( 115 base_features->AddFeaturesFromString("div,atomic_ldrd_strd,armv8a", &error_msg)); 116 ASSERT_TRUE(denver_features.get() != nullptr) << error_msg; 117 118 EXPECT_TRUE(denver_features->Equals(denver_features.get())); 119 EXPECT_FALSE(denver_features->Equals(krait_features.get())); 120 EXPECT_TRUE(denver_features->HasAtLeast(krait_features.get())); 121 EXPECT_FALSE(krait_features->Equals(denver_features.get())); 122 EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 123 EXPECT_TRUE(denver_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 124 EXPECT_STREQ("div,atomic_ldrd_strd,armv8a", denver_features->GetFeatureString().c_str()); 125 EXPECT_EQ(denver_features->AsBitmap(), 7U); 126 127 // Build features for a 32-bit default ARM processor. 128 std::unique_ptr<const InstructionSetFeatures> generic_features( 129 base_features->AddFeaturesFromString("default", &error_msg)); 130 ASSERT_TRUE(generic_features.get() != nullptr) << error_msg; 131 132 EXPECT_TRUE(generic_features->Equals(generic_features.get())); 133 EXPECT_FALSE(generic_features->Equals(krait_features.get())); 134 EXPECT_FALSE(krait_features->Equals(generic_features.get())); 135 EXPECT_FALSE(generic_features->AsArmInstructionSetFeatures()->HasDivideInstruction()); 136 EXPECT_FALSE(generic_features->AsArmInstructionSetFeatures()->HasAtomicLdrdAndStrd()); 137 EXPECT_STREQ("-div,-atomic_ldrd_strd,-armv8a", generic_features->GetFeatureString().c_str()); 138 EXPECT_EQ(generic_features->AsBitmap(), 0U); 139 } 140 141 } // namespace art 142