X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=crc%2Fcrc32c-intel.c;h=9a2cefdedcaf288fa5a302c952f21410353b88ea;hp=969a037f942d24e9509b11217fd3123e01658aea;hb=3d2d14bcb844e72809192311369a642c5d415472;hpb=2f68124f26e54233db41b462a257dabc48e5c32b diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c index 969a037f..9a2cefde 100644 --- a/crc/crc32c-intel.c +++ b/crc/crc32c-intel.c @@ -1,10 +1,3 @@ -#include -#include -#include -#include -#include -#include -#include #include "crc32c.h" /* @@ -18,6 +11,8 @@ * Volume 2A: Instruction Set Reference, A-M */ +bool crc32c_intel_available = false; + #ifdef ARCH_HAVE_SSE4_2 #if BITS_PER_LONG == 64 @@ -28,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__( @@ -74,30 +71,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 = true; + } } #endif /* ARCH_HAVE_SSE */