// File: attractivechaos[P]udb2/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 multiplers 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:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq %rsi, 0x28(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x5021(%rip), %rax      # 0x7100
movq %rax, 0x8(%rsp)
movl 0x501e(%rip), %eax      # 0x7108
movl %eax, 0x10(%rsp)
movabsq $0xdeadbeef, %rax       # imm = 0xDEADBEEF
addq 0x30(%rsp), %rax
movl %eax, 0x14(%rsp)
movl %eax, 0x18(%rsp)
movl %eax, 0x1c(%rsp)
movq 0x20(%rsp), %rdi
callq 0x1c20
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %edi
callq 0x2500
cmpl $0x0, %eax
je 0x2185
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
cmpl $0x0, %eax
je 0x2180
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
cmpl $0x0, %eax
je 0x217e
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
cmpl $0x0, %eax
je 0x217c
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
jmp 0x217e
jmp 0x2180
jmp 0x23e8
movl 0x4(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x20(%rsp), %rdi
addq $0x4, %rdi
callq 0x1c20
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %edi
callq 0x2500
cmpl $0x0, %eax
je 0x2211
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
cmpl $0x0, %eax
je 0x220c
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
cmpl $0x0, %eax
je 0x220a
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
cmpl $0x0, %eax
je 0x2208
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0x220a
jmp 0x220c
jmp 0x23e8
movl 0x4(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movq 0x20(%rsp), %rdi
addq $0x8, %rdi
callq 0x1c20
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %edi
callq 0x2500
cmpl $0x0, %eax
je 0x229d
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
cmpl $0x0, %eax
je 0x2298
movl 0x4(%rsp), %eax
andl 0x8(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
cmpl $0x0, %eax
je 0x2296
movl 0x4(%rsp), %eax
andl 0xc(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
cmpl $0x0, %eax
je 0x2294
movl 0x4(%rsp), %eax
andl 0x10(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
jmp 0x2296
jmp 0x2298
jmp 0x23e8
movl 0x4(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %ecx
movl 0x1c(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x1c(%rsp)
movl 0x14(%rsp), %eax
shll $0x4, %eax
movl 0x14(%rsp), %ecx
shrl $0x1c, %ecx
orl %ecx, %eax
xorl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x18(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x1c(%rsp), %ecx
movl 0x18(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x18(%rsp)
movl 0x1c(%rsp), %eax
shll $0x6, %eax
movl 0x1c(%rsp), %ecx
shrl $0x1a, %ecx
orl %ecx, %eax
xorl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x14(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x18(%rsp), %ecx
movl 0x14(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %eax
shll $0x8, %eax
movl 0x18(%rsp), %ecx
shrl $0x18, %ecx
orl %ecx, %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x1c(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x14(%rsp), %ecx
movl 0x1c(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x1c(%rsp)
movl 0x14(%rsp), %eax
shll $0x10, %eax
movl 0x14(%rsp), %ecx
shrl $0x10, %ecx
orl %ecx, %eax
xorl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x18(%rsp), %eax
addl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x1c(%rsp), %ecx
movl 0x18(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x18(%rsp)
movl 0x1c(%rsp), %eax
shll $0x13, %eax
movl 0x1c(%rsp), %ecx
shrl $0xd, %ecx
orl %ecx, %eax
xorl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x14(%rsp), %eax
addl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x18(%rsp), %ecx
movl 0x14(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %eax
shll $0x4, %eax
movl 0x18(%rsp), %ecx
shrl $0x1c, %ecx
orl %ecx, %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x1c(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movq 0x20(%rsp), %rax
addq $0xc, %rax
movq %rax, 0x20(%rsp)
jmp 0x2109
jmp 0x23ea
movl 0x18(%rsp), %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %ecx
shll $0xe, %ecx
movl 0x18(%rsp), %eax
shrl $0x12, %eax
orl %eax, %ecx
movl 0x14(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %eax
xorl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x14(%rsp), %ecx
shll $0xb, %ecx
movl 0x14(%rsp), %eax
shrl $0x15, %eax
orl %eax, %ecx
movl 0x1c(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
xorl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x1c(%rsp), %ecx
shll $0x19, %ecx
movl 0x1c(%rsp), %eax
shrl $0x7, %eax
orl %eax, %ecx
movl 0x18(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %ecx
shll $0x10, %ecx
movl 0x18(%rsp), %eax
shrl $0x10, %eax
orl %eax, %ecx
movl 0x14(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %eax
xorl 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movl 0x14(%rsp), %ecx
shll $0x4, %ecx
movl 0x14(%rsp), %eax
shrl $0x1c, %eax
orl %eax, %ecx
movl 0x1c(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
xorl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x1c(%rsp), %ecx
shll $0xe, %ecx
movl 0x1c(%rsp), %eax
shrl $0x12, %eax
orl %eax, %ecx
movl 0x18(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %ecx
shll $0x18, %ecx
movl 0x18(%rsp), %eax
shrl $0x8, %eax
orl %eax, %ecx
movl 0x14(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x14(%rsp)
movl 0x14(%rsp), %eax
addq $0x38, %rsp
retq
nopl (%rax)