void itoa(short n, char *buffer, unsigned char base) {
  unsigned short i, j;
  char digit;
  if (n < 0) {
    n = 0 - n;
    buffer[0] = '-';
  } else {
    buffer[0] = '+';
  }
  for (i = 1; n > 0; i++, n = n / base) {
    j = n % base;
    buffer[i] = (j > 9) ? (j + 'A' - 10) : (j + '0');
  }
  buffer[i] = '\0';
  for (j = i - 1, i = 1; j >= (i + 1); j--, i++) {
    digit = buffer[j];
    buffer[j] = buffer[i];
    buffer[i] = digit;
  }
}


x86 assembly (clang, -O0):
<itoa>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %di,%cx
mov    %cx,-0x2(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %al,-0x11(%rbp)
movswl -0x2(%rbp),%eax
cmp    $0x0,%eax
jge    1139 <itoa+0x39>
movswl -0x2(%rbp),%ecx
xor    %eax,%eax
sub    %ecx,%eax
mov    %ax,-0x2(%rbp)
mov    -0x10(%rbp),%rax
movb   $0x2d,(%rax)
jmp    1140 <itoa+0x40>
mov    -0x10(%rbp),%rax
movb   $0x2b,(%rax)
movw   $0x1,-0x14(%rbp)
movswl -0x2(%rbp),%eax
cmp    $0x0,%eax
jle    11be <itoa+0xbe>
movswl -0x2(%rbp),%eax
movzbl -0x11(%rbp),%ecx
cltd
idiv   %ecx
mov    %dx,%ax
mov    %ax,-0x16(%rbp)
movzwl -0x16(%rbp),%eax
cmp    $0x9,%eax
jle    1184 <itoa+0x84>
movzwl -0x16(%rbp),%eax
add    $0x41,%eax
sub    $0xa,%eax
mov    %eax,-0x1c(%rbp)
jmp    118e <itoa+0x8e>
movzwl -0x16(%rbp),%eax
add    $0x30,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
movzwl -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x14(%rbp)
movswl -0x2(%rbp),%eax
movzbl -0x11(%rbp),%ecx
cltd
idiv   %ecx
mov    %ax,-0x2(%rbp)
jmp    1146 <itoa+0x46>
mov    -0x10(%rbp),%rax
movzwl -0x14(%rbp),%ecx
movb   $0x0,(%rax,%rcx,1)
movzwl -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %ax,-0x16(%rbp)
movw   $0x1,-0x14(%rbp)
movzwl -0x16(%rbp),%eax
movzwl -0x14(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jl     123d <itoa+0x13d>
mov    -0x10(%rbp),%rax
movzwl -0x16(%rbp),%ecx
mov    (%rax,%rcx,1),%al
mov    %al,-0x17(%rbp)
mov    -0x10(%rbp),%rax
movzwl -0x14(%rbp),%ecx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
movzwl -0x16(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x17(%rbp),%dl
mov    -0x10(%rbp),%rax
movzwl -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x16(%rbp),%ax
add    $0xffff,%ax
mov    %ax,-0x16(%rbp)
mov    -0x14(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x14(%rbp)
jmp    11db <itoa+0xdb>
pop    %rbp
ret

x86 assembly (clang, -O2):
<itoa>:
movzwl %di,%ecx
mov    %ecx,%edi
shr    $0xf,%edi
add    %dil,%dil
add    $0x2b,%dil
mov    %ecx,%eax
neg    %ax
cmovs  %cx,%ax
mov    %dil,(%rsi)
test   %ax,%ax
jle    11a2 <itoa+0xa2>
movzbl %dl,%r9d
xor    %ecx,%ecx
mov    $0x37,%r8d
cwtd
idiv   %r9w
add    $0x1,%ecx
cmp    $0xa,%dx
mov    $0x30,%edi
cmovae %r8d,%edi
add    %dl,%dil
movzwl %cx,%edx
mov    %dil,(%rsi,%rdx,1)
test   %ax,%ax
jg     1130 <itoa+0x30>
lea    0x1(%rcx),%eax
movzwl %ax,%eax
movb   $0x0,(%rsi,%rax,1)
cmp    $0x2,%cx
jb     11a1 <itoa+0xa1>
movzwl %cx,%eax
add    $0xffffffffffffffff,%rax
mov    $0x1,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl 0x1(%rsi,%rax,1),%edi
movzbl (%rsi,%rcx,1),%edx
mov    %dl,0x1(%rsi,%rax,1)
mov    %dil,(%rsi,%rcx,1)
add    $0x1,%rcx
movzwl %ax,%edx
add    $0xffffffffffffffff,%rax
cmp    %rdx,%rcx
jb     1180 <itoa+0x80>
ret
movb   $0x0,0x1(%rsi)
ret

LLVM IR (-O0):
define void @itoa(i16 signext %0, i8* %1, i8 zeroext %2) {
%4 = alloca i16
%5 = alloca i8*
%6 = alloca i8
%7 = alloca i16
%8 = alloca i16
%9 = alloca i8
store i16 %0, i16* %4
store i8* %1, i8** %5
store i8 %2, i8* %6
%10 = load i16, i16* %4
%11 = sext i16 %10 to i32
%12 = icmp slt i32 %11, 0
br i1 %12, label %13, label %20
13: ; preds = %3
%14 = load i16, i16* %4
%15 = sext i16 %14 to i32
%16 = sub nsw i32 0, %15
%17 = trunc i32 %16 to i16
store i16 %17, i16* %4
%18 = load i8*, i8** %5
%19 = getelementptr inbounds i8, i8* %18, i64 0
store i8 45, i8* %19
br label %23
20: ; preds = %3
%21 = load i8*, i8** %5
%22 = getelementptr inbounds i8, i8* %21, i64 0
store i8 43, i8* %22
br label %23
23: ; preds = %20, %13
store i16 1, i16* %7
br label %24
24: ; preds = %54, %23
%25 = load i16, i16* %4
%26 = sext i16 %25 to i32
%27 = icmp sgt i32 %26, 0
br i1 %27, label %28, label %63
28: ; preds = %24
%29 = load i16, i16* %4
%30 = sext i16 %29 to i32
%31 = load i8, i8* %6
%32 = zext i8 %31 to i32
%33 = srem i32 %30, %32
%34 = trunc i32 %33 to i16
store i16 %34, i16* %8
%35 = load i16, i16* %8
%36 = zext i16 %35 to i32
%37 = icmp sgt i32 %36, 9
br i1 %37, label %38, label %43
38: ; preds = %28
%39 = load i16, i16* %8
%40 = zext i16 %39 to i32
%41 = add nsw i32 %40, 65
%42 = sub nsw i32 %41, 10
br label %47
43: ; preds = %28
%44 = load i16, i16* %8
%45 = zext i16 %44 to i32
%46 = add nsw i32 %45, 48
br label %47
47: ; preds = %43, %38
%48 = phi i32 [ %42, %38 ], [ %46, %43 ]
%49 = trunc i32 %48 to i8
%50 = load i8*, i8** %5
%51 = load i16, i16* %7
%52 = zext i16 %51 to i64
%53 = getelementptr inbounds i8, i8* %50, i64 %52
store i8 %49, i8* %53
br label %54
54: ; preds = %47
%55 = load i16, i16* %7
%56 = add i16 %55, 1
store i16 %56, i16* %7
%57 = load i16, i16* %4
%58 = sext i16 %57 to i32
%59 = load i8, i8* %6
%60 = zext i8 %59 to i32
%61 = sdiv i32 %58, %60
%62 = trunc i32 %61 to i16
store i16 %62, i16* %4
br label %24
63: ; preds = %24
%64 = load i8*, i8** %5
%65 = load i16, i16* %7
%66 = zext i16 %65 to i64
%67 = getelementptr inbounds i8, i8* %64, i64 %66
store i8 0, i8* %67
%68 = load i16, i16* %7
%69 = zext i16 %68 to i32
%70 = sub nsw i32 %69, 1
%71 = trunc i32 %70 to i16
store i16 %71, i16* %8
store i16 1, i16* %7
br label %72
72: ; preds = %99, %63
%73 = load i16, i16* %8
%74 = zext i16 %73 to i32
%75 = load i16, i16* %7
%76 = zext i16 %75 to i32
%77 = add nsw i32 %76, 1
%78 = icmp sge i32 %74, %77
br i1 %78, label %79, label %104
79: ; preds = %72
%80 = load i8*, i8** %5
%81 = load i16, i16* %8
%82 = zext i16 %81 to i64
%83 = getelementptr inbounds i8, i8* %80, i64 %82
%84 = load i8, i8* %83
store i8 %84, i8* %9
%85 = load i8*, i8** %5
%86 = load i16, i16* %7
%87 = zext i16 %86 to i64
%88 = getelementptr inbounds i8, i8* %85, i64 %87
%89 = load i8, i8* %88
%90 = load i8*, i8** %5
%91 = load i16, i16* %8
%92 = zext i16 %91 to i64
%93 = getelementptr inbounds i8, i8* %90, i64 %92
store i8 %89, i8* %93
%94 = load i8, i8* %9
%95 = load i8*, i8** %5
%96 = load i16, i16* %7
%97 = zext i16 %96 to i64
%98 = getelementptr inbounds i8, i8* %95, i64 %97
store i8 %94, i8* %98
br label %99
99: ; preds = %79
%100 = load i16, i16* %8
%101 = add i16 %100, -1
store i16 %101, i16* %8
%102 = load i16, i16* %7
%103 = add i16 %102, 1
store i16 %103, i16* %7
br label %72
104: ; preds = %72
ret void
}

LLVM IR (-O2):
define void @itoa(i16 signext %0, i8* nocapture %1, i8 zeroext %2) {
%4 = icmp slt i16 %0, 0
%5 = sub i16 0, %0
%6 = select i1 %4, i8 45, i8 43
%7 = select i1 %4, i16 %5, i16 %0
store i8 %6, i8* %1
%8 = icmp sgt i16 %7, 0
br i1 %8, label %11, label %9
9: ; preds = %3
%10 = getelementptr inbounds i8, i8* %1, i64 1
store i8 0, i8* %10
br label %43
11: ; preds = %3
%12 = zext i8 %2 to i16
br label %13
13: ; preds = %11, %13
%14 = phi i16 [ %7, %11 ], [ %24, %13 ]
%15 = phi i16 [ 1, %11 ], [ %23, %13 ]
%16 = srem i16 %14, %12
%17 = trunc i16 %16 to i8
%18 = icmp ugt i16 %16, 9
%19 = select i1 %18, i8 55, i8 48
%20 = add i8 %19, %17
%21 = zext i16 %15 to i64
%22 = getelementptr inbounds i8, i8* %1, i64 %21
store i8 %20, i8* %22
%23 = add i16 %15, 1
%24 = sdiv i16 %14, %12
%25 = icmp sgt i16 %24, 0
br i1 %25, label %13, label %26
26: ; preds = %13
%27 = zext i16 %23 to i64
%28 = getelementptr inbounds i8, i8* %1, i64 %27
store i8 0, i8* %28
%29 = icmp ugt i16 %15, 1
br i1 %29, label %30, label %43
30: ; preds = %26
%31 = zext i16 %15 to i64
br label %32
32: ; preds = %30, %32
%33 = phi i64 [ 1, %30 ], [ %39, %32 ]
%34 = phi i64 [ %31, %30 ], [ %40, %32 ]
%35 = getelementptr inbounds i8, i8* %1, i64 %34
%36 = load i8, i8* %35
%37 = getelementptr inbounds i8, i8* %1, i64 %33
%38 = load i8, i8* %37
store i8 %38, i8* %35
store i8 %36, i8* %37
%39 = add nuw nsw i64 %33, 1
%40 = add nsw i64 %34, -1
%41 = and i64 %40, 65535
%42 = icmp ult i64 %39, %41
br i1 %42, label %32, label %43
43: ; preds = %32, %9, %26
ret void
}