mirror of
https://github.com/hashcat/hashcat.git
synced 2025-07-23 06:58:31 +00:00
193 lines
3.3 KiB
C
193 lines
3.3 KiB
C
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "types.h"
|
|
#include "cpu_features.h"
|
|
|
|
#if defined(__aarch64__) || defined(__arm64__)
|
|
|
|
int cpu_supports_sse2 () { return 1; }
|
|
int cpu_supports_ssse3 () { return 0; }
|
|
int cpu_supports_xop () { return 0; }
|
|
int cpu_supports_avx2 () { return 0; }
|
|
int cpu_supports_avx512f () { return 0; }
|
|
int cpu_supports_avx512vl () { return 0; }
|
|
|
|
#else
|
|
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;
|
|
}
|
|
#endif
|
|
|
|
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;
|
|
}
|