// File: /workspace/github_cpp_makefile_star2_O3/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:
addl $0xdeadbeef, %edi       # imm = 0xDEADBEEF
movl (%rsi), %ecx
movl $0x1010100, %eax        # imm = 0x1010100
subl %ecx, %eax
orl %ecx, %eax
notl %eax
testl $0x80808080, %eax       # imm = 0x80808080
jne 0x4001
addq $0xc, %rsi
movl %edi, %edx
movl %edi, %eax
addl %edi, %ecx
movl -0x8(%rsi), %edi
movl $0x1010100, %r8d        # imm = 0x1010100
subl %edi, %r8d
orl %edi, %r8d
notl %r8d
testl $0x80808080, %r8d       # imm = 0x80808080
jne 0x4027
addl %edx, %edi
movl -0x4(%rsi), %edx
movl $0x1010100, %r8d        # imm = 0x1010100
subl %edx, %r8d
orl %edx, %r8d
notl %r8d
testl $0x80808080, %r8d       # imm = 0x80808080
jne 0x4045
addl %eax, %edx
movl %edx, %eax
roll $0x4, %eax
subl %edx, %ecx
xorl %ecx, %eax
addl %edi, %edx
subl %eax, %edi
movl %eax, %ecx
roll $0x6, %ecx
xorl %edi, %ecx
addl %edx, %eax
movl %ecx, %r8d
roll $0x8, %r8d
subl %ecx, %edx
xorl %edx, %r8d
addl %eax, %ecx
subl %r8d, %eax
movl %r8d, %edi
roll $0x10, %edi
xorl %eax, %edi
addl %ecx, %r8d
movl %edi, %edx
roll $0x13, %edx
subl %edi, %ecx
xorl %ecx, %edx
addl %r8d, %edi
subl %edx, %r8d
movl %edx, %eax
roll $0x4, %eax
xorl %r8d, %eax
addl %edi, %edx
movl (%rsi), %ecx
movl $0x1010100, %r8d        # imm = 0x1010100
subl %ecx, %r8d
orl %ecx, %r8d
notl %r8d
addq $0xc, %rsi
testl $0x80808080, %r8d       # imm = 0x80808080
je 0x3f4e
jmp 0x4005
movl %edi, %eax
movl %edi, %edx
movl %ecx, %esi
andl $0xff, %esi
je 0x4023
addl %edi, %esi
testl $0xff00, %ecx           # imm = 0xFF00
je 0x4065
andl $0xffff00, %ecx         # imm = 0xFFFF00
addl %esi, %ecx
jmp 0x4067
movl %edi, %ecx
jmp 0x4067
movl %edi, %esi
andl $0xff, %esi
je 0x4067
addl %esi, %edx
testl $0xff00, %edi           # imm = 0xFF00
je 0x4067
andl $0xffff00, %edi         # imm = 0xFFFF00
addl %edi, %edx
jmp 0x4067
movl %edx, %esi
andl $0xff, %esi
je 0x4061
addl %esi, %eax
testl $0xff00, %edx           # imm = 0xFF00
je 0x4061
andl $0xffff00, %edx         # imm = 0xFFFF00
addl %edx, %eax
movl %edi, %edx
jmp 0x4067
movl %esi, %ecx
xorl %edx, %eax
movl %edx, %esi
roll $0xe, %esi
subl %esi, %eax
xorl %eax, %ecx
movl %eax, %esi
roll $0xb, %esi
subl %esi, %ecx
xorl %ecx, %edx
movl %ecx, %esi
roll $0x19, %esi
subl %esi, %edx
movl %edx, %esi
roll $0x10, %esi
xorl %edx, %eax
subl %esi, %eax
xorl %eax, %ecx
movl %eax, %esi
roll $0x4, %esi
subl %esi, %ecx
xorl %ecx, %edx
roll $0xe, %ecx
subl %ecx, %edx
xorl %edx, %eax
roll $0x18, %edx
subl %edx, %eax
retq