// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/arlib/stringconv-float.cpp
// Function: fromstring_float(cstring, double&, floatinf const*)
static bool fromstring_float(cstring s, double& out, const floatinf * fi)
{
	out = 0;
	
	const char * start = (const char*)s.bytes().ptr();
	const char * end = start + s.length();
	const char * digits_end = end;
	if (end-start > 10000) return false; // 0.(9999 zeroes)1e+10000 is technically equal to 1, but it's also stupid.
	// TODO: should allow it anyways
	
	bool neg = false;
	if (start < end && *start == '-')
	{
		neg = true;
		start++;
	}
	
	if (UNLIKELY(!isdigit(*start) || start==end))
	{
		if (s == "inf") { out = HUGE_VAL; return true; }
		if (s == "-inf") { out = -HUGE_VAL; return true; }
		if (s == "nan") { out = NAN; return true; }
		return false;
	}
	
	const char * iter = start;
	
	int exponent = INT_MAX;
	uint64_t significand = 0;
	uint64_t significand_sum = 0;
	int n_digits = 0;
	
	while (true)
	{
		if ((uint8_t)(*iter-'0') <= 9)
		{
			significand *= 10;
			significand += *iter-'0';
			significand_sum |= significand; // make it sticky, so input 2^64 doesn't overflow significand back to zero
			exponent--;
			n_digits++;
		}
		else if (*iter == '.')
		{
			if (exponent <= 0) return false;
			if (iter == end || !isdigit(iter[1])) return false;
			exponent = 0;
		}
		else if ((0x20|*iter) == 'e')
		{
			digits_end = iter;
			if (exponent > 0) exponent = 0;
			iter++;
			
			bool exp_neg = false;
			if (*iter == '-') { exp_neg = true; iter++; }
			else if (*iter == '+') iter++;
			
			uint32_t newexp = 0;
			uint32_t newexp_sum = 0;
			if (iter == end) return false;
			while (iter < end)
			{
				if (UNLIKELY((uint8_t)(*iter-'0') > 9)) return false;
				newexp = newexp*10 + *iter-'0';
				newexp_sum |= newexp; // another sticky
				iter++;
			}
			if (newexp_sum >= 16384)
			{
				// if the exponent is crazy, ignore the digits; it's either zero or infinite
				if (!exp_neg && significand_sum != 0) out = HUGE_VAL;
				if (neg) out = -out;
				if (out == 0) return true;
				return false;
			}
			if (exp_neg) exponent -= newexp;
			else exponent += newexp;
			break;
		}
		else return false;
		iter++;
		if (iter == end)
		{
			if (exponent > 0) exponent = 0;
			break;
		}
	}
	
	// for small numbers, the correct answer can be calculated with a multiplication or division of two float-representable integers
	// there are some numbers where the mul or div rounds to exactly halfway between two floats, but to my knowledge,
	//  they all have significand or exponent out of range for floats and need the slow path
	// same may happen on i386 if fpcw is set to float80 rather than float64; I did not investigate this either
	if (LIKELY(abs(exponent) <= fi->max_int_exp && significand <= fi->max_sig && n_digits < ilog10(UINT64_MAX)))
	{
		bool neg_exp = (exponent < 0);
		exponent = abs(exponent);
		
		double exp_adjust = 1;
		if (exponent & 1) exp_adjust *= 10.0;
		if (exponent & 2) exp_adjust *= 100.0;
		if (exponent & 4) exp_adjust *= 10000.0;
		if (exponent & 8) exp_adjust *= 100000000.0;
		if (exponent & 16) exp_adjust *= 10000000000000000.0;
		
		double ret;
		if (!neg_exp)
			ret = (double)significand * exp_adjust;
		else
			ret = (double)significand / exp_adjust;
		if (neg) out = -ret;
		else out = ret;
		return true;
	}
	
	// for large numbers, use a slower algorithm
	// some float parser implementations have three different algorithms with different speed and limitations, but two's enough for me
	
	if (significand_sum == 0) // 0e+999 will go here, as will 0.000000000000000000000000 (it exceeds n_digits)
	{
		if (neg) out = -out;
		return true;
	}
	// inputs:
	// - start .. digits_end - digits of the input. The dot, if any, should be ignored.
	//    Contains at least one nonzero digit. Contains nothing but digits and the dot.
	// - exponent - Number of steps to shift the given digits.
	// - n_digits - Number of digits, though some may be leading or trailing zeroes. Not useful anymore.
	// - neg - Whether the input is negative.
	// - fi - Information about the float format.
	// Other variables should be ignored or discarded.
	
	// the digits need to be multiplied or divided such that the exponent is zero, then take the leftmost bits
	// for subnormals, the number of digits to round to is variable
	
	iter = start;
	while (*iter <= '0') iter++; // the only possible non-digit, ., is 0x2E <= '0' (0x30), and there's known to be a nonzero digit
	
	uint32_t limbs[100] = {}; // the traditional implementation is u8[800], but that's just wasteful. better pack eight digits in a u32
	// 9 would fit, but 8 makes the math easier
	// I could count how many limbs I'm using, but that'd be a lot more complexity for no reasonable benefit
	
	int limb_at = 0;
	uint32_t tmp = 0;
	while (limb_at < 800 && iter < digits_end)
	{
		if (*iter == '.') { iter++; continue; }
		tmp = tmp*10 + *iter-'0';
		if (limb_at%8 == 7)
		{
			limbs[limb_at/8] = tmp;
			tmp = 0;
		}
		limb_at++;
		iter++;
	}
	exponent += limb_at;
	if (tmp)
	{
		if ((8-limb_at)&4) tmp *= 10000;
		if ((8-limb_at)&2) tmp *= 100;
		if ((8-limb_at)&1) tmp *= 10;
		limbs[limb_at/8] = tmp;
	}
	
	while (iter < digits_end)
	{
		if (*iter > '0') limbs[99] |= 1; // some algorithms maintain an 'is truncated' bit, but it's easier to round up
		iter++;
		if (*iter != '.') exponent++;
	}
	
	// at the end of this process, I need
	// - limbs[0] concat limbs[1] concat limbs[2]/1000000 to be the output bits of the double
	// - limbs[0] >= 20000000
	// - every limb <= 99999999
	// - bin_exponent to tell how many bits it was shifted
	// min     4503599627370496
	// max 18446744073709551616
	// if output is 10.0, the limbs must be 10 << n such that 10<<n >= 200000000000000000, <= 999999999999999999
	// there two allowed limb values are
	// n=56 72057594 03792793 60+000000
	// n=55 36028797 01896396 80+000000
	// same limbs for 5, 20, 40, 80, 160, etc, just different bin_exponent
	
	int bin_exponent = 0;
	
	exponent -= 18; // need 18 decimal digits of mantissa
	if (exponent & 7)
	{
		// first limb is known >= 10000000, so multiplying by any power of ten will make it overflow and require shifting the limbs
		
		uint64_t mul = 1;
		if (exponent&4) mul *= 10000;
		if (exponent&2) mul *= 100;
		if (exponent&1) mul *= 10;
		exponent &= ~7;
		exponent += 8;
		
		uint64_t carry = 0;
		for (int i=0;i<100;i++)
		{
			uint64_t cur = carry + limbs[i]*mul;
			limbs[i] = cur/100000000;
			carry = cur%100000000*100000000;
		}
		if (carry) limbs[99] |= 1; // sticky overflow
	}
	
	// the top limb must be nonzero at all times
	while (true)
	{
		if (exponent > 0)
		{
			// divide by the smallest power of 2 that zeroes the top limb, and multiply by 1e8 (shift the limbs one step)
			int shift_bits = ilog2(limbs[0])+1;
			bin_exponent += shift_bits;
			exponent -= 8;
			
			uint32_t carry_mask = (1<<shift_bits)-1;
			
			// 64bit multiplication and division everywhere... sucks for 32bit cpus
			// I could change it to uint16[200], but not much point. 32bit is on its way out
			uint64_t carry = limbs[0]; // carry is NOT divided by shift_bits
			for (int i=1;i<100;i++)
			{
				uint64_t cur = (uint64_t)limbs[i] + carry*100000000;
				limbs[i-1] = cur >> shift_bits;
				carry = cur & carry_mask;
			}
			limbs[99] = carry; // this is too much, but it won't affect the result
		}
		else if (exponent < 0 && limbs[0] >= 2)
		{
			// multiply by 1<<26, and divide by 1e8
			int shift_bits = 26;
			bin_exponent -= shift_bits;
			exponent += 8;
			
			uint64_t cur = ((uint64_t)limbs[99] << shift_bits);
			
			uint64_t carry = cur/100000000 | (cur%100000000 ? 1 : 0);
			for (int i=98;i>=0;i--)
			{
				uint64_t cur = ((uint64_t)limbs[i] << shift_bits) + carry;
				limbs[i+1] = cur%100000000;
				carry = cur/100000000;
			}
			limbs[0] = carry;
		}
		else if (limbs[0] < 20000000)
		{
			// multiply by a low power of 2 so the top limb goes a bit higher
			int shift_bits = 25-ilog2(limbs[0]);
			bin_exponent -= shift_bits;
			
			uint64_t carry = 0;
			for (int i=99;i>=0;i--)
			{
				uint64_t cur = ((uint64_t)limbs[i] << shift_bits) + carry;
				limbs[i] = cur%100000000;
				carry = cur/100000000;
			}
		}
		else break;
	}
	
	bool ret = true;
	
	uint64_t mantissa = (uint64_t)limbs[0]*10000000000 + (uint64_t)limbs[1]*100 + limbs[2]/1000000;
	if (mantissa == 0)
		goto done;
	
	{
		int error = 60-ilog2(mantissa);
		mantissa <<= error;
		bin_exponent -= error;
	}
	
	if (bin_exponent+1023+60-1 <= -60) // too small, round to zero
		goto done;
	
	{
		uint64_t prev_mantissa = mantissa;
		int shift = 0;
		if (bin_exponent+1023+60-1 < 0)
		{
			shift = -(bin_exponent+1023+60-1);
		}
		if (fi->bits_mantissa != 52)
		{
			if (bin_exponent+209 <= 23)
				shift = 52-(bin_exponent+209);
			else
				shift = 52-23;
		}
		
		mantissa >>= shift;
		bin_exponent += shift;
		
		if (mantissa << shift != prev_mantissa)
			mantissa |= 1;
	}
	
	// if it's at least halfway to next number,
	if (mantissa & 0x80)
	{
		// and if bottom bit of output mantissa is set, any bit below half-mantissa is set,
		// or if any bit in the limbs outside the mantissa is set,
		// then round up (bits below that will be discarded)
		if ((mantissa & 0x017F) || limbs[2]%1000000)
		{
			mantissa += 0x80;
		}
		else
		{
			for (int i=3;i<100;i++)
			{
				if (limbs[i])
				{
					mantissa += 0x80;
					break;
				}
			}
		}
	}
	
	{
		int error = 61-ilog2(mantissa); // it's probably same power of two as last time, but not guaranteed; must renormalize
		mantissa <<= error;
		bin_exponent -= error;
	}
	
	if (bin_exponent+1023+61 <= 0) // subnormal (or rounded to zero)
	{
		mantissa >>= -(bin_exponent+1023+61);
		out = reinterpret<double>(mantissa>>10);
	}
	else if (bin_exponent >= fi->max_bin_exp) // infinite
	{
		out = HUGE_VAL;
		ret = false;
	}
	else // normal (or subnormal float - the double/float cast will handle that)
	{
		out = reinterpret<double>(((uint64_t)(bin_exponent+1023+61)<<52) | (mantissa<<3>>12));
	}
	
done:
	if (neg) out = -out;
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rcx, %r14
movq %rdx, %rbx
movq %rdi, %r15
leaq 0x10(%rsp), %rdx
movq %rdi, (%rdx)
movq %rsi, 0x8(%rdx)
movq $0x0, (%rbx)
movzbl 0xf(%rdx), %eax
movl %eax, %ecx
xorl $0xf, %ecx
testb %al, %al
cmovnsq %rdx, %r15
cmovsl 0x8(%rdx), %ecx
cmpl $0x2710, %ecx           # imm = 0x2710
jbe 0x1adf0
xorl %eax, %eax
jmp 0x1af4f
xorl %r12d, %r12d
testl %ecx, %ecx
je 0x1ae07
cmpb $0x2d, (%r15)
sete %r12b
movq %r12, %r13
addq %r15, %r13
jmp 0x1ae0a
movq %r15, %r13
movzbl (%r13), %edx
leaq 0x14efa(%rip), %r8      # 0x2fd10
testb $0x40, (%r8,%rdx)
je 0x1b0ed
addq %rcx, %r15
cmpq %r15, %r13
je 0x1b0ed
leaq 0x1(%r13), %rdi
movl $0x7fffffff, %r9d       # imm = 0x7FFFFFFF
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
movsbl -0x1(%rdi), %eax
movslq %eax, %r10
addq $-0x30, %r10
movl %r10d, %r11d
andl $0xfe, %r11d
cmpl $0x9, %r11d
ja 0x1ae6a
leaq (%rcx,%rcx,4), %rax
leaq (%r10,%rax,2), %rcx
orq %rcx, %rdx
decl %r9d
incl %esi
jmp 0x1ae8f
cmpb $0x2e, %al
jne 0x1af63
xorl %eax, %eax
testl %r9d, %r9d
jle 0x1af4f
movzbl (%rdi), %r9d
testb $0x40, (%r8,%r9)
je 0x1af4f
xorl %r9d, %r9d
leaq 0x1(%rdi), %rax
cmpq %r15, %rdi
movq %rax, %rdi
jne 0x1ae3d
movl %r9d, %ebp
sarl $0x1f, %ebp
andl %r9d, %ebp
movl %ebp, %eax
negl %eax
cmovsl %ebp, %eax
movzbl 0x8(%r14), %edi
cmpl %edi, %eax
ja 0x1b055
cmpq (%r14), %rcx
ja 0x1b055
cmpl $0x12, %esi
jg 0x1b055
xorl %edx, %edx
testb $0x1, %al
sete %dl
leaq 0x14f48(%rip), %rsi     # 0x2fe20
movsd (%rsi,%rdx,8), %xmm0
testb $0x2, %al
je 0x1aee9
mulsd 0x14f87(%rip), %xmm0    # 0x2fe70
testb $0x4, %al
je 0x1aef5
mulsd 0x14f83(%rip), %xmm0    # 0x2fe78
testb $0x8, %al
je 0x1af01
mulsd 0x14f7f(%rip), %xmm0    # 0x2fe80
testb $0x10, %al
je 0x1af0d
mulsd 0x14f7b(%rip), %xmm0    # 0x2fe88
movq %rcx, %xmm2
punpckldq 0x14f16(%rip), %xmm2 # xmm2 = xmm2[0],mem[0],xmm2[1],mem[1]
subpd 0x14f1e(%rip), %xmm2    # 0x2fe40
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
testl %ebp, %ebp
js 0x1af38
mulsd %xmm0, %xmm1
jmp 0x1af3c
divsd %xmm0, %xmm1
testb %r12b, %r12b
je 0x1af49
xorpd 0x14ec7(%rip), %xmm1    # 0x2fe10
movsd %xmm1, (%rbx)
movb $0x1, %al
andb $0x1, %al
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $-0x21, %eax
cmpl $0x45, %eax
jne 0x1ade9
movl %r9d, %ebp
sarl $0x1f, %ebp
andl %r9d, %ebp
movb (%rdi), %al
leaq 0x1(%rdi), %r8
cmpb $0x2b, %al
movq %rdi, %r9
cmoveq %r8, %r9
cmpb $0x2d, %al
cmoveq %r8, %r9
xorl %r8d, %r8d
cmpq %r15, %r9
je 0x1b02b
movl $0x0, %r10d
jae 0x1afe5
movq %r14, 0x8(%rsp)
xorl %r8d, %r8d
xorl %r10d, %r10d
movzbl (%r9), %r11d
leal -0x3a(%r11), %r14d
cmpb $-0xa, %r14b
jb 0x1b10d
leal (%r8,%r8,4), %r8d
leal (%r11,%r8,2), %r8d
addl $-0x30, %r8d
orl %r8d, %r10d
incq %r9
cmpq %r15, %r9
jb 0x1afac
cmpl $0x4000, %r10d          # imm = 0x4000
setae %r10b
movq 0x8(%rsp), %r14
testb %r10b, %r10b
je 0x1b02f
cmpb $0x2d, %al
je 0x1b000
testq %rdx, %rdx
je 0x1b000
movabsq $0x7ff0000000000000, %rax # imm = 0x7FF0000000000000
movq %rax, (%rbx)
testb %r12b, %r12b
je 0x1b015
movsd (%rbx), %xmm0
xorpd 0x14dff(%rip), %xmm0    # 0x2fe10
movlpd %xmm0, (%rbx)
xorpd %xmm0, %xmm0
cmpeqsd (%rbx), %xmm0
movq %xmm0, %rax
andl $0x1, %eax
xorl %r8d, %r8d
jmp 0x1b041
xorl %eax, %eax
jmp 0x1b041
movl %r8d, %r9d
negl %r9d
cmpb $0x2d, %al
cmovnel %r8d, %r9d
addl %r9d, %ebp
movb $0x1, %r8b
testb %r8b, %r8b
je 0x1af4f
decq %rdi
movq %rdi, %r15
jmp 0x1aea4
testq %rdx, %rdx
je 0x1b11c
decq %r13
cmpb $0x31, 0x1(%r13)
leaq 0x1(%r13), %r13
jl 0x1b061
leaq 0x20(%rsp), %rdi
movl $0x190, %edx            # imm = 0x190
xorl %esi, %esi
callq 0x3170
cmpq %r15, %r13
movq %r14, 0x8(%rsp)
jae 0x1b123
xorl %ecx, %ecx
movb $0x1, %sil
xorl %edx, %edx
movq %r13, %rax
movsbl (%rax), %edi
cmpl $0x2e, %edi
jne 0x1b0ae
incq %rax
cmpq %r15, %rax
setb %dil
testb %dil, %sil
jne 0x1b095
jmp 0x1b12d
leal (%rcx,%rcx,4), %ecx
leal (%rdi,%rcx,2), %ecx
addl $-0x30, %ecx
movl %edx, %esi
notl %esi
testb $0x7, %sil
jne 0x1b0cc
movl %edx, %esi
shrl $0x3, %esi
movl %ecx, 0x20(%rsp,%rsi,4)
xorl %ecx, %ecx
leal 0x1(%rdx), %r9d
cmpl $0x31f, %edx            # imm = 0x31F
setb %sil
jae 0x1b0e8
leaq 0x1(%rax), %r13
movl %r9d, %edx
cmpq %r15, %r13
jb 0x1b092
incq %rax
jmp 0x1b130
movzbl %al, %edi
leaq 0x10(%rsp), %rsi
leaq 0x20(%rsp), %r14
movq %rbx, %rdx
movq %r14, %rcx
callq 0x3d06
movb (%r14), %al
jmp 0x1af4f
xorl %r8d, %r8d
xorl %eax, %eax
movq 0x8(%rsp), %r14
jmp 0x1b041
movb $0x1, %al
jmp 0x1b4c6
xorl %ecx, %ecx
movq %r13, %rax
xorl %r9d, %r9d
jmp 0x1b130
movl %edx, %r9d
testl %ecx, %ecx
je 0x1b172
movl $0x8, %edx
subl %r9d, %edx
imull $0x2710, %ecx, %esi     # imm = 0x2710
testb $0x4, %dl
cmovel %ecx, %esi
imull $0x64, %esi, %ecx
testb $0x2, %dl
cmovel %esi, %ecx
leal (%rcx,%rcx), %esi
testb $0x1, %dl
leal (%rsi,%rsi,4), %edx
cmovel %ecx, %edx
leal 0x7(%r9), %ecx
testl %r9d, %r9d
cmovnsl %r9d, %ecx
sarl $0x3, %ecx
movslq %ecx, %rcx
movl %edx, 0x20(%rsp,%rcx,4)
addl %ebp, %r9d
cmpq %r15, %rax
jae 0x1b1ac
movl 0x1ac(%rsp), %ecx
subq %rax, %r15
xorl %edx, %edx
cmpb $0x31, (%rax,%rdx)
jl 0x1b196
orl $0x1, %ecx
movl %ecx, 0x1ac(%rsp)
xorl %esi, %esi
cmpb $0x2e, 0x1(%rax,%rdx)
setne %sil
addl %esi, %r9d
incq %rdx
cmpq %rdx, %r15
jne 0x1b186
leal -0x12(%r9), %edi
movabsq $-0x543388ee7b9e3103, %r8 # imm = 0xABCC77118461CEFD
testb $0x7, %dil
je 0x1b23a
testb $0x4, %dil
movl $0x1, %eax
movl $0x2710, %ecx           # imm = 0x2710
cmoveq %rax, %rcx
imulq $0x64, %rcx, %rax
testb $0x2, %dil
cmoveq %rcx, %rax
leal (%rax,%rax), %ecx
testb $0x1, %r9b
leaq (%rcx,%rcx,4), %rsi
cmoveq %rax, %rsi
andl $-0x8, %edi
xorl %r9d, %r9d
xorl %eax, %eax
movl 0x20(%rsp,%r9,4), %ecx
imulq %rsi, %rcx
addq %rax, %rcx
movq %rcx, %rax
mulq %r8
shrq $0x1a, %rdx
movl %edx, 0x20(%rsp,%r9,4)
imulq $0x5f5e100, %rdx, %rax  # imm = 0x5F5E100
subq %rax, %rcx
imulq $0x5f5e100, %rcx, %rax  # imm = 0x5F5E100
incq %r9
cmpq $0x64, %r9
jne 0x1b1f5
addl $0x8, %edi
testq %rcx, %rcx
je 0x1b23a
orb $0x1, 0x1ac(%rsp)
xorl %r9d, %r9d
movabsq $0xabcc77118461cf, %r10 # imm = 0xABCC77118461CF
movabsq $0x2c8ba43884000000, %r11 # imm = 0x2C8BA43884000000
movabsq $0x2af31dc461, %r15     # imm = 0x2AF31DC461
testl %edi, %edi
jg 0x1b2c1
setne %cl
movl 0x20(%rsp), %eax
cmpl $0x2, %eax
setae %dl
andb %cl, %dl
cmpb $0x1, %dl
je 0x1b31c
movl %eax, %eax
cmpl $0x1312cff, %eax        # imm = 0x1312CFF
ja 0x1b383
bsrl %eax, %ecx
notl %ecx
addl $0x1a, %ecx
movl $0x63, %r13d
xorl %edx, %edx
movl 0x20(%rsp,%r13,4), %esi
shlq %cl, %rsi
addq %rdx, %rsi
movq %rsi, %rax
mulq %r8
shrq $0x1a, %rdx
imull $0x5f5e100, %edx, %eax  # imm = 0x5F5E100
subl %eax, %esi
movl %esi, 0x20(%rsp,%r13,4)
addq $-0x1, %r13
jb 0x1b294
subl %ecx, %r9d
jmp 0x1b25b
movl 0x20(%rsp), %eax
bsrl %eax, %ecx
xorl $0x1f, %ecx
movb $0x20, %sil
subb %cl, %sil
negb %cl
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
shll %cl, %edx
movzbl %sil, %ecx
addl %ecx, %r9d
notl %edx
movl $0x1, %esi
movl 0x20(%rsp,%rsi,4), %r14d
imulq $0x5f5e100, %rax, %rax  # imm = 0x5F5E100
addq %r14, %rax
movq %rax, %r14
shrq %cl, %r14
movl %r14d, 0x1c(%rsp,%rsi,4)
andl %edx, %eax
incq %rsi
cmpq $0x64, %rsi
jne 0x1b2e8
addl $-0x8, %edi
movl %eax, 0x1ac(%rsp)
jmp 0x1b25b
movl 0x1ac(%rsp), %ecx
movq %rcx, %rax
shlq $0x1a, %rax
mulq %r10
movq %rdx, %rax
addl $-0x1a, %r9d
shrq $0x12, %rax
imulq %r11, %rcx
rorq $0x8, %rcx
xorl %edx, %edx
cmpq %r15, %rcx
seta %dl
orq %rax, %rdx
movl $0x18c, %esi            # imm = 0x18C
movl 0x1c(%rsp,%rsi), %ecx
shlq $0x1a, %rcx
addq %rdx, %rcx
movq %rcx, %rax
mulq %r8
shrq $0x1a, %rdx
imull $0x5f5e100, %edx, %eax  # imm = 0x5F5E100
subl %eax, %ecx
movl %ecx, 0x20(%rsp,%rsi)
addq $-0x4, %rsi
jne 0x1b350
addl $0x8, %edi
movl %edx, 0x20(%rsp)
jmp 0x1b25b
movabsq $0x2540be400, %rcx      # imm = 0x2540BE400
imulq %rcx, %rax
movl 0x24(%rsp), %ecx
movl 0x28(%rsp), %edi
imulq $0x64, %rcx, %r10
addq %rax, %r10
imulq $0x431bde83, %rdi, %r8  # imm = 0x431BDE83
shrq $0x32, %r8
movb $0x1, %al
addq %r8, %r10
je 0x1b4c6
bsrq %r10, %rcx
notl %ecx
addl $0x3d, %ecx
subl %ecx, %r9d
cmpl $0xfffffb8b, %r9d       # imm = 0xFFFFFB8B
jl 0x1b4c6
leal 0x43a(%r9), %edx
negl %edx
xorl %esi, %esi
cmpl $0xfffffbc6, %r9d       # imm = 0xFFFFFBC6
cmovll %edx, %esi
shlq %cl, %r10
movl $0xffffff63, %edx       # imm = 0xFFFFFF63
subl %r9d, %edx
cmpl $0xffffff47, %r9d       # imm = 0xFFFFFF47
movl $0x1d, %ecx
cmovll %edx, %ecx
movq 0x8(%rsp), %rdx
cmpb $0x34, 0x9(%rdx)
cmovel %esi, %ecx
movq %r10, %r11
shrq %cl, %r11
movl %ecx, %edx
addl %r9d, %edx
movq %r11, %r9
shlq %cl, %r9
xorl %esi, %esi
cmpq %r10, %r9
setne %sil
orq %r11, %rsi
testb %r11b, %r11b
jns 0x1b45c
imull $0xf4240, %r8d, %ecx    # imm = 0xF4240
subl %ecx, %edi
jne 0x1b458
movl %esi, %ecx
andl $0x17f, %ecx            # imm = 0x17F
jne 0x1b458
movl $0x3, %ecx
cmpl $0x0, 0x20(%rsp,%rcx,4)
jne 0x1b458
incq %rcx
cmpq $0x64, %rcx
jne 0x1b446
jmp 0x1b45c
subq $-0x80, %rsi
bsrq %rsi, %rcx
movl %ecx, %edi
notb %cl
addb $0x3e, %cl
shlq %cl, %rsi
xorl $0x3f, %edi
subl %edi, %edx
leal 0x2(%rdx), %ecx
cmpl $0xfffffbc4, %ecx       # imm = 0xFFFFFBC4
jg 0x1b48a
movb $-0x3e, %cl
subb %dl, %cl
shrq %cl, %rsi
shrq $0xa, %rsi
movq %rsi, (%rbx)
jmp 0x1b4c6
movq 0x8(%rsp), %rdi
cmpl 0xc(%rdi), %ecx
jge 0x1b4b7
addl $0x43e, %edx            # imm = 0x43E
shlq $0x34, %rdx
shrq $0x9, %rsi
movabsq $0xfffffffffffff, %rcx  # imm = 0xFFFFFFFFFFFFF
andq %rsi, %rcx
orq %rdx, %rcx
movq %rcx, (%rbx)
jmp 0x1b4c6
movabsq $0x7ff0000000000000, %rax # imm = 0x7FF0000000000000
movq %rax, (%rbx)
xorl %eax, %eax
testb %r12b, %r12b
je 0x1af4f
movsd (%rbx), %xmm0
xorpd 0x14935(%rip), %xmm0    # 0x2fe10
movlpd %xmm0, (%rbx)
jmp 0x1af4f