int encode_utf8(unsigned long u, unsigned char *buf) {
  int i;
  unsigned long max_val[6] = {0x0000007ful, 0x000007fful, 0x0000fffful,
                              0x001ffffful, 0x03fffffful, 0x7ffffffful};
  static const int MAX_VAL_SZ = sizeof(max_val) / sizeof(max_val[0]);
  for (i = 0; i < MAX_VAL_SZ; ++i) {
    if (u <= max_val[i])
      break;
  }
  if (i == MAX_VAL_SZ) {
    return -1;
  }
  if (i == 0) {
    buf[0] = u;
  } else {
    signed int j;
    for (j = i; j > 0; --j) {
      buf[j] = 0x80 | (u & 0x3f);
      u >>= 6;
    }
    unsigned char mask = ~(0xFF >> (i + 1));
    buf[0] = mask | u;
  }
  return i + 1;
}


x86 assembly (clang, -O0):
<encode_utf8>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
lea    -0x50(%rbp),%rdi
xor    %esi,%esi
mov    $0x30,%edx
call   1030 <memset@plt>
movq   $0x7f,-0x50(%rbp)
movq   $0x7ff,-0x48(%rbp)
movq   $0xffff,-0x40(%rbp)
movq   $0x1fffff,-0x38(%rbp)
movq   $0x3ffffff,-0x30(%rbp)
03
movq   $0x7fffffff,-0x28(%rbp)
7f
movl   $0x0,-0x1c(%rbp)
cmpl   $0x6,-0x1c(%rbp)
jge    119c <encode_utf8+0x8c>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
cmp    -0x50(%rbp,%rcx,8),%rax
ja     1189 <encode_utf8+0x79>
jmp    119c <encode_utf8+0x8c>
jmp    118e <encode_utf8+0x7e>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1167 <encode_utf8+0x57>
cmpl   $0x6,-0x1c(%rbp)
jne    11b2 <encode_utf8+0xa2>
movl   $0xffffffff,-0x4(%rbp)
jmp    123e <encode_utf8+0x12e>
cmpl   $0x0,-0x1c(%rbp)
jne    11cd <encode_utf8+0xbd>
mov    -0x10(%rbp),%rax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
jmp    1235 <encode_utf8+0x125>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x54(%rbp)
cmpl   $0x0,-0x54(%rbp)
jle    1212 <encode_utf8+0x102>
mov    -0x10(%rbp),%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x54(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
shr    $0x6,%rax
mov    %rax,-0x10(%rbp)
mov    -0x54(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x54(%rbp)
jmp    11d3 <encode_utf8+0xc3>
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
mov    $0xff,%eax
sar    %cl,%eax
xor    $0xffffffff,%eax
mov    %al,-0x55(%rbp)
movzbl -0x55(%rbp),%eax
or     -0x10(%rbp),%rax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<encode_utf8>:
xor    %ecx,%ecx
cmp    $0x80,%rdi
jb     11e0 <encode_utf8+0xe0>
cmp    $0x800,%rdi
jb     115d <encode_utf8+0x5d>
mov    $0x2,%ecx
mov    $0x1,%r8b
cmp    $0x10000,%rdi
jb     1165 <encode_utf8+0x65>
mov    $0x3,%ecx
cmp    $0x200000,%rdi
jb     1165 <encode_utf8+0x65>
mov    $0x4,%ecx
cmp    $0x4000000,%rdi
jb     1165 <encode_utf8+0x65>
mov    $0x5,%ecx
mov    $0xffffffff,%eax
cmp    $0x7fffffff,%rdi
jbe    1165 <encode_utf8+0x65>
jmp    11e8 <encode_utf8+0xe8>
mov    $0x1,%ecx
xor    %r8d,%r8d
mov    %ecx,%edx
mov    %edi,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,(%rsi,%rdx,1)
mov    %rdi,%rax
shr    $0x6,%rax
test   %r8b,%r8b
je     11d6 <encode_utf8+0xd6>
lea    -0x1(%rdx),%r8
and    $0x3f,%al
or     $0x80,%al
mov    %al,-0x1(%rsi,%rdx,1)
mov    %rdi,%rax
shr    $0xc,%rax
cmp    $0x2,%r8
jb     11d6 <encode_utf8+0xd6>
lea    -0x2(%rdx),%r8
and    $0x3f,%al
or     $0x80,%al
mov    %al,-0x2(%rsi,%rdx,1)
mov    %rdi,%rax
shr    $0x12,%rax
cmp    $0x2,%r8
jb     11d6 <encode_utf8+0xd6>
lea    -0x3(%rdx),%r8
and    $0x3f,%al
or     $0x80,%al
mov    %al,(%rsi,%r8,1)
mov    %rdi,%rax
shr    $0x18,%rax
cmp    $0x2,%r8
jb     11d6 <encode_utf8+0xd6>
and    $0x3f,%al
or     $0x80,%al
mov    %al,-0x4(%rdx,%rsi,1)
shr    $0x1e,%rdi
mov    %rdi,%rax
mov    $0xffffff80,%edi
sar    %cl,%edi
or     %rax,%rdi
mov    %dil,(%rsi)
add    $0x1,%ecx
mov    %ecx,%eax
ret

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

LLVM IR (-O2):
define i32 @encode_utf8(i64 %0, i8* nocapture writeonly %1) {
%3 = icmp ugt i64 %0, 127
br i1 %3, label %4, label %59
4: ; preds = %2
%5 = icmp ugt i64 %0, 2047
br i1 %5, label %6, label %14
6: ; preds = %4
%7 = icmp ugt i64 %0, 65535
br i1 %7, label %8, label %14
8: ; preds = %6
%9 = icmp ugt i64 %0, 2097151
br i1 %9, label %10, label %14
10: ; preds = %8
%11 = icmp ugt i64 %0, 67108863
br i1 %11, label %12, label %14
12: ; preds = %10
%13 = icmp ugt i64 %0, 2147483647
br i1 %13, label %64, label %14
14: ; preds = %4, %6, %8, %10, %12
%15 = phi i1 [ false, %4 ], [ true, %6 ], [ true, %8 ], [ true, %10 ], [ true, %12 ]
%16 = phi i32 [ 1, %4 ], [ 2, %6 ], [ 3, %8 ], [ 4, %10 ], [ 5, %12 ]
%17 = zext i32 %16 to i64
%18 = trunc i64 %0 to i8
%19 = and i8 %18, 63
%20 = or i8 %19, -128
%21 = getelementptr inbounds i8, i8* %1, i64 %17
store i8 %20, i8* %21
%22 = lshr i64 %0, 6
%23 = add nsw i64 %17, -1
br i1 %15, label %24, label %54
24: ; preds = %14
%25 = trunc i64 %22 to i8
%26 = and i8 %25, 63
%27 = or i8 %26, -128
%28 = getelementptr inbounds i8, i8* %1, i64 %23
store i8 %27, i8* %28
%29 = lshr i64 %0, 12
%30 = add nsw i64 %17, -2
%31 = icmp ugt i64 %23, 1
br i1 %31, label %32, label %54
32: ; preds = %24
%33 = trunc i64 %29 to i8
%34 = and i8 %33, 63
%35 = or i8 %34, -128
%36 = getelementptr inbounds i8, i8* %1, i64 %30
store i8 %35, i8* %36
%37 = lshr i64 %0, 18
%38 = add nsw i64 %17, -3
%39 = icmp ugt i64 %30, 1
br i1 %39, label %40, label %54
40: ; preds = %32
%41 = trunc i64 %37 to i8
%42 = and i8 %41, 63
%43 = or i8 %42, -128
%44 = getelementptr inbounds i8, i8* %1, i64 %38
store i8 %43, i8* %44
%45 = lshr i64 %0, 24
%46 = icmp ugt i64 %38, 1
br i1 %46, label %47, label %54
47: ; preds = %40
%48 = add nsw i64 %17, -4
%49 = trunc i64 %45 to i8
%50 = and i8 %49, 63
%51 = or i8 %50, -128
%52 = getelementptr inbounds i8, i8* %1, i64 %48
store i8 %51, i8* %52
%53 = lshr i64 %0, 30
br label %54
54: ; preds = %47, %40, %32, %24, %14
%55 = phi i64 [ %22, %14 ], [ %29, %24 ], [ %37, %32 ], [ %45, %40 ], [ %53, %47 ]
%56 = ashr i32 -128, %16
%57 = zext i32 %56 to i64
%58 = or i64 %55, %57
br label %59
59: ; preds = %2, %54
%60 = phi i32 [ %16, %54 ], [ 0, %2 ]
%61 = phi i64 [ %58, %54 ], [ %0, %2 ]
%62 = trunc i64 %61 to i8
store i8 %62, i8* %1
%63 = add nuw nsw i32 %60, 1
br label %64
64: ; preds = %12, %59
%65 = phi i32 [ %63, %59 ], [ -1, %12 ]
ret i32 %65
}