// File: sgielen[P]clife/./xxhash/xxhash.h
// Function: XXH3_len_129to240_64b(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned long)
XXH_NO_INLINE XXH_PUREF XXH64_hash_t
XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
                      const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
                      XXH64_hash_t seed)
{
    XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
    XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);

    #define XXH3_MIDSIZE_STARTOFFSET 3
    #define XXH3_MIDSIZE_LASTOFFSET  17

    {   xxh_u64 acc = len * XXH_PRIME64_1;
        int const nbRounds = (int)len / 16;
        int i;
        for (i=0; i<8; i++) {
            acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed);
        }
        acc = XXH3_avalanche(acc);
        XXH_ASSERT(nbRounds >= 8);
#if defined(__clang__)                                /* Clang */ \
    && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
    && !defined(XXH_ENABLE_AUTOVECTORIZE)             /* Define to disable */
        /*
         * UGLY HACK:
         * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86.
         * In everywhere else, it uses scalar code.
         *
         * For 64->128-bit multiplies, even if the NEON was 100% optimal, it
         * would still be slower than UMAAL (see XXH_mult64to128).
         *
         * Unfortunately, Clang doesn't handle the long multiplies properly and
         * converts them to the nonexistent "vmulq_u64" intrinsic, which is then
         * scalarized into an ugly mess of VMOV.32 instructions.
         *
         * This mess is difficult to avoid without turning autovectorization
         * off completely, but they are usually relatively minor and/or not
         * worth it to fix.
         *
         * This loop is the easiest to fix, as unlike XXH32, this pragma
         * _actually works_ because it is a loop vectorization instead of an
         * SLP vectorization.
         */
        #pragma clang loop vectorize(disable)
#endif
        for (i=8 ; i < nbRounds; i++) {
            acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
        }
        /* last bytes */
        acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
        return XXH3_avalanche(acc);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movabsq $-0x61c8864e7a143579, %rax # imm = 0x9E3779B185EBCA87
imulq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl $0x10, %ecx
cltd
idivl %ecx
movl %eax, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
cmpl $0x8, -0x38(%rbp)
jge 0x60c5
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %eax
shll $0x4, %eax
cltq
addq %rax, %rdi
movq -0x18(%rbp), %rsi
movl -0x38(%rbp), %eax
shll $0x4, %eax
cltq
addq %rax, %rsi
movq -0x28(%rbp), %rdx
callq 0x6540
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x6085
movq -0x30(%rbp), %rdi
callq 0x6400
movq %rax, -0x30(%rbp)
movl $0x8, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x6122
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %eax
shll $0x4, %eax
cltq
addq %rax, %rdi
movq -0x18(%rbp), %rsi
movl -0x38(%rbp), %eax
subl $0x8, %eax
shll $0x4, %eax
cltq
addq %rax, %rsi
addq $0x3, %rsi
movq -0x28(%rbp), %rdx
callq 0x6540
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x60d9
movq -0x8(%rbp), %rdi
addq -0x10(%rbp), %rdi
addq $-0x10, %rdi
movq -0x18(%rbp), %rsi
addq $0x88, %rsi
addq $-0x11, %rsi
movq -0x28(%rbp), %rdx
callq 0x6540
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0x6400
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)