#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 uint64_to_hexstr(uint64_t ui64Val, char *pcBuf, bool bLower) {
  int iNumDig, ix = 0;
  char cCh, tbuf[20];
  if (ui64Val == 0) {
    tbuf[ix++] = '0';
  }
  while (ui64Val) {
    cCh = ui64Val & 0xf;
    if (cCh > 9) {
      cCh += bLower ? 0x27 : 0x7;
    }
    tbuf[ix++] = cCh + '0';
    ui64Val >>= 4;
  }
  iNumDig = ix;
  if (pcBuf) {
    while (ix--) {
      *pcBuf++ = tbuf[ix];
    }
    *pcBuf = 0;
  }
  return iNumDig;
}


x86 assembly (clang, -O0):
<uint64_to_hexstr>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x0,-0x4(%rbp)
jne    1131 <uint64_to_hexstr+0x31>
mov    -0x1c(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x1c(%rbp)
cltq
movb   $0x30,-0x40(%rbp,%rax,1)
jmp    1136 <uint64_to_hexstr+0x36>
cmpl   $0x0,-0x4(%rbp)
je     119a <uint64_to_hexstr+0x9a>
mov    -0x4(%rbp),%eax
and    $0xf,%eax
mov    %al,-0x1d(%rbp)
movsbl -0x1d(%rbp),%eax
cmp    $0x9,%eax
jle    1172 <uint64_to_hexstr+0x72>
mov    -0x14(%rbp),%edx
mov    $0x7,%ecx
mov    $0x27,%eax
cmp    $0x0,%edx
cmovne %eax,%ecx
movsbl -0x1d(%rbp),%eax
add    %ecx,%eax
mov    %al,-0x1d(%rbp)
movsbl -0x1d(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x1c(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x1c(%rbp)
cltq
mov    %cl,-0x40(%rbp,%rax,1)
mov    -0x4(%rbp),%eax
sar    $0x4,%eax
mov    %eax,-0x4(%rbp)
jmp    1136 <uint64_to_hexstr+0x36>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     11e9 <uint64_to_hexstr+0xe9>
jmp    11b0 <uint64_to_hexstr+0xb0>
mov    -0x1c(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x1c(%rbp)
cmp    $0x0,%eax
je     11e2 <uint64_to_hexstr+0xe2>
movslq -0x1c(%rbp),%rax
mov    -0x40(%rbp,%rax,1),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
jmp    11b0 <uint64_to_hexstr+0xb0>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x18(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<uint64_to_hexstr>:
test   %edi,%edi
je     115e <uint64_to_hexstr+0x5e>
test   %edx,%edx
setne  %cl
shl    $0x5,%cl
or     $0x7,%cl
xor    %eax,%eax
movzbl %cl,%r8d
mov    %edi,%r9d
nopl   0x0(%rax,%rax,1)
mov    %edi,%ecx
and    $0xf,%cl
cmp    $0xa,%cl
mov    $0x0,%edx
cmovae %r8d,%edx
add    %cl,%dl
add    $0x30,%dl
mov    %dl,-0x18(%rsp,%rax,1)
add    $0x1,%rax
sar    $0x4,%r9d
cmp    $0xf,%edi
mov    %r9d,%edi
ja     1120 <uint64_to_hexstr+0x20>
test   %rsi,%rsi
je     1256 <uint64_to_hexstr+0x156>
test   %eax,%eax
jne    1171 <uint64_to_hexstr+0x71>
xor    %eax,%eax
jmp    1253 <uint64_to_hexstr+0x153>
movb   $0x30,-0x18(%rsp)
mov    $0x1,%eax
test   %rsi,%rsi
je     1256 <uint64_to_hexstr+0x156>
movslq %eax,%rcx
lea    -0x1(%rcx),%r9d
cmp    $0x1f,%r9d
jae    1186 <uint64_to_hexstr+0x86>
mov    %rsi,%r8
jmp    1237 <uint64_to_hexstr+0x137>
add    $0x1,%r9
mov    %r9,%r10
and    $0xffffffffffffffe0,%r10
lea    (%rsi,%r10,1),%r8
lea    -0x18(%rsp),%rdx
add    %rcx,%rdx
add    $0xfffffffffffffff0,%rdx
sub    %r10,%rcx
xor    %edi,%edi
pxor   %xmm0,%xmm0
nopw   0x0(%rax,%rax,1)
movdqu -0x10(%rdx),%xmm1
movdqu (%rdx),%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,(%rsi,%rdi,1)
movdqu %xmm1,0x10(%rsi,%rdi,1)
add    $0x20,%rdi
add    $0xffffffffffffffe0,%rdx
cmp    %rdi,%r10
jne    11b0 <uint64_to_hexstr+0xb0>
cmp    %r10,%r9
jne    1237 <uint64_to_hexstr+0x137>
mov    %r8,%rsi
jmp    1253 <uint64_to_hexstr+0x153>
mov    %r8,%rsi
nopw   0x0(%rax,%rax,1)
movzbl -0x19(%rsp,%rcx,1),%edx
add    $0xffffffffffffffff,%rcx
mov    %dl,(%rsi)
add    $0x1,%rsi
test   %ecx,%ecx
jne    1240 <uint64_to_hexstr+0x140>
movb   $0x0,(%rsi)
ret

LLVM IR (-O0):
define i32 @uint64_to_hexstr(i32 %0, i8* %1, i32 %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8
%10 = alloca [20 x i8]
store i32 %0, i32* %4
store i8* %1, i8** %5
store i32 %2, i32* %6
store i32 0, i32* %8
%11 = load i32, i32* %4
%12 = icmp eq i32 %11, 0
br i1 %12, label %13, label %18
13: ; preds = %3
%14 = load i32, i32* %8
%15 = add nsw i32 %14, 1
store i32 %15, i32* %8
%16 = sext i32 %14 to i64
%17 = getelementptr inbounds [20 x i8], [20 x i8]* %10, i64 0, i64 %16
store i8 48, i8* %17
br label %18
18: ; preds = %13, %3
br label %19
19: ; preds = %38, %18
%20 = load i32, i32* %4
%21 = icmp ne i32 %20, 0
br i1 %21, label %22, label %49
22: ; preds = %19
%23 = load i32, i32* %4
%24 = and i32 %23, 15
%25 = trunc i32 %24 to i8
store i8 %25, i8* %9
%26 = load i8, i8* %9
%27 = sext i8 %26 to i32
%28 = icmp sgt i32 %27, 9
br i1 %28, label %29, label %38
29: ; preds = %22
%30 = load i32, i32* %6
%31 = icmp ne i32 %30, 0
%32 = zext i1 %31 to i64
%33 = select i1 %31, i32 39, i32 7
%34 = load i8, i8* %9
%35 = sext i8 %34 to i32
%36 = add nsw i32 %35, %33
%37 = trunc i32 %36 to i8
store i8 %37, i8* %9
br label %38
38: ; preds = %29, %22
%39 = load i8, i8* %9
%40 = sext i8 %39 to i32
%41 = add nsw i32 %40, 48
%42 = trunc i32 %41 to i8
%43 = load i32, i32* %8
%44 = add nsw i32 %43, 1
store i32 %44, i32* %8
%45 = sext i32 %43 to i64
%46 = getelementptr inbounds [20 x i8], [20 x i8]* %10, i64 0, i64 %45
store i8 %42, i8* %46
%47 = load i32, i32* %4
%48 = ashr i32 %47, 4
store i32 %48, i32* %4
br label %19
49: ; preds = %19
%50 = load i32, i32* %8
store i32 %50, i32* %7
%51 = load i8*, i8** %5
%52 = icmp ne i8* %51, null
br i1 %52, label %53, label %67
53: ; preds = %49
br label %54
54: ; preds = %58, %53
%55 = load i32, i32* %8
%56 = add nsw i32 %55, -1
store i32 %56, i32* %8
%57 = icmp ne i32 %55, 0
br i1 %57, label %58, label %65
58: ; preds = %54
%59 = load i32, i32* %8
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds [20 x i8], [20 x i8]* %10, i64 0, i64 %60
%62 = load i8, i8* %61
%63 = load i8*, i8** %5
%64 = getelementptr inbounds i8, i8* %63, i32 1
store i8* %64, i8** %5
store i8 %62, i8* %63
br label %54
65: ; preds = %54
%66 = load i8*, i8** %5
store i8 0, i8* %66
br label %67
67: ; preds = %65, %49
%68 = load i32, i32* %7
ret i32 %68
}

LLVM IR (-O2):
define i32 @uint64_to_hexstr(i32 %0, i8* writeonly %1, i32 %2) {
%4 = alloca [20 x i8]
%5 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%6 = icmp eq i32 %0, 0
br i1 %6, label %26, label %7
7: ; preds = %3
%8 = icmp eq i32 %2, 0
%9 = select i1 %8, i8 7, i8 39
br label %10
10: ; preds = %7, %10
%11 = phi i64 [ 0, %7 ], [ %19, %10 ]
%12 = phi i32 [ %0, %7 ], [ %21, %10 ]
%13 = trunc i32 %12 to i8
%14 = and i8 %13, 15
%15 = icmp ugt i8 %14, 9
%16 = select i1 %15, i8 %9, i8 0
%17 = or i8 %14, 48
%18 = add nuw nsw i8 %17, %16
%19 = add nuw i64 %11, 1
%20 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 %11
store i8 %18, i8* %20
%21 = ashr i32 %12, 4
%22 = icmp ult i32 %12, 16
br i1 %22, label %23, label %10
23: ; preds = %10
%24 = trunc i64 %19 to i32
%25 = icmp eq i8* %1, null
br i1 %25, label %77, label %28
26: ; preds = %3
store i8 48, i8* %5
%27 = icmp eq i8* %1, null
br i1 %27, label %77, label %30
28: ; preds = %23
%29 = icmp eq i32 %24, 0
br i1 %29, label %74, label %30
30: ; preds = %26, %28
%31 = phi i32 [ %24, %28 ], [ 1, %26 ]
%32 = sext i32 %31 to i64
%33 = add i32 %31, -1
%34 = zext i32 %33 to i64
%35 = add nuw nsw i64 %34, 1
%36 = icmp ult i32 %33, 31
br i1 %36, label %62, label %37
37: ; preds = %30
%38 = and i64 %35, 8589934560
%39 = sub nsw i64 %32, %38
%40 = getelementptr i8, i8* %1, i64 %38
br label %41
41: ; preds = %41, %37
%42 = phi i64 [ 0, %37 ], [ %58, %41 ]
%43 = getelementptr i8, i8* %1, i64 %42
%44 = xor i64 %42, -1
%45 = add i64 %44, %32
%46 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 %45
%47 = getelementptr inbounds i8, i8* %46, i64 -15
%48 = bitcast i8* %47 to <16 x i8>*
%49 = load <16 x i8>, <16 x i8>* %48
%50 = shufflevector <16 x i8> %49, <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>
%51 = getelementptr inbounds i8, i8* %46, i64 -31
%52 = bitcast i8* %51 to <16 x i8>*
%53 = load <16 x i8>, <16 x i8>* %52
%54 = shufflevector <16 x i8> %53, <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>
%55 = bitcast i8* %43 to <16 x i8>*
store <16 x i8> %50, <16 x i8>* %55
%56 = getelementptr i8, i8* %43, i64 16
%57 = bitcast i8* %56 to <16 x i8>*
store <16 x i8> %54, <16 x i8>* %57
%58 = add nuw i64 %42, 32
%59 = icmp eq i64 %58, %38
br i1 %59, label %60, label %41
60: ; preds = %41
%61 = icmp eq i64 %35, %38
br i1 %61, label %74, label %62
62: ; preds = %30, %60
%63 = phi i64 [ %32, %30 ], [ %39, %60 ]
%64 = phi i8* [ %1, %30 ], [ %40, %60 ]
br label %65
65: ; preds = %62, %65
%66 = phi i64 [ %68, %65 ], [ %63, %62 ]
%67 = phi i8* [ %71, %65 ], [ %64, %62 ]
%68 = add nsw i64 %66, -1
%69 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 %68
%70 = load i8, i8* %69
%71 = getelementptr inbounds i8, i8* %67, i64 1
store i8 %70, i8* %67
%72 = trunc i64 %68 to i32
%73 = icmp eq i32 %72, 0
br i1 %73, label %74, label %65
74: ; preds = %65, %60, %28
%75 = phi i32 [ 0, %28 ], [ %31, %60 ], [ %31, %65 ]
%76 = phi i8* [ %1, %28 ], [ %40, %60 ], [ %71, %65 ]
store i8 0, i8* %76
br label %77
77: ; preds = %26, %74, %23
%78 = phi i32 [ 1, %26 ], [ %75, %74 ], [ %24, %23 ]
ret i32 %78
}