diff --git a/cpu.h b/cpu.h index d6a228a7..80246150 100644 --- a/cpu.h +++ b/cpu.h @@ -20,12 +20,6 @@ #if defined(__i386__) || defined(__x86_64__) -#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ -#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore) */ -#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */ -#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */ -#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ - static inline void cpuid(uint32_t func, uint32_t* reg) { asm volatile( @@ -44,15 +38,6 @@ static inline void cpuid(uint32_t func, uint32_t* reg) ); } -static inline int cpu_has(uint32_t flag) -{ - uint32_t reg[4]; - - cpuid((flag >> 5) ? 0x80000001 : 1, reg); - - return (reg[3] >> (flag & 31)) & 1; -} - #define CPU_VENDOR_MAX 13 static inline void cpu_info(char* vendor, unsigned* family, unsigned* model) @@ -90,15 +75,29 @@ static inline void cpu_info(char* vendor, unsigned* family, unsigned* model) static inline int cpu_has_mmx(void) { - return cpu_has(X86_FEATURE_MMX); + uint32_t reg[4]; + + cpuid(1, reg); + + return (reg[3] >> 23) & 1; } static inline int cpu_has_sse2(void) { - return cpu_has(X86_FEATURE_MMX) && - cpu_has(X86_FEATURE_FXSR) && - cpu_has(X86_FEATURE_XMM) && - cpu_has(X86_FEATURE_XMM2); + uint32_t reg[4]; + + cpuid(1, reg); + + return (reg[3] >> 26) & 1; +} + +static inline int cpu_has_sse42(void) +{ + uint32_t reg[4]; + + cpuid(1, reg); + + return (reg[2] >> 20) & 1; } /** diff --git a/snapraid.c b/snapraid.c index 572afed6..90c063f2 100644 --- a/snapraid.c +++ b/snapraid.c @@ -470,6 +470,7 @@ int main(int argc, char* argv[]) } raid_init(); + crc32c_init(); if (!opt.skip_self) selftest(opt.gui); diff --git a/util.c b/util.c index 748fb878..320d251f 100644 --- a/util.c +++ b/util.c @@ -18,6 +18,7 @@ #include "portable.h" #include "util.h" +#include "cpu.h" /****************************************************************************/ /* hex conversion table */ @@ -855,16 +856,50 @@ static uint32_t CRC32C[256] = { 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 }; -uint32_t crc32c(uint32_t crc, const unsigned char* ptr, unsigned size) +static uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size) { - unsigned i; - - for(i=0;i> 8); + while (size) { + crc = CRC32C[(crc ^ *ptr) & 0xff] ^ (crc >> 8); + ++ptr; + --size; + } return crc; } +#if defined(__i386__) || defined(__x86_64__) + +static uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size) +{ + while (size >= 4) { + asm volatile ("crc32l %1, %0\n" : "+r" (crc) : "rm" (*(uint32_t*)ptr)); + ptr += 4; + size -= 4; + } + + while (size) { + asm volatile ("crc32b %1, %0\n" : "+r" (crc) : "rm" (*ptr)); + ++ptr; + --size; + } + + return crc; +} + +#endif + +uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size); + +void crc32c_init(void) +{ + crc32c = crc32c_gen; +#if defined(__i386__) || defined(__x86_64__) + if (cpu_has_sse42()) { + crc32c = crc32c_x86; + } +#endif +} + /****************************************************************************/ /* path */ diff --git a/util.h b/util.h index dc1eefeb..9821a793 100644 --- a/util.h +++ b/util.h @@ -499,7 +499,12 @@ void randomize(void* ptr, unsigned size); /** * Computes the CRC-32 (Castagnoli) */ -uint32_t crc32c(uint32_t crc, const unsigned char* ptr, unsigned size); +uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size); + +/** + * Initializes the CRC-32 (Castagnoli) support. + */ +void crc32c_init(void); /****************************************************************************/ /* sax */