// File: /workspace/github_cpp_makefile_star2_O3/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 0x140c3(%rip), %rcx     # 0x33480
movsd (%rcx,%rax,8), %xmm1
movl %edx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movsd %xmm1, 0x10(%rsp)
divsd %xmm1, %xmm0
callq 0x33f0
movapd %xmm0, %xmm1
movl %r15d, %eax
cvtsi2sd %rax, %xmm4
testl %r12d, %r12d
je 0x1f40d
mulsd 0xc1c(%rip), %xmm4      # 0x20010
movapd %xmm4, %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x33f0
movsd 0x8(%rsp), %xmm1
movapd %xmm0, %xmm4
movsd 0x10(%rsp), %xmm2
mulsd %xmm2, %xmm1
movl $0x0, %edi
testb %r13b, %r13b
movl $0x0, %r13d
movsd %xmm4, 0x20(%rsp)
je 0x1f47f
movsd 0x13fa3(%rip), %xmm0    # 0x333d8
mulsd %xmm1, %xmm0
divsd 0xbdf(%rip), %xmm0      # 0x20020
divsd %xmm2, %xmm0
movsd %xmm1, 0x8(%rsp)
callq 0x33f0
mulsd 0x10(%rsp), %xmm0
cvttsd2si %xmm0, %r13
movsd 0x13f7d(%rip), %xmm0    # 0x333e0
mulsd 0x20(%rsp), %xmm0
callq 0x33f0
movsd 0x20(%rsp), %xmm4
movsd 0x8(%rsp), %xmm1
cvttsd2si %xmm0, %rdi
xorl %eax, %eax
cmpl $0x2, %ebp
sete %dl
leal (,%r13,2), %ecx
testb %r12b, %r12b
movsd 0x18(%rsp), %xmm2
jne 0x1f4a2
xorpd %xmm5, %xmm5
jne 0x1f4ac
jmp 0x1f4b0
movsd 0xb66(%rip), %xmm5      # 0x20010
je 0x1f4b0
addsd %xmm2, %xmm2
movb 0xa8(%rsp), %r12b
cmpl $0x1, %ebp
jne 0x1f4d0
movsd 0x13f6b(%rip), %xmm3    # 0x33430
movsd 0xf16a(%rip), %xmm9     # 0x2e638
jmp 0x1f4fd
movsd 0x13f60(%rip), %xmm0    # 0x33438
testb %r12b, %r12b
jne 0x1f4e3
movapd %xmm0, %xmm3
jmp 0x1f4eb
movsd 0x13f45(%rip), %xmm3    # 0x33430
cmpl $0x3, %ebp
je 0x1f4f4
movapd %xmm0, %xmm3
movsd 0x51db(%rip), %xmm9     # 0x246d8
movsd 0x51d3(%rip), %xmm0     # 0x246d8
testb %r12b, %r12b
jne 0x1f510
movaps %xmm0, %xmm8
jmp 0x1f519
movsd 0x13f27(%rip), %xmm8    # 0x33440
cmpl $0x2, %ebp
je 0x1f522
movaps %xmm0, %xmm8
movb %dl, %al
leal (,%r15,4), %edx
movl $0xaaaaaaab, %esi       # imm = 0xAAAAAAAB
imulq %rdx, %rsi
shrq $0x21, %rsi
cmpl %r14d, %esi
jne 0x1f54b
movsd 0x13f02(%rip), %xmm6    # 0x33448
jmp 0x1f5cc
movl %r15d, %edx
shll $0x4, %edx
imulq $0x38e38e39, %rdx, %rsi # imm = 0x38E38E39
shrq $0x21, %rsi
cmpl %r14d, %esi
jne 0x1f56b
movsd 0x13ee7(%rip), %xmm6    # 0x33450
jmp 0x1f5cc
movl %edx, %edx
movl $0xcccccccd, %esi       # imm = 0xCCCCCCCD
imulq %rdx, %rsi
shrq $0x23, %rsi
cmpl %r14d, %esi
jne 0x1f589
movsd 0xaa1(%rip), %xmm6      # 0x20028
jmp 0x1f5cc
testb $0x3, %r15b
jne 0x1f5a5
leal (%r15,%r15,4), %edx
shrl $0x2, %edx
cmpl %r14d, %edx
jne 0x1f5a5
movsd 0x13eb5(%rip), %xmm6    # 0x33458
jmp 0x1f5cc
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 0x13ed9(%rip), %rdx     # 0x334a0
movsd (%rdx,%rsi,8), %xmm6
xorps %xmm0, %xmm0
cvtsi2sd %rcx, %xmm0
leaq 0x13eb5(%rip), %rcx     # 0x33490
cmpl $0x2, %ebp
jae 0x1f5e8
movsd %xmm6, 0x48(%rsp)
jmp 0x1f5f6
movsd 0x13de0(%rip), %xmm7    # 0x333d0
movsd %xmm7, 0x48(%rsp)
addsd %xmm0, %xmm1
movq %rdi, %r15
leal (%rdi,%rdi), %edx
xorps %xmm7, %xmm7
cvtsi2sd %rdx, %xmm7
movsd (%rcx,%rax,8), %xmm0
movsd %xmm0, 0x30(%rsp)
movapd %xmm4, %xmm0
addsd %xmm7, %xmm0
testl %ebp, %ebp
movsd %xmm1, 0x8(%rsp)
je 0x1f6dc
movsd %xmm8, 0x50(%rsp)
movsd %xmm3, 0x38(%rsp)
movsd 0x13dba(%rip), %xmm1    # 0x333f8
movsd %xmm2, 0x18(%rsp)
divsd %xmm2, %xmm1
addsd 0x13e10(%rip), %xmm1    # 0x33460
divsd %xmm0, %xmm1
movsd 0x13e0c(%rip), %xmm0    # 0x33468
divsd %xmm1, %xmm0
movsd %xmm5, 0x40(%rsp)
movsd %xmm9, 0x60(%rsp)
movsd %xmm7, 0x58(%rsp)
callq 0x33f0
movsd 0x60(%rsp), %xmm4
movsd 0x40(%rsp), %xmm3
addsd 0x504c(%rip), %xmm0     # 0x246d8
movapd %xmm4, %xmm5
movsd 0x48(%rsp), %xmm2
addsd %xmm2, %xmm5
movsd 0x986(%rip), %xmm1      # 0x20028
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 0x1f830
addsd %xmm2, %xmm1
movapd %xmm1, 0x20(%rsp)
jmp 0x1f83e
movsd 0x4ff4(%rip), %xmm3     # 0x246d8
divsd %xmm2, %xmm3
addsd 0x13d00(%rip), %xmm3    # 0x333f0
movsd 0xef40(%rip), %xmm2     # 0x2e638
movsd %xmm2, 0x10(%rsp)
addsd %xmm2, %xmm0
addsd %xmm0, %xmm5
divsd %xmm5, %xmm3
mulsd 0x13ce6(%rip), %xmm3    # 0x333f8
movsd %xmm3, 0x18(%rsp)
movsd 0x13cc8(%rip), %xmm0    # 0x333e8
divsd %xmm3, %xmm0
movaps %xmm6, 0x20(%rsp)
callq 0x33f0
addsd 0x4fa2(%rip), %xmm0     # 0x246d8
movapd 0x20(%rsp), %xmm1
addsd 0x8e4(%rip), %xmm1      # 0x20028
maxsd %xmm0, %xmm1
movapd %xmm1, %xmm2
movapd %xmm1, 0x20(%rsp)
movsd 0x13d16(%rip), %xmm0    # 0x33470
mulsd 0x18(%rsp), %xmm0
divsd 0x8b0(%rip), %xmm0      # 0x20018
movsd 0x10(%rsp), %xmm1
addsd %xmm2, %xmm1
movsd %xmm1, 0x10(%rsp)
addsd 0x13cf8(%rip), %xmm0    # 0x33478
movsd 0x8b8(%rip), %xmm1      # 0x20040
maxsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd 0x882(%rip), %xmm2      # 0x20020
subsd %xmm1, %xmm2
divsd %xmm2, %xmm0
mulsd 0xeea2(%rip), %xmm0     # 0x2e650
callq 0x33f0
addsd %xmm0, %xmm0
mulsd 0x13c11(%rip), %xmm0    # 0x333d0
movsd %xmm0, 0x38(%rsp)
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x13c4b(%rip), %xmm0    # 0x33428
mulsd %xmm1, %xmm0
mulsd 0xa78f(%rip), %xmm0     # 0x29f78
callq 0x33f0
mulsd 0x13bda(%rip), %xmm0    # 0x333d0
movsd %xmm0, 0x40(%rsp)
movsd 0x8(%rsp), %xmm0
divsd 0x18(%rsp), %xmm0
mulsd 0x13c38(%rip), %xmm0    # 0x33448
callq 0x33f0
movapd 0x20(%rsp), %xmm2
movsd 0x10(%rsp), %xmm3
cvttsd2si 0x40(%rsp), %r14
movsd 0x30(%rsp), %xmm4
jmp 0x1f895
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 0x13b88(%rip), %xmm1    # 0x333f8
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
callq 0x33f0
movsd 0x30(%rsp), %xmm4
movl $0x20, %r14d
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
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
subsd %xmm1, %xmm3
subsd %xmm2, %xmm3
cvttsd2si %xmm3, %rax
mulsd %xmm0, %xmm4
movl %eax, 0x2c(%rbx)
mulsd 0x73c(%rip), %xmm4      # 0x20018
movapd %xmm4, %xmm0
callq 0x3100
cvttsd2si %xmm0, %rax
movsd 0x38(%rsp), %xmm1
mulsd 0x718(%rip), %xmm1      # 0x20010
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)
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 0x3c00
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq