// File: /workspace/github_c_makefile_star2_O0/cyb70289[P]tt/src/apn/decimal/mach.c
// Function: tt_dec_to_float
int tt_dec_to_float(const struct tt_dec *dec, double *num)
{
	int ret = 0;
	union {
		uint64_t i;
		double d;
	} v;
	struct tt_dec *dec_mm = NULL;

	/* Check zero */
	if (_tt_dec_is_zero(dec)) {
		v.i = 0;
		goto out;
	}

	/* Check NaN, Inf */
	if (dec->_inf_nan == TT_DEC_INF) {
		v.i = 2047ULL << 52;    /* Inf */
		ret = TT_APN_EOVERFLOW;
		goto out;
	} else if (dec->_inf_nan == TT_DEC_NAN) {
		v.i = (2047ULL << 52) | ((1ULL << 52) - 1);
		ret = TT_APN_EINVAL;
		goto out;
	}

	dec_mm = tt_dec_alloc(0);

	/* Check overflow */
	v.i = (2046ULL << 52) | ((1ULL << 52) - 1);	/* Max double */
	tt_dec_from_float(dec_mm, v.d);
	if (tt_dec_cmp_abs(dec, dec_mm) >= 0) {
		v.i = 2047ULL << 52;	/* Inf */
		ret = TT_APN_EOVERFLOW;
		tt_warn("Float overflow");
		goto out;
	}

	/* Check underflow
	 * XXX: Unnormalized double bound may cause underrun in the div loop.
	 */
#if 1
	v.i = 1;		/* Unnormalized, 4.94E-324 */
#else
	v.i = 1ULL << 52;	/* Normalized, 2.22E-308 */
#endif
	tt_dec_from_float(dec_mm, v.d);
	if (tt_dec_cmp_abs(dec_mm, dec) >= 0) {
		v.i = 0;
		ret = TT_APN_EUNDERFLOW;
		tt_warn("Float underflow");
		goto out;
	}

	/* Round to 19 significands */
	int sfr = 0, rnd = 0;
	if (dec->_msb > 19) {
		sfr = dec->_msb - 19;
		rnd = _tt_round(_tt_dec_get_dig(dec->_dig32, sfr) & 1,
					_tt_dec_get_dig(dec->_dig32, sfr-1),
					TT_ROUND_HALF_AWAY0);
	}

	/* Calculate significand */
	long double ld = 0;
	for (int i = dec->_msb - 1; i >= sfr; i--) {
		/* We can do much better here. Is it necessary? */
		ld *= 10;
		ld += _tt_dec_get_dig(dec->_dig32, i);
	}
	ld += rnd;	/* May cause overflow? */

	/* Multiply/divide exponent */
	int _exp = dec->_exp + sfr;
	int i = ARRAY_SIZE(_exp10) - 1;	/* _exp = 10^(2^i) */
	if (_exp > 0) {
		while (_exp > 0) {
			if (_exp >= 1U << i) {
				ld *= _exp10[i];
				_exp -= 1U << i;
			}
			i--;
		}
	} else if (_exp < 0) {
		_exp = -_exp;
		while (_exp > 0) {
			if (_exp >= 1U << i) {
				ld /= _exp10[i];
				_exp -= 1U << i;
			}
			i--;
		}
	}
	v.d = ld;

out:
	if (dec_mm)
		tt_dec_free(dec_mm);

	/* Check sign */
	if (dec->_sign)
		v.i |= 1ULL << 63;

	*num = v.d;
	return ret;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl $0x0, 0x64(%rsp)
movq $0x0, 0x50(%rsp)
movq 0x70(%rsp), %rdi
callq 0x2ee0
testb $0x1, %al
jne 0x2b6f
jmp 0x2b7d
movq $0x0, 0x58(%rsp)
jmp 0x2e90
movq 0x70(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x1, %eax
jne 0x2ba7
movabsq $0x7ff0000000000000, %rax # imm = 0x7FF0000000000000
movq %rax, 0x58(%rsp)
movl $0xffffff36, 0x64(%rsp) # imm = 0xFFFFFF36
jmp 0x2e90
movq 0x70(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x2, %eax
jne 0x2bd1
movabsq $0x7fffffffffffffff, %rax # imm = 0x7FFFFFFFFFFFFFFF
movq %rax, 0x58(%rsp)
movl $0xffffff32, 0x64(%rsp) # imm = 0xFFFFFF32
jmp 0x2e90
jmp 0x2bd3
xorl %edi, %edi
callq 0x1f00
movq %rax, 0x50(%rsp)
movabsq $0x7fefffffffffffff, %rax # imm = 0x7FEFFFFFFFFFFFFF
movq %rax, 0x58(%rsp)
movq 0x50(%rsp), %rdi
movsd 0x58(%rsp), %xmm0
callq 0x26b0
movq 0x70(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x62f0
cmpl $0x0, %eax
jl 0x2c48
movabsq $0x7ff0000000000000, %rax # imm = 0x7FF0000000000000
movq %rax, 0x58(%rsp)
movl $0xffffff36, 0x64(%rsp) # imm = 0xFFFFFF36
movl $0x1, %edi
leaq 0x1ba91(%rip), %rsi     # 0x1e6c6
leaq 0x1ba9a(%rip), %rdx     # 0x1e6d6
movb $0x0, %al
callq 0xe010
jmp 0x2e90
movq $0x1, 0x58(%rsp)
movq 0x50(%rsp), %rdi
movsd 0x58(%rsp), %xmm0
callq 0x26b0
movq 0x50(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x62f0
cmpl $0x0, %eax
jl 0x2ca5
movq $0x0, 0x58(%rsp)
movl $0xffffff35, 0x64(%rsp) # imm = 0xFFFFFF35
movl $0x1, %edi
leaq 0x1ba34(%rip), %rsi     # 0x1e6c6
leaq 0x1ba4c(%rip), %rdx     # 0x1e6e5
movb $0x0, %al
callq 0xe010
jmp 0x2e90
movl $0x0, 0x4c(%rsp)
movl $0x0, 0x48(%rsp)
movq 0x70(%rsp), %rax
cmpl $0x13, 0x14(%rax)
jle 0x2d11
movq 0x70(%rsp), %rax
movl 0x14(%rax), %eax
subl $0x13, %eax
movl %eax, 0x4c(%rsp)
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rdi
movl 0x4c(%rsp), %esi
callq 0x2350
andl $0x1, %eax
movl %eax, 0xc(%rsp)
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rdi
movl 0x4c(%rsp), %esi
subl $0x1, %esi
callq 0x2350
movl 0xc(%rsp), %edi
movl %eax, %esi
movl $0x2, %edx
callq 0xe9f0
movl %eax, 0x48(%rsp)
fldz
fstpt 0x30(%rsp)
movq 0x70(%rsp), %rax
movl 0x14(%rax), %eax
subl $0x1, %eax
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jl 0x2d74
fldt 0x30(%rsp)
flds 0x1bc7a(%rip)           # 0x1e9b4
fmulp %st, %st(1)
fstpt 0x30(%rsp)
movq 0x70(%rsp), %rax
movq 0x18(%rax), %rdi
movl 0x2c(%rsp), %esi
callq 0x2350
movl %eax, %eax
movq %rax, 0x10(%rsp)
fildll 0x10(%rsp)
fldt 0x30(%rsp)
faddp %st, %st(1)
fstpt 0x30(%rsp)
movl 0x2c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x2d26
movl 0x48(%rsp), %eax
movl %eax, 0x20(%rsp)
fildl 0x20(%rsp)
fldt 0x30(%rsp)
faddp %st, %st(1)
fstpt 0x30(%rsp)
movq 0x70(%rsp), %rax
movl 0x4(%rax), %eax
addl 0x4c(%rsp), %eax
movl %eax, 0x28(%rsp)
movl $0x8, 0x24(%rsp)
cmpl $0x0, 0x28(%rsp)
jle 0x2e0a
jmp 0x2dab
cmpl $0x0, 0x28(%rsp)
jle 0x2e08
movl 0x28(%rsp), %eax
movl 0x24(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jb 0x2dfb
movslq 0x24(%rsp), %rax
shlq $0x4, %rax
leaq 0xf339(%rip), %rcx      # 0x12110
fldt (%rax,%rcx)
fldt 0x30(%rsp)
fmulp %st, %st(1)
fstpt 0x30(%rsp)
movl 0x24(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movl 0x28(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x28(%rsp)
movl 0x24(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x2dab
jmp 0x2e7c
cmpl $0x0, 0x28(%rsp)
jge 0x2e7a
xorl %eax, %eax
subl 0x28(%rsp), %eax
movl %eax, 0x28(%rsp)
cmpl $0x0, 0x28(%rsp)
jle 0x2e78
movl 0x28(%rsp), %eax
movl 0x24(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jb 0x2e6b
movslq 0x24(%rsp), %rax
shlq $0x4, %rax
leaq 0xf2c9(%rip), %rcx      # 0x12110
fldt (%rax,%rcx)
fldt 0x30(%rsp)
fdivp %st, %st(1)
fstpt 0x30(%rsp)
movl 0x24(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movl 0x28(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x28(%rsp)
movl 0x24(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x2e1b
jmp 0x2e7a
jmp 0x2e7c
fldt 0x30(%rsp)
fstpl 0x18(%rsp)
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x2ea2
movq 0x50(%rsp), %rdi
callq 0x2080
movq 0x70(%rsp), %rax
cmpw $0x0, (%rax)
je 0x2ec1
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
orq 0x58(%rsp), %rax
movq %rax, 0x58(%rsp)
movsd 0x58(%rsp), %xmm0
movq 0x68(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x64(%rsp), %eax
addq $0x78, %rsp
retq
nopl (%rax)