int ucdecomp_hangul(unsigned long code, unsigned long *num,
                    unsigned long decomp[]) {
  if (!((code) >= 0xac00 && (code) <= 0xd7ff))
    return 0;
  code -= 0xac00;
  decomp[0] = 0x1100 + (unsigned long)(code / 588);
  decomp[1] = 0x1161 + (unsigned long)((code % 588) / 28);
  decomp[2] = 0x11a7 + (unsigned long)(code % 28);
  *num = (decomp[2] != 0x11a7) ? 3 : 2;
  return 1;
}


x86 assembly (clang, -O0):
<ucdecomp_hangul>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0xac00,-0x10(%rbp)
jb     112c <ucdecomp_hangul+0x2c>
cmpq   $0xd7ff,-0x10(%rbp)
jbe    1138 <ucdecomp_hangul+0x38>
movl   $0x0,-0x4(%rbp)
jmp    11dc <ucdecomp_hangul+0xdc>
mov    -0x10(%rbp),%rax
sub    $0xac00,%rax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    $0x24c,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,%rcx
add    $0x1100,%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rax
mov    $0x24c,%ecx
xor    %edx,%edx
div    %rcx
mov    %rdx,%rax
mov    $0x1c,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,%rcx
add    $0x1161,%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,0x8(%rax)
mov    -0x10(%rbp),%rax
mov    $0x1c,%ecx
xor    %edx,%edx
div    %rcx
add    $0x11a7,%rdx
mov    -0x20(%rbp),%rax
mov    %rdx,0x10(%rax)
mov    -0x20(%rbp),%rax
mov    0x10(%rax),%rdx
mov    $0x2,%eax
mov    $0x3,%ecx
cmp    $0x11a7,%rdx
cmovne %ecx,%eax
movslq %eax,%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ucdecomp_hangul>:
add    $0xffffffffffff5400,%rdi
xor    %eax,%eax
cmp    $0x2bff,%rdi
ja     118b <ucdecomp_hangul+0x8b>
movzwl %di,%r8d
imul   $0x6f75,%r8d,%ecx
shr    $0x18,%ecx
lea    0x1100(%rcx),%eax
mov    %rax,(%rdx)
imul   $0x24c,%ecx,%eax
mov    %edi,%ecx
sub    %eax,%ecx
movzwl %cx,%eax
shr    $0x2,%eax
imul   $0x4925,%eax,%eax
shr    $0x11,%eax
add    $0x1161,%eax
mov    %rax,0x8(%rdx)
shr    $0x2,%r8d
imul   $0x4925,%r8d,%eax
shr    $0x11,%eax
lea    (%rax,%rax,8),%ecx
lea    (%rcx,%rcx,2),%ecx
add    %eax,%ecx
mov    %edi,%eax
sub    %ecx,%eax
neg    %ecx
add    %edi,%ecx
add    $0x11a7,%ecx
movzwl %cx,%ecx
mov    %rcx,0x10(%rdx)
cmp    $0x1,%ax
mov    $0x3,%eax
sbb    $0x0,%rax
mov    %rax,(%rsi)
mov    $0x1,%eax
ret

LLVM IR (-O0):
define i32 @ucdecomp_hangul(i64 %0, i64* %1, i64* %2) {
%4 = alloca i32
%5 = alloca i64
%6 = alloca i64*
%7 = alloca i64*
store i64 %0, i64* %5
store i64* %1, i64** %6
store i64* %2, i64** %7
%8 = load i64, i64* %5
%9 = icmp uge i64 %8, 44032
br i1 %9, label %10, label %13
10: ; preds = %3
%11 = load i64, i64* %5
%12 = icmp ule i64 %11, 55295
br i1 %12, label %14, label %13
13: ; preds = %10, %3
store i32 0, i32* %4
br label %41
14: ; preds = %10
%15 = load i64, i64* %5
%16 = sub i64 %15, 44032
store i64 %16, i64* %5
%17 = load i64, i64* %5
%18 = udiv i64 %17, 588
%19 = add i64 4352, %18
%20 = load i64*, i64** %7
%21 = getelementptr inbounds i64, i64* %20, i64 0
store i64 %19, i64* %21
%22 = load i64, i64* %5
%23 = urem i64 %22, 588
%24 = udiv i64 %23, 28
%25 = add i64 4449, %24
%26 = load i64*, i64** %7
%27 = getelementptr inbounds i64, i64* %26, i64 1
store i64 %25, i64* %27
%28 = load i64, i64* %5
%29 = urem i64 %28, 28
%30 = add i64 4519, %29
%31 = load i64*, i64** %7
%32 = getelementptr inbounds i64, i64* %31, i64 2
store i64 %30, i64* %32
%33 = load i64*, i64** %7
%34 = getelementptr inbounds i64, i64* %33, i64 2
%35 = load i64, i64* %34
%36 = icmp ne i64 %35, 4519
%37 = zext i1 %36 to i64
%38 = select i1 %36, i32 3, i32 2
%39 = sext i32 %38 to i64
%40 = load i64*, i64** %6
store i64 %39, i64* %40
store i32 1, i32* %4
br label %41
41: ; preds = %14, %13
%42 = load i32, i32* %4
ret i32 %42
}

LLVM IR (-O2):
define i32 @ucdecomp_hangul(i64 %0, i64* nocapture writeonly %1, i64* nocapture writeonly %2) {
%4 = add i64 %0, -44032
%5 = icmp ult i64 %4, 11264
br i1 %5, label %6, label %22
6: ; preds = %3
%7 = trunc i64 %4 to i16
%8 = udiv i16 %7, 588
%9 = or i16 %8, 4352
%10 = zext i16 %9 to i64
store i64 %10, i64* %2
%11 = urem i16 %7, 588
%12 = udiv i16 %11, 28
%13 = add nuw nsw i16 %12, 4449
%14 = zext i16 %13 to i64
%15 = getelementptr inbounds i64, i64* %2, i64 1
store i64 %14, i64* %15
%16 = urem i16 %7, 28
%17 = add nuw nsw i16 %16, 4519
%18 = zext i16 %17 to i64
%19 = getelementptr inbounds i64, i64* %2, i64 2
store i64 %18, i64* %19
%20 = icmp eq i16 %16, 0
%21 = select i1 %20, i64 2, i64 3
store i64 %21, i64* %1
br label %22
22: ; preds = %3, %6
%23 = phi i32 [ 1, %6 ], [ 0, %3 ]
ret i32 %23
}