// File: /workspace/github_c_makefile_star2_O0/cyb70289[P]tt/src/apn/decimal/basic.c
// Function: tt_dec_mul
int tt_dec_mul(struct tt_dec *dst, const struct tt_dec *src1,
		const struct tt_dec *src2)
{
	int ret = 0;

	dst->_sign = src1->_sign ^ src2->_sign;

	/* Check NaN, Inf */
	if (src1->_inf_nan == TT_DEC_NAN || src2->_inf_nan == TT_DEC_NAN) {
		dst->_inf_nan = TT_DEC_NAN;
		return TT_APN_EINVAL;
	}
	if (src1->_inf_nan == TT_DEC_INF || src2->_inf_nan == TT_DEC_INF) {
		dst->_inf_nan = TT_DEC_INF;
		return TT_APN_EOVERFLOW;
	}
	dst->_inf_nan = 0;

	/* Check zero */
	if (_tt_dec_is_zero(src1) || _tt_dec_is_zero(src2)) {
		if (src1->_exp == 0 || src2->_exp == 0) {
			dst->_exp = 0;	/* True zero */
		} else {
			dst->_exp = src1->_exp + src1->_msb - 1 +
				src2->_exp + src2->_msb - 1;
			if (dst->_exp > 0)
				dst->_exp = 0;
		}
		dst->_msb = 1;
		memset(dst->_dig32, 0, dst->_digsz);
		return 0;
	}

	dst->_exp = src1->_exp + src2->_exp;

	/* Allocate result buffer
	 * - add one extra rounding guard digits
	 * - add 18 digits for extra 0 introduced by uint boundary
	 */
	const int uints = (src1->_msb + src2->_msb + 1 + 18 + 8) / 9;
	uint *digr = calloc(uints, 4);
	if (!digr)
		return TT_ENOMEM;

	/* Multiply */
	int msb = mul_digs(digr, src1->_dig32, src1->_msb,
			src2->_dig32, src2->_msb);

	/* Adjust significand, msb */
	int adj = 0;
	if (msb > dst->_prec) {
		adj = msb - dst->_prec;

		/* Check rounding */
		if (_tt_round(_tt_dec_get_dig(digr, adj) & 1,
				_tt_dec_get_dig(digr, adj-1), 0)) {
			/* Shift digr to have 1~9 extra digs */
			if (adj >= 10) {
				int shift = (adj - 1) / 9;
				shift *= 9;
				shift_digs(digr, uints*4, digr, msb, -shift);
				adj -= shift;
				msb -= shift;
				dst->_exp += shift;
			}
			/* Add 10^adj */
			tt_assert_fa(adj >=1 && adj <= 9);
			uint one[2] = { 0, 0 };
			one[adj / 9] = one_tbl[adj % 9];
			msb = add_digs(digr, msb, one, adj+1);
			/* Get new exponent adjust */
			adj = msb - dst->_prec;
			tt_assert_fa(adj >= 1);
		}

		dst->_exp += adj;
		dst->_msb = dst->_prec;
		ret = TT_APN_EROUNDED;
	} else {
		dst->_msb = msb;
	}

	/* Copy to dst */
	memset(dst->_dig32, 0, dst->_digsz);
	shift_digs(dst->_dig32, dst->_digsz, digr, msb, -adj);

	free(digr);
	return ret;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movq %rdx, 0x38(%rsp)
movl $0x0, 0x34(%rsp)
movq 0x40(%rsp), %rax
movswl (%rax), %eax
movq 0x38(%rsp), %rcx
movswl (%rcx), %ecx
xorl %ecx, %eax
movw %ax, %cx
movq 0x48(%rsp), %rax
movw %cx, (%rax)
movq 0x40(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x2, %eax
je 0x4474
movq 0x38(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x2, %eax
jne 0x448c
movq 0x48(%rsp), %rax
movw $0x2, 0x2(%rax)
movl $0xffffff32, 0x54(%rsp) # imm = 0xFFFFFF32
jmp 0x488e
movq 0x40(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x1, %eax
je 0x44a8
movq 0x38(%rsp), %rax
movswl 0x2(%rax), %eax
cmpl $0x1, %eax
jne 0x44c0
movq 0x48(%rsp), %rax
movw $0x1, 0x2(%rax)
movl $0xffffff36, 0x54(%rsp) # imm = 0xFFFFFF36
jmp 0x488e
movq 0x48(%rsp), %rax
movw $0x0, 0x2(%rax)
movq 0x40(%rsp), %rdi
callq 0x48a0
testb $0x1, %al
jne 0x44ec
movq 0x38(%rsp), %rdi
callq 0x48a0
testb $0x1, %al
jne 0x44ec
jmp 0x458a
movq 0x40(%rsp), %rax
cmpl $0x0, 0x4(%rax)
je 0x4502
movq 0x38(%rsp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x4510
movq 0x48(%rsp), %rax
movl $0x0, 0x4(%rax)
jmp 0x4557
movq 0x40(%rsp), %rax
movl 0x4(%rax), %ecx
movq 0x40(%rsp), %rax
addl 0x14(%rax), %ecx
subl $0x1, %ecx
movq 0x38(%rsp), %rax
addl 0x4(%rax), %ecx
movq 0x38(%rsp), %rax
addl 0x14(%rax), %ecx
subl $0x1, %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x4(%rax)
movq 0x48(%rsp), %rax
cmpl $0x0, 0x4(%rax)
jle 0x4555
movq 0x48(%rsp), %rax
movl $0x0, 0x4(%rax)
jmp 0x4557
movq 0x48(%rsp), %rax
movl $0x1, 0x14(%rax)
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x48(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x10e0
movl $0x0, 0x54(%rsp)
jmp 0x488e
movq 0x40(%rsp), %rax
movl 0x4(%rax), %ecx
movq 0x38(%rsp), %rax
addl 0x4(%rax), %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x4(%rax)
movq 0x40(%rsp), %rax
movl 0x14(%rax), %eax
movq 0x38(%rsp), %rcx
addl 0x14(%rcx), %eax
addl $0x1, %eax
addl $0x12, %eax
addl $0x8, %eax
movl $0x9, %ecx
cltd
idivl %ecx
movl %eax, 0x30(%rsp)
movslq 0x30(%rsp), %rdi
movl $0x4, %esi
callq 0x1110
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0x45f0
movl $0xffffffff, 0x54(%rsp) # imm = 0xFFFFFFFF
jmp 0x488e
movq 0x28(%rsp), %rdi
movq 0x40(%rsp), %rax
movq 0x18(%rax), %rsi
movq 0x40(%rsp), %rax
movl 0x14(%rax), %edx
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rcx
movq 0x38(%rsp), %rax
movl 0x14(%rax), %r8d
callq 0x48f0
movl %eax, 0x24(%rsp)
movl $0x0, 0x20(%rsp)
movl 0x24(%rsp), %eax
movq 0x48(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jle 0x482f
movl 0x24(%rsp), %eax
movq 0x48(%rsp), %rcx
subl 0x8(%rcx), %eax
movl %eax, 0x20(%rsp)
movq 0x28(%rsp), %rdi
movl 0x20(%rsp), %esi
callq 0x2350
andl $0x1, %eax
movl %eax, 0x10(%rsp)
movq 0x28(%rsp), %rdi
movl 0x20(%rsp), %esi
subl $0x1, %esi
callq 0x2350
movl 0x10(%rsp), %edi
movl %eax, %esi
xorl %edx, %edx
callq 0xe9f0
cmpl $0x0, %eax
je 0x4806
cmpl $0xa, 0x20(%rsp)
jl 0x46f7
movl 0x20(%rsp), %eax
subl $0x1, %eax
movl $0x9, %ecx
cltd
idivl %ecx
movl %eax, 0x1c(%rsp)
imull $0x9, 0x1c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x28(%rsp), %rdi
movl 0x30(%rsp), %esi
shll $0x2, %esi
movq 0x28(%rsp), %rdx
movl 0x24(%rsp), %ecx
xorl %r8d, %r8d
subl 0x1c(%rsp), %r8d
callq 0x4af0
movl 0x1c(%rsp), %ecx
movl 0x20(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x20(%rsp)
movl 0x1c(%rsp), %ecx
movl 0x24(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x24(%rsp)
movl 0x1c(%rsp), %ecx
movq 0x48(%rsp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
jmp 0x46f9
xorl %eax, %eax
cmpl $0x1, 0x20(%rsp)
movb %al, 0xf(%rsp)
jl 0x4712
cmpl $0x9, 0x20(%rsp)
setle %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
xorb $-0x1, %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x4752
xorl %edi, %edi
leaq 0x1a03f(%rip), %rsi     # 0x1e771
leaq 0xd9a5(%rip), %rdx      # 0x120de
leaq 0x1a03c(%rip), %rcx     # 0x1e77c
movl $0x286, %r8d            # imm = 0x286
movb $0x0, %al
callq 0xe010
callq 0x1060
jmp 0x4754
leaq 0x14(%rsp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x10e0
movl 0x20(%rsp), %eax
movl $0x9, %ecx
cltd
idivl %ecx
movslq %edx, %rcx
leaq 0xda45(%rip), %rax      # 0x121c0
movl (%rax,%rcx,4), %ecx
movl 0x20(%rsp), %eax
movl $0x9, %esi
cltd
idivl %esi
cltq
movl %ecx, 0x14(%rsp,%rax,4)
movq 0x28(%rsp), %rdi
movl 0x24(%rsp), %esi
leaq 0x14(%rsp), %rdx
movl 0x20(%rsp), %ecx
addl $0x1, %ecx
callq 0x4f80
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %eax
movq 0x48(%rsp), %rcx
subl 0x8(%rcx), %eax
movl %eax, 0x20(%rsp)
cmpl $0x1, 0x20(%rsp)
setge %al
xorb $-0x1, %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x4802
xorl %edi, %edi
leaq 0x19f8f(%rip), %rsi     # 0x1e771
leaq 0xd8f5(%rip), %rdx      # 0x120de
leaq 0x19f8c(%rip), %rcx     # 0x1e77c
movl $0x28c, %r8d            # imm = 0x28C
movb $0x0, %al
callq 0xe010
callq 0x1060
jmp 0x4804
jmp 0x4806
movl 0x20(%rsp), %ecx
movq 0x48(%rsp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
movq 0x48(%rsp), %rax
movl 0x8(%rax), %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x14(%rax)
movl $0xc9, 0x34(%rsp)
jmp 0x483b
movl 0x24(%rsp), %ecx
movq 0x48(%rsp), %rax
movl %ecx, 0x14(%rax)
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x48(%rsp), %rax
movl 0x10(%rax), %eax
movl %eax, %edx
xorl %esi, %esi
callq 0x10e0
movq 0x48(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x48(%rsp), %rax
movl 0x10(%rax), %esi
movq 0x28(%rsp), %rdx
movl 0x24(%rsp), %ecx
xorl %r8d, %r8d
subl 0x20(%rsp), %r8d
callq 0x4af0
movq 0x28(%rsp), %rdi
callq 0x1030
movl 0x34(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
addq $0x58, %rsp
retq
nopw (%rax,%rax)