Merge v0.6.0 into master.

Adjust Android build system rules for recent changes in upstream
cpu_features.

Test: lunch aosp_arm-eng \
        && mmma external/cpu_features \
        && atest --test-mapping external/cpu_features:all
Test: lunch aosp_arm64-eng \
        && mmma external/cpu_features \
        && atest --test-mapping external/cpu_features:all
Test: lunch aosp_x86-eng \
        && mmma external/cpu_features \
        && atest --test-mapping external/cpu_features:all
Test: lunch aosp_x86_64-eng \
        && mmma external/cpu_features
Bug: 169921883
Bug: 128901000
Change-Id: I5fa712b4ea6e52f60128fb0c907a52cd894f34f1
diff --git a/.github/workflows/Dockerfile b/.github/workflows/Dockerfile
new file mode 100644
index 0000000..41dfc93
--- /dev/null
+++ b/.github/workflows/Dockerfile
@@ -0,0 +1,5 @@
+# Create a virtual environment with all tools installed
+# ref: https://hub.docker.com/_/alpine
+FROM alpine:edge
+# Install system build dependencies
+RUN apk add --no-cache git clang
diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml
new file mode 100644
index 0000000..17d1567
--- /dev/null
+++ b/.github/workflows/clang_format.yml
@@ -0,0 +1,24 @@
+name: clang-format Check
+
+on: [push, pull_request]
+
+jobs:
+  # Building using the github runner environement directly.
+  clang-format:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - name: Fetch origin/master
+      run: git fetch origin master
+    - name: List of changed file(s)
+      run: git diff --name-only FETCH_HEAD
+
+    - name: Build clang-format docker
+      run: cd .github/workflows && docker build --tag=linter .
+    - name: Check clang-format
+      run: docker run --rm --init -v $(pwd):/repo linter:latest clang-format --version
+    - name: clang-format help
+      run: docker run --rm --init -v $(pwd):/repo linter:latest clang-format --help
+
+    - name: Check current commit
+      run: docker run --rm --init -v $(pwd):/repo -w /repo linter:latest sh -c "git diff --diff-filter=d --name-only FETCH_HEAD | grep '\.c$\|\.h$\|\.cc$' | xargs clang-format --style=file --dry-run --Werror "
diff --git a/Android.bp b/Android.bp
index df66e37..a6d18b2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -34,11 +34,10 @@
 }
 
 cc_library {
-    name: "libcpu_features-unix_based_hardware_detection",
+    name: "libcpu_features-hwcaps",
     defaults: ["cpu_features-defaults"],
     srcs: [
         "src/hwcaps.c",
-        "src/unix_features_aggregator.c",
     ],
     cflags: [
         "-DHAVE_DLFCN_H",
@@ -74,7 +73,7 @@
                 "src/cpuinfo_arm.c",
             ],
             whole_static_libs: [
-                "libcpu_features-unix_based_hardware_detection",
+                "libcpu_features-hwcaps",
             ],
         },
         arm64: {
@@ -82,7 +81,7 @@
                 "src/cpuinfo_aarch64.c",
             ],
             whole_static_libs: [
-                "libcpu_features-unix_based_hardware_detection",
+                "libcpu_features-hwcaps",
             ],
             cflags: [
                 "-Wno-gnu-designator",
@@ -186,8 +185,10 @@
     defaults: ["cpu_features-test-defaults"],
     cflags: [
         "-DCPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL",
+        "-DCPU_FEATURES_TEST",
     ],
     srcs: [
+        "src/hwcaps.c",
         "test/hwcaps_for_testing.cc",
     ],
     static_libs: [
@@ -239,9 +240,6 @@
         "cpu_features-test-defaults",
         "stack_line_reader-defaults",
     ],
-    srcs: [
-        "src/unix_features_aggregator.c",
-    ],
     whole_static_libs: [
         "libcpu_features-filesystem_for_testing",
         "libcpu_features-hwcaps_for_testing",
@@ -290,17 +288,6 @@
 }
 
 cc_test {
-    name: "cpu_features-unix_features_aggregator_test",
-    defaults: ["cpu_features-test-defaults"],
-    srcs: [
-        "test/unix_features_aggregator_test.cc",
-    ],
-    static_libs: [
-        "libcpu_features-all_libraries",
-    ],
-}
-
-cc_test {
     name: "cpu_features-cpuinfo_test",
     defaults: [
         "cpu_features-test-defaults",
@@ -308,6 +295,9 @@
     static_libs: [
         "libcpu_features-all_libraries",
     ],
+    cflags: [
+        "-DSTACK_LINE_READER_BUFFER_SIZE=1024",
+    ],
     arch: {
         x86: {
             cflags: [
@@ -330,9 +320,6 @@
             ],
         },
         arm: {
-            cflags: [
-                "-DSTACK_LINE_READER_BUFFER_SIZE=1024",
-            ],
             srcs: [
                 "test/cpuinfo_arm_test.cc",
                 "src/cpuinfo_arm.c",
@@ -340,7 +327,6 @@
         },
         arm64: {
             cflags: [
-                "-DSTACK_LINE_READER_BUFFER_SIZE=1024",
                 "-Wno-gnu-designator",
             ],
             srcs: [
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 85102c7..f9daeac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@
   cmake_policy(SET CMP0077 NEW)
 endif()
 
-project(CpuFeatures VERSION 0.5.0 LANGUAGES C)
+project(CpuFeatures VERSION 0.6.0 LANGUAGES C)
 
 set(CMAKE_C_STANDARD 99)
 
@@ -22,8 +22,8 @@
 option(BUILD_TESTING "Enable test (depends on googletest)." OFF)
 # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
 # it prominent in the GUI.
-# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). 
-# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways. 
+# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field).
+# As a consequence it is discouraged to use cpu_features as a shared library because different compilers may interpret the code in different ways.
 # Prefer static linking from source whenever possible.
 option(BUILD_SHARED_LIBS "Build library as shared." OFF)
 # PIC
@@ -114,9 +114,7 @@
 if(UNIX)
   add_library(unix_based_hardware_detection OBJECT
     ${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h
-    ${PROJECT_SOURCE_DIR}/include/internal/unix_features_aggregator.h
     ${PROJECT_SOURCE_DIR}/src/hwcaps.c
-    ${PROJECT_SOURCE_DIR}/src/unix_features_aggregator.c
   )
   setup_include_and_definitions(unix_based_hardware_detection)
   check_include_file(dlfcn.h HAVE_DLFCN_H)
@@ -148,6 +146,11 @@
 target_include_directories(cpu_features
   PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
 )
+if(PROCESSOR_IS_X86)
+  if(APPLE)
+    target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
+  endif()
+endif()
 add_library(CpuFeature::cpu_features ALIAS cpu_features)
 
 #
@@ -175,11 +178,11 @@
   # Automatically incorporate googletest into the CMake Project if target not
   # found.
   enable_language(CXX)
-  
+
   set(CMAKE_CXX_STANDARD 11)
   set(CMAKE_CXX_STANDARD_REQUIRED ON)
   set(CMAKE_CXX_EXTENSIONS OFF) # prefer use of -std11 instead of -gnustd11
-  
+
   if(NOT TARGET gtest OR NOT TARGET gmock_main)
     # Download and unpack googletest at configure time.
     configure_file(
diff --git a/METADATA b/METADATA
index 728702c..5e2b871 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/google/cpu_features.git"
   }
-  version: "v0.5.0"
+  version: "v0.6.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 9
-    day: 22
+    month: 10
+    day: 15
   }
 }
diff --git a/README.md b/README.md
index cbd115a..8a34168 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,6 @@
 ### Running sample code
 
 Building `cpu_features` (check [quickstart](#quickstart) below) brings a small executable to test the library.
-.
 
 ```shell
  % ./build/list_cpu_features
@@ -185,7 +184,7 @@
 <a name="quickstart"></a>
 ### Quickstart with `Ninja`
 
- - build `list_cpu_features` 
+ - build `list_cpu_features`
 ```
     cmake -B/tmp/cpu_features -H. -GNinja -DCMAKE_BUILD_TYPE=Release
     ninja -C/tmp/cpu_features
@@ -197,5 +196,4 @@
     cmake -B/tmp/cpu_features -H. -GNinja -DBUILD_TESTING=ON
     ninja -C/tmp/cpu_features
     ninja -C/tmp/cpu_features test
-    
 ```
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 0af6ef9..824f432 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -22,13 +22,6 @@
       "name": "cpu_features-stack_line_reader_test"
     },
     {
-      "name": "cpu_features-unix_features_aggregator_test",
-      "host": true
-    },
-    {
-      "name": "cpu_features-unix_features_aggregator_test"
-    },
-    {
       "name": "cpu_features-cpuinfo_test",
       "host": true
     },
diff --git a/include/cpu_features_cache_info.h b/include/cpu_features_cache_info.h
index b7cc046..1a61ee1 100644
--- a/include/cpu_features_cache_info.h
+++ b/include/cpu_features_cache_info.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/cpu_features_macros.h b/include/cpu_features_macros.h
index fae9f70..4b231a1 100644
--- a/include/cpu_features_macros.h
+++ b/include/cpu_features_macros.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -79,6 +79,10 @@
 #define CPU_FEATURES_OS_WINDOWS
 #endif
 
+#if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__))
+#define CPU_FEATURES_OS_DARWIN
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Compilers
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/include/cpuinfo_aarch64.h b/include/cpuinfo_aarch64.h
index a42ecdf..d85d46d 100644
--- a/include/cpuinfo_aarch64.h
+++ b/include/cpuinfo_aarch64.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,62 +15,62 @@
 #ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
 #define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
 
-#include "cpu_features_macros.h"
 #include "cpu_features_cache_info.h"
+#include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
 
 typedef struct {
-  int fp : 1;         // Floating-point.
-  int asimd : 1;      // Advanced SIMD.
-  int evtstrm : 1;    // Generic timer generated events.
-  int aes : 1;        // Hardware-accelerated Advanced Encryption Standard.
-  int pmull : 1;      // Polynomial multiply long.
-  int sha1 : 1;       // Hardware-accelerated SHA1.
-  int sha2 : 1;       // Hardware-accelerated SHA2-256.
-  int crc32 : 1;      // Hardware-accelerated CRC-32.
-  int atomics : 1;    // Armv8.1 atomic instructions.
-  int fphp : 1;       // Half-precision floating point support.
-  int asimdhp : 1;    // Advanced SIMD half-precision support.
-  int cpuid : 1;      // Access to certain ID registers.
-  int asimdrdm : 1;   // Rounding Double Multiply Accumulate/Subtract.
-  int jscvt : 1;      // Support for JavaScript conversion.
-  int fcma : 1;       // Floating point complex numbers.
-  int lrcpc : 1;      // Support for weaker release consistency.
-  int dcpop : 1;      // Data persistence writeback.
-  int sha3 : 1;       // Hardware-accelerated SHA3.
-  int sm3 : 1;        // Hardware-accelerated SM3.
-  int sm4 : 1;        // Hardware-accelerated SM4.
-  int asimddp : 1;    // Dot product instruction.
-  int sha512 : 1;     // Hardware-accelerated SHA512.
-  int sve : 1;        // Scalable Vector Extension.
-  int asimdfhm : 1;   // Additional half-precision instructions.
-  int dit : 1;        // Data independent timing.
-  int uscat : 1;      // Unaligned atomics support.
-  int ilrcpc : 1;     // Additional support for weaker release consistency.
-  int flagm : 1;      // Flag manipulation instructions.
-  int ssbs : 1;       // Speculative Store Bypass Safe PSTATE bit.
-  int sb : 1;         // Speculation barrier.
-  int paca : 1;       // Address authentication.
-  int pacg : 1;       // Generic authentication.
-  int dcpodp : 1;     // Data cache clean to point of persistence.
-  int sve2 : 1;       // Scalable Vector Extension (version 2).
-  int sveaes : 1;     // SVE AES instructions.
-  int svepmull : 1;   // SVE polynomial multiply long instructions.
-  int svebitperm : 1; // SVE bit permute instructions.
-  int svesha3 : 1;    // SVE SHA3 instructions.
-  int svesm4 : 1;     // SVE SM4 instructions.
-  int flagm2 : 1;     // Additional flag manipulation instructions.
-  int frint : 1;      // Floating point to integer rounding.
-  int svei8mm : 1;    // SVE Int8 matrix multiplication instructions.
-  int svef32mm : 1;   // SVE FP32 matrix multiplication instruction.
-  int svef64mm : 1;   // SVE FP64 matrix multiplication instructions.
-  int svebf16 : 1;    // SVE BFloat16 instructions.
-  int i8mm : 1;       // Int8 matrix multiplication instructions.
-  int bf16 : 1;       // BFloat16 instructions.
-  int dgh : 1;        // Data Gathering Hint instruction.
-  int rng : 1;        // True random number generator support.
-  int bti : 1;        // Branch target identification.
+  int fp : 1;          // Floating-point.
+  int asimd : 1;       // Advanced SIMD.
+  int evtstrm : 1;     // Generic timer generated events.
+  int aes : 1;         // Hardware-accelerated Advanced Encryption Standard.
+  int pmull : 1;       // Polynomial multiply long.
+  int sha1 : 1;        // Hardware-accelerated SHA1.
+  int sha2 : 1;        // Hardware-accelerated SHA2-256.
+  int crc32 : 1;       // Hardware-accelerated CRC-32.
+  int atomics : 1;     // Armv8.1 atomic instructions.
+  int fphp : 1;        // Half-precision floating point support.
+  int asimdhp : 1;     // Advanced SIMD half-precision support.
+  int cpuid : 1;       // Access to certain ID registers.
+  int asimdrdm : 1;    // Rounding Double Multiply Accumulate/Subtract.
+  int jscvt : 1;       // Support for JavaScript conversion.
+  int fcma : 1;        // Floating point complex numbers.
+  int lrcpc : 1;       // Support for weaker release consistency.
+  int dcpop : 1;       // Data persistence writeback.
+  int sha3 : 1;        // Hardware-accelerated SHA3.
+  int sm3 : 1;         // Hardware-accelerated SM3.
+  int sm4 : 1;         // Hardware-accelerated SM4.
+  int asimddp : 1;     // Dot product instruction.
+  int sha512 : 1;      // Hardware-accelerated SHA512.
+  int sve : 1;         // Scalable Vector Extension.
+  int asimdfhm : 1;    // Additional half-precision instructions.
+  int dit : 1;         // Data independent timing.
+  int uscat : 1;       // Unaligned atomics support.
+  int ilrcpc : 1;      // Additional support for weaker release consistency.
+  int flagm : 1;       // Flag manipulation instructions.
+  int ssbs : 1;        // Speculative Store Bypass Safe PSTATE bit.
+  int sb : 1;          // Speculation barrier.
+  int paca : 1;        // Address authentication.
+  int pacg : 1;        // Generic authentication.
+  int dcpodp : 1;      // Data cache clean to point of persistence.
+  int sve2 : 1;        // Scalable Vector Extension (version 2).
+  int sveaes : 1;      // SVE AES instructions.
+  int svepmull : 1;    // SVE polynomial multiply long instructions.
+  int svebitperm : 1;  // SVE bit permute instructions.
+  int svesha3 : 1;     // SVE SHA3 instructions.
+  int svesm4 : 1;      // SVE SM4 instructions.
+  int flagm2 : 1;      // Additional flag manipulation instructions.
+  int frint : 1;       // Floating point to integer rounding.
+  int svei8mm : 1;     // SVE Int8 matrix multiplication instructions.
+  int svef32mm : 1;    // SVE FP32 matrix multiplication instruction.
+  int svef64mm : 1;    // SVE FP64 matrix multiplication instructions.
+  int svebf16 : 1;     // SVE BFloat16 instructions.
+  int i8mm : 1;        // Int8 matrix multiplication instructions.
+  int bf16 : 1;        // BFloat16 instructions.
+  int dgh : 1;         // Data Gathering Hint instruction.
+  int rng : 1;         // True random number generator support.
+  int bti : 1;         // Branch target identification.
 
   // Make sure to update Aarch64FeaturesEnum below if you add a field here.
 } Aarch64Features;
diff --git a/include/cpuinfo_arm.h b/include/cpuinfo_arm.h
index d15471f..0952d7c 100644
--- a/include/cpuinfo_arm.h
+++ b/include/cpuinfo_arm.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -16,8 +16,9 @@
 #define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
 
 #include <stdint.h>  // uint32_t
-#include "cpu_features_macros.h"
+
 #include "cpu_features_cache_info.h"
+#include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
 
@@ -25,30 +26,33 @@
   int swp : 1;       // SWP instruction (atomic read-modify-write)
   int half : 1;      // Half-word loads and stores
   int thumb : 1;     // Thumb (16-bit instruction set)
-  int _26bit : 1;    // "26 Bit" Model (Processor status register folded into program counter)
+  int _26bit : 1;    // "26 Bit" Model (Processor status register folded into
+                     // program counter)
   int fastmult : 1;  // 32x32->64-bit multiplication
   int fpa : 1;       // Floating point accelerator
   int vfp : 1;       // Vector Floating Point.
-  int edsp : 1;      // DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)
-  int java : 1;      // Jazelle (Java bytecode accelerator)
-  int iwmmxt : 1;    // Intel Wireless MMX Technology.
-  int crunch : 1;    // MaverickCrunch coprocessor
-  int thumbee : 1;   // ThumbEE
-  int neon : 1;      // Advanced SIMD.
-  int vfpv3 : 1;     // VFP version 3
+  int edsp : 1;     // DSP extensions (the 'e' variant of the ARM9 CPUs, and all
+                    // others above)
+  int java : 1;     // Jazelle (Java bytecode accelerator)
+  int iwmmxt : 1;   // Intel Wireless MMX Technology.
+  int crunch : 1;   // MaverickCrunch coprocessor
+  int thumbee : 1;  // ThumbEE
+  int neon : 1;     // Advanced SIMD.
+  int vfpv3 : 1;    // VFP version 3
   int vfpv3d16 : 1;  // VFP version 3 with 16 D-registers
   int tls : 1;       // TLS register
   int vfpv4 : 1;     // VFP version 4 with fast context switching
   int idiva : 1;     // SDIV and UDIV hardware division in ARM mode.
   int idivt : 1;     // SDIV and UDIV hardware division in Thumb mode.
   int vfpd32 : 1;    // VFP with 32 D-registers
-  int lpae : 1;      // Large Physical Address Extension (>4GB physical memory on 32-bit architecture)
-  int evtstrm : 1;   // kernel event stream using generic architected timer
-  int aes : 1;       // Hardware-accelerated Advanced Encryption Standard.
-  int pmull : 1;     // Polynomial multiply long.
-  int sha1 : 1;      // Hardware-accelerated SHA1.
-  int sha2 : 1;      // Hardware-accelerated SHA2-256.
-  int crc32 : 1;     // Hardware-accelerated CRC-32.
+  int lpae : 1;     // Large Physical Address Extension (>4GB physical memory on
+                    // 32-bit architecture)
+  int evtstrm : 1;  // kernel event stream using generic architected timer
+  int aes : 1;      // Hardware-accelerated Advanced Encryption Standard.
+  int pmull : 1;    // Polynomial multiply long.
+  int sha1 : 1;     // Hardware-accelerated SHA1.
+  int sha2 : 1;     // Hardware-accelerated SHA2-256.
+  int crc32 : 1;    // Hardware-accelerated CRC-32.
 
   // Make sure to update ArmFeaturesEnum below if you add a field here.
 } ArmFeatures;
diff --git a/include/cpuinfo_mips.h b/include/cpuinfo_mips.h
index d82ae85..9e5e7fc 100644
--- a/include/cpuinfo_mips.h
+++ b/include/cpuinfo_mips.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
 #ifndef CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
 #define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
 
-#include "cpu_features_macros.h"
 #include "cpu_features_cache_info.h"
+#include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
 
diff --git a/include/cpuinfo_ppc.h b/include/cpuinfo_ppc.h
index eaac7da..f691194 100644
--- a/include/cpuinfo_ppc.h
+++ b/include/cpuinfo_ppc.h
@@ -15,8 +15,8 @@
 #ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
 #define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
 
-#include "cpu_features_macros.h"
 #include "cpu_features_cache_info.h"
+#include "cpu_features_macros.h"
 #include "internal/hwcaps.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
diff --git a/include/cpuinfo_x86.h b/include/cpuinfo_x86.h
index c21a46a..8d40f71 100644
--- a/include/cpuinfo_x86.h
+++ b/include/cpuinfo_x86.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 // Copyright 2020 Intel Corporation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/include/internal/bit_utils.h b/include/internal/bit_utils.h
index bc965cb..3467ff9 100644
--- a/include/internal/bit_utils.h
+++ b/include/internal/bit_utils.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
 #include <assert.h>
 #include <stdbool.h>
 #include <stdint.h>
+
 #include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
diff --git a/include/internal/cpuid_x86.h b/include/internal/cpuid_x86.h
index 754ca38..33327a4 100644
--- a/include/internal/cpuid_x86.h
+++ b/include/internal/cpuid_x86.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -26,7 +26,8 @@
   uint32_t eax, ebx, ecx, edx;
 } Leaf;
 
-Leaf CpuIdEx(uint32_t leaf_id, int ecx);
+// Returns the result of a call to the cpuid instruction.
+Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx);
 
 // Returns the eax value of the XCR0 register.
 uint32_t GetXCR0Eax(void);
diff --git a/include/internal/filesystem.h b/include/internal/filesystem.h
index 3378881..d8f2f6a 100644
--- a/include/internal/filesystem.h
+++ b/include/internal/filesystem.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
 
 #include <stddef.h>
 #include <stdint.h>
+
 #include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
diff --git a/include/internal/hwcaps.h b/include/internal/hwcaps.h
index f0e91b3..62037c8 100644
--- a/include/internal/hwcaps.h
+++ b/include/internal/hwcaps.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,7 +17,9 @@
 #ifndef CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
 #define CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
 
+#include <stdbool.h>
 #include <stdint.h>
+
 #include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
@@ -169,6 +171,8 @@
 } HardwareCapabilities;
 
 HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
+bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
+                             const HardwareCapabilities hwcaps);
 
 typedef struct {
   char platform[64];       // 0 terminated string
diff --git a/include/internal/stack_line_reader.h b/include/internal/stack_line_reader.h
index c540f6b..39c1b8b 100644
--- a/include/internal/stack_line_reader.h
+++ b/include/internal/stack_line_reader.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/include/internal/string_view.h b/include/internal/string_view.h
index aa3779c..64fed40 100644
--- a/include/internal/string_view.h
+++ b/include/internal/string_view.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <string.h>
+
 #include "cpu_features_macros.h"
 
 CPU_FEATURES_START_CPP_NAMESPACE
diff --git a/include/internal/unix_features_aggregator.h b/include/internal/unix_features_aggregator.h
deleted file mode 100644
index bed668d..0000000
--- a/include/internal/unix_features_aggregator.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2017 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// CapabilityConfig provides a way to map cpu features to hardware caps and
-// /proc/cpuinfo flags. We then provide functions to update capabilities from
-// either source.
-#ifndef CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
-#define CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
-
-#include <ctype.h>
-#include <stdint.h>
-#include "cpu_features_macros.h"
-#include "internal/hwcaps.h"
-#include "internal/string_view.h"
-
-CPU_FEATURES_START_CPP_NAMESPACE
-
-// Use the following macro to declare setter functions to be used in
-// CapabilityConfig.
-#define DECLARE_SETTER(FeatureType, FeatureName)                    \
-  static void set_##FeatureName(void* const features, bool value) { \
-    ((FeatureType*)features)->FeatureName = value;                  \
-  }
-
-// Use the following macro to declare getter functions to be used in
-// CapabilityConfig.
-#define DECLARE_GETTER(FeatureType, FeatureName)                    \
-  static int get_##FeatureName(void* const features) {              \
-    return ((FeatureType*)features)->FeatureName;                   \
-  }
-
-#define DECLARE_SETTER_AND_GETTER(FeatureType, FeatureName)         \
-  DECLARE_SETTER(FeatureType, FeatureName)                          \
-  DECLARE_GETTER(FeatureType, FeatureName)
-
-// Describes the relationship between hardware caps and /proc/cpuinfo flags.
-typedef struct {
-  const HardwareCapabilities hwcaps_mask;
-  const char* const proc_cpuinfo_flag;
-  void (*set_bit)(void* const, bool);  // setter for the corresponding bit.
-  int (*get_bit)(void* const); // getter for the corresponding bit.
-} CapabilityConfig;
-
-// For every config, looks into flags_line for the presence of the
-// corresponding proc_cpuinfo_flag, calls `set_bit` accordingly.
-// Note: features is a pointer to the underlying Feature struct.
-void CpuFeatures_SetFromFlags(const size_t configs_size,
-                              const CapabilityConfig* configs,
-                              const StringView flags_line,
-                              void* const features);
-
-// For every config, looks into hwcaps for the presence of the feature. Calls
-// `set_bit` with true if the hardware capability is found.
-// Note: features is a pointer to the underlying Feature struct.
-void CpuFeatures_OverrideFromHwCaps(const size_t configs_size,
-                                    const CapabilityConfig* configs,
-                                    const HardwareCapabilities hwcaps,
-                                    void* const features);
-
-CPU_FEATURES_END_CPP_NAMESPACE
-#endif  // CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
diff --git a/ndk_compat/cpu-features.c b/ndk_compat/cpu-features.c
index ca49ac3..27ff7bb 100644
--- a/ndk_compat/cpu-features.c
+++ b/ndk_compat/cpu-features.c
@@ -1,11 +1,12 @@
 #include "cpu-features.h"
+
+#include <pthread.h>
+
 #include "cpu_features_macros.h"
 #include "internal/filesystem.h"
 #include "internal/stack_line_reader.h"
 #include "internal/string_view.h"
 
-#include <pthread.h>
-
 #if defined(CPU_FEATURES_ARCH_ARM)
 #include "cpuinfo_arm.h"
 #elif defined(CPU_FEATURES_ARCH_X86)
diff --git a/ndk_compat/ndk-compat-test.c b/ndk_compat/ndk-compat-test.c
index 782dbbf..e4005d4 100644
--- a/ndk_compat/ndk-compat-test.c
+++ b/ndk_compat/ndk-compat-test.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+
 #include "cpu-features.h"
 
 int main() {
diff --git a/src/cpuinfo_aarch64.c b/src/cpuinfo_aarch64.c
index 6cd5308..0a52718 100644
--- a/src/cpuinfo_aarch64.c
+++ b/src/cpuinfo_aarch64.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,120 +14,70 @@
 
 #include "cpuinfo_aarch64.h"
 
+#include <assert.h>
+#include <ctype.h>
+
 #include "internal/filesystem.h"
 #include "internal/hwcaps.h"
 #include "internal/stack_line_reader.h"
 #include "internal/string_view.h"
-#include "internal/unix_features_aggregator.h"
 
-#include <assert.h>
-#include <ctype.h>
-
-DECLARE_SETTER_AND_GETTER(Aarch64Features, fp)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, asimd)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, evtstrm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, aes)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, pmull)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sha1)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sha2)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, crc32)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, atomics)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, fphp)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, asimdhp)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, cpuid)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, asimdrdm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, jscvt)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, fcma)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, lrcpc)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, dcpop)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sha3)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sm3)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sm4)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, asimddp)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sha512)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sve)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, asimdfhm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, dit)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, uscat)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, ilrcpc)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, flagm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, ssbs)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sb)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, paca)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, pacg)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, dcpodp)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sve2)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, sveaes)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svepmull)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svebitperm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svesha3)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svesm4)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, flagm2)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, frint)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svei8mm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svef32mm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svef64mm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, svebf16)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, i8mm)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, bf16)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, dgh)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, rng)
-DECLARE_SETTER_AND_GETTER(Aarch64Features, bti)
-
-static const CapabilityConfig kConfigs[] = {
-  [AARCH64_FP] = {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp, &get_fp},
-  [AARCH64_ASIMD] = {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd, &get_asimd},
-  [AARCH64_EVTSTRM] = {{AARCH64_HWCAP_EVTSTRM, 0}, "evtstrm", &set_evtstrm, &get_evtstrm},
-  [AARCH64_AES] = {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes, &get_aes},
-  [AARCH64_PMULL] = {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull, &get_pmull},
-  [AARCH64_SHA1] = {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1, &get_sha1},
-  [AARCH64_SHA2] = {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2, &get_sha2},
-  [AARCH64_CRC32] = {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32, &get_crc32},
-  [AARCH64_ATOMICS] = {{AARCH64_HWCAP_ATOMICS, 0}, "atomics", &set_atomics, &get_atomics},
-  [AARCH64_FPHP] = {{AARCH64_HWCAP_FPHP, 0}, "fphp", &set_fphp, &get_fphp},
-  [AARCH64_ASIMDHP] = {{AARCH64_HWCAP_ASIMDHP, 0}, "asimdhp", &set_asimdhp, &get_asimdhp},
-  [AARCH64_CPUID] = {{AARCH64_HWCAP_CPUID, 0}, "cpuid", &set_cpuid, &get_cpuid},
-  [AARCH64_ASIMDRDM] = {{AARCH64_HWCAP_ASIMDRDM, 0}, "asimdrdm", &set_asimdrdm, &get_asimdrdm},
-  [AARCH64_JSCVT] = {{AARCH64_HWCAP_JSCVT, 0}, "jscvt", &set_jscvt, &get_jscvt},
-  [AARCH64_FCMA] = {{AARCH64_HWCAP_FCMA, 0}, "fcma", &set_fcma, &get_fcma},
-  [AARCH64_LRCPC] = {{AARCH64_HWCAP_LRCPC, 0}, "lrcpc", &set_lrcpc, &get_lrcpc},
-  [AARCH64_DCPOP] = {{AARCH64_HWCAP_DCPOP, 0}, "dcpop", &set_dcpop, &get_dcpop},
-  [AARCH64_SHA3] = {{AARCH64_HWCAP_SHA3, 0}, "sha3", &set_sha3, &get_sha3},
-  [AARCH64_SM3] = {{AARCH64_HWCAP_SM3, 0}, "sm3", &set_sm3, &get_sm3},
-  [AARCH64_SM4] = {{AARCH64_HWCAP_SM4, 0}, "sm4", &set_sm4, &get_sm4},
-  [AARCH64_ASIMDDP] = {{AARCH64_HWCAP_ASIMDDP, 0}, "asimddp", &set_asimddp, &get_asimddp},
-  [AARCH64_SHA512] = {{AARCH64_HWCAP_SHA512, 0}, "sha512", &set_sha512, &get_sha512},
-  [AARCH64_SVE] = {{AARCH64_HWCAP_SVE, 0}, "sve", &set_sve, &get_sve},
-  [AARCH64_ASIMDFHM] = {{AARCH64_HWCAP_ASIMDFHM, 0}, "asimdfhm", &set_asimdfhm, &get_asimdfhm},
-  [AARCH64_DIT] = {{AARCH64_HWCAP_DIT, 0}, "dit", &set_dit, &get_dit},
-  [AARCH64_USCAT] = {{AARCH64_HWCAP_USCAT, 0}, "uscat", &set_uscat, &get_uscat},
-  [AARCH64_ILRCPC] = {{AARCH64_HWCAP_ILRCPC, 0}, "ilrcpc", &set_ilrcpc, &get_ilrcpc},
-  [AARCH64_FLAGM] = {{AARCH64_HWCAP_FLAGM, 0}, "flagm", &set_flagm, &get_flagm},
-  [AARCH64_SSBS] = {{AARCH64_HWCAP_SSBS, 0}, "ssbs", &set_ssbs, &get_ssbs},
-  [AARCH64_SB] = {{AARCH64_HWCAP_SB, 0}, "sb", &set_sb, &get_sb},
-  [AARCH64_PACA] = {{AARCH64_HWCAP_PACA, 0}, "paca", &set_paca, &get_paca},
-  [AARCH64_PACG] = {{AARCH64_HWCAP_PACG, 0}, "pacg", &set_pacg, &get_pacg},
-  [AARCH64_DCPODP] = {{0, AARCH64_HWCAP2_DCPODP}, "dcpodp", &set_dcpodp, &get_dcpodp},
-  [AARCH64_SVE2] = {{0, AARCH64_HWCAP2_SVE2}, "sve2", &set_sve2, &get_sve2},
-  [AARCH64_SVEAES] = {{0, AARCH64_HWCAP2_SVEAES}, "sveaes", &set_sveaes, &get_sveaes},
-  [AARCH64_SVEPMULL] = {{0, AARCH64_HWCAP2_SVEPMULL}, "svepmull", &set_svepmull, &get_svepmull},
-  [AARCH64_SVEBITPERM] = {{0, AARCH64_HWCAP2_SVEBITPERM}, "svebitperm", &set_svebitperm, &get_svebitperm},
-  [AARCH64_SVESHA3] = {{0, AARCH64_HWCAP2_SVESHA3}, "svesha3", &set_svesha3, &get_svesha3},
-  [AARCH64_SVESM4] = {{0, AARCH64_HWCAP2_SVESM4}, "svesm4", &set_svesm4, &get_svesm4},
-  [AARCH64_FLAGM2] = {{0, AARCH64_HWCAP2_FLAGM2}, "flagm2", &set_flagm2, &get_flagm2},
-  [AARCH64_FRINT] = {{0, AARCH64_HWCAP2_FRINT}, "frint", &set_frint, &get_frint},
-  [AARCH64_SVEI8MM] = {{0, AARCH64_HWCAP2_SVEI8MM}, "svei8mm", &set_svei8mm, &get_svei8mm},
-  [AARCH64_SVEF32MM] = {{0, AARCH64_HWCAP2_SVEF32MM}, "svef32mm", &set_svef32mm, &get_svef32mm},
-  [AARCH64_SVEF64MM] = {{0, AARCH64_HWCAP2_SVEF64MM}, "svef64mm", &set_svef64mm, &get_svef64mm},
-  [AARCH64_SVEBF16] = {{0, AARCH64_HWCAP2_SVEBF16}, "svebf16", &set_svebf16, &get_svebf16},
-  [AARCH64_I8MM] = {{0, AARCH64_HWCAP2_I8MM}, "i8mm", &set_i8mm, &get_i8mm},
-  [AARCH64_BF16] = {{0, AARCH64_HWCAP2_BF16}, "bf16", &set_bf16, &get_bf16},
-  [AARCH64_DGH] = {{0, AARCH64_HWCAP2_DGH}, "dgh", &set_dgh, &get_dgh},
-  [AARCH64_RNG] = {{0, AARCH64_HWCAP2_RNG}, "rng", &set_rng, &get_rng},
-  [AARCH64_BTI] = {{0, AARCH64_HWCAP2_BTI}, "bti", &set_bti, &get_bti},
-};
-
-static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);
+// Generation of feature's getters/setters functions and kGetters, kSetters,
+// kCpuInfoFlags and kHardwareCapabilities global tables.
+#define DEFINE_TABLE_FEATURES                                                 \
+  FEATURE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0)                          \
+  FEATURE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0)              \
+  FEATURE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0)      \
+  FEATURE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0)                      \
+  FEATURE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0)              \
+  FEATURE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0)                  \
+  FEATURE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0)                  \
+  FEATURE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0)              \
+  FEATURE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0)      \
+  FEATURE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0)                  \
+  FEATURE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0)      \
+  FEATURE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0)              \
+  FEATURE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0)  \
+  FEATURE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0)              \
+  FEATURE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0)                  \
+  FEATURE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0)              \
+  FEATURE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0)              \
+  FEATURE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0)                  \
+  FEATURE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0)                      \
+  FEATURE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0)                      \
+  FEATURE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0)      \
+  FEATURE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0)          \
+  FEATURE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0)                      \
+  FEATURE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0)  \
+  FEATURE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0)                      \
+  FEATURE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0)              \
+  FEATURE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0)          \
+  FEATURE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0)              \
+  FEATURE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0)                  \
+  FEATURE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0)                          \
+  FEATURE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0)                  \
+  FEATURE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0)                  \
+  FEATURE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP)         \
+  FEATURE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2)                 \
+  FEATURE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES)         \
+  FEATURE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \
+  FEATURE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0,                    \
+          AARCH64_HWCAP2_SVEBITPERM)                                          \
+  FEATURE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3)     \
+  FEATURE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4)         \
+  FEATURE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2)         \
+  FEATURE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT)             \
+  FEATURE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM)     \
+  FEATURE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \
+  FEATURE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \
+  FEATURE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16)     \
+  FEATURE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM)                 \
+  FEATURE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16)                 \
+  FEATURE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH)                     \
+  FEATURE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG)                     \
+  FEATURE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI)
+#define DEFINE_TABLE_FEATURE_TYPE Aarch64Features
+#include "define_tables.h"
 
 static bool HandleAarch64Line(const LineResult result,
                               Aarch64Info* const info) {
@@ -135,7 +85,10 @@
   StringView key, value;
   if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
     if (CpuFeatures_StringView_IsEquals(key, str("Features"))) {
-      CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features);
+      for (size_t i = 0; i < AARCH64_LAST_; ++i) {
+        kSetters[i](&info->features,
+                    CpuFeatures_StringView_HasWord(value, kCpuInfoFlags[i]));
+      }
     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) {
       info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value);
     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) {
@@ -166,17 +119,18 @@
 static const Aarch64Info kEmptyAarch64Info;
 
 Aarch64Info GetAarch64Info(void) {
-  assert(kConfigsSize == AARCH64_LAST_);
-
   // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
   // have some information if the executable is sandboxed (aka no access to
   // /proc/cpuinfo).
   Aarch64Info info = kEmptyAarch64Info;
 
   FillProcCpuInfoData(&info);
-  CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
-                                 CpuFeatures_GetHardwareCapabilities(),
-                                 &info.features);
+  const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
+  for (size_t i = 0; i < AARCH64_LAST_; ++i) {
+    if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
+      kSetters[i](&info.features, true);
+    }
+  }
 
   return info;
 }
@@ -186,13 +140,11 @@
 
 int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
                                 Aarch64FeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return false;
-  return kConfigs[value].get_bit((Aarch64Features*)features);
+  if (value >= AARCH64_LAST_) return false;
+  return kGetters[value](features);
 }
 
 const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return "unknown feature";
-  return kConfigs[value].proc_cpuinfo_flag;
+  if (value >= AARCH64_LAST_) return "unknown feature";
+  return kCpuInfoFlags[value];
 }
diff --git a/src/cpuinfo_arm.c b/src/cpuinfo_arm.c
index 741c99a..0f216bf 100644
--- a/src/cpuinfo_arm.c
+++ b/src/cpuinfo_arm.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,75 +14,47 @@
 
 #include "cpuinfo_arm.h"
 
+#include <assert.h>
+#include <ctype.h>
+
 #include "internal/bit_utils.h"
 #include "internal/filesystem.h"
 #include "internal/hwcaps.h"
 #include "internal/stack_line_reader.h"
 #include "internal/string_view.h"
-#include "internal/unix_features_aggregator.h"
 
-#include <assert.h>
-#include <ctype.h>
-
-DECLARE_SETTER_AND_GETTER(ArmFeatures, swp)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, half)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, thumb)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, _26bit)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, fastmult)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, fpa)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, vfp)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, edsp)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, java)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, iwmmxt)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, crunch)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, thumbee)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, neon)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, vfpv3)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, vfpv3d16)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, tls)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, vfpv4)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, idiva)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, idivt)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, vfpd32)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, lpae)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, evtstrm)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, aes)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, pmull)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, sha1)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, sha2)
-DECLARE_SETTER_AND_GETTER(ArmFeatures, crc32)
-
-static const CapabilityConfig kConfigs[] = {
-  [ARM_SWP] = {{ARM_HWCAP_SWP, 0}, "swp", &set_swp, &get_swp},                           //
-  [ARM_HALF] = {{ARM_HWCAP_HALF, 0}, "half", &set_half, &get_half},                      //
-  [ARM_THUMB] = {{ARM_HWCAP_THUMB, 0}, "thumb", &set_thumb, &get_thumb},                 //
-  [ARM_26BIT] = {{ARM_HWCAP_26BIT, 0}, "26bit", &set__26bit, &get__26bit},               //
-  [ARM_FASTMULT] = {{ARM_HWCAP_FAST_MULT, 0}, "fastmult", &set_fastmult, &get_fastmult}, //
-  [ARM_FPA] = {{ARM_HWCAP_FPA, 0}, "fpa", &set_fpa, &get_fpa},                           //
-  [ARM_VFP] = {{ARM_HWCAP_VFP, 0}, "vfp", &set_vfp, &get_vfp},                           //
-  [ARM_EDSP] = {{ARM_HWCAP_EDSP, 0}, "edsp", &set_edsp, &get_edsp},                      //
-  [ARM_JAVA] = {{ARM_HWCAP_JAVA, 0}, "java", &set_java, &get_java},                      //
-  [ARM_IWMMXT] = {{ARM_HWCAP_IWMMXT, 0}, "iwmmxt", &set_iwmmxt, &get_iwmmxt},            //
-  [ARM_CRUNCH] = {{ARM_HWCAP_CRUNCH, 0}, "crunch", &set_crunch, &get_crunch},            //
-  [ARM_THUMBEE] = {{ARM_HWCAP_THUMBEE, 0}, "thumbee", &set_thumbee, &get_thumbee},       //
-  [ARM_NEON] = {{ARM_HWCAP_NEON, 0}, "neon", &set_neon, &get_neon},                      //
-  [ARM_VFPV3] = {{ARM_HWCAP_VFPV3, 0}, "vfpv3", &set_vfpv3, &get_vfpv3},                 //
-  [ARM_VFPV3D16] = {{ARM_HWCAP_VFPV3D16, 0}, "vfpv3d16", &set_vfpv3d16, &get_vfpv3d16},  //
-  [ARM_TLS] = {{ARM_HWCAP_TLS, 0}, "tls", &set_tls, &get_tls},                           //
-  [ARM_VFPV4] = {{ARM_HWCAP_VFPV4, 0}, "vfpv4", &set_vfpv4, &get_vfpv4},                 //
-  [ARM_IDIVA] = {{ARM_HWCAP_IDIVA, 0}, "idiva", &set_idiva, &get_idiva},                 //
-  [ARM_IDIVT] = {{ARM_HWCAP_IDIVT, 0}, "idivt", &set_idivt, &get_idivt},                 //
-  [ARM_VFPD32] = {{ARM_HWCAP_VFPD32, 0}, "vfpd32", &set_vfpd32, &get_vfpd32},            //
-  [ARM_LPAE] = {{ARM_HWCAP_LPAE, 0}, "lpae", &set_lpae, &get_lpae},                      //
-  [ARM_EVTSTRM] = {{ARM_HWCAP_EVTSTRM, 0}, "evtstrm", &set_evtstrm, &get_evtstrm},       //
-  [ARM_AES] = {{0, ARM_HWCAP2_AES}, "aes", &set_aes, &get_aes},                          //
-  [ARM_PMULL] = {{0, ARM_HWCAP2_PMULL}, "pmull", &set_pmull, &get_pmull},                //
-  [ARM_SHA1] = {{0, ARM_HWCAP2_SHA1}, "sha1", &set_sha1, &get_sha1},                     //
-  [ARM_SHA2] = {{0, ARM_HWCAP2_SHA2}, "sha2", &set_sha2, &get_sha2},                     //
-  [ARM_CRC32] = {{0, ARM_HWCAP2_CRC32}, "crc32", &set_crc32, &get_crc32},                //
-};
-
-static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);
+// Generation of feature's getters/setters functions and kGetters, kSetters,
+// kCpuInfoFlags and kHardwareCapabilities global tables.
+#define DEFINE_TABLE_FEATURES                                         \
+  FEATURE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0)                      \
+  FEATURE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0)                  \
+  FEATURE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0)              \
+  FEATURE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0)             \
+  FEATURE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \
+  FEATURE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0)                      \
+  FEATURE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0)                      \
+  FEATURE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0)                  \
+  FEATURE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0)                  \
+  FEATURE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0)          \
+  FEATURE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0)          \
+  FEATURE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0)      \
+  FEATURE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0)                  \
+  FEATURE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0)              \
+  FEATURE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0)  \
+  FEATURE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0)                      \
+  FEATURE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0)              \
+  FEATURE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0)              \
+  FEATURE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0)              \
+  FEATURE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0)          \
+  FEATURE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0)                  \
+  FEATURE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0)      \
+  FEATURE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES)                     \
+  FEATURE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL)             \
+  FEATURE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1)                 \
+  FEATURE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2)                 \
+  FEATURE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32)
+#define DEFINE_TABLE_FEATURE_TYPE ArmFeatures
+#include "define_tables.h"
 
 typedef struct {
   bool processor_reports_armv6;
@@ -104,7 +76,10 @@
   StringView key, value;
   if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
     if (CpuFeatures_StringView_IsEquals(key, str("Features"))) {
-      CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features);
+      for (size_t i = 0; i < ARM_LAST_; ++i) {
+        kSetters[i](&info->features,
+                    CpuFeatures_StringView_HasWord(value, kCpuInfoFlags[i]));
+      }
     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) {
       info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value);
     } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) {
@@ -119,8 +94,8 @@
       const StringView digits =
           CpuFeatures_StringView_KeepFront(value, IndexOfNonDigit(value));
       info->architecture = CpuFeatures_StringView_ParsePositiveNumber(digits);
-    } else if (CpuFeatures_StringView_IsEquals(key, str("Processor"))
-               || CpuFeatures_StringView_IsEquals(key, str("model name")) ) {
+    } else if (CpuFeatures_StringView_IsEquals(key, str("Processor")) ||
+               CpuFeatures_StringView_IsEquals(key, str("model name"))) {
       // Android reports this in a non-Linux standard "Processor" but sometimes
       // also in "model name", Linux reports it only in "model name"
       // see RaspberryPiZero (Linux) vs InvalidArmv7 (Android) test-cases
@@ -210,9 +185,12 @@
   ProcCpuInfoData proc_cpu_info_data = kEmptyProcCpuInfoData;
 
   FillProcCpuInfoData(&info, &proc_cpu_info_data);
-  CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
-                                 CpuFeatures_GetHardwareCapabilities(),
-                                 &info.features);
+  const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
+  for (size_t i = 0; i < ARM_LAST_; ++i) {
+    if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
+      kSetters[i](&info.features, true);
+    }
+  }
 
   FixErrors(&info, &proc_cpu_info_data);
 
@@ -224,13 +202,11 @@
 
 int GetArmFeaturesEnumValue(const ArmFeatures* features,
                             ArmFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return false;
-  return kConfigs[value].get_bit((ArmFeatures*)features);
+  if (value >= ARM_LAST_) return false;
+  return kGetters[value](features);
 }
 
 const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return "unknown feature";
-  return kConfigs[value].proc_cpuinfo_flag;
+  if (value >= ARM_LAST_) return "unknown feature";
+  return kCpuInfoFlags[value];
 }
diff --git a/src/cpuinfo_mips.c b/src/cpuinfo_mips.c
index 0564bb8..83e959f 100644
--- a/src/cpuinfo_mips.c
+++ b/src/cpuinfo_mips.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,23 +14,21 @@
 
 #include "cpuinfo_mips.h"
 
-#include "internal/filesystem.h"
-#include "internal/stack_line_reader.h"
-#include "internal/string_view.h"
-#include "internal/unix_features_aggregator.h"
-
 #include <assert.h>
 
-DECLARE_SETTER_AND_GETTER(MipsFeatures, msa)
-DECLARE_SETTER_AND_GETTER(MipsFeatures, eva)
-DECLARE_SETTER_AND_GETTER(MipsFeatures, r6)
+#include "internal/filesystem.h"
+#include "internal/hwcaps.h"
+#include "internal/stack_line_reader.h"
+#include "internal/string_view.h"
 
-static const CapabilityConfig kConfigs[] = {
-  [MIPS_MSA] = {{MIPS_HWCAP_MSA, 0}, "msa", &set_msa, &get_msa},  //
-  [MIPS_EVA] = {{0, 0}, "eva", &set_eva, &get_eva},               //
-  [MIPS_R6] = {{MIPS_HWCAP_R6, 0}, "r6", &set_r6, &get_r6},       //
-};
-static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);
+// Generation of feature's getters/setters functions and kGetters, kSetters,
+// kCpuInfoFlags and kHardwareCapabilities global tables.
+#define DEFINE_TABLE_FEATURES                      \
+  FEATURE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \
+  FEATURE(MIPS_EVA, eva, "eva", 0, 0)              \
+  FEATURE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0)
+#define DEFINE_TABLE_FEATURE_TYPE MipsFeatures
+#include "define_tables.h"
 
 static bool HandleMipsLine(const LineResult result,
                            MipsFeatures* const features) {
@@ -38,7 +36,10 @@
   // See tests for an example.
   if (CpuFeatures_StringView_GetAttributeKeyValue(result.line, &key, &value)) {
     if (CpuFeatures_StringView_IsEquals(key, str("ASEs implemented"))) {
-      CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, features);
+      for (size_t i = 0; i < MIPS_LAST_; ++i) {
+        kSetters[i](features,
+                    CpuFeatures_StringView_HasWord(value, kCpuInfoFlags[i]));
+      }
     }
   }
   return !result.eof;
@@ -61,17 +62,18 @@
 static const MipsInfo kEmptyMipsInfo;
 
 MipsInfo GetMipsInfo(void) {
-  assert(kConfigsSize == MIPS_LAST_);
-
   // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
   // have some information if the executable is sandboxed (aka no access to
   // /proc/cpuinfo).
   MipsInfo info = kEmptyMipsInfo;
 
   FillProcCpuInfoData(&info.features);
-  CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
-                                 CpuFeatures_GetHardwareCapabilities(),
-                                 &info.features);
+  const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
+  for (size_t i = 0; i < MIPS_LAST_; ++i) {
+    if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
+      kSetters[i](&info.features, true);
+    }
+  }
   return info;
 }
 
@@ -80,13 +82,11 @@
 
 int GetMipsFeaturesEnumValue(const MipsFeatures* features,
                              MipsFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return false;
-  return kConfigs[value].get_bit((MipsFeatures*)features);
+  if (value >= MIPS_LAST_) return false;
+  return kGetters[value](features);
 }
 
 const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return "unknown feature";
-  return kConfigs[value].proc_cpuinfo_flag;
+  if (value >= MIPS_LAST_) return "unknown feature";
+  return kCpuInfoFlags[value];
 }
diff --git a/src/cpuinfo_ppc.c b/src/cpuinfo_ppc.c
index c088f86..24401f9 100644
--- a/src/cpuinfo_ppc.c
+++ b/src/cpuinfo_ppc.c
@@ -12,105 +12,69 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "cpuinfo_ppc.h"
+
 #include <assert.h>
 #include <stdbool.h>
 #include <string.h>
 
-#include "cpuinfo_ppc.h"
 #include "internal/bit_utils.h"
 #include "internal/filesystem.h"
 #include "internal/stack_line_reader.h"
 #include "internal/string_view.h"
-#include "internal/unix_features_aggregator.h"
 
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ppc32)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ppc64)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ppc601)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, altivec)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, fpu)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, mmu)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, mac_4xx)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, unifiedcache)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, spe)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, efpsingle)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, efpdouble)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, no_tb)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, power4)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, power5)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, power5plus)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, cell)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, booke)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, smt)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, icachesnoop)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, arch205)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, pa6t)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, dfp)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, power6ext)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, arch206)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, vsx)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, pseries_perfmon_compat)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, truele)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ppcle)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, arch207)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, htm)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, dscr)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ebb)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, isel)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, tar)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, vcrypto)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, htm_nosc)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, arch300)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, ieee128)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, darn)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, scv)
-DECLARE_SETTER_AND_GETTER(PPCFeatures, htm_no_suspend)
-
-static const CapabilityConfig kConfigs[] = {
-  [PPC_32] = {{PPC_FEATURE_32, 0}, "ppc32", &set_ppc32, &get_ppc32},
-  [PPC_64] = {{PPC_FEATURE_64, 0}, "ppc64", &set_ppc64, &get_ppc64},
-  [PPC_601_INSTR] = {{PPC_FEATURE_601_INSTR, 0}, "ppc601", &set_ppc601, &get_ppc601},
-  [PPC_HAS_ALTIVEC] = {{PPC_FEATURE_HAS_ALTIVEC, 0}, "altivec", &set_altivec, &get_altivec},
-  [PPC_HAS_FPU] = {{PPC_FEATURE_HAS_FPU, 0}, "fpu", &set_fpu, &get_fpu},
-  [PPC_HAS_MMU] = {{PPC_FEATURE_HAS_MMU, 0}, "mmu", &set_mmu, &get_mmu},
-  [PPC_HAS_4xxMAC] = {{PPC_FEATURE_HAS_4xxMAC, 0}, "4xxmac", &set_mac_4xx, &get_mac_4xx},
-  [PPC_UNIFIED_CACHE] = {{PPC_FEATURE_UNIFIED_CACHE, 0}, "ucache", &set_unifiedcache, &get_unifiedcache},
-  [PPC_HAS_SPE] = {{PPC_FEATURE_HAS_SPE, 0}, "spe", &set_spe, &get_spe},
-  [PPC_HAS_EFP_SINGLE] = {{PPC_FEATURE_HAS_EFP_SINGLE, 0}, "efpsingle", &set_efpsingle, &get_efpsingle},
-  [PPC_HAS_EFP_DOUBLE] = {{PPC_FEATURE_HAS_EFP_DOUBLE, 0}, "efpdouble", &set_efpdouble, &get_efpdouble},
-  [PPC_NO_TB] = {{PPC_FEATURE_NO_TB, 0}, "notb", &set_no_tb, &get_no_tb},
-  [PPC_POWER4] = {{PPC_FEATURE_POWER4, 0}, "power4", &set_power4, &get_power4},
-  [PPC_POWER5] = {{PPC_FEATURE_POWER5, 0}, "power5", &set_power5, &get_power5},
-  [PPC_POWER5_PLUS] = {{PPC_FEATURE_POWER5_PLUS, 0}, "power5+", &set_power5plus, &get_power5plus},
-  [PPC_CELL] = {{PPC_FEATURE_CELL, 0}, "cellbe", &set_cell, &get_cell},
-  [PPC_BOOKE] = {{PPC_FEATURE_BOOKE, 0}, "booke", &set_booke, &get_booke},
-  [PPC_SMT] = {{PPC_FEATURE_SMT, 0}, "smt", &set_smt, &get_smt},
-  [PPC_ICACHE_SNOOP] = {{PPC_FEATURE_ICACHE_SNOOP, 0}, "ic_snoop", &set_icachesnoop, &get_icachesnoop},
-  [PPC_ARCH_2_05] = {{PPC_FEATURE_ARCH_2_05, 0}, "arch_2_05", &set_arch205, &get_arch205},
-  [PPC_PA6T] = {{PPC_FEATURE_PA6T, 0}, "pa6t", &set_pa6t, &get_pa6t},
-  [PPC_HAS_DFP] = {{PPC_FEATURE_HAS_DFP, 0}, "dfp", &set_dfp, &get_dfp},
-  [PPC_POWER6_EXT] = {{PPC_FEATURE_POWER6_EXT, 0}, "power6x", &set_power6ext, &get_power6ext},
-  [PPC_ARCH_2_06] = {{PPC_FEATURE_ARCH_2_06, 0}, "arch_2_06", &set_arch206, &get_arch206},
-  [PPC_HAS_VSX] = {{PPC_FEATURE_HAS_VSX, 0}, "vsx", &set_vsx, &get_vsx},
-  [PPC_PSERIES_PERFMON_COMPAT] = {{PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0}, "archpmu",
-     &set_pseries_perfmon_compat, &get_pseries_perfmon_compat},
-  [PPC_TRUE_LE] = {{PPC_FEATURE_TRUE_LE, 0}, "true_le", &set_truele, &get_truele},
-  [PPC_PPC_LE] = {{PPC_FEATURE_PPC_LE, 0}, "ppcle", &set_ppcle, &get_ppcle},
-  [PPC_ARCH_2_07] = {{0, PPC_FEATURE2_ARCH_2_07}, "arch_2_07", &set_arch207, &get_arch207},
-  [PPC_HTM] = {{0, PPC_FEATURE2_HTM}, "htm", &set_htm, &get_htm},
-  [PPC_DSCR] = {{0, PPC_FEATURE2_DSCR}, "dscr", &set_dscr, &get_dscr},
-  [PPC_EBB] = {{0, PPC_FEATURE2_EBB}, "ebb", &set_ebb, &get_ebb},
-  [PPC_ISEL] = {{0, PPC_FEATURE2_ISEL}, "isel", &set_isel, &get_isel},
-  [PPC_TAR] = {{0, PPC_FEATURE2_TAR}, "tar", &set_tar, &get_tar},
-  [PPC_VEC_CRYPTO] = {{0, PPC_FEATURE2_VEC_CRYPTO}, "vcrypto", &set_vcrypto, &get_vcrypto},
-  [PPC_HTM_NOSC] = {{0, PPC_FEATURE2_HTM_NOSC}, "htm-nosc", &set_htm_nosc, &get_htm_nosc},
-  [PPC_ARCH_3_00] = {{0, PPC_FEATURE2_ARCH_3_00}, "arch_3_00", &set_arch300, &get_arch300},
-  [PPC_HAS_IEEE128] = {{0, PPC_FEATURE2_HAS_IEEE128}, "ieee128", &set_ieee128, &get_ieee128},
-  [PPC_DARN] = {{0, PPC_FEATURE2_DARN}, "darn", &set_darn, &get_darn},
-  [PPC_SCV] = {{0, PPC_FEATURE2_SCV}, "scv", &set_scv, &get_scv},
-  [PPC_HTM_NO_SUSPEND] = {{0, PPC_FEATURE2_HTM_NO_SUSPEND}, "htm-no-suspend", &set_htm_no_suspend,
-     &get_htm_no_suspend},
-};
-static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);
+// Generation of feature's getters/setters functions and kGetters, kSetters,
+// kCpuInfoFlags and kHardwareCapabilities global tables.
+#define DEFINE_TABLE_FEATURES                                                  \
+  FEATURE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0)                           \
+  FEATURE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0)                           \
+  FEATURE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0)           \
+  FEATURE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0)     \
+  FEATURE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0)                     \
+  FEATURE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0)                     \
+  FEATURE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0)        \
+  FEATURE(PPC_UNIFIED_CACHE, unifiedcache, "ucache",                           \
+          PPC_FEATURE_UNIFIED_CACHE, 0)                                        \
+  FEATURE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0)                     \
+  FEATURE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle",                          \
+          PPC_FEATURE_HAS_EFP_SINGLE, 0)                                       \
+  FEATURE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble",                          \
+          PPC_FEATURE_HAS_EFP_DOUBLE, 0)                                       \
+  FEATURE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0)                      \
+  FEATURE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0)                 \
+  FEATURE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0)                 \
+  FEATURE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0)  \
+  FEATURE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0)                       \
+  FEATURE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0)                     \
+  FEATURE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0)                             \
+  FEATURE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, \
+          0)                                                                   \
+  FEATURE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0)       \
+  FEATURE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0)                         \
+  FEATURE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0)                     \
+  FEATURE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0)     \
+  FEATURE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0)       \
+  FEATURE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0)                     \
+  FEATURE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu",       \
+          PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0)                               \
+  FEATURE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0)              \
+  FEATURE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0)                   \
+  FEATURE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07)      \
+  FEATURE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM)                            \
+  FEATURE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR)                        \
+  FEATURE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB)                            \
+  FEATURE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL)                        \
+  FEATURE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR)                            \
+  FEATURE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO)      \
+  FEATURE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC)        \
+  FEATURE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00)      \
+  FEATURE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128)    \
+  FEATURE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN)                        \
+  FEATURE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV)                            \
+  FEATURE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0,             \
+          PPC_FEATURE2_HTM_NO_SUSPEND)
+#define DEFINE_TABLE_FEATURE_TYPE PPCFeatures
+#include "define_tables.h"
 
 static bool HandlePPCLine(const LineResult result,
                           PPCPlatformStrings* const strings) {
@@ -156,10 +120,12 @@
    * the auxilary vector.
    */
   PPCInfo info = kEmptyPPCInfo;
-
-  CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
-                                 CpuFeatures_GetHardwareCapabilities(),
-                                 &info.features);
+  const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
+  for (size_t i = 0; i < PPC_LAST_; ++i) {
+    if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
+      kSetters[i](&info.features, true);
+    }
+  }
   return info;
 }
 
@@ -178,13 +144,11 @@
 
 int GetPPCFeaturesEnumValue(const PPCFeatures* features,
                             PPCFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return false;
-  return kConfigs[value].get_bit((PPCFeatures*)features);
+  if (value >= PPC_LAST_) return false;
+  return kGetters[value](features);
 }
 
 const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) {
-  if(value >= kConfigsSize)
-    return "unknown feature";
-  return kConfigs[value].proc_cpuinfo_flag;
+  if (value >= PPC_LAST_) return "unknown feature";
+  return kCpuInfoFlags[value];
 }
diff --git a/src/cpuinfo_x86.c b/src/cpuinfo_x86.c
index d5edd30..378ed05 100644
--- a/src/cpuinfo_x86.c
+++ b/src/cpuinfo_x86.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 // Copyright 2020 Intel Corporation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,6 +25,91 @@
 #error "Cannot compile cpuinfo_x86 on a non x86 platform."
 #endif
 
+// Generation of feature's getters/setters functions and kGetters, kSetters,
+// kCpuInfoFlags global tables.
+#define DEFINE_TABLE_FEATURES                                                  \
+  FEATURE(X86_FPU, fpu, "fpu", 0, 0)                                           \
+  FEATURE(X86_TSC, tsc, "tsc", 0, 0)                                           \
+  FEATURE(X86_CX8, cx8, "cx8", 0, 0)                                           \
+  FEATURE(X86_CLFSH, clfsh, "clfsh", 0, 0)                                     \
+  FEATURE(X86_MMX, mmx, "mmx", 0, 0)                                           \
+  FEATURE(X86_AES, aes, "aes", 0, 0)                                           \
+  FEATURE(X86_ERMS, erms, "erms", 0, 0)                                        \
+  FEATURE(X86_F16C, f16c, "f16c", 0, 0)                                        \
+  FEATURE(X86_FMA4, fma4, "fma4", 0, 0)                                        \
+  FEATURE(X86_FMA3, fma3, "fma3", 0, 0)                                        \
+  FEATURE(X86_VAES, vaes, "vaes", 0, 0)                                        \
+  FEATURE(X86_VPCLMULQDQ, vpclmulqdq, "vpclmulqdq", 0, 0)                      \
+  FEATURE(X86_BMI1, bmi1, "bmi1", 0, 0)                                        \
+  FEATURE(X86_HLE, hle, "hle", 0, 0)                                           \
+  FEATURE(X86_BMI2, bmi2, "bmi2", 0, 0)                                        \
+  FEATURE(X86_RTM, rtm, "rtm", 0, 0)                                           \
+  FEATURE(X86_RDSEED, rdseed, "rdseed", 0, 0)                                  \
+  FEATURE(X86_CLFLUSHOPT, clflushopt, "clflushopt", 0, 0)                      \
+  FEATURE(X86_CLWB, clwb, "clwb", 0, 0)                                        \
+  FEATURE(X86_SSE, sse, "sse", 0, 0)                                           \
+  FEATURE(X86_SSE2, sse2, "sse2", 0, 0)                                        \
+  FEATURE(X86_SSE3, sse3, "sse3", 0, 0)                                        \
+  FEATURE(X86_SSSE3, ssse3, "ssse3", 0, 0)                                     \
+  FEATURE(X86_SSE4_1, sse4_1, "sse4_1", 0, 0)                                  \
+  FEATURE(X86_SSE4_2, sse4_2, "sse4_2", 0, 0)                                  \
+  FEATURE(X86_SSE4A, sse4a, "sse4a", 0, 0)                                     \
+  FEATURE(X86_AVX, avx, "avx", 0, 0)                                           \
+  FEATURE(X86_AVX2, avx2, "avx2", 0, 0)                                        \
+  FEATURE(X86_AVX512F, avx512f, "avx512f", 0, 0)                               \
+  FEATURE(X86_AVX512CD, avx512cd, "avx512cd", 0, 0)                            \
+  FEATURE(X86_AVX512ER, avx512er, "avx512er", 0, 0)                            \
+  FEATURE(X86_AVX512PF, avx512pf, "avx512pf", 0, 0)                            \
+  FEATURE(X86_AVX512BW, avx512bw, "avx512bw", 0, 0)                            \
+  FEATURE(X86_AVX512DQ, avx512dq, "avx512dq", 0, 0)                            \
+  FEATURE(X86_AVX512VL, avx512vl, "avx512vl", 0, 0)                            \
+  FEATURE(X86_AVX512IFMA, avx512ifma, "avx512ifma", 0, 0)                      \
+  FEATURE(X86_AVX512VBMI, avx512vbmi, "avx512vbmi", 0, 0)                      \
+  FEATURE(X86_AVX512VBMI2, avx512vbmi2, "avx512vbmi2", 0, 0)                   \
+  FEATURE(X86_AVX512VNNI, avx512vnni, "avx512vnni", 0, 0)                      \
+  FEATURE(X86_AVX512BITALG, avx512bitalg, "avx512bitalg", 0, 0)                \
+  FEATURE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, "avx512vpopcntdq", 0, 0)       \
+  FEATURE(X86_AVX512_4VNNIW, avx512_4vnniw, "avx512_4vnniw", 0, 0)             \
+  FEATURE(X86_AVX512_4VBMI2, avx512_4vbmi2, "avx512_4vbmi2", 0, 0)             \
+  FEATURE(X86_AVX512_SECOND_FMA, avx512_second_fma, "avx512_second_fma", 0, 0) \
+  FEATURE(X86_AVX512_4FMAPS, avx512_4fmaps, "avx512_4fmaps", 0, 0)             \
+  FEATURE(X86_AVX512_BF16, avx512_bf16, "avx512_bf16", 0, 0)                   \
+  FEATURE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, "avx512_vp2intersect", \
+          0, 0)                                                                \
+  FEATURE(X86_AMX_BF16, amx_bf16, "amx_bf16", 0, 0)                            \
+  FEATURE(X86_AMX_TILE, amx_tile, "amx_tile", 0, 0)                            \
+  FEATURE(X86_AMX_INT8, amx_int8, "amx_int8", 0, 0)                            \
+  FEATURE(X86_PCLMULQDQ, pclmulqdq, "pclmulqdq", 0, 0)                         \
+  FEATURE(X86_SMX, smx, "smx", 0, 0)                                           \
+  FEATURE(X86_SGX, sgx, "sgx", 0, 0)                                           \
+  FEATURE(X86_CX16, cx16, "cx16", 0, 0)                                        \
+  FEATURE(X86_SHA, sha, "sha", 0, 0)                                           \
+  FEATURE(X86_POPCNT, popcnt, "popcnt", 0, 0)                                  \
+  FEATURE(X86_MOVBE, movbe, "movbe", 0, 0)                                     \
+  FEATURE(X86_RDRND, rdrnd, "rdrnd", 0, 0)                                     \
+  FEATURE(X86_DCA, dca, "dca", 0, 0)                                           \
+  FEATURE(X86_SS, ss, "ss", 0, 0)
+#define DEFINE_TABLE_FEATURE_TYPE X86Features
+#define DEFINE_TABLE_DONT_GENERATE_HWCAPS
+#include "define_tables.h"
+
+// The following includes are necessary to provide SSE detections on pre-AVX
+// microarchitectures.
+#if defined(CPU_FEATURES_OS_WINDOWS)
+#include <windows.h>  // IsProcessorFeaturePresent
+#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
+#include "internal/filesystem.h"         // Needed to parse /proc/cpuinfo
+#include "internal/stack_line_reader.h"  // Needed to parse /proc/cpuinfo
+#include "internal/string_view.h"        // Needed to parse /proc/cpuinfo
+#elif defined(CPU_FEATURES_OS_DARWIN)
+#if !defined(HAVE_SYSCTLBYNAME)
+#error "Darwin needs support for sysctlbyname"
+#endif
+#include <sys/sysctl.h>
+#else
+#error "Unsupported OS"
+#endif  // CPU_FEATURES_OS
+
 ////////////////////////////////////////////////////////////////////////////////
 // Definitions for CpuId and GetXCR0Eax.
 ////////////////////////////////////////////////////////////////////////////////
@@ -35,7 +120,7 @@
 
 #include <cpuid.h>
 
-Leaf CpuIdEx(uint32_t leaf_id, int ecx) {
+Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
   Leaf leaf;
   __cpuid_count(leaf_id, ecx, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx);
   return leaf;
@@ -55,7 +140,7 @@
 #include <immintrin.h>
 #include <intrin.h>  // For __cpuidex()
 
-Leaf CpuIdEx(uint32_t leaf_id, int ecx) {
+Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
   Leaf leaf;
   int data[4];
   __cpuidex(data, leaf_id, ecx);
@@ -72,13 +157,13 @@
 #error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC."
 #endif
 
-static Leaf CpuId(uint32_t leaf_id) { return CpuIdEx(leaf_id, 0); }
+static Leaf CpuId(uint32_t leaf_id) { return GetCpuidLeaf(leaf_id, 0); }
 
 static const Leaf kEmptyLeaf;
 
 static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) {
   if (leaf_id <= max_cpuid_leaf) {
-    return CpuIdEx(leaf_id, ecx);
+    return GetCpuidLeaf(leaf_id, ecx);
   } else {
     return kEmptyLeaf;
   }
@@ -1082,27 +1167,115 @@
 // Internal structure to hold the OS support for vector operations.
 // Avoid to recompute them since each call to cpuid is ~100 cycles.
 typedef struct {
-  bool have_sse;
+  bool have_sse_via_os;
+  bool have_sse_via_cpuid;
   bool have_avx;
   bool have_avx512;
   bool have_amx;
 } OsSupport;
 
+static const OsSupport kEmptyOsSupport;
+
+static OsSupport CheckOsSupport(const uint32_t max_cpuid_leaf) {
+  const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1);
+  const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
+  const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
+  const bool have_xcr0 = have_xsave && have_osxsave;
+
+  OsSupport os_support = kEmptyOsSupport;
+
+  if (have_xcr0) {
+    // AVX capable cpu will expose XCR0.
+    const uint32_t xcr0_eax = GetXCR0Eax();
+    os_support.have_sse_via_cpuid = HasXmmOsXSave(xcr0_eax);
+    os_support.have_avx = HasYmmOsXSave(xcr0_eax);
+    os_support.have_avx512 = HasZmmOsXSave(xcr0_eax);
+    os_support.have_amx = HasTmmOsXSave(xcr0_eax);
+  } else {
+    // Atom based or older cpus need to ask the OS for sse support.
+    os_support.have_sse_via_os = true;
+  }
+
+  return os_support;
+}
+
+#if defined(CPU_FEATURES_OS_WINDOWS)
+#if defined(CPU_FEATURES_MOCK_CPUID_X86)
+extern bool GetWindowsIsProcessorFeaturePresent(DWORD);
+#else  // CPU_FEATURES_MOCK_CPUID_X86
+static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
+  return IsProcessorFeaturePresent(ProcessorFeature);
+}
+#endif
+#endif  // CPU_FEATURES_OS_WINDOWS
+
+#if defined(CPU_FEATURES_OS_DARWIN)
+#if defined(CPU_FEATURES_MOCK_CPUID_X86)
+extern bool GetDarwinSysCtlByName(const char*);
+#else  // CPU_FEATURES_MOCK_CPUID_X86
+static bool GetDarwinSysCtlByName(const char* name) {
+  int enabled;
+  size_t enabled_len = sizeof(enabled);
+  const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0);
+  return failure ? false : enabled;
+}
+#endif
+#endif  // CPU_FEATURES_OS_DARWIN
+
+static void DetectSseViaOs(X86Features* features) {
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
+  features->sse =
+      GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
+  features->sse2 =
+      GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
+  features->sse3 =
+      GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
+#elif defined(CPU_FEATURES_OS_DARWIN)
+  // Handling Darwin platform through sysctlbyname.
+  features->sse = GetDarwinSysCtlByName("hw.optional.sse");
+  features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2");
+  features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3");
+  features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3");
+  features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1");
+  features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2");
+#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
+  // Handling Linux platform through /proc/cpuinfo.
+  const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
+  if (fd >= 0) {
+    StackLineReader reader;
+    StackLineReader_Initialize(&reader, fd);
+    for (;;) {
+      const LineResult result = StackLineReader_NextLine(&reader);
+      const StringView line = result.line;
+      StringView key, value;
+      if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
+        if (CpuFeatures_StringView_IsEquals(key, str("flags"))) {
+          features->sse = CpuFeatures_StringView_HasWord(value, "sse");
+          features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2");
+          features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3");
+          features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3");
+          features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1");
+          features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2");
+          break;
+        }
+      }
+      if (result.eof) break;
+    }
+    CpuFeatures_CloseFile(fd);
+  }
+#else
+#error "Unsupported fallback detection of SSE OS support."
+#endif
+}
+
 // Reference https://en.wikipedia.org/wiki/CPUID.
-static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
-                       OsSupport* os_support) {
+static void ParseCpuId(const uint32_t max_cpuid_leaf,
+                       const OsSupport os_support, X86Info* info) {
   const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1);
   const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7);
   const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1);
 
-  const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
-  const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
-  const uint32_t xcr0_eax = (have_xsave && have_osxsave) ? GetXCR0Eax() : 0;
-  os_support->have_sse = HasXmmOsXSave(xcr0_eax);
-  os_support->have_avx = HasYmmOsXSave(xcr0_eax);
-  os_support->have_avx512 = HasZmmOsXSave(xcr0_eax);
-  os_support->have_amx = HasTmmOsXSave(xcr0_eax);
-
   const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8);
   const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20);
   const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4);
@@ -1142,7 +1315,9 @@
   features->vaes = IsBitSet(leaf_7.ecx, 9);
   features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
 
-  if (os_support->have_sse) {
+  if (os_support.have_sse_via_os) {
+    DetectSseViaOs(features);
+  } else if (os_support.have_sse_via_cpuid) {
     features->sse = IsBitSet(leaf_1.edx, 25);
     features->sse2 = IsBitSet(leaf_1.edx, 26);
     features->sse3 = IsBitSet(leaf_1.ecx, 0);
@@ -1151,13 +1326,13 @@
     features->sse4_2 = IsBitSet(leaf_1.ecx, 20);
   }
 
-  if (os_support->have_avx) {
+  if (os_support.have_avx) {
     features->fma3 = IsBitSet(leaf_1.ecx, 12);
     features->avx = IsBitSet(leaf_1.ecx, 28);
     features->avx2 = IsBitSet(leaf_7.ebx, 5);
   }
 
-  if (os_support->have_avx512) {
+  if (os_support.have_avx512) {
     features->avx512f = IsBitSet(leaf_7.ebx, 16);
     features->avx512cd = IsBitSet(leaf_7.ebx, 28);
     features->avx512er = IsBitSet(leaf_7.ebx, 27);
@@ -1179,7 +1354,7 @@
     features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8);
   }
 
-  if (os_support->have_amx) {
+  if (os_support.have_amx) {
     features->amx_bf16 = IsBitSet(leaf_7.edx, 22);
     features->amx_tile = IsBitSet(leaf_7.edx, 24);
     features->amx_int8 = IsBitSet(leaf_7.edx, 25);
@@ -1195,7 +1370,7 @@
 
   X86Features* const features = &info->features;
 
-  if (os_support.have_sse) {
+  if (os_support.have_sse_via_cpuid) {
     features->sse4a = IsBitSet(leaf_80000001.ecx, 6);
   }
 
@@ -1205,22 +1380,21 @@
 }
 
 static const X86Info kEmptyX86Info;
-static const OsSupport kEmptyOsSupport;
 static const CacheInfo kEmptyCacheInfo;
 
 X86Info GetX86Info(void) {
   X86Info info = kEmptyX86Info;
-  OsSupport os_support = kEmptyOsSupport;
   const Leaf leaf_0 = CpuId(0);
   const bool is_intel = IsVendor(leaf_0, "GenuineIntel");
   const bool is_amd = IsVendor(leaf_0, "AuthenticAMD");
   SetVendor(leaf_0, info.vendor);
   if (is_intel || is_amd) {
     const uint32_t max_cpuid_leaf = leaf_0.eax;
-    ParseCpuId(max_cpuid_leaf, &info, &os_support);
-  }
-  if (is_amd) {
-    ParseExtraAMDCpuId(&info, os_support);
+    const OsSupport os_support = CheckOsSupport(max_cpuid_leaf);
+    ParseCpuId(max_cpuid_leaf, os_support, &info);
+    if (is_amd) {
+      ParseExtraAMDCpuId(&info, os_support);
+    }
   }
   return info;
 }
@@ -1380,259 +1554,13 @@
 
 int GetX86FeaturesEnumValue(const X86Features* features,
                             X86FeaturesEnum value) {
-  switch (value) {
-    case X86_FPU:
-      return features->fpu;
-    case X86_TSC:
-      return features->tsc;
-    case X86_CX8:
-      return features->cx8;
-    case X86_CLFSH:
-      return features->clfsh;
-    case X86_MMX:
-      return features->mmx;
-    case X86_AES:
-      return features->aes;
-    case X86_ERMS:
-      return features->erms;
-    case X86_F16C:
-      return features->f16c;
-    case X86_FMA4:
-      return features->fma4;
-    case X86_FMA3:
-      return features->fma3;
-    case X86_VAES:
-      return features->vaes;
-    case X86_VPCLMULQDQ:
-      return features->vpclmulqdq;
-    case X86_BMI1:
-      return features->bmi1;
-    case X86_HLE:
-      return features->hle;
-    case X86_BMI2:
-      return features->bmi2;
-    case X86_RTM:
-      return features->rtm;
-    case X86_RDSEED:
-      return features->rdseed;
-    case X86_CLFLUSHOPT:
-      return features->clflushopt;
-    case X86_CLWB:
-      return features->clwb;
-    case X86_SSE:
-      return features->sse;
-    case X86_SSE2:
-      return features->sse2;
-    case X86_SSE3:
-      return features->sse3;
-    case X86_SSSE3:
-      return features->ssse3;
-    case X86_SSE4_1:
-      return features->sse4_1;
-    case X86_SSE4_2:
-      return features->sse4_2;
-    case X86_SSE4A:
-      return features->sse4a;
-    case X86_AVX:
-      return features->avx;
-    case X86_AVX2:
-      return features->avx2;
-    case X86_AVX512F:
-      return features->avx512f;
-    case X86_AVX512CD:
-      return features->avx512cd;
-    case X86_AVX512ER:
-      return features->avx512er;
-    case X86_AVX512PF:
-      return features->avx512pf;
-    case X86_AVX512BW:
-      return features->avx512bw;
-    case X86_AVX512DQ:
-      return features->avx512dq;
-    case X86_AVX512VL:
-      return features->avx512vl;
-    case X86_AVX512IFMA:
-      return features->avx512ifma;
-    case X86_AVX512VBMI:
-      return features->avx512vbmi;
-    case X86_AVX512VBMI2:
-      return features->avx512vbmi2;
-    case X86_AVX512VNNI:
-      return features->avx512vnni;
-    case X86_AVX512BITALG:
-      return features->avx512bitalg;
-    case X86_AVX512VPOPCNTDQ:
-      return features->avx512vpopcntdq;
-    case X86_AVX512_4VNNIW:
-      return features->avx512_4vnniw;
-    case X86_AVX512_4VBMI2:
-      return features->avx512_4vbmi2;
-    case X86_AVX512_SECOND_FMA:
-      return features->avx512_second_fma;
-    case X86_AVX512_4FMAPS:
-      return features->avx512_4fmaps;
-    case X86_AVX512_BF16:
-      return features->avx512_bf16;
-    case X86_AVX512_VP2INTERSECT:
-      return features->avx512_vp2intersect;
-    case X86_AMX_BF16:
-      return features->amx_bf16;
-    case X86_AMX_TILE:
-      return features->amx_tile;
-    case X86_AMX_INT8:
-      return features->amx_int8;
-    case X86_PCLMULQDQ:
-      return features->pclmulqdq;
-    case X86_SMX:
-      return features->smx;
-    case X86_SGX:
-      return features->sgx;
-    case X86_CX16:
-      return features->cx16;
-    case X86_SHA:
-      return features->sha;
-    case X86_POPCNT:
-      return features->popcnt;
-    case X86_MOVBE:
-      return features->movbe;
-    case X86_RDRND:
-      return features->rdrnd;
-    case X86_DCA:
-      return features->dca;
-    case X86_SS:
-      return features->ss;
-    case X86_LAST_:
-      break;
-  }
-  return false;
+  if (value >= X86_LAST_) return false;
+  return kGetters[value](features);
 }
 
 const char* GetX86FeaturesEnumName(X86FeaturesEnum value) {
-  switch (value) {
-    case X86_FPU:
-      return "fpu";
-    case X86_TSC:
-      return "tsc";
-    case X86_CX8:
-      return "cx8";
-    case X86_CLFSH:
-      return "clfsh";
-    case X86_MMX:
-      return "mmx";
-    case X86_AES:
-      return "aes";
-    case X86_ERMS:
-      return "erms";
-    case X86_F16C:
-      return "f16c";
-    case X86_FMA4:
-      return "fma4";
-    case X86_FMA3:
-      return "fma3";
-    case X86_VAES:
-      return "vaes";
-    case X86_VPCLMULQDQ:
-      return "vpclmulqdq";
-    case X86_BMI1:
-      return "bmi1";
-    case X86_HLE:
-      return "hle";
-    case X86_BMI2:
-      return "bmi2";
-    case X86_RTM:
-      return "rtm";
-    case X86_RDSEED:
-      return "rdseed";
-    case X86_CLFLUSHOPT:
-      return "clflushopt";
-    case X86_CLWB:
-      return "clwb";
-    case X86_SSE:
-      return "sse";
-    case X86_SSE2:
-      return "sse2";
-    case X86_SSE3:
-      return "sse3";
-    case X86_SSSE3:
-      return "ssse3";
-    case X86_SSE4_1:
-      return "sse4_1";
-    case X86_SSE4_2:
-      return "sse4_2";
-    case X86_SSE4A:
-      return "sse4a";
-    case X86_AVX:
-      return "avx";
-    case X86_AVX2:
-      return "avx2";
-    case X86_AVX512F:
-      return "avx512f";
-    case X86_AVX512CD:
-      return "avx512cd";
-    case X86_AVX512ER:
-      return "avx512er";
-    case X86_AVX512PF:
-      return "avx512pf";
-    case X86_AVX512BW:
-      return "avx512bw";
-    case X86_AVX512DQ:
-      return "avx512dq";
-    case X86_AVX512VL:
-      return "avx512vl";
-    case X86_AVX512IFMA:
-      return "avx512ifma";
-    case X86_AVX512VBMI:
-      return "avx512vbmi";
-    case X86_AVX512VBMI2:
-      return "avx512vbmi2";
-    case X86_AVX512VNNI:
-      return "avx512vnni";
-    case X86_AVX512BITALG:
-      return "avx512bitalg";
-    case X86_AVX512VPOPCNTDQ:
-      return "avx512vpopcntdq";
-    case X86_AVX512_4VNNIW:
-      return "avx512_4vnniw";
-    case X86_AVX512_4VBMI2:
-      return "avx512_4vbmi2";
-    case X86_AVX512_SECOND_FMA:
-      return "avx512_second_fma";
-    case X86_AVX512_4FMAPS:
-      return "avx512_4fmaps";
-    case X86_AVX512_BF16:
-      return "avx512_bf16";
-    case X86_AVX512_VP2INTERSECT:
-      return "avx512_vp2intersect";
-    case X86_AMX_BF16:
-      return "amx_bf16";
-    case X86_AMX_TILE:
-      return "amx_tile";
-    case X86_AMX_INT8:
-      return "amx_int8";
-    case X86_PCLMULQDQ:
-      return "pclmulqdq";
-    case X86_SMX:
-      return "smx";
-    case X86_SGX:
-      return "sgx";
-    case X86_CX16:
-      return "cx16";
-    case X86_SHA:
-      return "sha";
-    case X86_POPCNT:
-      return "popcnt";
-    case X86_MOVBE:
-      return "movbe";
-    case X86_RDRND:
-      return "rdrnd";
-    case X86_DCA:
-      return "dca";
-    case X86_SS:
-      return "ss";
-    case X86_LAST_:
-      break;
-  }
-  return "unknown_feature";
+  if (value >= X86_LAST_) return "unknown_feature";
+  return kCpuInfoFlags[value];
 }
 
 const char* GetX86MicroarchitectureName(X86Microarchitecture uarch) {
diff --git a/src/define_tables.h b/src/define_tables.h
new file mode 100644
index 0000000..dc1485c
--- /dev/null
+++ b/src/define_tables.h
@@ -0,0 +1,67 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// The following preprocessor constants must be defined before including this
+// file:
+//  - DEFINE_TABLE_FEATURE_TYPE, the underlying type (e.g. X86Features)
+//  - DEFINE_TABLE_FEATURES, the list of FEATURE macros to be inserted.
+
+// This file is to be included once per `cpuinfo_XXX.c` in order to construct
+// feature getters and setters functions as well as several enum indexed tables
+// from the db file.
+// - `kGetters` a table of getters function pointers from feature enum to
+// retrieve a feature,
+// - `kSetters` a table of setters function pointers from feature enum to set a
+// feature,
+// - `kCpuInfoFlags` a table of strings from feature enum to /proc/cpuinfo
+// flags,
+// - `kHardwareCapabilities` a table of HardwareCapabilities structs indexed by
+// their feature enum.
+
+#ifndef SRC_DEFINE_TABLES_H_
+#define SRC_DEFINE_TABLES_H_
+
+#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = CPUINFO_FLAG,
+static const char* kCpuInfoFlags[] = {DEFINE_TABLE_FEATURES};
+#undef FEATURE
+
+#ifndef DEFINE_TABLE_DONT_GENERATE_HWCAPS
+#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \
+  [ENUM] = (HardwareCapabilities){HWCAP, HWCAP2},
+static const HardwareCapabilities kHardwareCapabilities[] = {
+    DEFINE_TABLE_FEATURES};
+#undef FEATURE
+#endif  // DEFINE_TABLE_DONT_GENERATE_HWCAPS
+
+#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2)                    \
+  static void set_##ENUM(DEFINE_TABLE_FEATURE_TYPE* features, bool value) { \
+    features->NAME = value;                                                 \
+  }                                                                         \
+  static int get_##ENUM(const DEFINE_TABLE_FEATURE_TYPE* features) {        \
+    return features->NAME;                                                  \
+  }
+DEFINE_TABLE_FEATURES
+#undef FEATURE
+
+#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = set_##ENUM,
+static void (*const kSetters[])(DEFINE_TABLE_FEATURE_TYPE*,
+                                bool) = {DEFINE_TABLE_FEATURES};
+#undef FEATURE
+
+#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = get_##ENUM,
+static int (*const kGetters[])(const DEFINE_TABLE_FEATURE_TYPE*) = {
+    DEFINE_TABLE_FEATURES};
+#undef FEATURE
+
+#endif  // SRC_DEFINE_TABLES_H_
diff --git a/src/filesystem.c b/src/filesystem.c
index 2f7083b..46c9906 100644
--- a/src/filesystem.c
+++ b/src/filesystem.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/src/hwcaps.c b/src/hwcaps.c
index 815e5c1..dd17e3b 100644
--- a/src/hwcaps.c
+++ b/src/hwcaps.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,14 +12,33 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "internal/hwcaps.h"
+
 #include <stdlib.h>
 #include <string.h>
 
 #include "cpu_features_macros.h"
 #include "internal/filesystem.h"
-#include "internal/hwcaps.h"
 #include "internal/string_view.h"
 
+static bool IsSet(const uint32_t mask, const uint32_t value) {
+  if (mask == 0) return false;
+  return (value & mask) == mask;
+}
+
+bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
+                             const HardwareCapabilities hwcaps) {
+  return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
+         IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2);
+}
+
+#ifdef CPU_FEATURES_TEST
+// In test mode, hwcaps_for_testing will define the following functions.
+HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
+PlatformType CpuFeatures_GetPlatformType(void);
+#else
+
+// Debug facilities
 #if defined(NDEBUG)
 #define D(...)
 #else
@@ -35,9 +54,12 @@
 // Implementation of GetElfHwcapFromGetauxval
 ////////////////////////////////////////////////////////////////////////////////
 
-#if defined(CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL)
-// Implementation will be provided by test/hwcaps_for_testing.cc.
-#elif defined(HAVE_STRONG_GETAUXVAL)
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+#define AT_PLATFORM 15
+#define AT_BASE_PLATFORM 24
+
+#if defined(HAVE_STRONG_GETAUXVAL)
 #include <sys/auxv.h>
 static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
   return getauxval(hwcap_type);
@@ -59,17 +81,13 @@
 // initialization layer.
 
 #include <dlfcn.h>
-#define AT_HWCAP 16
-#define AT_HWCAP2 26
-#define AT_PLATFORM 15
-#define AT_BASE_PLATFORM 24
 
 typedef unsigned long getauxval_func_t(unsigned long);
 
 static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type) {
   uint32_t ret = 0;
-  void* libc_handle = NULL;
-  getauxval_func_t* func = NULL;
+  void *libc_handle = NULL;
+  getauxval_func_t *func = NULL;
 
   dlerror();  // Cleaning error state before calling dlopen.
   libc_handle = dlopen("libc.so", RTLD_NOW);
@@ -77,7 +95,7 @@
     D("Could not dlopen() C library: %s\n", dlerror());
     return 0;
   }
-  func = (getauxval_func_t*)dlsym(libc_handle, "getauxval");
+  func = (getauxval_func_t *)dlsym(libc_handle, "getauxval");
   if (!func) {
     D("Could not find getauxval() in C library\n");
   } else {
@@ -109,7 +127,7 @@
     return 0;
   }
   for (;;) {
-    const int ret = CpuFeatures_ReadFile(fd, (char*)&entry, sizeof entry);
+    const int ret = CpuFeatures_ReadFile(fd, (char *)&entry, sizeof entry);
     if (ret < 0) {
       D("Error while reading %s\n", filepath);
       break;
@@ -160,3 +178,5 @@
                                       sizeof(type.base_platform));
   return type;
 }
+
+#endif  // CPU_FEATURES_TEST
diff --git a/src/stack_line_reader.c b/src/stack_line_reader.c
index b2c48ba..ffc778d 100644
--- a/src/stack_line_reader.c
+++ b/src/stack_line_reader.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,12 +13,13 @@
 // limitations under the License.
 
 #include "internal/stack_line_reader.h"
-#include "internal/filesystem.h"
 
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 
+#include "internal/filesystem.h"
+
 void StackLineReader_Initialize(StackLineReader* reader, int fd) {
   reader->view.ptr = reader->buffer;
   reader->view.size = 0;
diff --git a/src/string_view.c b/src/string_view.c
index 856731c..dc3158f 100644
--- a/src/string_view.c
+++ b/src/string_view.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/src/unix_features_aggregator.c b/src/unix_features_aggregator.c
deleted file mode 100644
index 1b43a36..0000000
--- a/src/unix_features_aggregator.c
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "internal/unix_features_aggregator.h"
-#include "internal/string_view.h"
-
-void CpuFeatures_SetFromFlags(const size_t configs_size,
-                              const CapabilityConfig* configs,
-                              const StringView flags_line,
-                              void* const features) {
-  size_t i = 0;
-  for (; i < configs_size; ++i) {
-    const CapabilityConfig config = configs[i];
-    config.set_bit(features, CpuFeatures_StringView_HasWord(
-                                 flags_line, config.proc_cpuinfo_flag));
-  }
-}
-
-static bool IsSet(const uint32_t mask, const uint32_t value) {
-  if (mask == 0) return false;
-  return (value & mask) == mask;
-}
-
-static bool IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
-                        const HardwareCapabilities hwcaps) {
-  return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
-         IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2);
-}
-
-void CpuFeatures_OverrideFromHwCaps(const size_t configs_size,
-                                    const CapabilityConfig* configs,
-                                    const HardwareCapabilities hwcaps,
-                                    void* const features) {
-  size_t i = 0;
-  for (; i < configs_size; ++i) {
-    const CapabilityConfig* config = &configs[i];
-    if (IsHwCapsSet(config->hwcaps_mask, hwcaps)) {
-      config->set_bit(features, true);
-    }
-  }
-}
diff --git a/src/utils/list_cpu_features.c b/src/utils/list_cpu_features.c
index 0783648..c80ffc5 100644
--- a/src/utils/list_cpu_features.c
+++ b/src/utils/list_cpu_features.c
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@
 // the data accordingly.
 
 // We use a bump allocator to allocate strings and nodes of the tree,
-// Memory is not intented to be reclaimed.
+// Memory is not intended to be reclaimed.
 typedef struct {
   char* ptr;
   size_t size;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index eb67ac0..c10e617 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -12,7 +12,6 @@
 target_compile_definitions(filesystem_for_testing PUBLIC CPU_FEATURES_MOCK_FILESYSTEM)
 ##------------------------------------------------------------------------------
 add_library(hwcaps_for_testing hwcaps_for_testing.cc)
-target_compile_definitions(hwcaps_for_testing PUBLIC CPU_FEATURES_MOCK_GET_ELF_HWCAP_FROM_GETAUXVAL)
 target_link_libraries(hwcaps_for_testing filesystem_for_testing)
 ##------------------------------------------------------------------------------
 add_library(stack_line_reader ../src/stack_line_reader.c)
@@ -23,7 +22,7 @@
 target_compile_definitions(stack_line_reader_for_test PUBLIC STACK_LINE_READER_BUFFER_SIZE=16)
 target_link_libraries(stack_line_reader_for_test string_view filesystem_for_testing)
 ##------------------------------------------------------------------------------
-add_library(all_libraries ../src/stack_line_reader.c ../src/unix_features_aggregator.c)
+add_library(all_libraries ../src/hwcaps.c  ../src/stack_line_reader.c)
 target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view)
 
 #
@@ -46,15 +45,13 @@
 target_link_libraries(stack_line_reader_test stack_line_reader_for_test)
 add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test)
 ##------------------------------------------------------------------------------
-## unix_features_aggregator_test
-add_executable(unix_features_aggregator_test unix_features_aggregator_test.cc)
-target_link_libraries(unix_features_aggregator_test all_libraries)
-add_test(NAME unix_features_aggregator_test COMMAND unix_features_aggregator_test)
-##------------------------------------------------------------------------------
 ## cpuinfo_x86_test
 if(PROCESSOR_IS_X86)
   add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c)
   target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86)
+  if(APPLE)
+    target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME)
+  endif()
   target_link_libraries(cpuinfo_x86_test all_libraries)
   add_test(NAME cpuinfo_x86_test COMMAND cpuinfo_x86_test)
 endif()
diff --git a/test/bit_utils_test.cc b/test/bit_utils_test.cc
index 9c8c1bb..3874e13 100644
--- a/test/bit_utils_test.cc
+++ b/test/bit_utils_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/test/cpuinfo_aarch64_test.cc b/test/cpuinfo_aarch64_test.cc
index 1bd0648..5afaaa8 100644
--- a/test/cpuinfo_aarch64_test.cc
+++ b/test/cpuinfo_aarch64_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "cpuinfo_aarch64.h"
-#include "filesystem_for_testing.h"
-#include "hwcaps_for_testing.h"
 
+#include "filesystem_for_testing.h"
 #include "gtest/gtest.h"
+#include "hwcaps_for_testing.h"
 
 namespace cpu_features {
 namespace {
@@ -62,7 +62,8 @@
 }
 
 TEST(CpuinfoAarch64Test, FromHardwareCap2) {
-  SetHardwareCapabilities(AARCH64_HWCAP_FP, AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI);
+  SetHardwareCapabilities(AARCH64_HWCAP_FP,
+                          AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI);
   GetEmptyFilesystem();  // disabling /proc/cpuinfo
   const auto info = GetAarch64Info();
   EXPECT_TRUE(info.features.fp);
diff --git a/test/cpuinfo_arm_test.cc b/test/cpuinfo_arm_test.cc
index fa92e11..e0b08a4 100644
--- a/test/cpuinfo_arm_test.cc
+++ b/test/cpuinfo_arm_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "cpuinfo_arm.h"
-#include "filesystem_for_testing.h"
-#include "hwcaps_for_testing.h"
 
+#include "filesystem_for_testing.h"
 #include "gtest/gtest.h"
+#include "hwcaps_for_testing.h"
 
 namespace cpu_features {
 namespace {
diff --git a/test/cpuinfo_mips_test.cc b/test/cpuinfo_mips_test.cc
index fbec04d..d734058 100644
--- a/test/cpuinfo_mips_test.cc
+++ b/test/cpuinfo_mips_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,13 +13,13 @@
 // limitations under the License.
 
 #include "cpuinfo_mips.h"
+
 #include "filesystem_for_testing.h"
+#include "gtest/gtest.h"
 #include "hwcaps_for_testing.h"
 #include "internal/stack_line_reader.h"
 #include "internal/string_view.h"
 
-#include "gtest/gtest.h"
-
 namespace cpu_features {
 
 namespace {
diff --git a/test/cpuinfo_ppc_test.cc b/test/cpuinfo_ppc_test.cc
index 5d5e798..8f0cb65 100644
--- a/test/cpuinfo_ppc_test.cc
+++ b/test/cpuinfo_ppc_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "cpuinfo_ppc.h"
+
 #include "filesystem_for_testing.h"
+#include "gtest/gtest.h"
 #include "hwcaps_for_testing.h"
 #include "internal/string_view.h"
 
-#include "gtest/gtest.h"
-
 namespace cpu_features {
 namespace {
 
diff --git a/test/cpuinfo_x86_test.cc b/test/cpuinfo_x86_test.cc
index 3c80eee..636d0f9 100644
--- a/test/cpuinfo_x86_test.cc
+++ b/test/cpuinfo_x86_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,20 +12,25 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "cpuinfo_x86.h"
+
 #include <cassert>
 #include <cstdio>
 #include <map>
+#include <set>
+#if defined(CPU_FEATURES_OS_WINDOWS)
+#include <windows.h>  // IsProcessorFeaturePresent
+#endif                // CPU_FEATURES_OS_WINDOWS
 
+#include "filesystem_for_testing.h"
 #include "gtest/gtest.h"
-
-#include "cpuinfo_x86.h"
 #include "internal/cpuid_x86.h"
 
 namespace cpu_features {
 
 class FakeCpu {
  public:
-  Leaf CpuIdEx(uint32_t leaf_id, int ecx) const {
+  Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) const {
     const auto itr = cpuid_leaves_.find(std::make_pair(leaf_id, ecx));
     if (itr != cpuid_leaves_.end()) {
       return itr->second;
@@ -43,22 +48,66 @@
     xcr0_eax_ = os_backups_extended_registers ? -1 : 0;
   }
 
+#if defined(CPU_FEATURES_OS_DARWIN)
+  bool GetDarwinSysCtlByName(std::string name) const {
+    return darwin_sysctlbyname_.count(name);
+  }
+
+  void SetDarwinSysCtlByName(std::string name) {
+    darwin_sysctlbyname_.insert(name);
+  }
+#endif  // CPU_FEATURES_OS_DARWIN
+
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
+    return windows_isprocessorfeaturepresent_.count(ProcessorFeature);
+  }
+
+  void SetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
+    windows_isprocessorfeaturepresent_.insert(ProcessorFeature);
+  }
+#endif  // CPU_FEATURES_OS_WINDOWS
+
  private:
   std::map<std::pair<uint32_t, int>, Leaf> cpuid_leaves_;
+#if defined(CPU_FEATURES_OS_DARWIN)
+  std::set<std::string> darwin_sysctlbyname_;
+#endif  // CPU_FEATURES_OS_DARWIN
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  std::set<DWORD> windows_isprocessorfeaturepresent_;
+#endif  // CPU_FEATURES_OS_WINDOWS
   uint32_t xcr0_eax_;
 };
 
-auto* g_fake_cpu = new FakeCpu();
+FakeCpu* g_fake_cpu = nullptr;
 
-extern "C" Leaf CpuIdEx(uint32_t leaf_id, int ecx) {
-  return g_fake_cpu->CpuIdEx(leaf_id, ecx);
+extern "C" Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
+  return g_fake_cpu->GetCpuidLeaf(leaf_id, ecx);
 }
 
 extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); }
 
+#if defined(CPU_FEATURES_OS_DARWIN)
+extern "C" bool GetDarwinSysCtlByName(const char* name) {
+  return g_fake_cpu->GetDarwinSysCtlByName(name);
+}
+#endif  // CPU_FEATURES_OS_DARWIN
+
+#if defined(CPU_FEATURES_OS_WINDOWS)
+extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
+  return g_fake_cpu->GetWindowsIsProcessorFeaturePresent(ProcessorFeature);
+}
+#endif  // CPU_FEATURES_OS_WINDOWS
+
 namespace {
 
-TEST(CpuidX86Test, SandyBridge) {
+class CpuidX86Test : public ::testing::Test {
+ protected:
+  void SetUp() override { g_fake_cpu = new FakeCpu(); }
+  void TearDown() override { delete g_fake_cpu; }
+};
+
+TEST_F(CpuidX86Test, SandyBridge) {
   g_fake_cpu->SetOsBackupsExtendedRegisters(true);
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
@@ -104,7 +153,7 @@
 const int KiB = 1024;
 const int MiB = 1024 * KiB;
 
-TEST(CpuidX86Test, SandyBridgeTestOsSupport) {
+TEST_F(CpuidX86Test, SandyBridgeTestOsSupport) {
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
       {{0x00000001, 0}, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}},
@@ -118,7 +167,7 @@
   EXPECT_TRUE(GetX86Info().features.avx);
 }
 
-TEST(CpuidX86Test, SkyLake) {
+TEST_F(CpuidX86Test, SkyLake) {
   g_fake_cpu->SetOsBackupsExtendedRegisters(true);
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
@@ -133,7 +182,7 @@
   EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL);
 }
 
-TEST(CpuidX86Test, Branding) {
+TEST_F(CpuidX86Test, Branding) {
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
       {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
@@ -149,7 +198,7 @@
   EXPECT_STREQ(brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz");
 }
 
-TEST(CpuidX86Test, KabyLakeCache) {
+TEST_F(CpuidX86Test, KabyLakeCache) {
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
       {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
@@ -198,7 +247,7 @@
   EXPECT_EQ(info.levels[3].partitioning, 1);
 }
 
-TEST(CpuidX86Test, HSWCache) {
+TEST_F(CpuidX86Test, HSWCache) {
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
       {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
@@ -246,8 +295,9 @@
   EXPECT_EQ(info.levels[3].tlb_entries, 8192);
   EXPECT_EQ(info.levels[3].partitioning, 1);
 }
+
 // http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt
-TEST(CpuidX86Test, AMD_K15) {
+TEST_F(CpuidX86Test, AMD_K15) {
   g_fake_cpu->SetLeaves({
       {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
       {{0x00000001, 0}, Leaf{0x00630F81, 0x00040800, 0x3E98320B, 0x178BFBFF}},
@@ -273,6 +323,208 @@
   EXPECT_STREQ(brand_string, "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
 }
 
+// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00106A1_Nehalem_CPUID.txt
+TEST_F(CpuidX86Test, Nehalem) {
+  // Pre AVX cpus don't have xsave
+  g_fake_cpu->SetOsBackupsExtendedRegisters(false);
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_XMMI_INSTRUCTIONS_AVAILABLE);
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_XMMI64_INSTRUCTIONS_AVAILABLE);
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_SSE3_INSTRUCTIONS_AVAILABLE);
+#endif  // CPU_FEATURES_OS_WINDOWS
+#if defined(CPU_FEATURES_OS_DARWIN)
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse2");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse3");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.supplementalsse3");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_1");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_2");
+#endif  // CPU_FEATURES_OS_DARWIN
+#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
+  auto& fs = GetEmptyFilesystem();
+  fs.CreateFile("/proc/cpuinfo", R"(processor       :
+flags           : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
+)");
+#endif  // CPU_FEATURES_OS_LINUX_OR_ANDROID
+  g_fake_cpu->SetLeaves({
+      {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
+      {{0x00000001, 0}, Leaf{0x000106A2, 0x00100800, 0x00BCE3BD, 0xBFEBFBFF}},
+      {{0x00000002, 0}, Leaf{0x55035A01, 0x00F0B0E3, 0x00000000, 0x09CA212C}},
+      {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x00000004, 0}, Leaf{0x1C004121, 0x01C0003F, 0x0000003F, 0x00000000}},
+      {{0x00000004, 0}, Leaf{0x1C004122, 0x00C0003F, 0x0000007F, 0x00000000}},
+      {{0x00000004, 0}, Leaf{0x1C004143, 0x01C0003F, 0x000001FF, 0x00000000}},
+      {{0x00000004, 0}, Leaf{0x1C03C163, 0x03C0003F, 0x00000FFF, 0x00000002}},
+      {{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x00021120}},
+      {{0x00000006, 0}, Leaf{0x00000001, 0x00000002, 0x00000001, 0x00000000}},
+      {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x00000008, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x00000009, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x0000000A, 0}, Leaf{0x07300403, 0x00000000, 0x00000000, 0x00000603}},
+      {{0x0000000B, 0}, Leaf{0x00000001, 0x00000001, 0x00000100, 0x00000000}},
+      {{0x0000000B, 0}, Leaf{0x00000004, 0x00000002, 0x00000201, 0x00000000}},
+      {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000001, 0x28100000}},
+      {{0x80000002, 0}, Leaf{0x756E6547, 0x20656E69, 0x65746E49, 0x2952286C}},
+      {{0x80000003, 0}, Leaf{0x55504320, 0x20202020, 0x20202020, 0x40202020}},
+      {{0x80000004, 0}, Leaf{0x30303020, 0x20402030, 0x37382E31, 0x007A4847}},
+      {{0x80000005, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x80000006, 0}, Leaf{0x00000000, 0x00000000, 0x01006040, 0x00000000}},
+      {{0x80000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000100}},
+      {{0x80000008, 0}, Leaf{0x00003028, 0x00000000, 0x00000000, 0x00000000}},
+  });
+  const auto info = GetX86Info();
+
+  EXPECT_STREQ(info.vendor, "GenuineIntel");
+  EXPECT_EQ(info.family, 0x06);
+  EXPECT_EQ(info.model, 0x1A);
+  EXPECT_EQ(info.stepping, 0x02);
+  EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
+
+  char brand_string[49];
+  FillX86BrandString(brand_string);
+  EXPECT_STREQ(brand_string, "Genuine Intel(R) CPU           @ 0000 @ 1.87GHz");
+
+  EXPECT_TRUE(info.features.sse);
+  EXPECT_TRUE(info.features.sse2);
+  EXPECT_TRUE(info.features.sse3);
+#ifndef CPU_FEATURES_OS_WINDOWS
+  // Currently disabled on Windows as IsProcessorFeaturePresent do not support
+  // feature detection > sse3.
+  EXPECT_TRUE(info.features.ssse3);
+  EXPECT_TRUE(info.features.sse4_1);
+  EXPECT_TRUE(info.features.sse4_2);
+#endif  // CPU_FEATURES_OS_WINDOWS
+}
+
+// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0030673_Silvermont3_CPUID.txt
+TEST_F(CpuidX86Test, Atom) {
+  // Pre AVX cpus don't have xsave
+  g_fake_cpu->SetOsBackupsExtendedRegisters(false);
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_XMMI_INSTRUCTIONS_AVAILABLE);
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_XMMI64_INSTRUCTIONS_AVAILABLE);
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_SSE3_INSTRUCTIONS_AVAILABLE);
+#endif  // CPU_FEATURES_OS_WINDOWS
+#if defined(CPU_FEATURES_OS_DARWIN)
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse2");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse3");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.supplementalsse3");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_1");
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_2");
+#endif  // CPU_FEATURES_OS_DARWIN
+#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
+  auto& fs = GetEmptyFilesystem();
+  fs.CreateFile("/proc/cpuinfo", R"(
+flags           : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
+)");
+#endif  // CPU_FEATURES_OS_LINUX_OR_ANDROID
+  g_fake_cpu->SetLeaves({
+      {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
+      {{0x00000001, 0}, Leaf{0x00030673, 0x00100800, 0x41D8E3BF, 0xBFEBFBFF}},
+      {{0x00000002, 0}, Leaf{0x61B3A001, 0x0000FFC2, 0x00000000, 0x00000000}},
+      {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x00000004, 0}, Leaf{0x1C000121, 0x0140003F, 0x0000003F, 0x00000001}},
+      {{0x00000004, 1}, Leaf{0x1C000122, 0x01C0003F, 0x0000003F, 0x00000001}},
+      {{0x00000004, 2}, Leaf{0x1C00C143, 0x03C0003F, 0x000003FF, 0x00000001}},
+      {{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x33000020}},
+      {{0x00000006, 0}, Leaf{0x00000005, 0x00000002, 0x00000009, 0x00000000}},
+      {{0x00000007, 0}, Leaf{0x00000000, 0x00002282, 0x00000000, 0x00000000}},
+      {{0x00000008, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x00000009, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x0000000A, 0}, Leaf{0x07280203, 0x00000000, 0x00000000, 0x00004503}},
+      {{0x0000000B, 0}, Leaf{0x00000001, 0x00000001, 0x00000100, 0x00000000}},
+      {{0x0000000B, 1}, Leaf{0x00000004, 0x00000004, 0x00000201, 0x00000000}},
+      {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000101, 0x28100000}},
+      {{0x80000002, 0}, Leaf{0x20202020, 0x6E492020, 0x286C6574, 0x43202952}},
+      {{0x80000003, 0}, Leaf{0x72656C65, 0x52286E6F, 0x50432029, 0x4A202055}},
+      {{0x80000004, 0}, Leaf{0x30303931, 0x20402020, 0x39392E31, 0x007A4847}},
+      {{0x80000005, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+      {{0x80000006, 0}, Leaf{0x00000000, 0x00000000, 0x04008040, 0x00000000}},
+      {{0x80000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000100}},
+      {{0x80000008, 0}, Leaf{0x00003024, 0x00000000, 0x00000000, 0x00000000}},
+  });
+  const auto info = GetX86Info();
+
+  EXPECT_STREQ(info.vendor, "GenuineIntel");
+  EXPECT_EQ(info.family, 0x06);
+  EXPECT_EQ(info.model, 0x37);
+  EXPECT_EQ(info.stepping, 0x03);
+  EXPECT_EQ(GetX86Microarchitecture(&info),
+            X86Microarchitecture::INTEL_ATOM_SMT);
+
+  char brand_string[49];
+  FillX86BrandString(brand_string);
+  EXPECT_STREQ(brand_string, "      Intel(R) Celeron(R) CPU  J1900  @ 1.99GHz");
+
+  EXPECT_TRUE(info.features.sse);
+  EXPECT_TRUE(info.features.sse2);
+  EXPECT_TRUE(info.features.sse3);
+#ifndef CPU_FEATURES_OS_WINDOWS
+  // Currently disabled on Windows as IsProcessorFeaturePresent do not support
+  // feature detection > sse3.
+  EXPECT_TRUE(info.features.ssse3);
+  EXPECT_TRUE(info.features.sse4_1);
+  EXPECT_TRUE(info.features.sse4_2);
+#endif  // CPU_FEATURES_OS_WINDOWS
+}
+
+// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000673_P3_KatmaiDP_CPUID.txt
+TEST_F(CpuidX86Test, P3) {
+  // Pre AVX cpus don't have xsave
+  g_fake_cpu->SetOsBackupsExtendedRegisters(false);
+#if defined(CPU_FEATURES_OS_WINDOWS)
+  g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
+      PF_XMMI_INSTRUCTIONS_AVAILABLE);
+#endif  // CPU_FEATURES_OS_WINDOWS
+#if defined(CPU_FEATURES_OS_DARWIN)
+  g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
+#endif  // CPU_FEATURES_OS_DARWIN
+#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
+  auto& fs = GetEmptyFilesystem();
+  fs.CreateFile("/proc/cpuinfo", R"(
+flags           : fpu mmx sse
+)");
+#endif  // CPU_FEATURES_OS_LINUX_OR_ANDROID
+  g_fake_cpu->SetLeaves({
+      {{0x00000000, 0}, Leaf{0x00000003, 0x756E6547, 0x6C65746E, 0x49656E69}},
+      {{0x00000001, 0}, Leaf{0x00000673, 0x00000000, 0x00000000, 0x0387FBFF}},
+      {{0x00000002, 0}, Leaf{0x03020101, 0x00000000, 0x00000000, 0x0C040843}},
+      {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x4CECC782, 0x00006778}},
+  });
+  const auto info = GetX86Info();
+
+  EXPECT_STREQ(info.vendor, "GenuineIntel");
+  EXPECT_EQ(info.family, 0x06);
+  EXPECT_EQ(info.model, 0x07);
+  EXPECT_EQ(info.stepping, 0x03);
+  EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
+
+  char brand_string[49];
+  FillX86BrandString(brand_string);
+  EXPECT_STREQ(brand_string, "");
+
+  EXPECT_TRUE(info.features.mmx);
+  EXPECT_TRUE(info.features.sse);
+  EXPECT_FALSE(info.features.sse2);
+  EXPECT_FALSE(info.features.sse3);
+#ifndef CPU_FEATURES_OS_WINDOWS
+  // Currently disabled on Windows as IsProcessorFeaturePresent do not support
+  // feature detection > sse3.
+  EXPECT_FALSE(info.features.ssse3);
+  EXPECT_FALSE(info.features.sse4_1);
+  EXPECT_FALSE(info.features.sse4_2);
+#endif  // CPU_FEATURES_OS_WINDOWS
+}
+
 // TODO(user): test what happens when xsave/osxsave are not present.
 // TODO(user): test what happens when xmm/ymm/zmm os support are not
 // present.
diff --git a/test/filesystem_for_testing.cc b/test/filesystem_for_testing.cc
index 0a11416..648a53e 100644
--- a/test/filesystem_for_testing.cc
+++ b/test/filesystem_for_testing.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/test/filesystem_for_testing.h b/test/filesystem_for_testing.h
index 7474b5f..ef717fd 100644
--- a/test/filesystem_for_testing.h
+++ b/test/filesystem_for_testing.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/test/hwcaps_for_testing.cc b/test/hwcaps_for_testing.cc
index 07f68e8..a8086a0 100644
--- a/test/hwcaps_for_testing.cc
+++ b/test/hwcaps_for_testing.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,9 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "hwcaps_for_testing.h"
+
 #include <string.h>
 
-#include "hwcaps_for_testing.h"
 #include "internal/string_view.h"
 
 namespace cpu_features {
diff --git a/test/hwcaps_for_testing.h b/test/hwcaps_for_testing.h
index 0d03777..bcab82e 100644
--- a/test/hwcaps_for_testing.h
+++ b/test/hwcaps_for_testing.h
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/test/stack_line_reader_test.cc b/test/stack_line_reader_test.cc
index c8f9691..9ac5388 100644
--- a/test/stack_line_reader_test.cc
+++ b/test/stack_line_reader_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
 // limitations under the License.
 
 #include "internal/stack_line_reader.h"
-#include "filesystem_for_testing.h"
 
+#include "filesystem_for_testing.h"
 #include "gtest/gtest.h"
 
 namespace cpu_features {
diff --git a/test/string_view_test.cc b/test/string_view_test.cc
index 0b6c7c2..ca3e023 100644
--- a/test/string_view_test.cc
+++ b/test/string_view_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2017 Google Inc.
+// Copyright 2017 Google LLC
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -117,13 +117,13 @@
 
 TEST(StringViewTest, CpuFeatures_StringView_TrimWhitespace) {
   EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("  first middle last  ")),
-                                                  str("first middle last"));
+            str("first middle last"));
   EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("first middle last  ")),
-                                                  str("first middle last"));
+            str("first middle last"));
   EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("  first middle last")),
-                                                  str("first middle last"));
+            str("first middle last"));
   EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("first middle last")),
-                                                  str("first middle last"));
+            str("first middle last"));
 }
 
 TEST(StringViewTest, CpuFeatures_StringView_ParsePositiveNumber) {
diff --git a/test/unix_features_aggregator_test.cc b/test/unix_features_aggregator_test.cc
deleted file mode 100644
index 9017644..0000000
--- a/test/unix_features_aggregator_test.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2017 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <array>
-
-#include "internal/unix_features_aggregator.h"
-
-#include "gtest/gtest.h"
-
-namespace cpu_features {
-
-namespace {
-
-struct Features {
-  bool a = false;
-  bool b = false;
-  bool c = false;
-};
-
-enum eFeatures {
-  TEST_a,
-  TEST_b,
-  TEST_c
-};
-
-DECLARE_SETTER_AND_GETTER(Features, a)
-DECLARE_SETTER_AND_GETTER(Features, b)
-DECLARE_SETTER_AND_GETTER(Features, c)
-
-class LinuxFeatureAggregatorTest : public testing::Test {
- public:
-  const std::array<CapabilityConfig, 3> kConfigs = {{
-    {{0b0001, 0b0000}, "a", &set_a, &get_a},
-    {{0b0010, 0b0000}, "b", &set_b, &get_b},
-    {{0b0000, 0b1100}, "c", &set_c, &get_c}
-  }};
-};
-
-TEST_F(LinuxFeatureAggregatorTest, FromFlagsEmpty) {
-  Features features;
-  CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str(""),
-                           &features);
-  EXPECT_FALSE(features.a);
-  EXPECT_FALSE(features.b);
-  EXPECT_FALSE(features.c);
-
-  EXPECT_FALSE(kConfigs[TEST_a].get_bit(&features));
-}
-
-TEST_F(LinuxFeatureAggregatorTest, FromFlagsAllSet) {
-  Features features;
-  CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a c b"),
-                           &features);
-  EXPECT_TRUE(features.a);
-  EXPECT_TRUE(features.b);
-  EXPECT_TRUE(features.c);
-
-  EXPECT_TRUE(kConfigs[TEST_a].get_bit(&features));
-}
-
-TEST_F(LinuxFeatureAggregatorTest, FromFlagsOnlyA) {
-  Features features;
-  CpuFeatures_SetFromFlags(kConfigs.size(), kConfigs.data(), str("a"),
-                           &features);
-  EXPECT_TRUE(features.a);
-  EXPECT_FALSE(features.b);
-  EXPECT_FALSE(features.c);
-
-  EXPECT_TRUE(kConfigs[TEST_a].get_bit(&features));
-  EXPECT_FALSE(kConfigs[TEST_b].get_bit(&features));
-  EXPECT_FALSE(kConfigs[TEST_c].get_bit(&features));
-}
-
-TEST_F(LinuxFeatureAggregatorTest, FromHwcapsNone) {
-  HardwareCapabilities capability;
-  capability.hwcaps = 0;   // matches none
-  capability.hwcaps2 = 0;  // matches none
-  Features features;
-  CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability,
-                                 &features);
-  EXPECT_FALSE(features.a);
-  EXPECT_FALSE(features.b);
-  EXPECT_FALSE(features.c);
-}
-
-TEST_F(LinuxFeatureAggregatorTest, FromHwcapsSet) {
-  HardwareCapabilities capability;
-  capability.hwcaps = 0b0010;   // matches b but not a
-  capability.hwcaps2 = 0b1111;  // matches c
-  Features features;
-  CpuFeatures_OverrideFromHwCaps(kConfigs.size(), kConfigs.data(), capability,
-                                 &features);
-  EXPECT_FALSE(features.a);
-  EXPECT_TRUE(features.b);
-  EXPECT_TRUE(features.c);
-}
-
-}  // namespace
-}  // namespace cpu_features