int sprintf_dec(char *str, int num, int zero_padding, int width) {
  char *dst;
  int i = 0;
  char tmp_buf[16 + 1];
  int minus_sign = 0;
  int one_digit;
  dst = str;
  if (num == 0) {
    tmp_buf[i++] = '0';
  } else {
    if (num < 0) {
      minus_sign = 1;
      num = -1 * num;
    }
    while (num > 0) {
      one_digit = num % 10;
      tmp_buf[i++] = '0' + one_digit;
      num /= 10;
    }
  }
  while (width - i > 0) {
    tmp_buf[i++] = '0';
  }
  if (minus_sign == 1) {
    tmp_buf[i++] = '-';
  }
  while (i-- > 0) {
    *dst++ = tmp_buf[i];
  }
  return dst - str;
}


x86 assembly (clang, -O0):
<sprintf_dec>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x44(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1148 <sprintf_dec+0x48>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movb   $0x30,-0x40(%rbp,%rax,1)
jmp    11b1 <sprintf_dec+0xb1>
cmpl   $0x0,-0xc(%rbp)
jge    1163 <sprintf_dec+0x63>
movl   $0x1,-0x44(%rbp)
imul   $0xffffffff,-0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
jmp    1168 <sprintf_dec+0x68>
cmpl   $0x0,-0xc(%rbp)
jle    11ac <sprintf_dec+0xac>
mov    -0xc(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %edx,-0x48(%rbp)
mov    -0x48(%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,-0x40(%rbp,%rax,1)
mov    -0xc(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    %eax,-0xc(%rbp)
jmp    1168 <sprintf_dec+0x68>
jmp    11b1 <sprintf_dec+0xb1>
jmp    11b6 <sprintf_dec+0xb6>
mov    -0x14(%rbp),%eax
sub    -0x24(%rbp),%eax
cmp    $0x0,%eax
jle    11dc <sprintf_dec+0xdc>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movb   $0x30,-0x40(%rbp,%rax,1)
jmp    11b6 <sprintf_dec+0xb6>
cmpl   $0x1,-0x44(%rbp)
jne    11f8 <sprintf_dec+0xf8>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0x1,%ecx
mov    %ecx,-0x24(%rbp)
cltq
movb   $0x2d,-0x40(%rbp,%rax,1)
jmp    11fd <sprintf_dec+0xfd>
mov    -0x24(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x24(%rbp)
cmp    $0x0,%eax
jle    122f <sprintf_dec+0x12f>
movslq -0x24(%rbp),%rax
mov    -0x40(%rbp,%rax,1),%cl
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %cl,(%rax)
jmp    11fd <sprintf_dec+0xfd>
mov    -0x20(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<sprintf_dec>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %ecx,%ebp
mov    %rdi,%r15
test   %esi,%esi
je     116d <sprintf_dec+0x5d>
mov    %esi,%r14d
shr    $0x1f,%r14d
mov    %esi,%eax
neg    %eax
cmovs  %esi,%eax
xor    %ebx,%ebx
mov    $0xcccccccd,%ecx
nopl   0x0(%rax)
mov    %eax,%edx
imul   %rcx,%rdx
shr    $0x23,%rdx
lea    (%rdx,%rdx,1),%esi
lea    (%rsi,%rsi,4),%esi
mov    %eax,%edi
sub    %esi,%edi
or     $0x30,%dil
mov    %dil,(%rsp,%rbx,1)
add    $0x1,%rbx
cmp    $0x9,%eax
mov    %edx,%eax
ja     1140 <sprintf_dec+0x30>
cmp    %ebp,%ebx
jl     117d <sprintf_dec+0x6d>
jmp    11d8 <sprintf_dec+0xc8>
movb   $0x30,(%rsp)
xor    %r14d,%r14d
mov    $0x1,%ebx
cmp    %ebp,%ebx
jge    11d8 <sprintf_dec+0xc8>
mov    %ebx,%r12d
lea    (%rsp,%r12,1),%rdi
mov    %ebx,%r13d
not    %r13d
add    %ebp,%r13d
lea    0x1(%r13),%rdx
mov    $0x30,%esi
call   1030 <memset@plt>
mov    %ebp,%eax
sub    %ebx,%eax
and    $0x7,%eax
je     11c6 <sprintf_dec+0xb6>
neg    %eax
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
add    $0xffffffffffffffff,%rcx
cmp    %ecx,%eax
jne    11b0 <sprintf_dec+0xa0>
sub    %rcx,%r12
mov    %r12,%rbx
cmp    $0x7,%r13d
jae    11cc <sprintf_dec+0xbc>
jmp    11d8 <sprintf_dec+0xc8>
cmp    $0x7,%r13d
jb     11d8 <sprintf_dec+0xc8>
mov    %r12,%rbx
nop
add    $0x8,%rbx
cmp    %ebp,%ebx
jl     11d0 <sprintf_dec+0xc0>
test   %r14d,%r14d
je     11e6 <sprintf_dec+0xd6>
mov    %ebx,%eax
add    $0x1,%ebx
movb   $0x2d,(%rsp,%rax,1)
mov    %r15,%rax
test   %ebx,%ebx
jle    12e7 <sprintf_dec+0x1d7>
mov    %ebx,%edx
cmp    $0x20,%ebx
jb     12bf <sprintf_dec+0x1af>
lea    -0x1(%rdx),%rsi
add    $0xffffffff,%ebx
cmp    %esi,%ebx
jb     12bf <sprintf_dec+0x1af>
mov    %rsi,%rax
shr    $0x20,%rax
jne    12bf <sprintf_dec+0x1af>
mov    %edx,%edi
and    $0xffffffe0,%edi
mov    %edx,%ecx
and    $0x1f,%ecx
lea    (%r15,%rdi,1),%rax
xor    %ebp,%ebp
pxor   %xmm0,%xmm0
nopl   0x0(%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    1230 <sprintf_dec+0x120>
cmp    %rdx,%rdi
jne    12c5 <sprintf_dec+0x1b5>
jmp    12e7 <sprintf_dec+0x1d7>
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     12d0 <sprintf_dec+0x1c0>
sub    %r15d,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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