int sprint_hexlong(char *s, unsigned long 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_hexlong>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x10(%rbp),%rax
and    $0xf,%rax
cmp    $0xa,%rax
jae    1140 <sprint_hexlong+0x40>
mov    -0x10(%rbp),%rax
and    $0xf,%rax
add    $0x30,%rax
mov    %al,%cl
movslq -0x38(%rbp),%rax
mov    %cl,-0x30(%rbp,%rax,1)
jmp    115a <sprint_hexlong+0x5a>
mov    -0x10(%rbp),%rax
and    $0xf,%rax
sub    $0xa,%rax
add    $0x61,%rax
mov    %al,%cl
movslq -0x38(%rbp),%rax
mov    %cl,-0x30(%rbp,%rax,1)
mov    -0x10(%rbp),%rax
shr    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1113 <sprint_hexlong+0x13>
mov    -0x38(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x38(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x38(%rbp),%eax
jg     11bb <sprint_hexlong+0xbb>
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    118a <sprint_hexlong+0x8a>
mov    -0x34(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sprint_hexlong>:
xor    %eax,%eax
mov    %rsi,%rcx
cs nopw 0x0(%rax,%rax,1)
nop
mov    %esi,%edx
and    $0xf,%edx
lea    0x30(%rdx),%r8d
lea    0x57(%rdx),%r9d
cmp    $0xa,%rdx
movzbl %r8b,%r8d
movzbl %r9b,%edx
cmovb  %r8d,%edx
mov    %dl,-0x28(%rsp,%rax,1)
shr    $0x4,%rcx
add    $0x1,%rax
cmp    $0xf,%rsi
mov    %rcx,%rsi
ja     1110 <sprint_hexlong+0x10>
lea    -0x1(%rax),%rcx
cmp    $0x7,%ecx
jae    1153 <sprint_hexlong+0x53>
xor    %r11d,%r11d
jmp    12f9 <sprint_hexlong+0x1f9>
cmp    $0xf,%ecx
jae    11c4 <sprint_hexlong+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
nopw   0x0(%rax,%rax,1)
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_hexlong+0x80>
cmp    %r11,%rax
jne    12f9 <sprint_hexlong+0x1f9>
jmp    1324 <sprint_hexlong+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_hexlong+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_hexlong+0x110>
neg    %r9
test   $0x1,%r8b
je     12ec <sprint_hexlong+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_hexlong+0x224>
test   $0x8,%al
jne    115b <sprint_hexlong+0x5b>
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_hexlong+0x210>
ret
xor    %r9d,%r9d
test   $0x1,%r8b
jne    12a6 <sprint_hexlong+0x1a6>
jmp    12ec <sprint_hexlong+0x1ec>

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

LLVM IR (-O2):
define i32 @sprint_hexlong(i8* nocapture writeonly %0, i64 %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 i64 [ %15, %5 ], [ %1, %2 ]
%8 = and i64 %7, 15
%9 = icmp ult i64 %8, 10
%10 = trunc i64 %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 i64 %7, 4
%16 = add nuw nsw i64 %6, 1
%17 = icmp ult i64 %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
}