// File: /workspace/github_c_makefile_star2_O0/FredTheDino[P]Fog/src/engine/util/printf.c
// Function: ftoa(void (*)(char, void*, unsigned long, unsigned long), char*, unsigned long, unsigned long, double, unsigned int, unsigned int, unsigned int)
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
  char buf[PRINTF_FTOA_BUFFER_SIZE];
  size_t len  = 0U;
  double diff = 0.0;

  // powers of 10
  static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

  // test for special values
  if (value != value)
    return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
  if (value < -DBL_MAX)
    return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
  if (value > DBL_MAX)
    return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);

  // test for very large values
  // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
  if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
    return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
    return 0U;
#endif
  }

  // test for negative
  bool negative = false;
  if (value < 0) {
    negative = true;
    value = 0 - value;
  }

  // set default precision, if not set explicitly
  if (!(flags & FLAGS_PRECISION)) {
    prec = PRINTF_DEFAULT_FLOAT_PRECISION;
  }
  // limit precision to 9, cause a prec >= 10 can lead to overflow errors
  while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
    buf[len++] = '0';
    prec--;
  }

  int whole = (int)value;
  double tmp = (value - whole) * pow10[prec];
  unsigned long frac = (unsigned long)tmp;
  diff = tmp - frac;

  if (diff > 0.5) {
    ++frac;
    // handle rollover, e.g. case 0.99 with prec 1 is 1.0
    if (frac >= pow10[prec]) {
      frac = 0;
      ++whole;
    }
  }
  else if (diff < 0.5) {
  }
  else if ((frac == 0U) || (frac & 1U)) {
    // if halfway, round up if odd OR if last digit is 0
    ++frac;
  }

  if (prec == 0U) {
    diff = value - (double)whole;
    if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
      // exactly 0.5 and ODD, then round up
      // 1.5 -> 2, but 2.5 -> 2
      ++whole;
    }
  }
  else {
    unsigned int count = prec;
    // now do fractional part, as an unsigned number
    while (len < PRINTF_FTOA_BUFFER_SIZE) {
      --count;
      buf[len++] = (char)(48U + (frac % 10U));
      if (!(frac /= 10U)) {
        break;
      }
    }
    // add extra 0s
    while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
      buf[len++] = '0';
    }
    if (len < PRINTF_FTOA_BUFFER_SIZE) {
      // add decimal
      buf[len++] = '.';
    }
  }

  // do whole part, number is reversed
  while (len < PRINTF_FTOA_BUFFER_SIZE) {
    buf[len++] = (char)(48 + (whole % 10));
    if (!(whole /= 10)) {
      break;
    }
  }

  // pad leading zeros
  if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
    if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
      width--;
    }
    while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
      buf[len++] = '0';
    }
  }

  if (len < PRINTF_FTOA_BUFFER_SIZE) {
    if (negative) {
      buf[len++] = '-';
    }
    else if (flags & FLAGS_PLUS) {
      buf[len++] = '+';  // ignore the space if the '+' exists
    }
    else if (flags & FLAGS_SPACE) {
      buf[len++] = ' ';
    }
  }

  return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movl 0x10(%rbp), %eax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movsd %xmm0, -0x30(%rbp)
movl %r8d, -0x34(%rbp)
movl %r9d, -0x38(%rbp)
movq $0x0, -0x68(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x30(%rbp), %xmm0
ucomisd -0x30(%rbp), %xmm0
jne 0x3f5db
jp 0x3f5db
jmp 0x3f615
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl -0x38(%rbp), %r10d
movl 0x10(%rbp), %eax
leaq 0x80d9(%rip), %r8       # 0x476d2
movl $0x3, %r9d
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x40470
movq %rax, -0x8(%rbp)
jmp 0x3fb86
movsd 0x6453(%rip), %xmm0     # 0x45a70
ucomisd -0x30(%rbp), %xmm0
jbe 0x3f65e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl -0x38(%rbp), %r10d
movl 0x10(%rbp), %eax
leaq 0x8094(%rip), %r8       # 0x476d6
movl $0x4, %r9d
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x40470
movq %rax, -0x8(%rbp)
jmp 0x3fb86
movsd -0x30(%rbp), %xmm0
movsd 0x640d(%rip), %xmm1     # 0x45a78
ucomisd %xmm1, %xmm0
jbe 0x3f6dc
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl 0x10(%rbp), %r9d
andl $0x4, %r9d
leaq 0x8050(%rip), %r8       # 0x476e0
leaq 0x8044(%rip), %rax      # 0x476db
cmpl $0x0, %r9d
cmovneq %rax, %r8
movl 0x10(%rbp), %r10d
andl $0x4, %r10d
movl $0x3, %eax
movl $0x4, %r9d
cmpl $0x0, %r10d
cmovnel %r9d, %eax
movl %eax, %eax
movl %eax, %r9d
movl -0x38(%rbp), %r10d
movl 0x10(%rbp), %eax
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x40470
movq %rax, -0x8(%rbp)
jmp 0x3fb86
movsd -0x30(%rbp), %xmm0
movsd 0x6397(%rip), %xmm1     # 0x45a80
ucomisd %xmm1, %xmm0
ja 0x3f6fe
movsd 0x6391(%rip), %xmm0     # 0x45a88
ucomisd -0x30(%rbp), %xmm0
jbe 0x3f72f
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movsd -0x30(%rbp), %xmm0
movl -0x34(%rbp), %r8d
movl -0x38(%rbp), %r9d
movl 0x10(%rbp), %eax
movl %eax, (%rsp)
callq 0x3fba0
movq %rax, -0x8(%rbp)
jmp 0x3fb86
movb $0x0, -0x71(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x30(%rbp), %xmm0
jbe 0x3f74e
movb $0x1, -0x71(%rbp)
xorps %xmm0, %xmm0
subsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movl 0x10(%rbp), %eax
andl $0x400, %eax            # imm = 0x400
cmpl $0x0, %eax
jne 0x3f762
movl $0x6, -0x34(%rbp)
jmp 0x3f764
xorl %eax, %eax
cmpq $0x20, -0x68(%rbp)
movb %al, -0x8d(%rbp)
jae 0x3f780
cmpl $0x9, -0x34(%rbp)
seta %al
movb %al, -0x8d(%rbp)
movb -0x8d(%rbp), %al
testb $0x1, %al
jne 0x3f78c
jmp 0x3f7ab
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x30, -0x60(%rbp,%rax)
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3f764
cvttsd2si -0x30(%rbp), %eax
movl %eax, -0x78(%rbp)
movsd -0x30(%rbp), %xmm0
cvtsi2sdl -0x78(%rbp), %xmm1
subsd %xmm1, %xmm0
movl -0x34(%rbp), %eax
movl %eax, %ecx
leaq 0x61e3(%rip), %rax      # 0x459b0
movsd (%rax,%rcx,8), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rbp)
movsd -0x80(%rbp), %xmm0
movsd 0x62a8(%rip), %xmm2     # 0x45a90
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %rcx
cvttsd2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x88(%rbp)
movsd -0x80(%rbp), %xmm0
movaps 0x61f7(%rip), %xmm2     # 0x45a10
movq -0x88(%rbp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x61f3(%rip), %xmm2     # 0x45a20
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
movsd -0x70(%rbp), %xmm0
movsd 0x57fe(%rip), %xmm1     # 0x45050
ucomisd %xmm1, %xmm0
jbe 0x3f8bc
movq -0x88(%rbp), %rax
incq %rax
movq %rax, -0x88(%rbp)
movaps 0x61a0(%rip), %xmm1     # 0x45a10
movq -0x88(%rbp), %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x619c(%rip), %xmm1     # 0x45a20
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movl -0x34(%rbp), %eax
movl %eax, %ecx
leaq 0x6111(%rip), %rax      # 0x459b0
ucomisd (%rax,%rcx,8), %xmm0
jb 0x3f8ba
movq $0x0, -0x88(%rbp)
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x3f8fe
movsd 0x578c(%rip), %xmm0     # 0x45050
ucomisd -0x70(%rbp), %xmm0
jbe 0x3f8cd
jmp 0x3f8fc
cmpq $0x0, -0x88(%rbp)
je 0x3f8e8
movq -0x88(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x3f8fa
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x3f8fc
jmp 0x3f8fe
cmpl $0x0, -0x34(%rbp)
jne 0x3f952
movsd -0x30(%rbp), %xmm0
cvtsi2sdl -0x78(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
movsd 0x5731(%rip), %xmm0     # 0x45050
ucomisd -0x70(%rbp), %xmm0
jbe 0x3f939
movsd -0x70(%rbp), %xmm0
movsd 0x571d(%rip), %xmm1     # 0x45050
ucomisd %xmm1, %xmm0
jbe 0x3f94d
movl -0x78(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x3f94d
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x3fa2a
movl -0x34(%rbp), %eax
movl %eax, -0x8c(%rbp)
cmpq $0x20, -0x68(%rbp)
jae 0x3f9bd
movl -0x8c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x8c(%rbp)
movq -0x88(%rbp), %rax
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
addq $0x30, %rdx
movb %dl, %cl
movq -0x68(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x68(%rbp)
movb %cl, -0x60(%rbp,%rax)
movq -0x88(%rbp), %rax
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
jne 0x3f9bb
jmp 0x3f9bd
jmp 0x3f95b
jmp 0x3f9bf
xorl %eax, %eax
cmpq $0x20, -0x68(%rbp)
movb %al, -0x8e(%rbp)
jae 0x3f9eb
movl -0x8c(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x8c(%rbp)
cmpl $0x0, %eax
seta %al
movb %al, -0x8e(%rbp)
movb -0x8e(%rbp), %al
testb $0x1, %al
jne 0x3f9f7
jmp 0x3fa0d
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x30, -0x60(%rbp,%rax)
jmp 0x3f9bf
cmpq $0x20, -0x68(%rbp)
jae 0x3fa28
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x2e, -0x60(%rbp,%rax)
jmp 0x3fa2a
jmp 0x3fa2c
cmpq $0x20, -0x68(%rbp)
jae 0x3fa6d
movl -0x78(%rbp), %eax
movl $0xa, %ecx
cltd
idivl %ecx
addl $0x30, %edx
movb %dl, %cl
movq -0x68(%rbp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, -0x68(%rbp)
movb %cl, -0x60(%rbp,%rax)
movl -0x78(%rbp), %eax
movl $0xa, %ecx
cltd
idivl %ecx
movl %eax, -0x78(%rbp)
cmpl $0x0, %eax
jne 0x3fa6b
jmp 0x3fa6d
jmp 0x3fa2c
movl 0x10(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x3faed
movl 0x10(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x3faed
cmpl $0x0, -0x38(%rbp)
je 0x3faa3
testb $0x1, -0x71(%rbp)
jne 0x3fa9a
movl 0x10(%rbp), %eax
andl $0xc, %eax
cmpl $0x0, %eax
je 0x3faa3
movl -0x38(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x3faa5
movq -0x68(%rbp), %rcx
movl -0x38(%rbp), %eax
movl %eax, %edx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x8f(%rbp)
jae 0x3fac9
cmpq $0x20, -0x68(%rbp)
setb %al
movb %al, -0x8f(%rbp)
movb -0x8f(%rbp), %al
testb $0x1, %al
jne 0x3fad5
jmp 0x3faeb
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x30, -0x60(%rbp,%rax)
jmp 0x3faa5
jmp 0x3faed
cmpq $0x20, -0x68(%rbp)
jae 0x3fb56
testb $0x1, -0x71(%rbp)
je 0x3fb10
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x2d, -0x60(%rbp,%rax)
jmp 0x3fb54
movl 0x10(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x3fb31
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x2b, -0x60(%rbp,%rax)
jmp 0x3fb52
movl 0x10(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x3fb50
movq -0x68(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x68(%rbp)
movb $0x20, -0x60(%rbp,%rax)
jmp 0x3fb52
jmp 0x3fb54
jmp 0x3fb56
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq -0x60(%rbp), %r8
movq -0x68(%rbp), %r9
movl -0x38(%rbp), %r10d
movl 0x10(%rbp), %eax
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x40470
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)