Adding code. Closes #0.
diff --git a/include/cpu_features_macros.h b/include/cpu_features_macros.h
new file mode 100644
index 0000000..a8d4229
--- /dev/null
+++ b/include/cpu_features_macros.h
@@ -0,0 +1,121 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
+
+////////////////////////////////////////////////////////////////////////////////
+// Architectures
+////////////////////////////////////////////////////////////////////////////////
+
+#if ((defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
+      defined(__x86_64__)) &&                                     \
+     !defined(__pnacl__) && !defined(__CLR_VER))
+#define CPU_FEATURES_ARCH_X86
+#endif
+
+#if (defined(__arm__) || defined(_M_ARM))
+#define CPU_FEATURES_ARCH_ARM
+#endif
+
+#if defined(__aarch64__)
+#define CPU_FEATURES_ARCH_AARCH64
+#endif
+
+#if (defined(CPU_FEATURES_ARCH_AARCH64) || defined(CPU_FEATURES_ARCH_ARM))
+#define CPU_FEATURES_ARCH_ANY_ARM
+#endif
+
+#if defined(__mips__)
+#define CPU_FEATURES_ARCH_MIPS
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Os
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__linux__)
+#define CPU_FEATURES_OS_LINUX_OR_ANDROID
+#endif
+
+#if defined(__ANDROID__)
+#define CPU_FEATURES_OS_ANDROID
+#endif
+
+#if (defined(_WIN64) || defined(_WIN32))
+#define CPU_FEATURES_OS_WINDOWS
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Compilers
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__clang__)
+#define CPU_FEATURES_COMPILER_CLANG
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+#define CPU_FEATURES_COMPILER_GCC
+#endif
+
+#if defined(_MSC_VER)
+#define CPU_FEATURES_COMPILER_MSC
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Cpp
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(__cplusplus)
+#define START_CPP_NAMESPACE \
+  namespace cpu_features {  \
+  extern "C" {
+#define END_CPP_NAMESPACE \
+  }                       \
+  }
+#else
+#define START_CPP_NAMESPACE
+#define END_CPP_NAMESPACE
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Compiler flags
+////////////////////////////////////////////////////////////////////////////////
+
+// Use the following to check if a feature is known to be available at compile
+// time. See README.md for an example.
+#if defined(CPU_FEATURES_ARCH_X86)
+#define CPU_FEATURES_COMPILED_X86_AES defined(__AES__)
+#define CPU_FEATURES_COMPILED_X86_F16C defined(__F16C__)
+#define CPU_FEATURES_COMPILED_X86_BMI defined(__BMI__)
+#define CPU_FEATURES_COMPILED_X86_BMI2 defined(__BMI2__)
+#define CPU_FEATURES_COMPILED_X86_SSE (defined(__SSE__) || (_M_IX86_FP >= 1))
+#define CPU_FEATURES_COMPILED_X86_SSE2 (defined(__SSE2__) || (_M_IX86_FP >= 2))
+#define CPU_FEATURES_COMPILED_X86_SSE3 defined(__SSE3__)
+#define CPU_FEATURES_COMPILED_X86_SSSE3 defined(__SSSE3__)
+#define CPU_FEATURES_COMPILED_X86_SSE4_1 defined(__SSE4_1__)
+#define CPU_FEATURES_COMPILED_X86_SSE4_2 defined(__SSE4_2__)
+#define CPU_FEATURES_COMPILED_X86_AVX defined(__AVX__)
+#define CPU_FEATURES_COMPILED_x86_AVX2 defined(__AVX2__)
+#endif
+
+#if defined(CPU_FEATURES_ARCH_ANY_ARM)
+#define CPU_FEATURES_COMPILED_ANY_ARM_NEON defined(__ARM_NEON__)
+#endif
+
+#if defined(CPU_FEATURES_ARCH_MIPS)
+#define CPU_FEATURES_COMPILED_MIPS_MSA defined(__mips_msa)
+#endif
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
diff --git a/include/cpuinfo_aarch64.h b/include/cpuinfo_aarch64.h
new file mode 100644
index 0000000..3948153
--- /dev/null
+++ b/include/cpuinfo_aarch64.h
@@ -0,0 +1,65 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
+
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+typedef struct {
+  int fp : 1;     // Floating-point.
+  int asimd : 1;  // Advanced SIMD.
+  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 Aarch64FeaturesEnum below if you add a field here.
+} Aarch64Features;
+
+typedef struct {
+  Aarch64Features features;
+  int implementer;
+  int variant;
+  int part;
+  int revision;
+} Aarch64Info;
+
+Aarch64Info GetAarch64Info(void);
+
+////////////////////////////////////////////////////////////////////////////////
+// Introspection functions
+
+typedef enum {
+  AARCH64_FP,
+  AARCH64_ASIMD,
+  AARCH64_AES,
+  AARCH64_PMULL,
+  AARCH64_SHA1,
+  AARCH64_SHA2,
+  AARCH64_CRC32,
+  AARCH64_LAST_,
+} Aarch64FeaturesEnum;
+
+int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
+                                Aarch64FeaturesEnum value);
+
+const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
diff --git a/include/cpuinfo_arm.h b/include/cpuinfo_arm.h
new file mode 100644
index 0000000..cc7e2d9
--- /dev/null
+++ b/include/cpuinfo_arm.h
@@ -0,0 +1,80 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
+
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+typedef struct {
+  int vfp : 1;       // Vector Floating Point.
+  int iwmmxt : 1;    // Intel Wireless MMX Technology.
+  int neon : 1;      // Advanced SIMD.
+  int vfpv3 : 1;     // VFP version 3
+  int vfpv3d16 : 1;  // VFP version 3 with 16 D-registers
+  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 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;
+
+typedef struct {
+  ArmFeatures features;
+  int implementer;
+  int architecture;
+  int variant;
+  int part;
+  int revision;
+} ArmInfo;
+
+// TODO(user): Add macros to know which features are present at compile
+// time.
+
+ArmInfo GetArmInfo(void);
+
+////////////////////////////////////////////////////////////////////////////////
+// Introspection functions
+
+typedef enum {
+  ARM_VFP,
+  ARM_IWMMXT,
+  ARM_NEON,
+  ARM_VFPV3,
+  ARM_VFPV3D16,
+  ARM_VFPV4,
+  ARM_IDIVA,
+  ARM_IDIVT,
+  ARM_AES,
+  ARM_PMULL,
+  ARM_SHA1,
+  ARM_SHA2,
+  ARM_CRC32,
+  ARM_LAST_,
+} ArmFeaturesEnum;
+
+int GetArmFeaturesEnumValue(const ArmFeatures* features, ArmFeaturesEnum value);
+
+const char* GetArmFeaturesEnumName(ArmFeaturesEnum);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
diff --git a/include/cpuinfo_mips.h b/include/cpuinfo_mips.h
new file mode 100644
index 0000000..bcece1e
--- /dev/null
+++ b/include/cpuinfo_mips.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
+
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+typedef struct {
+  int msa : 1;  // MIPS SIMD Architecture
+                // https://www.mips.com/products/architectures/ase/simd/
+  int eva : 1;  // Enhanced Virtual Addressing
+                // https://www.mips.com/products/architectures/mips64/
+
+  // Make sure to update MipsFeaturesEnum below if you add a field here.
+} MipsFeatures;
+
+typedef struct {
+  MipsFeatures features;
+} MipsInfo;
+
+MipsInfo GetMipsInfo(void);
+
+////////////////////////////////////////////////////////////////////////////////
+// Introspection functions
+
+typedef enum {
+  MIPS_MSA,
+  MIPS_EVA,
+  MIPS_LAST_,
+} MipsFeaturesEnum;
+
+int GetMipsFeaturesEnumValue(const MipsFeatures* features,
+                             MipsFeaturesEnum value);
+
+const char* GetMipsFeaturesEnumName(MipsFeaturesEnum);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
diff --git a/include/cpuinfo_x86.h b/include/cpuinfo_x86.h
new file mode 100644
index 0000000..bad8e4d
--- /dev/null
+++ b/include/cpuinfo_x86.h
@@ -0,0 +1,147 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
+
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features.
+typedef struct {
+  int aes : 1;
+  int erms : 1;
+  int f16c : 1;
+  int fma3 : 1;
+  int vpclmulqdq : 1;
+  int bmi1 : 1;
+  int bmi2 : 1;
+
+  int ssse3 : 1;
+  int sse4_1 : 1;
+  int sse4_2 : 1;
+
+  int avx : 1;
+  int avx2 : 1;
+
+  int avx512f : 1;
+  int avx512cd : 1;
+  int avx512er : 1;
+  int avx512pf : 1;
+  int avx512bw : 1;
+  int avx512dq : 1;
+  int avx512vl : 1;
+  int avx512ifma : 1;
+  int avx512vbmi : 1;
+  int avx512vbmi2 : 1;
+  int avx512vnni : 1;
+  int avx512bitalg : 1;
+  int avx512vpopcntdq : 1;
+  int avx512_4vnniw : 1;
+  int avx512_4vbmi2 : 1;
+
+  // Make sure to update X86FeaturesEnum below if you add a field here.
+} X86Features;
+
+typedef struct {
+  X86Features features;
+  int family;
+  int model;
+  int stepping;
+  char vendor[13];  // 0 terminated string
+} X86Info;
+
+// Calls cpuid and returns an initialized X86info.
+// This function is guaranteed to be malloc, memset and memcpy free.
+X86Info GetX86Info(void);
+
+typedef enum {
+  X86_UNKNOWN,
+  INTEL_CORE,      // CORE
+  INTEL_PNR,       // PENRYN
+  INTEL_NHM,       // NEHALEM
+  INTEL_ATOM_BNL,  // BONNELL
+  INTEL_WSM,       // WESTMERE
+  INTEL_SNB,       // SANDYBRIDGE
+  INTEL_IVB,       // IVYBRIDGE
+  INTEL_ATOM_SMT,  // SILVERMONT
+  INTEL_HSW,       // HASWELL
+  INTEL_BDW,       // BROADWELL
+  INTEL_SKL,       // SKYLAKE
+  INTEL_ATOM_GMT,  // GOLDMONT
+  INTEL_KBL,       // KABY LAKE
+  INTEL_CFL,       // COFFEE LAKE
+  INTEL_CNL,       // CANON LAKE
+  AMD_HAMMER,      // K8
+  AMD_K10,         // K10
+  AMD_BOBCAT,      // K14
+  AMD_BULLDOZER,   // K15
+  AMD_JAGUAR,      // K16
+  AMD_ZEN,         // K17
+} X86Microarchitecture;
+
+// Returns the underlying microarchitecture by looking at X86Info's vendor,
+// family and model.
+X86Microarchitecture GetX86Microarchitecture(const X86Info* info);
+
+// Calls cpuid and fills the brand_string.
+// - brand_string *must* be of size 49 (beware of array decaying).
+// - brand_string will be zero terminated.
+// - This function calls memcpy.
+void FillX86BrandString(char brand_string[49]);
+
+////////////////////////////////////////////////////////////////////////////////
+// Introspection functions
+
+typedef enum {
+  X86_AES,
+  X86_ERMS,
+  X86_F16C,
+  X86_FMA3,
+  X86_VPCLMULQDQ,
+  X86_BMI1,
+  X86_BMI2,
+  X86_SSSE3,
+  X86_SSE4_1,
+  X86_SSE4_2,
+  X86_AVX,
+  X86_AVX2,
+  X86_AVX512F,
+  X86_AVX512CD,
+  X86_AVX512ER,
+  X86_AVX512PF,
+  X86_AVX512BW,
+  X86_AVX512DQ,
+  X86_AVX512VL,
+  X86_AVX512IFMA,
+  X86_AVX512VBMI,
+  X86_AVX512VBMI2,
+  X86_AVX512VNNI,
+  X86_AVX512BITALG,
+  X86_AVX512VPOPCNTDQ,
+  X86_AVX512_4VNNIW,
+  X86_AVX512_4VBMI2,
+  X86_LAST_,
+} X86FeaturesEnum;
+
+int GetX86FeaturesEnumValue(const X86Features* features, X86FeaturesEnum value);
+
+const char* GetX86FeaturesEnumName(X86FeaturesEnum);
+
+const char* GetX86MicroarchitectureName(X86Microarchitecture);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
diff --git a/include/internal/bit_utils.h b/include/internal/bit_utils.h
new file mode 100644
index 0000000..b2d42fe
--- /dev/null
+++ b/include/internal/bit_utils.h
@@ -0,0 +1,39 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+inline static bool IsBitSet(uint32_t reg, uint32_t bit) {
+  return (reg >> bit) & 0x1;
+}
+
+inline static uint32_t ExtractBitRange(uint32_t reg, uint32_t msb,
+                                       uint32_t lsb) {
+  const uint64_t bits = msb - lsb + 1;
+  const uint64_t mask = (1ULL << bits) - 1ULL;
+  assert(msb >= lsb);
+  return (reg >> lsb) & mask;
+}
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
diff --git a/include/internal/cpuid_x86.h b/include/internal/cpuid_x86.h
new file mode 100644
index 0000000..dea1ffd
--- /dev/null
+++ b/include/internal/cpuid_x86.h
@@ -0,0 +1,37 @@
+// 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.
+
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
+
+#include <stdint.h>
+
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+// A struct to hold the result of a call to cpuid.
+typedef struct {
+  uint32_t eax, ebx, ecx, edx;
+} Leaf;
+
+// Retrieves the leaf for a particular cpuid.
+Leaf CpuId(uint32_t leaf_id);
+
+// Returns the eax value of the XCR0 register.
+uint32_t GetXCR0Eax(void);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
diff --git a/include/internal/filesystem.h b/include/internal/filesystem.h
new file mode 100644
index 0000000..da4a789
--- /dev/null
+++ b/include/internal/filesystem.h
@@ -0,0 +1,38 @@
+// 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.
+
+// An interface for the filesystem that allows mocking the filesystem in
+// unittests.
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+// Same as linux "open(filename, O_RDONLY)", retries automatically on EINTR.
+int OpenFile(const char* filename);
+
+// Same as linux "read(file_descriptor, buffer, buffer_size)", retries
+// automatically on EINTR.
+int ReadFile(int file_descriptor, void* buffer, size_t buffer_size);
+
+// Same as linux "close(file_descriptor)".
+void CloseFile(int file_descriptor);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_
diff --git a/include/internal/hwcaps.h b/include/internal/hwcaps.h
new file mode 100644
index 0000000..e220b33
--- /dev/null
+++ b/include/internal/hwcaps.h
@@ -0,0 +1,73 @@
+// 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.
+
+// Interface to retrieve hardware capabilities. It relies on Linux's getauxval
+// or `/proc/self/auxval` under the hood.
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
+
+#include <stdint.h>
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+// To avoid depending on the linux kernel we reproduce the architecture specific
+// constants here.
+
+// http://elixir.free-electrons.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h
+#define AARCH64_HWCAP_FP (1UL << 0)
+#define AARCH64_HWCAP_ASIMD (1UL << 1)
+#define AARCH64_HWCAP_AES (1UL << 3)
+#define AARCH64_HWCAP_PMULL (1UL << 4)
+#define AARCH64_HWCAP_SHA1 (1UL << 5)
+#define AARCH64_HWCAP_SHA2 (1UL << 6)
+#define AARCH64_HWCAP_CRC32 (1UL << 7)
+
+// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
+#define ARM_HWCAP_VFP (1UL << 6)
+#define ARM_HWCAP_IWMMXT (1UL << 9)
+#define ARM_HWCAP_NEON (1UL << 12)
+#define ARM_HWCAP_VFPV3 (1UL << 13)
+#define ARM_HWCAP_VFPV3D16 (1UL << 14)
+#define ARM_HWCAP_VFPV4 (1UL << 16)
+#define ARM_HWCAP_IDIVA (1UL << 17)
+#define ARM_HWCAP_IDIVT (1UL << 18)
+#define ARM_HWCAP2_AES (1UL << 0)
+#define ARM_HWCAP2_PMULL (1UL << 1)
+#define ARM_HWCAP2_SHA1 (1UL << 2)
+#define ARM_HWCAP2_SHA2 (1UL << 3)
+#define ARM_HWCAP2_CRC32 (1UL << 4)
+
+// http://elixir.free-electrons.com/linux/latest/source/arch/mips/include/uapi/asm/hwcap.h
+#define MIPS_HWCAP_VZ (1UL << 0)
+#define MIPS_HWCAP_EVA (1UL << 1)
+#define MIPS_HWCAP_HTW (1UL << 2)
+#define MIPS_HWCAP_FPU (1UL << 3)
+#define MIPS_HWCAP_MIPS32R2 (1UL << 4)
+#define MIPS_HWCAP_MIPS32R5 (1UL << 5)
+#define MIPS_HWCAP_MIPS64R6 (1UL << 6)
+#define MIPS_HWCAP_DSPR1 (1UL << 7)
+#define MIPS_HWCAP_DSPR2 (1UL << 8)
+#define MIPS_HWCAP_MSA (1UL << 9)
+
+typedef struct {
+  uint32_t hwcaps;
+  uint32_t hwcaps2;
+} HardwareCapabilities;
+
+HardwareCapabilities GetHardwareCapabilities(void);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_
diff --git a/include/internal/linux_features_aggregator.h b/include/internal/linux_features_aggregator.h
new file mode 100644
index 0000000..5939565
--- /dev/null
+++ b/include/internal/linux_features_aggregator.h
@@ -0,0 +1,58 @@
+// 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 THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
+#define THIRD_PARTY_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"
+
+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;                  \
+  }
+
+// 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.
+} 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 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 OverrideFromHwCaps(const size_t configs_size,
+                        const CapabilityConfig* configs,
+                        const HardwareCapabilities hwcaps,
+                        void* const features);
+
+END_CPP_NAMESPACE
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_LINUX_FEATURES_AGGREGATOR_H_
diff --git a/include/internal/stack_line_reader.h b/include/internal/stack_line_reader.h
new file mode 100644
index 0000000..4fde348
--- /dev/null
+++ b/include/internal/stack_line_reader.h
@@ -0,0 +1,49 @@
+// 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.
+
+// Reads a file line by line and stores the data on the stack. This allows
+// parsing files in one go without allocating.
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
+
+#include <stdbool.h>
+
+#include "cpu_features_macros.h"
+#include "internal/string_view.h"
+
+START_CPP_NAMESPACE
+
+typedef struct {
+  char buffer[STACK_LINE_READER_BUFFER_SIZE];
+  StringView view;
+  int fd;
+  bool skip_mode;
+} StackLineReader;
+
+// Initializes a StackLineReader.
+void StackLineReader_Initialize(StackLineReader* reader, int fd);
+
+typedef struct {
+  StringView line;  // A view of the line.
+  bool eof;         // Nothing more to read, we reached EOF.
+  bool full_line;   // If false the line was truncated to
+                    // STACK_LINE_READER_BUFFER_SIZE.
+} LineResult;
+
+// Reads the file pointed to by fd and tries to read a full line.
+LineResult StackLineReader_NextLine(StackLineReader* reader);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_
diff --git a/include/internal/string_view.h b/include/internal/string_view.h
new file mode 100644
index 0000000..a528ad4
--- /dev/null
+++ b/include/internal/string_view.h
@@ -0,0 +1,101 @@
+// 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.
+
+// A view over a piece of string. The view is not 0 terminated.
+#ifndef THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
+#define THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "cpu_features_macros.h"
+
+START_CPP_NAMESPACE
+
+typedef struct {
+  const char* ptr;
+  size_t size;
+} StringView;
+
+#ifdef __cplusplus
+static const StringView kEmptyStringView = {NULL, 0};
+#else
+static const StringView kEmptyStringView;
+#endif
+
+// Returns a StringView from the provided string.
+// Passing NULL is valid only if size is 0.
+static inline StringView view(const char* str, const size_t size) {
+  StringView view;
+  view.ptr = str;
+  view.size = size;
+  return view;
+}
+
+static inline StringView str(const char* str) { return view(str, strlen(str)); }
+
+// Returns the index of the first occurrence of c in view or -1 if not found.
+int IndexOfChar(const StringView view, char c);
+
+// Returns the index of the first occurrence of sub_view in view or -1 if not
+// found.
+int IndexOf(const StringView view, const StringView sub_view);
+
+// Returns whether a is equal to b (same content).
+bool IsEquals(const StringView a, const StringView b);
+
+// Returns whether a starts with b.
+bool StartsWith(const StringView a, const StringView b);
+
+// Removes count characters from the beginning of view or kEmptyStringView if
+// count if greater than view.size.
+StringView PopFront(const StringView view, size_t count);
+
+// Removes count characters from the end of view or kEmptyStringView if count if
+// greater than view.size.
+StringView PopBack(const StringView str_view, size_t count);
+
+// Keeps the count first characters of view or view if count if greater than
+// view.size.
+StringView KeepFront(const StringView view, size_t count);
+
+// Retrieves the first character of view. If view is empty the behavior is
+// undefined.
+char Front(const StringView view);
+
+// Retrieves the last character of view. If view is empty the behavior is
+// undefined.
+char Back(const StringView view);
+
+// Removes leading and tailing space characters.
+StringView TrimWhitespace(StringView view);
+
+// Convert StringView to positive integer. e.g. "42", "0x2a".
+// Returns -1 on error.
+int ParsePositiveNumber(const StringView view);
+
+// Copies src StringView to dst buffer.
+void CopyString(const StringView src, char* dst, size_t dst_size);
+
+// Checks if line contains the specified whitespace separated word.
+bool HasWord(const StringView line, const char* const word);
+
+// Get key/value from line. key and value are separated by ": ".
+// key and value are cleaned up from leading and trailing whitespaces.
+bool GetAttributeKeyValue(const StringView line, StringView* key,
+                          StringView* value);
+
+END_CPP_NAMESPACE
+
+#endif  // THIRD_PARTY_CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_