int unicode_width(unsigned long c, int tab_size) {
  if (c >= 0x1100 &&
      (c <= 0x115f || c == 0x2329 || c == 0x232a ||
       (c >= 0x2e80 && c <= 0xa4cf && c != 0x303f) ||
       (c >= 0xac00 && c <= 0xd7a3) || (c >= 0xf900 && c <= 0xfaff) ||
       (c >= 0xfe30 && c <= 0xfe6f) || (c >= 0xff00 && c <= 0xff60) ||
       (c >= 0xffe0 && c <= 0xffe6) || (c >= 0x20000 && c <= 0x2fffd) ||
       (c >= 0x30000 && c <= 0x3fffd)))
    return 2;
  if (c == '\t')
    return tab_size;
  return 1;
}


x86 assembly (clang, -O0):
<unicode_width>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
cmpq   $0x1100,-0x10(%rbp)
jb     123d <unicode_width+0x13d>
cmpq   $0x115f,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0x2329,-0x10(%rbp)
je     1231 <unicode_width+0x131>
cmpq   $0x232a,-0x10(%rbp)
je     1231 <unicode_width+0x131>
cmpq   $0x2e80,-0x10(%rbp)
jb     116d <unicode_width+0x6d>
cmpq   $0xa4cf,-0x10(%rbp)
ja     116d <unicode_width+0x6d>
cmpq   $0x303f,-0x10(%rbp)
jne    1231 <unicode_width+0x131>
cmpq   $0xac00,-0x10(%rbp)
jb     1189 <unicode_width+0x89>
cmpq   $0xd7a3,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0xf900,-0x10(%rbp)
jb     11a5 <unicode_width+0xa5>
cmpq   $0xfaff,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0xfe30,-0x10(%rbp)
jb     11c1 <unicode_width+0xc1>
cmpq   $0xfe6f,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0xff00,-0x10(%rbp)
jb     11dd <unicode_width+0xdd>
cmpq   $0xff60,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0xffe0,-0x10(%rbp)
jb     11f9 <unicode_width+0xf9>
cmpq   $0xffe6,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0x20000,-0x10(%rbp)
jb     1215 <unicode_width+0x115>
cmpq   $0x2fffd,-0x10(%rbp)
jbe    1231 <unicode_width+0x131>
cmpq   $0x30000,-0x10(%rbp)
jb     123d <unicode_width+0x13d>
cmpq   $0x3fffd,-0x10(%rbp)
ja     123d <unicode_width+0x13d>
movl   $0x2,-0x4(%rbp)
jmp    125a <unicode_width+0x15a>
cmpq   $0x9,-0x10(%rbp)
jne    1253 <unicode_width+0x153>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    125a <unicode_width+0x15a>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unicode_width>:
cmp    $0x1100,%rdi
jb     11b8 <unicode_width+0xb8>
mov    $0x2,%eax
cmp    $0x1160,%rdi
jb     11c4 <unicode_width+0xc4>
lea    -0x2329(%rdi),%rcx
cmp    $0x2,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0x2e80(%rdi),%rcx
cmp    $0x7650,%rcx
setb   %r8b
cmp    $0x303f,%rdi
setne  %dl
lea    -0x30000(%rdi),%rcx
cmp    $0xfffe,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0x20000(%rdi),%rcx
cmp    $0xfffe,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0xffe0(%rdi),%rcx
cmp    $0x7,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0xff00(%rdi),%rcx
cmp    $0x61,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0xfe30(%rdi),%rcx
cmp    $0x40,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0xf900(%rdi),%rcx
cmp    $0x200,%rcx
jb     11c4 <unicode_width+0xc4>
lea    -0xac00(%rdi),%rcx
cmp    $0x2ba4,%rcx
jb     11c4 <unicode_width+0xc4>
and    %r8b,%dl
jne    11c4 <unicode_width+0xc4>
cmp    $0x9,%rdi
mov    $0x1,%eax
cmove  %esi,%eax
ret

LLVM IR (-O0):
define i32 @unicode_width(i64 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i64
%5 = alloca i32
store i64 %0, i64* %4
store i32 %1, i32* %5
%6 = load i64, i64* %4
%7 = icmp uge i64 %6, 4352
br i1 %7, label %8, label %69
8: ; preds = %2
%9 = load i64, i64* %4
%10 = icmp ule i64 %9, 4447
br i1 %10, label %68, label %11
11: ; preds = %8
%12 = load i64, i64* %4
%13 = icmp eq i64 %12, 9001
br i1 %13, label %68, label %14
14: ; preds = %11
%15 = load i64, i64* %4
%16 = icmp eq i64 %15, 9002
br i1 %16, label %68, label %17
17: ; preds = %14
%18 = load i64, i64* %4
%19 = icmp uge i64 %18, 11904
br i1 %19, label %20, label %26
20: ; preds = %17
%21 = load i64, i64* %4
%22 = icmp ule i64 %21, 42191
br i1 %22, label %23, label %26
23: ; preds = %20
%24 = load i64, i64* %4
%25 = icmp ne i64 %24, 12351
br i1 %25, label %68, label %26
26: ; preds = %23, %20, %17
%27 = load i64, i64* %4
%28 = icmp uge i64 %27, 44032
br i1 %28, label %29, label %32
29: ; preds = %26
%30 = load i64, i64* %4
%31 = icmp ule i64 %30, 55203
br i1 %31, label %68, label %32
32: ; preds = %29, %26
%33 = load i64, i64* %4
%34 = icmp uge i64 %33, 63744
br i1 %34, label %35, label %38
35: ; preds = %32
%36 = load i64, i64* %4
%37 = icmp ule i64 %36, 64255
br i1 %37, label %68, label %38
38: ; preds = %35, %32
%39 = load i64, i64* %4
%40 = icmp uge i64 %39, 65072
br i1 %40, label %41, label %44
41: ; preds = %38
%42 = load i64, i64* %4
%43 = icmp ule i64 %42, 65135
br i1 %43, label %68, label %44
44: ; preds = %41, %38
%45 = load i64, i64* %4
%46 = icmp uge i64 %45, 65280
br i1 %46, label %47, label %50
47: ; preds = %44
%48 = load i64, i64* %4
%49 = icmp ule i64 %48, 65376
br i1 %49, label %68, label %50
50: ; preds = %47, %44
%51 = load i64, i64* %4
%52 = icmp uge i64 %51, 65504
br i1 %52, label %53, label %56
53: ; preds = %50
%54 = load i64, i64* %4
%55 = icmp ule i64 %54, 65510
br i1 %55, label %68, label %56
56: ; preds = %53, %50
%57 = load i64, i64* %4
%58 = icmp uge i64 %57, 131072
br i1 %58, label %59, label %62
59: ; preds = %56
%60 = load i64, i64* %4
%61 = icmp ule i64 %60, 196605
br i1 %61, label %68, label %62
62: ; preds = %59, %56
%63 = load i64, i64* %4
%64 = icmp uge i64 %63, 196608
br i1 %64, label %65, label %69
65: ; preds = %62
%66 = load i64, i64* %4
%67 = icmp ule i64 %66, 262141
br i1 %67, label %68, label %69
68: ; preds = %65, %59, %53, %47, %41, %35, %29, %23, %14, %11, %8
store i32 2, i32* %3
br label %75
69: ; preds = %65, %62, %2
%70 = load i64, i64* %4
%71 = icmp eq i64 %70, 9
br i1 %71, label %72, label %74
72: ; preds = %69
%73 = load i32, i32* %5
store i32 %73, i32* %3
br label %75
74: ; preds = %69
store i32 1, i32* %3
br label %75
75: ; preds = %74, %72, %68
%76 = load i32, i32* %3
ret i32 %76
}

LLVM IR (-O2):
define i32 @unicode_width(i64 %0, i32 %1) {
%3 = icmp ugt i64 %0, 4351
br i1 %3, label %4, label %35
4: ; preds = %2
%5 = icmp ult i64 %0, 4448
%6 = add i64 %0, -9001
%7 = icmp ult i64 %6, 2
%8 = or i1 %5, %7
br i1 %8, label %38, label %9
9: ; preds = %4
%10 = add i64 %0, -11904
%11 = icmp ult i64 %10, 30288
%12 = icmp ne i64 %0, 12351
%13 = and i1 %12, %11
%14 = add i64 %0, -44032
%15 = icmp ult i64 %14, 11172
%16 = or i1 %15, %13
%17 = add i64 %0, -63744
%18 = icmp ult i64 %17, 512
%19 = or i1 %18, %16
%20 = add i64 %0, -65072
%21 = icmp ult i64 %20, 64
%22 = or i1 %21, %19
%23 = add i64 %0, -65280
%24 = icmp ult i64 %23, 97
%25 = or i1 %24, %22
%26 = add i64 %0, -65504
%27 = icmp ult i64 %26, 7
%28 = or i1 %27, %25
%29 = add i64 %0, -131072
%30 = icmp ult i64 %29, 65534
%31 = or i1 %30, %28
%32 = add i64 %0, -196608
%33 = icmp ult i64 %32, 65534
%34 = or i1 %33, %31
br i1 %34, label %38, label %35
35: ; preds = %9, %2
%36 = icmp eq i64 %0, 9
%37 = select i1 %36, i32 %1, i32 1
br label %38
38: ; preds = %35, %4, %9
%39 = phi i32 [ 2, %9 ], [ 2, %4 ], [ %37, %35 ]
ret i32 %39
}