// File: /workspace/github_c_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movzwl (%rdx), %eax
xorw (%rsi), %ax
movq %rdi, %rbx
movw %ax, (%rdi)
movzwl 0x2(%rsi), %eax
cmpw $0x2, %ax
je 0x2c4f
movq %rdx, %r15
movzwl 0x2(%rdx), %ecx
cmpw $0x2, %cx
jne 0x2c6d
movw $0x2, 0x2(%rbx)
movl $0xffffff32, %r15d      # imm = 0xFFFFFF32
movl %r15d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpw $0x1, %ax
setne %al
cmpw $0x1, %cx
setne %cl
testb %cl, %al
jne 0x2c8d
movw $0x1, 0x2(%rbx)
movl $0xffffff36, %r15d      # imm = 0xFFFFFF36
jmp 0x2c5b
movq %rsi, %r12
andw $0x0, 0x2(%rbx)
movq %rsi, %rdi
callq 0x3009
testb %al, %al
jne 0x2cad
movq %r15, %rdi
callq 0x3009
testb %al, %al
je 0x2d01
movl 0x4(%r12), %eax
testl %eax, %eax
je 0x2ce0
movl 0x4(%r15), %ecx
testl %ecx, %ecx
je 0x2ce0
addl %ecx, %eax
addl 0x14(%r12), %eax
movl 0x14(%r15), %ecx
leal (%rcx,%rax), %edx
decl %edx
addl %ecx, %eax
addl $-0x2, %eax
xorl %ecx, %ecx
cmpl $0x2, %edx
cmovll %eax, %ecx
movl %ecx, 0x4(%rbx)
jmp 0x2ce4
andl $0x0, 0x4(%rbx)
movl $0x1, 0x14(%rbx)
movq 0x18(%rbx), %rdi
movl 0x10(%rbx), %edx
xorl %r15d, %r15d
xorl %esi, %esi
callq 0x10e0
jmp 0x2c5b
movl 0x4(%r15), %eax
addl 0x4(%r12), %eax
movq %rbx, 0x10(%rsp)
movl %eax, 0x4(%rbx)
movl 0x14(%r12), %ebx
movl 0x14(%r15), %r13d
leal 0x1b(%r13,%rbx), %eax
pushq $0x9
popq %r14
cltd
idivl %r14d
movl %eax, %ebp
movslq %eax, %rdi
pushq $0x4
popq %rsi
callq 0x1100
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0x2f5e
movl %ebp, 0x18(%rsp)
leal (%rbx,%r13), %eax
movl %eax, 0x1c(%rsp)
movl %r14d, %ecx
movq 0x18(%r12), %r14
movq 0x18(%r15), %rax
movq %rax, 0x58(%rsp)
leal 0x8(%rbx), %eax
cltd
idivl %ecx
movl %eax, %esi
addl $0x8, %r13d
movl %r13d, %eax
cltd
idivl %ecx
movq %rax, 0x48(%rsp)
addl %esi, %eax
movslq %esi, %rcx
movq %rcx, 0x40(%rsp)
decl %esi
movq %rsi, 0x50(%rsp)
xorl %r13d, %r13d
testl %eax, %eax
cmovlel %r13d, %eax
movq %rax, 0x60(%rsp)
pushq $0x1
popq %rbp
movq %rbx, %r15
cmpq 0x60(%rsp), %r13
je 0x2e48
cmpq 0x40(%rsp), %r13
movq 0x50(%rsp), %rax
cmovll %r13d, %eax
movl %r13d, %ecx
subl 0x48(%rsp), %ecx
pushq $-0x1
popq %rdx
cmovsl %edx, %ecx
cltq
movslq %ecx, %rcx
movl %r13d, %edx
subl %eax, %edx
movslq %edx, %rdx
movq 0x58(%rsp), %rsi
leaq (%rsi,%rdx,4), %rdi
xorl %esi, %esi
xorl %edx, %edx
cmpq %rcx, %rax
jle 0x2dfc
movl (%r14,%rax,4), %r8d
movl (%rdi), %r9d
imulq %r8, %r9
addq %r9, %rsi
adcq $0x0, %rdx
decq %rax
addq $0x4, %rdi
jmp 0x2ddc
movq %rsi, %rax
orq %rdx, %rax
je 0x2e40
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andl $0x0, 0x30(%rsp)
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x1c7a
movq 0x8(%rsp), %rcx
leaq (%rcx,%r13,4), %rdi
leal (%r13,%r13,8), %r12d
subl %r12d, %ebp
movl %ebp, %esi
movq %rbx, %rdx
movl %eax, %ecx
callq 0x32b5
movl %eax, %ebp
addl %r12d, %ebp
incq %r13
jmp 0x2d9c
cmpl %r15d, %ebp
jl 0x2fc1
cmpl 0x1c(%rsp), %ebp
jg 0x2fc1
xorl %r15d, %r15d
movl %ebp, %r12d
movq 0x10(%rsp), %rbx
subl 0x8(%rbx), %r12d
jle 0x2f67
movq 0x8(%rsp), %r14
movq %r14, %rdi
movl %r12d, %esi
callq 0x1c07
movl %eax, %r13d
andl $0x1, %r13d
leal -0x1(%r12), %r15d
movq %r14, %rdi
movl %r15d, %esi
callq 0x1c07
movl %r13d, %edi
movl %eax, %esi
xorl %edx, %edx
callq 0x829c
testl %eax, %eax
je 0x2f6f
cmpl $0xa, %r12d
movq 0x10(%rsp), %rbx
jl 0x2ee9
movl %r15d, %eax
xorl %edx, %edx
pushq $0x9
popq %rcx
divl %ecx
subl %edx, %r15d
movl 0x18(%rsp), %esi
shll $0x2, %esi
movl %r15d, %r8d
negl %r8d
movq 0x8(%rsp), %rdi
movq %rdi, %rdx
movl %ebp, %ecx
callq 0x3024
subl %r15d, %r12d
subl %r15d, %ebp
addl %r15d, 0x4(%rbx)
leal -0xa(%r12), %eax
cmpl $-0xa, %eax
jbe 0x2fe0
leaq 0x20(%rsp), %rdx
andq $0x0, (%rdx)
xorl %eax, %eax
movl %r12d, %ecx
subl $0x9, %ecx
cmovbl %r12d, %ecx
leaq 0x725d(%rip), %rsi      # 0xa170
movl (%rsi,%rcx,4), %ecx
setae %al
movl %ecx, 0x20(%rsp,%rax,4)
incl %r12d
movq 0x8(%rsp), %rdi
movl %ebp, %esi
movl %r12d, %ecx
callq 0x32b5
movl %eax, %ebp
movl 0x8(%rbx), %eax
movl %ebp, %r12d
subl %eax, %r12d
jg 0x2f77
leaq 0x13906(%rip), %rsi     # 0x16849
leaq 0x7138(%rip), %rdx      # 0xa082
leaq 0x13903(%rip), %rcx     # 0x16854
xorl %edi, %edi
movl $0x28c, %r8d            # imm = 0x28C
jmp 0x2ffd
pushq $-0x1
popq %r15
jmp 0x2c5b
movl %ebp, %r13d
xorl %r12d, %r12d
jmp 0x2f86
movq 0x10(%rsp), %rbx
movl 0x8(%rbx), %eax
addl %r12d, 0x4(%rbx)
movl %ebp, %r13d
movl $0xc9, %r15d
movl %eax, %ebp
movl %ebp, 0x14(%rbx)
movq 0x18(%rbx), %rdi
movl 0x10(%rbx), %edx
xorl %esi, %esi
callq 0x10e0
movq 0x18(%rbx), %rdi
movl 0x10(%rbx), %esi
negl %r12d
movq 0x8(%rsp), %rbx
movq %rbx, %rdx
movl %r13d, %ecx
movl %r12d, %r8d
callq 0x3024
movq %rbx, %rdi
callq 0x1030
jmp 0x2c5b
leaq 0x138ca(%rip), %rsi     # 0x16892
leaq 0x70b3(%rip), %rdx      # 0xa082
leaq 0x1387e(%rip), %rcx     # 0x16854
xorl %edi, %edi
movl $0xea, %r8d
jmp 0x2ffd
leaq 0x13862(%rip), %rsi     # 0x16849
leaq 0x7094(%rip), %rdx      # 0xa082
leaq 0x1385f(%rip), %rcx     # 0x16854
xorl %edi, %edi
movl $0x286, %r8d            # imm = 0x286
xorl %eax, %eax
callq 0x7de8
callq 0x1050