// File: /workspace/github_c_makefile_star2_O3/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 0xca6a0
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r14
movq %rdi, %r15
movzbl %sil, %ebp
shll $0x2, %ebp
movl $0xfff, %r12d           # imm = 0xFFF
xorl %r13d, %r13d
movl (%r15,%r13,4), %edi
movl %edi, %edx
andl $0x1f, %edx
je 0xca692
movl %edi, %eax
shrl $0x5, %eax
andl $0x7, %eax
je 0xca692
movl %eax, %ecx
xorl $0x1, %ecx
movl %edx, %r8d
xorl $0x1, %r8d
movl $0x1, %esi
orl %ecx, %r8d
je 0xca5b3
movl %edx, %r8d
xorl $0x2, %r8d
xorl %esi, %esi
orl %ecx, %r8d
je 0xca5b3
movl %eax, %r8d
xorl $0x2, %r8d
movl %edx, %ecx
xorl $0x3, %ecx
movl $0x2, %esi
orl %ecx, %r8d
je 0xca5b3
movl %eax, %r8d
xorl $0x3, %r8d
movl $0x3, %esi
orl %ecx, %r8d
je 0xca5b3
movl %eax, %r8d
xorl $0x4, %r8d
movl $0x4, %esi
orl %r8d, %ecx
jne 0xca672
shrl $0xe, %edi
andl %r12d, %edi
je 0xca60f
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 0xca611
xorl %ecx, %ecx
movl 0x4(%r15,%r13,4), %r8d
movl 0x8(%r15,%r13,4), %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)
movl $0x1, %edi
movl %eax, %ecx
movq %r14, %r9
callq 0xca409
addq $0x4, %r13
cmpq %r13, %rbp
jne 0xca536
jmp 0xca692
leaq 0x4a2f0(%rip), %rdi     # 0x114969
movl %eax, %esi
xorl %eax, %eax
callq 0xc9b82
leaq 0x4a325(%rip), %rdi     # 0x1149ae
xorl %eax, %eax
callq 0xc9b82
jmp 0xca663
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)