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_