// File: /workspace/github_c_makefile_star2_O2/enzo1982[P]smooth/libraries/libcpuid/libcpuid_util.c
// Function: decode_deterministic_cache_info_x86
void decode_deterministic_cache_info_x86(uint32_t cache_regs[][NUM_REGS],
                                         uint8_t subleaf_count,
                                         struct cpu_id_t* data,
                                         struct internal_id_info_t* internal)
{
	uint8_t i;
	uint32_t cache_level, cache_type, ways, partitions, linesize, sets, size, num_sharing_cache, index_msb;
	cache_type_t type;

	for (i = 0; i < subleaf_count; i++) {
		cache_level = EXTRACTS_BITS(cache_regs[i][EAX], 7, 5);
		cache_type  = EXTRACTS_BITS(cache_regs[i][EAX], 4, 0);
		if ((cache_level == 0) || (cache_type == 0))
			break;
		if (cache_level == 1 && cache_type == 1)
			type = L1D;
		else if (cache_level == 1 && cache_type == 2)
			type = L1I;
		else if (cache_level == 2 && cache_type == 3)
			type = L2;
		else if (cache_level == 3 && cache_type == 3)
			type = L3;
		else if (cache_level == 4 && cache_type == 3)
			type = L4;
		else {
			warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", cache_level, cache_type);
			warnf("deterministic_cache: recognize cache type\n");
			continue;
		}
		num_sharing_cache       = EXTRACTS_BITS(cache_regs[i][EAX], 25, 14) + 1;
		ways                    = EXTRACTS_BITS(cache_regs[i][EBX], 31, 22) + 1;
		partitions              = EXTRACTS_BITS(cache_regs[i][EBX], 21, 12) + 1;
		linesize                = EXTRACTS_BITS(cache_regs[i][EBX], 11,  0) + 1;
		sets                    = EXTRACTS_BITS(cache_regs[i][ECX], 31,  0) + 1;
		size                    = ways * partitions * linesize * sets / 1024;
		index_msb               = get_count_order(num_sharing_cache);
		internal->cache_mask[i] = ~((1 << index_msb) - 1);
		assign_cache_data(1, type, size, ways, linesize, data);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, (%rsp)
movq %rdx, %r14
movl %esi, %r15d
movq %rdi, %r12
shll $0x2, %r15d
pushq $0x1
popq %rbp
movl $0xfff, %r13d           # imm = 0xFFF
xorl %ebx, %ebx
cmpq %rbx, %r15
je 0xc3ec3
movl (%r12,%rbx,4), %edi
movl %edi, %edx
andl $0x1f, %edx
je 0xc3ec3
movl %edi, %eax
shrl $0x5, %eax
andl $0x7, %eax
je 0xc3ec3
movl %eax, %ecx
xorl $0x1, %ecx
movl %edx, %esi
xorl $0x1, %esi
orl %ecx, %esi
movl %ebp, %esi
je 0xc3dec
movl %edx, %r8d
xorl $0x2, %r8d
xorl %esi, %esi
orl %ecx, %r8d
je 0xc3dec
movl %eax, %esi
xorl $0x2, %esi
movl %edx, %ecx
xorl $0x3, %ecx
orl %ecx, %esi
pushq $0x2
popq %rsi
je 0xc3dec
movl %eax, %esi
xorl $0x3, %esi
orl %ecx, %esi
pushq $0x3
popq %rsi
je 0xc3dec
movl %eax, %esi
xorl $0x4, %esi
orl %esi, %ecx
pushq $0x4
popq %rsi
jne 0xc3ea3
shrl $0xe, %edi
andl %r13d, %edi
je 0xc3e48
xorl %eax, %eax
cmpl $0x100, %edi            # imm = 0x100
setae %al
setb %cl
shlb $0x3, %cl
orb $0x10, %cl
shll %cl, %edi
leal 0x8(,%rax,8), %ecx
movl %edi, %edx
shll $0x4, %edx
cmpl $0x10000000, %edi       # imm = 0x10000000
leal 0x4(,%rax,8), %eax
cmovael %edi, %edx
cmovael %ecx, %eax
leal (,%rdx,4), %ecx
leal -0x2(%rax), %edi
cmpl $0x40000000, %edx       # imm = 0x40000000
cmovael %edx, %ecx
cmovael %eax, %edi
notl %ecx
sarl $0x1f, %ecx
addl %edi, %ecx
jmp 0xc3e4a
xorl %ecx, %ecx
movl 0x4(%r12,%rbx,4), %r8d
movl 0x8(%r12,%rbx,4), %edi
movl %r8d, %eax
shrl $0x16, %eax
incl %eax
movl %r8d, %edx
shrl $0xc, %edx
andl $0x3ff, %edx            # imm = 0x3FF
incl %edx
andl %r13d, %r8d
incl %r8d
incl %edi
imull %edx, %edi
movl %r8d, %edx
imull %eax, %edx
imull %edi, %edx
shrl $0xa, %edx
pushq $-0x1
popq %rdi
shll %cl, %edi
movq (%rsp), %rcx
movl %edi, 0x14(%rcx,%rbx)
movl %ebp, %edi
movl %eax, %ecx
movq %r14, %r9
callq 0xc3c5f
addq $0x4, %rbx
jmp 0xc3d7b
leaq 0x4094f(%rip), %rdi     # 0x1047f9
movl %eax, %esi
xorl %eax, %eax
callq 0xc340e
leaq 0x40984(%rip), %rdi     # 0x10483e
xorl %eax, %eax
callq 0xc340e
jmp 0xc3e9a
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop