// File: /workspace/github_cpp_makefile_star2_O3/rpavlik[P]edid-decode/parse-base-block.cpp
// Function: edid_state::detailed_cvt_descriptor(char const*, unsigned char const*, bool)
void edid_state::detailed_cvt_descriptor(const char *prefix, const unsigned char *x, bool first)
{
	static const unsigned char empty[3] = { 0, 0, 0 };
	struct timings cvt_t = {};
	unsigned char preferred;

	if (!first && !memcmp(x, empty, 3))
		return;

	cvt_t.vact = x[0];
	if (!cvt_t.vact)
		fail("CVT byte 0 is 0, which is a reserved value.\n");
	cvt_t.vact |= (x[1] & 0xf0) << 4;
	cvt_t.vact++;
	cvt_t.vact *= 2;

	switch (x[1] & 0x0c) {
	case 0x00:
	default: /* avoids 'width/ratio may be used uninitialized' warnings */
		cvt_t.hratio = 4;
		cvt_t.vratio = 3;
		break;
	case 0x04:
		cvt_t.hratio = 16;
		cvt_t.vratio = 9;
		break;
	case 0x08:
		cvt_t.hratio = 16;
		cvt_t.vratio = 10;
		break;
	case 0x0c:
		cvt_t.hratio = 15;
		cvt_t.vratio = 9;
		break;
	}
	cvt_t.hact = 8 * (((cvt_t.vact * cvt_t.hratio) / cvt_t.vratio) / 8);

	if (x[1] & 0x03)
		fail("Reserved bits of CVT byte 1 are non-zero.\n");
	if (x[2] & 0x80)
		fail("Reserved bit of CVT byte 2 is non-zero.\n");
	if (!(x[2] & 0x1f))
		fail("CVT byte 2 does not support any vertical rates.\n");
	preferred = (x[2] & 0x60) >> 5;
	if (preferred == 1 && (x[2] & 0x01))
		preferred = 4;
	if (!(x[2] & (1 << (4 - preferred))))
		fail("The preferred CVT Vertical Rate is not supported.\n");

	static const char *s_pref = "preferred vertical rate";

	if (x[2] & 0x10) {
		edid_cvt_mode(50, cvt_t);
		print_timings(prefix, &cvt_t, "CVT", preferred == 0 ? s_pref : "");
	}
	if (x[2] & 0x08) {
		edid_cvt_mode(60, cvt_t);
		print_timings(prefix, &cvt_t, "CVT", preferred == 1 ? s_pref : "");
	}
	if (x[2] & 0x04) {
		edid_cvt_mode(75, cvt_t);
		print_timings(prefix, &cvt_t, "CVT", preferred == 2 ? s_pref : "");
	}
	if (x[2] & 0x02) {
		edid_cvt_mode(85, cvt_t);
		print_timings(prefix, &cvt_t, "CVT", preferred == 3 ? s_pref : "");
	}
	if (x[2] & 0x01) {
		cvt_t.rb = RB_CVT_V1;
		edid_cvt_mode(60, cvt_t);
		print_timings(prefix, &cvt_t, "CVT", preferred == 4 ? s_pref : "");
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movl $0x0, 0x60(%rsp)
testl %ecx, %ecx
jne 0x9c32
movzbl 0x2(%r15), %eax
orw (%r15), %ax
je 0x9ebb
movzbl (%r15), %r12d
testl %r12d, %r12d
jne 0x9c4b
leaq 0x1ab05(%rip), %rsi     # 0x24747
xorl %edi, %edi
xorl %eax, %eax
callq 0x37cc
movzbl 0x1(%r15), %ecx
movl %ecx, %eax
andl $-0x10, %eax
shll $0x5, %eax
leal (%rax,%r12,2), %edx
addl $0x2, %edx
movl %edx, 0x14(%rsp)
leaq 0x1aa96(%rip), %rax     # 0x24700
movl %ecx, %esi
andl $0xc, %esi
movl (%rsi,%rax), %eax
leaq 0x1aa97(%rip), %rdi     # 0x24710
movl (%rsi,%rdi), %esi
movl %eax, 0x18(%rsp)
movl %esi, 0x1c(%rsp)
imull %edx, %eax
xorl %edx, %edx
divl %esi
andl $0x7ffffff8, %eax       # imm = 0x7FFFFFF8
movl %eax, 0x10(%rsp)
testb $0x3, %cl
je 0x9ca9
leaq 0x1aad4(%rip), %rsi     # 0x24774
xorl %edi, %edi
xorl %eax, %eax
callq 0x37cc
movb 0x2(%r15), %al
testb %al, %al
jns 0x9cc5
leaq 0x1aae7(%rip), %rsi     # 0x2479f
xorl %edi, %edi
xorl %eax, %eax
callq 0x37cc
movb 0x2(%r15), %al
testb $0x1f, %al
jne 0x9cdd
leaq 0x1aaf8(%rip), %rsi     # 0x247c8
xorl %edi, %edi
xorl %eax, %eax
callq 0x37cc
movb 0x2(%r15), %al
movl %eax, %ecx
shrb $0x5, %cl
andb $0x3, %cl
cmpb $0x1, %cl
sete %bpl
andb %al, %bpl
movzbl %cl, %ecx
movl $0x4, %r13d
cmovel %ecx, %r13d
movzbl %al, %ecx
movb $0x4, %dl
subb %r13b, %dl
movzbl %dl, %edx
btl %edx, %ecx
jb 0x9d20
leaq 0x1aae6(%rip), %rsi     # 0x247f9
xorl %edi, %edi
xorl %eax, %eax
callq 0x37cc
movb 0x2(%r15), %al
testb $0x10, %al
je 0x9d71
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movl $0x32, %esi
movq %r12, %rdx
callq 0x1f964
testb %r13b, %r13b
leaq 0x1aae9(%rip), %rax     # 0x2482c
leaq 0x16f3f(%rip), %r8      # 0x20c89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x27072(%rip), %rcx     # 0x30dce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3e8c
movb 0x2(%r15), %al
testb $0x8, %al
je 0x9dc3
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movl $0x3c, %esi
movq %r12, %rdx
callq 0x1f964
cmpb $0x1, %r13b
leaq 0x1aa97(%rip), %rax     # 0x2482c
leaq 0x16eed(%rip), %r8      # 0x20c89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x27020(%rip), %rcx     # 0x30dce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3e8c
movb 0x2(%r15), %al
testb $0x4, %al
je 0x9e15
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movl $0x4b, %esi
movq %r12, %rdx
callq 0x1f964
cmpb $0x2, %r13b
leaq 0x1aa45(%rip), %rax     # 0x2482c
leaq 0x16e9b(%rip), %r8      # 0x20c89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x26fce(%rip), %rcx     # 0x30dce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3e8c
movb 0x2(%r15), %al
testb $0x2, %al
je 0x9e67
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movl $0x55, %esi
movq %r12, %rdx
callq 0x1f964
cmpb $0x3, %r13b
leaq 0x1a9f3(%rip), %rax     # 0x2482c
leaq 0x16e49(%rip), %r8      # 0x20c89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x26f7c(%rip), %rcx     # 0x30dce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3e8c
movb 0x2(%r15), %al
testb $0x1, %al
je 0x9ebb
movl $0x1, %r12d
leaq 0x10(%rsp), %r15
movl %r12d, 0x14(%r15)
movq %r14, %rdi
movl $0x3c, %esi
movq %r15, %rdx
callq 0x1f964
leaq 0x1a99b(%rip), %rax     # 0x2482c
leaq 0x16df1(%rip), %r8      # 0x20c89
testb %bpl, %bpl
cmovneq %rax, %r8
movl %r12d, (%rsp)
leaq 0x26f24(%rip), %rcx     # 0x30dce
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
xorl %r9d, %r9d
callq 0x3e8c
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq