// File: /workspace/github_c_makefile_star2_O0/983[P]bigint/bigint.c
// Function: bigint_div_mod
bigint* bigint_div_mod(
    bigint *dst_quotient,
    bigint *dst_remainder,
    const bigint *src_numerator,
    const bigint *src_denominator
){
    int shift;
    int src_numerator_neg = src_numerator->neg;
    int src_denominator_neg = src_denominator->neg;
    bigint denominator[1], *remainder = dst_remainder, *quotient = dst_quotient;

    if (src_denominator->size == 0) return NULL;

    /* fast path for native word size */
    if (src_numerator->size == 1 && src_denominator->size == 1){
        /* make sure this is not overwritten */
        bigint_word a = src_numerator->words[0];
        bigint_word b = src_denominator->words[0];
        bigint_from_word(quotient, a / b);
        bigint_from_word(remainder, a % b);
        quotient->neg = src_numerator_neg ^ src_denominator_neg;
        remainder->neg = src_numerator_neg;
        return dst_quotient;
    }

    /* fast path for half word size */
    if (src_denominator->size == 1 &&
        src_denominator->words[0] <= BIGINT_HALF_WORD_MAX
    ){
        bigint_word rem;
        bigint_cpy(quotient, src_numerator);
        bigint_div_mod_half_word(quotient, &rem, src_denominator->words[0]);
        bigint_from_word(remainder, rem);
        quotient->neg = src_numerator_neg ^ src_denominator_neg;
        remainder->neg = src_numerator_neg;
        return dst_quotient;
    }

    bigint_cpy(remainder, src_numerator);
    remainder->neg = 0;
    quotient->size = 0;

    if (bigint_cmp_abs(remainder, src_denominator) >= 0){
        shift = bigint_bitlength(remainder) - bigint_bitlength(src_denominator);

        bigint_init(denominator);
        bigint_shift_left(denominator, src_denominator, shift);
        denominator->neg = 0;

        /* divide bit by bit */
        for (; shift >= 0; shift--) {
            if (bigint_cmp_abs(remainder, denominator) >= 0) {
                bigint_sub(remainder, remainder, denominator);
                bigint_set_bit(quotient, shift);
            }
            bigint_shift_right(denominator, denominator, 1);
        }

        bigint_free(denominator);
    }

    quotient->neg = src_numerator_neg ^ src_denominator_neg;
    remainder->neg = src_numerator_neg;
    return dst_quotient;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq %rdx, 0x58(%rsp)
movq %rcx, 0x50(%rsp)
movq 0x58(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x48(%rsp)
movq 0x50(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x44(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x50(%rsp), %rax
cmpl $0x0, 0xc(%rax)
jne 0x473d
movq $0x0, 0x70(%rsp)
jmp 0x4956
movq 0x58(%rsp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x47c6
movq 0x50(%rsp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x47c6
movq 0x58(%rsp), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0xc(%rsp)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x8(%rsp)
movq 0x10(%rsp), %rdi
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl 0x8(%rsp)
movl %eax, %esi
callq 0x3a60
movq 0x18(%rsp), %rdi
movl 0xc(%rsp), %eax
xorl %edx, %edx
divl 0x8(%rsp)
movl %edx, %esi
callq 0x3a60
movl 0x48(%rsp), %ecx
xorl 0x44(%rsp), %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x8(%rax)
movl 0x48(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x4956
movq 0x50(%rsp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x4842
movq 0x50(%rsp), %rax
movq (%rax), %rax
cmpl $0xffff, (%rax)         # imm = 0xFFFF
ja 0x4842
movq 0x10(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x2580
movq 0x10(%rsp), %rdi
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl (%rax), %edx
leaq 0x4(%rsp), %rsi
callq 0x4960
movq 0x18(%rsp), %rdi
movl 0x4(%rsp), %esi
callq 0x3a60
movl 0x48(%rsp), %ecx
xorl 0x44(%rsp), %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x8(%rax)
movl 0x48(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x4956
movq 0x18(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x2580
movq 0x18(%rsp), %rax
movl $0x0, 0x8(%rax)
movq 0x10(%rsp), %rax
movl $0x0, 0xc(%rax)
movq 0x18(%rsp), %rdi
movq 0x50(%rsp), %rsi
callq 0x22c0
cmpl $0x0, %eax
jl 0x4930
movq 0x18(%rsp), %rdi
callq 0x4640
movl %eax, (%rsp)
movq 0x50(%rsp), %rdi
callq 0x4640
movl %eax, %ecx
movl (%rsp), %eax
subl %ecx, %eax
movl %eax, 0x4c(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x20a0
leaq 0x20(%rsp), %rdi
movq 0x50(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x44d0
movl $0x0, 0x28(%rsp)
cmpl $0x0, 0x4c(%rsp)
jl 0x4926
movq 0x18(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x22c0
cmpl $0x0, %eax
jl 0x4905
movq 0x18(%rsp), %rdi
movq 0x18(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x3de0
movq 0x10(%rsp), %rdi
movl 0x4c(%rsp), %esi
callq 0x2730
leaq 0x20(%rsp), %rdi
leaq 0x20(%rsp), %rsi
movl $0x1, %edx
callq 0x4570
movl 0x4c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x48c8
leaq 0x20(%rsp), %rdi
callq 0x21b0
movl 0x48(%rsp), %ecx
xorl 0x44(%rsp), %ecx
movq 0x10(%rsp), %rax
movl %ecx, 0x8(%rax)
movl 0x48(%rsp), %ecx
movq 0x18(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x68(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
addq $0x78, %rsp
retq