// File: /workspace/github_c_makefile_star2_O0/ebiggers[P]xpack/lib/x86_cpu_features.c
// Function: x86_setup_cpu_features
void
x86_setup_cpu_features(void)
{
	u32 features = 0;
	u32 dummy1, dummy2, dummy3, dummy4;
	u32 max_function;
	u32 features_1, features_2, features_3, features_4;
	bool os_saves_ymm_regs = false;

	/* Get maximum supported function */
	cpuid(0, 0, &max_function, &dummy2, &dummy3, &dummy4);
	if (max_function < 1)
		goto out;

	/* Standard feature flags */
	cpuid(1, 0, &dummy1, &dummy2, &features_2, &features_1);

	if (IS_SET(features_1, 25))
		features |= X86_CPU_FEATURE_SSE;

	if (IS_SET(features_1, 26))
		features |= X86_CPU_FEATURE_SSE2;

	if (IS_SET(features_2, 0))
		features |= X86_CPU_FEATURE_SSE3;

	if (IS_SET(features_2, 9))
		features |= X86_CPU_FEATURE_SSSE3;

	if (IS_SET(features_2, 19))
		features |= X86_CPU_FEATURE_SSE4_1;

	if (IS_SET(features_2, 20))
		features |= X86_CPU_FEATURE_SSE4_2;

	if (IS_SET(features_2, 27)) /* OSXSAVE set? */
		if ((read_xcr(0) & 0x6) == 0x6)
			os_saves_ymm_regs = true;

	if (os_saves_ymm_regs && IS_SET(features_2, 28))
		features |= X86_CPU_FEATURE_AVX;

	if (max_function < 7)
		goto out;

	/* Extended feature flags */
	cpuid(7, 0, &dummy1, &features_3, &features_4, &dummy4);

	if (IS_SET(features_3, 3))
		features |= X86_CPU_FEATURE_BMI;

	if (os_saves_ymm_regs && IS_SET(features_3, 5))
		features |= X86_CPU_FEATURE_AVX2;

	if (IS_SET(features_3, 8))
		features |= X86_CPU_FEATURE_BMI2;

out:

#if DEBUG
	printf("Detected x86 CPU features: ");
	if (features & X86_CPU_FEATURE_SSE)
		printf("SSE ");
	if (features & X86_CPU_FEATURE_SSE2)
		printf("SSE2 ");
	if (features & X86_CPU_FEATURE_SSE3)
		printf("SSE3 ");
	if (features & X86_CPU_FEATURE_SSSE3)
		printf("SSSE3 ");
	if (features & X86_CPU_FEATURE_SSE4_1)
		printf("SSE4.1 ");
	if (features & X86_CPU_FEATURE_SSE4_2)
		printf("SSE4.2 ");
	if (features & X86_CPU_FEATURE_BMI)
		printf("BMI ");
	if (features & X86_CPU_FEATURE_AVX)
		printf("AVX ");
	if (features & X86_CPU_FEATURE_BMI2)
		printf("BMI2 ");
	if (features & X86_CPU_FEATURE_AVX2)
		printf("AVX2 ");
	printf("\n");
#endif /* DEBUG */

	_x86_cpu_features = features | X86_CPU_FEATURES_KNOWN;
}

// Assembly:
subq $0x38, %rsp
movl $0x0, 0x34(%rsp)
movb $0x0, 0xf(%rsp)
xorl %esi, %esi
leaq 0x20(%rsp), %rdx
leaq 0x2c(%rsp), %rcx
leaq 0x28(%rsp), %r8
leaq 0x24(%rsp), %r9
movl %esi, %edi
callq 0x1320
cmpl $0x1, 0x20(%rsp)
jae 0x118a
jmp 0x1303
movl $0x1, %edi
xorl %esi, %esi
leaq 0x30(%rsp), %rdx
leaq 0x2c(%rsp), %rcx
leaq 0x18(%rsp), %r8
leaq 0x1c(%rsp), %r9
callq 0x1320
movl 0x1c(%rsp), %eax
andl $0x2000000, %eax        # imm = 0x2000000
cmpl $0x0, %eax
je 0x11c3
movl 0x34(%rsp), %eax
orl $0x1, %eax
movl %eax, 0x34(%rsp)
movl 0x1c(%rsp), %eax
andl $0x4000000, %eax        # imm = 0x4000000
cmpl $0x0, %eax
je 0x11dc
movl 0x34(%rsp), %eax
orl $0x2, %eax
movl %eax, 0x34(%rsp)
movl 0x18(%rsp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x11f3
movl 0x34(%rsp), %eax
orl $0x4, %eax
movl %eax, 0x34(%rsp)
movl 0x18(%rsp), %eax
andl $0x200, %eax            # imm = 0x200
cmpl $0x0, %eax
je 0x120c
movl 0x34(%rsp), %eax
orl $0x8, %eax
movl %eax, 0x34(%rsp)
movl 0x18(%rsp), %eax
andl $0x80000, %eax          # imm = 0x80000
cmpl $0x0, %eax
je 0x1225
movl 0x34(%rsp), %eax
orl $0x10, %eax
movl %eax, 0x34(%rsp)
movl 0x18(%rsp), %eax
andl $0x100000, %eax         # imm = 0x100000
cmpl $0x0, %eax
je 0x123e
movl 0x34(%rsp), %eax
orl $0x20, %eax
movl %eax, 0x34(%rsp)
movl 0x18(%rsp), %eax
andl $0x8000000, %eax        # imm = 0x8000000
cmpl $0x0, %eax
je 0x1264
xorl %edi, %edi
callq 0x1380
andq $0x6, %rax
cmpq $0x6, %rax
jne 0x1262
movb $0x1, 0xf(%rsp)
jmp 0x1264
testb $0x1, 0xf(%rsp)
je 0x1284
movl 0x18(%rsp), %eax
andl $0x10000000, %eax       # imm = 0x10000000
cmpl $0x0, %eax
je 0x1284
movl 0x34(%rsp), %eax
orl $0x40, %eax
movl %eax, 0x34(%rsp)
cmpl $0x7, 0x20(%rsp)
jae 0x128d
jmp 0x1303
movl $0x7, %edi
xorl %esi, %esi
leaq 0x30(%rsp), %rdx
leaq 0x14(%rsp), %rcx
leaq 0x10(%rsp), %r8
leaq 0x24(%rsp), %r9
callq 0x1320
movl 0x14(%rsp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x12c6
movl 0x34(%rsp), %eax
orl $0x80, %eax
movl %eax, 0x34(%rsp)
testb $0x1, 0xf(%rsp)
je 0x12e6
movl 0x14(%rsp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x12e6
movl 0x34(%rsp), %eax
orl $0x100, %eax            # imm = 0x100
movl %eax, 0x34(%rsp)
movl 0x14(%rsp), %eax
andl $0x100, %eax            # imm = 0x100
cmpl $0x0, %eax
je 0x1301
movl 0x34(%rsp), %eax
orl $0x200, %eax            # imm = 0x200
movl %eax, 0x34(%rsp)
jmp 0x1303
movl 0x34(%rsp), %eax
orl $0x80000000, %eax       # imm = 0x80000000
movl %eax, 0xed3a(%rip)      # 0x1004c
addq $0x38, %rsp
retq
nopw (%rax,%rax)