// File: night-shift[P]Srl/src/lib/fpconv/fpconv.c
// Function: generate_digits
static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K)
{
    uint64_t wfrac = upper->frac - fp->frac;
    uint64_t delta = upper->frac - lower->frac;

    Fp one;
    one.frac = 1ULL << -upper->exp;
    one.exp  = upper->exp;

    uint64_t part1 = upper->frac >> -one.exp;
    uint64_t part2 = upper->frac & (one.frac - 1);

    int idx = 0, kappa = 10;
    uint64_t* divp;
    /* 1000000000 */
    for(divp = tens + 10; kappa > 0; divp++) {

        uint64_t div = *divp;
        unsigned digit = part1 / div;

        if (digit || idx) {
            digits[idx++] = digit + '0';
        }

        part1 -= digit * div;
        kappa--;

        uint64_t tmp = (part1 <<-one.exp) + part2;
        if (tmp <= delta) {
            *K += kappa;
            round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac);

            return idx;
        }
    }

    /* 10 */
    uint64_t* unit = tens + 18;

    while(true) {
        part2 *= 10;
        delta *= 10;
        kappa--;

        unsigned digit = part2 >> -one.exp;
        if (digit || idx) {
            digits[idx++] = digit + '0';
        }

        part2 &= one.frac - 1;
        if (part2 < delta) {
            *K += kappa;
            round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit);

            return idx;
        }

        unit--;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
subq (%rcx), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
subq (%rcx), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rcx
xorl %eax, %eax
subl 0x8(%rcx), %eax
movl %eax, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
xorl %ecx, %ecx
subl -0x48(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x50(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
movl $0xa, -0x68(%rbp)
leaq 0x1daba(%rip), %rax     # 0x86400
addq $0x50, %rax
movq %rax, -0x70(%rbp)
cmpl $0x0, -0x68(%rbp)
jle 0x68a41
movq -0x70(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x58(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x78(%rbp)
movl %eax, -0x7c(%rbp)
cmpl $0x0, -0x7c(%rbp)
jne 0x6897e
cmpl $0x0, -0x64(%rbp)
je 0x6899b
movl -0x7c(%rbp), %eax
addl $0x30, %eax
movb %al, %dl
movq -0x28(%rbp), %rax
movl -0x64(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x64(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x7c(%rbp), %eax
movl %eax, %ecx
imulq -0x78(%rbp), %rcx
movq -0x58(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x58(%rbp)
movl -0x68(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x68(%rbp)
movq -0x58(%rbp), %rax
xorl %ecx, %ecx
subl -0x48(%rbp), %ecx
movl %ecx, %ecx
shlq %cl, %rax
addq -0x60(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x40(%rbp), %rax
ja 0x68a2e
movl -0x68(%rbp), %ecx
movq -0x30(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
movl -0x64(%rbp), %esi
movq -0x40(%rbp), %rdx
movq -0x88(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x78(%rbp), %r8
xorl %eax, %eax
subl -0x48(%rbp), %eax
movl %eax, %eax
movl %eax, %ecx
shlq %cl, %r8
movq -0xa0(%rbp), %rcx
movq -0x38(%rbp), %r9
callq 0x68b30
movl -0x64(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x68b1e
jmp 0x68a30
movq -0x70(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x70(%rbp)
jmp 0x6894e
leaq 0x1d9b8(%rip), %rax     # 0x86400
addq $0x90, %rax
movq %rax, -0x90(%rbp)
imulq $0xa, -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
imulq $0xa, -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movl -0x68(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x68(%rbp)
movq -0x60(%rbp), %rax
xorl %ecx, %ecx
subl -0x48(%rbp), %ecx
movl %ecx, %ecx
shrq %cl, %rax
movl %eax, -0x94(%rbp)
cmpl $0x0, -0x94(%rbp)
jne 0x68a93
cmpl $0x0, -0x64(%rbp)
je 0x68ab3
movl -0x94(%rbp), %eax
addl $0x30, %eax
movb %al, %dl
movq -0x28(%rbp), %rax
movl -0x64(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x64(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movq -0x50(%rbp), %rax
subq $0x1, %rax
andq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x68b07
movl -0x68(%rbp), %ecx
movq -0x30(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
movq -0x28(%rbp), %rdi
movl -0x64(%rbp), %esi
movq -0x40(%rbp), %rdx
movq -0x60(%rbp), %rcx
movq -0x50(%rbp), %r8
movq -0x38(%rbp), %r9
movq -0x90(%rbp), %rax
imulq (%rax), %r9
callq 0x68b30
movl -0x64(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x68b1e
movq -0x90(%rbp), %rax
addq $-0x8, %rax
movq %rax, -0x90(%rbp)
jmp 0x68a55
movl -0x4(%rbp), %eax
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)