X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=crc%2Fcrc32c-intel.c;h=0b0f193c0564a75de8d5d00e80695af40e49dd6a;hb=2ed0bd1cefe817d44e2f735e2cea41f6253f571d;hp=77d6df411973510298342d79e190db4b3a447ffa;hpb=e0ab5f977075ec2f8ad42378c95eb800a611f0ef;p=fio.git diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c index 77d6df41..0b0f193c 100644 --- a/crc/crc32c-intel.c +++ b/crc/crc32c-intel.c @@ -18,7 +18,9 @@ * Volume 2A: Instruction Set Reference, A-M */ -#ifdef ARCH_HAVE_SSE +int crc32c_intel_available = 0; + +#ifdef ARCH_HAVE_SSE4_2 #if BITS_PER_LONG == 64 #define REX_PRE "0x48, " @@ -28,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__( @@ -74,30 +78,17 @@ 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) +void crc32c_intel_probe(void) { - int id = *eax; + if (!crc32c_probed) { + unsigned int eax, ebx, ecx = 0, edx; - 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"); -} + eax = 1; -int crc32c_intel_works(void) -{ - unsigned int eax, ebx, ecx, edx; - - eax = 1; - - do_cpuid(&eax, &ebx, &ecx, &edx); - return (ecx & (1 << 20)) != 0; + do_cpuid(&eax, &ebx, &ecx, &edx); + crc32c_intel_available = (ecx & (1 << 20)) != 0; + crc32c_probed = 1; + } } #endif /* ARCH_HAVE_SSE */