#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 */
typedef int uint64_t;

/* Variables and functions */
int divu64_10(int);
int uint64_to_str(uint64_t ui64Val, char *pcBuf) {
  char tbuf[25];
  int ix = 0, iNumDig = 0;
  unsigned uMod;
  uint64_t u64Tmp;
  do {
    u64Tmp = divu64_10(ui64Val);
    uMod = ui64Val - (u64Tmp * 10);
    tbuf[ix++] = uMod + '0';
    ui64Val = u64Tmp;
  } while (ui64Val);
  iNumDig = ix;
  if (pcBuf) {
    while (ix--) {
      *pcBuf++ = tbuf[ix];
    }
    *pcBuf = 0x00;
  }
  return iNumDig;
}


x86 assembly (clang, -O0):
<uint64_to_str>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x34(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x4(%rbp),%edi
call   1030 <divu64_10@plt>
mov    %eax,-0x40(%rbp)
mov    -0x4(%rbp),%eax
imul   $0xa,-0x40(%rbp),%ecx
sub    %ecx,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x34(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x34(%rbp)
cltq
mov    %cl,-0x30(%rbp,%rax,1)
mov    -0x40(%rbp),%eax
mov    %eax,-0x4(%rbp)
cmpl   $0x0,-0x4(%rbp)
jne    112d <uint64_to_str+0x1d>
mov    -0x34(%rbp),%eax
mov    %eax,-0x38(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     11bc <uint64_to_str+0xac>
jmp    1183 <uint64_to_str+0x73>
mov    -0x34(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x34(%rbp)
cmp    $0x0,%eax
je     11b5 <uint64_to_str+0xa5>
movslq -0x34(%rbp),%rax
mov    -0x30(%rbp,%rax,1),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
jmp    1183 <uint64_to_str+0x73>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x38(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<uint64_to_str>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x20,%rsp
mov    %rsi,%r14
mov    %edi,%ebp
movabs $0xffffffff00000000,%rbx
ff ff ff
xor    %r15d,%r15d
movabs $0x100000000,%r12
nopl   0x0(%rax,%rax,1)
add    %r12,%rbx
mov    %ebp,%edi
call   1030 <divu64_10@plt>
lea    (%rax,%rax,1),%ecx
lea    (%rcx,%rcx,4),%ecx
sub    %ecx,%ebp
add    $0x30,%bpl
mov    %bpl,(%rsp,%r15,1)
add    $0x1,%r15
mov    %eax,%ebp
test   %eax,%eax
jne    1140 <uint64_to_str+0x30>
test   %r14,%r14
je     1263 <uint64_to_str+0x153>
sar    $0x20,%rbx
lea    0x1(%rbx),%rcx
cmp    $0x20,%rcx
jae    1183 <uint64_to_str+0x73>
mov    %r14,%rax
jmp    1250 <uint64_to_str+0x140>
mov    %rcx,%rdx
and    $0xffffffffffffffe0,%rdx
sub    %rdx,%rbx
lea    (%r14,%rdx,1),%rax
add    $0x10,%r14
lea    -0x1(%r15),%esi
movslq %esi,%rdi
lea    0x1(%rdi),%rsi
and    $0xffffffffffffffe0,%rsi
neg    %rsi
add    %rsp,%rdi
add    $0xfffffffffffffff1,%rdi
xor    %ebp,%ebp
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movdqu -0x10(%rdi,%rbp,1),%xmm1
movdqu (%rdi,%rbp,1),%xmm2
movdqa %xmm2,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm3,%xmm2
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm2,-0x10(%r14)
movdqu %xmm1,(%r14)
add    $0x20,%r14
add    $0xffffffffffffffe0,%rbp
cmp    %rbp,%rsi
jne    11c0 <uint64_to_str+0xb0>
cmp    %rdx,%rcx
je     1260 <uint64_to_str+0x150>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl (%rsp,%rbx,1),%ecx
mov    %cl,(%rax)
add    $0x1,%rax
add    $0xffffffffffffffff,%rbx
jb     1250 <uint64_to_str+0x140>
movb   $0x0,(%rax)
mov    %r15d,%eax
add    $0x20,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @uint64_to_str(i32 %0, i8* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca [25 x i8]
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i32 %0, i32* %3
store i8* %1, i8** %4
store i32 0, i32* %6
store i32 0, i32* %7
br label %10
10: ; preds = %25, %2
%11 = load i32, i32* %3
%12 = call i32 @divu64_10(i32 %11)
store i32 %12, i32* %9
%13 = load i32, i32* %3
%14 = load i32, i32* %9
%15 = mul nsw i32 %14, 10
%16 = sub nsw i32 %13, %15
store i32 %16, i32* %8
%17 = load i32, i32* %8
%18 = add i32 %17, 48
%19 = trunc i32 %18 to i8
%20 = load i32, i32* %6
%21 = add nsw i32 %20, 1
store i32 %21, i32* %6
%22 = sext i32 %20 to i64
%23 = getelementptr inbounds [25 x i8], [25 x i8]* %5, i64 0, i64 %22
store i8 %19, i8* %23
%24 = load i32, i32* %9
store i32 %24, i32* %3
br label %25
25: ; preds = %10
%26 = load i32, i32* %3
%27 = icmp ne i32 %26, 0
br i1 %27, label %10, label %28
28: ; preds = %25
%29 = load i32, i32* %6
store i32 %29, i32* %7
%30 = load i8*, i8** %4
%31 = icmp ne i8* %30, null
br i1 %31, label %32, label %46
32: ; preds = %28
br label %33
33: ; preds = %37, %32
%34 = load i32, i32* %6
%35 = add nsw i32 %34, -1
store i32 %35, i32* %6
%36 = icmp ne i32 %34, 0
br i1 %36, label %37, label %44
37: ; preds = %33
%38 = load i32, i32* %6
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds [25 x i8], [25 x i8]* %5, i64 0, i64 %39
%41 = load i8, i8* %40
%42 = load i8*, i8** %4
%43 = getelementptr inbounds i8, i8* %42, i32 1
store i8* %43, i8** %4
store i8 %41, i8* %42
br label %33
44: ; preds = %33
%45 = load i8*, i8** %4
store i8 0, i8* %45
br label %46
46: ; preds = %44, %28
%47 = load i32, i32* %7
ret i32 %47
}

LLVM IR (-O2):
define i32 @uint64_to_str(i32 %0, i8* writeonly %1) {
%3 = alloca [25 x i8]
%4 = getelementptr inbounds [25 x i8], [25 x i8]* %3, i64 0, i64 0
br label %5
5: ; preds = %5, %2
%6 = phi i64 [ %13, %5 ], [ 0, %2 ]
%7 = phi i32 [ %8, %5 ], [ %0, %2 ]
%8 = tail call i32 @divu64_10(i32 %7)
%9 = mul i32 %8, -10
%10 = add i32 %9, %7
%11 = trunc i32 %10 to i8
%12 = add i8 %11, 48
%13 = add nuw i64 %6, 1
%14 = getelementptr inbounds [25 x i8], [25 x i8]* %3, i64 0, i64 %6
store i8 %12, i8* %14
%15 = icmp eq i32 %8, 0
br i1 %15, label %16, label %5
16: ; preds = %5
%17 = icmp eq i8* %1, null
br i1 %17, label %60, label %18
18: ; preds = %16
%19 = shl i64 %6, 32
%20 = ashr exact i64 %19, 32
%21 = add nsw i64 %20, 1
%22 = icmp ult i64 %21, 32
br i1 %22, label %47, label %23
23: ; preds = %18
%24 = and i64 %21, -32
%25 = sub nsw i64 %20, %24
%26 = getelementptr i8, i8* %1, i64 %24
br label %27
27: ; preds = %27, %23
%28 = phi i64 [ 0, %23 ], [ %43, %27 ]
%29 = sub i64 %20, %28
%30 = getelementptr i8, i8* %1, i64 %28
%31 = getelementptr inbounds [25 x i8], [25 x i8]* %3, i64 0, i64 %29
%32 = getelementptr inbounds i8, i8* %31, i64 -15
%33 = bitcast i8* %32 to <16 x i8>*
%34 = load <16 x i8>, <16 x i8>* %33
%35 = shufflevector <16 x i8> %34, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%36 = getelementptr inbounds i8, i8* %31, i64 -31
%37 = bitcast i8* %36 to <16 x i8>*
%38 = load <16 x i8>, <16 x i8>* %37
%39 = shufflevector <16 x i8> %38, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%40 = bitcast i8* %30 to <16 x i8>*
store <16 x i8> %35, <16 x i8>* %40
%41 = getelementptr i8, i8* %30, i64 16
%42 = bitcast i8* %41 to <16 x i8>*
store <16 x i8> %39, <16 x i8>* %42
%43 = add nuw i64 %28, 32
%44 = icmp eq i64 %43, %24
br i1 %44, label %45, label %27
45: ; preds = %27
%46 = icmp eq i64 %21, %24
br i1 %46, label %58, label %47
47: ; preds = %18, %45
%48 = phi i64 [ %20, %18 ], [ %25, %45 ]
%49 = phi i8* [ %1, %18 ], [ %26, %45 ]
br label %50
50: ; preds = %47, %50
%51 = phi i64 [ %56, %50 ], [ %48, %47 ]
%52 = phi i8* [ %55, %50 ], [ %49, %47 ]
%53 = getelementptr inbounds [25 x i8], [25 x i8]* %3, i64 0, i64 %51
%54 = load i8, i8* %53
%55 = getelementptr inbounds i8, i8* %52, i64 1
store i8 %54, i8* %52
%56 = add nsw i64 %51, -1
%57 = icmp eq i64 %51, 0
br i1 %57, label %58, label %50
58: ; preds = %50, %45
%59 = phi i8* [ %26, %45 ], [ %55, %50 ]
store i8 0, i8* %59
br label %60
60: ; preds = %58, %16
%61 = trunc i64 %13 to i32
ret i32 %61
}