// File: /workspace/github_c_makefile_star2_O1/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:
testl %esi, %esi
je 0xcb497
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r14
movq %rdi, %r15
addq $0x8, %r15
movzbl %sil, %ebp
movl $0xfff, %r12d           # imm = 0xFFF
xorl %r13d, %r13d
movl -0x8(%r15), %edi
movl %edi, %edx
andl $0x1f, %edx
je 0xcb489
movl %edi, %eax
shrl $0x5, %eax
andl $0x7, %eax
je 0xcb489
movl %eax, %ecx
xorl $0x1, %ecx
movl %edx, %r8d
xorl $0x1, %r8d
movl $0x1, %esi
orl %ecx, %r8d
je 0xcb3aa
movl %edx, %r8d
xorl $0x2, %r8d
xorl %esi, %esi
orl %ecx, %r8d
je 0xcb3aa
movl %eax, %r8d
xorl $0x2, %r8d
movl %edx, %ecx
xorl $0x3, %ecx
movl $0x2, %esi
orl %ecx, %r8d
je 0xcb3aa
movl %eax, %r8d
xorl $0x3, %r8d
movl $0x3, %esi
orl %ecx, %r8d
je 0xcb3aa
movl %eax, %r8d
xorl $0x4, %r8d
movl $0x4, %esi
orl %r8d, %ecx
jne 0xcb469
shrl $0xe, %edi
andl %r12d, %edi
je 0xcb406
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 0xcb408
xorl %ecx, %ecx
movl -0x4(%r15), %r8d
movl (%r15), %edi
movl %r8d, %eax
shrl $0x16, %eax
incl %eax
movl %r8d, %edx
shrl $0xc, %edx
andl $0x3ff, %edx            # imm = 0x3FF
incl %edx
andl %r12d, %r8d
incl %r8d
incl %edi
imull %edx, %edi
movl %r8d, %edx
imull %eax, %edx
imull %edi, %edx
shrl $0xa, %edx
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
shll %cl, %edi
movl %edi, 0x14(%rbx,%r13,4)
movl $0x1, %edi
movl %eax, %ecx
movq %r14, %r9
callq 0xcb1ff
incq %r13
addq $0x10, %r15
cmpb %r13b, %bpl
jne 0xcb32d
jmp 0xcb489
leaq 0x4a2e9(%rip), %rdi     # 0x115759
movl %eax, %esi
xorl %eax, %eax
callq 0xca95e
leaq 0x4a31e(%rip), %rdi     # 0x11579e
xorl %eax, %eax
callq 0xca95e
jmp 0xcb457
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq