checksums-fnv.c
text/x-csrc
#define N_SUMS 32
#define FNV_PRIME 16777619
static uint32 multiplyVectors[4] =
{
FNV_PRIME, FNV_PRIME, FNV_PRIME, FNV_PRIME
};
static uint32 checksumOffsets[32] = {
0x5B1F36E9, 0xB8525960, 0x02AB50AA, 0x1DE66D2A,
0x79FF467A, 0x9BB9F8A3, 0x217E7CD2, 0x83E13D2C,
0xF8D4474F, 0xE39EB970, 0x42C6AE16, 0x993216FA,
0x7B093B5D, 0x98DAFF3C, 0xF718902A, 0x0B1C9CDB,
0xE58F764B, 0x187636BC, 0x5D7B3BB1, 0xE73DE7DE,
0x92BEC979, 0xCCA6C0B2, 0x304A0979, 0x85AA43D4,
0x783125BB, 0x6CA8EAA2, 0xE407EAC6, 0x4B5CFC3E,
0x9FBF8C76, 0x15CA20BE, 0xF2CA9FD3, 0x959BD756
};
#ifndef DONT_USE_SRL
__attribute__ ((noinline)) static uint16
checksum_fast(char *page, uint32 blkno)
{
uint32 result;
uint16 checksum;
asm __volatile__ (
"mov $0x80, %%rdx\n" // vector length
"xor %%rcx, %%rcx\n" // offset
"movdqa (%4), %%xmm0\n"
"movdqa 0x10(%4), %%xmm1\n"
"movdqa 0x20(%4), %%xmm2\n"
"movdqa 0x30(%4), %%xmm3\n"
"movdqa 0x40(%4), %%xmm4\n"
"movdqa 0x50(%4), %%xmm5\n"
"movdqa 0x60(%4), %%xmm6\n"
"movdqa 0x70(%4), %%xmm7\n"
"movdqa (%2), %%xmm9\n"
/* first vector of the first iteration needs to zero out the checksum */
"movdqu (%1,%%rcx,1), %%xmm8\n"
"pinsrw $0x4, %%ecx, %%xmm8\n" // zero out checksum
"jmp 2f\n"
// main loop, accumulate hash codes in parallel
"1:\n"
".align 16\n"
"movdqu (%1,%%rcx,1), %%xmm8\n"
"2:\n"
"pxor %%xmm8, %%xmm0\n"
"movdqa %%xmm0, %%xmm10\n"
"pmulld %%xmm9, %%xmm0\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm0\n"
"movdqu 0x10(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm1\n"
"movdqa %%xmm1, %%xmm10\n"
"pmulld %%xmm9, %%xmm1\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm1\n"
"movdqu 0x20(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm2\n"
"movdqa %%xmm2, %%xmm10\n"
"pmulld %%xmm9, %%xmm2\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm2\n"
"movdqu 0x30(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm3\n"
"movdqa %%xmm3, %%xmm10\n"
"pmulld %%xmm9, %%xmm3\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm3\n"
"movdqu 0x40(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm4\n"
"movdqa %%xmm4, %%xmm10\n"
"pmulld %%xmm9, %%xmm4\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm4\n"
"movdqu 0x50(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm5\n"
"movdqa %%xmm5, %%xmm10\n"
"pmulld %%xmm9, %%xmm5\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm5\n"
"movdqu 0x60(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm6\n"
"movdqa %%xmm6, %%xmm10\n"
"pmulld %%xmm9, %%xmm6\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm6\n"
"movdqu 0x70(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm7\n"
"movdqa %%xmm7, %%xmm10\n"
"pmulld %%xmm9, %%xmm7\n"
"psrld $0x3, %%xmm10\n"
"pxor %%xmm10, %%xmm7\n"
"add %%rdx, %%rcx\n"
"cmp %3, %%ecx\n"
"jnz 1b\n"
/* xor fold */
"pxor %%xmm0, %%xmm1\n"
"pxor %%xmm2, %%xmm3\n"
"pxor %%xmm4, %%xmm5\n"
"pxor %%xmm6, %%xmm7\n"
"pxor %%xmm1, %%xmm3\n"
"pxor %%xmm5, %%xmm7\n"
"pxor %%xmm3, %%xmm7\n"
"movdqa %%xmm7, %%xmm0\n"
"psrldq $0x8, %%xmm7\n"
"pxor %%xmm7, %%xmm0\n"
"movdqa %%xmm0, %%xmm1\n"
"psrldq $0x4, %%xmm1\n"
"pxor %%xmm1, %%xmm0\n"
"movd %%xmm0, %0\n"
: "=r"(result)
: "r"(page), "r"(multiplyVectors), "r"(PAGE_SIZE), "r"(checksumOffsets)
: "rcx","rdx","xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8", "xmm9","xmm10","xmm11"
);
result ^= blkno;
checksum = (result % 65521) + 1;
return checksum;
}
#else
__attribute__ ((noinline)) static uint16
checksum_fast(char *page, uint32 blkno)
{
uint32 result;
uint16 checksum;
asm __volatile__ (
"mov $0x80, %%rdx\n" // vector length
"xor %%rcx, %%rcx\n" // offset
"movdqa (%4), %%xmm0\n"
"movdqa 0x10(%4), %%xmm1\n"
"movdqa 0x20(%4), %%xmm2\n"
"movdqa 0x30(%4), %%xmm3\n"
"movdqa 0x40(%4), %%xmm4\n"
"movdqa 0x50(%4), %%xmm5\n"
"movdqa 0x60(%4), %%xmm6\n"
"movdqa 0x70(%4), %%xmm7\n"
"movdqa (%2), %%xmm9\n"
/* first vector of the first iteration needs to zero out the checksum */
"movdqu (%1,%%rcx,1), %%xmm8\n"
"pinsrw $0x4, %%ecx, %%xmm8\n" // zero out checksum
"jmp 2f\n"
// main loop, accumulate hash codes in parallel
"1:\n"
".align 16\n"
"movdqu (%1,%%rcx,1), %%xmm8\n"
"2:\n"
"pxor %%xmm8, %%xmm0\n"
"pmulld %%xmm9, %%xmm0\n"
"movdqu 0x10(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm1\n"
"pmulld %%xmm9, %%xmm1\n"
"movdqu 0x20(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm2\n"
"pmulld %%xmm9, %%xmm2\n"
"movdqu 0x30(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm3\n"
"pmulld %%xmm9, %%xmm3\n"
"movdqu 0x40(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm4\n"
"pmulld %%xmm9, %%xmm4\n"
"movdqu 0x50(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm5\n"
"pmulld %%xmm9, %%xmm5\n"
"movdqu 0x60(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm6\n"
"pmulld %%xmm9, %%xmm6\n"
"movdqu 0x70(%1,%%rcx,1), %%xmm8\n"
"pxor %%xmm8, %%xmm7\n"
"pmulld %%xmm9, %%xmm7\n"
"add %%rdx, %%rcx\n"
"cmp %3, %%ecx\n"
"jnz 1b\n"
/* xor fold */
"pxor %%xmm0, %%xmm1\n"
"pxor %%xmm2, %%xmm3\n"
"pxor %%xmm4, %%xmm5\n"
"pxor %%xmm6, %%xmm7\n"
"pxor %%xmm1, %%xmm3\n"
"pxor %%xmm5, %%xmm7\n"
"pxor %%xmm3, %%xmm7\n"
"movdqa %%xmm7, %%xmm0\n"
"psrldq $0x8, %%xmm7\n"
"pxor %%xmm7, %%xmm0\n"
"movdqa %%xmm0, %%xmm1\n"
"psrldq $0x4, %%xmm1\n"
"pxor %%xmm1, %%xmm0\n"
"movd %%xmm0, %0\n"
: "=r"(result)
: "r"(page), "r"(multiplyVectors), "r"(PAGE_SIZE), "r"(checksumOffsets)
: "rcx","rdx","xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7","xmm8", "xmm9","xmm10","xmm11"
);
result ^= blkno;
checksum = (result % 65521) + 1;
return checksum;
}
#endif