// File: /workspace/github_cpp_makefile_star2_O3/tonymugen[P]sampleSNPs/varfiles.cpp
// Function: sampFiles::BedFileI::_ld(char const*, char const*, unsigned long const&, unsigned short const&, double&, double&, double&, double&)
void BedFileI::_ld(const char *snp1, const char *snp2, const size_t &N, const unsigned short &pad, double &rSq, double &Dprime, double &dcnt1, double &dcnt2){
	// Using the Gaunt et al. (2007) formulation
	// The data in .bed files are strictly biallelic by definition of the format, so that makes things easier.
	// Using derived alleles because they are mostly at low frequency so the expected number of calculations is low
	// However, then convert everything to the most common allele frequencies to make things compatible with Gaunt et al.
	// Using the notation in that paper, too, to make things more clear

	// constants
	const char allMiss = static_cast<char>(0x55); // all genotypes missing in a byte
	const char homDerv = static_cast<char>(0x00); // homozygous derived for all bit-pair positions

	// modifiable parameters
	double D     = 0.0;
	double p1    = 0.0; // frequency of the derived allele at snp1
	double q1    = 0.0; // frequency of the derived allele at snp2
	double f11   = 0.0; // frequency of the (hom. maj. allele @1, hom. maj.allel @2) haplotype; to be estimated; D = f11 - p1*q1
	double n11   = 0.0; // # of 1,1 homozygote haplotypes
	double n12   = 0.0; // # of hom. 1, heterozygous 2 haplotypes
	double n21   = 0.0; // # of het. 1, hom. 2 haplotypes
	double n22   = 0.0; // # of het. 1, het. 2 haplotypes
	double Npres = 0.0; // # of present genotypes (present at both loci)
	double p1q1;        // p1*q1
	double p2q2;        // p2*q2
	// f11 min and max
	double f11Min;
	double f11Max;
	// re-used intermediate variables
	double opq;         // 1-2p-2q
	double smn;         // 2n11+n12+n21
	double ppq;         // p1+q1
	// qubic equation coefficients
	double a;
	double b;
	double c;
	double d;
	// decision variables
	double bda;    // b/a
	double xN;
	double deltaSq;
	double hSq;
	double gammaN;
	double Delta3;

	char curBitPair1;
	char curBitPair2;

	// Data missing at either locus are ignored (i.e. I am using pairwise-complete observations)
	for (size_t ind = 0; ind < N-1; ind++) { // leave the last byte out for now since it has padding bits (in general)
		if ( (snp1[ind] == allMiss) || (snp2[ind] == allMiss) ) { // a byte with all data missing; ignore (NOTE the OR)
			continue;
		}

		// go through the byte from the end
		for (size_t inByte = 0; inByte < 4; inByte++) {
			curBitPair1 = snp1[ind] & _masks[inByte];
			curBitPair2 = snp2[ind] & _masks[inByte];

			// Test missingness
			if ( (curBitPair1 == _tests.at('M')[inByte]) || (curBitPair2 == _tests.at('M')[inByte]) ) { // must use .at() because _tests is const
				continue;
			}
			Npres += 1.0;
			// Go through all the pairwise possibilities; adding up gametes (one per diploid)
			if (curBitPair1 == homDerv) {
				p1 += 1.0;
				if (curBitPair2 == homDerv) {
					q1  += 1.0;
					n11 += 1.0;
				} else if (curBitPair2 == _tests.at('H')[inByte]){
					q1  += 0.5;
					n12 += 1.0;
				}
			} else if (curBitPair1 == _tests.at('H')[inByte]){
				p1 += 0.5;
				if (curBitPair2 == homDerv) {
					q1  += 1.0;
					n21 += 1.0;
				} else if (curBitPair2 == _tests.at('H')[inByte]){
					q1  += 0.5;
					n22 += 1.0;
				}
			} else {
				if (curBitPair2 == homDerv) {
					q1 += 1.0;
				} else if (curBitPair2 == _tests.at('H')[inByte]){
					q1 += 0.5;
				}
			}
		}
	}
	// finally, deal with the padded byte
	for (size_t inByte = 0; inByte < (4 - pad); inByte++) { // not testing for sane values of pad, since this is a protected function and I can expect sane values in correct class implementation
		curBitPair1 = snp1[N-1] & _masks[inByte];
		curBitPair2 = snp2[N-1] & _masks[inByte];

		// Test missingness
		if ( (curBitPair1 == _tests.at('M')[inByte]) || (curBitPair2 == _tests.at('M')[inByte]) ) { // must use .at() because _tests is const
			continue;
		}
		Npres += 1.0;
		// Go through all the pairwise possibilities; adding up gametes (one per diploid)
		if (curBitPair1 == homDerv) {
			p1 += 1.0;
			if (curBitPair2 == homDerv) {
				q1  += 1.0;
				n11 += 1.0;
			} else if (curBitPair2 == _tests.at('H')[inByte]){
				q1  += 0.5;
				n12 += 1.0;
			}
		} else if (curBitPair1 == _tests.at('H')[inByte]){
			p1 += 0.5;
			if (curBitPair2 == homDerv) {
				q1  += 1.0;
				n21 += 1.0;
			} else if (curBitPair2 == _tests.at('H')[inByte]){
				q1  += 0.5;
				n22 += 1.0;
			}
		} else {
			if (curBitPair2 == homDerv) {
				q1 += 1.0;
			} else if (curBitPair2 == _tests.at('H')[inByte]){
				q1 += 0.5;
			}
		}
	}

	// minor allele counts
	dcnt1 = (p1 <= Npres - p1 ? 2.0*p1 : 2.0*(Npres - p1));
	dcnt2 = (q1 <= Npres - q1 ? 2.0*q1 : 2.0*(Npres - q1));

	if (Npres <= 1.0) {
		rSq    = -9.0;
		Dprime = -9.0;
		return;
	}
	if ( (dcnt1 == 0.0) || (dcnt2 == 0.0) ) { // even if the SNPs are pre-screened for polymorphism, the alternatives may correspond to missing at the other locus
		rSq    = -9.0;
		Dprime = -9.0;
		return;
	}
	if (n22 == Npres) { // if everyone is het, cannot determine LD because we don't know the phase
		rSq    = -9.0;
		Dprime = -9.0;
		return;
	}
	// Finish calculating statistics if everything is sane
	p1   = p1/Npres;
	q1   = q1/Npres;
	// intermediate values
	p1q1 = p1*q1;

	if (n22 == 0.0) { // no het/het match-ups; means I can directly enumerate haplotypes
		f11  = (n11 + 0.5*(n12 + n21))/Npres;
		D    = f11 - p1q1;
		p2q2 = (1.0-p1)*(1.0-q1);
		rSq  = (D*D)/(p1q1*p2q2);

		if (D < -10.0*EPS) {
			double Dmax = ( p1q1 <= p2q2 ? -p1q1 : -p2q2 ); // (9) of Gaunt et al.
			Dprime      = D/Dmax;
		} else if (D > 10.0*EPS) {
			p1q1 = p1*(1.0 - q1);
			p2q2 = (1.0 - p1)*q1;

			double Dmax = ( p1q1 <= p2q2 ? p1q1 : p2q2 ); // (9) of Gaunt et al.
			Dprime      = D/Dmax;
		} else {
			Dprime = 0.0;
		}

		return;
	}

	// There is n22, so need to estimate f11 via ML (using Gaunt et al. cubic equation); they say f11 is between major alleles, but that is not necessary. Results will be the same for minor or any other combination
	// Calculate the bracketing values for f11:
	f11Min = n11 + 0.5*(n12 + n21); // i.e., all the het/het haplotypes are crossovers
	f11Max = f11Min + 0.5*n22;      // i.e., all het/het haplotypes are in phase
	f11Min = f11Min/Npres - 100.0*EPS; // some padding to take into account round-off errors
	f11Max = f11Max/Npres + 100.0*EPS;
	// re-used auxiliary variables
	ppq = p1 + q1;
	opq = 1.0 - 2.0*ppq;
	smn = 2.0*n11 + n12 + n21;
	// coefficients
	a   = 2.0*Npres; // will need to multiply again later to make 4N; doing this to re-use the 2N
	b   = a*opq - 2.0*smn - n22;
	c   = a*p1q1 - smn*opq - n22*(1.0 - ppq);
	d   = -smn*p1q1;
	a  *= 2.0;
	// decision variables
	bda     = b/a;
	xN      = -bda/3.0;
	deltaSq = bda*bda/9.0 - c/(3.0*a);
	hSq     = 4.0*a*a*deltaSq*deltaSq*deltaSq;
	gammaN  = xN*( xN*( a*xN + b ) + c ) + d;
	Delta3  = gammaN*gammaN - hSq;

	// now decide how many roots we have
	if (Delta3 > 100.0*EPS) { // everything is cool, only one distinct root
		f11 = xN + cbrt((sqrt(Delta3) - gammaN)/(2.0*a)) + cbrt(-(sqrt(Delta3) + gammaN)/(2.0*a));
	} else if (Delta3 < -100.0*EPS){ // Three roots; worst case scenario
		double theta  = acos(-gammaN/sqrt(hSq))/3.0;
		double ddelta = 2.0*sqrt(deltaSq);
		double alpha  = xN + ddelta*cos(theta);
		double beta   = xN + ddelta*cos(2.0*PI/3.0 + theta);
		double gamma  = xN + ddelta*cos(4.0*PI/3.0 + theta);

		if ( (alpha < f11Min) || (alpha > f11Max) ) {
			if ( (beta < f11Min) || (beta > f11Max) ) {
				if ( (gamma < f11Min) || (gamma > f11Max) ) {
					rSq    = -9.0;
					Dprime = -9.0;

					return;

				} else {
					f11 = gamma;
				}
			} else if ( (gamma < f11Min) || (gamma > f11Max) ) {
				f11 = beta;
			} else {
				// two plausible roots; choose the one with smallest |D|
				f11 = (fabs(beta - p1q1) <= fabs(gamma - p1q1) ? beta : gamma);
			}
		} else {
			if ( (beta < f11Min) || (beta > f11Max) ) {
				if ( (gamma < f11Min) || (gamma > f11Max) ) {
					f11 = alpha;
				} else {
					// two plausible roots; choose the one with smallest |D|
					f11 = (fabs(alpha - p1q1) <= fabs(gamma - p1q1) ? alpha : gamma);
				}
			} else if ( (gamma < f11Min) || (gamma > f11Max) ) {
				// two plausible roots; choose the one with smallest |D|
				f11 = (fabs(beta - p1q1) <= fabs(alpha - p1q1) ? beta : alpha);
			} else {
				// three plausible roots; choose the one with smallest |D|
				double minAB = (fabs(beta - p1q1) <= fabs(alpha - p1q1) ? beta : alpha);
				f11 = (fabs(minAB - p1q1) <= fabs(gamma - p1q1) ? minAB : gamma);
			}

		}
	} else { // Delta3 == 0; two different roots
		double mu    = cbrt(gammaN/(2.0*a));
		double alpha = xN + mu;
		double gamma = xN - 2.0*mu;
		if ( (alpha < f11Min) || (alpha > f11Max) ) { // f11 cannot be greater than min(p1, q1)
			if ( (gamma < f11Min) || (gamma > f11Max) ) {
				rSq    = -9.0;
				Dprime = -9.0;

				return;
			} else {
				f11 = gamma;
			}
		} else {
			if ( (gamma < f11Min) || (gamma > f11Max) ) { // impossible gamma; going with alpha
				f11 = alpha;
			} else { // both doable; conservatively choose the one minimzing |D|
				f11 = (fabs(alpha - p1q1) <= fabs(gamma - p1q1) ? alpha : gamma);
			}
		}

	}

	D    = f11 - p1q1;
	p2q2 = (1.0-p1)*(1.0-q1);
	rSq  = (D*D)/(p1q1*p2q2);

	if (D < -10.0*EPS) {
		double Dmax = ( p1q1 <= p2q2 ? -p1q1 : -p2q2 ); // (9) of Gaunt et al.
		Dprime      = D/Dmax;
	} else if (D > 10.0*EPS) {
		p1q1 = p1*(1.0 - q1);
		p2q2 = (1.0 - p1)*q1;

		double Dmax = ( p1q1 <= p2q2 ? p1q1 : p2q2 ); // (9) of Gaunt et al.
		Dprime      = D/Dmax;
	} else {
		Dprime = 0.0;
	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %r9, 0x48(%rsp)
movq %r8, 0xb0(%rsp)
movq %rdx, 0x80(%rsp)
movq %rsi, 0x90(%rsp)
movq %rcx, 0x70(%rsp)
movq (%rcx), %rax
xorpd %xmm0, %xmm0
movapd %xmm0, 0x50(%rsp)
movapd %xmm0, 0x60(%rsp)
xorpd %xmm1, %xmm1
movapd %xmm0, 0xc0(%rsp)
movapd %xmm0, 0xa0(%rsp)
xorpd %xmm5, %xmm5
cmpq $0x1, %rax
je 0x9a7e
xorl %r15d, %r15d
leaq 0x16b4c(%rip), %rbp     # 0x20300
movapd %xmm1, 0xa0(%rsp)
movapd %xmm1, 0xc0(%rsp)
movapd %xmm1, 0x60(%rsp)
movapd %xmm1, 0x50(%rsp)
movq 0x90(%rsp), %rcx
cmpb $0x55, (%rcx,%r15)
je 0x9a6e
movq 0x80(%rsp), %rcx
cmpb $0x55, (%rcx,%r15)
je 0x9a6e
xorl %r14d, %r14d
movapd %xmm1, 0x20(%rsp)
movapd %xmm0, 0x30(%rsp)
movapd %xmm5, 0x10(%rsp)
movq 0x16ad4(%rip), %rax     # 0x202e8
movb (%rax,%r14), %r13b
movq 0x90(%rsp), %rax
movb (%rax,%r15), %r12b
andb %r13b, %r12b
movq 0x80(%rsp), %rax
movb (%rax,%r15), %bl
movb $0x4d, 0xf(%rsp)
movq %rbp, %rdi
leaq 0xf(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %r12b
jne 0x9866
movapd 0x10(%rsp), %xmm5
movapd 0x30(%rsp), %xmm0
jmp 0x989a
movb $0x4d, 0xe(%rsp)
movq %rbp, %rdi
leaq 0xe(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
andb %r13b, %bl
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %bl
movapd 0x10(%rsp), %xmm5
movapd 0x30(%rsp), %xmm0
jne 0x98b2
movapd 0x20(%rsp), %xmm1
incq %r14
cmpq $0x4, %r14
jne 0x97fb
jmp 0x9a66
movapd 0x50(%rsp), %xmm1
movsd 0xec20(%rip), %xmm2     # 0x184e0
addsd %xmm2, %xmm1
movapd %xmm1, 0x50(%rsp)
testb %r12b, %r12b
je 0x9976
movb $0x48, 0xc(%rsp)
movq %rbp, %rdi
leaq 0xc(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %r12b
movapd 0x10(%rsp), %xmm5
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
jne 0x99dd
addsd 0xebd2(%rip), %xmm5     # 0x184e8
testb %bl, %bl
je 0x9a44
movapd %xmm5, 0x10(%rsp)
movb $0x48, 0xb(%rsp)
movq %rbp, %rdi
leaq 0xb(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %bl
movapd 0x30(%rsp), %xmm0
jne 0x996b
addsd 0xeb91(%rip), %xmm0     # 0x184e8
movapd 0x60(%rsp), %xmm1
addsd 0xeb7b(%rip), %xmm1     # 0x184e0
movapd %xmm1, 0x60(%rsp)
movapd 0x10(%rsp), %xmm5
jmp 0x989a
addsd %xmm2, %xmm5
testb %bl, %bl
je 0x9a25
movapd %xmm5, 0x10(%rsp)
movb $0x48, 0xd(%rsp)
movq %rbp, %rdi
leaq 0xd(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %bl
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
jne 0x9a1a
addsd 0xeb27(%rip), %xmm0     # 0x184e8
movapd 0xc0(%rsp), %xmm2
addsd 0xeb0e(%rip), %xmm2     # 0x184e0
movapd %xmm2, 0xc0(%rsp)
jmp 0x9a1a
testb %bl, %bl
je 0x9a59
movb $0x48, 0xa(%rsp)
movq %rbp, %rdi
leaq 0xa(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r14), %bl
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
jne 0x9a1a
addsd 0xeace(%rip), %xmm0     # 0x184e8
movapd 0x10(%rsp), %xmm5
jmp 0x98a0
addsd %xmm2, %xmm0
movapd 0xa0(%rsp), %xmm1
addsd %xmm2, %xmm1
movapd %xmm1, 0xa0(%rsp)
jmp 0x989a
movsd 0xea94(%rip), %xmm2     # 0x184e0
addsd %xmm2, %xmm0
addsd %xmm2, %xmm1
jmp 0x98a0
addsd 0xea7f(%rip), %xmm0     # 0x184e0
jmp 0x98a0
movq 0x70(%rsp), %rax
movq (%rax), %rax
incq %r15
leaq -0x1(%rax), %rcx
cmpq %rcx, %r15
jb 0x97d2
movq 0xb0(%rsp), %rax
cmpw $0x4, (%rax)
movapd %xmm0, 0x30(%rsp)
movapd %xmm1, 0x20(%rsp)
je 0x9d53
xorl %r15d, %r15d
leaq 0x1685a(%rip), %rbx     # 0x20300
leaq 0x9(%rsp), %r14
movapd %xmm5, 0x10(%rsp)
movq 0x70(%rsp), %rax
movq (%rax), %rax
movq 0x16828(%rip), %rcx     # 0x202e8
movb (%rcx,%r15), %r13b
movq 0x90(%rsp), %rcx
movb -0x1(%rcx,%rax), %r12b
andb %r13b, %r12b
movq 0x80(%rsp), %rcx
movb -0x1(%rcx,%rax), %bpl
movb $0x4d, 0x9(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %r12b
jne 0x9b15
movapd 0x10(%rsp), %xmm5
movapd 0x20(%rsp), %xmm1
jmp 0x9d2e
movb $0x4d, 0x8(%rsp)
movq %rbx, %rdi
leaq 0x8(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
andb %r13b, %bpl
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %bpl
movapd 0x10(%rsp), %xmm5
movapd 0x50(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
movsd 0xe98b(%rip), %xmm2     # 0x184e0
je 0x9d2e
addsd %xmm2, %xmm0
testb %r12b, %r12b
movapd %xmm0, 0x50(%rsp)
je 0x9c1a
movb $0x48, 0x6(%rsp)
movq %rbx, %rdi
leaq 0x6(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %r12b
movapd 0x10(%rsp), %xmm5
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
jne 0x9c8c
addsd 0xe937(%rip), %xmm5     # 0x184e8
testb %bpl, %bpl
je 0x9d04
movapd %xmm5, 0x10(%rsp)
movb $0x48, 0x5(%rsp)
movq %rbx, %rdi
leaq 0x5(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %bpl
movapd 0x30(%rsp), %xmm0
movsd 0xe8ef(%rip), %xmm1     # 0x184e0
jne 0x9b04
addsd 0xe8e9(%rip), %xmm0     # 0x184e8
movapd %xmm0, 0x30(%rsp)
movapd 0x60(%rsp), %xmm0
addsd %xmm1, %xmm0
movapd %xmm0, 0x60(%rsp)
jmp 0x9b04
addsd %xmm2, %xmm5
testb %bpl, %bpl
je 0x9cdc
movapd %xmm5, 0x10(%rsp)
movb $0x48, 0x7(%rsp)
movq %rbx, %rdi
leaq 0x7(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %bpl
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
movsd 0xe87c(%rip), %xmm2     # 0x184e0
jne 0x9cd4
addsd 0xe87a(%rip), %xmm0     # 0x184e8
movapd %xmm0, 0x30(%rsp)
movapd 0xc0(%rsp), %xmm0
addsd %xmm2, %xmm0
movapd %xmm0, 0xc0(%rsp)
jmp 0x9cd4
testb %bpl, %bpl
je 0x9d1c
movb $0x48, 0x4(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x16bf6
testq %rax, %rax
je 0xa5cb
movq 0x10(%rax), %rax
cmpb (%rax,%r15), %bpl
movapd 0x30(%rsp), %xmm0
movapd 0x20(%rsp), %xmm1
jne 0x9cd4
addsd 0xe81a(%rip), %xmm0     # 0x184e8
movapd %xmm0, 0x30(%rsp)
movapd 0x10(%rsp), %xmm5
jmp 0x9d2e
movapd 0x30(%rsp), %xmm0
addsd %xmm2, %xmm0
movapd %xmm0, 0x30(%rsp)
movapd 0xa0(%rsp), %xmm0
addsd %xmm2, %xmm0
movapd %xmm0, 0xa0(%rsp)
jmp 0x9d2e
movsd 0xe7d4(%rip), %xmm2     # 0x184e0
addsd %xmm2, %xmm0
movapd %xmm0, 0x30(%rsp)
addsd %xmm2, %xmm1
jmp 0x9d2e
movsd 0xe7bc(%rip), %xmm2     # 0x184e0
addsd %xmm2, %xmm0
movapd %xmm0, 0x30(%rsp)
movapd %xmm1, 0x20(%rsp)
incq %r15
movq 0xb0(%rsp), %rax
movzwl (%rax), %eax
movl $0x4, %ecx
subq %rax, %rcx
cmpq %rcx, %r15
jb 0x9aab
movq 0x120(%rsp), %rcx
movq 0x118(%rsp), %rax
movq 0x110(%rsp), %rbx
movapd 0x50(%rsp), %xmm4
movapd %xmm4, %xmm0
subsd %xmm5, %xmm0
movapd %xmm5, %xmm1
cmplesd %xmm0, %xmm1
movapd %xmm1, %xmm2
andnpd %xmm0, %xmm2
andpd %xmm5, %xmm1
orpd %xmm2, %xmm1
addsd %xmm1, %xmm1
movsd %xmm1, (%rax)
movapd %xmm4, %xmm1
movapd 0x30(%rsp), %xmm3
subsd %xmm3, %xmm1
movapd %xmm3, %xmm0
cmplesd %xmm1, %xmm0
movapd %xmm0, %xmm2
andnpd %xmm1, %xmm2
andpd %xmm3, %xmm0
orpd %xmm2, %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, (%rcx)
movsd 0xe70e(%rip), %xmm10    # 0x184e0
ucomisd %xmm4, %xmm10
jae 0x9e05
movsd (%rax), %xmm2
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm2
jne 0x9de9
jnp 0x9e05
ucomisd %xmm1, %xmm0
jne 0x9df1
jnp 0x9e05
movapd 0x60(%rsp), %xmm0
movapd 0x50(%rsp), %xmm6
ucomisd %xmm6, %xmm0
jne 0x9e35
jp 0x9e35
movabsq $-0x3fde000000000000, %rax # imm = 0xC022000000000000
movq 0x48(%rsp), %rcx
movq %rax, (%rcx)
movsd 0xe6d1(%rip), %xmm1     # 0x184f0
movsd %xmm1, (%rbx)
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
divsd %xmm6, %xmm5
movapd 0x30(%rsp), %xmm2
divsd %xmm6, %xmm2
movapd %xmm2, %xmm11
mulsd %xmm5, %xmm11
xorpd %xmm0, %xmm0
movapd 0x60(%rsp), %xmm1
ucomisd %xmm0, %xmm1
movapd 0x60(%rsp), %xmm0
movapd 0x20(%rsp), %xmm7
movapd %xmm7, %xmm12
movapd 0xc0(%rsp), %xmm9
addsd %xmm9, %xmm12
mulsd 0xe664(%rip), %xmm12    # 0x184e8
movapd 0xa0(%rsp), %xmm8
addsd %xmm8, %xmm12
jne 0x9f14
jp 0x9f14
divsd %xmm6, %xmm12
subsd %xmm11, %xmm12
movapd %xmm10, %xmm0
subsd %xmm5, %xmm0
movapd %xmm2, %xmm4
subsd %xmm2, %xmm10
movapd %xmm10, %xmm1
mulsd %xmm0, %xmm1
movapd %xmm12, %xmm2
mulsd %xmm12, %xmm2
movapd %xmm11, %xmm3
mulsd %xmm1, %xmm3
divsd %xmm3, %xmm2
movq 0x48(%rsp), %rax
movsd %xmm2, (%rax)
movsd 0xe654(%rip), %xmm2     # 0x18538
ucomisd %xmm12, %xmm2
jbe 0xa192
movapd %xmm11, %xmm0
cmplesd %xmm1, %xmm0
andpd %xmm0, %xmm11
andnpd %xmm1, %xmm0
orpd %xmm11, %xmm0
xorpd 0xe5c1(%rip), %xmm0     # 0x184d0
jmp 0xa1c3
movsd 0xe5e4(%rip), %xmm1     # 0x18500
movapd %xmm2, 0x30(%rsp)
movapd %xmm0, %xmm13
movapd %xmm2, %xmm0
addsd %xmm5, %xmm0
movapd %xmm10, %xmm3
subsd %xmm0, %xmm3
addsd %xmm0, %xmm0
movapd %xmm10, %xmm4
subsd %xmm0, %xmm4
addsd %xmm8, %xmm8
addsd %xmm9, %xmm8
addsd %xmm8, %xmm7
movapd %xmm6, %xmm9
addsd %xmm6, %xmm9
movapd %xmm9, %xmm0
mulsd %xmm4, %xmm0
movapd %xmm7, %xmm2
addsd %xmm7, %xmm2
subsd %xmm2, %xmm0
subsd %xmm13, %xmm0
mulsd %xmm7, %xmm4
movapd %xmm9, %xmm2
mulsd %xmm11, %xmm2
subsd %xmm4, %xmm2
mulsd %xmm13, %xmm3
subsd %xmm3, %xmm2
mulsd %xmm11, %xmm7
addsd %xmm9, %xmm9
movapd %xmm0, %xmm3
divsd %xmm9, %xmm3
movsd 0xe55a(%rip), %xmm4     # 0x18508
movapd %xmm3, %xmm8
divsd %xmm4, %xmm8
mulsd %xmm3, %xmm3
divsd 0xe54c(%rip), %xmm3     # 0x18510
mulsd %xmm9, %xmm4
movapd %xmm9, %xmm10
mulsd %xmm8, %xmm10
addsd %xmm0, %xmm10
mulsd %xmm8, %xmm10
addsd %xmm2, %xmm10
divsd %xmm4, %xmm2
addsd %xmm3, %xmm2
movsd 0xe526(%rip), %xmm0     # 0x18518
mulsd %xmm9, %xmm0
mulsd %xmm9, %xmm0
mulsd %xmm2, %xmm0
mulsd %xmm2, %xmm0
mulsd %xmm2, %xmm0
mulsd %xmm8, %xmm10
subsd %xmm7, %xmm10
movapd %xmm10, %xmm3
mulsd %xmm10, %xmm3
subsd %xmm0, %xmm3
ucomisd %xmm1, %xmm3
movapd %xmm5, 0x10(%rsp)
movapd %xmm11, 0x90(%rsp)
movapd %xmm8, 0x20(%rsp)
jbe 0xa1d2
xorps %xmm0, %xmm0
sqrtsd %xmm3, %xmm0
xorpd %xmm1, %xmm1
movapd %xmm3, 0x50(%rsp)
ucomisd %xmm1, %xmm3
movsd %xmm0, 0xb0(%rsp)
movapd %xmm10, 0x70(%rsp)
jae 0xa08e
movapd 0x50(%rsp), %xmm0
movsd %xmm9, 0x80(%rsp)
callq 0x4220
movapd 0x70(%rsp), %xmm10
movsd 0x80(%rsp), %xmm9
subsd %xmm10, %xmm0
addsd %xmm9, %xmm9
movsd %xmm9, 0x80(%rsp)
divsd %xmm9, %xmm0
callq 0x4070
movapd 0x20(%rsp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
movapd 0x50(%rsp), %xmm0
ucomisd 0xe47e(%rip), %xmm0     # 0x18548
movsd 0xb0(%rsp), %xmm1
jae 0xa0de
callq 0x4220
movapd %xmm0, %xmm1
movapd 0x70(%rsp), %xmm0
addsd %xmm1, %xmm0
xorpd 0xe3e0(%rip), %xmm0     # 0x184d0
divsd 0x80(%rsp), %xmm0
callq 0x4070
movapd 0x20(%rsp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, %xmm0
movapd 0x10(%rsp), %xmm5
movsd 0xe3c6(%rip), %xmm6     # 0x184e0
movapd 0x90(%rsp), %xmm7
subsd %xmm7, %xmm0
movapd %xmm6, %xmm2
subsd %xmm5, %xmm2
subsd 0x30(%rsp), %xmm6
movapd %xmm6, %xmm1
mulsd %xmm2, %xmm1
movapd %xmm0, %xmm3
mulsd %xmm0, %xmm3
movapd %xmm7, %xmm4
mulsd %xmm1, %xmm4
divsd %xmm4, %xmm3
movq 0x48(%rsp), %rax
movsd %xmm3, (%rax)
movsd 0xe3d6(%rip), %xmm3     # 0x18538
ucomisd %xmm0, %xmm3
jbe 0xa240
movapd %xmm7, %xmm2
cmplesd %xmm1, %xmm2
andpd %xmm2, %xmm7
andnpd %xmm1, %xmm2
orpd %xmm7, %xmm2
xorpd 0xe347(%rip), %xmm2     # 0x184d0
divsd %xmm2, %xmm0
jmp 0xa279
xorpd %xmm1, %xmm1
ucomisd 0xe3a1(%rip), %xmm12    # 0x18540
jbe 0x9e1f
mulsd %xmm10, %xmm5
mulsd %xmm0, %xmm4
movapd %xmm5, %xmm0
cmplesd %xmm4, %xmm0
andpd %xmm0, %xmm5
andnpd %xmm4, %xmm0
orpd %xmm5, %xmm0
divsd %xmm0, %xmm12
movapd %xmm12, %xmm1
jmp 0x9e1f
mulsd 0xe30d(%rip), %xmm13    # 0x184e8
addsd %xmm12, %xmm13
divsd %xmm6, %xmm12
addsd 0xe30a(%rip), %xmm12    # 0x184f8
divsd %xmm6, %xmm13
addsd %xmm1, %xmm13
movsd 0xe2f8(%rip), %xmm1     # 0x184f8
ucomisd %xmm3, %xmm1
movapd %xmm13, 0x60(%rsp)
movapd %xmm12, 0x80(%rsp)
jbe 0xa282
movsd %xmm2, 0xb0(%rsp)
xorpd 0xe2a7(%rip), %xmm10    # 0x184d0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xa357
sqrtsd %xmm0, %xmm0
jmp 0xa36a
xorpd %xmm1, %xmm1
ucomisd 0xe2f4(%rip), %xmm0     # 0x18540
jbe 0x9e1f
mulsd %xmm6, %xmm5
movapd 0x30(%rsp), %xmm3
mulsd %xmm2, %xmm3
movapd %xmm5, %xmm1
cmplesd %xmm3, %xmm1
andpd %xmm1, %xmm5
andnpd %xmm3, %xmm1
orpd %xmm5, %xmm1
divsd %xmm1, %xmm0
movapd %xmm0, %xmm1
jmp 0x9e1f
addsd %xmm9, %xmm9
divsd %xmm9, %xmm10
movapd %xmm10, %xmm0
callq 0x4070
movapd 0x60(%rsp), %xmm4
movapd 0x20(%rsp), %xmm2
movapd %xmm2, %xmm1
addsd %xmm0, %xmm1
addsd %xmm0, %xmm0
subsd %xmm0, %xmm2
movapd %xmm2, %xmm0
movapd 0x80(%rsp), %xmm5
ucomisd %xmm1, %xmm5
movapd %xmm4, %xmm2
cmpltpd %xmm0, %xmm2
movapd %xmm0, %xmm3
cmpltpd %xmm5, %xmm3
orpd %xmm2, %xmm3
movd %xmm3, %eax
ja 0xa333
ucomisd %xmm4, %xmm1
ja 0xa333
testb $0x1, %al
movapd 0x10(%rsp), %xmm5
movsd 0xe1eb(%rip), %xmm6     # 0x184e0
movapd 0x90(%rsp), %xmm7
jne 0xa560
movapd %xmm1, %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
movapd %xmm7, %xmm3
unpcklpd %xmm7, %xmm3            # xmm3 = xmm3[0],xmm7[0]
subpd %xmm3, %xmm2
andpd 0xe1a0(%rip), %xmm2     # 0x184c0
pshufd $0xee, %xmm2, %xmm3     # xmm3 = xmm2[2,3,2,3]
cmplesd %xmm3, %xmm2
andpd %xmm2, %xmm1
jmp 0xa513
testb $0x1, %al
movapd 0x10(%rsp), %xmm5
movsd 0xe19d(%rip), %xmm6     # 0x184e0
movapd 0x90(%rsp), %xmm7
jne 0x9e05
jmp 0xa123
movapd %xmm10, 0x70(%rsp)
callq 0x4220
movapd 0x70(%rsp), %xmm10
divsd %xmm0, %xmm10
movapd %xmm10, %xmm0
callq 0x4280
divsd 0xe19f(%rip), %xmm0     # 0x18520
movsd %xmm0, 0x50(%rsp)
movsd 0xb0(%rsp), %xmm0
ucomisd 0xe1b0(%rip), %xmm0     # 0x18548
jb 0xa3a0
sqrtsd %xmm0, %xmm0
jmp 0xa3a5
callq 0x4220
addsd %xmm0, %xmm0
movapd %xmm0, 0x70(%rsp)
movsd 0x50(%rsp), %xmm0
callq 0x4520
mulsd 0x70(%rsp), %xmm0
addsd 0x20(%rsp), %xmm0
movapd %xmm0, 0xb0(%rsp)
movsd 0xe151(%rip), %xmm0     # 0x18528
addsd 0x50(%rsp), %xmm0
callq 0x4520
movapd %xmm0, 0xa0(%rsp)
movsd 0x50(%rsp), %xmm0
addsd 0xe137(%rip), %xmm0     # 0x18530
callq 0x4520
movapd 0xb0(%rsp), %xmm8
movapd 0x20(%rsp), %xmm4
movapd 0x70(%rsp), %xmm1
unpcklpd %xmm1, %xmm1            # xmm1 = xmm1[0,0]
movapd 0xa0(%rsp), %xmm2
unpcklpd %xmm0, %xmm2            # xmm2 = xmm2[0],xmm0[0]
mulpd %xmm1, %xmm2
unpcklpd %xmm4, %xmm4            # xmm4 = xmm4[0,0]
addpd %xmm2, %xmm4
movapd 0x80(%rsp), %xmm5
ucomisd %xmm8, %xmm5
movapd 0x60(%rsp), %xmm3
movapd %xmm3, %xmm0
cmpltpd %xmm4, %xmm0
movapd %xmm4, %xmm1
cmpltpd %xmm5, %xmm1
orpd %xmm0, %xmm1
movd %xmm1, %ecx
movapd %xmm4, %xmm0
unpckhpd %xmm4, %xmm0            # xmm0 = xmm0[1],xmm4[1]
movapd %xmm3, %xmm1
cmpltpd %xmm0, %xmm1
movapd %xmm0, %xmm2
cmpltpd %xmm5, %xmm2
orpd %xmm1, %xmm2
movd %xmm2, %eax
ja 0xa4b8
ucomisd %xmm3, %xmm8
ja 0xa4b8
testb $0x1, %cl
movapd 0x10(%rsp), %xmm5
movsd 0xe045(%rip), %xmm6     # 0x184e0
movapd 0x90(%rsp), %xmm7
je 0xa524
testb $0x1, %al
je 0xa569
movapd %xmm8, %xmm0
jmp 0xa123
testb $0x1, %cl
movapd 0x10(%rsp), %xmm5
movsd 0xe017(%rip), %xmm6     # 0x184e0
movapd 0x90(%rsp), %xmm7
je 0xa4e1
testb $0x1, %al
jne 0x9e05
jmp 0xa123
testb $0x1, %al
jne 0xa5c2
movapd %xmm7, %xmm1
unpcklpd %xmm7, %xmm1            # xmm1 = xmm1[0],xmm7[0]
movapd %xmm4, %xmm2
subpd %xmm1, %xmm2
andpd 0xdfbf(%rip), %xmm2     # 0x184c0
pshufd $0xee, %xmm2, %xmm1     # xmm1 = xmm2[2,3,2,3]
cmplesd %xmm1, %xmm2
movapd %xmm2, %xmm1
andpd %xmm4, %xmm1
andnpd %xmm0, %xmm2
orpd %xmm1, %xmm2
movapd %xmm2, %xmm0
jmp 0xa123
movapd %xmm4, %xmm1
unpcklpd %xmm8, %xmm1            # xmm1 = xmm1[0],xmm8[0]
movapd %xmm7, %xmm2
unpcklpd %xmm7, %xmm2            # xmm2 = xmm2[0],xmm7[0]
subpd %xmm2, %xmm1
andpd 0xdf7f(%rip), %xmm1     # 0x184c0
pshufd $0xee, %xmm1, %xmm3     # xmm3 = xmm1[2,3,2,3]
cmplesd %xmm3, %xmm1
movapd %xmm1, %xmm3
andpd %xmm4, %xmm3
andnpd %xmm8, %xmm1
orpd %xmm3, %xmm1
testb $0x1, %al
je 0xa59c
movapd %xmm1, %xmm0
jmp 0xa123
movsd %xmm8, %xmm4            # xmm4 = xmm8[0],xmm4[1]
movapd %xmm7, %xmm1
unpcklpd %xmm7, %xmm1            # xmm1 = xmm1[0],xmm7[0]
subpd %xmm1, %xmm4
andpd 0xdf3e(%rip), %xmm4     # 0x184c0
pshufd $0xee, %xmm4, %xmm1     # xmm1 = xmm4[2,3,2,3]
cmplesd %xmm1, %xmm4
andpd %xmm4, %xmm8
andnpd %xmm0, %xmm4
orpd %xmm8, %xmm4
jmp 0xa5c2
movsd %xmm1, %xmm4            # xmm4 = xmm1[0],xmm4[1]
subpd %xmm2, %xmm4
andpd 0xdf14(%rip), %xmm4     # 0x184c0
pshufd $0xee, %xmm4, %xmm2     # xmm2 = xmm4[2,3,2,3]
cmplesd %xmm2, %xmm4
andpd %xmm4, %xmm1
andnpd %xmm0, %xmm4
orpd %xmm1, %xmm4
movapd %xmm4, %xmm0
jmp 0xa123
leaq 0xe946(%rip), %rdi      # 0x18f18
callq 0x43e0
nop