xref: /aosp_15_r20/external/cpu_features/README.md (revision eca53ba6d2e951e174b64682eaf56a36b8204c89)
1*eca53ba6SRoland Levillain# cpu_features
2*eca53ba6SRoland Levillain
3*eca53ba6SRoland LevillainA cross-platform C library to retrieve CPU features (such as available
4*eca53ba6SRoland Levillaininstructions) at runtime.
5*eca53ba6SRoland Levillain
6*eca53ba6SRoland Levillain# GitHub-CI Status
7*eca53ba6SRoland Levillain
8*eca53ba6SRoland Levillain[comment]: <> (The following lines are generated by "scripts/generate_badges.d" that you can run online https://run.dlang.io/)
9*eca53ba6SRoland Levillain
10*eca53ba6SRoland Levillain|  | Linux | FreeBSD | MacOS | Windows |
11*eca53ba6SRoland Levillain| :-- | --: | --: | --: | --: |
12*eca53ba6SRoland Levillain| amd64 | [![CMake][i1a0]][l1a0]<br/>[![Bazel][i1a1]][l1a1] | [![CMake][i2a0]][l2a0]<br/>![Bazel][d1] | [![CMake][i3a0]][l3a0]<br/>[![Bazel][i3a1]][l3a1] | [![CMake][i4a0]][l4a0]<br/>![Bazel][d1] |
13*eca53ba6SRoland Levillain| AArch64 | [![CMake][i1b0]][l1b0]<br/>[![Bazel][i1b1]][l1b1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
14*eca53ba6SRoland Levillain| ARM | [![CMake][i1c0]][l1c0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
15*eca53ba6SRoland Levillain| MIPS | [![CMake][i1d0]][l1d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
16*eca53ba6SRoland Levillain| POWER | [![CMake][i1e0]][l1e0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
17*eca53ba6SRoland Levillain| RISCV | [![CMake][i1f0]][l1f0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
18*eca53ba6SRoland Levillain| LOONGARCH | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
19*eca53ba6SRoland Levillain| s390x | [![CMake][i1h0]][l1h0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] | ![CMake][d0]<br/>![Bazel][d1] |
20*eca53ba6SRoland Levillain
21*eca53ba6SRoland Levillain[d0]: https://img.shields.io/badge/n%2Fa-lightgrey?&logo=cmake
22*eca53ba6SRoland Levillain[d1]: https://img.shields.io/badge/n%2Fa-lightgrey?&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4=
23*eca53ba6SRoland Levillain[i1a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
24*eca53ba6SRoland Levillain[i1a1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_linux_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4=
25*eca53ba6SRoland Levillain[i1b0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/aarch64_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
26*eca53ba6SRoland Levillain[i1b1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/aarch64_linux_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4=
27*eca53ba6SRoland Levillain[i1c0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/arm_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
28*eca53ba6SRoland Levillain[i1d0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/mips_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
29*eca53ba6SRoland Levillain[i1e0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/power_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
30*eca53ba6SRoland Levillain[i1f0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/riscv_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
31*eca53ba6SRoland Levillain[i1h0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/s390x_linux_cmake.yml?branch=main&event=push&label=&logo=cmake
32*eca53ba6SRoland Levillain[i2a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_freebsd_cmake.yml?branch=main&event=push&label=&logo=cmake
33*eca53ba6SRoland Levillain[i3a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_macos_cmake.yml?branch=main&event=push&label=&logo=cmake
34*eca53ba6SRoland Levillain[i3a1]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_macos_bazel.yml?branch=main&event=push&label=&logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNiAuMTZsNS43ODYgNS43ODZMNiAxMS43MzIuMjE0IDUuOTQ2IDYgLjE2MXpNMCA2LjIxNFYxMmw1Ljc4NiA1Ljc4NlYxMkwwIDYuMjE0ek0xOCAuMTZsNS43ODYgNS43ODZMMTggMTEuNzMybC01Ljc4Ni01Ljc4NkwxOCAuMTYxek0yNCA2LjIxNFYxMmwtNS43ODYgNS43ODZWMTJMMjQgNi4yMTR6TTEyIDYuMTZsNS43ODYgNS43ODZMMTIgMTcuNzMybC01Ljc4Ni01Ljc4NkwxMiA2LjE2MXpNMTEuODQgMTguMDU0djUuNzg1bC01Ljc4Ni01Ljc4NXYtNS43ODZsNS43ODUgNS43ODZ6TTEyLjE2IDE4LjA1NGw1Ljc4Ni01Ljc4NnY1Ljc4NmwtNS43ODUgNS43ODV2LTUuNzg1eiIgc3Ryb2tlPSJ0cmFuc3BhcmVudCIgZmlsbD0id2hpdGUiLz48L3N2Zz4=
35*eca53ba6SRoland Levillain[i4a0]: https://img.shields.io/github/actions/workflow/status/google/cpu_features/amd64_windows_cmake.yml?branch=main&event=push&label=&logo=cmake
36*eca53ba6SRoland Levillain[l1a0]: https://github.com/google/cpu_features/actions/workflows/amd64_linux_cmake.yml
37*eca53ba6SRoland Levillain[l1a1]: https://github.com/google/cpu_features/actions/workflows/amd64_linux_bazel.yml
38*eca53ba6SRoland Levillain[l1b0]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_cmake.yml
39*eca53ba6SRoland Levillain[l1b1]: https://github.com/google/cpu_features/actions/workflows/aarch64_linux_bazel.yml
40*eca53ba6SRoland Levillain[l1c0]: https://github.com/google/cpu_features/actions/workflows/arm_linux_cmake.yml
41*eca53ba6SRoland Levillain[l1d0]: https://github.com/google/cpu_features/actions/workflows/mips_linux_cmake.yml
42*eca53ba6SRoland Levillain[l1e0]: https://github.com/google/cpu_features/actions/workflows/power_linux_cmake.yml
43*eca53ba6SRoland Levillain[l1f0]: https://github.com/google/cpu_features/actions/workflows/riscv_linux_cmake.yml
44*eca53ba6SRoland Levillain[l1h0]: https://github.com/google/cpu_features/actions/workflows/s390x_linux_cmake.yml
45*eca53ba6SRoland Levillain[l2a0]: https://github.com/google/cpu_features/actions/workflows/amd64_freebsd_cmake.yml
46*eca53ba6SRoland Levillain[l3a0]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_cmake.yml
47*eca53ba6SRoland Levillain[l3a1]: https://github.com/google/cpu_features/actions/workflows/amd64_macos_bazel.yml
48*eca53ba6SRoland Levillain[l4a0]: https://github.com/google/cpu_features/actions/workflows/amd64_windows_cmake.yml
49*eca53ba6SRoland Levillain
50*eca53ba6SRoland Levillain## Table of Contents
51*eca53ba6SRoland Levillain
52*eca53ba6SRoland Levillain- [Design Rationale](#rationale)
53*eca53ba6SRoland Levillain- [Code samples](#codesample)
54*eca53ba6SRoland Levillain- [Running sample code](#usagesample)
55*eca53ba6SRoland Levillain- [What's supported](#support)
56*eca53ba6SRoland Levillain- [Android NDK's drop in replacement](#ndk)
57*eca53ba6SRoland Levillain- [License](#license)
58*eca53ba6SRoland Levillain- [Build with cmake](#cmake)
59*eca53ba6SRoland Levillain- [Community Bindings](#bindings)
60*eca53ba6SRoland Levillain
61*eca53ba6SRoland Levillain<a name="rationale"></a>
62*eca53ba6SRoland Levillain## Design Rationale
63*eca53ba6SRoland Levillain
64*eca53ba6SRoland Levillain-   **Simple to use.** See the snippets below for examples.
65*eca53ba6SRoland Levillain-   **Extensible.** Easy to add missing features or architectures.
66*eca53ba6SRoland Levillain-   **Compatible with old compilers** and available on many architectures so it
67*eca53ba6SRoland Levillain    can be used widely. To ensure that cpu_features works on as many platforms
68*eca53ba6SRoland Levillain    as possible, we implemented it in a highly portable version of C: C99.
69*eca53ba6SRoland Levillain-   **Sandbox-compatible.** The library uses a variety of strategies to cope
70*eca53ba6SRoland Levillain    with sandboxed environments or when `cpuid` is unavailable. This is useful
71*eca53ba6SRoland Levillain    when running integration tests in hermetic environments.
72*eca53ba6SRoland Levillain-   **Thread safe, no memory allocation, and raises no exceptions.**
73*eca53ba6SRoland Levillain    cpu_features is suitable for implementing fundamental libc functions like
74*eca53ba6SRoland Levillain    `malloc`, `memcpy`, and `memcmp`.
75*eca53ba6SRoland Levillain-   **Unit tested.**
76*eca53ba6SRoland Levillain
77*eca53ba6SRoland Levillain<a name="codesample"></a>
78*eca53ba6SRoland Levillain## Code samples
79*eca53ba6SRoland Levillain
80*eca53ba6SRoland Levillain**Note:** For C++ code, the library functions are defined in the `cpu_features` namespace.
81*eca53ba6SRoland Levillain
82*eca53ba6SRoland Levillain### Checking features at runtime
83*eca53ba6SRoland Levillain
84*eca53ba6SRoland LevillainHere's a simple example that executes a codepath if the CPU supports both the
85*eca53ba6SRoland LevillainAES and the SSE4.2 instruction sets:
86*eca53ba6SRoland Levillain
87*eca53ba6SRoland Levillain```c
88*eca53ba6SRoland Levillain#include "cpuinfo_x86.h"
89*eca53ba6SRoland Levillain
90*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;`
91*eca53ba6SRoland Levillainstatic const X86Features features = GetX86Info().features;
92*eca53ba6SRoland Levillain
93*eca53ba6SRoland Levillainvoid Compute(void) {
94*eca53ba6SRoland Levillain  if (features.aes && features.sse4_2) {
95*eca53ba6SRoland Levillain    // Run optimized code.
96*eca53ba6SRoland Levillain  } else {
97*eca53ba6SRoland Levillain    // Run standard code.
98*eca53ba6SRoland Levillain  }
99*eca53ba6SRoland Levillain}
100*eca53ba6SRoland Levillain```
101*eca53ba6SRoland Levillain
102*eca53ba6SRoland Levillain### Caching for faster evaluation of complex checks
103*eca53ba6SRoland Levillain
104*eca53ba6SRoland LevillainIf you wish, you can read all the features at once into a global variable, and
105*eca53ba6SRoland Levillainthen query for the specific features you care about. Below, we store all the ARM
106*eca53ba6SRoland Levillainfeatures and then check whether AES and NEON are supported.
107*eca53ba6SRoland Levillain
108*eca53ba6SRoland Levillain```c
109*eca53ba6SRoland Levillain#include <stdbool.h>
110*eca53ba6SRoland Levillain#include "cpuinfo_arm.h"
111*eca53ba6SRoland Levillain
112*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;`
113*eca53ba6SRoland Levillainstatic const ArmFeatures features = GetArmInfo().features;
114*eca53ba6SRoland Levillainstatic const bool has_aes_and_neon = features.aes && features.neon;
115*eca53ba6SRoland Levillain
116*eca53ba6SRoland Levillain// use has_aes_and_neon.
117*eca53ba6SRoland Levillain```
118*eca53ba6SRoland Levillain
119*eca53ba6SRoland LevillainThis is a good approach to take if you're checking for combinations of features
120*eca53ba6SRoland Levillainwhen using a compiler that is slow to extract individual bits from bit-packed
121*eca53ba6SRoland Levillainstructures.
122*eca53ba6SRoland Levillain
123*eca53ba6SRoland Levillain### Checking compile time flags
124*eca53ba6SRoland Levillain
125*eca53ba6SRoland LevillainThe following code determines whether the compiler was told to use the AVX
126*eca53ba6SRoland Levillaininstruction set (e.g., `g++ -mavx`) and sets `has_avx` accordingly.
127*eca53ba6SRoland Levillain
128*eca53ba6SRoland Levillain```c
129*eca53ba6SRoland Levillain#include <stdbool.h>
130*eca53ba6SRoland Levillain#include "cpuinfo_x86.h"
131*eca53ba6SRoland Levillain
132*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;`
133*eca53ba6SRoland Levillainstatic const X86Features features = GetX86Info().features;
134*eca53ba6SRoland Levillainstatic const bool has_avx = CPU_FEATURES_COMPILED_X86_AVX || features.avx;
135*eca53ba6SRoland Levillain
136*eca53ba6SRoland Levillain// use has_avx.
137*eca53ba6SRoland Levillain```
138*eca53ba6SRoland Levillain
139*eca53ba6SRoland Levillain`CPU_FEATURES_COMPILED_X86_AVX` is set to 1 if the compiler was instructed to
140*eca53ba6SRoland Levillainuse AVX and 0 otherwise, combining compile time and runtime knowledge.
141*eca53ba6SRoland Levillain
142*eca53ba6SRoland Levillain### Rejecting poor hardware implementations based on microarchitecture
143*eca53ba6SRoland Levillain
144*eca53ba6SRoland LevillainOn x86, the first incarnation of a feature in a microarchitecture might not be
145*eca53ba6SRoland Levillainthe most efficient (e.g. AVX on Sandy Bridge). We provide a function to retrieve
146*eca53ba6SRoland Levillainthe underlying microarchitecture so you can decide whether to use it.
147*eca53ba6SRoland Levillain
148*eca53ba6SRoland LevillainBelow, `has_fast_avx` is set to 1 if the CPU supports the AVX instruction
149*eca53ba6SRoland Levillainset&mdash;but only if it's not Sandy Bridge.
150*eca53ba6SRoland Levillain
151*eca53ba6SRoland Levillain```c
152*eca53ba6SRoland Levillain#include <stdbool.h>
153*eca53ba6SRoland Levillain#include "cpuinfo_x86.h"
154*eca53ba6SRoland Levillain
155*eca53ba6SRoland Levillain// For C++, add `using namespace cpu_features;`
156*eca53ba6SRoland Levillainstatic const X86Info info = GetX86Info();
157*eca53ba6SRoland Levillainstatic const X86Microarchitecture uarch = GetX86Microarchitecture(&info);
158*eca53ba6SRoland Levillainstatic const bool has_fast_avx = info.features.avx && uarch != INTEL_SNB;
159*eca53ba6SRoland Levillain
160*eca53ba6SRoland Levillain// use has_fast_avx.
161*eca53ba6SRoland Levillain```
162*eca53ba6SRoland Levillain
163*eca53ba6SRoland LevillainThis feature is currently available only for x86 microarchitectures.
164*eca53ba6SRoland Levillain
165*eca53ba6SRoland Levillain<a name="usagesample"></a>
166*eca53ba6SRoland Levillain### Running sample code
167*eca53ba6SRoland Levillain
168*eca53ba6SRoland LevillainBuilding `cpu_features` (check [quickstart](#quickstart) below) brings a small executable to test the library.
169*eca53ba6SRoland Levillain
170*eca53ba6SRoland Levillain```shell
171*eca53ba6SRoland Levillain % ./build/list_cpu_features
172*eca53ba6SRoland Levillainarch            : x86
173*eca53ba6SRoland Levillainbrand           :        Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz
174*eca53ba6SRoland Levillainfamily          :   6 (0x06)
175*eca53ba6SRoland Levillainmodel           :  45 (0x2D)
176*eca53ba6SRoland Levillainstepping        :   7 (0x07)
177*eca53ba6SRoland Levillainuarch           : INTEL_SNB
178*eca53ba6SRoland Levillainflags           : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
179*eca53ba6SRoland Levillain```
180*eca53ba6SRoland Levillain
181*eca53ba6SRoland Levillain```shell
182*eca53ba6SRoland Levillain% ./build/list_cpu_features --json
183*eca53ba6SRoland Levillain{"arch":"x86","brand":"       Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz","family":6,"model":45,"stepping":7,"uarch":"INTEL_SNB","flags":["aes","avx","cx16","smx","sse4_1","sse4_2","ssse3"]}
184*eca53ba6SRoland Levillain```
185*eca53ba6SRoland Levillain
186*eca53ba6SRoland Levillain<a name="support"></a>
187*eca53ba6SRoland Levillain## What's supported
188*eca53ba6SRoland Levillain
189*eca53ba6SRoland Levillain|         | x86³ | AArch64 | ARM     | MIPS⁴   | POWER   | RISCV   | Loongarch | s390x   |
190*eca53ba6SRoland Levillain|---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|:---------:|:-------:|
191*eca53ba6SRoland Levillain| Linux   | yes² | yes¹    | yes¹    | yes¹    | yes¹    | yes¹    | yes¹      | yes¹    |
192*eca53ba6SRoland Levillain| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A     | not yet   | not yet |
193*eca53ba6SRoland Levillain| MacOs   | yes² | yes⁵    | N/A     | N/A     | N/A     | N/A     | N/A       | N/A     |
194*eca53ba6SRoland Levillain| Windows | yes² | not yet | not yet | N/A     | N/A     | N/A     | N/A       | N/A     |
195*eca53ba6SRoland Levillain| Android | yes² | yes¹    | yes¹    | yes¹    | N/A     | N/A     | N/A       | N/A     |
196*eca53ba6SRoland Levillain| iOS     | N/A  | not yet | not yet | N/A     | N/A     | N/A     | N/A       | N/A     |
197*eca53ba6SRoland Levillain
198*eca53ba6SRoland Levillain1.  **Features revealed from Linux.** We gather data from several sources
199*eca53ba6SRoland Levillain    depending on availability:
200*eca53ba6SRoland Levillain    +   from glibc's
201*eca53ba6SRoland Levillain        [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html)
202*eca53ba6SRoland Levillain    +   by parsing `/proc/self/auxv`
203*eca53ba6SRoland Levillain    +   by parsing `/proc/cpuinfo`
204*eca53ba6SRoland Levillain2.  **Features revealed from CPU.** features are retrieved by using the `cpuid`
205*eca53ba6SRoland Levillain    instruction.
206*eca53ba6SRoland Levillain3.  **Microarchitecture detection.** On x86 some features are not always
207*eca53ba6SRoland Levillain    implemented efficiently in hardware (e.g. AVX on Sandybridge). Exposing the
208*eca53ba6SRoland Levillain    microarchitecture allows the client to reject particular microarchitectures.
209*eca53ba6SRoland Levillain4.  All flavors of Mips are supported, little and big endian as well as 32/64
210*eca53ba6SRoland Levillain    bits.
211*eca53ba6SRoland Levillain5.  **Features revealed from sysctl.** features are retrieved by the `sysctl`
212*eca53ba6SRoland Levillain    instruction.
213*eca53ba6SRoland Levillain
214*eca53ba6SRoland Levillain<a name="ndk"></a>
215*eca53ba6SRoland Levillain## Android NDK's drop in replacement
216*eca53ba6SRoland Levillain
217*eca53ba6SRoland Levillain[cpu_features](https://github.com/google/cpu_features) is now officially
218*eca53ba6SRoland Levillainsupporting Android and offers a drop in replacement of for the NDK's [cpu-features.h](https://android.googlesource.com/platform/ndk/+/main/sources/android/cpufeatures/cpu-features.h)
219*eca53ba6SRoland Levillain, see [ndk_compat](ndk_compat) folder for details.
220*eca53ba6SRoland Levillain
221*eca53ba6SRoland Levillain<a name="license"></a>
222*eca53ba6SRoland Levillain## License
223*eca53ba6SRoland Levillain
224*eca53ba6SRoland LevillainThe cpu_features library is licensed under the terms of the Apache license.
225*eca53ba6SRoland LevillainSee [LICENSE](LICENSE) for more information.
226*eca53ba6SRoland Levillain
227*eca53ba6SRoland Levillain<a name="cmake"></a>
228*eca53ba6SRoland Levillain## Build with CMake
229*eca53ba6SRoland Levillain
230*eca53ba6SRoland LevillainPlease check the [CMake build instructions](cmake/README.md).
231*eca53ba6SRoland Levillain
232*eca53ba6SRoland Levillain<a name="quickstart"></a>
233*eca53ba6SRoland Levillain### Quickstart
234*eca53ba6SRoland Levillain
235*eca53ba6SRoland Levillain- Run `list_cpu_features`
236*eca53ba6SRoland Levillain  ```sh
237*eca53ba6SRoland Levillain  cmake -S. -Bbuild -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release
238*eca53ba6SRoland Levillain  cmake --build build --config Release -j
239*eca53ba6SRoland Levillain  ./build/list_cpu_features --json
240*eca53ba6SRoland Levillain  ```
241*eca53ba6SRoland Levillain
242*eca53ba6SRoland Levillain  _Note_: Use `--target ALL_BUILD` on the second line for `Visual Studio` and `XCode`.
243*eca53ba6SRoland Levillain
244*eca53ba6SRoland Levillain- run tests
245*eca53ba6SRoland Levillain  ```sh
246*eca53ba6SRoland Levillain  cmake -S. -Bbuild -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Debug
247*eca53ba6SRoland Levillain  cmake --build build --config Debug -j
248*eca53ba6SRoland Levillain  cmake --build build --config Debug --target test
249*eca53ba6SRoland Levillain  ```
250*eca53ba6SRoland Levillain
251*eca53ba6SRoland Levillain  _Note_: Use `--target RUN_TESTS` on the last line for `Visual Studio` and `--target RUN_TEST` for `XCode`.
252*eca53ba6SRoland Levillain
253*eca53ba6SRoland Levillain
254*eca53ba6SRoland Levillain- install `cpu_features`
255*eca53ba6SRoland Levillain  ```sh
256*eca53ba6SRoland Levillain  cmake --build build --config Release --target install -v
257*eca53ba6SRoland Levillain  ```
258*eca53ba6SRoland Levillain
259*eca53ba6SRoland Levillain  _Note_: Use `--target INSTALL` for `Visual Studio`.
260*eca53ba6SRoland Levillain
261*eca53ba6SRoland Levillain  _Note_: When using `Makefile` or `XCode` generator, you can use
262*eca53ba6SRoland Levillain  [`DESTDIR`](https://www.gnu.org/software/make/manual/html_node/DESTDIR.html)
263*eca53ba6SRoland Levillain  to install on a local repository.<br>
264*eca53ba6SRoland Levillain  e.g.
265*eca53ba6SRoland Levillain  ```sh
266*eca53ba6SRoland Levillain  cmake --build build --config Release --target install -v -- DESTDIR=install
267*eca53ba6SRoland Levillain  ```
268*eca53ba6SRoland Levillain
269*eca53ba6SRoland Levillain<a name="bindings"></a>
270*eca53ba6SRoland Levillain## Community bindings
271*eca53ba6SRoland Levillain
272*eca53ba6SRoland LevillainLinks provided here are not affiliated with Google but are kindly provided by the OSS Community.
273*eca53ba6SRoland Levillain
274*eca53ba6SRoland Levillain - .Net
275*eca53ba6SRoland Levillain   - https://github.com/toor1245/cpu_features.NET
276*eca53ba6SRoland Levillain - Python
277*eca53ba6SRoland Levillain   - https://github.com/Narasimha1997/py_cpu
278*eca53ba6SRoland Levillain - Java
279*eca53ba6SRoland Levillain   - https://github.com/aecsocket/cpu-features-java
280*eca53ba6SRoland Levillain
281*eca53ba6SRoland Levillain
282*eca53ba6SRoland Levillain_Send PR to showcase your wrapper here_
283