Refined HasAtLeast() for x86 and x86_64.

Rationale:
This refinement is needed once we start passing in more
architecture specific flags on x86_* builds. This CL
also makes the arm version a bit more readable.

Test: instruction_set_features_test
Bug: 63585550

Change-Id: Ia6fe47654141feaf1899da225abaee8a5ea8249a
diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc
index 8384460..0942356 100644
--- a/runtime/arch/arm/instruction_set_features_arm.cc
+++ b/runtime/arch/arm/instruction_set_features_arm.cc
@@ -279,10 +279,9 @@
     return false;
   }
   const ArmInstructionSetFeatures* other_as_arm = other->AsArmInstructionSetFeatures();
-
-  return (has_div_ || (has_div_ == other_as_arm->has_div_))
-      && (has_atomic_ldrd_strd_ || (has_atomic_ldrd_strd_ == other_as_arm->has_atomic_ldrd_strd_))
-      && (has_armv8a_ || (has_armv8a_ == other_as_arm->has_armv8a_));
+  return (has_div_ || !other_as_arm->has_div_)
+      && (has_atomic_ldrd_strd_ || !other_as_arm->has_atomic_ldrd_strd_)
+      && (has_armv8a_ || !other_as_arm->has_armv8a_);
 }
 
 uint32_t ArmInstructionSetFeatures::AsBitmap() const {
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index cc0bdf2..ea5a90d 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -230,6 +230,19 @@
       (has_POPCNT_ == other_as_x86->has_POPCNT_);
 }
 
+bool X86InstructionSetFeatures::HasAtLeast(const InstructionSetFeatures* other) const {
+  if (GetInstructionSet() != other->GetInstructionSet()) {
+    return false;
+  }
+  const X86InstructionSetFeatures* other_as_x86 = other->AsX86InstructionSetFeatures();
+  return (has_SSSE3_ || !other_as_x86->has_SSSE3_) &&
+      (has_SSE4_1_ || !other_as_x86->has_SSE4_1_) &&
+      (has_SSE4_2_ || !other_as_x86->has_SSE4_2_) &&
+      (has_AVX_ || !other_as_x86->has_AVX_) &&
+      (has_AVX2_ || !other_as_x86->has_AVX2_) &&
+      (has_POPCNT_ || !other_as_x86->has_POPCNT_);
+}
+
 uint32_t X86InstructionSetFeatures::AsBitmap() const {
   return (has_SSSE3_ ? kSsse3Bitfield : 0) |
       (has_SSE4_1_ ? kSse4_1Bitfield : 0) |
diff --git a/runtime/arch/x86/instruction_set_features_x86.h b/runtime/arch/x86/instruction_set_features_x86.h
index eb8a710..56cb07e 100644
--- a/runtime/arch/x86/instruction_set_features_x86.h
+++ b/runtime/arch/x86/instruction_set_features_x86.h
@@ -29,12 +29,11 @@
  public:
   // Process a CPU variant string like "atom" or "nehalem" and create InstructionSetFeatures.
   static X86FeaturesUniquePtr FromVariant(const std::string& variant,
-                                                                      std::string* error_msg,
-                                                                      bool x86_64 = false);
+                                          std::string* error_msg,
+                                          bool x86_64 = false);
 
   // Parse a bitmap and create an InstructionSetFeatures.
-  static X86FeaturesUniquePtr FromBitmap(uint32_t bitmap,
-                                                                     bool x86_64 = false);
+  static X86FeaturesUniquePtr FromBitmap(uint32_t bitmap, bool x86_64 = false);
 
   // Turn C pre-processor #defines into the equivalent instruction set features.
   static X86FeaturesUniquePtr FromCppDefines(bool x86_64 = false);
@@ -52,6 +51,8 @@
 
   bool Equals(const InstructionSetFeatures* other) const OVERRIDE;
 
+  bool HasAtLeast(const InstructionSetFeatures* other) const OVERRIDE;
+
   virtual InstructionSet GetInstructionSet() const OVERRIDE {
     return kX86;
   }