// File: chahk0129[P]hash_bench/./util/hash.h
// Function: hash_compute(void const*, unsigned long, unsigned long, unsigned int)
uint64_t hash_compute(const void *input, uint64_t length, uint64_t seed, uint32_t align)
{
    const uint8_t *p = (const uint8_t *)input;
    const uint8_t *end = p + length;
    uint64_t hash;

    if (length >= 32)
    {
        const uint8_t *const limitation = end - 32;
        uint64_t v1 = seed + NUMBER64_1 + NUMBER64_2;
        uint64_t v2 = seed + NUMBER64_2;
        uint64_t v3 = seed + 0;
        uint64_t v4 = seed - NUMBER64_1;

        do
        {
            v1 += hash_get64bits(p) * NUMBER64_2;
            p += 8;
            v1 = shifting_hash(v1, 31);
            v1 *= NUMBER64_1;
            v2 += hash_get64bits(p) * NUMBER64_2;
            p += 8;
            v2 = shifting_hash(v2, 31);
            v2 *= NUMBER64_1;
            v3 += hash_get64bits(p) * NUMBER64_2;
            p += 8;
            v3 = shifting_hash(v3, 31);
            v3 *= NUMBER64_1;
            v4 += hash_get64bits(p) * NUMBER64_2;
            p += 8;
            v4 = shifting_hash(v4, 31);
            v4 *= NUMBER64_1;
        } while (p <= limitation);

        hash = shifting_hash(v1, 1) + shifting_hash(v2, 7) + shifting_hash(v3, 12) + shifting_hash(v4, 18);

        v1 *= NUMBER64_2;
        v1 = shifting_hash(v1, 31);
        v1 *= NUMBER64_1;
        hash ^= v1;
        hash = hash * NUMBER64_1 + NUMBER64_4;

        v2 *= NUMBER64_2;
        v2 = shifting_hash(v2, 31);
        v2 *= NUMBER64_1;
        hash ^= v2;
        hash = hash * NUMBER64_1 + NUMBER64_4;

        v3 *= NUMBER64_2;
        v3 = shifting_hash(v3, 31);
        v3 *= NUMBER64_1;
        hash ^= v3;
        hash = hash * NUMBER64_1 + NUMBER64_4;

        v4 *= NUMBER64_2;
        v4 = shifting_hash(v4, 31);
        v4 *= NUMBER64_1;
        hash ^= v4;
        hash = hash * NUMBER64_1 + NUMBER64_4;
    }
    else
    {
        hash = seed + NUMBER64_5;
    }

    hash += (uint64_t)length;

    while (p + 8 <= end)
    {
        uint64_t k1 = hash_get64bits(p);
        k1 *= NUMBER64_2;
        k1 = shifting_hash(k1, 31);
        k1 *= NUMBER64_1;
        hash ^= k1;
        hash = shifting_hash(hash, 27) * NUMBER64_1 + NUMBER64_4;
        p += 8;
    }

    if (p + 4 <= end)
    {
        hash ^= (uint64_t)(hash_get32bits(p)) * NUMBER64_1;
        hash = shifting_hash(hash, 23) * NUMBER64_2 + NUMBER64_3;
        p += 4;
    }

    while (p < end)
    {
        hash ^= (*p) * NUMBER64_5;
        hash = shifting_hash(hash, 11) * NUMBER64_1;
        p++;
    }

    hash ^= hash >> 33;
    hash *= NUMBER64_2;
    hash ^= hash >> 29;
    hash *= NUMBER64_3;
    hash ^= hash >> 32;

    return hash;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
addq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x20, -0x10(%rbp)
jb 0x6fd0
movq -0x30(%rbp), %rax
addq $-0x20, %rax
movq %rax, -0x40(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
addq -0x18(%rbp), %rax
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
addq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rax
addq $0x0, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movabsq $-0x61c8864e7a143579, %rcx # imm = 0x9E3779B185EBCA87
subq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6b70
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
imulq %rcx, %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
shlq $0x1f, %rax
movq -0x48(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x48(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6b70
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
imulq %rcx, %rax
addq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x50(%rbp), %rax
shlq $0x1f, %rax
movq -0x50(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x50(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6b70
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
imulq %rcx, %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x58(%rbp), %rax
shlq $0x1f, %rax
movq -0x58(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x58(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6b70
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
imulq %rcx, %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x60(%rbp), %rax
shlq $0x1f, %rax
movq -0x60(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x60(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x40(%rbp), %rax
jbe 0x6c64
movq -0x48(%rbp), %rax
shlq %rax
movq -0x48(%rbp), %rcx
shrq $0x3f, %rcx
orq %rcx, %rax
movq -0x50(%rbp), %rcx
shlq $0x7, %rcx
movq -0x50(%rbp), %rdx
shrq $0x39, %rdx
orq %rdx, %rcx
addq %rcx, %rax
movq -0x58(%rbp), %rcx
shlq $0xc, %rcx
movq -0x58(%rbp), %rdx
shrq $0x34, %rdx
orq %rdx, %rcx
addq %rcx, %rax
movq -0x60(%rbp), %rcx
shlq $0x12, %rcx
movq -0x60(%rbp), %rdx
shrq $0x2e, %rdx
orq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
shlq $0x1f, %rax
movq -0x48(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x48(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x38(%rbp), %rax
movabsq $-0x7a1435883d4d519d, %rcx # imm = 0x85EBCA77C2B2AE63
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
shlq $0x1f, %rax
movq -0x50(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x50(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x50(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x38(%rbp), %rax
movabsq $-0x7a1435883d4d519d, %rcx # imm = 0x85EBCA77C2B2AE63
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
shlq $0x1f, %rax
movq -0x58(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x58(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x38(%rbp), %rax
movabsq $-0x7a1435883d4d519d, %rcx # imm = 0x85EBCA77C2B2AE63
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
shlq $0x1f, %rax
movq -0x60(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x60(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x38(%rbp), %rax
movabsq $-0x7a1435883d4d519d, %rcx # imm = 0x85EBCA77C2B2AE63
addq %rcx, %rax
movq %rax, -0x38(%rbp)
jmp 0x6fe2
movabsq $0x27d4eb2f165667c5, %rax # imm = 0x27D4EB2F165667C5
addq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
cmpq -0x30(%rbp), %rax
ja 0x709c
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6b70
movq %rax, -0x68(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
shlq $0x1f, %rax
movq -0x68(%rbp), %rcx
shrq $0x21, %rcx
orq %rcx, %rax
movq %rax, -0x68(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shlq $0x1b, %rax
movq -0x38(%rbp), %rcx
shrq $0x25, %rcx
orq %rcx, %rax
movabsq $-0x61c8864e7a143579, %rcx # imm = 0x9E3779B185EBCA87
imulq %rcx, %rax
movabsq $-0x7a1435883d4d519d, %rcx # imm = 0x85EBCA77C2B2AE63
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0x6fee
movq -0x28(%rbp), %rax
addq $0x4, %rax
cmpq -0x30(%rbp), %rax
ja 0x710c
movq -0x28(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x6ba0
movl %eax, %eax
movabsq $-0x61c8864e7a143579, %rcx # imm = 0x9E3779B185EBCA87
imulq %rcx, %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shlq $0x17, %rax
movq -0x38(%rbp), %rcx
shrq $0x29, %rcx
orq %rcx, %rax
movabsq $-0x3d4d51c2d82b14b1, %rcx # imm = 0xC2B2AE3D27D4EB4F
imulq %rcx, %rax
movabsq $0x165667b19e3779f9, %rcx # imm = 0x165667B19E3779F9
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x28(%rbp)
jmp 0x710e
movq -0x28(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x7168
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
movabsq $0x27d4eb2f165667c5, %rcx # imm = 0x27D4EB2F165667C5
imulq %rcx, %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shlq $0xb, %rax
movq -0x38(%rbp), %rcx
shrq $0x35, %rcx
orq %rcx, %rax
movabsq $-0x61c8864e7a143579, %rcx # imm = 0x9E3779B185EBCA87
imulq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x710e
movq -0x38(%rbp), %rax
shrq $0x21, %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $-0x3d4d51c2d82b14b1, %rax # imm = 0xC2B2AE3D27D4EB4F
imulq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shrq $0x1d, %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movabsq $0x165667b19e3779f9, %rax # imm = 0x165667B19E3779F9
imulq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
shrq $0x20, %rax
xorq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)