Add denver64 as a known ARM64 variant.

Other bits of instruction_set_features_test clean up.
Bug: 18385422

Change-Id: Ic48cfa0564b41ea140805a700de7c1e51addf49d
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index 696dd94..5bc943c 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -26,15 +26,29 @@
 
 const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromVariant(
     const std::string& variant ATTRIBUTE_UNUSED, std::string* error_msg ATTRIBUTE_UNUSED) {
-  if (variant != "default" && variant != "generic") {
-    std::ostringstream os;
-    os << "Unexpected CPU variant for Arm64: " << variant;
-    *error_msg = os.str();
-    return nullptr;
-  }
   const bool smp = true;  // Conservative default.
-  const bool is_a53 = true;  // Pessimistically assume all ARM64s are A53s.
-  return new Arm64InstructionSetFeatures(smp, is_a53);
+
+  // Look for variants that need a fix for a53 erratum 835769.
+  static const char* arm64_variants_with_a53_835769_bug[] = {
+      "default", "generic"  // Pessimistically assume all generic ARM64s are A53s.
+  };
+  bool needs_a53_835769_fix = FindVariantInArray(arm64_variants_with_a53_835769_bug,
+                                                 arraysize(arm64_variants_with_a53_835769_bug),
+                                                 variant);
+
+  if (!needs_a53_835769_fix) {
+    // Check to see if this is an expected variant.
+    static const char* arm64_known_variants[] = {
+        "denver64"
+    };
+    if (!FindVariantInArray(arm64_known_variants, arraysize(arm64_known_variants), variant)) {
+      std::ostringstream os;
+      os << "Unexpected CPU variant for Arm64: " << variant;
+      *error_msg = os.str();
+      return nullptr;
+    }
+  }
+  return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix);
 }
 
 const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.h b/runtime/arch/arm64/instruction_set_features_arm64.h
index ee41536..b0c66b3 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.h
+++ b/runtime/arch/arm64/instruction_set_features_arm64.h
@@ -70,8 +70,8 @@
                                  std::string* error_msg) const OVERRIDE;
 
  private:
-  explicit Arm64InstructionSetFeatures(bool smp, bool is_a53)
-      : InstructionSetFeatures(smp), fix_cortex_a53_835769_(is_a53) {
+  explicit Arm64InstructionSetFeatures(bool smp, bool needs_a53_835769_fix)
+      : InstructionSetFeatures(smp), fix_cortex_a53_835769_(needs_a53_835769_fix) {
   }
 
   // Bitmap positions for encoding features as a bitmap.
diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc
index 83571cf..e6f4e7a 100644
--- a/runtime/arch/instruction_set_features_test.cc
+++ b/runtime/arch/instruction_set_features_test.cc
@@ -27,12 +27,17 @@
 namespace art {
 
 #ifdef HAVE_ANDROID_OS
+#if defined(__aarch64__)
+TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) {
+  LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
+#else
 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) {
+#endif
   // Take the default set of instruction features from the build.
   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
       InstructionSetFeatures::FromCppDefines());
 
-  // Read the features property.
+  // Read the variant property.
   std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA));
   char dex2oat_isa_variant[PROPERTY_VALUE_MAX];
   if (property_get(key.c_str(), dex2oat_isa_variant, nullptr) > 0) {
@@ -49,29 +54,41 @@
   }
 }
 
+#if defined(__aarch64__)
+TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) {
+  LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769";
+#else
 TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) {
+#endif
   // Take the default set of instruction features from the build.
   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
       InstructionSetFeatures::FromCppDefines());
 
-  // Read the features property.
-  std::string key = StringPrintf("dalvik.vm.isa.%s.features", GetInstructionSetString(kRuntimeISA));
-  char dex2oat_isa_features[PROPERTY_VALUE_MAX];
-  if (property_get(key.c_str(), dex2oat_isa_features, nullptr) > 0) {
-    // Use features from property to build InstructionSetFeatures and check against build's
-    // features.
-    std::string error_msg;
-    std::unique_ptr<const InstructionSetFeatures> base_features(
-        InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg));
-    ASSERT_TRUE(base_features.get() != nullptr) << error_msg;
+  // Read the variant property.
+  std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant",
+                                         GetInstructionSetString(kRuntimeISA));
+  char dex2oat_isa_variant[PROPERTY_VALUE_MAX];
+  if (property_get(variant_key.c_str(), dex2oat_isa_variant, nullptr) > 0) {
+    // Read the features property.
+    std::string features_key = StringPrintf("dalvik.vm.isa.%s.features",
+                                            GetInstructionSetString(kRuntimeISA));
+    char dex2oat_isa_features[PROPERTY_VALUE_MAX];
+    if (property_get(features_key.c_str(), dex2oat_isa_features, nullptr) > 0) {
+      // Use features from property to build InstructionSetFeatures and check against build's
+      // features.
+      std::string error_msg;
+      std::unique_ptr<const InstructionSetFeatures> base_features(
+          InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg));
+      ASSERT_TRUE(base_features.get() != nullptr) << error_msg;
 
-    std::unique_ptr<const InstructionSetFeatures> property_features(
-        base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg));
-    ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
+      std::unique_ptr<const InstructionSetFeatures> property_features(
+          base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg));
+      ASSERT_TRUE(property_features.get() != nullptr) << error_msg;
 
-    EXPECT_TRUE(property_features->Equals(instruction_set_features.get()))
+      EXPECT_TRUE(property_features->Equals(instruction_set_features.get()))
       << "System property features: " << *property_features.get()
       << "\nFeatures from build: " << *instruction_set_features.get();
+    }
   }
 }
 
@@ -127,13 +144,7 @@
       << "\nFeatures from build: " << *instruction_set_features.get();
 }
 
-
-#if defined(__arm__)
-TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromAssembly) {
-  LOG(WARNING) << "Test disabled due to buggy ARM kernels";
-#else
 TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) {
-#endif
   // Take the default set of instruction features from the build.
   std::unique_ptr<const InstructionSetFeatures> instruction_set_features(
       InstructionSetFeatures::FromCppDefines());