// File: /workspace/github_c_makefile_star2_O0/enzo1982[P]smooth/libraries/libcpuid/recog_amd.c
// Function: decode_amd_cache_info
static void decode_amd_cache_info(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
	int l3_result, l3_assoc;
	const int assoc_table[16] = {
		0, 1, 2, 0, 4, 0, 8, 0, 16, 16, 32, 48, 64, 96, 128, 255
	};
	unsigned n = raw->ext_cpuid[0][EAX];

	if (n >= 0x80000005) {
		/* L1 Data Cache */
		data->l1_data_cache     = EXTRACTS_BITS(raw->ext_cpuid[5][ECX], 31, 24); // L1DcSize
		data->l1_data_assoc     = EXTRACTS_BITS(raw->ext_cpuid[5][ECX], 23, 16); // L1DcAssoc
		data->l1_data_cacheline = EXTRACTS_BITS(raw->ext_cpuid[5][ECX],  7,  0); // L1DcLineSize

		/* L1 Instruction Cache */
		data->l1_instruction_cache     = EXTRACTS_BITS(raw->ext_cpuid[5][EDX], 31, 24); // L1IcSize
		data->l1_instruction_assoc     = EXTRACTS_BITS(raw->ext_cpuid[5][EDX], 23, 16); // L1IcAssoc
		data->l1_instruction_cacheline = EXTRACTS_BITS(raw->ext_cpuid[5][EDX],  7,  0); // L1IcLineSize
	}
	if (n >= 0x80000006) {
		data->l2_cache = (raw->ext_cpuid[6][ECX] >> 16) & 0xffff;
		data->l2_assoc = assoc_table[(raw->ext_cpuid[6][ECX] >> 12) & 0xf];
		data->l2_cacheline = (raw->ext_cpuid[6][ECX]) & 0xff;

		l3_result = (raw->ext_cpuid[6][EDX] >> 18);
		if (l3_result > 0) {
			l3_result *= 512; /* AMD spec says it's a range, but we take the lower bound */
			l3_assoc = (raw->ext_cpuid[6][EDX] >> 12) & 0xf;
			data->l3_cache = l3_result;
			data->l3_assoc = assoc_table[l3_assoc];
			data->l3_cacheline = (raw->ext_cpuid[6][EDX]) & 0xff;
		} else {
			data->l3_cache = -1;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x60(%rbp), %rdi
leaq 0x78c35(%rip), %rsi     # 0x1b01d0
movl $0x40, %edx
callq 0x593a0
movq -0x8(%rbp), %rax
movl 0x200(%rax), %eax
movl %eax, -0x64(%rbp)
cmpl $0x80000005, -0x64(%rbp) # imm = 0x80000005
jb 0x137685
movq -0x8(%rbp), %rax
movl 0x258(%rax), %eax
shrl $0x18, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xf8(%rax)
movq -0x8(%rbp), %rax
movl 0x258(%rax), %eax
shrl $0x10, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x110(%rax)
movq -0x8(%rbp), %rax
movl 0x258(%rax), %eax
shrl $0x0, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x128(%rax)
movq -0x8(%rbp), %rax
movl 0x25c(%rax), %eax
shrl $0x18, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xfc(%rax)
movq -0x8(%rbp), %rax
movl 0x25c(%rax), %eax
shrl $0x10, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x114(%rax)
movq -0x8(%rbp), %rax
movl 0x25c(%rax), %eax
shrl $0x0, %eax
movl %eax, %eax
andq $0xff, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x12c(%rax)
cmpl $0x80000006, -0x64(%rbp) # imm = 0x80000006
jb 0x137766
movq -0x8(%rbp), %rax
movl 0x268(%rax), %ecx
shrl $0x10, %ecx
andl $0xffff, %ecx           # imm = 0xFFFF
movq -0x10(%rbp), %rax
movl %ecx, 0x100(%rax)
movq -0x8(%rbp), %rax
movl 0x268(%rax), %eax
shrl $0xc, %eax
andl $0xf, %eax
movl %eax, %eax
movl -0x60(%rbp,%rax,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x118(%rax)
movq -0x8(%rbp), %rax
movl 0x268(%rax), %ecx
andl $0xff, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x130(%rax)
movq -0x8(%rbp), %rax
movl 0x26c(%rax), %eax
shrl $0x12, %eax
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jle 0x137756
movl -0x14(%rbp), %eax
shll $0x9, %eax
movl %eax, -0x14(%rbp)
movq -0x8(%rbp), %rax
movl 0x26c(%rax), %eax
shrl $0xc, %eax
andl $0xf, %eax
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x104(%rax)
movslq -0x18(%rbp), %rax
movl -0x60(%rbp,%rax,4), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x11c(%rax)
movq -0x8(%rbp), %rax
movl 0x26c(%rax), %ecx
andl $0xff, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x134(%rax)
jmp 0x137764
movq -0x10(%rbp), %rax
movl $0xffffffff, 0x104(%rax) # imm = 0xFFFFFFFF
jmp 0x137766
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)