int sprint_hexshort(char *s, unsigned short a) {
  char c[32];
  int j, i = 0;
  do {
    if ((a & 0x0f) < 10)
      c[i] = '0' + (a & 0x0f);
    else
      c[i] = 'a' + ((a & 0x0f) - 10);
    a >>= 4;
    i++;
  } while (a);
  i--;
  for (j = 0; j <= i; j++)
    s[j] = c[i - j];
  return j;
}


x86 assembly (clang, -O0):
<sprint_hexshort>:
push   %rbp
mov    %rsp,%rbp
mov    %si,%ax
mov    %rdi,-0x8(%rbp)
mov    %ax,-0xa(%rbp)
movl   $0x0,-0x38(%rbp)
movzwl -0xa(%rbp),%eax
and    $0xf,%eax
cmp    $0xa,%eax
jge    113f <sprint_hexshort+0x3f>
movzwl -0xa(%rbp),%eax
and    $0xf,%eax
add    $0x30,%eax
mov    %al,%cl
movslq -0x38(%rbp),%rax
mov    %cl,-0x30(%rbp,%rax,1)
jmp    1156 <sprint_hexshort+0x56>
movzwl -0xa(%rbp),%eax
and    $0xf,%eax
sub    $0xa,%eax
add    $0x61,%eax
mov    %al,%cl
movslq -0x38(%rbp),%rax
mov    %cl,-0x30(%rbp,%rax,1)
movzwl -0xa(%rbp),%eax
sar    $0x4,%eax
mov    %ax,-0xa(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
cmpw   $0x0,-0xa(%rbp)
jne    1116 <sprint_hexshort+0x16>
mov    -0x38(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x38(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x38(%rbp),%eax
jg     11b6 <sprint_hexshort+0xb6>
mov    -0x38(%rbp),%eax
sub    -0x34(%rbp),%eax
cltq
mov    -0x30(%rbp,%rax,1),%dl
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1185 <sprint_hexshort+0x85>
mov    -0x34(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sprint_hexshort>:
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzwl %si,%r8d
mov    %r8d,%edx
and    $0xf,%edx
lea    0x30(%rdx),%esi
mov    %edx,%ecx
add    $0x57,%cl
cmp    $0xa,%dx
movzbl %sil,%edx
movzbl %cl,%ecx
cmovb  %edx,%ecx
mov    %cl,-0x28(%rsp,%rax,1)
mov    %r8d,%esi
shr    $0x4,%esi
add    $0x1,%rax
cmp    $0xf,%r8w
ja     1110 <sprint_hexshort+0x10>
lea    -0x1(%rax),%rcx
cmp    $0x7,%ecx
jae    1156 <sprint_hexshort+0x56>
xor    %r11d,%r11d
jmp    12f9 <sprint_hexshort+0x1f9>
cmp    $0xf,%ecx
jae    11c4 <sprint_hexshort+0xc4>
xor    %r11d,%r11d
mov    %r11,%rdx
mov    %eax,%r11d
and    $0xfffffff8,%r11d
lea    (%rdi,%rdx,1),%rsi
neg    %rdx
mov    %rax,%r8
and    $0xfffffffffffffff8,%r8
neg    %r8
pxor   %xmm0,%xmm0
nopl   (%rax)
lea    (%rsp,%rdx,1),%rcx
add    $0xffffffffffffffd8,%rcx
movq   -0x8(%rax,%rcx,1),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,(%rsi)
add    $0xfffffffffffffff8,%rdx
add    $0x8,%rsi
cmp    %rdx,%r8
jne    1180 <sprint_hexshort+0x80>
cmp    %r11,%rax
jne    12f9 <sprint_hexshort+0x1f9>
jmp    1324 <sprint_hexshort+0x224>
mov    %eax,%r11d
and    $0xfffffff0,%r11d
lea    -0x10(%r11),%rdx
mov    %rdx,%r8
shr    $0x4,%r8
add    $0x1,%r8
test   %rdx,%rdx
je     1325 <sprint_hexshort+0x225>
lea    0x10(%rdi),%rsi
mov    %rax,%rdx
and    $0xfffffffffffffff0,%rdx
add    $0xfffffffffffffff0,%rdx
shr    $0x4,%rdx
add    $0x1,%rdx
and    $0xfffffffffffffffe,%rdx
xor    %r9d,%r9d
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nop
lea    (%rsp,%r9,1),%r10
add    $0xffffffffffffffd8,%r10
movdqu -0x10(%rax,%r10,1),%xmm1
movdqa %xmm1,%xmm2
punpcklbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm2,%xmm1
movdqu %xmm1,-0x10(%rsi)
movdqu -0x20(%rax,%r10,1),%xmm1
movdqa %xmm1,%xmm2
punpcklbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm2,%xmm1
movdqu %xmm1,(%rsi)
add    $0xffffffffffffffe0,%r9
add    $0x20,%rsi
add    $0xfffffffffffffffe,%rdx
jne    1210 <sprint_hexshort+0x110>
neg    %r9
test   $0x1,%r8b
je     12ec <sprint_hexshort+0x1ec>
lea    -0x28(%rsp),%rdx
sub    %r9,%rdx
movdqu -0x10(%rdx,%rax,1),%xmm0
pxor   %xmm1,%xmm1
movdqa %xmm0,%xmm2
punpcklbw %xmm1,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm1,%xmm0
pshufd $0x4e,%xmm0,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm0
packuswb %xmm2,%xmm0
movdqu %xmm0,(%rdi,%r9,1)
cmp    %r11,%rax
je     1324 <sprint_hexshort+0x224>
test   $0x8,%al
jne    115e <sprint_hexshort+0x5e>
mov    %r11,%rcx
neg    %rcx
add    %rsp,%rcx
add    $0xffffffffffffffd8,%rcx
lea    (%rax,%rcx,1),%rdx
add    $0xffffffffffffffff,%rdx
xchg   %ax,%ax
movzbl (%rdx),%ecx
mov    %cl,(%rdi,%r11,1)
add    $0x1,%r11
add    $0xffffffffffffffff,%rdx
cmp    %r11,%rax
jne    1310 <sprint_hexshort+0x210>
ret
xor    %r9d,%r9d
test   $0x1,%r8b
jne    12a6 <sprint_hexshort+0x1a6>
jmp    12ec <sprint_hexshort+0x1ec>

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

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