void uitoa(unsigned int value, char *string, int radix) {
  unsigned char index, i;
  index = 16;
  i = 0;
  do {
    string[--index] = '0' + (value % radix);
    if (string[index] > '9')
      string[index] += 'A' - ':';
    value /= radix;
  } while (value != 0);
  do {
    string[i++] = string[index++];
  } while (index < 16);
  string[i] = 0;
}


x86 assembly (clang, -O0):
<uitoa>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movb   $0x10,-0x15(%rbp)
movb   $0x0,-0x16(%rbp)
mov    -0x4(%rbp),%eax
xor    %edx,%edx
divl   -0x14(%rbp)
add    $0x30,%edx
mov    -0x10(%rbp),%rax
mov    -0x15(%rbp),%cl
add    $0xff,%cl
mov    %cl,-0x15(%rbp)
movzbl %cl,%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movzbl -0x15(%rbp),%ecx
movsbl (%rax,%rcx,1),%eax
cmp    $0x39,%eax
jle    115b <uitoa+0x5b>
mov    -0x10(%rbp),%rax
movzbl -0x15(%rbp),%ecx
movsbl (%rax,%rcx,1),%edx
add    $0x7,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%ecx
mov    -0x4(%rbp),%eax
xor    %edx,%edx
div    %ecx
mov    %eax,-0x4(%rbp)
cmpl   $0x0,-0x4(%rbp)
jne    1116 <uitoa+0x16>
jmp    1177 <uitoa+0x77>
mov    -0x10(%rbp),%rax
mov    -0x15(%rbp),%cl
mov    %cl,%dl
add    $0x1,%dl
mov    %dl,-0x15(%rbp)
movzbl %cl,%ecx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
mov    -0x16(%rbp),%cl
mov    %cl,%sil
add    $0x1,%sil
mov    %sil,-0x16(%rbp)
movzbl %cl,%ecx
mov    %dl,(%rax,%rcx,1)
movzbl -0x15(%rbp),%eax
cmp    $0x10,%eax
jl     1177 <uitoa+0x77>
mov    -0x10(%rbp),%rax
movzbl -0x16(%rbp),%ecx
movb   $0x0,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<uitoa>:
push   %rbp
push   %r15
push   %r14
push   %rbx
mov    %edx,%r10d
mov    $0xbf,%r14b
mov    $0xef,%r9b
mov    $0xfe,%r8b
mov    $0xf,%bl
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    %edi,%eax
xor    %edx,%edx
div    %r10d
lea    0x30(%rdx),%ebp
movzbl %bl,%ebx
add    $0x37,%dl
cmp    $0x3a,%bpl
movzbl %dl,%ecx
movzbl %bpl,%edx
cmovge %ecx,%edx
mov    %dl,(%rsi,%rbx,1)
add    $0x1,%r14b
add    $0x1,%r9b
add    $0x1,%r8b
add    $0xff,%bl
cmp    %r10d,%edi
mov    %eax,%edi
jae    1120 <uitoa+0x20>
mov    %dl,(%rsi)
mov    %r9d,%ebx
neg    %bl
mov    $0x1,%eax
cmp    $0xf,%bl
ja     12c6 <uitoa+0x1c6>
lea    0x3f(%r14),%r15d
mov    $0x1,%eax
cmp    $0xf,%r15b
jb     12b0 <uitoa+0x1b0>
movzbl %r15b,%edx
lea    0x1(%rsi),%rcx
movzbl %bl,%edi
lea    (%rdx,%rdi,1),%rbp
add    %rsi,%rbp
add    $0x1,%rbp
cmp    %rbp,%rcx
jae    11ae <uitoa+0xae>
lea    (%rdx,%rsi,1),%rcx
add    $0x2,%rcx
add    %rsi,%rdi
cmp    %rcx,%rdi
jb     12b0 <uitoa+0x1b0>
lea    0x1(%rdx),%r10
mov    %r10d,%r11d
and    $0xfffffff0,%r11d
lea    -0x10(%r11),%rax
mov    %rax,%rbx
shr    $0x4,%rbx
add    $0x1,%rbx
cmp    $0x30,%rax
jae    11d2 <uitoa+0xd2>
xor    %eax,%eax
jmp    123c <uitoa+0x13c>
neg    %r14b
add    $0x1,%edx
and    $0xfffffff0,%edx
add    $0xfffffffffffffff0,%rdx
shr    $0x4,%rdx
add    $0x1,%rdx
and    $0xfffffffffffffffc,%rdx
xor    %eax,%eax
nopl   (%rax)
lea    -0x30(%r14),%ecx
movzbl %cl,%ecx
movups (%rsi,%rcx,1),%xmm0
movups %xmm0,0x1(%rsi,%rax,1)
lea    -0x20(%r14),%ecx
movzbl %cl,%ecx
movups (%rsi,%rcx,1),%xmm0
movups %xmm0,0x11(%rsi,%rax,1)
lea    -0x10(%r14),%ecx
movzbl %cl,%ecx
movups (%rsi,%rcx,1),%xmm0
movups %xmm0,0x21(%rsi,%rax,1)
movzbl %r14b,%r14d
movups (%rsi,%r14,1),%xmm0
movups %xmm0,0x31(%rsi,%rax,1)
add    $0x40,%rax
add    $0x40,%r14b
add    $0xfffffffffffffffc,%rdx
jne    11f0 <uitoa+0xf0>
test   $0x3,%bl
je     128f <uitoa+0x18f>
mov    %eax,%ecx
sub    %r9b,%cl
add    $0x1,%r15b
and    $0x30,%r15b
add    $0xf0,%r15b
shr    $0x4,%r15b
add    $0x1,%r15b
movzbl %r15b,%edx
and    $0x3,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %rax,%rdi
or     $0x1,%rdi
movzbl %cl,%ecx
movups (%rsi,%rcx,1),%xmm0
movups %xmm0,(%rsi,%rdi,1)
add    $0x10,%rax
add    $0x10,%cl
add    $0xffffffffffffffff,%rdx
jne    1270 <uitoa+0x170>
lea    0x1(%r11),%rax
cmp    %r11,%r10
je     12c6 <uitoa+0x1c6>
add    $0x1,%r8b
and    $0xf0,%r8b
sub    %r9b,%r8b
mov    %r8d,%ebx
cs nopw 0x0(%rax,%rax,1)
movzbl %bl,%ebx
movzbl (%rsi,%rbx,1),%ecx
add    $0x1,%bl
mov    %cl,(%rsi,%rax,1)
add    $0x1,%rax
cmp    $0x10,%bl
jb     12b0 <uitoa+0x1b0>
movzbl %al,%eax
movb   $0x0,(%rsi,%rax,1)
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @uitoa(i32 %0, i8* nocapture %1, i32 %2) {
br label %4
4: ; preds = %4, %3
%5 = phi i32 [ %0, %3 ], [ %16, %4 ]
%6 = phi i8 [ 16, %3 ], [ %10, %4 ]
%7 = urem i32 %5, %2
%8 = trunc i32 %7 to i8
%9 = add i8 %8, 48
%10 = add i8 %6, -1
%11 = zext i8 %10 to i64
%12 = getelementptr inbounds i8, i8* %1, i64 %11
%13 = icmp sgt i8 %9, 57
%14 = add i8 %8, 55
%15 = select i1 %13, i8 %14, i8 %9
store i8 %15, i8* %12
%16 = udiv i32 %5, %2
%17 = icmp ult i32 %5, %2
br i1 %17, label %18, label %4
18: ; preds = %4
store i8 %15, i8* %1
%19 = icmp ult i8 %6, 16
br i1 %19, label %20, label %129
20: ; preds = %18
%21 = sub i8 15, %6
%22 = zext i8 %21 to i64
%23 = add nuw nsw i64 %22, 1
%24 = icmp ult i8 %21, 15
br i1 %24, label %116, label %25
25: ; preds = %20
%26 = getelementptr i8, i8* %1, i64 1
%27 = sub i8 15, %6
%28 = zext i8 %27 to i64
%29 = add nuw nsw i64 %28, 2
%30 = getelementptr i8, i8* %1, i64 %29
%31 = zext i8 %6 to i64
%32 = getelementptr i8, i8* %1, i64 %31
%33 = add nuw nsw i64 %28, %31
%34 = add nuw nsw i64 %33, 1
%35 = getelementptr i8, i8* %1, i64 %34
%36 = icmp ult i8* %26, %35
%37 = icmp ult i8* %32, %30
%38 = and i1 %36, %37
br i1 %38, label %116, label %39
39: ; preds = %25
%40 = and i64 %23, 496
%41 = or i64 %40, 1
%42 = trunc i64 %40 to i8
%43 = add i8 %6, %42
%44 = add nsw i64 %40, -16
%45 = lshr exact i64 %44, 4
%46 = add nuw nsw i64 %45, 1
%47 = and i64 %46, 3
%48 = icmp ult i64 %44, 48
br i1 %48, label %96, label %49
49: ; preds = %39
%50 = and i64 %46, 2305843009213693948
br label %51
51: ; preds = %51, %49
%52 = phi i64 [ 0, %49 ], [ %93, %51 ]
%53 = phi i64 [ 0, %49 ], [ %94, %51 ]
%54 = or i64 %52, 1
%55 = trunc i64 %52 to i8
%56 = add i8 %6, %55
%57 = zext i8 %56 to i64
%58 = getelementptr inbounds i8, i8* %1, i64 %57
%59 = bitcast i8* %58 to <16 x i8>*
%60 = load <16 x i8>, <16 x i8>* %59
%61 = getelementptr inbounds i8, i8* %1, i64 %54
%62 = bitcast i8* %61 to <16 x i8>*
store <16 x i8> %60, <16 x i8>* %62
%63 = or i64 %52, 17
%64 = trunc i64 %52 to i8
%65 = or i8 %64, 16
%66 = add i8 %6, %65
%67 = zext i8 %66 to i64
%68 = getelementptr inbounds i8, i8* %1, i64 %67
%69 = bitcast i8* %68 to <16 x i8>*
%70 = load <16 x i8>, <16 x i8>* %69
%71 = getelementptr inbounds i8, i8* %1, i64 %63
%72 = bitcast i8* %71 to <16 x i8>*
store <16 x i8> %70, <16 x i8>* %72
%73 = or i64 %52, 33
%74 = trunc i64 %52 to i8
%75 = or i8 %74, 32
%76 = add i8 %6, %75
%77 = zext i8 %76 to i64
%78 = getelementptr inbounds i8, i8* %1, i64 %77
%79 = bitcast i8* %78 to <16 x i8>*
%80 = load <16 x i8>, <16 x i8>* %79
%81 = getelementptr inbounds i8, i8* %1, i64 %73
%82 = bitcast i8* %81 to <16 x i8>*
store <16 x i8> %80, <16 x i8>* %82
%83 = or i64 %52, 49
%84 = trunc i64 %52 to i8
%85 = or i8 %84, 48
%86 = add i8 %6, %85
%87 = zext i8 %86 to i64
%88 = getelementptr inbounds i8, i8* %1, i64 %87
%89 = bitcast i8* %88 to <16 x i8>*
%90 = load <16 x i8>, <16 x i8>* %89
%91 = getelementptr inbounds i8, i8* %1, i64 %83
%92 = bitcast i8* %91 to <16 x i8>*
store <16 x i8> %90, <16 x i8>* %92
%93 = add nuw i64 %52, 64
%94 = add i64 %53, 4
%95 = icmp eq i64 %94, %50
br i1 %95, label %96, label %51
96: ; preds = %51, %39
%97 = phi i64 [ 0, %39 ], [ %93, %51 ]
%98 = icmp eq i64 %47, 0
br i1 %98, label %114, label %99
99: ; preds = %96, %99
%100 = phi i64 [ %111, %99 ], [ %97, %96 ]
%101 = phi i64 [ %112, %99 ], [ 0, %96 ]
%102 = or i64 %100, 1
%103 = trunc i64 %100 to i8
%104 = add i8 %6, %103
%105 = zext i8 %104 to i64
%106 = getelementptr inbounds i8, i8* %1, i64 %105
%107 = bitcast i8* %106 to <16 x i8>*
%108 = load <16 x i8>, <16 x i8>* %107
%109 = getelementptr inbounds i8, i8* %1, i64 %102
%110 = bitcast i8* %109 to <16 x i8>*
store <16 x i8> %108, <16 x i8>* %110
%111 = add nuw i64 %100, 16
%112 = add i64 %101, 1
%113 = icmp eq i64 %112, %47
br i1 %113, label %114, label %99
114: ; preds = %99, %96
%115 = icmp eq i64 %23, %40
br i1 %115, label %129, label %116
116: ; preds = %25, %20, %114
%117 = phi i64 [ 1, %25 ], [ 1, %20 ], [ %41, %114 ]
%118 = phi i8 [ %6, %25 ], [ %6, %20 ], [ %43, %114 ]
br label %119
119: ; preds = %116, %119
%120 = phi i64 [ %126, %119 ], [ %117, %116 ]
%121 = phi i8 [ %125, %119 ], [ %118, %116 ]
%122 = zext i8 %121 to i64
%123 = getelementptr inbounds i8, i8* %1, i64 %122
%124 = load i8, i8* %123
%125 = add i8 %121, 1
%126 = add nuw nsw i64 %120, 1
%127 = getelementptr inbounds i8, i8* %1, i64 %120
store i8 %124, i8* %127
%128 = icmp ult i8 %125, 16
br i1 %128, label %119, label %129
129: ; preds = %119, %114, %18
%130 = phi i64 [ 1, %18 ], [ %41, %114 ], [ %126, %119 ]
%131 = and i64 %130, 255
%132 = getelementptr inbounds i8, i8* %1, i64 %131
store i8 0, i8* %132
ret void
}