// File: /workspace/github_cpp_makefile_star2_O2/rpavlik[P]edid-decode/calc-gtf-cvt.cpp
// Function: edid_state::calc_cvt_mode(unsigned int, unsigned int, double, unsigned int, bool, bool, bool)
timings edid_state::calc_cvt_mode(unsigned h_pixels, unsigned v_lines,
				  double ip_freq_rqd, unsigned rb, bool int_rqd,
				  bool margins_rqd, bool alt)
{
	timings t = {};

	t.hact = h_pixels;
	t.vact = v_lines;
	t.interlaced = int_rqd;

	double cell_gran = rb == RB_CVT_V2 ? 1 : CELL_GRAN;
	double h_pixels_rnd = floor(h_pixels / cell_gran) * cell_gran;
	double v_lines_rnd = int_rqd ? floor(v_lines / 2.0) : v_lines;
	unsigned hor_margin = margins_rqd ?
		floor((h_pixels_rnd * MARGIN_PERC / 100.0) / cell_gran) * cell_gran : 0;
	unsigned vert_margin = margins_rqd ? floor(MARGIN_PERC / 100.0 * v_lines_rnd) : 0;
	double interlace = int_rqd ? 0.5 : 0;
	double total_active_pixels = h_pixels_rnd + hor_margin * 2;
	double v_field_rate_rqd = int_rqd ? ip_freq_rqd * 2 : ip_freq_rqd;
	double clock_step = rb == RB_CVT_V2 ? 0.001 : 0.25;
	double h_blank = (rb == RB_CVT_V1 || (rb == RB_CVT_V3 && alt)) ? 160 : 80;
	double rb_v_fporch = rb == RB_CVT_V1 ? 3 : 1;
	double refresh_multiplier = (rb == RB_CVT_V2 && alt) ? 1000.0 / 1001.0 : 1;
	double h_sync = 32;

	double v_sync;
	double pixel_freq;
	double v_blank;
	double v_sync_bp;

	/* Determine VSync Width from aspect ratio */
	if ((t.vact * 4 / 3) == t.hact)
		v_sync = 4;
	else if ((t.vact * 16 / 9) == t.hact)
		v_sync = 5;
	else if ((t.vact * 16 / 10) == t.hact)
		v_sync = 6;
	else if (!(t.vact % 4) && ((t.vact * 5 / 4) == t.hact))
		v_sync = 7;
	else if ((t.vact * 15 / 9) == t.hact)
		v_sync = 7;
	else                        /* Custom */
		v_sync = 10;

	if (rb >= RB_CVT_V2)
		v_sync = 8;

	if (rb == RB_NONE) {
		double h_period_est = ((1.0 / v_field_rate_rqd) - CVT_MIN_VSYNC_BP / 1000000.0) /
			(v_lines_rnd + vert_margin * 2 + CVT_MIN_V_PORCH + interlace) * 1000000.0;
		v_sync_bp = floor(CVT_MIN_VSYNC_BP / h_period_est) + 1;
		if (v_sync_bp < v_sync + CVT_MIN_V_BPORCH)
			v_sync_bp = v_sync + CVT_MIN_V_BPORCH;
		v_blank = v_sync_bp + CVT_MIN_V_PORCH;
		double ideal_duty_cycle = CVT_C_PRIME - (CVT_M_PRIME * h_period_est / 1000.0);
		if (ideal_duty_cycle < 20)
			ideal_duty_cycle = 20;
		h_blank = floor(total_active_pixels * ideal_duty_cycle /
				(100.0 - ideal_duty_cycle) /
				(2 * CELL_GRAN)) * 2 * CELL_GRAN;
		double total_pixels = total_active_pixels + h_blank;
		h_sync = floor(total_pixels * 0.08 / CELL_GRAN) * CELL_GRAN;
		pixel_freq = floor((total_pixels / h_period_est) / clock_step) * clock_step;
	} else {
		double h_period_est = ((1000000.0 / v_field_rate_rqd) - CVT_RB_MIN_VBLANK) /
					(v_lines_rnd + vert_margin * 2);
		double vbi_lines = floor(CVT_RB_MIN_VBLANK / h_period_est) + 1;
		double rb_min_vbi = rb_v_fporch + v_sync + CVT_MIN_V_BPORCH;
		v_blank = vbi_lines < rb_min_vbi ? rb_min_vbi : vbi_lines;
		double total_v_lines = v_blank + v_lines_rnd + vert_margin * 2 + interlace;
		if (rb == RB_CVT_V1)
			v_sync_bp = v_blank - rb_v_fporch;
		else
			v_sync_bp = v_sync + CVT_MIN_V_BPORCH;
		double total_pixels = h_blank + total_active_pixels;
		pixel_freq = floor((v_field_rate_rqd * total_v_lines * total_pixels / 1000000.0 *
				    refresh_multiplier) / clock_step) * clock_step;
	}

	t.vbp = v_sync_bp - v_sync;
	t.vsync = v_sync;
	t.vfp = v_blank - t.vbp - t.vsync;
	t.pixclk_khz = round(1000.0 * pixel_freq);
	t.hsync = h_sync;
	t.hfp = (h_blank / 2.0) - t.hsync;
	t.hbp = t.hfp + t.hsync;
	t.hborder = hor_margin;
	t.vborder = vert_margin;
	t.rb = rb;
	if (alt && (rb == RB_CVT_V2 || rb == RB_CVT_V3))
		t.rb |= RB_ALT;
	t.pos_pol_hsync = t.rb;
	t.pos_pol_vsync = !t.rb;
	calc_ratio(&t);
	return t;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r9d, %r12d
movl %r8d, %ebp
movsd %xmm0, 0x18(%rsp)
movl %ecx, %r15d
movl %edx, %r14d
movq %rdi, %rbx
xorl %eax, %eax
cmpl $0x2, %r8d
sete %al
movb 0xa0(%rsp), %r13b
xorps %xmm0, %xmm0
movups %xmm0, 0x18(%rdi)
movups %xmm0, 0x44(%rdi)
movups %xmm0, 0x38(%rdi)
movups %xmm0, 0x28(%rdi)
movups %xmm0, 0x8(%rdi)
movl %edx, (%rdi)
movl %ecx, 0x4(%rdi)
movb %r12b, 0x18(%rdi)
leaq 0x13bd9(%rip), %rcx     # 0x2d480
movsd (%rcx,%rax,8), %xmm1
movl %edx, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm1, 0x10(%rsp)
divsd %xmm1, %xmm0
callq 0x3420
movapd %xmm0, %xmm1
movl %r15d, %eax
cvtsi2sd %rax, %xmm4
testl %r12d, %r12d
je 0x198f4
mulsd 0x735(%rip), %xmm4      # 0x1a010
movapd %xmm4, %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x3420
movsd 0x8(%rsp), %xmm1
movapd %xmm0, %xmm4
movsd 0x10(%rsp), %xmm2
mulsd %xmm2, %xmm1
movl $0x0, %r10d
testb %r13b, %r13b
movl $0x0, %r13d
movsd %xmm4, 0x20(%rsp)
je 0x19967
movsd 0x13abb(%rip), %xmm0    # 0x2d3d8
mulsd %xmm1, %xmm0
divsd 0x6f7(%rip), %xmm0      # 0x1a020
divsd %xmm2, %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x3420
mulsd 0x10(%rsp), %xmm0
cvttsd2si %xmm0, %r13
movsd 0x13a95(%rip), %xmm0    # 0x2d3e0
mulsd 0x20(%rsp), %xmm0
callq 0x3420
movsd 0x20(%rsp), %xmm4
movsd 0x8(%rsp), %xmm1
cvttsd2si %xmm0, %r10
xorl %esi, %esi
cmpl $0x2, %ebp
sete %al
leal (,%r13,2), %edi
testb %r12b, %r12b
movsd 0x18(%rsp), %xmm2
jne 0x1998a
xorpd %xmm5, %xmm5
jne 0x19994
jmp 0x19998
movsd 0x67e(%rip), %xmm5      # 0x1a010
je 0x19998
addsd %xmm2, %xmm2
movb 0xa8(%rsp), %r12b
cmpl $0x1, %ebp
jne 0x199b8
movsd 0x13a83(%rip), %xmm3    # 0x2d430
movsd 0xec8a(%rip), %xmm9     # 0x28640
jmp 0x199e5
movsd 0x13a78(%rip), %xmm0    # 0x2d438
testb %r12b, %r12b
jne 0x199cb
movapd %xmm0, %xmm3
jmp 0x199d3
movsd 0x13a5d(%rip), %xmm3    # 0x2d430
cmpl $0x3, %ebp
je 0x199dc
movapd %xmm0, %xmm3
movsd 0x4cf3(%rip), %xmm9     # 0x1e6d8
movsd 0x4ceb(%rip), %xmm0     # 0x1e6d8
testb %r12b, %r12b
jne 0x199f8
movaps %xmm0, %xmm8
jmp 0x19a01
movsd 0x13a3f(%rip), %xmm8    # 0x2d440
cmpl $0x2, %ebp
je 0x19a0a
movaps %xmm0, %xmm8
movb %al, %sil
leal (,%r15,4), %eax
pushq $0x3
popq %rcx
xorl %edx, %edx
divl %ecx
cmpl %r14d, %eax
jne 0x19a2b
movsd 0x13a1f(%rip), %xmm6    # 0x2d448
jmp 0x19a9e
movl %r15d, %ecx
shll $0x4, %ecx
pushq $0x9
popq %r8
movl %ecx, %eax
xorl %edx, %edx
divl %r8d
cmpl %r14d, %eax
jne 0x19a4b
movsd 0x13a07(%rip), %xmm6    # 0x2d450
jmp 0x19a9e
pushq $0xa
popq %r9
movl %ecx, %eax
xorl %edx, %edx
divl %r9d
cmpl %r14d, %eax
jne 0x19a65
movsd 0x5c5(%rip), %xmm6      # 0x1a028
jmp 0x19a9e
testb $0x3, %r15b
jne 0x19a81
leal (%r15,%r15,4), %eax
shrl $0x2, %eax
cmpl %r14d, %eax
jne 0x19a81
movsd 0x139d9(%rip), %xmm6    # 0x2d458
jmp 0x19a9e
imull $0xf, %r15d, %eax
xorl %edx, %edx
divl %r8d
xorl %ecx, %ecx
cmpl %r14d, %eax
sete %cl
leaq 0x13a07(%rip), %rax     # 0x2d4a0
movsd (%rax,%rcx,8), %xmm6
cvtsi2sd %rdi, %xmm0
leaq 0x139e6(%rip), %rax     # 0x2d490
cmpl $0x2, %ebp
jae 0x19ab7
movsd %xmm6, 0x48(%rsp)
jmp 0x19ac5
movsd 0x13911(%rip), %xmm7    # 0x2d3d0
movsd %xmm7, 0x48(%rsp)
addsd %xmm0, %xmm1
movq %r10, %r15
leal (%r10,%r10), %ecx
cvtsi2sd %rcx, %xmm7
movsd (%rax,%rsi,8), %xmm0
movsd %xmm0, 0x30(%rsp)
movapd %xmm4, %xmm0
addsd %xmm7, %xmm0
testl %ebp, %ebp
movsd %xmm1, 0x8(%rsp)
je 0x19ba9
movsd %xmm8, 0x50(%rsp)
movsd %xmm3, 0x38(%rsp)
movsd 0x138ed(%rip), %xmm1    # 0x2d3f8
movsd %xmm2, 0x18(%rsp)
divsd %xmm2, %xmm1
addsd 0x13943(%rip), %xmm1    # 0x2d460
divsd %xmm0, %xmm1
movsd 0x1393f(%rip), %xmm0    # 0x2d468
divsd %xmm1, %xmm0
movsd %xmm5, 0x40(%rsp)
movsd %xmm9, 0x60(%rsp)
movsd %xmm7, 0x58(%rsp)
callq 0x3420
movsd 0x60(%rsp), %xmm4
movsd 0x40(%rsp), %xmm3
addsd 0x4b7f(%rip), %xmm0     # 0x1e6d8
movapd %xmm4, %xmm5
movsd 0x48(%rsp), %xmm2
addsd %xmm2, %xmm5
movsd 0x4b9(%rip), %xmm1      # 0x1a028
addsd %xmm1, %xmm5
maxsd %xmm0, %xmm5
movsd 0x20(%rsp), %xmm0
addsd %xmm5, %xmm0
addsd 0x58(%rsp), %xmm0
addsd %xmm0, %xmm3
cmpl $0x1, %ebp
movsd %xmm5, 0x10(%rsp)
je 0x19cfd
addsd %xmm2, %xmm1
movapd %xmm1, 0x20(%rsp)
jmp 0x19d0b
movsd 0x4b27(%rip), %xmm3     # 0x1e6d8
divsd %xmm2, %xmm3
addsd 0x13833(%rip), %xmm3    # 0x2d3f0
movsd 0xea7b(%rip), %xmm2     # 0x28640
movsd %xmm2, 0x10(%rsp)
addsd %xmm2, %xmm0
addsd %xmm0, %xmm5
divsd %xmm5, %xmm3
mulsd 0x13819(%rip), %xmm3    # 0x2d3f8
movsd %xmm3, 0x18(%rsp)
movsd 0x137fb(%rip), %xmm0    # 0x2d3e8
divsd %xmm3, %xmm0
movaps %xmm6, 0x20(%rsp)
callq 0x3420
addsd 0x4ad5(%rip), %xmm0     # 0x1e6d8
movapd 0x20(%rsp), %xmm1
addsd 0x417(%rip), %xmm1      # 0x1a028
maxsd %xmm0, %xmm1
movapd %xmm1, %xmm2
movapd %xmm1, 0x20(%rsp)
movsd 0x13849(%rip), %xmm0    # 0x2d470
mulsd 0x18(%rsp), %xmm0
divsd 0x3e3(%rip), %xmm0      # 0x1a018
movsd 0x10(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x10(%rsp)
addsd 0x1382b(%rip), %xmm0    # 0x2d478
movsd 0x3eb(%rip), %xmm1      # 0x1a040
maxsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd 0x3b5(%rip), %xmm2      # 0x1a020
subsd %xmm1, %xmm2
divsd %xmm2, %xmm0
mulsd 0xe9dd(%rip), %xmm0     # 0x28658
callq 0x3420
addsd %xmm0, %xmm0
mulsd 0x13744(%rip), %xmm0    # 0x2d3d0
movsd %xmm0, 0x38(%rsp)
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x1377e(%rip), %xmm0    # 0x2d428
mulsd %xmm1, %xmm0
mulsd 0xa2c2(%rip), %xmm0     # 0x23f78
callq 0x3420
mulsd 0x1370d(%rip), %xmm0    # 0x2d3d0
movsd %xmm0, 0x40(%rsp)
movsd 0x8(%rsp), %xmm0
divsd 0x18(%rsp), %xmm0
mulsd 0x1376b(%rip), %xmm0    # 0x2d448
callq 0x3420
movapd 0x20(%rsp), %xmm2
movsd 0x10(%rsp), %xmm3
cvttsd2si 0x40(%rsp), %r14
movsd 0x30(%rsp), %xmm4
jmp 0x19d60
movapd %xmm5, %xmm0
subsd %xmm4, %xmm0
movapd %xmm0, 0x20(%rsp)
movsd 0x8(%rsp), %xmm5
movsd 0x38(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movsd 0x50(%rsp), %xmm0
addsd %xmm1, %xmm5
movsd 0x18(%rsp), %xmm1
mulsd %xmm3, %xmm1
mulsd %xmm5, %xmm1
divsd 0x136bb(%rip), %xmm1    # 0x2d3f8
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
callq 0x3420
movsd 0x30(%rsp), %xmm4
pushq $0x20
popq %r14
movapd 0x20(%rsp), %xmm2
movsd 0x10(%rsp), %xmm3
movsd 0x48(%rsp), %xmm1
subsd %xmm1, %xmm2
cvttsd2si %xmm2, %eax
movl %eax, 0x34(%rbx)
cvttsd2si %xmm1, %rax
cvttpd2dq %xmm2, %xmm1
cvtdq2pd %xmm1, %xmm1
movl %eax, 0x30(%rbx)
movl %eax, %eax
cvtsi2sd %rax, %xmm2
subsd %xmm1, %xmm3
subsd %xmm2, %xmm3
cvttsd2si %xmm3, %rax
mulsd %xmm0, %xmm4
movl %eax, 0x2c(%rbx)
mulsd 0x274(%rip), %xmm4      # 0x1a018
movapd %xmm4, %xmm0
callq 0x3100
cvttsd2si %xmm0, %rax
movsd 0x38(%rsp), %xmm1
mulsd 0x250(%rip), %xmm1      # 0x1a010
movl %eax, 0x10(%rbx)
movl %r14d, %eax
cvtsi2sd %rax, %xmm0
movl %r14d, 0x20(%rbx)
subsd %xmm0, %xmm1
cvttsd2si %xmm1, %eax
movl %eax, 0x1c(%rbx)
addl %eax, %r14d
movl %r14d, 0x24(%rbx)
movl %r13d, 0x3c(%rbx)
movl %r15d, 0x40(%rbx)
movl %ebp, %eax
andl $-0x2, %eax
movl %ebp, %ecx
orl $0x80, %ecx
testb %r12b, %r12b
cmovel %ebp, %ecx
cmpl $0x2, %eax
cmovnel %ebp, %ecx
movl %ecx, 0x14(%rbx)
testl %ecx, %ecx
setne 0x28(%rbx)
sete 0x38(%rbx)
movq %rbx, %rdi
callq 0x38fe
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop