#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
unsigned char SPECIAL_ltoa(long long, char *);
unsigned char SPECIAL_ftoa(double numero, int decimales, char *conv) {
  const long long dec[16] = {0,
                             10,
                             100,
                             1000,
                             10000,
                             100000,
                             1000000,
                             10000000,
                             100000000,
                             1000000000,
                             10000000000,
                             100000000000,
                             1000000000000,
                             10000000000000,
                             100000000000000,
                             1000000000000000};
  register long long deci = 0;
  register double decimal = 0;
  register unsigned char valores = 0;
  decimal = numero - (long long)numero;
  decimal *= dec[decimales];
  deci = (long long)decimal;
  if (deci < 0)
    deci *= -1;
  valores = SPECIAL_ltoa((long long)numero, conv);
  conv[valores] = '.';
  valores++;
  valores += SPECIAL_ltoa(deci, &conv[valores]);
  return valores;
}


x86 assembly (clang, -O0):
<SPECIAL_ftoa>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
lea    -0xa0(%rbp),%rdi
lea    0xebb(%rip),%rsi
mov    $0x80,%edx
call   1030 <memcpy@plt>
movq   $0x0,-0xa8(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movb   $0x0,-0xb1(%rbp)
movsd  -0x8(%rbp),%xmm0
cvttsd2si -0x8(%rbp),%rax
cvtsi2sd %rax,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movslq -0xc(%rbp),%rax
cvtsi2sdq -0xa0(%rbp,%rax,8),%xmm0
ff ff ff
mulsd  -0xb0(%rbp),%xmm0
ff
movsd  %xmm0,-0xb0(%rbp)
ff
cvttsd2si -0xb0(%rbp),%rax
ff ff
mov    %rax,-0xa8(%rbp)
cmpq   $0x0,-0xa8(%rbp)
jge    11d3 <SPECIAL_ftoa+0xb3>
imul   $0xffffffffffffffff,-0xa8(%rbp),%rax
ff
mov    %rax,-0xa8(%rbp)
cvttsd2si -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <SPECIAL_ltoa@plt>
mov    %al,-0xb1(%rbp)
mov    -0x18(%rbp),%rax
movzbl -0xb1(%rbp),%ecx
movb   $0x2e,(%rax,%rcx,1)
mov    -0xb1(%rbp),%al
add    $0x1,%al
mov    %al,-0xb1(%rbp)
mov    -0xa8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzbl -0xb1(%rbp),%eax
add    %rax,%rsi
call   1040 <SPECIAL_ltoa@plt>
movzbl %al,%ecx
movzbl -0xb1(%rbp),%eax
add    %ecx,%eax
mov    %al,-0xb1(%rbp)
movzbl -0xb1(%rbp),%eax
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<SPECIAL_ftoa>:
push   %r15
push   %r14
push   %rbx
cvttsd2si %xmm0,%rax
cvtsi2sd %rax,%xmm1
movslq %edi,%rcx
lea    0xed7(%rip),%rdx
cvtsi2sdq (%rdx,%rcx,8),%xmm2
subsd  %xmm1,%xmm0
mulsd  %xmm0,%xmm2
cvttsd2si %xmm2,%rcx
mov    %rsi,%r14
mov    %rcx,%rbx
neg    %rbx
cmovs  %rcx,%rbx
mov    %rax,%rdi
call   1030 <SPECIAL_ltoa@plt>
movzbl %al,%eax
movb   $0x2e,(%r14,%rax,1)
add    $0x1,%al
movzbl %al,%r15d
lea    (%r15,%r14,1),%rsi
mov    %rbx,%rdi
call   1030 <SPECIAL_ltoa@plt>
add    %r15b,%al
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@__const.SPECIAL_ftoa.dec = [16 x i64] [i64 0, i64 10, i64 100, i64 1000, i64 10000, i64 100000, i64 1000000, i64 10000000, i64 100000000, i64 1000000000, i64 10000000000, i64 100000000000, i64 1000000000000, i64 10000000000000, i64 100000000000000, i64 1000000000000000]
define zeroext i8 @SPECIAL_ftoa(double %0, i32 %1, i8* %2) {
%4 = alloca double
%5 = alloca i32
%6 = alloca i8*
%7 = alloca [16 x i64]
%8 = alloca i64
%9 = alloca double
%10 = alloca i8
store double %0, double* %4
store i32 %1, i32* %5
store i8* %2, i8** %6
%11 = bitcast [16 x i64]* %7 to i8*
store i64 0, i64* %8
store double 0.000000e+00, double* %9
store i8 0, i8* %10
%12 = load double, double* %4
%13 = load double, double* %4
%14 = fptosi double %13 to i64
%15 = sitofp i64 %14 to double
%16 = fsub double %12, %15
store double %16, double* %9
%17 = load i32, i32* %5
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds [16 x i64], [16 x i64]* %7, i64 0, i64 %18
%20 = load i64, i64* %19
%21 = sitofp i64 %20 to double
%22 = load double, double* %9
%23 = fmul double %22, %21
store double %23, double* %9
%24 = load double, double* %9
%25 = fptosi double %24 to i64
store i64 %25, i64* %8
%26 = load i64, i64* %8
%27 = icmp slt i64 %26, 0
br i1 %27, label %28, label %31
28: ; preds = %3
%29 = load i64, i64* %8
%30 = mul nsw i64 %29, -1
store i64 %30, i64* %8
br label %31
31: ; preds = %28, %3
%32 = load double, double* %4
%33 = fptosi double %32 to i64
%34 = load i8*, i8** %6
%35 = call zeroext i8 @SPECIAL_ltoa(i64 %33, i8* %34)
store i8 %35, i8* %10
%36 = load i8*, i8** %6
%37 = load i8, i8* %10
%38 = zext i8 %37 to i64
%39 = getelementptr inbounds i8, i8* %36, i64 %38
store i8 46, i8* %39
%40 = load i8, i8* %10
%41 = add i8 %40, 1
store i8 %41, i8* %10
%42 = load i64, i64* %8
%43 = load i8*, i8** %6
%44 = load i8, i8* %10
%45 = zext i8 %44 to i64
%46 = getelementptr inbounds i8, i8* %43, i64 %45
%47 = call zeroext i8 @SPECIAL_ltoa(i64 %42, i8* %46)
%48 = zext i8 %47 to i32
%49 = load i8, i8* %10
%50 = zext i8 %49 to i32
%51 = add nsw i32 %50, %48
%52 = trunc i32 %51 to i8
store i8 %52, i8* %10
%53 = load i8, i8* %10
ret i8 %53
}

LLVM IR (-O2):
@__const.SPECIAL_ftoa.dec = [16 x i64] [i64 0, i64 10, i64 100, i64 1000, i64 10000, i64 100000, i64 1000000, i64 10000000, i64 100000000, i64 1000000000, i64 10000000000, i64 100000000000, i64 1000000000000, i64 10000000000000, i64 100000000000000, i64 1000000000000000]
define zeroext i8 @SPECIAL_ftoa(double %0, i32 %1, i8* %2) {
%4 = fptosi double %0 to i64
%5 = sitofp i64 %4 to double
%6 = fsub double %0, %5
%7 = sext i32 %1 to i64
%8 = getelementptr inbounds [16 x i64], [16 x i64]* @__const.SPECIAL_ftoa.dec, i64 0, i64 %7
%9 = load i64, i64* %8
%10 = sitofp i64 %9 to double
%11 = fmul double %6, %10
%12 = fptosi double %11 to i64
%13 = tail call i64 @llvm.abs.i64(i64 %12, i1 true)
%14 = tail call zeroext i8 @SPECIAL_ltoa(i64 %4, i8* %2)
%15 = zext i8 %14 to i64
%16 = getelementptr inbounds i8, i8* %2, i64 %15
store i8 46, i8* %16
%17 = add i8 %14, 1
%18 = zext i8 %17 to i64
%19 = getelementptr inbounds i8, i8* %2, i64 %18
%20 = tail call zeroext i8 @SPECIAL_ltoa(i64 %13, i8* %19)
%21 = add i8 %20, %17
ret i8 %21
}