Uses the fast crc32 instruction if SSE4.2 is available.

This commit is contained in:
Andrea Mazzoleni 2013-08-17 17:38:18 +02:00
parent 3698064040
commit 37ac46a284
4 changed files with 66 additions and 26 deletions

39
cpu.h
View file

@ -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;
}
/**

View file

@ -470,6 +470,7 @@ int main(int argc, char* argv[])
}
raid_init();
crc32c_init();
if (!opt.skip_self)
selftest(opt.gui);

45
util.c
View file

@ -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<size;++i)
crc = CRC32C[(crc ^ ptr[i]) & 0xff] ^ (crc >> 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 */

7
util.h
View file

@ -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 */