// File: /workspace/github_c_makefile_star2_O1/enzo1982[P]smooth/libraries/libcpuid/cpuid_main.c
// Function: cpu_identify_all
int cpu_identify_all(struct cpu_raw_data_array_t* raw_array, struct system_id_t* system)
{
	int cur_error = cpuid_set_error(ERR_OK);
	int ret_error = cpuid_set_error(ERR_OK);
	double smt_divisor;
	bool is_new_cpu_type;
	bool is_last_item;
	bool is_smt_supported;
	bool is_apic_supported = true;
	uint8_t cpu_type_index = 0;
	int32_t num_logical_cpus = 0;
	int32_t cur_package_id = 0;
	int32_t prev_package_id = 0;
	logical_cpu_t logical_cpu = 0;
	cpu_purpose_t purpose;
	cpu_affinity_mask_t affinity_mask;
	struct cpu_raw_data_array_t my_raw_array;
	struct internal_id_info_t id_info;
	struct internal_apic_info_t apic_info;
	struct internal_core_instances_t cores_type;
	struct internal_cache_instances_t caches_type, caches_all;

	if (system == NULL)
		return cpuid_set_error(ERR_HANDLE);
	if (!raw_array) {
		if ((ret_error = cpuid_get_all_raw_data(&my_raw_array)) < 0)
			return cpuid_set_error(ret_error);
		raw_array = &my_raw_array;
	}
	system_id_t_constructor(system);
	core_instances_t_constructor(&cores_type);
	cache_instances_t_constructor(&caches_type);
	cache_instances_t_constructor(&caches_all);
	if (raw_array->with_affinity)
		init_affinity_mask(&affinity_mask);

	/* Iterate over all raw */
	for (logical_cpu = 0; logical_cpu < raw_array->num_raw; logical_cpu++) {
		is_new_cpu_type = false;
		is_last_item    = (logical_cpu + 1 >= raw_array->num_raw);
		debugf(2, "Identifying logical core %u\n", logical_cpu);
		/* Get CPU purpose and APIC ID
		   For hybrid CPUs, the purpose may be different than the previous iteration (e.g. from P-cores to E-cores)
		   APIC ID are unique for each logical CPU cores.
		*/
		purpose = cpu_ident_purpose(&raw_array->raw[logical_cpu]);
		if (raw_array->with_affinity && is_apic_supported) {
			is_apic_supported = cpu_ident_apic_id(logical_cpu, &raw_array->raw[logical_cpu], &apic_info);
			if (is_apic_supported)
				cur_package_id = apic_info.package_id;
		}

		/* Put data to system->cpu_types on the first iteration or when purpose is different than previous core */
		if ((system->num_cpu_types == 0) || (purpose != system->cpu_types[system->num_cpu_types - 1].purpose) || (cur_package_id != prev_package_id)) {
			is_new_cpu_type = true;
			cpu_type_index  = system->num_cpu_types;
			cpuid_grow_system_id(system, system->num_cpu_types + 1);
			cur_error = cpu_ident_internal(&raw_array->raw[logical_cpu], &system->cpu_types[cpu_type_index], &id_info);
			if (ret_error == ERR_OK)
				ret_error = cur_error;
		}
		/* Increment counters only for current purpose */
		if (raw_array->with_affinity && ((logical_cpu == 0) || !is_new_cpu_type)) {
			set_affinity_mask_bit(logical_cpu, &affinity_mask);
			num_logical_cpus++;
			if (is_apic_supported) {
				update_core_instances(&cores_type, &apic_info);
				update_cache_instances(&caches_type, &apic_info, &id_info, true);
				update_cache_instances(&caches_all,  &apic_info, &id_info, false);
			}
		}

		/* Update logical CPU counters, physical CPU counters and cache instance in system->cpu_types
		   Note: we need to differenciate two events:
		     - is_new_cpu_type (e.g. purpose was 'efficiency' during previous loop, and now purpose is 'performance')
		     - is_last_item (i.e. this is the last iteration in raw_array->num_raw)
		   In some cases, both events can occur during the same iteration, thus we have to update counters twice for the same logical_cpu.
		   This occurs with single-core CPU type. For instance, Pentacore Lakefield CPU consists of:
		     - 1 "big" Sunny Cove core
		     - 4 "little" Tremont cores
		   On the last iteration, there is no need to reset values for the next purpose.
		*/
		if (raw_array->with_affinity && (is_last_item || (is_new_cpu_type && (system->num_cpu_types > 1)))) {
			enum event_t {
				EVENT_NEW_CPU_TYPE = 0,
				EVENT_LAST_ITEM    = 1
			};
			const enum event_t first_event = is_new_cpu_type && (system->num_cpu_types > 1) ? EVENT_NEW_CPU_TYPE : EVENT_LAST_ITEM;
			const enum event_t last_event  = is_last_item                                   ? EVENT_LAST_ITEM    : EVENT_NEW_CPU_TYPE;
			enum event_t event;
			for (event = first_event; event <= last_event; event++) {
				switch (event) {
					case EVENT_NEW_CPU_TYPE: cpu_type_index = system->num_cpu_types - 2; break;
					case EVENT_LAST_ITEM:    cpu_type_index = system->num_cpu_types - 1; break;
					default: warnf("Warning: event %i in cpu_identify_all() not handled.\n", event); return cpuid_set_error(ERR_NOT_IMP);
				}
				copy_affinity_mask(&system->cpu_types[cpu_type_index].affinity_mask, &affinity_mask);
				if (event != EVENT_LAST_ITEM) {
					init_affinity_mask(&affinity_mask);
					set_affinity_mask_bit(logical_cpu, &affinity_mask);
				}
				if (is_apic_supported) {
					system->cpu_types[cpu_type_index].num_cores                = cores_type.instances;
					system->cpu_types[cpu_type_index].l1_instruction_instances = caches_type.instances[L1I];
					system->cpu_types[cpu_type_index].l1_data_instances        = caches_type.instances[L1D];
					system->cpu_types[cpu_type_index].l2_instances             = caches_type.instances[L2];
					system->cpu_types[cpu_type_index].l3_instances             = caches_type.instances[L3];
					system->cpu_types[cpu_type_index].l4_instances             = caches_type.instances[L4];
					if (event != EVENT_LAST_ITEM) {
						core_instances_t_constructor(&cores_type);
						cache_instances_t_constructor(&caches_type);
						update_core_instances(&cores_type, &apic_info);
						update_cache_instances(&caches_type, &apic_info, &id_info, true);
						update_cache_instances(&caches_all,  &apic_info, &id_info, false);
					}
				}
				else {
					/* Note: if SMT is disabled by BIOS, smt_divisor will no reflect the current state properly */
					is_smt_supported = system->cpu_types[cpu_type_index].num_cores > 0 ? (system->cpu_types[cpu_type_index].num_logical_cpus % system->cpu_types[cpu_type_index].num_cores) == 0 : false;
					smt_divisor      = is_smt_supported ? system->cpu_types[cpu_type_index].num_logical_cpus / system->cpu_types[cpu_type_index].num_cores : 1.0;
					system->cpu_types[cpu_type_index].num_cores = (int32_t) (num_logical_cpus / smt_divisor);
				}
				/* Save current values in system->cpu_types[cpu_type_index] and reset values for the next purpose */
				system->cpu_types[cpu_type_index].num_logical_cpus = num_logical_cpus;
				num_logical_cpus = 1;
			}
		}
		prev_package_id = cur_package_id;
	}

	/* Update the grand total of cache instances */
	if (is_apic_supported) {
		system->l1_instruction_total_instances = caches_all.instances[L1I];
		system->l1_data_total_instances        = caches_all.instances[L1D];
		system->l2_total_instances             = caches_all.instances[L2];
		system->l3_total_instances             = caches_all.instances[L3];
		system->l4_total_instances             = caches_all.instances[L4];
	}

	/* Update the total_logical_cpus value for each purpose */
	for (cpu_type_index = 0; cpu_type_index < system->num_cpu_types; cpu_type_index++)
		system->cpu_types[cpu_type_index].total_logical_cpus = logical_cpu;

	return ret_error;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78d8, %rsp           # imm = 0x78D8
movq %rsi, %r14
movq %rdi, %r15
leaq 0xa29fd(%rip), %rdi     # 0x16c330
callq 0x566e0
leaq 0x30(%rax), %rax
movq %rax, 0x30(%rsp)
movl $0x0, (%rax)
testq %r14, %r14
je 0xca070
xorl %ebx, %ebx
movl $0x0, %ebp
testq %r15, %r15
jne 0xc9979
leaq 0xb0(%rsp), %r15
movq %r15, %rdi
callq 0xc83da
movl %eax, %ebp
testl %eax, %eax
js 0xca075
movb %bl, (%r14)
movq $0x0, 0x8(%r14)
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x10(%r14)
movl $0xffffffff, 0x20(%r14) # imm = 0xFFFFFFFF
leaq 0xc8(%rsp), %rdi
movb %bl, -0x4(%rdi)
movl $0x800, %edx            # imm = 0x800
xorl %esi, %esi
callq 0x55f20
leaq 0x8d0(%rsp), %rdi
movl %ebx, -0x8(%rdi)
movb %bl, -0x4(%rdi)
movl $0x2800, %edx           # imm = 0x2800
xorl %esi, %esi
callq 0x55f20
leaq 0x30d8(%rsp), %rdi
movl %ebx, -0x8(%rdi)
movb %bl, -0x4(%rdi)
movl $0x2800, %edx           # imm = 0x2800
xorl %esi, %esi
callq 0x55f20
cmpb $0x1, (%r15)
jne 0xc99f4
leaq 0x58d8(%rsp), %rdi
callq 0xcb1ae
movzwl 0x2(%r15), %ecx
testw %cx, %cx
je 0xca088
movl %ebp, 0x10(%rsp)
movb $0x1, %al
movl %eax, 0x8(%rsp)
movl $0x494, %eax            # imm = 0x494
xorl %ebp, %ebp
xorl %r13d, %r13d
movl $0x0, 0xc(%rsp)
xorl %r12d, %r12d
movq %r15, 0x18(%rsp)
movq %rcx, 0x70(%rsp)
movq %rax, 0x38(%rsp)
movl 0xc(%rsp), %ebx
movl $0x2, %edi
leaq 0x4afd1(%rip), %rsi     # 0x114a11
movl %r13d, %edx
xorl %eax, %eax
callq 0xcaa16
imulq $0x580, %rbp, %rcx      # imm = 0x580
movq 0x8(%r15), %rdi
movq %rcx, 0x28(%rsp)
addq %rcx, %rdi
callq 0xca10b
movl %eax, %edx
cmpb $0x1, (%r15)
movl %r13d, 0x14(%rsp)
jne 0xc9bb7
movl %ebx, 0xc(%rsp)
testb $0x1, 0x8(%rsp)
je 0xc9bbb
movl %edx, 0x20(%rsp)
movq 0x8(%r15), %r15
movq 0x28(%rsp), %rax
leaq (%r15,%rax), %r13
pxor %xmm0, %xmm0
movdqa %xmm0, 0x50(%rsp)
movq $0x0, 0x60(%rsp)
pcmpeqd %xmm0, %xmm0
movdqa %xmm0, 0x40(%rsp)
movw %bp, 0x64(%rsp)
movq %r13, %rdi
leaq 0xa0(%rsp), %rsi
callq 0xca57e
cmpl $0x2, %eax
jae 0xc9ffa
cmpl $0xb, (%r13)
jb 0xca00a
cmpw $0x0, 0xb4(%r13)
je 0xca00a
movl 0x480(%r13), %ecx
xorl %eax, %eax
testl %ecx, %ecx
je 0xc9b2a
cmpl $0x0, 0x484(%r13)
je 0xc9b2a
movq 0x38(%rsp), %rax
leaq (%r15,%rax), %rdx
movl %ecx, %edi
xorl %esi, %esi
movl %edi, %eax
movl -0x4(%rdx), %edi
testl %edi, %edi
je 0xc9b27
cmpq $0x2, %rsi
ja 0xc9b27
incq %rsi
cmpl $0x0, (%rdx)
leaq 0x10(%rdx), %rdx
jne 0xc9b0c
andl $0x1f, %eax
testl %ecx, %ecx
je 0xca043
movl 0x48(%rsp), %edx
movl 0x4c(%rsp), %esi
cmpl $0x0, 0x484(%r13)
je 0xca048
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl %eax, %ecx
shll %cl, %r8d
addq 0x38(%rsp), %r15
xorl %r9d, %r9d
movzbl -0xb(%r15), %r11d
movl -0x8(%r15), %edi
cmpl $0x2, %r11d
je 0xc9b87
cmpl $0x1, %r11d
jne 0xc9b91
movb -0x14(%r15), %cl
movl $0xffffffff, %r10d      # imm = 0xFFFFFFFF
shll %cl, %r10d
notl %r10d
movl %edi, %esi
andl %r10d, %esi
jmp 0xc9b91
movl %r8d, %edx
xorl %r10d, %edx
notl %edx
andl %edi, %edx
cmpl $0x0, -0x4(%r15)
je 0xc9bab
cmpq $0x2, %r9
ja 0xc9bab
incq %r9
cmpl $0x0, (%r15)
leaq 0x10(%r15), %r15
jne 0xc9b5b
testb %r11b, %r11b
setne %r13b
jmp 0xca04f
movl %ebx, 0xc(%rsp)
movzbl (%r14), %r13d
testq %r13, %r13
movq %rbp, 0x20(%rsp)
je 0xc9bee
movq 0x8(%r14), %rax
leal -0x1(%r13), %ecx
imulq $0x21e0, %rcx, %rcx     # imm = 0x21E0
cmpl 0x21d8(%rax,%rcx), %edx
jne 0xc9bee
cmpl %ebx, 0xc(%rsp)
jne 0xc9bee
xorl %ebx, %ebx
jmp 0xc9d13
movl %r13d, %ebp
incb %bpl
je 0xc9ce1
movzbl %bpl, %r15d
movl $0x3, %edi
leaq 0x4b947(%rip), %rsi     # 0x115551
movl %r13d, %edx
movl %r15d, %ecx
xorl %eax, %eax
callq 0xcaa16
movq 0x8(%r14), %rdi
imulq $0x21e0, %r15, %rsi     # imm = 0x21E0
callq 0x553d0
testq %rax, %rax
je 0xc9cd1
movq %rax, 0x68(%rsp)
movzbl (%r14), %eax
cmpb %bpl, %al
jae 0xc9cc3
subq %rax, %r15
imulq $0x21e0, %rax, %rbx     # imm = 0x21E0
addq 0x68(%rsp), %rbx
movl $0x21e0, %edx           # imm = 0x21E0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x55f20
movl $0xffffffff, 0x190(%rbx) # imm = 0xFFFFFFFF
leaq 0x1d8(%rbx), %rdi
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0xf8(%rbx)
movdqu %xmm0, 0x108(%rbx)
movdqu %xmm0, 0x118(%rbx)
movdqu %xmm0, 0x128(%rbx)
movdqu %xmm0, 0x138(%rbx)
movq $-0x1, 0x148(%rbx)
callq 0xcb1ae
movl $0x0, 0x21d8(%rbx)
addq $0x21e0, %rbx           # imm = 0x21E0
decq %r15
jne 0xc9c51
movb %bpl, (%r14)
movq 0x68(%rsp), %rax
movq %rax, 0x8(%r14)
jmp 0xc9cdc
movq 0x30(%rsp), %rax
movl $0xfffffffd, (%rax)     # imm = 0xFFFFFFFD
movq 0x18(%rsp), %r15
movq 0x28(%rsp), %rdi
addq 0x8(%r15), %rdi
imulq $0x21e0, %r13, %rsi     # imm = 0x21E0
addq 0x8(%r14), %rsi
leaq 0x78(%rsp), %rdx
callq 0xc94ec
movl 0x10(%rsp), %ecx
testl %ecx, %ecx
cmovel %eax, %ecx
movl %ecx, 0x10(%rsp)
movb $0x1, %bl
movq 0x20(%rsp), %rbp
testq %rbp, %rbp
setne %al
testb %bl, %al
movl 0x14(%rsp), %r13d
jne 0xc9d91
cmpb $0x0, (%r15)
je 0xc9d91
movzwl %bp, %edi
leaq 0x58d8(%rsp), %rsi
callq 0xcb1c4
incl %r12d
testb $0x1, 0x8(%rsp)
je 0xc9d91
leaq 0xc4(%rsp), %rdi
leaq 0x40(%rsp), %rbp
movq %rbp, %rsi
callq 0xca19d
leaq 0x8c8(%rsp), %rdi
movq %rbp, %rsi
movl %r13d, %ebp
leaq 0x78(%rsp), %r13
movq %r13, %rdx
movl $0x1, %ecx
callq 0xca1ee
leaq 0x30d0(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %r13, %rdx
movl %ebp, %r13d
xorl %ecx, %ecx
callq 0xca1ee
cmpb $0x1, (%r15)
jne 0xc9fcc
incl %r13d
movzwl 0x70(%rsp), %eax
cmpl %eax, %r13d
jb 0xc9fbe
movl $0x1, %r15d
testb %bl, %bl
je 0xc9dc1
xorl %r15d, %r15d
cmpb $0x2, (%r14)
setb %r15b
xorl %ecx, %ecx
cmpl %eax, %r13d
setae %cl
cmpl %ecx, %r15d
leaq 0x58d8(%rsp), %rbx
ja 0xc9fcc
cmpl %eax, %r13d
movl $0x1, %eax
sbbl $-0x1, %eax
movl %eax, 0x14(%rsp)
movzwl 0x20(%rsp), %eax
movl %eax, 0x28(%rsp)
movl 0x8(%rsp), %r13d
testl %r15d, %r15d
sete %al
notb %al
addb (%r14), %al
movq 0x8(%r14), %rcx
movzbl %al, %eax
imulq $0x21e0, %rax, %rbp     # imm = 0x21E0
leaq (%rcx,%rbp), %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
movq %rbx, %rsi
callq 0xcb1ba
cmpl $0x1, %r15d
je 0xc9e3d
movq %rbx, %rdi
callq 0xcb1ae
movl 0x28(%rsp), %edi
movq %rbx, %rsi
callq 0xcb1c4
testb $0x1, %r13b
je 0xc9f4e
movzbl 0xc4(%rsp), %eax
movq 0x8(%r14), %rcx
movl %eax, 0xec(%rcx,%rbp)
movzbl 0x8c8(%rsp), %eax
movl %eax, 0x140(%rcx,%rbp)
movzbl 0x8c9(%rsp), %eax
movl %eax, 0x13c(%rcx,%rbp)
movzbl 0x8ca(%rsp), %eax
movl %eax, 0x144(%rcx,%rbp)
movzbl 0x8cb(%rsp), %eax
movl %eax, 0x148(%rcx,%rbp)
movzbl 0x8cc(%rsp), %eax
movl %eax, 0x14c(%rcx,%rbp)
cmpl $0x1, %r15d
je 0xc9f9c
xorl %ebx, %ebx
movb %bl, 0xc4(%rsp)
movl $0x800, %edx            # imm = 0x800
leaq 0xc8(%rsp), %rdi
xorl %esi, %esi
callq 0x55f20
movb %bl, 0x8cc(%rsp)
movl $0x0, 0x8c8(%rsp)
movl $0x2800, %edx           # imm = 0x2800
leaq 0x8d0(%rsp), %rdi
xorl %esi, %esi
callq 0x55f20
leaq 0xc4(%rsp), %rdi
movq %r14, %r13
leaq 0x40(%rsp), %r14
movq %r14, %rsi
callq 0xca19d
leaq 0x8c8(%rsp), %rdi
movq %r14, %rsi
leaq 0x78(%rsp), %rbx
movq %rbx, %rdx
movl $0x1, %ecx
callq 0xca1ee
leaq 0x30d0(%rsp), %rdi
movq %r14, %rsi
movq %r13, %r14
movl 0x8(%rsp), %r13d
movq %rbx, %rdx
leaq 0x58d8(%rsp), %rbx
xorl %ecx, %ecx
callq 0xca1ee
jmp 0xc9f9c
movq 0x8(%r14), %rcx
movl 0xec(%rcx,%rbp), %esi
movsd 0x2a427(%rip), %xmm0    # 0xf4388
testl %esi, %esi
jle 0xc9f85
leaq (%rcx,%rbp), %rax
movl 0xf0(%rax), %eax
cltd
idivl %esi
movsd 0x2a40e(%rip), %xmm0    # 0xf4388
testl %edx, %edx
jne 0xc9f85
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r12d, %xmm1
divsd %xmm0, %xmm1
cvttsd2si %xmm1, %eax
movl %eax, 0xec(%rcx,%rbp)
movq 0x8(%r14), %rax
movl %r12d, 0xf0(%rax,%rbp)
incl %r15d
movl $0x1, %r12d
cmpl %r15d, 0x14(%rsp)
jne 0xc9df7
jmp 0xc9fcc
testb %bl, %bl
je 0xc9fcc
cmpb $0x2, (%r14)
jae 0xc9dac
movq 0x20(%rsp), %rbp
incq %rbp
movl %ebp, %r13d
movq 0x18(%rsp), %r15
movzwl 0x2(%r15), %ecx
movq 0x38(%rsp), %rax
addq $0x580, %rax            # imm = 0x580
cmpq %rcx, %rbp
jb 0xc9a26
jmp 0xca07e
cmpl $-0x1, %eax
jne 0xca00a
movq 0x30(%rsp), %rax
movl $0xfffffff9, (%rax)     # imm = 0xFFFFFFF9
xorl %r13d, %r13d
leaq 0x4b4bc(%rip), %rdi     # 0x1154d0
xorl %eax, %eax
callq 0xca95e
movq 0x18(%rsp), %r15
movl %ebx, 0xc(%rsp)
movl %r13d, 0x8(%rsp)
testb %r13b, %r13b
movl 0x20(%rsp), %edx
je 0xc9bbb
movl 0x44(%rsp), %eax
movl %eax, 0xc(%rsp)
jmp 0xc9bbb
xorl %r13d, %r13d
jmp 0xca05b
movl 0x40(%rsp), %edi
xorl %r13d, %r13d
movl %edi, 0x40(%rsp)
movl %edx, 0x48(%rsp)
movl %esi, 0x4c(%rsp)
movq 0x18(%rsp), %r15
movl 0x40(%rsp), %edx
movl %eax, %ecx
shrl %cl, %edx
shll %cl, %edx
movl %edx, 0x44(%rsp)
jmp 0xca020
movl $0xfffffff4, %ebp       # imm = 0xFFFFFFF4
movq 0x30(%rsp), %rax
movl %ebp, (%rax)
jmp 0xca0f7
movl 0x10(%rsp), %ebp
movl 0x8(%rsp), %eax
jmp 0xca08d
xorl %r13d, %r13d
movb $0x1, %al
testb $0x1, %al
je 0xca0cd
movzbl 0x30d0(%rsp), %eax
movl %eax, 0x14(%r14)
movzbl 0x30d1(%rsp), %eax
movl %eax, 0x10(%r14)
movzbl 0x30d2(%rsp), %eax
movl %eax, 0x18(%r14)
movzbl 0x30d3(%rsp), %eax
movl %eax, 0x1c(%r14)
movzbl 0x30d4(%rsp), %eax
movl %eax, 0x20(%r14)
movzbl (%r14), %ecx
testq %rcx, %rcx
je 0xca0f7
movq 0x8(%r14), %rax
imulq $0x21e0, %rcx, %rcx     # imm = 0x21E0
xorl %edx, %edx
movl %r13d, 0xf4(%rax,%rdx)
addq $0x21e0, %rdx           # imm = 0x21E0
cmpq %rdx, %rcx
jne 0xca0e3
movl %ebp, %eax
addq $0x78d8, %rsp           # imm = 0x78D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq