#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 */
scalar_t__ nsvg__isdigit(char);
double pow(double, double);
long strtol(char *, char **, int);
long long strtoll(char *, char **, int);
double nsvg__atof(const char *s) {
  char *cur = (char *)s;
  char *end = NULL;
  double res = 0.0, sign = 1.0;
  long long intPart = 0, fracPart = 0;
  char hasIntPart = 0, hasFracPart = 0;
  if (*cur == '+') {
    cur++;
  } else if (*cur == '-') {
    sign = -1;
    cur++;
  }
  if (nsvg__isdigit(*cur)) {
    intPart = strtoll(cur, &end, 10);
    if (cur != end) {
      res = (double)intPart;
      hasIntPart = 1;
      cur = end;
    }
  }
  if (*cur == '.') {
    cur++;
    if (nsvg__isdigit(*cur)) {
      fracPart = strtoll(cur, &end, 10);
      if (cur != end) {
        res += (double)fracPart / pow(10.0, (double)(end - cur));
        hasFracPart = 1;
        cur = end;
      }
    }
  }
  if (!hasIntPart && !hasFracPart)
    return 0.0;
  if (*cur == 'e' || *cur == 'E') {
    long expPart = 0;
    cur++;
    expPart = strtol(cur, &end, 10);
    if (cur != end) {
      res *= pow(10.0, (double)expPart);
    }
  }
  return res * sign;
}


x86 assembly (clang, -O0):
<nsvg__atof>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xe94(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
movb   $0x0,-0x41(%rbp)
movb   $0x0,-0x42(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2b,%eax
jne    11aa <nsvg__atof+0x6a>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    11d8 <nsvg__atof+0x98>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    11d3 <nsvg__atof+0x93>
movsd  0xe46(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    11d8 <nsvg__atof+0x98>
mov    -0x18(%rbp),%rax
movsbl (%rax),%edi
call   1030 <nsvg__isdigit@plt>
cmp    $0x0,%rax
je     122e <nsvg__atof+0xee>
mov    -0x18(%rbp),%rdi
lea    -0x20(%rbp),%rsi
mov    $0xa,%edx
call   1040 <strtoll@plt>
mov    %rax,-0x38(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
je     1229 <nsvg__atof+0xe9>
cvtsi2sdq -0x38(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movb   $0x1,-0x41(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x18(%rbp)
jmp    122e <nsvg__atof+0xee>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    12d8 <nsvg__atof+0x198>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%edi
call   1030 <nsvg__isdigit@plt>
cmp    $0x0,%rax
je     12d3 <nsvg__atof+0x193>
mov    -0x18(%rbp),%rdi
lea    -0x20(%rbp),%rsi
mov    $0xa,%edx
call   1040 <strtoll@plt>
mov    %rax,-0x40(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
je     12ce <nsvg__atof+0x18e>
cvtsi2sdq -0x40(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    %rcx,%rax
cvtsi2sd %rax,%xmm1
movsd  0xd69(%rip),%xmm0
call   1060 <pow@plt>
movaps %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
divsd  %xmm1,%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movb   $0x1,-0x42(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x18(%rbp)
jmp    12d3 <nsvg__atof+0x193>
jmp    12d8 <nsvg__atof+0x198>
cmpb   $0x0,-0x41(%rbp)
jne    12f9 <nsvg__atof+0x1b9>
cmpb   $0x0,-0x42(%rbp)
jne    12f9 <nsvg__atof+0x1b9>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1382 <nsvg__atof+0x242>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x65,%eax
je     1319 <nsvg__atof+0x1d9>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x45,%eax
jne    1373 <nsvg__atof+0x233>
movq   $0x0,-0x50(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
lea    -0x20(%rbp),%rsi
mov    $0xa,%edx
call   1050 <strtol@plt>
mov    %rax,-0x50(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
je     136e <nsvg__atof+0x22e>
cvtsi2sdq -0x50(%rbp),%xmm1
movsd  0xcb1(%rip),%xmm0
call   1060 <pow@plt>
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    1373 <nsvg__atof+0x233>
movsd  -0x28(%rbp),%xmm0
mulsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nsvg__atof>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %rdi,%rbx
movq   $0x0,0x8(%rsp)
mov    (%rdi),%al
cmp    $0x2d,%al
je     1172 <nsvg__atof+0x32>
movsd  0xe9e(%rip),%xmm0
cmp    $0x2b,%al
movsd  %xmm0,0x10(%rsp)
jne    1184 <nsvg__atof+0x44>
add    $0x1,%rbx
jmp    1184 <nsvg__atof+0x44>
add    $0x1,%rbx
movsd  0xe8a(%rip),%xmm0
movsd  %xmm0,0x10(%rsp)
movsbl (%rbx),%edi
call   1030 <nsvg__isdigit@plt>
xorpd  %xmm1,%xmm1
test   %rax,%rax
je     11c9 <nsvg__atof+0x89>
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
mov    $0xa,%edx
call   1040 <strtoll@plt>
mov    0x8(%rsp),%rcx
cmp    %rcx,%rbx
je     11d5 <nsvg__atof+0x95>
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
mov    $0x1,%bpl
mov    %rcx,%rbx
cmpb   $0x2e,(%rbx)
je     11e0 <nsvg__atof+0xa0>
jmp    1256 <nsvg__atof+0x116>
xor    %ebp,%ebp
cmpb   $0x2e,(%rbx)
je     11e0 <nsvg__atof+0xa0>
jmp    1256 <nsvg__atof+0x116>
xor    %ebp,%ebp
xorpd  %xmm1,%xmm1
cmpb   $0x2e,(%rbx)
jne    1256 <nsvg__atof+0x116>
movsd  %xmm1,(%rsp)
movsbl 0x1(%rbx),%edi
add    $0x1,%rbx
call   1030 <nsvg__isdigit@plt>
test   %rax,%rax
je     1251 <nsvg__atof+0x111>
lea    0x8(%rsp),%rsi
mov    %rbx,%rdi
mov    $0xa,%edx
call   1040 <strtoll@plt>
mov    0x8(%rsp),%r14
cmp    %r14,%rbx
je     1251 <nsvg__atof+0x111>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
movsd  %xmm0,0x18(%rsp)
mov    %r14,%rax
sub    %rbx,%rax
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
movsd  0xdd9(%rip),%xmm0
call   1060 <pow@plt>
movsd  0x18(%rsp),%xmm2
divsd  %xmm0,%xmm2
movsd  (%rsp),%xmm1
addsd  %xmm2,%xmm1
jmp    1262 <nsvg__atof+0x122>
movsd  (%rsp),%xmm1
xorpd  %xmm0,%xmm0
mov    %rbx,%r14
test   %bpl,%bpl
je     12c2 <nsvg__atof+0x182>
mov    (%r14),%al
or     $0x20,%al
cmp    $0x65,%al
jne    12ab <nsvg__atof+0x16b>
movsd  %xmm1,(%rsp)
add    $0x1,%r14
lea    0x8(%rsp),%rsi
mov    %r14,%rdi
mov    $0xa,%edx
call   1050 <strtol@plt>
cmp    0x8(%rsp),%r14
je     12b3 <nsvg__atof+0x173>
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
movsd  0xd73(%rip),%xmm0
call   1060 <pow@plt>
movsd  (%rsp),%xmm1
mulsd  %xmm0,%xmm1
movsd  0x10(%rsp),%xmm0
jmp    12be <nsvg__atof+0x17e>
movsd  0x10(%rsp),%xmm0
movsd  (%rsp),%xmm1
mulsd  %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define double @nsvg__atof(i8* %0) {
%2 = alloca double
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca double
%7 = alloca double
%8 = alloca i64
%9 = alloca i64
%10 = alloca i8
%11 = alloca i8
%12 = alloca i64
store i8* %0, i8** %3
%13 = load i8*, i8** %3
store i8* %13, i8** %4
store i8* null, i8** %5
store double 0.000000e+00, double* %6
store double 1.000000e+00, double* %7
store i64 0, i64* %8
store i64 0, i64* %9
store i8 0, i8* %10
store i8 0, i8* %11
%14 = load i8*, i8** %4
%15 = load i8, i8* %14
%16 = sext i8 %15 to i32
%17 = icmp eq i32 %16, 43
br i1 %17, label %18, label %21
18: ; preds = %1
%19 = load i8*, i8** %4
%20 = getelementptr inbounds i8, i8* %19, i32 1
store i8* %20, i8** %4
br label %30
21: ; preds = %1
%22 = load i8*, i8** %4
%23 = load i8, i8* %22
%24 = sext i8 %23 to i32
%25 = icmp eq i32 %24, 45
br i1 %25, label %26, label %29
26: ; preds = %21
store double -1.000000e+00, double* %7
%27 = load i8*, i8** %4
%28 = getelementptr inbounds i8, i8* %27, i32 1
store i8* %28, i8** %4
br label %29
29: ; preds = %26, %21
br label %30
30: ; preds = %29, %18
%31 = load i8*, i8** %4
%32 = load i8, i8* %31
%33 = call i64 @nsvg__isdigit(i8 signext %32)
%34 = icmp ne i64 %33, 0
br i1 %34, label %35, label %46
35: ; preds = %30
%36 = load i8*, i8** %4
%37 = call i64 @strtoll(i8* %36, i8** %5, i32 10)
store i64 %37, i64* %8
%38 = load i8*, i8** %4
%39 = load i8*, i8** %5
%40 = icmp ne i8* %38, %39
br i1 %40, label %41, label %45
41: ; preds = %35
%42 = load i64, i64* %8
%43 = sitofp i64 %42 to double
store double %43, double* %6
store i8 1, i8* %10
%44 = load i8*, i8** %5
store i8* %44, i8** %4
br label %45
45: ; preds = %41, %35
br label %46
46: ; preds = %45, %30
%47 = load i8*, i8** %4
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = icmp eq i32 %49, 46
br i1 %50, label %51, label %80
51: ; preds = %46
%52 = load i8*, i8** %4
%53 = getelementptr inbounds i8, i8* %52, i32 1
store i8* %53, i8** %4
%54 = load i8*, i8** %4
%55 = load i8, i8* %54
%56 = call i64 @nsvg__isdigit(i8 signext %55)
%57 = icmp ne i64 %56, 0
br i1 %57, label %58, label %79
58: ; preds = %51
%59 = load i8*, i8** %4
%60 = call i64 @strtoll(i8* %59, i8** %5, i32 10)
store i64 %60, i64* %9
%61 = load i8*, i8** %4
%62 = load i8*, i8** %5
%63 = icmp ne i8* %61, %62
br i1 %63, label %64, label %78
64: ; preds = %58
%65 = load i64, i64* %9
%66 = sitofp i64 %65 to double
%67 = load i8*, i8** %5
%68 = load i8*, i8** %4
%69 = ptrtoint i8* %67 to i64
%70 = ptrtoint i8* %68 to i64
%71 = sub i64 %69, %70
%72 = sitofp i64 %71 to double
%73 = call double @pow(double 1.000000e+01, double %72)
%74 = fdiv double %66, %73
%75 = load double, double* %6
%76 = fadd double %75, %74
store double %76, double* %6
store i8 1, i8* %11
%77 = load i8*, i8** %5
store i8* %77, i8** %4
br label %78
78: ; preds = %64, %58
br label %79
79: ; preds = %78, %51
br label %80
80: ; preds = %79, %46
%81 = load i8, i8* %10
%82 = icmp ne i8 %81, 0
br i1 %82, label %87, label %83
83: ; preds = %80
%84 = load i8, i8* %11
%85 = icmp ne i8 %84, 0
br i1 %85, label %87, label %86
86: ; preds = %83
store double 0.000000e+00, double* %2
br label %116
87: ; preds = %83, %80
%88 = load i8*, i8** %4
%89 = load i8, i8* %88
%90 = sext i8 %89 to i32
%91 = icmp eq i32 %90, 101
br i1 %91, label %97, label %92
92: ; preds = %87
%93 = load i8*, i8** %4
%94 = load i8, i8* %93
%95 = sext i8 %94 to i32
%96 = icmp eq i32 %95, 69
br i1 %96, label %97, label %112
97: ; preds = %92, %87
store i64 0, i64* %12
%98 = load i8*, i8** %4
%99 = getelementptr inbounds i8, i8* %98, i32 1
store i8* %99, i8** %4
%100 = load i8*, i8** %4
%101 = call i64 @strtol(i8* %100, i8** %5, i32 10)
store i64 %101, i64* %12
%102 = load i8*, i8** %4
%103 = load i8*, i8** %5
%104 = icmp ne i8* %102, %103
br i1 %104, label %105, label %111
105: ; preds = %97
%106 = load i64, i64* %12
%107 = sitofp i64 %106 to double
%108 = call double @pow(double 1.000000e+01, double %107)
%109 = load double, double* %6
%110 = fmul double %109, %108
store double %110, double* %6
br label %111
111: ; preds = %105, %97
br label %112
112: ; preds = %111, %92
%113 = load double, double* %6
%114 = load double, double* %7
%115 = fmul double %113, %114
store double %115, double* %2
br label %116
116: ; preds = %112, %86
%117 = load double, double* %2
ret double %117
}

LLVM IR (-O2):
define double @nsvg__atof(i8* %0) {
%2 = alloca i8*
%3 = bitcast i8** %2 to i8*
store i8* null, i8** %2
%4 = load i8, i8* %0
switch i8 %4, label %9 [
i8 43, label %5
i8 45, label %7
]
5: ; preds = %1
%6 = getelementptr inbounds i8, i8* %0, i64 1
br label %9
7: ; preds = %1
%8 = getelementptr inbounds i8, i8* %0, i64 1
br label %9
9: ; preds = %1, %7, %5
%10 = phi i8* [ %6, %5 ], [ %8, %7 ], [ %0, %1 ]
%11 = phi double [ 1.000000e+00, %5 ], [ -1.000000e+00, %7 ], [ 1.000000e+00, %1 ]
%12 = load i8, i8* %10
%13 = tail call i64 @nsvg__isdigit(i8 signext %12)
%14 = icmp eq i64 %13, 0
br i1 %14, label %21, label %15
15: ; preds = %9
%16 = call i64 @strtoll(i8* %10, i8** %2, i32 10)
%17 = load i8*, i8** %2
%18 = icmp eq i8* %10, %17
br i1 %18, label %21, label %19
19: ; preds = %15
%20 = sitofp i64 %16 to double
br label %21
21: ; preds = %15, %19, %9
%22 = phi i8* [ %17, %19 ], [ %10, %15 ], [ %10, %9 ]
%23 = phi double [ %20, %19 ], [ 0.000000e+00, %15 ], [ 0.000000e+00, %9 ]
%24 = phi i1 [ true, %19 ], [ false, %15 ], [ false, %9 ]
%25 = load i8, i8* %22
%26 = icmp eq i8 %25, 46
br i1 %26, label %27, label %45
27: ; preds = %21
%28 = getelementptr inbounds i8, i8* %22, i64 1
%29 = load i8, i8* %28
%30 = tail call i64 @nsvg__isdigit(i8 signext %29)
%31 = icmp eq i64 %30, 0
br i1 %31, label %45, label %32
32: ; preds = %27
%33 = call i64 @strtoll(i8* %28, i8** %2, i32 10)
%34 = load i8*, i8** %2
%35 = icmp eq i8* %28, %34
br i1 %35, label %45, label %36
36: ; preds = %32
%37 = sitofp i64 %33 to double
%38 = ptrtoint i8* %34 to i64
%39 = ptrtoint i8* %28 to i64
%40 = sub i64 %38, %39
%41 = sitofp i64 %40 to double
%42 = tail call double @pow(double 1.000000e+01, double %41)
%43 = fdiv double %37, %42
%44 = fadd double %23, %43
br label %47
45: ; preds = %27, %32, %21
%46 = phi i8* [ %28, %32 ], [ %28, %27 ], [ %22, %21 ]
br i1 %24, label %47, label %63
47: ; preds = %36, %45
%48 = phi double [ %44, %36 ], [ %23, %45 ]
%49 = phi i8* [ %34, %36 ], [ %46, %45 ]
%50 = load i8, i8* %49
switch i8 %50, label %60 [
i8 101, label %51
i8 69, label %51
]
51: ; preds = %47, %47
%52 = getelementptr inbounds i8, i8* %49, i64 1
%53 = call i64 @strtol(i8* %52, i8** %2, i32 10)
%54 = load i8*, i8** %2
%55 = icmp eq i8* %52, %54
br i1 %55, label %60, label %56
56: ; preds = %51
%57 = sitofp i64 %53 to double
%58 = tail call double @pow(double 1.000000e+01, double %57)
%59 = fmul double %48, %58
br label %60
60: ; preds = %51, %56, %47
%61 = phi double [ %48, %47 ], [ %59, %56 ], [ %48, %51 ]
%62 = fmul double %11, %61
br label %63
63: ; preds = %45, %60
%64 = phi double [ %62, %60 ], [ 0.000000e+00, %45 ]
ret double %64
}