int utf8_char_decode(int unicode, unsigned char *utf) {
  int count = -1;
  if (unicode < 0x80)
    count = 1;
  else if (unicode < 0x800)
    count = 2;
  else if (unicode < 0x10000)
    count = 3;
  else if (unicode < 0x200000)
    count = 4;
  else if (unicode < 0x4000000)
    count = 5;
  else if (unicode <= 0x7fffffff)
    count = 6;
  else
    return count;
  switch (count) {
  case 6:
    utf[5] = 0x80 | (unicode & 0x3f);
    unicode = unicode >> 6;
    unicode |= 0x4000000;
  case 5:
    utf[4] = 0x80 | (unicode & 0x3f);
    unicode = unicode >> 6;
    unicode |= 0x200000;
  case 4:
    utf[3] = 0x80 | (unicode & 0x3f);
    unicode = unicode >> 6;
    unicode |= 0x10000;
  case 3:
    utf[2] = 0x80 | (unicode & 0x3f);
    unicode = unicode >> 6;
    unicode |= 0x800;
  case 2:
    utf[1] = 0x80 | (unicode & 0x3f);
    unicode = unicode >> 6;
    unicode |= 0xc0;
  case 1:
    utf[0] = (char)unicode;
  }
  return count;
}


x86 assembly (clang, -O0):
<utf8_char_decode>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0xffffffff,-0x14(%rbp)
cmpl   $0x80,-0x8(%rbp)
jge    112b <utf8_char_decode+0x2b>
movl   $0x1,-0x14(%rbp)
jmp    11cc <utf8_char_decode+0xcc>
cmpl   $0x800,-0x8(%rbp)
jge    1144 <utf8_char_decode+0x44>
movl   $0x2,-0x14(%rbp)
jmp    11c7 <utf8_char_decode+0xc7>
cmpl   $0x10000,-0x8(%rbp)
jge    115d <utf8_char_decode+0x5d>
movl   $0x3,-0x14(%rbp)
jmp    11c2 <utf8_char_decode+0xc2>
cmpl   $0x200000,-0x8(%rbp)
jge    1176 <utf8_char_decode+0x76>
movl   $0x4,-0x14(%rbp)
jmp    11bd <utf8_char_decode+0xbd>
cmpl   $0x4000000,-0x8(%rbp)
jge    118f <utf8_char_decode+0x8f>
movl   $0x5,-0x14(%rbp)
jmp    11b8 <utf8_char_decode+0xb8>
cmpl   $0x7fffffff,-0x8(%rbp)
jg     11a8 <utf8_char_decode+0xa8>
movl   $0x6,-0x14(%rbp)
jmp    11b3 <utf8_char_decode+0xb3>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    12ce <utf8_char_decode+0x1ce>
jmp    11b8 <utf8_char_decode+0xb8>
jmp    11bd <utf8_char_decode+0xbd>
jmp    11c2 <utf8_char_decode+0xc2>
jmp    11c7 <utf8_char_decode+0xc7>
jmp    11cc <utf8_char_decode+0xcc>
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x20(%rbp)
sub    $0x5,%eax
ja     12c8 <utf8_char_decode+0x1c8>
mov    -0x20(%rbp),%rax
lea    0xe14(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x5(%rax)
mov    -0x8(%rbp),%eax
sar    $0x6,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
or     $0x4000000,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x4(%rax)
mov    -0x8(%rbp),%eax
sar    $0x6,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
or     $0x200000,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x3(%rax)
mov    -0x8(%rbp),%eax
sar    $0x6,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
or     $0x10000,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x8(%rbp),%eax
sar    $0x6,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
or     $0x800,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x8(%rbp),%eax
sar    $0x6,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
or     $0xc0,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8_char_decode>:
mov    $0x1,%eax
cmp    $0x80,%edi
jl     11ac <utf8_char_decode+0xac>
mov    $0x2,%eax
cmp    $0x800,%edi
jb     1198 <utf8_char_decode+0x98>
mov    $0x3,%eax
cmp    $0x10000,%edi
jb     1184 <utf8_char_decode+0x84>
mov    $0x4,%eax
cmp    $0x200000,%edi
jb     1170 <utf8_char_decode+0x70>
mov    $0x5,%eax
cmp    $0x4000000,%edi
jb     115c <utf8_char_decode+0x5c>
mov    %edi,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x5(%rsi)
shr    $0x6,%edi
or     $0x4000000,%edi
mov    $0x6,%eax
mov    %edi,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x4(%rsi)
sar    $0x6,%edi
or     $0x200000,%edi
mov    %edi,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x3(%rsi)
sar    $0x6,%edi
or     $0x10000,%edi
mov    %edi,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x2(%rsi)
sar    $0x6,%edi
or     $0x800,%edi
mov    %edi,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x1(%rsi)
sar    $0x6,%edi
or     $0xc0,%edi
mov    %dil,(%rsi)
ret

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

LLVM IR (-O2):
define i32 @utf8_char_decode(i32 %0, i8* nocapture writeonly %1) {
%3 = icmp slt i32 %0, 128
br i1 %3, label %55, label %4
4: ; preds = %2
%5 = icmp ult i32 %0, 2048
br i1 %5, label %46, label %6
6: ; preds = %4
%7 = icmp ult i32 %0, 65536
br i1 %7, label %37, label %8
8: ; preds = %6
%9 = icmp ult i32 %0, 2097152
br i1 %9, label %28, label %10
10: ; preds = %8
%11 = icmp ult i32 %0, 67108864
br i1 %11, label %19, label %12
12: ; preds = %10
%13 = trunc i32 %0 to i8
%14 = and i8 %13, 63
%15 = or i8 %14, -128
%16 = getelementptr inbounds i8, i8* %1, i64 5
store i8 %15, i8* %16
%17 = lshr i32 %0, 6
%18 = or i32 %17, 67108864
br label %19
19: ; preds = %10, %12
%20 = phi i32 [ 6, %12 ], [ 5, %10 ]
%21 = phi i32 [ %18, %12 ], [ %0, %10 ]
%22 = trunc i32 %21 to i8
%23 = and i8 %22, 63
%24 = or i8 %23, -128
%25 = getelementptr inbounds i8, i8* %1, i64 4
store i8 %24, i8* %25
%26 = ashr i32 %21, 6
%27 = or i32 %26, 2097152
br label %28
28: ; preds = %8, %19
%29 = phi i32 [ %20, %19 ], [ 4, %8 ]
%30 = phi i32 [ %27, %19 ], [ %0, %8 ]
%31 = trunc i32 %30 to i8
%32 = and i8 %31, 63
%33 = or i8 %32, -128
%34 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %33, i8* %34
%35 = ashr i32 %30, 6
%36 = or i32 %35, 65536
br label %37
37: ; preds = %6, %28
%38 = phi i32 [ %29, %28 ], [ 3, %6 ]
%39 = phi i32 [ %36, %28 ], [ %0, %6 ]
%40 = trunc i32 %39 to i8
%41 = and i8 %40, 63
%42 = or i8 %41, -128
%43 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %42, i8* %43
%44 = ashr i32 %39, 6
%45 = or i32 %44, 2048
br label %46
46: ; preds = %4, %37
%47 = phi i32 [ %38, %37 ], [ 2, %4 ]
%48 = phi i32 [ %45, %37 ], [ %0, %4 ]
%49 = trunc i32 %48 to i8
%50 = and i8 %49, 63
%51 = or i8 %50, -128
%52 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %51, i8* %52
%53 = ashr i32 %48, 6
%54 = or i32 %53, 192
br label %55
55: ; preds = %46, %2
%56 = phi i32 [ %47, %46 ], [ 1, %2 ]
%57 = phi i32 [ %54, %46 ], [ %0, %2 ]
%58 = trunc i32 %57 to i8
store i8 %58, i8* %1
ret i32 %56
}