// File: /workspace/github_cpp_makefile_star2_O2/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)
andl $0x0, 0x60(%rsp)
testl %ecx, %ecx
jne 0x842a
leaq 0x16285(%rip), %rsi     # 0x1e69c
pushq $0x3
popq %rdx
movq %r15, %rdi
callq 0x3290
testl %eax, %eax
je 0x86a5
movzbl (%r15), %r12d
testl %r12d, %r12d
jne 0x8443
leaq 0x1630d(%rip), %rsi     # 0x1e747
xorl %edi, %edi
xorl %eax, %eax
callq 0x362c
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 0x1629e(%rip), %rax     # 0x1e700
movl %ecx, %esi
andl $0xc, %esi
movl (%rsi,%rax), %eax
leaq 0x1629f(%rip), %rdi     # 0x1e710
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 0x84a1
leaq 0x162dc(%rip), %rsi     # 0x1e774
xorl %edi, %edi
xorl %eax, %eax
callq 0x362c
movb 0x2(%r15), %al
testb %al, %al
jns 0x84bd
leaq 0x162ef(%rip), %rsi     # 0x1e79f
xorl %edi, %edi
xorl %eax, %eax
callq 0x362c
movb 0x2(%r15), %al
testb $0x1f, %al
jne 0x84d5
leaq 0x16300(%rip), %rsi     # 0x1e7c8
xorl %edi, %edi
xorl %eax, %eax
callq 0x362c
movb 0x2(%r15), %al
movl %eax, %ecx
shrb $0x5, %cl
andb $0x3, %cl
cmpb $0x1, %cl
sete %bpl
andb %al, %bpl
movzbl %cl, %ecx
pushq $0x4
popq %r13
cmovel %ecx, %r13d
movzbl %al, %ecx
movb $0x4, %dl
subb %r13b, %dl
movzbl %dl, %edx
btl %edx, %ecx
jb 0x8516
leaq 0x162f0(%rip), %rsi     # 0x1e7f9
xorl %edi, %edi
xorl %eax, %eax
callq 0x362c
movb 0x2(%r15), %al
testb $0x10, %al
je 0x8565
pushq $0x32
popq %rsi
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movq %r12, %rdx
callq 0x19e2a
testb %r13b, %r13b
leaq 0x162f5(%rip), %rax     # 0x1e82c
leaq 0x1274b(%rip), %r8      # 0x1ac89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x2287e(%rip), %rcx     # 0x2adce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3af0
movb 0x2(%r15), %al
testb $0x8, %al
je 0x85b5
pushq $0x3c
popq %rsi
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movq %r12, %rdx
callq 0x19e2a
cmpb $0x1, %r13b
leaq 0x162a5(%rip), %rax     # 0x1e82c
leaq 0x126fb(%rip), %r8      # 0x1ac89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x2282e(%rip), %rcx     # 0x2adce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3af0
movb 0x2(%r15), %al
testb $0x4, %al
je 0x8605
pushq $0x4b
popq %rsi
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movq %r12, %rdx
callq 0x19e2a
cmpb $0x2, %r13b
leaq 0x16255(%rip), %rax     # 0x1e82c
leaq 0x126ab(%rip), %r8      # 0x1ac89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x227de(%rip), %rcx     # 0x2adce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3af0
movb 0x2(%r15), %al
testb $0x2, %al
je 0x8655
pushq $0x55
popq %rsi
leaq 0x10(%rsp), %r12
movq %r14, %rdi
movq %r12, %rdx
callq 0x19e2a
cmpb $0x3, %r13b
leaq 0x16205(%rip), %rax     # 0x1e82c
leaq 0x1265b(%rip), %r8      # 0x1ac89
cmoveq %rax, %r8
movl $0x1, (%rsp)
leaq 0x2278e(%rip), %rcx     # 0x2adce
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
xorl %r9d, %r9d
callq 0x3af0
movb 0x2(%r15), %al
testb $0x1, %al
je 0x86a5
pushq $0x1
popq %r12
leaq 0x10(%rsp), %r15
movl %r12d, 0x14(%r15)
pushq $0x3c
popq %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x19e2a
leaq 0x161b1(%rip), %rax     # 0x1e82c
leaq 0x12607(%rip), %r8      # 0x1ac89
testb %bpl, %bpl
cmovneq %rax, %r8
movl %r12d, (%rsp)
leaq 0x2273a(%rip), %rcx     # 0x2adce
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
xorl %r9d, %r9d
callq 0x3af0
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq