int utf8parse(unsigned char byte) {
  static int wc = 0;
  static int len = 0;
  static int coline = 0;
  switch (coline) {
  case 0:;
    if (!(byte & 0x80))
      do {
        coline = 0;
        return byte;
      } while (0);
    else if (!(byte & 0x40))
      do {
        coline = 0;
        return '?';
      } while (0);
    else if (!(byte & 0x20)) {
      wc = byte & 0x1f;
      len = 1;
    } else if (!(byte & 0x10)) {
      wc = byte & 0x0f;
      len = 2;
    } else {
      wc = byte & 0x07;
      len = 3;
    }
    while (len--) {
      do {
        coline = 66;
        return -1;
      case 66:;
      } while (0);
      if ((byte & 0xc0) != 0x80)
        do {
          coline = 0;
          return '?';
        } while (0);
      wc = (wc << 6) | (byte & 0x3f);
    }
    do {
      coline = 0;
      return wc;
    } while (0);
  }
  coline = 0;
  return -1;
}


x86 assembly (clang, -O0):
<utf8parse>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x5(%rbp)
mov    0x2f1c(%rip),%eax
mov    %eax,-0xc(%rbp)
test   %eax,%eax
je     1131 <utf8parse+0x31>
jmp    1120 <utf8parse+0x20>
mov    -0xc(%rbp),%eax
sub    $0x42,%eax
je     1241 <utf8parse+0x141>
jmp    12af <utf8parse+0x1af>
movzbl -0x5(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
jne    115e <utf8parse+0x5e>
jmp    1148 <utf8parse+0x48>
movl   $0x0,0x2eda(%rip)
movzbl -0x5(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    12c0 <utf8parse+0x1c0>
movzbl -0x5(%rbp),%eax
and    $0x40,%eax
cmp    $0x0,%eax
jne    1189 <utf8parse+0x89>
jmp    1173 <utf8parse+0x73>
movl   $0x0,0x2eaf(%rip)
movl   $0x3f,-0x4(%rbp)
jmp    12c0 <utf8parse+0x1c0>
movzbl -0x5(%rbp),%eax
and    $0x20,%eax
cmp    $0x0,%eax
jne    11b5 <utf8parse+0xb5>
movzbl -0x5(%rbp),%eax
and    $0x1f,%eax
mov    %eax,0x2e7e(%rip)
movl   $0x1,0x2e78(%rip)
jmp    11fd <utf8parse+0xfd>
movzbl -0x5(%rbp),%eax
and    $0x10,%eax
cmp    $0x0,%eax
jne    11e1 <utf8parse+0xe1>
movzbl -0x5(%rbp),%eax
and    $0xf,%eax
mov    %eax,0x2e52(%rip)
movl   $0x2,0x2e4c(%rip)
jmp    11f8 <utf8parse+0xf8>
movzbl -0x5(%rbp),%eax
and    $0x7,%eax
mov    %eax,0x2e36(%rip)
movl   $0x3,0x2e30(%rip)
jmp    11fd <utf8parse+0xfd>
jmp    1202 <utf8parse+0x102>
jmp    1207 <utf8parse+0x107>
jmp    120c <utf8parse+0x10c>
mov    0x2e16(%rip),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,0x2e0b(%rip)
cmp    $0x0,%eax
je     1292 <utf8parse+0x192>
jmp    122b <utf8parse+0x12b>
movl   $0x42,0x2df7(%rip)
movl   $0xffffffff,-0x4(%rbp)
jmp    12c0 <utf8parse+0x1c0>
jmp    1246 <utf8parse+0x146>
movzbl -0x5(%rbp),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     1275 <utf8parse+0x175>
jmp    125f <utf8parse+0x15f>
movl   $0x0,0x2dc3(%rip)
movl   $0x3f,-0x4(%rbp)
jmp    12c0 <utf8parse+0x1c0>
mov    0x2da9(%rip),%eax
shl    $0x6,%eax
movzbl -0x5(%rbp),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,0x2d97(%rip)
jmp    120c <utf8parse+0x10c>
jmp    1297 <utf8parse+0x197>
movl   $0x0,0x2d8b(%rip)
mov    0x2d7d(%rip),%eax
mov    %eax,-0x4(%rbp)
jmp    12c0 <utf8parse+0x1c0>
movl   $0x0,0x2d73(%rip)
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8parse>:
mov    %edi,%eax
cmpb   $0x0,0x2f23(%rip)
je     1145 <utf8parse+0x45>
mov    %eax,%ecx
and    $0xffffffc0,%ecx
cmp    $0x80,%ecx
jne    114d <utf8parse+0x4d>
mov    0x2f06(%rip),%ecx
shl    $0x6,%ecx
and    $0x3f,%eax
or     %ecx,%eax
mov    %eax,0x2ef8(%rip)
subl   $0x1,0x2ef5(%rip)
setae  %cl
mov    $0xffffffff,%edx
cmovae %edx,%eax
mov    %cl,0x2ee8(%rip)
ret
test   $0x80,%al
je     1152 <utf8parse+0x52>
test   $0x40,%al
jne    115b <utf8parse+0x5b>
mov    $0x3f,%eax
xor    %ecx,%ecx
mov    %cl,0x2ed2(%rip)
ret
mov    %eax,%ecx
shl    $0x1a,%ecx
sar    $0x1f,%ecx
xor    %edx,%edx
test   $0x10,%al
sete   %dl
mov    $0x2,%esi
sub    %edx,%esi
test   $0x20,%al
lea    0x7(,%rdx,8),%edx
mov    $0x1f,%edi
cmovne %edx,%edi
and    %ecx,%esi
and    %eax,%edi
mov    %edi,0x2e98(%rip)
mov    %esi,0x2e96(%rip)
mov    $0xffffffff,%eax
mov    $0x1,%cl
mov    %cl,0x2e8d(%rip)
ret

LLVM IR (-O0):
@utf8parse.wc = internal global i32 0
@utf8parse.len = internal global i32 0
@utf8parse.coline = internal global i32 0
define i32 @utf8parse(i8 zeroext %0) {
%2 = alloca i32
%3 = alloca i8
store i8 %0, i8* %3
%4 = load i32, i32* @utf8parse.coline
switch i32 %4, label %75 [
i32 0, label %5
i32 66, label %55
]
5: ; preds = %1
%6 = load i8, i8* %3
%7 = zext i8 %6 to i32
%8 = and i32 %7, 128
%9 = icmp ne i32 %8, 0
br i1 %9, label %15, label %10
10: ; preds = %5
br label %11
11: ; preds = %10
store i32 0, i32* @utf8parse.coline
%12 = load i8, i8* %3
%13 = zext i8 %12 to i32
store i32 %13, i32* %2
br label %76
14: ; No predecessors!
br label %48
15: ; preds = %5
%16 = load i8, i8* %3
%17 = zext i8 %16 to i32
%18 = and i32 %17, 64
%19 = icmp ne i32 %18, 0
br i1 %19, label %23, label %20
20: ; preds = %15
br label %21
21: ; preds = %20
store i32 0, i32* @utf8parse.coline
store i32 63, i32* %2
br label %76
22: ; No predecessors!
br label %47
23: ; preds = %15
%24 = load i8, i8* %3
%25 = zext i8 %24 to i32
%26 = and i32 %25, 32
%27 = icmp ne i32 %26, 0
br i1 %27, label %32, label %28
28: ; preds = %23
%29 = load i8, i8* %3
%30 = zext i8 %29 to i32
%31 = and i32 %30, 31
store i32 %31, i32* @utf8parse.wc
store i32 1, i32* @utf8parse.len
br label %46
32: ; preds = %23
%33 = load i8, i8* %3
%34 = zext i8 %33 to i32
%35 = and i32 %34, 16
%36 = icmp ne i32 %35, 0
br i1 %36, label %41, label %37
37: ; preds = %32
%38 = load i8, i8* %3
%39 = zext i8 %38 to i32
%40 = and i32 %39, 15
store i32 %40, i32* @utf8parse.wc
store i32 2, i32* @utf8parse.len
br label %45
41: ; preds = %32
%42 = load i8, i8* %3
%43 = zext i8 %42 to i32
%44 = and i32 %43, 7
store i32 %44, i32* @utf8parse.wc
store i32 3, i32* @utf8parse.len
br label %45
45: ; preds = %41, %37
br label %46
46: ; preds = %45, %28
br label %47
47: ; preds = %46, %22
br label %48
48: ; preds = %47, %14
br label %49
49: ; preds = %64, %48
%50 = load i32, i32* @utf8parse.len
%51 = add nsw i32 %50, -1
store i32 %51, i32* @utf8parse.len
%52 = icmp ne i32 %50, 0
br i1 %52, label %53, label %71
53: ; preds = %49
br label %54
54: ; preds = %53
store i32 66, i32* @utf8parse.coline
store i32 -1, i32* %2
br label %76
55: ; preds = %1
br label %56
56: ; preds = %55
%57 = load i8, i8* %3
%58 = zext i8 %57 to i32
%59 = and i32 %58, 192
%60 = icmp ne i32 %59, 128
br i1 %60, label %61, label %64
61: ; preds = %56
br label %62
62: ; preds = %61
store i32 0, i32* @utf8parse.coline
store i32 63, i32* %2
br label %76
63: ; No predecessors!
br label %64
64: ; preds = %63, %56
%65 = load i32, i32* @utf8parse.wc
%66 = shl i32 %65, 6
%67 = load i8, i8* %3
%68 = zext i8 %67 to i32
%69 = and i32 %68, 63
%70 = or i32 %66, %69
store i32 %70, i32* @utf8parse.wc
br label %49
71: ; preds = %49
br label %72
72: ; preds = %71
store i32 0, i32* @utf8parse.coline
%73 = load i32, i32* @utf8parse.wc
store i32 %73, i32* %2
br label %76
74: ; No predecessors!
br label %75
75: ; preds = %74, %1
store i32 0, i32* @utf8parse.coline
store i32 -1, i32* %2
br label %76
76: ; preds = %75, %72, %62, %54, %21, %11
%77 = load i32, i32* %2
ret i32 %77
}

LLVM IR (-O2):
@utf8parse.wc = internal unnamed_addr global i32 0
@utf8parse.len = internal unnamed_addr global i32 0
@utf8parse.coline = internal unnamed_addr global i1 false
define i32 @utf8parse(i8 zeroext %0) {
%2 = load i1, i1* @utf8parse.coline
%3 = zext i8 %0 to i32
br i1 %2, label %30, label %4
4: ; preds = %1
%5 = and i32 %3, 128
%6 = icmp eq i32 %5, 0
br i1 %6, label %33, label %7
7: ; preds = %4
%8 = and i32 %3, 64
%9 = icmp eq i32 %8, 0
br i1 %9, label %33, label %10
10: ; preds = %7
%11 = and i32 %3, 32
%12 = icmp eq i32 %11, 0
%13 = and i32 %3, 16
%14 = icmp eq i32 %13, 0
%15 = select i1 %14, i32 15, i32 7
%16 = select i1 %14, i32 1, i32 2
%17 = select i1 %12, i32 31, i32 %15
%18 = select i1 %12, i32 0, i32 %16
%19 = and i32 %17, %3
store i32 %19, i32* @utf8parse.wc
store i32 %18, i32* @utf8parse.len
br label %33
20: ; preds = %30
%21 = load i32, i32* @utf8parse.wc
%22 = shl i32 %21, 6
%23 = and i32 %3, 63
%24 = or i32 %22, %23
store i32 %24, i32* @utf8parse.wc
%25 = load i32, i32* @utf8parse.len
%26 = add nsw i32 %25, -1
store i32 %26, i32* @utf8parse.len
%27 = icmp eq i32 %25, 0
%28 = xor i1 %27, true
%29 = select i1 %27, i32 %24, i32 -1
br label %33
30: ; preds = %1
%31 = and i32 %3, 192
%32 = icmp eq i32 %31, 128
br i1 %32, label %20, label %33
33: ; preds = %20, %30, %10, %7, %4
%34 = phi i1 [ false, %4 ], [ false, %7 ], [ true, %10 ], [ false, %30 ], [ %28, %20 ]
%35 = phi i32 [ %3, %4 ], [ 63, %7 ], [ -1, %10 ], [ 63, %30 ], [ %29, %20 ]
store i1 %34, i1* @utf8parse.coline
ret i32 %35
}