// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x78e0, %rsp           # imm = 0x78E0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
xorl %edi, %edi
callq 0x131660
movl %eax, -0x1c(%rbp)
xorl %edi, %edi
callq 0x131660
movl %eax, -0x20(%rbp)
movb $0x1, -0x2c(%rbp)
movb $0x0, -0x2d(%rbp)
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movw $0x0, -0x3e(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x1338e3
movl $0xfffffff4, %edi       # imm = 0xFFFFFFF4
callq 0x131660
movl %eax, -0x4(%rbp)
jmp 0x133fe0
cmpq $0x0, -0x10(%rbp)
jne 0x133919
leaq -0x2058(%rbp), %rdi
callq 0x131ab0
movl %eax, -0x20(%rbp)
cmpl $0x0, %eax
jge 0x13390e
movl -0x20(%rbp), %edi
callq 0x131660
movl %eax, -0x4(%rbp)
jmp 0x133fe0
leaq -0x2058(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x18(%rbp), %rdi
callq 0x133ff0
leaq -0x28ac(%rbp), %rdi
callq 0x134050
leaq -0x50b4(%rbp), %rdi
callq 0x134080
leaq -0x78bc(%rbp), %rdi
callq 0x134080
movq -0x10(%rbp), %rax
testb $0x1, (%rax)
je 0x13395b
leaq -0x2044(%rbp), %rdi
callq 0x136260
movw $0x0, -0x3e(%rbp)
movzwl -0x3e(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
cmpl %ecx, %eax
jge 0x133f51
movb $0x0, -0x29(%rbp)
movzwl -0x3e(%rbp), %eax
addl $0x1, %eax
movq -0x10(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
cmpl %ecx, %eax
setge %al
andb $0x1, %al
movb %al, -0x2a(%rbp)
movzwl -0x3e(%rbp), %edx
movl $0x2, %edi
leaq 0x739ab(%rip), %rsi     # 0x1a734d
movb $0x0, %al
callq 0x135780
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movzwl -0x3e(%rbp), %eax
imulq $0x580, %rax, %rax      # imm = 0x580
addq %rax, %rdi
callq 0x1340c0
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rax
testb $0x1, (%rax)
je 0x133a15
testb $0x1, -0x2c(%rbp)
je 0x133a15
movw -0x3e(%rbp), %ax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rsi
movzwl -0x3e(%rbp), %ecx
imulq $0x580, %rcx, %rcx      # imm = 0x580
addq %rcx, %rsi
leaq -0x20a8(%rbp), %rdx
movzwl %ax, %edi
callq 0x134170
andb $0x1, %al
movb %al, -0x2c(%rbp)
testb $0x1, -0x2c(%rbp)
je 0x133a13
movl -0x20a4(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0x133a15
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0x133a53
movl -0x44(%rbp), %eax
movq -0x18(%rbp), %rcx
movq 0x8(%rcx), %rcx
movq -0x18(%rbp), %rdx
movzbl (%rdx), %edx
subl $0x1, %edx
movslq %edx, %rdx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rcx
cmpl 0x21d8(%rcx), %eax
jne 0x133a53
movl -0x38(%rbp), %eax
cmpl -0x3c(%rbp), %eax
je 0x133abf
movb $0x1, -0x29(%rbp)
movq -0x18(%rbp), %rax
movb (%rax), %al
movb %al, -0x2d(%rbp)
movq -0x18(%rbp), %rdi
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
addl $0x1, %eax
movzbl %al, %esi
callq 0x134410
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movzwl -0x3e(%rbp), %eax
imulq $0x580, %rax, %rax      # imm = 0x580
addq %rax, %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movzbl -0x2d(%rbp), %eax
imulq $0x21e0, %rax, %rax     # imm = 0x21E0
addq %rax, %rsi
leaq -0x2080(%rbp), %rdx
callq 0x133340
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x133abd
movl -0x1c(%rbp), %eax
movl %eax, -0x20(%rbp)
jmp 0x133abf
movq -0x10(%rbp), %rax
testb $0x1, (%rax)
je 0x133b46
movzwl -0x3e(%rbp), %eax
cmpl $0x0, %eax
je 0x133ad7
testb $0x1, -0x29(%rbp)
jne 0x133b46
leaq -0x2044(%rbp), %rsi
movzwl -0x3e(%rbp), %edi
callq 0x1362c0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
testb $0x1, -0x2c(%rbp)
je 0x133b44
leaq -0x28ac(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
callq 0x1344f0
leaq -0x50b4(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
leaq -0x2080(%rbp), %rdx
movl $0x1, %ecx
callq 0x1345b0
leaq -0x78bc(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
leaq -0x2080(%rbp), %rdx
xorl %ecx, %ecx
callq 0x1345b0
jmp 0x133b46
movq -0x10(%rbp), %rax
testb $0x1, (%rax)
je 0x133f3a
testb $0x1, -0x2a(%rbp)
jne 0x133b73
testb $0x1, -0x29(%rbp)
je 0x133f3a
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jle 0x133f3a
xorl %eax, %eax
testb $0x1, -0x29(%rbp)
movb %al, -0x78c9(%rbp)
je 0x133b94
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
setg %al
movb %al, -0x78c9(%rbp)
movb -0x78c9(%rbp), %dl
movl $0x1, %eax
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x78c0(%rbp)
movb -0x2a(%rbp), %dl
xorl %eax, %eax
movl $0x1, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, -0x78c4(%rbp)
movl -0x78c0(%rbp), %eax
movl %eax, -0x78c8(%rbp)
movl -0x78c8(%rbp), %eax
cmpl -0x78c4(%rbp), %eax
ja 0x133f38
movl -0x78c8(%rbp), %eax
movl %eax, -0x78d0(%rbp)
testl %eax, %eax
je 0x133c00
jmp 0x133bf3
movl -0x78d0(%rbp), %eax
subl $0x1, %eax
je 0x133c0f
jmp 0x133c1e
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
subl $0x2, %eax
movb %al, -0x2d(%rbp)
jmp 0x133c44
movq -0x18(%rbp), %rax
movzbl (%rax), %eax
subl $0x1, %eax
movb %al, -0x2d(%rbp)
jmp 0x133c44
movl -0x78c8(%rbp), %esi
leaq 0x7373f(%rip), %rdi     # 0x1a736a
movb $0x0, %al
callq 0x1356a0
movl $0xfffffffa, %edi       # imm = 0xFFFFFFFA
callq 0x131660
movl %eax, -0x4(%rbp)
jmp 0x133fe0
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movzbl -0x2d(%rbp), %eax
imulq $0x21e0, %rax, %rax     # imm = 0x21E0
addq %rax, %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
leaq -0x2044(%rbp), %rsi
callq 0x136290
cmpl $0x1, -0x78c8(%rbp)
je 0x133c92
leaq -0x2044(%rbp), %rdi
callq 0x136260
leaq -0x2044(%rbp), %rsi
movzwl -0x3e(%rbp), %edi
callq 0x1362c0
testb $0x1, -0x2c(%rbp)
je 0x133de2
movzbl -0x28ac(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0xec(%rax)
movzbl -0x50b4(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0x140(%rax)
movzbl -0x50b3(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0x13c(%rax)
movzbl -0x50b2(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0x144(%rax)
movzbl -0x50b1(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0x148(%rax)
movzbl -0x50b0(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0x14c(%rax)
cmpl $0x1, -0x78c8(%rbp)
je 0x133ddd
leaq -0x28ac(%rbp), %rdi
callq 0x134050
leaq -0x50b4(%rbp), %rdi
callq 0x134080
leaq -0x28ac(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
callq 0x1344f0
leaq -0x50b4(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
leaq -0x2080(%rbp), %rdx
movl $0x1, %ecx
callq 0x1345b0
leaq -0x78bc(%rbp), %rdi
leaq -0x20a8(%rbp), %rsi
leaq -0x2080(%rbp), %rdx
xorl %ecx, %ecx
callq 0x1345b0
jmp 0x133efe
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %ecx
imulq $0x21e0, %rcx, %rcx     # imm = 0x21E0
addq %rcx, %rax
cmpl $0x0, 0xec(%rax)
jle 0x133e4d
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %ecx
imulq $0x21e0, %rcx, %rcx     # imm = 0x21E0
addq %rcx, %rax
movl 0xf0(%rax), %eax
movq -0x18(%rbp), %rcx
movq 0x8(%rcx), %rcx
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rcx
cltd
idivl 0xec(%rcx)
cmpl $0x0, %edx
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x78d4(%rbp)
jmp 0x133e57
xorl %eax, %eax
movl %eax, -0x78d4(%rbp)
jmp 0x133e57
movl -0x78d4(%rbp), %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x2b(%rbp)
testb $0x1, -0x2b(%rbp)
je 0x133eb5
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %ecx
imulq $0x21e0, %rcx, %rcx     # imm = 0x21E0
addq %rcx, %rax
movl 0xf0(%rax), %eax
movq -0x18(%rbp), %rcx
movq 0x8(%rcx), %rcx
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rcx
cltd
idivl 0xec(%rcx)
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x78e0(%rbp)
jmp 0x133ec7
movsd 0x534ab(%rip), %xmm0    # 0x187368
movsd %xmm0, -0x78e0(%rbp)
jmp 0x133ec7
movsd -0x78e0(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
cvtsi2sdl -0x34(%rbp), %xmm0
divsd -0x28(%rbp), %xmm0
cvttsd2si %xmm0, %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0xec(%rax)
movl -0x34(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0xf0(%rax)
movl $0x1, -0x34(%rbp)
movl -0x78c8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78c8(%rbp)
jmp 0x133bcf
jmp 0x133f3a
movl -0x38(%rbp), %eax
movl %eax, -0x3c(%rbp)
movw -0x3e(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x3e(%rbp)
jmp 0x133961
testb $0x1, -0x2c(%rbp)
je 0x133f9d
movzbl -0x78bc(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x14(%rax)
movzbl -0x78bb(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x10(%rax)
movzbl -0x78ba(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x18(%rax)
movzbl -0x78b9(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x1c(%rax)
movzbl -0x78b8(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x20(%rax)
movb $0x0, -0x2d(%rbp)
movzbl -0x2d(%rbp), %eax
movq -0x18(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x133fda
movzwl -0x3e(%rbp), %ecx
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movzbl -0x2d(%rbp), %edx
imulq $0x21e0, %rdx, %rdx     # imm = 0x21E0
addq %rdx, %rax
movl %ecx, 0xf4(%rax)
movb -0x2d(%rbp), %al
addb $0x1, %al
movb %al, -0x2d(%rbp)
jmp 0x133fa1
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x78e0, %rsp           # imm = 0x78E0
popq %rbp
retq
nopl (%rax)