X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=crc%2Fcrc32c-intel.c;h=6e810a28f93608dfafcaac4bb6dec03bea526554;hp=cec5ad5dec9d5d88ec7498133f2915ae0c1bd146;hb=58dc28f4e56cba465cc56b9f81065862b1e98548;hpb=419484b934222e589f0b718e9494b045df176167 diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c index cec5ad5d..6e810a28 100644 --- a/crc/crc32c-intel.c +++ b/crc/crc32c-intel.c @@ -1,4 +1,3 @@ -#include #include "crc32c.h" /* @@ -12,7 +11,9 @@ * Volume 2A: Instruction Set Reference, A-M */ -#ifdef ARCH_HAVE_SSE +bool crc32c_intel_available = false; + +#ifdef ARCH_HAVE_SSE4_2 #if BITS_PER_LONG == 64 #define REX_PRE "0x48, " @@ -22,8 +23,10 @@ #define SCALE_F 4 #endif -uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data, - unsigned long length) +static bool crc32c_probed; + +static uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data, + unsigned long length) { while (length--) { __asm__ __volatile__( @@ -68,5 +71,17 @@ uint32_t crc32c_intel(unsigned char const *data, unsigned long length) return crc; } -#endif /* ARCH_HAVE_SSE */ +void crc32c_intel_probe(void) +{ + if (!crc32c_probed) { + unsigned int eax, ebx, ecx = 0, edx; + + eax = 1; + + do_cpuid(&eax, &ebx, &ecx, &edx); + crc32c_intel_available = (ecx & (1 << 20)) != 0; + crc32c_probed = true; + } +} +#endif /* ARCH_HAVE_SSE4_2 */