// File: /workspace/github_cpp_makefile_star2_O2/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:
movq %rdi, %rax
addl $0xdeadbeef, %eax       # imm = 0xDEADBEEF
movl %eax, %ecx
movl %eax, %edi
movl (%rsi), %edx
movl $0x1010100, %r8d        # imm = 0x1010100
subl %edx, %r8d
orl %edx, %r8d
notl %r8d
testl $0x80808080, %r8d       # imm = 0x80808080
jne 0x350b
addl %edi, %edx
movl 0x4(%rsi), %edi
movl $0x1010100, %r8d        # imm = 0x1010100
subl %edi, %r8d
orl %edi, %r8d
notl %r8d
testl $0x80808080, %r8d       # imm = 0x80808080
jne 0x3528
addl %ecx, %edi
movl 0x8(%rsi), %ecx
movl $0x1010100, %r8d        # imm = 0x1010100
subl %ecx, %r8d
orl %ecx, %r8d
notl %r8d
testl $0x80808080, %r8d       # imm = 0x80808080
jne 0x3545
addl %eax, %ecx
subl %ecx, %edx
movl %ecx, %eax
roll $0x4, %eax
xorl %edx, %eax
addl %edi, %ecx
movl %eax, %edx
roll $0x6, %edx
subl %eax, %edi
xorl %edi, %edx
addl %ecx, %eax
subl %edx, %ecx
movl %edx, %r8d
roll $0x8, %r8d
xorl %ecx, %r8d
addl %eax, %edx
movl %r8d, %edi
roll $0x10, %edi
subl %r8d, %eax
xorl %eax, %edi
addl %edx, %r8d
subl %edi, %edx
movl %edi, %ecx
roll $0x13, %ecx
xorl %edx, %ecx
addl %r8d, %edi
movl %ecx, %eax
roll $0x4, %eax
subl %ecx, %r8d
xorl %r8d, %eax
addl %edi, %ecx
addq $0xc, %rsi
jmp 0x3455
movl %edx, %esi
andl $0xff, %esi
je 0x3564
addl %edi, %esi
testw $0xff00, %dx            # imm = 0xFF00
je 0x3568
andl $0xffff00, %edx         # imm = 0xFFFF00
addl %esi, %edx
jmp 0x356a
movl %edi, %esi
andl $0xff, %esi
je 0x356a
addl %esi, %ecx
testw $0xff00, %di            # imm = 0xFF00
je 0x356a
andl $0xffff00, %edi         # imm = 0xFFFF00
addl %edi, %ecx
jmp 0x356a
movl %ecx, %esi
andl $0xff, %esi
je 0x3560
addl %esi, %eax
testw $0xff00, %cx            # imm = 0xFF00
je 0x3560
andl $0xffff00, %ecx         # imm = 0xFFFF00
addl %ecx, %eax
movl %edi, %ecx
jmp 0x356a
movl %edi, %edx
jmp 0x356a
movl %esi, %edx
xorl %ecx, %eax
movl %ecx, %esi
roll $0xe, %esi
subl %esi, %eax
xorl %eax, %edx
movl %eax, %esi
roll $0xb, %esi
subl %esi, %edx
xorl %edx, %ecx
movl %edx, %esi
roll $0x19, %esi
subl %esi, %ecx
movl %ecx, %esi
roll $0x10, %esi
xorl %ecx, %eax
subl %esi, %eax
xorl %eax, %edx
movl %eax, %esi
roll $0x4, %esi
subl %esi, %edx
xorl %edx, %ecx
roll $0xe, %edx
subl %edx, %ecx
xorl %ecx, %eax
roll $0x18, %ecx
subl %ecx, %eax
retq