void testReadDouble() {
  char str[255];
  char *msg = &str;
  char passed = 0;
  char signedChar;
  double signedDouble;
  printf("Testing fiolSReadDouble...\r\n");
  msg = "28 -4489.67 +42.888888";
  passed = 1;
  printf("\t(\"%s\")\r\n", msg);
  msg += fiolSReadDouble(msg, &signedDouble);
  if (signedDouble - 28 > 0.0001) {
    printf("\t\tfailed, returned %f instead of %f\r\n", signedDouble, 28.0);
    passed = 0;
  }
  msg += fiolSReadChar(msg, &signedChar);
  if (signedChar != ' ') {
    printf("\t\tfailed, returned '%c' instead of '%c'\r\n", signedChar, ' ');
    passed = 0;
  }
  msg += fiolSReadDouble(msg, &signedDouble);
  if (signedDouble - (-4489.67) > 0.0001) {
    printf("\t\tfailed, returned %f instead of %f\r\n", signedDouble, -4489.67);
    passed = 0;
  }
  msg += fiolSReadChar(msg, &signedChar);
  if (signedChar != ' ') {
    printf("\t\tfailed, returned '%c' instead of '%c'\r\n", signedChar, ' ');
    passed = 0;
  }
  msg += fiolSReadDouble(msg, &signedDouble);
  if (signedDouble - (+42.888888) > 0.0001) {
    printf("\t\tfailed, returned %f instead of %f\r\n", signedDouble,
           +42.888888);
    passed = 0;
  }
  if (passed == 1)
    printf("\t\tPassed!\r\n");
}


x86 assembly (clang, -O0):
<testReadDouble>:
push   %rbp
mov    %rsp,%rbp
sub    $0x120,%rsp
lea    -0x100(%rbp),%rax
mov    %rax,-0x108(%rbp)
movb   $0x0,-0x109(%rbp)
lea    0xec9(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xed8(%rip),%rax
mov    %rax,-0x108(%rbp)
movb   $0x1,-0x109(%rbp)
mov    -0x108(%rbp),%rsi
lea    0xed3(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x108(%rbp),%rdi
lea    -0x118(%rbp),%rsi
mov    $0x0,%al
call   1040 <fiolSReadDouble@plt>
mov    %eax,%ecx
mov    -0x108(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x108(%rbp)
movsd  -0x118(%rbp),%xmm0
ff
movsd  0xe45(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xe31(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11fe <testReadDouble+0xce>
movsd  -0x118(%rbp),%xmm0
ff
lea    0xe76(%rip),%rdi
movsd  0xe18(%rip),%xmm1
mov    $0x2,%al
call   1030 <printf@plt>
movb   $0x0,-0x109(%rbp)
mov    -0x108(%rbp),%rdi
lea    -0x10a(%rbp),%rsi
mov    $0x0,%al
call   1050 <fiolSReadChar@plt>
mov    %eax,%ecx
mov    -0x108(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x108(%rbp)
movsbl -0x10a(%rbp),%eax
cmp    $0x20,%eax
je     125a <testReadDouble+0x12a>
movsbl -0x10a(%rbp),%esi
lea    0xe3d(%rip),%rdi
mov    $0x20,%edx
mov    $0x0,%al
call   1030 <printf@plt>
movb   $0x0,-0x109(%rbp)
mov    -0x108(%rbp),%rdi
lea    -0x118(%rbp),%rsi
mov    $0x0,%al
call   1040 <fiolSReadDouble@plt>
mov    %eax,%ecx
mov    -0x108(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x108(%rbp)
movsd  -0x118(%rbp),%xmm0
ff
movsd  0xd7b(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xd5f(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12d0 <testReadDouble+0x1a0>
movsd  -0x118(%rbp),%xmm0
ff
lea    0xda4(%rip),%rdi
movsd  0xd4e(%rip),%xmm1
mov    $0x2,%al
call   1030 <printf@plt>
movb   $0x0,-0x109(%rbp)
mov    -0x108(%rbp),%rdi
lea    -0x10a(%rbp),%rsi
mov    $0x0,%al
call   1050 <fiolSReadChar@plt>
mov    %eax,%ecx
mov    -0x108(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x108(%rbp)
movsbl -0x10a(%rbp),%eax
cmp    $0x20,%eax
je     132c <testReadDouble+0x1fc>
movsbl -0x10a(%rbp),%esi
lea    0xd6b(%rip),%rdi
mov    $0x20,%edx
mov    $0x0,%al
call   1030 <printf@plt>
movb   $0x0,-0x109(%rbp)
mov    -0x108(%rbp),%rdi
lea    -0x118(%rbp),%rsi
mov    $0x0,%al
call   1040 <fiolSReadDouble@plt>
mov    %eax,%ecx
mov    -0x108(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x108(%rbp)
movsd  -0x118(%rbp),%xmm0
ff
movsd  0xcb1(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  0xc8d(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    13a2 <testReadDouble+0x272>
movsd  -0x118(%rbp),%xmm0
ff
lea    0xcd2(%rip),%rdi
movsd  0xc84(%rip),%xmm1
mov    $0x2,%al
call   1030 <printf@plt>
movb   $0x0,-0x109(%rbp)
movsbl -0x109(%rbp),%eax
cmp    $0x1,%eax
jne    13c0 <testReadDouble+0x290>
lea    0xcf5(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
add    $0x120,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<testReadDouble>:
push   %rbp
push   %r14
push   %rbx
sub    $0x10,%rsp
lea    0xf5a(%rip),%rdi
call   1030 <puts@plt>
lea    0xef4(%rip),%rdi
lea    0xed6(%rip),%rbx
mov    %rbx,%rsi
xor    %eax,%eax
call   1040 <printf@plt>
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
xor    %eax,%eax
call   1050 <fiolSReadDouble@plt>
movslq %eax,%r14
add    %rbx,%r14
movsd  0x8(%rsp),%xmm0
movsd  0xe71(%rip),%xmm1
addsd  %xmm0,%xmm1
mov    $0x1,%ebp
ucomisd 0xe68(%rip),%xmm1
jbe    11ba <testReadDouble+0x7a>
lea    0xeb0(%rip),%rdi
movsd  0xe5f(%rip),%xmm1
mov    $0x2,%al
call   1040 <printf@plt>
xor    %ebp,%ebp
lea    0x7(%rsp),%rsi
mov    %r14,%rdi
xor    %eax,%eax
call   1060 <fiolSReadChar@plt>
movslq %eax,%rbx
add    %r14,%rbx
movsbl 0x7(%rsp),%esi
cmp    $0x20,%esi
je     11ee <testReadDouble+0xae>
lea    0xe9f(%rip),%rdi
mov    $0x20,%edx
xor    %eax,%eax
call   1040 <printf@plt>
xor    %ebp,%ebp
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
xor    %eax,%eax
call   1050 <fiolSReadDouble@plt>
movslq %eax,%r14
add    %rbx,%r14
movsd  0x8(%rsp),%xmm0
movsd  0xe07(%rip),%xmm1
addsd  %xmm0,%xmm1
ucomisd 0xdeb(%rip),%xmm1
jbe    1237 <testReadDouble+0xf7>
lea    0xe33(%rip),%rdi
movsd  0xdf2(%rip),%xmm1
mov    $0x2,%al
call   1040 <printf@plt>
xor    %ebp,%ebp
lea    0x7(%rsp),%rsi
mov    %r14,%rdi
xor    %eax,%eax
call   1060 <fiolSReadChar@plt>
movslq %eax,%rbx
add    %r14,%rbx
movsbl 0x7(%rsp),%esi
cmp    $0x20,%esi
je     126b <testReadDouble+0x12b>
lea    0xe22(%rip),%rdi
mov    $0x20,%edx
xor    %eax,%eax
call   1040 <printf@plt>
xor    %ebp,%ebp
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
xor    %eax,%eax
call   1050 <fiolSReadDouble@plt>
movsd  0x8(%rsp),%xmm0
movsd  0xda0(%rip),%xmm1
addsd  %xmm0,%xmm1
ucomisd 0xd74(%rip),%xmm1
jbe    12ae <testReadDouble+0x16e>
lea    0xdbc(%rip),%rdi
movsd  0xd8b(%rip),%xmm1
mov    $0x2,%al
call   1040 <printf@plt>
jmp    12be <testReadDouble+0x17e>
test   %ebp,%ebp
je     12be <testReadDouble+0x17e>
lea    0xe0c(%rip),%rdi
call   1030 <puts@plt>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
@.str = [29 x i8] c"Testing fiolSReadDouble...\0D\0A\00"
@.str.1 = [23 x i8] c"28 -4489.67 +42.888888\00"
@.str.2 = [10 x i8] c"\09(\22%s\22)\0D\0A\00"
@.str.3 = [38 x i8] c"\09\09failed, returned %f instead of %f\0D\0A\00"
@.str.4 = [42 x i8] c"\09\09failed, returned '%c' instead of '%c'\0D\0A\00"
@.str.5 = [12 x i8] c"\09\09Passed!\0D\0A\00"
define void @testReadDouble() {
%1 = alloca [255 x i8]
%2 = alloca i8*
%3 = alloca i8
%4 = alloca i8
%5 = alloca double
%6 = bitcast [255 x i8]* %1 to i8*
store i8* %6, i8** %2
store i8 0, i8* %3
%7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0))
store i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), i8** %2
store i8 1, i8* %3
%8 = load i8*, i8** %2
%9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* %8)
%10 = load i8*, i8** %2
%11 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* %10, double* %5)
%12 = load i8*, i8** %2
%13 = sext i32 %11 to i64
%14 = getelementptr inbounds i8, i8* %12, i64 %13
store i8* %14, i8** %2
%15 = load double, double* %5
%16 = fsub double %15, 2.800000e+01
%17 = fcmp ogt double %16, 1.000000e-04
br i1 %17, label %18, label %21
18: ; preds = %0
%19 = load double, double* %5
%20 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %19, double 2.800000e+01)
store i8 0, i8* %3
br label %21
21: ; preds = %18, %0
%22 = load i8*, i8** %2
%23 = call i32 (i8*, i8*, ...) bitcast (i32 (...)* @fiolSReadChar to i32 (i8*, i8*, ...)*)(i8* %22, i8* %4)
%24 = load i8*, i8** %2
%25 = sext i32 %23 to i64
%26 = getelementptr inbounds i8, i8* %24, i64 %25
store i8* %26, i8** %2
%27 = load i8, i8* %4
%28 = sext i8 %27 to i32
%29 = icmp ne i32 %28, 32
br i1 %29, label %30, label %34
30: ; preds = %21
%31 = load i8, i8* %4
%32 = sext i8 %31 to i32
%33 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.4, i64 0, i64 0), i32 %32, i32 32)
store i8 0, i8* %3
br label %34
34: ; preds = %30, %21
%35 = load i8*, i8** %2
%36 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* %35, double* %5)
%37 = load i8*, i8** %2
%38 = sext i32 %36 to i64
%39 = getelementptr inbounds i8, i8* %37, i64 %38
store i8* %39, i8** %2
%40 = load double, double* %5
%41 = fsub double %40, -4.489670e+03
%42 = fcmp ogt double %41, 1.000000e-04
br i1 %42, label %43, label %46
43: ; preds = %34
%44 = load double, double* %5
%45 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %44, double -4.489670e+03)
store i8 0, i8* %3
br label %46
46: ; preds = %43, %34
%47 = load i8*, i8** %2
%48 = call i32 (i8*, i8*, ...) bitcast (i32 (...)* @fiolSReadChar to i32 (i8*, i8*, ...)*)(i8* %47, i8* %4)
%49 = load i8*, i8** %2
%50 = sext i32 %48 to i64
%51 = getelementptr inbounds i8, i8* %49, i64 %50
store i8* %51, i8** %2
%52 = load i8, i8* %4
%53 = sext i8 %52 to i32
%54 = icmp ne i32 %53, 32
br i1 %54, label %55, label %59
55: ; preds = %46
%56 = load i8, i8* %4
%57 = sext i8 %56 to i32
%58 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str.4, i64 0, i64 0), i32 %57, i32 32)
store i8 0, i8* %3
br label %59
59: ; preds = %55, %46
%60 = load i8*, i8** %2
%61 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* %60, double* %5)
%62 = load i8*, i8** %2
%63 = sext i32 %61 to i64
%64 = getelementptr inbounds i8, i8* %62, i64 %63
store i8* %64, i8** %2
%65 = load double, double* %5
%66 = fsub double %65, 0x404571C714FCE747
%67 = fcmp ogt double %66, 1.000000e-04
br i1 %67, label %68, label %71
68: ; preds = %59
%69 = load double, double* %5
%70 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %69, double 0x404571C714FCE747)
store i8 0, i8* %3
br label %71
71: ; preds = %68, %59
%72 = load i8, i8* %3
%73 = sext i8 %72 to i32
%74 = icmp eq i32 %73, 1
br i1 %74, label %75, label %77
75: ; preds = %71
%76 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.5, i64 0, i64 0))
br label %77
77: ; preds = %75, %71
ret void
}

LLVM IR (-O2):
@.str.1 = [23 x i8] c"28 -4489.67 +42.888888\00"
@.str.2 = [10 x i8] c"\09(\22%s\22)\0D\0A\00"
@.str.3 = [38 x i8] c"\09\09failed, returned %f instead of %f\0D\0A\00"
@.str.4 = [42 x i8] c"\09\09failed, returned '%c' instead of '%c'\0D\0A\00"
@str = [28 x i8] c"Testing fiolSReadDouble...\0D\00"
@str.6 = [11 x i8] c"\09\09Passed!\0D\00"
define void @testReadDouble() {
%1 = alloca i8
%2 = alloca double
%3 = bitcast double* %2 to i8*
%4 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([28 x i8], [28 x i8]* @str, i64 0, i64 0))
%5 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0))
%6 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.1, i64 0, i64 0), double* %2)
%7 = sext i32 %6 to i64
%8 = getelementptr inbounds [23 x i8], [23 x i8]* @.str.1, i64 0, i64 %7
%9 = load double, double* %2
%10 = fadd double %9, -2.800000e+01
%11 = fcmp ogt double %10, 1.000000e-04
br i1 %11, label %12, label %14
12: ; preds = %0
%13 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %9, double 2.800000e+01)
br label %14
14: ; preds = %12, %0
%15 = phi i32 [ 0, %12 ], [ 1, %0 ]
%16 = call i32 (i8*, i8*, ...) bitcast (i32 (...)* @fiolSReadChar to i32 (i8*, i8*, ...)*)(i8* %8, i8* %1)
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %8, i64 %17
%19 = load i8, i8* %1
%20 = icmp eq i8 %19, 32
br i1 %20, label %24, label %21
21: ; preds = %14
%22 = sext i8 %19 to i32
%23 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([42 x i8], [42 x i8]* @.str.4, i64 0, i64 0), i32 %22, i32 32)
br label %24
24: ; preds = %21, %14
%25 = phi i32 [ 0, %21 ], [ %15, %14 ]
%26 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* %18, double* %2)
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i8, i8* %18, i64 %27
%29 = load double, double* %2
%30 = fadd double %29, 4.489670e+03
%31 = fcmp ogt double %30, 1.000000e-04
br i1 %31, label %32, label %34
32: ; preds = %24
%33 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %29, double -4.489670e+03)
br label %34
34: ; preds = %32, %24
%35 = phi i32 [ 0, %32 ], [ %25, %24 ]
%36 = call i32 (i8*, i8*, ...) bitcast (i32 (...)* @fiolSReadChar to i32 (i8*, i8*, ...)*)(i8* %28, i8* %1)
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds i8, i8* %28, i64 %37
%39 = load i8, i8* %1
%40 = icmp eq i8 %39, 32
br i1 %40, label %44, label %41
41: ; preds = %34
%42 = sext i8 %39 to i32
%43 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([42 x i8], [42 x i8]* @.str.4, i64 0, i64 0), i32 %42, i32 32)
br label %44
44: ; preds = %41, %34
%45 = phi i32 [ 0, %41 ], [ %35, %34 ]
%46 = call i32 (i8*, double*, ...) bitcast (i32 (...)* @fiolSReadDouble to i32 (i8*, double*, ...)*)(i8* %38, double* %2)
%47 = load double, double* %2
%48 = fadd double %47, 0xC04571C714FCE747
%49 = fcmp ogt double %48, 1.000000e-04
br i1 %49, label %50, label %52
50: ; preds = %44
%51 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([38 x i8], [38 x i8]* @.str.3, i64 0, i64 0), double %47, double 0x404571C714FCE747)
br label %56
52: ; preds = %44
%53 = icmp eq i32 %45, 1
br i1 %53, label %54, label %56
54: ; preds = %52
%55 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @str.6, i64 0, i64 0))
br label %56
56: ; preds = %50, %54, %52
ret void
}