#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 long long simple_strtoull(char const *, char **, int /*<<< orphan*/);
unsigned long long memparse(const char *ptr, char **retptr) {
  char *endptr;
  unsigned long long ret = simple_strtoull(ptr, &endptr, 0);
  switch (*endptr) {
  case 'G':
  case 'g':
    ret <<= 10;
  case 'M':
  case 'm':
    ret <<= 10;
  case 'K':
  case 'k':
    ret <<= 10;
    endptr++;
  default:
    break;
  }
  if (retptr)
    *retptr = endptr;
  return ret;
}


x86 assembly (clang, -O0):
<memparse>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x18(%rbp),%rsi
xor    %edx,%edx
call   1030 <simple_strtoull@plt>
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x24(%rbp)
sub    $0x47,%eax
je     11a0 <memparse+0x90>
jmp    114b <memparse+0x3b>
mov    -0x24(%rbp),%eax
sub    $0x4b,%eax
je     11b8 <memparse+0xa8>
jmp    115c <memparse+0x4c>
mov    -0x24(%rbp),%eax
sub    $0x4d,%eax
je     11ac <memparse+0x9c>
jmp    116d <memparse+0x5d>
mov    -0x24(%rbp),%eax
sub    $0x67,%eax
je     11a0 <memparse+0x90>
jmp    117e <memparse+0x6e>
mov    -0x24(%rbp),%eax
sub    $0x6b,%eax
je     11b8 <memparse+0xa8>
jmp    118f <memparse+0x7f>
mov    -0x24(%rbp),%eax
sub    $0x6d,%eax
je     11ac <memparse+0x9c>
jmp    11d0 <memparse+0xc0>
mov    -0x20(%rbp),%rax
shl    $0xa,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
shl    $0xa,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
shl    $0xa,%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    11d5 <memparse+0xc5>
cmpq   $0x0,-0x10(%rbp)
je     11eb <memparse+0xdb>
mov    -0x18(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<memparse>:
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%rbx
lea    0x8(%rsp),%rsi
xor    %edx,%edx
call   1030 <simple_strtoull@plt>
mov    0x8(%rsp),%rcx
movsbl (%rcx),%edx
add    $0xffffffb9,%edx
cmp    $0x26,%edx
ja     1176 <memparse+0x66>
movabs $0x100000001,%rsi
bt     %rdx,%rsi
jb     1166 <memparse+0x56>
movabs $0x1000000010,%rsi
bt     %rdx,%rsi
jb     116e <memparse+0x5e>
movabs $0x4000000040,%rsi
bt     %rdx,%rsi
jb     116a <memparse+0x5a>
jmp    1176 <memparse+0x66>
shl    $0xa,%rax
shl    $0xa,%rax
shl    $0xa,%rax
add    $0x1,%rcx
test   %rbx,%rbx
je     117e <memparse+0x6e>
mov    %rcx,(%rbx)
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define i64 @memparse(i8* %0, i8** %1) {
%3 = alloca i8*
%4 = alloca i8**
%5 = alloca i8*
%6 = alloca i64
store i8* %0, i8** %3
store i8** %1, i8*** %4
%7 = load i8*, i8** %3
%8 = call i64 @simple_strtoull(i8* %7, i8** %5, i32 0)
store i64 %8, i64* %6
%9 = load i8*, i8** %5
%10 = load i8, i8* %9
%11 = sext i8 %10 to i32
switch i32 %11, label %23 [
i32 71, label %12
i32 103, label %12
i32 77, label %15
i32 109, label %15
i32 75, label %18
i32 107, label %18
]
12: ; preds = %2, %2
%13 = load i64, i64* %6
%14 = shl i64 %13, 10
store i64 %14, i64* %6
br label %15
15: ; preds = %2, %2, %12
%16 = load i64, i64* %6
%17 = shl i64 %16, 10
store i64 %17, i64* %6
br label %18
18: ; preds = %2, %2, %15
%19 = load i64, i64* %6
%20 = shl i64 %19, 10
store i64 %20, i64* %6
%21 = load i8*, i8** %5
%22 = getelementptr inbounds i8, i8* %21, i32 1
store i8* %22, i8** %5
br label %23
23: ; preds = %2, %18
br label %24
24: ; preds = %23
%25 = load i8**, i8*** %4
%26 = icmp ne i8** %25, null
br i1 %26, label %27, label %30
27: ; preds = %24
%28 = load i8*, i8** %5
%29 = load i8**, i8*** %4
store i8* %28, i8** %29
br label %30
30: ; preds = %27, %24
%31 = load i64, i64* %6
ret i64 %31
}

LLVM IR (-O2):
define i64 @memparse(i8* %0, i8** writeonly %1) {
%3 = alloca i8*
%4 = bitcast i8** %3 to i8*
%5 = call i64 @simple_strtoull(i8* %0, i8** %3, i32 0)
%6 = load i8*, i8** %3
%7 = load i8, i8* %6
%8 = sext i8 %7 to i32
switch i32 %8, label %18 [
i32 71, label %9
i32 103, label %9
i32 77, label %11
i32 109, label %11
i32 75, label %14
i32 107, label %14
]
9: ; preds = %2, %2
%10 = shl i64 %5, 10
br label %11
11: ; preds = %2, %2, %9
%12 = phi i64 [ %5, %2 ], [ %5, %2 ], [ %10, %9 ]
%13 = shl i64 %12, 10
br label %14
14: ; preds = %2, %2, %11
%15 = phi i64 [ %5, %2 ], [ %5, %2 ], [ %13, %11 ]
%16 = shl i64 %15, 10
%17 = getelementptr inbounds i8, i8* %6, i64 1
br label %18
18: ; preds = %14, %2
%19 = phi i8* [ %6, %2 ], [ %17, %14 ]
%20 = phi i64 [ %5, %2 ], [ %16, %14 ]
%21 = icmp eq i8** %1, null
br i1 %21, label %23, label %22
22: ; preds = %18
store i8* %19, i8** %1
br label %23
23: ; preds = %22, %18
ret i64 %20
}