// File: /workspace/github_cpp_makefile_star2_O1/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, 0x10(%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, (%rdi)
movups %xmm0, 0x10(%rdi)
movups %xmm0, 0x40(%rdi)
movups %xmm0, 0x30(%rdi)
movups %xmm0, 0x20(%rdi)
movl $0x0, 0x50(%rdi)
movl %edx, (%rdi)
movl %ecx, 0x4(%rdi)
movb %r12b, 0x18(%rdi)
leaq 0x13cb7(%rip), %rcx     # 0x33440
movsd (%rcx,%rax,8), %xmm1
movl %edx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movsd %xmm1, 0x8(%rsp)
divsd %xmm1, %xmm0
callq 0x33f0
movapd %xmm0, %xmm1
movl %r15d, %eax
cvtsi2sd %rax, %xmm4
testl %r12d, %r12d
je 0x1f7d7
mulsd 0x848(%rip), %xmm4      # 0x20008
movapd %xmm4, %xmm0
movsd %xmm1, (%rsp)
callq 0x33f0
movsd (%rsp), %xmm1
movapd %xmm0, %xmm4
movsd 0x8(%rsp), %xmm2
mulsd %xmm2, %xmm1
movl $0x0, %ecx
testb %r13b, %r13b
movsd %xmm1, (%rsp)
movsd %xmm4, 0x30(%rsp)
je 0x1f829
movsd 0x13b9a(%rip), %xmm0    # 0x33398
mulsd %xmm1, %xmm0
divsd 0x80e(%rip), %xmm0      # 0x20018
divsd %xmm2, %xmm0
callq 0x33f0
movsd 0x30(%rsp), %xmm4
movsd (%rsp), %xmm1
mulsd 0x8(%rsp), %xmm0
cvttsd2si %xmm0, %rcx
testb %r13b, %r13b
movl $0x0, %r13d
je 0x1f85b
movsd 0x13b64(%rip), %xmm0    # 0x333a0
mulsd %xmm4, %xmm0
movq %rcx, %r13
callq 0x33f0
movsd 0x30(%rsp), %xmm4
movsd (%rsp), %xmm1
movq %r13, %rcx
cvttsd2si %xmm0, %r13
xorl %eax, %eax
cmpl $0x2, %ebp
sete %dl
movq %rcx, 0x60(%rsp)
addl %ecx, %ecx
testb %r12b, %r12b
movsd 0x10(%rsp), %xmm2
jne 0x1f87d
xorpd %xmm5, %xmm5
jne 0x1f887
jmp 0x1f88b
movsd 0x783(%rip), %xmm5      # 0x20008
je 0x1f88b
addsd %xmm2, %xmm2
movb 0xa8(%rsp), %r12b
cmpl $0x1, %ebp
jne 0x1f8ab
movsd 0x13b50(%rip), %xmm3    # 0x333f0
movsd 0xed67(%rip), %xmm8     # 0x2e610
jmp 0x1f8d8
movsd 0x13b45(%rip), %xmm0    # 0x333f8
testb %r12b, %r12b
jne 0x1f8be
movapd %xmm0, %xmm3
jmp 0x1f8c6
movsd 0x13b2a(%rip), %xmm3    # 0x333f0
cmpl $0x3, %ebp
je 0x1f8cf
movapd %xmm0, %xmm3
movsd 0x4df0(%rip), %xmm8     # 0x246c8
movsd 0x4de8(%rip), %xmm0     # 0x246c8
testb %r12b, %r12b
jne 0x1f8ea
movaps %xmm0, %xmm7
jmp 0x1f8f2
movsd 0x13b0e(%rip), %xmm7    # 0x33400
cmpl $0x2, %ebp
je 0x1f8fa
movaps %xmm0, %xmm7
movb %dl, %al
leal (,%r15,4), %edx
movl $0xaaaaaaab, %esi       # imm = 0xAAAAAAAB
imulq %rdx, %rsi
shrq $0x21, %rsi
cmpl %r14d, %esi
jne 0x1f923
movsd 0x13aea(%rip), %xmm6    # 0x33408
jmp 0x1f9a4
movl %r15d, %edx
shll $0x4, %edx
imulq $0x38e38e39, %rdx, %rsi # imm = 0x38E38E39
shrq $0x21, %rsi
cmpl %r14d, %esi
jne 0x1f943
movsd 0x13acf(%rip), %xmm6    # 0x33410
jmp 0x1f9a4
movl %edx, %edx
movl $0xcccccccd, %esi       # imm = 0xCCCCCCCD
imulq %rdx, %rsi
shrq $0x23, %rsi
cmpl %r14d, %esi
jne 0x1f961
movsd 0x6c1(%rip), %xmm6      # 0x20020
jmp 0x1f9a4
testb $0x3, %r15b
jne 0x1f97d
leal (%r15,%r15,4), %edx
shrl $0x2, %edx
cmpl %r14d, %edx
jne 0x1f97d
movsd 0x13a9d(%rip), %xmm6    # 0x33418
jmp 0x1f9a4
leal (%r15,%r15,4), %edx
leal (%rdx,%rdx,2), %edx
imulq $0x38e38e39, %rdx, %rdx # imm = 0x38E38E39
shrq $0x21, %rdx
xorl %esi, %esi
cmpl %r14d, %edx
sete %sil
leaq 0x13ac1(%rip), %rdx     # 0x33460
movsd (%rdx,%rsi,8), %xmm6
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
leaq 0x13a9d(%rip), %rcx     # 0x33450
cmpl $0x2, %ebp
jb 0x1f9c0
movsd 0x139d0(%rip), %xmm6    # 0x33390
movsd %xmm6, 0x8(%rsp)
addsd %xmm0, %xmm1
leal (,%r13,2), %edx
cvtsi2sd %rdx, %xmm9
movsd (%rcx,%rax,8), %xmm6
movapd %xmm4, %xmm0
addsd %xmm9, %xmm0
testl %ebp, %ebp
movsd %xmm1, (%rsp)
movsd %xmm6, 0x28(%rsp)
je 0x1faab
movsd %xmm7, 0x48(%rsp)
movsd %xmm3, 0x20(%rsp)
movsd 0x139ac(%rip), %xmm1    # 0x333b8
movsd %xmm2, 0x10(%rsp)
divsd %xmm2, %xmm1
addsd 0x13a02(%rip), %xmm1    # 0x33420
divsd %xmm0, %xmm1
movsd 0x139fe(%rip), %xmm0    # 0x33428
divsd %xmm1, %xmm0
movsd %xmm5, 0x40(%rsp)
movsd %xmm8, 0x58(%rsp)
movsd %xmm9, 0x50(%rsp)
callq 0x33f0
movsd 0x58(%rsp), %xmm2
movsd 0x40(%rsp), %xmm3
addsd 0x4c6d(%rip), %xmm0     # 0x246c8
movapd %xmm2, %xmm4
movsd 0x8(%rsp), %xmm1
addsd %xmm1, %xmm4
movsd 0x5af(%rip), %xmm5      # 0x20020
addsd %xmm5, %xmm4
maxsd %xmm0, %xmm4
movsd 0x30(%rsp), %xmm0
addsd %xmm4, %xmm0
addsd 0x50(%rsp), %xmm0
addsd %xmm0, %xmm3
cmpl $0x1, %ebp
movsd %xmm4, 0x18(%rsp)
je 0x1fbf0
addsd %xmm1, %xmm5
movapd %xmm5, 0x30(%rsp)
jmp 0x1fbfa
movsd 0x4c15(%rip), %xmm3     # 0x246c8
divsd %xmm2, %xmm3
addsd 0x138f1(%rip), %xmm3    # 0x333b0
movsd 0xeb49(%rip), %xmm2     # 0x2e610
movsd %xmm2, 0x18(%rsp)
addsd %xmm2, %xmm0
addsd %xmm0, %xmm5
divsd %xmm5, %xmm3
mulsd 0x138d7(%rip), %xmm3    # 0x333b8
movsd %xmm3, 0x10(%rsp)
movsd 0x138b9(%rip), %xmm0    # 0x333a8
divsd %xmm3, %xmm0
callq 0x33f0
addsd 0x4bc8(%rip), %xmm0     # 0x246c8
movsd 0x518(%rip), %xmm2      # 0x20020
addsd 0x8(%rsp), %xmm2
maxsd %xmm0, %xmm2
movapd %xmm2, 0x30(%rsp)
movsd 0x13910(%rip), %xmm0    # 0x33430
mulsd 0x10(%rsp), %xmm0
divsd 0x4e2(%rip), %xmm0      # 0x20010
movsd 0x18(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x18(%rsp)
addsd 0x138f2(%rip), %xmm0    # 0x33438
movsd 0x502(%rip), %xmm1      # 0x20050
maxsd %xmm0, %xmm1
movsd (%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd 0x4b5(%rip), %xmm2      # 0x20018
subsd %xmm1, %xmm2
divsd %xmm2, %xmm0
mulsd 0xeab5(%rip), %xmm0     # 0x2e628
callq 0x33f0
addsd %xmm0, %xmm0
mulsd 0x1380c(%rip), %xmm0    # 0x33390
movsd %xmm0, 0x20(%rsp)
movsd (%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
movsd 0x13848(%rip), %xmm0    # 0x333e8
mulsd %xmm1, %xmm0
mulsd 0xa3a4(%rip), %xmm0     # 0x29f50
callq 0x33f0
mulsd 0x137d7(%rip), %xmm0    # 0x33390
movsd %xmm0, 0x40(%rsp)
movsd (%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
divsd 0x28(%rsp), %xmm0
callq 0x33f0
movsd 0x8(%rsp), %xmm2
movapd 0x30(%rsp), %xmm1
movsd 0x18(%rsp), %xmm3
cvttsd2si 0x40(%rsp), %r14
jmp 0x1fc50
subsd %xmm2, %xmm4
movapd %xmm4, 0x30(%rsp)
movsd (%rsp), %xmm5
movsd 0x20(%rsp), %xmm1
movsd 0x28(%rsp), %xmm4
movsd 0x48(%rsp), %xmm0
addsd %xmm1, %xmm5
movsd 0x10(%rsp), %xmm1
mulsd %xmm3, %xmm1
mulsd %xmm5, %xmm1
divsd 0x1378d(%rip), %xmm1    # 0x333b8
mulsd %xmm1, %xmm0
divsd %xmm4, %xmm0
callq 0x33f0
movl $0x20, %r14d
movsd 0x8(%rsp), %xmm2
movsd 0x18(%rsp), %xmm3
movapd 0x30(%rsp), %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %eax
movl %eax, 0x34(%rbx)
cvttsd2si %xmm2, %rax
cvttpd2dq %xmm1, %xmm1
cvtdq2pd %xmm1, %xmm1
movl %eax, 0x30(%rbx)
movl %eax, %eax
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
subsd %xmm1, %xmm3
subsd %xmm2, %xmm3
cvttsd2si %xmm3, %rax
movsd 0x28(%rsp), %xmm1
mulsd %xmm0, %xmm1
movl %eax, 0x2c(%rbx)
mulsd 0x379(%rip), %xmm1      # 0x20010
movapd %xmm1, %xmm0
callq 0x3100
cvttsd2si %xmm0, %rax
movsd 0x20(%rsp), %xmm1
mulsd 0x355(%rip), %xmm1      # 0x20008
movl %eax, 0x10(%rbx)
movl %r14d, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %r14d, 0x20(%rbx)
subsd %xmm0, %xmm1
cvttsd2si %xmm1, %eax
movl %eax, 0x1c(%rbx)
addl %eax, %r14d
movl %r14d, 0x24(%rbx)
movq 0x60(%rsp), %rax
movl %eax, 0x3c(%rbx)
movl %r13d, 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 0x3c2c
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop