1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-07-01 20:32:38 +00:00

- Add CPU SIMD detection at runtime, relevant for bridge plugins

- Update BUILD_WSL.md document, add preparation for python bridge
This commit is contained in:
Jens Steube 2025-06-04 10:09:44 +02:00
parent ad38c92530
commit 3d4901a60c
15 changed files with 274 additions and 47 deletions

View File

@ -1,24 +1,27 @@
# Compiling hashcat for Windows with Windows Subsystem for Linux.
# Compiling hashcat for Windows with Windows Subsystem for Linux 2.
Tested on Windows 10 x64, should also work to build hashcat for Windows on Linux.
Tested on Windows 11 x64, should also work to build hashcat for Windows on Linux.
I had it tested with WSL2 using Ubuntu_2004.2020.424.0_x64.appx.
I had it tested with WSL2 using "Ubuntu", which at the time of writing is Ubuntu 24.04
Make sure to have the system upgraded after install (otherwise it will fail to find the gcc-mingw-w64-x86-64 package).
### Installation ###
Enable WSL.
Enable WSL2.
Press the win + r key on your keyboard simultaneously and in the "Run" popup window type bash and make sure to install additional dependencies necessary for hashcat compilation
```bash
sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 make git
sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 make git zstd python3-dev
git clone https://github.com/hashcat/hashcat
git clone https://github.com/win-iconv/win-iconv
cd win-iconv/
cmake -D WIN_ICONV_BUILD_EXECUTABLE=OFF -D CMAKE_INSTALL_PREFIX=/opt/win-iconv-64 -D CMAKE_CXX_COMPILER=$(which x86_64-w64-mingw32-g++) -D CMAKE_C_COMPILER=$(which x86_64-w64-mingw32-gcc)
sudo make install
cd ../
wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
sudo mkdir /opt/win-python
sudo tar --zstd -xf mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst -C /opt/win-python
```
### Building ###

View File

@ -43,8 +43,8 @@ RUN cmake \
make -j$(nproc) && make install
# Download and extract MSYS2 Python headers (still 3.12)
RUN mkdir /opt/cpython-mingw
WORKDIR /opt/cpython-mingw
RUN mkdir /opt/win-python
WORKDIR /opt/win-python
RUN wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst && \
zstd -d mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst && \
tar -xf mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar

View File

@ -79,8 +79,8 @@ ENV PATH="/opt/linux-python/bin:$PATH"
WORKDIR /root
RUN mkdir /opt/cpython-mingw
WORKDIR /opt/cpython-mingw
RUN mkdir /opt/win-python
WORKDIR /opt/win-python
RUN wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
RUN unzstd mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
RUN tar -xf mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar

21
include/cpu_features.h Normal file
View File

@ -0,0 +1,21 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#ifndef HC_CPU_FEATURES_H
#define HC_CPU_FEATURES_H
#include <stdio.h>
#include <cpuid.h>
// SIMD detection
int cpu_supports_sse2 ();
int cpu_supports_ssse3 ();
int cpu_supports_xop ();
int cpu_supports_avx2 ();
int cpu_supports_avx512f ();
int cpu_chipset_test ();
#endif // HC_CPU_FEATURES_H

View File

@ -7,6 +7,8 @@
#include "types.h"
#include "bridges.h"
#include "memory.h"
#include "shared.h"
#include "cpu_features.h"
// argon2 reference
@ -133,7 +135,11 @@ static void units_term (bridge_argon2id_t *bridge_argon2id)
void *platform_init ()
{
// bridge_argon2id_t will be our platform context
// Verify CPU features
if (cpu_chipset_test () == -1) return NULL;
// Allocate platform context
bridge_argon2id_t *bridge_argon2id = (bridge_argon2id_t *) hcmalloc (sizeof (bridge_argon2id_t));

View File

@ -15,16 +15,16 @@ endif
endif
ifeq ($(BUILD_MODE),cross)
bridges/bridge_argon2id_reference.so: src/bridges/bridge_argon2id_reference.c obj/combined.LINUX.a
bridges/bridge_argon2id_reference.so: src/bridges/bridge_argon2id_reference.c src/cpu_features.c obj/combined.LINUX.a
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(ARGON2_REFERENCE_CFLAGS)
bridges/bridge_argon2id_reference.dll: src/bridges/bridge_argon2id_reference.c obj/combined.WIN.a
bridges/bridge_argon2id_reference.dll: src/bridges/bridge_argon2id_reference.c src/cpu_features.c obj/combined.WIN.a
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(ARGON2_REFERENCE_CFLAGS)
else
ifeq ($(SHARED),1)
bridges/bridge_argon2id_reference.$(BRIDGE_SUFFIX): src/bridges/bridge_argon2id_reference.c $(HASHCAT_LIBRARY)
bridges/bridge_argon2id_reference.$(BRIDGE_SUFFIX): src/bridges/bridge_argon2id_reference.c src/cpu_features.c $(HASHCAT_LIBRARY)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(ARGON2_REFERENCE_CFLAGS)
else
bridges/bridge_argon2id_reference.$(BRIDGE_SUFFIX): src/bridges/bridge_argon2id_reference.c obj/combined.NATIVE.a
bridges/bridge_argon2id_reference.$(BRIDGE_SUFFIX): src/bridges/bridge_argon2id_reference.c src/cpu_features.c obj/combined.NATIVE.a
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(ARGON2_REFERENCE_CFLAGS)
endif
endif

View File

@ -8,6 +8,7 @@
#include "bridges.h"
#include "memory.h"
#include "shared.h"
#include "cpu_features.h"
#include "dynloader.h"
#if defined (_WIN)
@ -679,6 +680,12 @@ static void units_term (python_interpreter_t *python_interpreter)
void *platform_init (user_options_t *user_options)
{
// Verify CPU features
if (cpu_chipset_test () == -1) return NULL;
// Allocate platform context
python_interpreter_t *python_interpreter = (python_interpreter_t *) hcmalloc (sizeof (python_interpreter_t));
hc_python_lib_t *python = (hc_python_lib_t *) hcmalloc (sizeof (hc_python_lib_t));

View File

@ -1,24 +1,19 @@
PYTHON_CONFIG_FLAGS_LINUX := `python3-config --includes`
# Experimental support for for Windows:
# $ mkdir /opt/cpython-mingw
# $ cd /opt/cpython-mingw
# $ wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
# $ tar --zstd -xf mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
PYTHON_CONFIG_FLAGS_WIN := -I/opt/cpython-mingw/mingw64/include/python3.12
# See BUILD_WSL.md to prepare /opt/win-python
PYTHON_CONFIG_FLAGS_WIN := -I/opt/win-python/mingw64/include/python3.12
ifeq ($(BUILD_MODE),cross)
bridges/bridge_python_generic_hash_mp.so: src/bridges/bridge_python_generic_hash_mp.c obj/combined.LINUX.a
bridges/bridge_python_generic_hash_mp.so: src/bridges/bridge_python_generic_hash_mp.c src/cpu_features.c obj/combined.LINUX.a
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX)
bridges/bridge_python_generic_hash_mp.dll: src/bridges/bridge_python_generic_hash_mp.c obj/combined.WIN.a
bridges/bridge_python_generic_hash_mp.dll: src/bridges/bridge_python_generic_hash_mp.c src/cpu_features.c obj/combined.WIN.a
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_WIN)
else
ifeq ($(SHARED),1)
bridges/bridge_python_generic_hash_mp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_mp.c $(HASHCAT_LIBRARY)
bridges/bridge_python_generic_hash_mp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_mp.c src/cpu_features.c $(HASHCAT_LIBRARY)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX) $(PYTHON_CONFIG_FLAGS_WIN)
else
bridges/bridge_python_generic_hash_mp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_mp.c obj/combined.NATIVE.a
bridges/bridge_python_generic_hash_mp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_mp.c src/cpu_features.c obj/combined.NATIVE.a
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX) $(PYTHON_CONFIG_FLAGS_WIN)
endif
endif

View File

@ -8,6 +8,7 @@
#include "bridges.h"
#include "memory.h"
#include "shared.h"
#include "cpu_features.h"
#include "dynloader.h"
#if defined (_WIN)
@ -687,6 +688,12 @@ static void units_term (python_interpreter_t *python_interpreter)
void *platform_init (user_options_t *user_options)
{
// Verify CPU features
if (cpu_chipset_test () == -1) return NULL;
// Allocate platform context
python_interpreter_t *python_interpreter = (python_interpreter_t *) hcmalloc (sizeof (python_interpreter_t));
hc_python_lib_t *python = (hc_python_lib_t *) hcmalloc (sizeof (hc_python_lib_t));

View File

@ -1,24 +1,19 @@
PYTHON_CONFIG_FLAGS_LINUX := `python3-config --includes`
# Experimental support for for Windows:
# $ mkdir /opt/cpython-mingw
# $ cd /opt/cpython-mingw
# $ wget https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
# $ tar --zstd -xf mingw-w64-x86_64-python-3.12.10-1-any.pkg.tar.zst
PYTHON_CONFIG_FLAGS_WIN := -I/opt/cpython-mingw/mingw64/include/python3.12
# See BUILD_WSL.md to prepare /opt/win-python
PYTHON_CONFIG_FLAGS_WIN := -I/opt/win-python/mingw64/include/python3.12
ifeq ($(BUILD_MODE),cross)
bridges/bridge_python_generic_hash_sp.so: src/bridges/bridge_python_generic_hash_sp.c obj/combined.LINUX.a
bridges/bridge_python_generic_hash_sp.so: src/bridges/bridge_python_generic_hash_sp.c src/cpu_features.c obj/combined.LINUX.a
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX)
bridges/bridge_python_generic_hash_sp.dll: src/bridges/bridge_python_generic_hash_sp.c obj/combined.WIN.a
bridges/bridge_python_generic_hash_sp.dll: src/bridges/bridge_python_generic_hash_sp.c src/cpu_features.c obj/combined.WIN.a
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_WIN)
else
ifeq ($(SHARED),1)
bridges/bridge_python_generic_hash_sp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_sp.c $(HASHCAT_LIBRARY)
bridges/bridge_python_generic_hash_sp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_sp.c src/cpu_features.c $(HASHCAT_LIBRARY)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX) $(PYTHON_CONFIG_FLAGS_WIN)
else
bridges/bridge_python_generic_hash_sp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_sp.c obj/combined.NATIVE.a
bridges/bridge_python_generic_hash_sp.$(BRIDGE_SUFFIX): src/bridges/bridge_python_generic_hash_sp.c src/cpu_features.c obj/combined.NATIVE.a
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(PYTHON_CONFIG_FLAGS_LINUX) $(PYTHON_CONFIG_FLAGS_WIN)
endif
endif

View File

@ -7,6 +7,8 @@
#include "types.h"
#include "bridges.h"
#include "memory.h"
#include "shared.h"
#include "cpu_features.h"
#include "code/scrypt-jane-portable.h"
#include "code/scrypt-jane-hash.h"
@ -106,7 +108,11 @@ static void units_term (bridge_scrypt_jane_t *bridge_scrypt_jane)
void *platform_init ()
{
// bridge_scrypt_jane_t will be our platform context
// Verify CPU features
if (cpu_chipset_test () == -1) return NULL;
// Allocate platform context
bridge_scrypt_jane_t *bridge_scrypt_jane = (bridge_scrypt_jane_t *) hcmalloc (sizeof (bridge_scrypt_jane_t));

View File

@ -15,16 +15,16 @@ endif
endif
ifeq ($(BUILD_MODE),cross)
bridges/bridge_scrypt_jane.so: src/bridges/bridge_scrypt_jane.c obj/combined.LINUX.a
bridges/bridge_scrypt_jane.so: src/bridges/bridge_scrypt_jane.c src/cpu_features.c obj/combined.LINUX.a
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_JANE_CFLAGS)
bridges/bridge_scrypt_jane.dll: src/bridges/bridge_scrypt_jane.c obj/combined.WIN.a
bridges/bridge_scrypt_jane.dll: src/bridges/bridge_scrypt_jane.c src/cpu_features.c obj/combined.WIN.a
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_JANE_CFLAGS)
else
ifeq ($(SHARED),1)
bridges/bridge_scrypt_jane.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_jane.c $(HASHCAT_LIBRARY)
bridges/bridge_scrypt_jane.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_jane.c src/cpu_features.c $(HASHCAT_LIBRARY)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_JANE_CFLAGS)
else
bridges/bridge_scrypt_jane.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_jane.c obj/combined.NATIVE.a
bridges/bridge_scrypt_jane.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_jane.c src/cpu_features.c obj/combined.NATIVE.a
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_JANE_CFLAGS)
endif
endif

View File

@ -7,6 +7,8 @@
#include "types.h"
#include "bridges.h"
#include "memory.h"
#include "shared.h"
#include "cpu_features.h"
#include "yescrypt.h"
@ -108,7 +110,11 @@ static void units_term (bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt)
void *platform_init ()
{
// bridge_scrypt_yescrypt_t will be our platform context
// Verify CPU features
if (cpu_chipset_test () == -1) return NULL;
// Allocate platform context
bridge_scrypt_yescrypt_t *bridge_scrypt_yescrypt = (bridge_scrypt_yescrypt_t *) hcmalloc (sizeof (bridge_scrypt_yescrypt_t));

View File

@ -15,16 +15,16 @@ endif
endif
ifeq ($(BUILD_MODE),cross)
bridges/bridge_scrypt_yescrypt.so: src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.LINUX.a
bridges/bridge_scrypt_yescrypt.so: src/bridges/bridge_scrypt_yescrypt.c src/cpu_features.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.LINUX.a
$(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
bridges/bridge_scrypt_yescrypt.dll: src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.WIN.a
bridges/bridge_scrypt_yescrypt.dll: src/bridges/bridge_scrypt_yescrypt.c src/cpu_features.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.WIN.a
$(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
else
ifeq ($(SHARED),1)
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c $(HASHCAT_LIBRARY)
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c src/cpu_features.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c $(HASHCAT_LIBRARY)
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
else
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.NATIVE.a
bridges/bridge_scrypt_yescrypt.$(BRIDGE_SUFFIX): src/bridges/bridge_scrypt_yescrypt.c src/cpu_features.c $(SCRYPT_YESCRYPT)/yescrypt-opt.c $(SCRYPT_YESCRYPT)/sha256.c obj/combined.NATIVE.a
$(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D BRIDGE_INTERFACE_VERSION_CURRENT=$(BRIDGE_INTERFACE_VERSION) $(SCRYPT_YESCRYPT_CFLAGS)
endif
endif

181
src/cpu_features.c Normal file
View File

@ -0,0 +1,181 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
#include "common.h"
#include "types.h"
#include "cpu_features.h"
static inline void cpuid (u32 leaf, u32 subleaf, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
{
__cpuid_count (leaf, subleaf, *eax, *ebx, *ecx, *edx);
}
static inline u64 xgetbv (u32 index)
{
u32 eax, edx;
__asm__ volatile (".byte 0x0f, 0x01, 0xd0"
: "=a"(eax), "=d"(edx)
: "c"(index));
return ((u64)edx << 32) | eax;
}
// Should always be present on 64 bit?
int cpu_supports_sse2 ()
{
u32 eax, ebx, ecx, edx;
cpuid(1, 0, &eax, &ebx, &ecx, &edx);
return (edx & bit_SSE2) != 0;
}
int cpu_supports_ssse3 ()
{
u32 eax, ebx, ecx, edx;
cpuid (1, 0, &eax, &ebx, &ecx, &edx);
return (ecx & bit_SSSE3) != 0;
}
int cpu_supports_xop ()
{
u32 eax, ebx, ecx, edx;
cpuid (0x80000000, 0, &eax, &ebx, &ecx, &edx);
if (eax < 0x80000001)
{
return 0;
}
cpuid (0x80000001, 0, &eax, &ebx, &ecx, &edx);
return (ecx & (1 << 11)) != 0; // No macro for XOP
}
int cpu_supports_avx2 ()
{
u32 eax, ebx, ecx, edx;
cpuid (1, 0, &eax, &ebx, &ecx, &edx);
if (!(ecx & bit_OSXSAVE) || !(ecx & bit_AVX))
{
return 0;
}
if ((xgetbv(0) & 0x6) != 0x6) // XMM and YMM state
{
return 0;
}
cpuid (7, 0, &eax, &ebx, &ecx, &edx);
return (ebx & bit_AVX2) != 0;
}
int cpu_supports_avx512f ()
{
u32 eax, ebx, ecx, edx;
cpuid (1, 0, &eax, &ebx, &ecx, &edx);
if (!(ecx & bit_OSXSAVE) || !(ecx & bit_AVX))
{
return 0;
}
if ((xgetbv(0) & 0xE6) != 0xE6)
{
return 0;
}
cpuid (7, 0, &eax, &ebx, &ecx, &edx);
return (ebx & bit_AVX512F) != 0;
}
int cpu_supports_avx512vl ()
{
u32 eax, ebx, ecx, edx;
cpuid (1, 0, &eax, &ebx, &ecx, &edx);
if (!(ecx & bit_OSXSAVE) || !(ecx & bit_AVX))
{
return 0;
}
if ((xgetbv(0) & 0xE6) != 0xE6)
{
return 0;
}
cpuid (7, 0, &eax, &ebx, &ecx, &edx);
return (ebx & (1u << 31)) != 0;
}
int cpu_chipset_test ()
{
#ifdef __SSE2__
if (cpu_supports_sse2 () == 0)
{
fprintf (stderr, "ERROR: Compiled with SSE2 but CPU does not support it.\n");
return -1;
}
#endif
#ifdef __SSSE3__
if (cpu_supports_ssse3 () == 0)
{
fprintf (stderr, "ERROR: Compiled with SSSE3 but CPU does not support it.\n");
return -1;
}
#endif
#ifdef __XOP__
if (cpu_supports_xop () == 0)
{
fprintf (stderr, "ERROR: Compiled with XOP but CPU does not support it.\n");
return -1;
}
#endif
#ifdef __AVX2__
if (cpu_supports_avx2 () == 0)
{
fprintf (stderr, "ERROR: Compiled with AVX2 but CPU does not support it.\n");
return -1;
}
#endif
#ifdef __AVX512F__
if (cpu_supports_avx512f () == 0)
{
fprintf (stderr, "ERROR: Compiled with AVX512F but CPU does not support it.\n");
return -1;
}
#endif
#ifdef __AVX512VL__
if (cpu_supports_avx512vl () == 0)
{
fprintf (stderr, "ERROR: Compiled with AVX512VL but CPU does not support it.\n");
return -1;
}
#endif
return 0;
}