X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=crc%2Fcrc32c-intel.c;h=8a6e6dcefb749b41ed5ecddb7035ae6a8c247adf;hb=dd366728eb503e6344215ae6ec153c7ab6eafd9b;hp=c0abe73ad7a85ac5bb794f3e50b6137b796391df;hpb=3845591fadea480177223e28c9d1c03642d34f0e;p=fio.git diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c index c0abe73a..8a6e6dce 100644 --- a/crc/crc32c-intel.c +++ b/crc/crc32c-intel.c @@ -1,4 +1,11 @@ #include +#include +#include +#include +#include +#include +#include +#include "crc32c.h" /* * Based on a posting to lkml by Austin Zhang @@ -11,6 +18,10 @@ * Volume 2A: Instruction Set Reference, A-M */ +int crc32c_intel_available = 0; + +#ifdef ARCH_HAVE_SSE4_2 + #if BITS_PER_LONG == 64 #define REX_PRE "0x48, " #define SCALE_F 8 @@ -19,8 +30,10 @@ #define SCALE_F 4 #endif -uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data, - unsigned long length) +static int crc32c_probed; + +static uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data, + unsigned long length) { while (length--) { __asm__ __volatile__( @@ -64,3 +77,34 @@ uint32_t crc32c_intel(unsigned char const *data, unsigned long length) return crc; } + +static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx) +{ + int id = *eax; + + asm("movl %4, %%eax;" + "cpuid;" + "movl %%eax, %0;" + "movl %%ebx, %1;" + "movl %%ecx, %2;" + "movl %%edx, %3;" + : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx) + : "r" (id) + : "eax", "ebx", "ecx", "edx"); +} + +void crc32c_intel_probe(void) +{ + if (!crc32c_probed) { + unsigned int eax, ebx, ecx, edx; + + eax = 1; + + do_cpuid(&eax, &ebx, &ecx, &edx); + crc32c_intel_available = (ecx & (1 << 20)) != 0; + crc32c_probed = 1; + } +} + +#endif /* ARCH_HAVE_SSE */