char *itoa(unsigned int num, char *str, unsigned int base) {
  int pos = 0;
  int opos = 0;
  int top = 0;
  char temp[32];
  char *digits = "0123456789ABCDEF";
  if (num == 0 || base > 16) {
    str[0] = '0';
    str[1] = '\0';
    return str;
  }
  while (num != 0) {
    temp[pos] = digits[num % base];
    pos++;
    num /= base;
  }
  top = pos--;
  for (opos = 0; opos < top; pos--, opos++) {
    str[opos] = temp[pos];
  }
  str[opos] = 0;
  return str;
}


x86 assembly (clang, -O0):
<itoa>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
lea    0xed6(%rip),%rax
mov    %rax,-0x58(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     1142 <itoa+0x42>
cmpl   $0x10,-0x1c(%rbp)
jbe    115e <itoa+0x5e>
mov    -0x18(%rbp),%rax
movb   $0x30,(%rax)
mov    -0x18(%rbp),%rax
movb   $0x0,0x1(%rax)
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1208 <itoa+0x108>
jmp    1163 <itoa+0x63>
cmpl   $0x0,-0xc(%rbp)
je     11a9 <itoa+0xa9>
mov    -0x58(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0xc(%rbp),%eax
xor    %edx,%edx
divl   -0x1c(%rbp)
mov    -0x60(%rbp),%rax
mov    %edx,%ecx
mov    (%rax,%rcx,1),%cl
movslq -0x20(%rbp),%rax
mov    %cl,-0x50(%rbp,%rax,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0x1c(%rbp),%ecx
mov    -0xc(%rbp),%eax
xor    %edx,%edx
div    %ecx
mov    %eax,-0xc(%rbp)
jmp    1163 <itoa+0x63>
mov    -0x20(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x20(%rbp)
mov    %eax,-0x28(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x28(%rbp),%eax
jge    11f4 <itoa+0xf4>
movslq -0x20(%rbp),%rax
mov    -0x50(%rbp,%rax,1),%dl
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11be <itoa+0xbe>
mov    -0x18(%rbp),%rax
movslq -0x24(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<itoa>:
push   %rbx
mov    %rsi,%r8
test   %edi,%edi
je     115c <itoa+0x5c>
mov    %edx,%ecx
cmp    $0x10,%edx
ja     115c <itoa+0x5c>
movabs $0xffffffff00000000,%r9
ff ff ff
xor    %esi,%esi
lea    0xede(%rip),%r10
movabs $0x100000000,%rbx
nopl   0x0(%rax)
mov    %edi,%eax
xor    %edx,%edx
div    %ecx
movzbl (%rdx,%r10,1),%edx
mov    %dl,-0x20(%rsp,%rsi,1)
add    $0x1,%rsi
add    %rbx,%r9
cmp    %ecx,%edi
mov    %eax,%edi
jae    1130 <itoa+0x30>
sar    $0x20,%r9
cmp    $0x8,%esi
jae    116a <itoa+0x6a>
xor    %eax,%eax
jmp    1297 <itoa+0x197>
movb   $0x30,(%r8)
mov    $0x1,%eax
jmp    12c6 <itoa+0x1c6>
mov    %esi,%r11d
lea    -0x1(%rsi),%r10
cmp    $0x20,%esi
jae    117d <itoa+0x7d>
xor    %eax,%eax
jmp    122c <itoa+0x12c>
mov    %r11d,%eax
and    $0xffffffe0,%eax
lea    0x10(%r8),%rdi
mov    %esi,%edx
and    $0xffffffe0,%edx
neg    %rdx
movslq %r10d,%rcx
add    %rsp,%rcx
add    $0xffffffffffffffd1,%rcx
xor    %ebx,%ebx
pxor   %xmm0,%xmm0
nop
movdqu -0x10(%rcx,%rbx,1),%xmm1
movdqu (%rcx,%rbx,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(%rdi)
movdqu %xmm1,(%rdi)
add    $0x20,%rdi
add    $0xffffffffffffffe0,%rbx
cmp    %rbx,%rdx
jne    11a0 <itoa+0xa0>
cmp    %r11,%rax
je     12c4 <itoa+0x1c4>
test   $0x18,%r11b
je     1294 <itoa+0x194>
mov    %rax,%rcx
mov    %r11d,%eax
and    $0xfffffff8,%eax
sub    %rax,%r9
lea    (%r8,%rcx,1),%rdx
mov    %esi,%edi
and    $0xfffffff8,%edi
neg    %rdi
neg    %rcx
movslq %r10d,%rbx
add    %rsp,%rbx
add    $0xffffffffffffffd9,%rbx
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nop
movq   (%rbx,%rcx,1),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,(%rdx)
add    $0x8,%rdx
add    $0xfffffffffffffff8,%rcx
cmp    %rcx,%rdi
jne    1260 <itoa+0x160>
cmp    %r11,%rax
jne    1297 <itoa+0x197>
jmp    12c4 <itoa+0x1c4>
sub    %rax,%r9
mov    %esi,%ecx
lea    (%rsp,%r9,1),%rdx
add    $0xffffffffffffffe0,%rdx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl (%rdx),%ebx
mov    %bl,(%r8,%rax,1)
add    $0x1,%rax
add    $0xffffffffffffffff,%rdx
cmp    %rax,%rcx
jne    12b0 <itoa+0x1b0>
mov    %esi,%eax
movb   $0x0,(%r8,%rax,1)
mov    %r8,%rax
pop    %rbx
ret

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

LLVM IR (-O2):
@.str = [17 x i8] c"0123456789ABCDEF\00"
define i8* @itoa(i32 %0, i8* returned writeonly %1, i32 %2) {
%4 = alloca [32 x i8]
%5 = getelementptr inbounds [32 x i8], [32 x i8]* %4, i64 0, i64 0
%6 = icmp eq i32 %0, 0
%7 = icmp ugt i32 %2, 16
%8 = or i1 %6, %7
br i1 %8, label %9, label %66
9: ; preds = %3
store i8 48, i8* %1
br label %88
10: ; preds = %66
%11 = trunc i64 %67 to i32
%12 = shl i64 %67, 32
%13 = ashr exact i64 %12, 32
%14 = add i32 %11, 1
%15 = zext i32 %14 to i64
%16 = icmp ult i32 %14, 8
br i1 %16, label %63, label %17
17: ; preds = %10
%18 = icmp ult i32 %14, 32
br i1 %18, label %45, label %19
19: ; preds = %17
%20 = and i64 %15, 4294967264
br label %21
21: ; preds = %21, %19
%22 = phi i64 [ 0, %19 ], [ %37, %21 ]
%23 = sub i64 %13, %22
%24 = getelementptr inbounds [32 x i8], [32 x i8]* %4, i64 0, i64 %23
%25 = getelementptr inbounds i8, i8* %24, i64 -15
%26 = bitcast i8* %25 to <16 x i8>*
%27 = load <16 x i8>, <16 x i8>* %26
%28 = shufflevector <16 x i8> %27, <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>
%29 = getelementptr inbounds i8, i8* %24, i64 -31
%30 = bitcast i8* %29 to <16 x i8>*
%31 = load <16 x i8>, <16 x i8>* %30
%32 = shufflevector <16 x i8> %31, <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>
%33 = getelementptr inbounds i8, i8* %1, i64 %22
%34 = bitcast i8* %33 to <16 x i8>*
store <16 x i8> %28, <16 x i8>* %34
%35 = getelementptr inbounds i8, i8* %33, i64 16
%36 = bitcast i8* %35 to <16 x i8>*
store <16 x i8> %32, <16 x i8>* %36
%37 = add nuw i64 %22, 32
%38 = icmp eq i64 %37, %20
br i1 %38, label %39, label %21
39: ; preds = %21
%40 = icmp eq i64 %20, %15
br i1 %40, label %86, label %41
41: ; preds = %39
%42 = sub nsw i64 %13, %20
%43 = and i64 %15, 24
%44 = icmp eq i64 %43, 0
br i1 %44, label %63, label %45
45: ; preds = %17, %41
%46 = phi i64 [ %20, %41 ], [ 0, %17 ]
%47 = and i64 %15, 4294967288
%48 = sub nsw i64 %13, %47
br label %49
49: ; preds = %49, %45
%50 = phi i64 [ %46, %45 ], [ %59, %49 ]
%51 = sub i64 %13, %50
%52 = getelementptr inbounds [32 x i8], [32 x i8]* %4, i64 0, i64 %51
%53 = getelementptr inbounds i8, i8* %52, i64 -7
%54 = bitcast i8* %53 to <8 x i8>*
%55 = load <8 x i8>, <8 x i8>* %54
%56 = shufflevector <8 x i8> %55, <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%57 = getelementptr inbounds i8, i8* %1, i64 %50
%58 = bitcast i8* %57 to <8 x i8>*
store <8 x i8> %56, <8 x i8>* %58
%59 = add nuw i64 %50, 8
%60 = icmp eq i64 %59, %47
br i1 %60, label %61, label %49
61: ; preds = %49
%62 = icmp eq i64 %47, %15
br i1 %62, label %86, label %63
63: ; preds = %10, %41, %61
%64 = phi i64 [ 0, %10 ], [ %20, %41 ], [ %47, %61 ]
%65 = phi i64 [ %13, %10 ], [ %42, %41 ], [ %48, %61 ]
br label %77
66: ; preds = %3, %66
%67 = phi i64 [ %74, %66 ], [ 0, %3 ]
%68 = phi i32 [ %75, %66 ], [ %0, %3 ]
%69 = urem i32 %68, %2
%70 = zext i32 %69 to i64
%71 = getelementptr inbounds [17 x i8], [17 x i8]* @.str, i64 0, i64 %70
%72 = load i8, i8* %71
%73 = getelementptr inbounds [32 x i8], [32 x i8]* %4, i64 0, i64 %67
store i8 %72, i8* %73
%74 = add nuw i64 %67, 1
%75 = udiv i32 %68, %2
%76 = icmp ult i32 %68, %2
br i1 %76, label %10, label %66
77: ; preds = %63, %77
%78 = phi i64 [ %83, %77 ], [ %64, %63 ]
%79 = phi i64 [ %84, %77 ], [ %65, %63 ]
%80 = getelementptr inbounds [32 x i8], [32 x i8]* %4, i64 0, i64 %79
%81 = load i8, i8* %80
%82 = getelementptr inbounds i8, i8* %1, i64 %78
store i8 %81, i8* %82
%83 = add nuw nsw i64 %78, 1
%84 = add nsw i64 %79, -1
%85 = icmp eq i64 %83, %15
br i1 %85, label %86, label %77
86: ; preds = %77, %61, %39
%87 = zext i32 %14 to i64
br label %88
88: ; preds = %86, %9
%89 = phi i64 [ %87, %86 ], [ 1, %9 ]
%90 = getelementptr inbounds i8, i8* %1, i64 %89
store i8 0, i8* %90
ret i8* %1
}