Detect CPU features with single-file
Detect CPU ISA features with single-file
CPU | ✅ x86, x86-64 ✅ arm, aarch64 ✅ mips ✅ powerpc ✅ s390x ✅ loongarch ✅ risc-v ✅ openrisc |
|
OS | ✅ Windows ✅ Linux ✅ macOS ✅ Android ✅ iOS ✅ FreeBSD ✅ NetBSD ✅ OpenBSD ✅ DragonflyBSD ✅ Solaris ✅ SyterKit | |
Compiler | ✅ GCC ✅ Clang ✅ MSVC ✅ MinGW |
ruapu.h
in multiple compilation unitsruapu.c
for your projectruapu.c
is ONLY #define RUAPU_IMPLEMENTATION
and #include "ruapu.h"
#include "ruapu.h"
but NO #define RUAPU_IMPLEMENTATION
sse2
, avx
, avx512f
, neon
, etc.
amx
, risc-v vendor ISA, etc.
IsProcessorFeaturePresent()
returns little ISA information
x86-avx512
on macOS correctly
macOS hides it in cpuid
auxv
or MISA
fma4
on zen1, ISA in hypervisor, etc.
CPU | ISA |
---|---|
x86 | mmx sse sse2 sse3 ssse3 sse41 sse42 sse4a xop avx f16c fma fma4 avx2 avx512f avx512bw avx512cd avx512dq avx512vl avx512vnni avx512bf16 avx512ifma avx512vbmi avx512vbmi2 avx512fp16 avx512er avx5124fmaps avx5124vnniw avxvnni avxvnniint8 avxvnniint16 avxifma amxfp16 amxbf16 amxint8 amxtile |
arm | half edsp neon vfpv4 idiv |
aarch64 | neon vfpv4 lse cpuid asimdrdm asimdhp asimddp asimdfhm bf16 i8mm frint jscvt fcma mte mte2 sve sve2 svebf16 svei8mm svef32mm svef64mm sme smef16f16 smef64f64 smei64i64 pmull crc32 aes sha1 sha2 sha3 sha512 sm3 sm4 svepmull svebitperm sveaes svesha3 svesm4 amx |
mips | msa mmi sx asx msa2 crypto |
powerpc | vsx |
s390x | zvector |
loongarch | lsx lasx |
risc-v | i m a f d c zfa zfh zfhmin zicsr zifencei zmmul xtheadba xtheadbb xtheadbs xtheadcondmov xtheadfmemidx xtheadfmv xtheadmac xtheadmemidx xtheadmempair xtheadsync xtheadvdot |
openrisc | orbis32 orbis64 orfpx32 orfpx64 orvdx64 |
Compile ruapu test program
|
Run ruapu in command line
|
Compile and install ruapu library
|
Use ruapu in python
|
Compile ruapu library
|
Use ruapu in Rust
|
Compile ruapu library
|
Use ruapu in Lua
|
Compile ruapu library
|
Use ruapu in Erlang
|
Compile ruapu library
|
Use ruapu in Fortran
|
Compile ruapu library
|
Use ruapu in Golang
|
Add ruapu library to your project
|
Use ruapu in Haskell
|
Compile ruapu library
|
Use ruapu in Vlang
|
Compile ruapu library
|
Use ruapu in Pascal
|
Compile ruapu library and example
Run example
|
Use ruapu in Java
|
mmx = 1
sse = 1
sse2 = 1
sse3 = 1
ssse3 = 1
sse41 = 1
sse42 = 1
sse4a = 1
xop = 0
avx = 1
f16c = 1
fma = 1
avx2 = 1
avx512f = 0
avx512bw = 0
avx512cd = 0
avx512dq = 0
avx512vl = 0
avx512vnni = 0
avx512bf16 = 0
avx512ifma = 0
avx512vbmi = 0
avx512vbmi2 = 0
avx512fp16 = 0
avx512er = 0
avx5124fmaps = 0
avx5124vnniw = 0
avxvnni = 0
avxvnniint8 = 0
avxifma = 0
amxfp16 = 0
amxbf16 = 0
amxint8 = 0
amxtile = 0
mmx = 1
sse = 1
sse2 = 1
sse3 = 1
ssse3 = 1
sse41 = 1
sse42 = 1
sse4a = 0
xop = 0
avx = 1
f16c = 1
fma = 1
avx2 = 1
avx512f = 0
avx512bw = 0
avx512cd = 0
avx512dq = 0
avx512vl = 0
avx512vnni = 0
avx512bf16 = 0
avx512ifma = 0
avx512vbmi = 0
avx512vbmi2 = 0
avx512fp16 = 0
avx512er = 0
avx5124fmaps = 0
avx5124vnniw = 0
avxvnni = 0
avxvnniint8 = 0
avxifma = 0
amxfp16 = 0
amxbf16 = 0
amxint8 = 0
amxtile = 0
neon = 1
vfpv4 = 1
cpuid = 0
asimdhp = 1
asimddp = 1
asimdfhm = 1
bf16 = 0
i8mm = 0
sve = 0
sve2 = 0
svebf16 = 0
svei8mm = 0
svef32mm = 0
mmx = 1
sse = 1
sse2 = 1
sse3 = 1
ssse3 = 1
sse41 = 1
sse42 = 1
sse4a = 1
xop = 0
avx = 1
f16c = 1
fma = 1
avx2 = 1
avx512f = 0
avx512bw = 0
avx512cd = 0
avx512dq = 0
avx512vl = 0
avx512vnni = 0
avx512bf16 = 0
avx512ifma = 0
avx512vbmi = 0
avx512vbmi2 = 0
avx512fp16 = 0
avx512er = 0
avx5124fmaps = 0
avx5124vnniw = 0
avxvnni = 0
avxvnniint8 = 0
avxifma = 0
amxfp16 = 0
amxbf16 = 0
amxint8 = 0
amxtile = 0
mmx = 1
sse = 1
sse2 = 1
sse3 = 1
ssse3 = 1
sse41 = 1
sse42 = 1
sse4a = 1
xop = 0
avx = 1
f16c = 1
fma = 1
fma4 = 0
avx2 = 1
avx512f = 0
avx512bw = 0
avx512cd = 0
avx512dq = 0
avx512vl = 0
avx512vnni = 0
avx512bf16 = 0
avx512ifma = 0
avx512vbmi = 0
avx512vbmi2 = 0
avx512fp16 = 0
avx512er = 0
avx5124fmaps = 0
avx5124vnniw = 0
avxvnni = 0
avxvnniint8 = 0
avxifma = 0
amxfp16 = 0
amxbf16 = 0
amxint8 = 0
amxtile = 0
ruapu is implemented in C language to ensure the widest possible portability.
ruapu determines whether the CPU supports certain instruction sets by trying to execute instructions and detecting whether an Illegal Instruction
exception occurs. ruapu does not rely on the cpuid instructions and registers related to the CPU architecture, nor does it rely on the MISA
information and system calls of the operating system. This can help us get more detailed CPU ISA information.
ruapu is the abbreviation of rua-cpu, which means using various extended instructions to harass and amuse the CPU (rua!). Based on whether the CPU reacts violently (throws an illegal instruction exception), it is inferred whether the CPU supports a certain extended instruction set.
We consider gcc builtin functions to be good practice, saying __builtin_cpu_init()
and __builtin_cpu_supports()
. ruapu refers to this design, which can be a 1:1 replacement for gcc functions, and supports more operating systems and compilers, giving it better portability.
gdb
, lldb
, qemu-user
, sde
etc. Because debuggers and simulators capture the signal and stop the ruapu signal handler function by default, we can continue execution at this time, or configure it specifically, such as handle SIGILL nostop
in gdb. ruapu technically cannot prevent programs from stopping in debuggers and emulators
Assume that the new extended instruction set is named rua
RUAPU_INSTCODE(rua, rua-inst-hex) // rua r0,r0
and RUAPU_ISAENTRY(rua)
in ruapu.h
PRINT_ISA_SUPPORT(rua)
in main.c
to print the detection resultrua
in README.mdhttps://godbolt.org/ is a good helper to view the compiled binary code of instructions.
MIT License