// File: /workspace/github_c_makefile_star2_O0/janet-lang[P]janet/src/core/strtod.c
// Function: convert
static double convert(
    int negative,
    struct BigNat *mant,
    int32_t base,
    int32_t exponent) {

    int32_t exponent2 = 0;

    /* Approximate exponent in base 2 of mant and exponent. This should get us a good estimate of the final size of the
     * number, within * 2^32 or so. */
    int64_t mant_exp2_approx = mant->n * 32 + 16;
    int64_t exp_exp2_approx = (int64_t)(floor(log2(base) * exponent));
    int64_t exp2_approx = mant_exp2_approx + exp_exp2_approx;

    /* Short circuit zero, huge, and small numbers. We use the exponent range of valid IEEE754 doubles (-1022, 1023)
     * with a healthy buffer to allow for inaccuracies in the approximation and denormailzed numbers. */
    if (mant->n == 0 && mant->first_digit == 0)
        return negative ? -0.0 : 0.0;
    if (exp2_approx > 1176)
        return negative ? -INFINITY : INFINITY;
    if (exp2_approx < -1175)
        return negative ? -0.0 : 0.0;

    /* Final value is X = mant * base ^ exponent * 2 ^ exponent2
     * Get exponent to zero while holding X constant. */

    /* Positive exponents are simple */
    for (; exponent > 3; exponent -= 4) bignat_muladd(mant, base * base * base * base, 0);
    for (; exponent > 1; exponent -= 2) bignat_muladd(mant, base * base, 0);
    for (; exponent > 0; exponent -= 1) bignat_muladd(mant, base, 0);

    /* Negative exponents are tricky - we don't want to loose bits
     * from integer division, so we need to premultiply. */
    if (exponent < 0) {
        int32_t shamt = 5 - exponent / 4;
        bignat_lshift_n(mant, shamt);
        exponent2 -= shamt * BIGNAT_NBIT;
        for (; exponent < -3; exponent += 4) bignat_div(mant, base * base * base * base);
        for (; exponent < -1; exponent += 2) bignat_div(mant, base * base);
        for (; exponent <  0; exponent += 1) bignat_div(mant, base);
    }

    return negative
           ? -bignat_extract(mant, exponent2)
           : bignat_extract(mant, exponent2);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
shll $0x5, %eax
addl $0x10, %eax
cltq
movq %rax, -0x30(%rbp)
cvtsi2sdl -0x1c(%rbp), %xmm0
callq 0x120e0
cvtsi2sdl -0x20(%rbp), %xmm1
mulsd %xmm1, %xmm0
callq 0x12a00
cvttsd2si %xmm0, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
addq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jne 0x669c8
movq -0x18(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x669c8
movl -0xc(%rbp), %eax
movsd 0x30f4b(%rip), %xmm0    # 0x978e8
xorps %xmm1, %xmm1
movsd %xmm1, -0x58(%rbp)
cmpl $0x0, %eax
movsd %xmm0, -0x50(%rbp)
jne 0x669b9
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x66bb5
cmpq $0x498, -0x40(%rbp)     # imm = 0x498
jle 0x66a11
movl -0xc(%rbp), %eax
movss 0x30f13(%rip), %xmm0    # 0x978f0
movss 0x30f0f(%rip), %xmm1    # 0x978f4
movss %xmm1, -0x60(%rbp)
cmpl $0x0, %eax
movss %xmm0, -0x5c(%rbp)
jne 0x669fe
movss -0x60(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movss -0x5c(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x66bb5
cmpq $-0x497, -0x40(%rbp)    # imm = 0xFB69
jge 0x66a51
movl -0xc(%rbp), %eax
movsd 0x30ec2(%rip), %xmm0    # 0x978e8
xorps %xmm1, %xmm1
movsd %xmm1, -0x70(%rbp)
cmpl $0x0, %eax
movsd %xmm0, -0x68(%rbp)
jne 0x66a42
movsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x66bb5
jmp 0x66a53
cmpl $0x3, -0x20(%rbp)
jle 0x66a7e
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
xorl %edx, %edx
callq 0x66850
movl -0x20(%rbp), %eax
subl $0x4, %eax
movl %eax, -0x20(%rbp)
jmp 0x66a53
jmp 0x66a80
cmpl $0x1, -0x20(%rbp)
jle 0x66aa3
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
xorl %edx, %edx
callq 0x66850
movl -0x20(%rbp), %eax
subl $0x2, %eax
movl %eax, -0x20(%rbp)
jmp 0x66a80
jmp 0x66aa5
cmpl $0x0, -0x20(%rbp)
jle 0x66ac4
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
xorl %edx, %edx
callq 0x66850
movl -0x20(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x66aa5
cmpl $0x0, -0x20(%rbp)
jge 0x66b6a
movl -0x20(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl $0x5, %eax
subl %ecx, %eax
movl %eax, -0x44(%rbp)
movq -0x18(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x673b0
imull $0x1f, -0x44(%rbp), %ecx
movl -0x24(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x24(%rbp)
cmpl $-0x3, -0x20(%rbp)
jge 0x66b26
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
callq 0x67450
movl -0x20(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x20(%rbp)
jmp 0x66afd
jmp 0x66b28
cmpl $-0x1, -0x20(%rbp)
jge 0x66b49
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
imull -0x1c(%rbp), %esi
callq 0x67450
movl -0x20(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x20(%rbp)
jmp 0x66b28
jmp 0x66b4b
cmpl $0x0, -0x20(%rbp)
jge 0x66b68
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
callq 0x67450
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x66b4b
jmp 0x66b6a
cmpl $0x0, -0xc(%rbp)
je 0x66b9a
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x67570
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x78(%rbp)
jmp 0x66bab
movq -0x18(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x67570
movsd %xmm0, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)