int sprintf_hex(char *str, unsigned int num, int capital, int zero_padding,
                int width) {
  char *dst;
  int i = 0;
  char tmp_buf[8];
  int sign = 1;
  int one_digit;
  dst = str;
  if (num == 0) {
    tmp_buf[i++] = '0';
  } else {
    while (num > 0) {
      one_digit = num % 16;
      if (one_digit <= 9) {
        tmp_buf[i++] = '0' + one_digit;
      } else {
        tmp_buf[i++] = (capital != 0 ? 'A' : 'a') + (one_digit - 10);
      }
      num /= 16;
    }
  }
  while (width - i > 0) {
    tmp_buf[i++] = '0';
  }
  while (i-- > 0) {
    *dst++ = tmp_buf[i];
  }
  return dst - str;
}


x86 assembly (clang, -O0):
<sprintf_hex>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x1,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    114c <sprintf_hex+0x4c>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movb   $0x30,-0x2c(%rbp,%rax,1)
jmp    11cd <sprintf_hex+0xcd>
jmp    1151 <sprintf_hex+0x51>
cmpl   $0x0,-0xc(%rbp)
jbe    11c8 <sprintf_hex+0xc8>
mov    -0xc(%rbp),%eax
and    $0xf,%eax
mov    %eax,-0x34(%rbp)
cmpl   $0x9,-0x34(%rbp)
jg     118c <sprintf_hex+0x8c>
mov    -0x34(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x24(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x24(%rbp)
cltq
mov    %cl,-0x2c(%rbp,%rax,1)
jmp    11ba <sprintf_hex+0xba>
mov    -0x10(%rbp),%edx
mov    $0x61,%eax
mov    $0x41,%ecx
cmp    $0x0,%edx
cmovne %ecx,%eax
mov    -0x34(%rbp),%ecx
sub    $0xa,%ecx
add    %ecx,%eax
mov    %al,%cl
mov    -0x24(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x24(%rbp)
cltq
mov    %cl,-0x2c(%rbp,%rax,1)
mov    -0xc(%rbp),%eax
shr    $0x4,%eax
mov    %eax,-0xc(%rbp)
jmp    1151 <sprintf_hex+0x51>
jmp    11cd <sprintf_hex+0xcd>
jmp    11d2 <sprintf_hex+0xd2>
mov    -0x18(%rbp),%eax
sub    -0x24(%rbp),%eax
cmp    $0x0,%eax
jle    11f8 <sprintf_hex+0xf8>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movb   $0x30,-0x2c(%rbp,%rax,1)
jmp    11d2 <sprintf_hex+0xd2>
jmp    11fd <sprintf_hex+0xfd>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x24(%rbp)
cmp    $0x0,%eax
jle    122f <sprintf_hex+0x12f>
movslq -0x24(%rbp),%rax
mov    -0x2c(%rbp,%rax,1),%cl
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %cl,(%rax)
jmp    11fd <sprintf_hex+0xfd>
mov    -0x20(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sprintf_hex>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %r8d,%r14d
mov    %rdi,%r15
test   %esi,%esi
je     1187 <sprintf_hex+0x77>
xor    %eax,%eax
test   %edx,%edx
sete   %al
shl    $0x5,%eax
add    $0x37,%eax
xor    %edx,%edx
mov    %esi,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %esi,%edi
and    $0xf,%edi
lea    0x30(%rdi),%ebp
lea    (%rax,%rdi,1),%ebx
cmp    $0xa,%edi
movzbl %bpl,%edi
cmovae %ebx,%edi
mov    %dil,(%rsp,%rdx,1)
add    $0x1,%rdx
shr    $0x4,%ecx
cmp    $0xf,%esi
mov    %ecx,%esi
ja     1140 <sprintf_hex+0x30>
cmp    %r14d,%edx
jge    1195 <sprintf_hex+0x85>
mov    %edx,%eax
lea    (%rsp,%rax,1),%rdi
not    %edx
add    %r14d,%edx
add    $0x1,%rdx
mov    $0x30,%esi
call   1030 <memset@plt>
jmp    1198 <sprintf_hex+0x88>
movb   $0x30,(%rsp)
mov    $0x1,%edx
cmp    %r14d,%edx
jl     116c <sprintf_hex+0x5c>
mov    %edx,%r14d
mov    %r15,%rax
test   %r14d,%r14d
jle    12a7 <sprintf_hex+0x197>
mov    %r14d,%edx
cmp    $0x20,%r14d
jb     127f <sprintf_hex+0x16f>
lea    -0x1(%rdx),%rsi
add    $0xffffffff,%r14d
cmp    %esi,%r14d
jb     127f <sprintf_hex+0x16f>
mov    %rsi,%rax
shr    $0x20,%rax
jne    127f <sprintf_hex+0x16f>
mov    %edx,%edi
and    $0xffffffe0,%edi
mov    %edx,%ecx
and    $0x1f,%ecx
lea    (%r15,%rdi,1),%rax
xor    %ebp,%ebp
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %esi,%ebx
movdqu -0x1f(%rsp,%rbx,1),%xmm1
movdqu -0xf(%rsp,%rbx,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,(%r15,%rbp,1)
movdqu %xmm1,0x10(%r15,%rbp,1)
add    $0x20,%rbp
add    $0xffffffffffffffe0,%rsi
cmp    %rbp,%rdi
jne    11f0 <sprintf_hex+0xe0>
cmp    %rdx,%rdi
jne    1285 <sprintf_hex+0x175>
jmp    12a7 <sprintf_hex+0x197>
mov    %rdx,%rcx
mov    %r15,%rax
add    $0x1,%rcx
nopl   0x0(%rax)
lea    -0x2(%rcx),%edx
movzbl (%rsp,%rdx,1),%edx
mov    %dl,(%rax)
add    $0x1,%rax
add    $0xffffffffffffffff,%rcx
cmp    $0x1,%rcx
ja     1290 <sprintf_hex+0x180>
sub    %r15d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @sprintf_hex(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i32
%13 = alloca [8 x i8]
%14 = alloca i32
%15 = alloca i32
store i8* %0, i8** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
store i32 %4, i32* %10
store i32 0, i32* %12
store i32 1, i32* %14
%16 = load i8*, i8** %6
store i8* %16, i8** %11
%17 = load i32, i32* %7
%18 = icmp eq i32 %17, 0
br i1 %18, label %19, label %24
19: ; preds = %5
%20 = load i32, i32* %12
%21 = add nsw i32 %20, 1
store i32 %21, i32* %12
%22 = sext i32 %20 to i64
%23 = getelementptr inbounds [8 x i8], [8 x i8]* %13, i64 0, i64 %22
store i8 48, i8* %23
br label %58
24: ; preds = %5
br label %25
25: ; preds = %54, %24
%26 = load i32, i32* %7
%27 = icmp ugt i32 %26, 0
br i1 %27, label %28, label %57
28: ; preds = %25
%29 = load i32, i32* %7
%30 = urem i32 %29, 16
store i32 %30, i32* %15
%31 = load i32, i32* %15
%32 = icmp sle i32 %31, 9
br i1 %32, label %33, label %41
33: ; preds = %28
%34 = load i32, i32* %15
%35 = add nsw i32 48, %34
%36 = trunc i32 %35 to i8
%37 = load i32, i32* %12
%38 = add nsw i32 %37, 1
store i32 %38, i32* %12
%39 = sext i32 %37 to i64
%40 = getelementptr inbounds [8 x i8], [8 x i8]* %13, i64 0, i64 %39
store i8 %36, i8* %40
br label %54
41: ; preds = %28
%42 = load i32, i32* %8
%43 = icmp ne i32 %42, 0
%44 = zext i1 %43 to i64
%45 = select i1 %43, i32 65, i32 97
%46 = load i32, i32* %15
%47 = sub nsw i32 %46, 10
%48 = add nsw i32 %45, %47
%49 = trunc i32 %48 to i8
%50 = load i32, i32* %12
%51 = add nsw i32 %50, 1
store i32 %51, i32* %12
%52 = sext i32 %50 to i64
%53 = getelementptr inbounds [8 x i8], [8 x i8]* %13, i64 0, i64 %52
store i8 %49, i8* %53
br label %54
54: ; preds = %41, %33
%55 = load i32, i32* %7
%56 = udiv i32 %55, 16
store i32 %56, i32* %7
br label %25
57: ; preds = %25
br label %58
58: ; preds = %57, %19
br label %59
59: ; preds = %64, %58
%60 = load i32, i32* %10
%61 = load i32, i32* %12
%62 = sub nsw i32 %60, %61
%63 = icmp sgt i32 %62, 0
br i1 %63, label %64, label %69
64: ; preds = %59
%65 = load i32, i32* %12
%66 = add nsw i32 %65, 1
store i32 %66, i32* %12
%67 = sext i32 %65 to i64
%68 = getelementptr inbounds [8 x i8], [8 x i8]* %13, i64 0, i64 %67
store i8 48, i8* %68
br label %59
69: ; preds = %59
br label %70
70: ; preds = %74, %69
%71 = load i32, i32* %12
%72 = add nsw i32 %71, -1
store i32 %72, i32* %12
%73 = icmp sgt i32 %71, 0
br i1 %73, label %74, label %81
74: ; preds = %70
%75 = load i32, i32* %12
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds [8 x i8], [8 x i8]* %13, i64 0, i64 %76
%78 = load i8, i8* %77
%79 = load i8*, i8** %11
%80 = getelementptr inbounds i8, i8* %79, i32 1
store i8* %80, i8** %11
store i8 %78, i8* %79
br label %70
81: ; preds = %70
%82 = load i8*, i8** %11
%83 = load i8*, i8** %6
%84 = ptrtoint i8* %82 to i64
%85 = ptrtoint i8* %83 to i64
%86 = sub i64 %84, %85
%87 = trunc i64 %86 to i32
ret i32 %87
}

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