// Copyright 2016, VIXL authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of ARM Limited nor the names of its contributors may be
//     used to endorse or promote products derived from this software without
//     specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <iostream>
#include <set>
#include <sstream>
#include <vector>

#include "test-runner.h"

#include "cpu-features.h"
#include "utils-vixl.h"

#if __cplusplus >= 201103L
#include <type_traits>
#endif

#define TEST(name) TEST_(API_##name)

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

namespace vixl {

// Describe the result of a test. Should IsUintN() and IsIntN() return true or
// false for N and X?
template <typename T>
struct UintIntTest {
  bool is_uintn;
  bool is_intn;
  unsigned n;
  T x;
};

// Test IsUintN() and IsIntN() against various values and integral types.
TEST(IsUint_IsInt) {
  UintIntTest<uint32_t> test_little_values_unsigned[] = {
      {true, true, 1, UINT32_C(0x0)},   {true, false, 1, UINT32_C(0x1)},
      {false, false, 1, UINT32_C(0x2)}, {false, false, 1, UINT32_C(0x3)},
      {false, false, 1, UINT32_C(0x4)}, {false, false, 1, UINT32_C(0x5)},
      {false, false, 1, UINT32_C(0x6)}, {false, false, 1, UINT32_C(0x7)},
      {false, false, 1, UINT32_C(0x8)}, {false, false, 1, UINT32_C(0x9)},
      {false, false, 1, UINT32_C(0xa)}, {false, false, 1, UINT32_C(0xb)},
      {false, false, 1, UINT32_C(0xc)}, {false, false, 1, UINT32_C(0xd)},
      {false, false, 1, UINT32_C(0xe)}, {false, false, 1, UINT32_C(0xf)},

      {true, true, 2, UINT32_C(0x0)},   {true, true, 2, UINT32_C(0x1)},
      {true, false, 2, UINT32_C(0x2)},  {true, false, 2, UINT32_C(0x3)},
      {false, false, 2, UINT32_C(0x4)}, {false, false, 2, UINT32_C(0x5)},
      {false, false, 2, UINT32_C(0x6)}, {false, false, 2, UINT32_C(0x7)},
      {false, false, 2, UINT32_C(0x8)}, {false, false, 2, UINT32_C(0x9)},
      {false, false, 2, UINT32_C(0xa)}, {false, false, 2, UINT32_C(0xb)},
      {false, false, 2, UINT32_C(0xc)}, {false, false, 2, UINT32_C(0xd)},
      {false, false, 2, UINT32_C(0xe)}, {false, false, 2, UINT32_C(0xf)},
  };

  UintIntTest<int32_t> test_little_values_signed[] = {
      {true, true, 1, INT32_C(0)},    {true, false, 1, INT32_C(1)},
      {false, false, 1, INT32_C(2)},  {false, false, 1, INT32_C(3)},
      {false, false, 1, INT32_C(4)},  {false, false, 1, INT32_C(5)},
      {false, false, 1, INT32_C(6)},  {false, false, 1, INT32_C(7)},
      {false, true, 1, INT32_C(-1)},  {false, false, 1, INT32_C(-2)},
      {false, false, 1, INT32_C(-3)}, {false, false, 1, INT32_C(-4)},
      {false, false, 1, INT32_C(-5)}, {false, false, 1, INT32_C(-6)},
      {false, false, 1, INT32_C(-7)}, {false, false, 1, INT32_C(-8)},

      {true, true, 2, INT32_C(0)},    {true, true, 2, INT32_C(1)},
      {true, false, 2, INT32_C(2)},   {true, false, 2, INT32_C(3)},
      {false, false, 2, INT32_C(4)},  {false, false, 2, INT32_C(5)},
      {false, false, 2, INT32_C(6)},  {false, false, 2, INT32_C(7)},
      {false, true, 2, INT32_C(-1)},  {false, true, 2, INT32_C(-2)},
      {false, false, 2, INT32_C(-3)}, {false, false, 2, INT32_C(-4)},
      {false, false, 2, INT32_C(-5)}, {false, false, 2, INT32_C(-6)},
      {false, false, 2, INT32_C(-7)}, {false, false, 2, INT32_C(-8)},
  };

  UintIntTest<uint32_t> test_u16[] = {
      {true, true, 16, UINT32_C(0x0)},
      {true, false, 16, UINT32_C(0xabcd)},
      {true, false, 16, UINT32_C(0x8000)},
      {true, false, 16, UINT32_C(0xffff)},
      {false, false, 16, UINT32_C(0x10000)},
      {false, false, 16, UINT32_C(0xffff0000)},
      {false, false, 16, UINT32_C(0xffff8000)},
      {false, false, 16, UINT32_C(0xffffffff)},
  };

  UintIntTest<int32_t> test_i16[] = {
      {true, true, 16, INT32_C(0x0)},
      {true, false, 16, INT32_C(0xabcd)},
      {true, false, 16, INT32_C(0x8000)},
      {true, false, 16, INT32_C(0xffff)},
      {false, false, 16, INT32_C(0x10000)},
      {true, true, 16, INT32_C(42)},
      {false, true, 16, INT32_C(-42)},
      {false, true, 16, INT32_C(-1)},
  };

  UintIntTest<uint64_t> test_u32[] = {
      {true, true, 32, UINT64_C(0x0)},
      {true, false, 32, UINT64_C(0xabcdabcd)},
      {true, false, 32, UINT64_C(0x80000000)},
      {true, false, 32, UINT64_C(0xffffffff)},
  };

  UintIntTest<int64_t> test_i32[] = {
      {true, true, 32, INT64_C(0)},
      {true, true, 32, INT64_C(42)},
      {false, true, 32, INT64_C(-42)},
      {false, true, 32, INT64_C(-1)},
      {true, true, 32, INT64_C(2147483647)},    // (1 << (32 - 1)) - 1
      {false, true, 32, INT64_C(-2147483648)},  // -(1 << (32 - 1))
  };

  UintIntTest<uint64_t> test_unsigned_higher_than_32[] = {
      {false, false, 54, UINT64_C(0xabcdef9012345678)},
      {true, false, 33, UINT64_C(0x100000000)},
      {true, false, 62, UINT64_C(0x3fffffffffffffff)},
      {true, false, 63, UINT64_C(0x7fffffffffffffff)},
  };

  UintIntTest<int64_t> test_signed_higher_than_32[] = {
      {true, true, 54, INT64_C(9007199254740991)},   // (1 << (54 - 1)) - 1
      {true, false, 54, INT64_C(9007199254740992)},  // 1 << (54 - 1)
      {true, true, 33, INT64_C(4294967295)},         // (1 << (33 - 1) - 1)
      {false, true, 33, INT64_C(-4294967296)},       // -(1 << (33 - 1))
  };

#define TEST_LIST(M)              \
  M(test_little_values_unsigned)  \
  M(test_little_values_signed)    \
  M(test_u16)                     \
  M(test_i16)                     \
  M(test_u32)                     \
  M(test_i32)                     \
  M(test_unsigned_higher_than_32) \
  M(test_signed_higher_than_32)


#define TEST_UINT(test_vector)                                  \
  for (unsigned i = 0; i < ARRAY_SIZE(test_vector); i++) {      \
    if (test_vector[i].is_uintn) {                              \
      VIXL_CHECK(IsUintN(test_vector[i].n, test_vector[i].x));  \
    } else {                                                    \
      VIXL_CHECK(!IsUintN(test_vector[i].n, test_vector[i].x)); \
    }                                                           \
  }

#define TEST_INT(test_vector)                                  \
  for (unsigned i = 0; i < ARRAY_SIZE(test_vector); i++) {     \
    if (test_vector[i].is_intn) {                              \
      VIXL_CHECK(IsIntN(test_vector[i].n, test_vector[i].x));  \
    } else {                                                   \
      VIXL_CHECK(!IsIntN(test_vector[i].n, test_vector[i].x)); \
    }                                                          \
  }

  TEST_LIST(TEST_UINT)
  TEST_LIST(TEST_INT)

#undef TEST_UINT
#undef TEST_INT

#undef TEST_LIST
}


TEST(CPUFeatures_iterator_api) {
  // CPUFeaturesIterator does not fully satisfy the requirements of C++'s
  // iterator concepts, but it should implement enough for some basic usage.

  // Arbitrary feature lists.
  CPUFeatures f1(CPUFeatures::kFP, CPUFeatures::kNEON);
  CPUFeatures f2(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kCRC32);
  CPUFeatures f3;

  typedef CPUFeatures::const_iterator It;

  It it0;
  It it1_neon(&f1, CPUFeatures::kNEON);
  It it2_neon(&f2, CPUFeatures::kNEON);
  It it2_crc32(&f2, CPUFeatures::kCRC32);
  It it3(&f3);

  // Equality
  VIXL_CHECK(it0 == it0);
  VIXL_CHECK(it1_neon == it1_neon);
  VIXL_CHECK(it2_neon == it2_neon);
  VIXL_CHECK(it2_crc32 == it2_crc32);
  VIXL_CHECK(it3 == it3);
  VIXL_CHECK(!(it0 == it1_neon));
  VIXL_CHECK(!(it0 == it3));
  VIXL_CHECK(!(it1_neon == it2_neon));
  VIXL_CHECK(!(it1_neon == it2_crc32));
  VIXL_CHECK(!(it1_neon == it3));
  VIXL_CHECK(!(it2_neon == it2_crc32));
  VIXL_CHECK(!(it3 == it0));
  VIXL_CHECK(!(it3 == it1_neon));

  // Inequality
  //   (a == b)  <->  !(a != b)
  VIXL_CHECK(!(it0 != it0));
  VIXL_CHECK(!(it1_neon != it1_neon));
  VIXL_CHECK(!(it2_neon != it2_neon));
  VIXL_CHECK(!(it2_crc32 != it2_crc32));
  VIXL_CHECK(!(it3 != it3));
  //   !(a == b)  <->  (a != b)
  VIXL_CHECK(it0 != it1_neon);
  VIXL_CHECK(it0 != it3);
  VIXL_CHECK(it1_neon != it2_neon);
  VIXL_CHECK(it1_neon != it2_crc32);
  VIXL_CHECK(it1_neon != it3);
  VIXL_CHECK(it2_neon != it2_crc32);
  VIXL_CHECK(it3 != it0);
  VIXL_CHECK(it3 != it1_neon);

  // Dereferenceable
  VIXL_CHECK(*it0 == CPUFeatures::kNone);
  VIXL_CHECK(*it1_neon == CPUFeatures::kNEON);
  VIXL_CHECK(*it2_neon == CPUFeatures::kNEON);
  VIXL_CHECK(*it2_crc32 == CPUFeatures::kCRC32);
  VIXL_CHECK(*it3 == CPUFeatures::kNone);

#if __cplusplus >= 201103L
  VIXL_STATIC_ASSERT(std::is_copy_constructible<It>::value);
  VIXL_STATIC_ASSERT(std::is_copy_assignable<It>::value);
  VIXL_STATIC_ASSERT(std::is_destructible<It>::value);
#endif
  // Copy constructable
  It test0 = it0;
  It test1 = it1_neon;
  It test2(it2_neon);
  VIXL_CHECK(test0 == It(NULL, CPUFeatures::kNone));
  VIXL_CHECK(test1 == It(&f1, CPUFeatures::kNEON));
  VIXL_CHECK(test2 == It(&f2, CPUFeatures::kNEON));

  // Copy assignable
  test2 = it2_crc32;
  VIXL_CHECK(test2 == It(&f2, CPUFeatures::kCRC32));

  // Incrementable
  // - Incrementing has no effect on an empty CPUFeatures.
  VIXL_CHECK(it3++ == CPUFeatures::kNone);
  VIXL_CHECK(++it3 == CPUFeatures::kNone);
  VIXL_CHECK(it3 == It(&f3, CPUFeatures::kNone));
  // - Incrementing moves to the next feature, wrapping around (through kNone).
  //   This test will need to be updated if the Feature enum is reordered.
  VIXL_CHECK(it2_neon++ == CPUFeatures::kNEON);
  VIXL_CHECK(it2_neon++ == CPUFeatures::kCRC32);
  VIXL_CHECK(it2_neon++ == CPUFeatures::kNone);
  VIXL_CHECK(it2_neon++ == CPUFeatures::kFP);
  VIXL_CHECK(it2_neon == It(&f2, CPUFeatures::kNEON));
  VIXL_CHECK(++it2_crc32 == CPUFeatures::kNone);
  VIXL_CHECK(++it2_crc32 == CPUFeatures::kFP);
  VIXL_CHECK(++it2_crc32 == CPUFeatures::kNEON);
  VIXL_CHECK(++it2_crc32 == CPUFeatures::kCRC32);
  VIXL_CHECK(it2_crc32 == It(&f2, CPUFeatures::kCRC32));
}


TEST(CPUFeatures_iterator_loops) {
  // Check that CPUFeaturesIterator can be used for some simple loops.

  // Arbitrary feature lists.
  CPUFeatures f1(CPUFeatures::kFP, CPUFeatures::kNEON);
  CPUFeatures f2(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kCRC32);
  CPUFeatures f3;

  // This test will need to be updated if the Feature enum is reordered.

  std::vector<CPUFeatures::Feature> f1_list;
  for (CPUFeatures::const_iterator it = f1.begin(); it != f1.end(); ++it) {
    f1_list.push_back(*it);
  }
  VIXL_CHECK(f1_list.size() == 2);
  VIXL_CHECK(f1_list[0] == CPUFeatures::kFP);
  VIXL_CHECK(f1_list[1] == CPUFeatures::kNEON);

  std::vector<CPUFeatures::Feature> f2_list;
  for (CPUFeatures::const_iterator it = f2.begin(); it != f2.end(); ++it) {
    f2_list.push_back(*it);
  }
  VIXL_CHECK(f2_list.size() == 3);
  VIXL_CHECK(f2_list[0] == CPUFeatures::kFP);
  VIXL_CHECK(f2_list[1] == CPUFeatures::kNEON);
  VIXL_CHECK(f2_list[2] == CPUFeatures::kCRC32);

  std::vector<CPUFeatures::Feature> f3_list;
  for (CPUFeatures::const_iterator it = f3.begin(); it != f3.end(); ++it) {
    f3_list.push_back(*it);
  }
  VIXL_CHECK(f3_list.size() == 0);

#if __cplusplus >= 201103L
  std::vector<CPUFeatures::Feature> f2_list_cxx11;
  for (auto&& feature : f2) {
    f2_list_cxx11.push_back(feature);
  }
  VIXL_CHECK(f2_list_cxx11.size() == 3);
  VIXL_CHECK(f2_list_cxx11[0] == CPUFeatures::kFP);
  VIXL_CHECK(f2_list_cxx11[1] == CPUFeatures::kNEON);
  VIXL_CHECK(f2_list_cxx11[2] == CPUFeatures::kCRC32);

  std::vector<CPUFeatures::Feature> f3_list_cxx11;
  for (auto&& feature : f3) {
    f3_list_cxx11.push_back(feature);
  }
  VIXL_CHECK(f3_list_cxx11.size() == 0);
#endif
}


TEST(CPUFeatures_empty) {
  // A default-constructed CPUFeatures has no features enabled.
  CPUFeatures f;
  for (CPUFeatures::const_iterator it = f.begin(); it != f.end(); ++it) {
    VIXL_ABORT();
  }
}


static void CPUFeaturesFormatHelper(const char* expected,
                                    const CPUFeatures& features) {
  std::stringstream os;
  os << features;
  std::string os_str = os.str();
  if (os_str != expected) {
    std::cout << "Found: " << os_str << "\n";
    std::cout << "Expected: " << expected << "\n";
    VIXL_ABORT();
  }
}


TEST(CPUFeatures_format) {
  // Check that the debug output is complete and accurate.

  // Individual features.
  CPUFeaturesFormatHelper("", CPUFeatures(CPUFeatures::kNone));
  CPUFeaturesFormatHelper("FP", CPUFeatures(CPUFeatures::kFP));
  CPUFeaturesFormatHelper("NEON", CPUFeatures(CPUFeatures::kNEON));
  CPUFeaturesFormatHelper("AES", CPUFeatures(CPUFeatures::kAES));
  CPUFeaturesFormatHelper("Pmull1Q", CPUFeatures(CPUFeatures::kPmull1Q));
  CPUFeaturesFormatHelper("SHA1", CPUFeatures(CPUFeatures::kSHA1));
  CPUFeaturesFormatHelper("SHA2", CPUFeatures(CPUFeatures::kSHA2));
  CPUFeaturesFormatHelper("CRC32", CPUFeatures(CPUFeatures::kCRC32));

  // Combinations of (arbitrary) features.
  // This test will need to be updated if the Feature enum is reordered.
  CPUFeatures f(CPUFeatures::kFP, CPUFeatures::kNEON);
  CPUFeaturesFormatHelper("FP, NEON", f);
  f.Combine(CPUFeatures::kCRC32);
  CPUFeaturesFormatHelper("FP, NEON, CRC32", f);
  f.Combine(CPUFeatures::kFcma);
  CPUFeaturesFormatHelper("FP, NEON, CRC32, Fcma", f);
  f.Combine(CPUFeatures::kSHA1);
  CPUFeaturesFormatHelper("FP, NEON, CRC32, SHA1, Fcma", f);

  CPUFeaturesFormatHelper(
      "ID register emulation, "
      // Armv8.0
      "FP, NEON, CRC32, "
      "AES, SHA1, SHA2, Pmull1Q, "
      // Armv8.1
      "Atomics, LORegions, RDM, "
      // Armv8.2
      "SVE, DotProduct, FPHalf, NEONHalf, RAS, DCPoP, DCCVADP, SHA3, SHA512, "
      "SM3, SM4, "
      // Armv8.3
      "PAuth, PAuthQARMA, PAuthGeneric, PAuthGenericQARMA, JSCVT, Fcma, RCpc, "
      // Armv8.4
      "RCpc (imm), FlagM, USCAT, FHM, DIT, "
      // Armv8.5
      "BTI, AXFlag, RNG, Frint (bounded)",
      CPUFeatures::All());
}


static void CPUFeaturesPredefinedResultCheckHelper(
    const std::set<CPUFeatures::Feature>& unexpected,
    const std::set<CPUFeatures::Feature>& expected) {
  // Print a helpful diagnostic before checking the result.
  typedef std::set<CPUFeatures::Feature>::const_iterator It;
  if (!unexpected.empty()) {
    std::cout << "Unexpected features:\n";
    for (It it = unexpected.begin(); it != unexpected.end(); ++it) {
      std::cout << "  " << *it << "\n";
    }
  }
  if (!expected.empty()) {
    std::cout << "Missing features:\n";
    for (It it = expected.begin(); it != expected.end(); ++it) {
      std::cout << "  " << *it << "\n";
    }
  }
  VIXL_CHECK(unexpected.empty() && expected.empty());
}


TEST(CPUFeatures_predefined_legacy) {
  CPUFeatures f = CPUFeatures::AArch64LegacyBaseline();
  std::set<CPUFeatures::Feature> unexpected;
  std::set<CPUFeatures::Feature> expected;
  expected.insert(CPUFeatures::kFP);
  expected.insert(CPUFeatures::kNEON);
  expected.insert(CPUFeatures::kCRC32);

  for (CPUFeatures::const_iterator it = f.begin(); it != f.end(); ++it) {
    if (expected.erase(*it) == 0) unexpected.insert(*it);
  }
  CPUFeaturesPredefinedResultCheckHelper(unexpected, expected);
}


TEST(CPUFeatures_predefined_all) {
  CPUFeatures f = CPUFeatures::All();
  std::set<CPUFeatures::Feature> found;

  for (CPUFeatures::const_iterator it = f.begin(); it != f.end(); ++it) {
    found.insert(*it);
  }
  VIXL_CHECK(found.size() == CPUFeatures::kNumberOfFeatures);
}

// The CPUFeaturesScope constructor is templated, and needs an object which
// implements `CPUFeatures* GetCPUFeatures()`. This is normally something like
// the Assembler, but for the tests we use an architecture-independent wrapper.
class GetCPUFeaturesWrapper {
 public:
  explicit GetCPUFeaturesWrapper(CPUFeatures* cpu_features)
      : cpu_features_(cpu_features) {}

  CPUFeatures* GetCPUFeatures() const { return cpu_features_; }

 private:
  CPUFeatures* cpu_features_;
};

TEST(CPUFeaturesScope) {
  // Test that CPUFeaturesScope properly preserves state.

  CPUFeatures cpu(CPUFeatures::kCRC32, CPUFeatures::kSHA1, CPUFeatures::kAES);
  GetCPUFeaturesWrapper top_level(&cpu);

  const CPUFeatures original_outer = cpu;

  {  // Test setting both new and existing features.
    CPUFeaturesScope outer(&top_level, CPUFeatures::kSHA2, CPUFeatures::kAES);
    VIXL_CHECK(outer.GetCPUFeatures() == &cpu);
    VIXL_CHECK(cpu.Has(CPUFeatures::kCRC32,
                       CPUFeatures::kSHA1,
                       CPUFeatures::kSHA2,
                       CPUFeatures::kAES));

    // Features can be added or removed directly, in the usual fashion.
    // (The scope will restore their original status when it ends.)
    cpu.Combine(CPUFeatures::kSHA1, CPUFeatures::kAtomics);
    VIXL_CHECK(cpu.Has(CPUFeatures::kCRC32,
                       CPUFeatures::kSHA1,
                       CPUFeatures::kSHA2,
                       CPUFeatures::kAES));
    VIXL_CHECK(cpu.Has(CPUFeatures::kAtomics));

    cpu.Remove(CPUFeatures::kSHA2, CPUFeatures::kAES);
    VIXL_CHECK(!cpu.Has(CPUFeatures::kSHA2, CPUFeatures::kAES));
    VIXL_CHECK(cpu.Has(CPUFeatures::kCRC32,
                       CPUFeatures::kSHA1,
                       CPUFeatures::kAtomics));

    const CPUFeatures original_inner = cpu;

    // Scopes can be nested.
    {
      // A CPUFeaturesScope can be constructed from a CPUFeatures*, or any
      // (non-local) object that implements `CPUFeatures* GetCPUFeatures()`.
      // Typically, this would be an Assembler or MacroAssembler, but
      // CPUFeatureScope itself provides this method, and allows the test to
      // remain architecture-agnostic.

      CPUFeatures auth(CPUFeatures::kPAuth,
                       CPUFeatures::kPAuthQARMA,
                       CPUFeatures::kPAuthGeneric,
                       CPUFeatures::kPAuthGenericQARMA);

      CPUFeaturesScope inner(&outer, auth);
      VIXL_CHECK(inner.GetCPUFeatures() == &cpu);
      VIXL_CHECK(cpu.Has(auth.With(CPUFeatures::kCRC32,
                                   CPUFeatures::kSHA1,
                                   CPUFeatures::kAtomics)));
    }
    // Check for equivalence.
    VIXL_CHECK(cpu.Has(original_inner));
    VIXL_CHECK(original_inner.Has(cpu));
  }

  // Check for equivalence.
  VIXL_CHECK(cpu.Has(original_outer));
  VIXL_CHECK(original_outer.Has(cpu));
}

TEST(CPUFeatures_infer_from_os) {
  // Test that CPUFeatures::InferFromOS functions on supported platforms.
  CPUFeatures os;
  VIXL_ASSERT(os.HasNoFeatures());
  os = CPUFeatures::InferFromOS();

  // Every real platform has FP and NEON. However, InferFromOS does not support
  // every platform, so we also have to tolerate empty results.
  if (os.HasNoFeatures()) {
    std::cout << "Warning: CPUFeatures::InferFromOS() returned no results.\n";
  } else {
    std::cout << "CPUFeatures::InferFromOS():\n  {" << os << "}\n";
    VIXL_CHECK(os.Has(CPUFeatures::kFP));
    VIXL_CHECK(os.Has(CPUFeatures::kNEON));
  }
}

TEST(CPUFeatures_infer_from_id_registers) {
  CPUFeatures os_only =
      CPUFeatures::InferFromOS(CPUFeatures::kDontQueryIDRegisters);
  std::cout << "CPUFeatures::InferFromOS(kDontQueryIDRegisters):\n  {"
            << os_only << "}\n";
  if (os_only.Has(CPUFeatures::kIDRegisterEmulation)) {
    CPUFeatures id_regs = CPUFeatures::InferFromIDRegisters();
    std::cout << "CPUFeatures::InferFromIDRegisters():\n  {" << id_regs
              << "}\n";
    // The ID registers should return at least as many features as the OS
    // information. This is intended to verify VIXL's InferFromIDRegisters
    // logic, but it also relies on the OS presenting consistent information.
    VIXL_CHECK(id_regs.Has(os_only));

    // The default InferFromOS should combine its results with
    // InferFromIDRegisters.
    CPUFeatures os_auto = CPUFeatures::InferFromOS();
    CPUFeatures os_with_id_regs = os_only.With(id_regs);
    // Check equivalence.
    VIXL_CHECK(os_auto.Has(os_with_id_regs));
    VIXL_CHECK(os_with_id_regs.Has(os_auto));
  } else {
    // Note: This message needs to match REGEXP_MISSING_FEATURES from
    // tools/threaded_test.py.
    std::cout << "SKIPPED: Missing features: { "
              << CPUFeatures::kIDRegisterEmulation << " }\n";
    std::cout << "This test requires the following features to run its "
                 "generated code on this CPU: "
              << CPUFeatures::kIDRegisterEmulation << "\n";
  }
}

}  // namespace vixl
