// File: /workspace/github_c_makefile_star2_O3/janet-lang[P]janet/src/core/value.c
// Function: janet_hash
int32_t janet_hash(Janet x) {
    int32_t hash = 0;
    switch (janet_type(x)) {
        case JANET_NIL:
            hash = 0;
            break;
        case JANET_BOOLEAN:
            hash = janet_unwrap_boolean(x);
            break;
        case JANET_STRING:
        case JANET_SYMBOL:
        case JANET_KEYWORD:
            hash = janet_string_hash(janet_unwrap_string(x));
            break;
        case JANET_TUPLE:
            hash = janet_tuple_hash(janet_unwrap_tuple(x));
            hash += (janet_tuple_flag(janet_unwrap_tuple(x)) & JANET_TUPLE_FLAG_BRACKETCTOR) ? 1 : 0;
            break;
        case JANET_STRUCT:
            hash = janet_struct_hash(janet_unwrap_struct(x));
            break;
        case JANET_NUMBER: {
            union {
                double d;
                uint64_t u;
            } as;
            as.d = janet_unwrap_number(x);
            as.d += 0.0; /* normalize negative 0 */
            uint32_t lo = (uint32_t)(as.u & 0xFFFFFFFF);
            uint32_t hi = (uint32_t)(as.u >> 32);
            uint32_t hilo = (hi ^ lo) * 2654435769u;
            hash = (int32_t)((hilo << 16) | (hilo >> 16));
            break;
        }
        case JANET_ABSTRACT: {
            JanetAbstract xx = janet_unwrap_abstract(x);
            const JanetAbstractType *at = janet_abstract_type(xx);
            if (at->hash != NULL) {
                hash = at->hash(xx, janet_abstract_size(xx));
                break;
            }
        }
        /* fallthrough */
        default:
            if (sizeof(double) == sizeof(void *)) {
                /* Assuming 8 byte pointer (8 byte aligned) */
                uint64_t i = murmur64(janet_u64(x));
                hash = (int32_t)(i >> 32);
            } else {
                /* Assuming 4 byte pointer (or smaller) */
                uintptr_t diff = (uintptr_t) janet_unwrap_pointer(x);
                uint32_t hilo = (uint32_t) diff * 2654435769u;
                hash = (int32_t)((hilo << 16) | (hilo >> 16));
            }
            break;
    }
    return hash;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq %rdi, %xmm0
movq %rdi, %rax
shrq $0x2f, %rax
andl $0xf, %eax
xorl %r14d, %r14d
ucomisd %xmm0, %xmm0
cmovnpl %r14d, %eax
cmpl $0xe, %eax
ja 0x4a759
leaq 0x21059(%rip), %rcx     # 0x6b70c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rbx, %rdi
callq 0x4ebc4
movl -0x4(%rax), %r14d
jmp 0x4a78d
andl $0x1, %ebx
movl %ebx, %r14d
jmp 0x4a78d
movq %rbx, %rdi
callq 0x4ebc4
movl -0xc(%rax), %r14d
movq %rbx, %rdi
callq 0x4ebc4
btl $0x10, -0x20(%rax)
adcl $0x0, %r14d
jmp 0x4a78d
movq %rbx, %rdi
callq 0x4ebc4
movl -0x14(%rax), %r14d
jmp 0x4a78d
xorpd %xmm1, %xmm1
addsd %xmm1, %xmm0
movq %xmm0, %rax
movq %rax, %rcx
shrq $0x20, %rcx
xorl %eax, %ecx
imull $0x9e3779b9, %ecx, %r14d # imm = 0x9E3779B9
imull $0x79b90000, %ecx, %eax # imm = 0x79B90000
shrl $0x10, %r14d
orl %eax, %r14d
jmp 0x4a78d
movq %rbx, %rdi
callq 0x4ebc4
movq -0x10(%rax), %rcx
movq 0x48(%rcx), %rcx
testq %rcx, %rcx
je 0x4a759
movq -0x8(%rax), %rsi
movq %rax, %rdi
popq %rbx
popq %r14
popq %rbp
jmpq *%rcx
movq %rbx, %rax
shrq $0x21, %rax
xorq %rbx, %rax
movabsq $-0xae502812aa7333, %rcx # imm = 0xFF51AFD7ED558CCD
imulq %rax, %rcx
movq %rcx, %rax
shrq $0x21, %rax
xorq %rcx, %rax
movabsq $-0x3b314601e57a13ad, %r14 # imm = 0xC4CEB9FE1A85EC53
imulq %rax, %r14
shrq $0x20, %r14
movl %r14d, %eax
popq %rbx
popq %r14
popq %rbp
retq