// File: amadvance[P]tommyds/tommyds/tommyhash.c
// Function: tommy_strhash_u32
tommy_uint32_t tommy_strhash_u32(tommy_uint64_t init_val, const void* void_key)
{
	const unsigned char* key = tommy_cast(const unsigned char*, void_key);
	tommy_uint32_t a, b, c;
	tommy_uint32_t m[3] = { 0xff, 0xff00, 0xff0000 };

	a = b = c = 0xdeadbeef + init_val;
	/* this is different than original lookup3 and the result won't match */

	while (1) {
		tommy_uint32_t v = tommy_le_uint32_read(key);

		if (tommy_haszero_u32(v)) {
			if (v & m[0]) {
				a += v & m[0];
				if (v & m[1]) {
					a += v & m[1];
					if (v & m[2])
						a += v & m[2];
				}
			}

			break;
		}

		a += v;

		v = tommy_le_uint32_read(key + 4);

		if (tommy_haszero_u32(v)) {
			if (v & m[0]) {
				b += v & m[0];
				if (v & m[1]) {
					b += v & m[1];
					if (v & m[2])
						b += v & m[2];
				}
			}

			break;
		}

		b += v;

		v = tommy_le_uint32_read(key + 8);

		if (tommy_haszero_u32(v)) {
			if (v & m[0]) {
				c += v & m[0];
				if (v & m[1]) {
					c += v & m[1];
					if (v & m[2])
						c += v & m[2];
				}
			}

			break;
		}

		c += v;

		tommy_mix(a, b, c);

		key += 12;
	}

	/* for lengths that are multipliers of 12 we already have called mix */
	/* this is different than the original lookup3 and the result won't match */

	tommy_final(a, b, c);

	return c;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
movq 0x52a5(%rip), %rax      # 0xa4e4
movq %rax, -0x30(%rbp)
movl 0x52a3(%rip), %eax      # 0xa4ec
movl %eax, -0x28(%rbp)
movabsq $0xdeadbeef, %rax       # imm = 0xDEADBEEF
addq -0x8(%rbp), %rax
movl %eax, -0x24(%rbp)
movl %eax, -0x20(%rbp)
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4e40
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %edi
callq 0x55a0
cmpl $0x0, %eax
je 0x52ca
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
cmpl $0x0, %eax
je 0x52c5
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
cmpl $0x0, %eax
je 0x52c3
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
cmpl $0x0, %eax
je 0x52c1
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
jmp 0x52c3
jmp 0x52c5
jmp 0x54bc
movl -0x34(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
addq $0x4, %rdi
callq 0x4e40
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %edi
callq 0x55a0
cmpl $0x0, %eax
je 0x533e
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
cmpl $0x0, %eax
je 0x5339
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
cmpl $0x0, %eax
je 0x5337
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
cmpl $0x0, %eax
je 0x5335
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
jmp 0x5337
jmp 0x5339
jmp 0x54bc
movl -0x34(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x4e40
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %edi
callq 0x55a0
cmpl $0x0, %eax
je 0x53b2
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
cmpl $0x0, %eax
je 0x53ad
movl -0x34(%rbp), %eax
andl -0x30(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
cmpl $0x0, %eax
je 0x53ab
movl -0x34(%rbp), %eax
andl -0x2c(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
cmpl $0x0, %eax
je 0x53a9
movl -0x34(%rbp), %eax
andl -0x28(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x53ab
jmp 0x53ad
jmp 0x54bc
movl -0x34(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x24(%rbp), %eax
shll $0x4, %eax
movl -0x24(%rbp), %ecx
shrl $0x1c, %ecx
orl %ecx, %eax
xorl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x1c(%rbp), %ecx
movl -0x20(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
shll $0x6, %eax
movl -0x1c(%rbp), %ecx
shrl $0x1a, %ecx
orl %ecx, %eax
xorl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x24(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %eax
shll $0x8, %eax
movl -0x20(%rbp), %ecx
shrl $0x18, %ecx
orl %ecx, %eax
xorl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x24(%rbp), %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x24(%rbp), %eax
shll $0x10, %eax
movl -0x24(%rbp), %ecx
shrl $0x10, %ecx
orl %ecx, %eax
xorl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x1c(%rbp), %ecx
movl -0x20(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
shll $0x13, %eax
movl -0x1c(%rbp), %ecx
shrl $0xd, %ecx
orl %ecx, %eax
xorl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x24(%rbp), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %eax
shll $0x4, %eax
movl -0x20(%rbp), %ecx
shrl $0x1c, %ecx
orl %ecx, %eax
xorl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x1c(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x18(%rbp)
jmp 0x5263
jmp 0x54be
movl -0x20(%rbp), %eax
xorl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %ecx
shll $0xe, %ecx
movl -0x20(%rbp), %eax
shrl $0x12, %eax
orl %eax, %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
xorl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x24(%rbp), %ecx
shll $0xb, %ecx
movl -0x24(%rbp), %eax
shrl $0x15, %eax
orl %eax, %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
xorl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %ecx
shll $0x19, %ecx
movl -0x1c(%rbp), %eax
shrl $0x7, %eax
orl %eax, %ecx
movl -0x20(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
xorl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %ecx
shll $0x10, %ecx
movl -0x20(%rbp), %eax
shrl $0x10, %eax
orl %eax, %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
xorl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x24(%rbp), %ecx
shll $0x4, %ecx
movl -0x24(%rbp), %eax
shrl $0x1c, %eax
orl %eax, %ecx
movl -0x1c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
xorl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %ecx
shll $0xe, %ecx
movl -0x1c(%rbp), %eax
shrl $0x12, %eax
orl %eax, %ecx
movl -0x20(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
xorl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x20(%rbp), %ecx
shll $0x18, %ecx
movl -0x20(%rbp), %eax
shrl $0x8, %eax
orl %eax, %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq