int _cvt(unsigned long val, char *buf, long radix, char *digits) {
  char temp[80];
  char *cp = temp;
  int length = 0;
  if (val == 0) {
    *cp++ = '0';
  } else
    while (val) {
      *cp++ = digits[val % radix];
      val /= radix;
    }
  while (cp != temp) {
    *buf++ = *--cp;
    length++;
  }
  *buf = '\0';
  return (length);
}


x86 assembly (clang, -O0):
<_cvt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
lea    -0x70(%rbp),%rax
mov    %rax,-0x78(%rbp)
movl   $0x0,-0x7c(%rbp)
cmpq   $0x0,-0x8(%rbp)
jne    1149 <_cvt+0x49>
mov    -0x78(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x78(%rbp)
movb   $0x30,(%rax)
jmp    11a6 <_cvt+0xa6>
jmp    114e <_cvt+0x4e>
cmpq   $0x0,-0x8(%rbp)
je     11a1 <_cvt+0xa1>
mov    -0x20(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    -0x8(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x18(%rbp)
mov    -0x88(%rbp),%rax
mov    (%rax,%rdx,1),%cl
mov    -0x78(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x78(%rbp)
mov    %cl,(%rax)
mov    -0x18(%rbp),%rcx
mov    -0x8(%rbp),%rax
xor    %edx,%edx
div    %rcx
mov    %rax,-0x8(%rbp)
jmp    114e <_cvt+0x4e>
jmp    11a6 <_cvt+0xa6>
jmp    11ab <_cvt+0xab>
mov    -0x78(%rbp),%rax
lea    -0x70(%rbp),%rcx
cmp    %rcx,%rax
je     11ed <_cvt+0xed>
mov    -0x78(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x78(%rbp)
mov    -0x1(%rax),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x7c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x7c(%rbp)
jmp    11ab <_cvt+0xab>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x7c(%rbp),%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<_cvt>:
test   %rdi,%rdi
je     1155 <_cvt+0x55>
mov    %rdx,%r8
mov    %rdi,%r9
xor    %edi,%edi
jmp    112c <_cvt+0x2c>
nop
mov    %r9,%rax
xor    %edx,%edx
div    %r8
movzbl (%rcx,%rdx,1),%edx
mov    %dl,-0x58(%rsp,%rdi,1)
add    $0x1,%rdi
cmp    %r8,%r9
mov    %rax,%r9
jb     1142 <_cvt+0x42>
mov    %r9,%rax
or     %r8,%rax
shr    $0x20,%rax
jne    1110 <_cvt+0x10>
mov    %r9d,%eax
xor    %edx,%edx
div    %r8d
jmp    1118 <_cvt+0x18>
test   %rdi,%rdi
je     1209 <_cvt+0x109>
lea    (%rsp,%rdi,1),%rax
add    $0xffffffffffffffa8,%rax
jmp    115f <_cvt+0x5f>
lea    -0x57(%rsp),%rax
movb   $0x30,-0x58(%rsp)
lea    -0x58(%rsp),%r8
mov    %rax,%r10
sub    %r8,%r10
cmp    $0x20,%r10
jb     1186 <_cvt+0x86>
cmp    %rsi,%rax
jbe    120f <_cvt+0x10f>
lea    (%rsi,%r10,1),%rcx
cmp    %rcx,%r8
jae    120f <_cvt+0x10f>
mov    %rax,%rdi
mov    %rsi,%rdx
mov    %r8,%r9
not    %r9
add    %rdi,%r9
mov    %rdi,%rsi
and    $0x7,%rsi
je     11b4 <_cvt+0xb4>
xchg   %ax,%ax
movzbl -0x1(%rdi),%ecx
add    $0xffffffffffffffff,%rdi
mov    %cl,(%rdx)
add    $0x1,%rdx
add    $0xffffffffffffffff,%rsi
jne    11a0 <_cvt+0xa0>
cmp    $0x7,%r9
jb     12b7 <_cvt+0x1b7>
xchg   %ax,%ax
movzbl -0x1(%rdi),%ecx
mov    %cl,(%rdx)
movzbl -0x2(%rdi),%ecx
mov    %cl,0x1(%rdx)
movzbl -0x3(%rdi),%ecx
mov    %cl,0x2(%rdx)
movzbl -0x4(%rdi),%ecx
mov    %cl,0x3(%rdx)
movzbl -0x5(%rdi),%ecx
mov    %cl,0x4(%rdx)
movzbl -0x6(%rdi),%ecx
mov    %cl,0x5(%rdx)
movzbl -0x7(%rdi),%ecx
mov    %cl,0x6(%rdx)
movzbl -0x8(%rdi),%ecx
add    $0xfffffffffffffff8,%rdi
mov    %cl,0x7(%rdx)
add    $0x8,%rdx
cmp    %r8,%rdi
jne    11c0 <_cvt+0xc0>
jmp    12b7 <_cvt+0x1b7>
xor    %eax,%eax
movb   $0x0,(%rsi)
ret
mov    %r10,%r9
and    $0xffffffffffffffe0,%r9
mov    %r9,%r11
neg    %r11
mov    %rax,%rdi
sub    %r9,%rdi
lea    (%rsi,%r9,1),%rdx
add    $0x10,%rsi
xor    %ecx,%ecx
pxor   %xmm0,%xmm0
movdqu -0x20(%rax,%rcx,1),%xmm1
movdqu -0x10(%rax,%rcx,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(%rsi)
movdqu %xmm1,(%rsi)
add    $0x20,%rsi
add    $0xffffffffffffffe0,%rcx
cmp    %rcx,%r11
jne    1230 <_cvt+0x130>
cmp    %r9,%r10
jne    118c <_cvt+0x8c>
sub    %r8d,%eax
movb   $0x0,(%rdx)
ret

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

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