int utf8char(const char *const ss) {
  const unsigned char *const s = (const unsigned char *)ss;
  if (s[0] < 0x80)
    return s[0];
  if (s[0] < 0xC0)
    return -1;
  if (s[0] < 0xE0)
    return (s[0] & 0x1F) << 6 | s[1] & 0x3F;
  if (s[0] < 0xF0)
    return (s[0] & 0xF) << 12 | (s[1] & 0x3F) << 6 | (s[2] & 0x3F);
  if (s[0] < 0xF8)
    return (s[0] & 0x7) << 18 | (s[1] & 0x3F) << 12 | (s[2] & 0x3F) << 6 |
           (s[3] & 0x3F);
  if (s[0] < 0xFC)
    return (s[0] & 0x3) << 24 | (s[1] & 0x3F) << 18 | (s[2] & 0x3F) << 12 |
           (s[3] & 0x3F) << 6 | (s[4] & 0x3F);
  return (s[0] & 0x1) << 30 | (s[1] & 0x3F) << 24 | (s[2] & 0x3F) << 18 |
         (s[3] & 0x3F) << 12 | (s[4] & 0x3F) << 6 | (s[5] & 0x3F);
}


x86 assembly (clang, -O0):
<utf8char>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x80,%eax
jge    1131 <utf8char+0x31>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xc0,%eax
jge    114f <utf8char+0x4f>
movl   $0xffffffff,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xe0,%eax
jge    1183 <utf8char+0x83>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
and    $0x1f,%eax
shl    $0x6,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xf0,%eax
jge    11c7 <utf8char+0xc7>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
and    $0xf,%eax
shl    $0xc,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xf8,%eax
jge    121b <utf8char+0x11b>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
and    $0x7,%eax
shl    $0x12,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xfc,%eax
jge    127f <utf8char+0x17f>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
and    $0x3,%eax
shl    $0x18,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x12,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x4(%rcx),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
jmp    12dc <utf8char+0x1dc>
mov    -0x18(%rbp),%rax
movzbl (%rax),%eax
and    $0x1,%eax
shl    $0x1e,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x18,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x12,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x3(%rcx),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x4(%rcx),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x18(%rbp),%rcx
movzbl 0x5(%rcx),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8char>:
movzbl (%rdi),%ecx
test   %cl,%cl
js     110a <utf8char+0xa>
mov    %ecx,%eax
ret
mov    $0xffffffff,%eax
cmp    $0xc0,%cl
jb     1219 <utf8char+0x119>
cmp    $0xdf,%cl
ja     112d <utf8char+0x2d>
and    $0x1f,%ecx
shl    $0x6,%ecx
mov    $0x1,%eax
jmp    1210 <utf8char+0x110>
cmp    $0xef,%cl
ja     114e <utf8char+0x4e>
shl    $0xc,%ecx
movzwl %cx,%eax
movzbl 0x1(%rdi),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %eax,%ecx
mov    $0x2,%eax
jmp    1210 <utf8char+0x110>
cmp    $0xf7,%cl
ja     117b <utf8char+0x7b>
and    $0x7,%ecx
shl    $0x12,%ecx
movzbl 0x1(%rdi),%eax
and    $0x3f,%eax
shl    $0xc,%eax
or     %ecx,%eax
movzbl 0x2(%rdi),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %eax,%ecx
mov    $0x3,%eax
jmp    1210 <utf8char+0x110>
cmp    $0xfb,%cl
ja     11b1 <utf8char+0xb1>
and    $0x3,%ecx
shl    $0x18,%ecx
movzbl 0x1(%rdi),%eax
and    $0x3f,%eax
shl    $0x12,%eax
or     %ecx,%eax
movzbl 0x2(%rdi),%edx
and    $0x3f,%edx
shl    $0xc,%edx
or     %eax,%edx
movzbl 0x3(%rdi),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %edx,%ecx
mov    $0x4,%eax
jmp    1210 <utf8char+0x110>
and    $0x1,%ecx
shl    $0x1e,%ecx
movd   0x1(%rdi),%xmm0
pand   0xe3c(%rip),%xmm0
pxor   %xmm1,%xmm1
punpcklbw %xmm1,%xmm0
punpcklwd %xmm1,%xmm0
pshufd $0xf5,%xmm0,%xmm1
pmuludq 0xe33(%rip),%xmm0
pshufd $0xe8,%xmm0,%xmm0
pmuludq 0xe36(%rip),%xmm1
pshufd $0xe8,%xmm1,%xmm1
punpckldq %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
por    %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
por    %xmm1,%xmm0
movd   %xmm0,%eax
or     %eax,%ecx
mov    $0x5,%eax
movzbl (%rdi,%rax,1),%eax
and    $0x3f,%eax
or     %ecx,%eax
ret

LLVM IR (-O0):
define i32 @utf8char(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i8*
store i8* %0, i8** %3
%5 = load i8*, i8** %3
store i8* %5, i8** %4
%6 = load i8*, i8** %4
%7 = getelementptr inbounds i8, i8* %6, i64 0
%8 = load i8, i8* %7
%9 = zext i8 %8 to i32
%10 = icmp slt i32 %9, 128
br i1 %10, label %11, label %16
11: ; preds = %1
%12 = load i8*, i8** %4
%13 = getelementptr inbounds i8, i8* %12, i64 0
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
store i32 %15, i32* %2
br label %182
16: ; preds = %1
%17 = load i8*, i8** %4
%18 = getelementptr inbounds i8, i8* %17, i64 0
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = icmp slt i32 %20, 192
br i1 %21, label %22, label %23
22: ; preds = %16
store i32 -1, i32* %2
br label %182
23: ; preds = %16
%24 = load i8*, i8** %4
%25 = getelementptr inbounds i8, i8* %24, i64 0
%26 = load i8, i8* %25
%27 = zext i8 %26 to i32
%28 = icmp slt i32 %27, 224
br i1 %28, label %29, label %42
29: ; preds = %23
%30 = load i8*, i8** %4
%31 = getelementptr inbounds i8, i8* %30, i64 0
%32 = load i8, i8* %31
%33 = zext i8 %32 to i32
%34 = and i32 %33, 31
%35 = shl i32 %34, 6
%36 = load i8*, i8** %4
%37 = getelementptr inbounds i8, i8* %36, i64 1
%38 = load i8, i8* %37
%39 = zext i8 %38 to i32
%40 = and i32 %39, 63
%41 = or i32 %35, %40
store i32 %41, i32* %2
br label %182
42: ; preds = %23
%43 = load i8*, i8** %4
%44 = getelementptr inbounds i8, i8* %43, i64 0
%45 = load i8, i8* %44
%46 = zext i8 %45 to i32
%47 = icmp slt i32 %46, 240
br i1 %47, label %48, label %68
48: ; preds = %42
%49 = load i8*, i8** %4
%50 = getelementptr inbounds i8, i8* %49, i64 0
%51 = load i8, i8* %50
%52 = zext i8 %51 to i32
%53 = and i32 %52, 15
%54 = shl i32 %53, 12
%55 = load i8*, i8** %4
%56 = getelementptr inbounds i8, i8* %55, i64 1
%57 = load i8, i8* %56
%58 = zext i8 %57 to i32
%59 = and i32 %58, 63
%60 = shl i32 %59, 6
%61 = or i32 %54, %60
%62 = load i8*, i8** %4
%63 = getelementptr inbounds i8, i8* %62, i64 2
%64 = load i8, i8* %63
%65 = zext i8 %64 to i32
%66 = and i32 %65, 63
%67 = or i32 %61, %66
store i32 %67, i32* %2
br label %182
68: ; preds = %42
%69 = load i8*, i8** %4
%70 = getelementptr inbounds i8, i8* %69, i64 0
%71 = load i8, i8* %70
%72 = zext i8 %71 to i32
%73 = icmp slt i32 %72, 248
br i1 %73, label %74, label %101
74: ; preds = %68
%75 = load i8*, i8** %4
%76 = getelementptr inbounds i8, i8* %75, i64 0
%77 = load i8, i8* %76
%78 = zext i8 %77 to i32
%79 = and i32 %78, 7
%80 = shl i32 %79, 18
%81 = load i8*, i8** %4
%82 = getelementptr inbounds i8, i8* %81, i64 1
%83 = load i8, i8* %82
%84 = zext i8 %83 to i32
%85 = and i32 %84, 63
%86 = shl i32 %85, 12
%87 = or i32 %80, %86
%88 = load i8*, i8** %4
%89 = getelementptr inbounds i8, i8* %88, i64 2
%90 = load i8, i8* %89
%91 = zext i8 %90 to i32
%92 = and i32 %91, 63
%93 = shl i32 %92, 6
%94 = or i32 %87, %93
%95 = load i8*, i8** %4
%96 = getelementptr inbounds i8, i8* %95, i64 3
%97 = load i8, i8* %96
%98 = zext i8 %97 to i32
%99 = and i32 %98, 63
%100 = or i32 %94, %99
store i32 %100, i32* %2
br label %182
101: ; preds = %68
%102 = load i8*, i8** %4
%103 = getelementptr inbounds i8, i8* %102, i64 0
%104 = load i8, i8* %103
%105 = zext i8 %104 to i32
%106 = icmp slt i32 %105, 252
br i1 %106, label %107, label %141
107: ; preds = %101
%108 = load i8*, i8** %4
%109 = getelementptr inbounds i8, i8* %108, i64 0
%110 = load i8, i8* %109
%111 = zext i8 %110 to i32
%112 = and i32 %111, 3
%113 = shl i32 %112, 24
%114 = load i8*, i8** %4
%115 = getelementptr inbounds i8, i8* %114, i64 1
%116 = load i8, i8* %115
%117 = zext i8 %116 to i32
%118 = and i32 %117, 63
%119 = shl i32 %118, 18
%120 = or i32 %113, %119
%121 = load i8*, i8** %4
%122 = getelementptr inbounds i8, i8* %121, i64 2
%123 = load i8, i8* %122
%124 = zext i8 %123 to i32
%125 = and i32 %124, 63
%126 = shl i32 %125, 12
%127 = or i32 %120, %126
%128 = load i8*, i8** %4
%129 = getelementptr inbounds i8, i8* %128, i64 3
%130 = load i8, i8* %129
%131 = zext i8 %130 to i32
%132 = and i32 %131, 63
%133 = shl i32 %132, 6
%134 = or i32 %127, %133
%135 = load i8*, i8** %4
%136 = getelementptr inbounds i8, i8* %135, i64 4
%137 = load i8, i8* %136
%138 = zext i8 %137 to i32
%139 = and i32 %138, 63
%140 = or i32 %134, %139
store i32 %140, i32* %2
br label %182
141: ; preds = %101
%142 = load i8*, i8** %4
%143 = getelementptr inbounds i8, i8* %142, i64 0
%144 = load i8, i8* %143
%145 = zext i8 %144 to i32
%146 = and i32 %145, 1
%147 = shl i32 %146, 30
%148 = load i8*, i8** %4
%149 = getelementptr inbounds i8, i8* %148, i64 1
%150 = load i8, i8* %149
%151 = zext i8 %150 to i32
%152 = and i32 %151, 63
%153 = shl i32 %152, 24
%154 = or i32 %147, %153
%155 = load i8*, i8** %4
%156 = getelementptr inbounds i8, i8* %155, i64 2
%157 = load i8, i8* %156
%158 = zext i8 %157 to i32
%159 = and i32 %158, 63
%160 = shl i32 %159, 18
%161 = or i32 %154, %160
%162 = load i8*, i8** %4
%163 = getelementptr inbounds i8, i8* %162, i64 3
%164 = load i8, i8* %163
%165 = zext i8 %164 to i32
%166 = and i32 %165, 63
%167 = shl i32 %166, 12
%168 = or i32 %161, %167
%169 = load i8*, i8** %4
%170 = getelementptr inbounds i8, i8* %169, i64 4
%171 = load i8, i8* %170
%172 = zext i8 %171 to i32
%173 = and i32 %172, 63
%174 = shl i32 %173, 6
%175 = or i32 %168, %174
%176 = load i8*, i8** %4
%177 = getelementptr inbounds i8, i8* %176, i64 5
%178 = load i8, i8* %177
%179 = zext i8 %178 to i32
%180 = and i32 %179, 63
%181 = or i32 %175, %180
store i32 %181, i32* %2
br label %182
182: ; preds = %141, %107, %74, %48, %29, %22, %11
%183 = load i32, i32* %2
ret i32 %183
}

LLVM IR (-O2):
define i32 @utf8char(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = zext i8 %2 to i32
%4 = icmp sgt i8 %2, -1
br i1 %4, label %82, label %5
5: ; preds = %1
%6 = icmp ult i8 %2, -64
br i1 %6, label %82, label %7
7: ; preds = %5
%8 = icmp ult i8 %2, -32
br i1 %8, label %9, label %12
9: ; preds = %7
%10 = shl nuw nsw i32 %3, 6
%11 = and i32 %10, 1984
br label %74
12: ; preds = %7
%13 = icmp ult i8 %2, -16
br i1 %13, label %14, label %23
14: ; preds = %12
%15 = shl nuw nsw i32 %3, 12
%16 = and i32 %15, 61440
%17 = getelementptr inbounds i8, i8* %0, i64 1
%18 = load i8, i8* %17
%19 = and i8 %18, 63
%20 = zext i8 %19 to i32
%21 = shl nuw nsw i32 %20, 6
%22 = or i32 %21, %16
br label %74
23: ; preds = %12
%24 = icmp ult i8 %2, -8
br i1 %24, label %25, label %40
25: ; preds = %23
%26 = shl nuw nsw i32 %3, 18
%27 = and i32 %26, 1835008
%28 = getelementptr inbounds i8, i8* %0, i64 1
%29 = load i8, i8* %28
%30 = and i8 %29, 63
%31 = zext i8 %30 to i32
%32 = shl nuw nsw i32 %31, 12
%33 = or i32 %32, %27
%34 = getelementptr inbounds i8, i8* %0, i64 2
%35 = load i8, i8* %34
%36 = and i8 %35, 63
%37 = zext i8 %36 to i32
%38 = shl nuw nsw i32 %37, 6
%39 = or i32 %33, %38
br label %74
40: ; preds = %23
%41 = icmp ult i8 %2, -4
br i1 %41, label %42, label %63
42: ; preds = %40
%43 = shl nuw i32 %3, 24
%44 = and i32 %43, 50331648
%45 = getelementptr inbounds i8, i8* %0, i64 1
%46 = load i8, i8* %45
%47 = and i8 %46, 63
%48 = zext i8 %47 to i32
%49 = shl nuw nsw i32 %48, 18
%50 = or i32 %49, %44
%51 = getelementptr inbounds i8, i8* %0, i64 2
%52 = load i8, i8* %51
%53 = and i8 %52, 63
%54 = zext i8 %53 to i32
%55 = shl nuw nsw i32 %54, 12
%56 = or i32 %50, %55
%57 = getelementptr inbounds i8, i8* %0, i64 3
%58 = load i8, i8* %57
%59 = and i8 %58, 63
%60 = zext i8 %59 to i32
%61 = shl nuw nsw i32 %60, 6
%62 = or i32 %56, %61
br label %74
63: ; preds = %40
%64 = shl i32 %3, 30
%65 = and i32 %64, 1073741824
%66 = getelementptr inbounds i8, i8* %0, i64 1
%67 = bitcast i8* %66 to <4 x i8>*
%68 = load <4 x i8>, <4 x i8>* %67
%69 = and <4 x i8> %68, <i8 63, i8 63, i8 63, i8 63>
%70 = zext <4 x i8> %69 to <4 x i32>
%71 = shl nuw nsw <4 x i32> %70, <i32 24, i32 18, i32 12, i32 6>
%72 = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %71)
%73 = or i32 %72, %65
br label %74
74: ; preds = %9, %14, %25, %42, %63
%75 = phi i64 [ 5, %63 ], [ 4, %42 ], [ 3, %25 ], [ 2, %14 ], [ 1, %9 ]
%76 = phi i32 [ %73, %63 ], [ %62, %42 ], [ %39, %25 ], [ %22, %14 ], [ %11, %9 ]
%77 = getelementptr inbounds i8, i8* %0, i64 %75
%78 = load i8, i8* %77
%79 = and i8 %78, 63
%80 = zext i8 %79 to i32
%81 = or i32 %76, %80
br label %82
82: ; preds = %74, %5, %1
%83 = phi i32 [ %3, %1 ], [ -1, %5 ], [ %81, %74 ]
ret i32 %83
}