// File: /workspace/github_c_makefile_star2_O3/cyb70289[P]tt/src/apn/decimal/basic.c
// Function: tt_dec_div
int tt_dec_div(struct tt_dec *dst, const struct tt_dec *src1,
		const struct tt_dec *src2)
{
	int ret = 0, sign = src1->_sign ^ src2->_sign;

	dst->_sign = 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) {
		if (src2->_inf_nan == TT_DEC_INF) {
			dst->_inf_nan = TT_DEC_NAN;
			return TT_APN_EINVAL;
		} else {
			dst->_inf_nan = TT_DEC_INF;
			return TT_APN_EOVERFLOW;
		}
	}
	if (src2->_inf_nan == TT_DEC_INF) {
		_tt_dec_zero(dst);
		return 0;
	}

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

	/* Allocate a new DEC if dst overlaps src */
	struct tt_dec *quotient = dst;
	if (quotient == src1 || quotient == src2) {
		quotient = tt_dec_alloc(quotient->_prec);
		if (!quotient)
			return TT_ENOMEM;
	} else {
		_tt_dec_zero(quotient);
	}

	quotient->_sign = sign;
	quotient->_exp = src1->_exp - src2->_exp;

	/* Allocate dividend, divisor buffer */
	const int uints = (_tt_max(src1->_msb, src2->_msb) + 1 + 8) / 9;
	uint *dividend = calloc(uints, 4);
	uint *divisor = calloc(uints, 4);
	if (!dividend || !divisor) {
		ret = TT_ENOMEM;
		goto out;
	}
	memcpy(dividend, src1->_dig32, _tt_min(src1->_digsz, uints*4));
	memcpy(divisor, src2->_dig32, _tt_min(src2->_digsz, uints*4));

	int msb_dividend = src1->_msb;
	int msb_divisor = src2->_msb;

	/* Get highest digit */
	int top_dividend = _tt_dec_get_dig(dividend, msb_dividend-1);
	int top_divisor = _tt_dec_get_dig(divisor, msb_divisor-1);
	tt_assert_fa(top_divisor && top_dividend);

	/* Make dividend/divisor within [1, 10) */
	int adj = msb_dividend - msb_divisor;
	quotient->_exp += adj;
	if (adj < 0)
		msb_dividend = shift_digs(dividend, 0,
				dividend, msb_dividend, -adj);
	else if (adj > 0)
		msb_divisor = shift_digs(divisor, 0, divisor, msb_divisor, adj);
	if (cmp_digs(dividend, msb_dividend, divisor, msb_divisor) < 0) {
		quotient->_exp--;
		msb_dividend = shift_digs(dividend, 0, dividend, msb_dividend, 1);
		tt_assert_fa(msb_dividend == msb_divisor + 1);
	} else {
		tt_assert_fa(msb_dividend == msb_divisor);
	}

	/* Remove common trailing zeros */
	while (1) {
		if (msb_dividend <= 9 || msb_divisor <= 9)
			break;
		if (dividend[0] || divisor[0])
			break;
		const int sz_dividend = (msb_dividend + 8) / 9 * 4;
		const int sz_divisor = (msb_divisor + 8) / 9 * 4;
		msb_dividend = shift_digs(dividend, sz_dividend,
				dividend, msb_dividend, -9);
		msb_divisor = shift_digs(divisor, sz_divisor,
				divisor, msb_divisor, -9);
	}

	int msb_result = 1;
	uint *result = quotient->_dig32;
	while (1) {
		tt_assert_fa(msb_result <= (quotient->_prec + 1));

		/* Repeat sub divisor from dividend till remainder < divisor */
		int r;
		for (r = 1; r < 10; r++) {
			msb_dividend = sub_digs(dividend, dividend, msb_dividend,
					divisor, msb_divisor);
			if ((msb_dividend < msb_divisor) ||
					(msb_dividend == msb_divisor &&
					 cmp_digs(dividend, msb_dividend,
						 divisor, msb_divisor) < 0))
				break;
		}
		tt_assert_fa(r < 10 && cmp_digs(dividend, msb_dividend,
					divisor, msb_divisor) < 0);

		/* Store quotient */
		tt_assert_fa(result[0] % 10 == 0);
		result[0] += r;

		/* Precision+rounding reached or residue is zero */
		if ((msb_result > quotient->_prec) ||
				(msb_dividend == 1 && dividend[0] == 0))
			break;

		/* Get highest digit */
		top_dividend = _tt_dec_get_dig(dividend, msb_dividend-1);
		top_divisor = _tt_dec_get_dig(divisor, msb_divisor-1);
		tt_assert_fa(top_divisor && top_dividend);

		/* Make dividend/divisor within [1, 10)
		 * - dividend is less than divisor now
		 */
		adj = msb_dividend - msb_divisor;
		if (adj < 0)
			msb_dividend = shift_digs(dividend, 0,
					dividend, msb_dividend, -adj);
		if (cmp_digs(dividend, msb_dividend, divisor, msb_divisor) < 0) {
			adj--;
			msb_dividend = shift_digs(dividend, 0,
					dividend, msb_dividend, 1);
			tt_assert_fa(msb_dividend == msb_divisor + 1);
		} else {
			tt_assert_fa(msb_dividend == msb_divisor);
		}
		tt_assert_fa(adj < 0);
		adj = -adj;

		/* Append zero to quotient */
		int prec_left = quotient->_prec - msb_result;
		if (adj > (prec_left+1)) {
			/* Precision+rounding reached */
			msb_result = shift_digs(result, 0,
					result, msb_result, prec_left);
			quotient->_exp -= prec_left;
			ret = TT_APN_EROUNDED;
			break;
		}
		msb_result = shift_digs(result, 0, result, msb_result, adj);
		quotient->_exp -= adj;
	}

	/* Check rounding */
	if (msb_result > quotient->_prec) {
		if (_tt_round(_tt_dec_get_dig(result, 1) & 1,
				_tt_dec_get_dig(result, 0), 0)) {
			const uint ten = 10;
			msb_result = add_digs(result, msb_result, &ten, 2);
		}
		adj = msb_result - quotient->_prec;
		msb_result = shift_digs(result, quotient->_digsz,
				result, msb_result, -adj);
		quotient->_exp += adj;
		ret = TT_APN_EROUNDED;
	}

	quotient->_msb = msb_result;

	/* Switch buffer if dst overlaps src */
	if (quotient != dst) {
		free(dst->_dig32);
		memcpy(dst, quotient, sizeof(struct tt_dec));
		free(quotient);
		quotient = NULL;
	}

out:
	if (dividend)
		free(dividend);
	if (divisor)
		free(divisor);
	if (quotient && quotient != dst)
		tt_dec_free(quotient);

	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movzwl (%rdx), %ebp
xorw (%rsi), %bp
movq %rdi, %r15
movw %bp, (%rdi)
movzwl 0x2(%rsi), %eax
cmpw $0x2, %ax
je 0x3f18
movq %rdx, %rbx
movzwl 0x2(%rdx), %edx
cmpw $0x2, %dx
jne 0x3f37
movw $0x2, 0x2(%r15)
movl $0xffffff32, %r14d      # imm = 0xFFFFFF32
movl %r14d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpw $0x1, %ax
jne 0x3f52
cmpw $0x1, %dx
je 0x3f18
movw $0x1, 0x2(%r15)
movl $0xffffff36, %r14d      # imm = 0xFFFFFF36
jmp 0x3f25
cmpw $0x1, %dx
jne 0x3f65
movq %r15, %rdi
callq 0x24bc
xorl %r14d, %r14d
jmp 0x3f25
movq %rsi, %r13
movl 0x14(%rbx), %ecx
cmpl $0x1, %ecx
jne 0x3fb1
testw %dx, %dx
jne 0x3fb1
movq 0x18(%rbx), %rdx
cmpl $0x0, (%rdx)
jne 0x3fb1
cmpl $0x1, 0x14(%r13)
jne 0x414e
testw %ax, %ax
jne 0x414e
movq 0x18(%r13), %rax
cmpl $0x0, (%rax)
jne 0x414e
movw $0x2, 0x2(%r15)
movl $0xffffff33, %r14d      # imm = 0xFFFFFF33
jmp 0x3f25
cmpl $0x1, 0x14(%r13)
jne 0x400b
testw %ax, %ax
jne 0x400b
movq 0x18(%r13), %rax
cmpl $0x0, (%rax)
jne 0x400b
movl 0x4(%r13), %eax
xorl %r14d, %r14d
movl $0x0, %edx
testl %eax, %eax
je 0x3fe4
addl 0x4(%rbx), %ecx
subl %ecx, %eax
incl %eax
movl %eax, %edx
sarl $0x1f, %edx
andl %eax, %edx
movl %edx, 0x4(%r15)
movw $0x0, 0x2(%r15)
movl $0x1, 0x14(%r15)
movq 0x18(%r15), %rdi
movl 0x10(%r15), %edx
xorl %esi, %esi
callq 0x10e0
jmp 0x3f25
cmpq %r13, %r15
setne %al
cmpq %rbx, %r15
setne %cl
testb %cl, %al
jne 0x4034
movl 0x8(%r15), %edi
callq 0x23c8
testq %rax, %rax
jne 0x403f
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x3f25
movq %r15, %rdi
callq 0x24bc
movq %r15, %rax
movq %r15, 0x38(%rsp)
movw %bp, (%rax)
movl 0x4(%r13), %edx
subl 0x4(%rbx), %edx
movq %rax, 0x10(%rsp)
movl %edx, 0x4(%rax)
movl 0x14(%r13), %ebp
movl 0x14(%rbx), %ecx
movl %ebp, %eax
subl %ecx, %eax
movl %eax, 0x28(%rsp)
movq %rcx, 0x18(%rsp)
movl %ecx, %eax
cmovgl %ebp, %eax
addl $0x9, %eax
cltq
imulq $0x38e38e39, %rax, %rcx # imm = 0x38E38E39
movq %rcx, %rax
shrq $0x3f, %rax
sarq $0x21, %rcx
addl %eax, %ecx
movq %rcx, 0x8(%rsp)
movslq %ecx, %r14
movl $0x4, %esi
movq %r14, %rdi
callq 0x1100
movq %rax, %r12
movl $0x4, %esi
movq %r14, %rdi
callq 0x1100
movq %rax, %r15
testq %r12, %r12
sete %al
testq %r15, %r15
sete %cl
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
orb %al, %cl
jne 0x457c
movq 0x18(%r13), %rsi
movl 0x10(%r13), %edx
movq 0x8(%rsp), %r14
shll $0x2, %r14d
cmpl %r14d, %edx
cmovael %r14d, %edx
movq %r12, %rdi
callq 0x1120
movq 0x18(%rbx), %rsi
movl 0x10(%rbx), %eax
cmpl %r14d, %eax
cmovbl %eax, %r14d
movq %r15, %rdi
movq %r14, %rdx
callq 0x1120
leal -0x1(%rbp), %esi
movq %r12, %rdi
callq 0x2607
movl %eax, %ebx
movq 0x18(%rsp), %r13
leal -0x1(%r13), %esi
movq %r15, %rdi
callq 0x2607
testl %eax, %eax
je 0x4602
testl %ebx, %ebx
je 0x4602
movq 0x10(%rsp), %r14
movl 0x28(%rsp), %r8d
addl %r8d, 0x4(%r14)
testl %r8d, %r8d
js 0x4160
cmpl %r13d, %ebp
jne 0x4176
movl %ebp, %r13d
jmp 0x4189
movw $0x1, 0x2(%r15)
movl $0xffffff34, %r14d      # imm = 0xFFFFFF34
jmp 0x3f25
negl %r8d
movq %r12, %rdi
xorl %esi, %esi
movq %r12, %rdx
movl %ebp, %ecx
callq 0x3ac9
movl %eax, %ebp
jmp 0x4189
movq %r15, %rdi
xorl %esi, %esi
movq %r15, %rdx
movl %r13d, %ecx
callq 0x3ac9
movl %eax, %r13d
movq %r12, %rdi
movl %ebp, %esi
movq %r15, %rdx
movl %r13d, %ecx
callq 0x460c
testl %eax, %eax
js 0x41a7
cmpl %r13d, %ebp
je 0x41ce
callq 0x148c
decl 0x4(%r14)
movq %r12, %rdi
xorl %esi, %esi
movq %r12, %rdx
movl %ebp, %ecx
movl $0x1, %r8d
callq 0x3ac9
movl %eax, %ebp
leal 0x1(%r13), %eax
cmpl %eax, %ebp
jne 0x4607
cmpl $0xa, %ebp
jl 0x4246
cmpl $0xa, %r13d
jl 0x4246
cmpl $0x0, (%r12)
jne 0x4246
cmpl $0x0, (%r15)
jne 0x4246
leal 0x8(%rbp), %eax
imulq $0x38e38e39, %rax, %rsi # imm = 0x38E38E39
shrq $0x20, %rsi
addl %esi, %esi
andl $-0x4, %esi
leal 0x8(%r13), %eax
imulq $0x38e38e39, %rax, %rbx # imm = 0x38E38E39
shrq $0x20, %rbx
addl %ebx, %ebx
andl $-0x4, %ebx
movq %r12, %rdi
movq %r12, %rdx
movl %ebp, %ecx
movl $0xfffffff7, %r8d       # imm = 0xFFFFFFF7
callq 0x3ac9
movl %eax, %ebp
movq %r15, %rdi
movl %ebx, %esi
movq %r15, %rdx
movl %r13d, %ecx
movl $0xfffffff7, %r8d       # imm = 0xFFFFFFF7
callq 0x3ac9
movl %eax, %r13d
cmpl $0xa, %ebp
jl 0x4246
cmpl $0x9, %r13d
jg 0x41d9
cmpl $0x0, 0x8(%r14)
js 0x45bb
movq 0x18(%r14), %rax
movq %rax, 0x20(%rsp)
leal -0x1(%r13), %eax
movl %eax, 0x34(%rsp)
leal 0x1(%r13), %eax
movl %eax, 0x30(%rsp)
leal 0x8(%r13), %eax
imulq $0x38e38e39, %rax, %rax # imm = 0x38E38E39
shrq $0x21, %rax
movq %rax, 0x28(%rsp)
movl $0x1, 0x8(%rsp)
movq %r13, 0x18(%rsp)
movl $0x1, %ebx
movq %r12, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq %r15, %rcx
movl %r13d, %r8d
callq 0x4667
movl %eax, %ebp
cmpl %r13d, %eax
jl 0x447b
jne 0x42d1
movq 0x28(%rsp), %rax
testq %rax, %rax
jle 0x42d1
movl -0x4(%r12,%rax,4), %ecx
movl -0x4(%r15,%rax,4), %edx
cmpl %edx, %ecx
ja 0x42d1
decq %rax
cmpl %edx, %ecx
jae 0x42b5
jmp 0x42dd
incl %ebx
cmpl $0xa, %ebx
jne 0x4290
jmp 0x45d9
movl %r13d, %ebp
leal 0x8(%rbp), %eax
imulq $0x38e38e39, %rax, %rax # imm = 0x38E38E39
shrq $0x21, %rax
testq %rax, %rax
jle 0x45d9
movl -0x4(%r12,%rax,4), %ecx
movl -0x4(%r15,%rax,4), %edx
cmpl %edx, %ecx
ja 0x45d9
decq %rax
cmpl %edx, %ecx
jae 0x42ee
movq 0x20(%rsp), %rdx
movl (%rdx), %esi
imull $0xcccccccd, %esi, %ecx # imm = 0xCCCCCCCD
rorl %ecx
cmpl $0x1999999a, %ecx       # imm = 0x1999999A
movl 0x8(%rsp), %eax
jae 0x45c0
addl %ebx, %esi
movl %esi, (%rdx)
movl 0x8(%r14), %ecx
xorl %r14d, %r14d
cmpl %ecx, %eax
jg 0x448f
cmpl $0x1, %ebp
jne 0x4352
cmpl $0x0, (%r12)
je 0x448f
leal -0x1(%rbp), %esi
movq %r12, %rdi
callq 0x2607
movl %eax, %ebx
movq %r15, %rdi
movl 0x34(%rsp), %esi
callq 0x2607
testl %eax, %eax
je 0x45c5
testl %ebx, %ebx
je 0x45c5
movl %ebp, %r13d
movq 0x18(%rsp), %rbx
subl %ebx, %r13d
movl 0x8(%rsp), %ecx
js 0x43f4
cmpl 0x18(%rsp), %ebp
jge 0x43be
movq %r12, %rdi
xorl %esi, %esi
movq %r12, %rdx
movl %ebp, %ecx
movl $0x1, %r8d
callq 0x3ac9
movl 0x30(%rsp), %ecx
cmpl %ecx, %eax
jne 0x45d4
decl %r13d
movl %ecx, %ebp
movl 0x8(%rsp), %ecx
jmp 0x442a
jg 0x441b
leal 0x8(%rbp), %eax
cltq
imulq $0x38e38e39, %rax, %rax # imm = 0x38E38E39
movq %rax, %rdx
shrq $0x3f, %rdx
sarq $0x21, %rax
addl %edx, %eax
testl %eax, %eax
jle 0x441b
movl -0x4(%r12,%rax,4), %esi
movl -0x4(%r15,%rax,4), %edx
cmpl %edx, %esi
ja 0x441b
decq %rax
cmpl %edx, %esi
jae 0x43d9
jmp 0x4392
movl %r13d, %r8d
negl %r8d
movq %r12, %rdi
xorl %esi, %esi
movq %r12, %rdx
movl %ebp, %ecx
callq 0x3ac9
movl %eax, %ebp
testl %ebx, %ebx
jg 0x4486
testl %ebp, %ebp
movl 0x8(%rsp), %ecx
jg 0x438c
movq 0x18(%rsp), %rax
cmpl %eax, %ebp
movl %eax, %ebp
jne 0x45cf
testl %r13d, %r13d
jns 0x45ca
movl %r13d, %r8d
negl %r8d
movq 0x10(%rsp), %r14
movl 0x8(%r14), %ebx
subl %ecx, %ebx
leal 0x1(%rbx), %eax
cmpl %r8d, %eax
jl 0x4496
movq 0x20(%rsp), %rdi
xorl %esi, %esi
movq %rdi, %rdx
callq 0x3ac9
addl %r13d, 0x4(%r14)
movl 0x8(%r14), %ecx
incl %ecx
movl %eax, 0x8(%rsp)
cmpl %ecx, %eax
movq 0x18(%rsp), %r13
jle 0x428b
jmp 0x45bb
jae 0x42e0
jmp 0x4310
movl 0x8(%rsp), %ecx
jmp 0x438c
movq 0x20(%rsp), %rbp
jmp 0x44b9
movq 0x20(%rsp), %rbp
movq %rbp, %rdi
xorl %esi, %esi
movq %rbp, %rdx
movl %ebx, %r8d
callq 0x3ac9
subl %ebx, 0x4(%r14)
movl 0x8(%r14), %ecx
movl $0xc9, %r14d
cmpl %ecx, %eax
jle 0x450f
movl %eax, %r14d
movq %rbp, %rdi
movl $0x1, %esi
callq 0x2607
movl %eax, %ebx
andl $0x1, %ebx
movq %rbp, %rdi
xorl %esi, %esi
callq 0x2607
movl %ebx, %edi
movl %eax, %esi
xorl %edx, %edx
callq 0x90d6
testl %eax, %eax
je 0x4516
leaq 0x44(%rsp), %rdx
movl $0xa, (%rdx)
movq %rbp, %rdi
movl %r14d, %esi
movl $0x2, %ecx
callq 0x3dca
movl %eax, %ecx
movq 0x10(%rsp), %r13
jmp 0x451e
movq 0x10(%rsp), %r13
jmp 0x4543
movq 0x10(%rsp), %r13
movl %r14d, %ecx
movl %ecx, %ebx
subl 0x8(%r13), %ebx
movl 0x10(%r13), %esi
movl %ebx, %r8d
negl %r8d
movq %rbp, %rdi
movq %rbp, %rdx
callq 0x3ac9
addl %ebx, 0x4(%r13)
movl $0xc9, %r14d
movl %eax, 0x14(%r13)
movq 0x38(%rsp), %rbx
cmpq %rbx, %r13
je 0x457c
movq 0x18(%rbx), %rdi
callq 0x1030
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups %xmm1, 0x10(%rbx)
movups %xmm0, (%rbx)
movq %r13, %rdi
callq 0x1030
movq $0x0, 0x10(%rsp)
testq %r12, %r12
je 0x4589
movq %r12, %rdi
callq 0x1030
testq %r15, %r15
je 0x4596
movq %r15, %rdi
callq 0x1030
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
sete %al
cmpq 0x38(%rsp), %rdi
sete %cl
orb %al, %cl
jne 0x3f25
callq 0x24a6
jmp 0x3f25
callq 0x15b2
callq 0x14e0
callq 0x1588
callq 0x155e
callq 0x1534
callq 0x150a
leaq 0x132ac(%rip), %rsi     # 0x1788c
leaq 0x6ab7(%rip), %rdx      # 0xb09e
leaq 0x13286(%rip), %rcx     # 0x17874
xorl %edi, %edi
movl $0x321, %r8d            # imm = 0x321
xorl %eax, %eax
callq 0x8cca
callq 0x1050
callq 0x15dc
callq 0x14b6