#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int js_read_u_escaped(char **);
unsigned long js_read_code_point(char **s) {
  unsigned long cp = js_read_u_escaped(s);
  return (cp >= 0xd800 && cp <= 0xdfff)
             ? (((cp - 0xd800) & 0x3ff) << 10 |
                ((js_read_u_escaped(s) - 0xdc00) & 0x3ff)) +
                   0x10000
             : cp;
}


x86 assembly (clang, -O0):
<js_read_code_point>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <js_read_u_escaped@plt>
cltq
mov    %rax,-0x10(%rbp)
cmpq   $0xd800,-0x10(%rbp)
jb     118f <js_read_code_point+0x7f>
cmpq   $0xdfff,-0x10(%rbp)
ja     118f <js_read_code_point+0x7f>
mov    -0x10(%rbp),%rax
sub    $0xd800,%rax
and    $0x3ff,%rax
shl    $0xa,%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <js_read_u_escaped@plt>
mov    %eax,%ecx
mov    -0x20(%rbp),%rax
sub    $0xdc00,%ecx
and    $0x3ff,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
add    $0x10000,%rax
mov    %rax,-0x18(%rbp)
jmp    1197 <js_read_code_point+0x87>
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<js_read_code_point>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
call   1030 <js_read_u_escaped@plt>
mov    %eax,%ebx
and    $0xfffff800,%eax
cmp    $0xd800,%eax
jne    114b <js_read_code_point+0x3b>
shl    $0xa,%ebx
and    $0xffc00,%ebx
mov    %r14,%rdi
call   1030 <js_read_u_escaped@plt>
and    $0x3ff,%eax
add    %rbx,%rax
add    $0x10000,%rax
jmp    114e <js_read_code_point+0x3e>
movslq %ebx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define i64 @js_read_code_point(i8** %0) {
%2 = alloca i8**
%3 = alloca i64
store i8** %0, i8*** %2
%4 = load i8**, i8*** %2
%5 = call i32 @js_read_u_escaped(i8** %4)
%6 = sext i32 %5 to i64
store i64 %6, i64* %3
%7 = load i64, i64* %3
%8 = icmp uge i64 %7, 55296
br i1 %8, label %9, label %24
9: ; preds = %1
%10 = load i64, i64* %3
%11 = icmp ule i64 %10, 57343
br i1 %11, label %12, label %24
12: ; preds = %9
%13 = load i64, i64* %3
%14 = sub i64 %13, 55296
%15 = and i64 %14, 1023
%16 = shl i64 %15, 10
%17 = load i8**, i8*** %2
%18 = call i32 @js_read_u_escaped(i8** %17)
%19 = sub nsw i32 %18, 56320
%20 = and i32 %19, 1023
%21 = sext i32 %20 to i64
%22 = or i64 %16, %21
%23 = add i64 %22, 65536
br label %26
24: ; preds = %9, %1
%25 = load i64, i64* %3
br label %26
26: ; preds = %24, %12
%27 = phi i64 [ %23, %12 ], [ %25, %24 ]
ret i64 %27
}

LLVM IR (-O2):
define i64 @js_read_code_point(i8** %0) {
%2 = tail call i32 @js_read_u_escaped(i8** %0)
%3 = sext i32 %2 to i64
%4 = and i32 %2, -2048
%5 = icmp eq i32 %4, 55296
br i1 %5, label %6, label %14
6: ; preds = %1
%7 = shl nsw i64 %3, 10
%8 = and i64 %7, 1047552
%9 = tail call i32 @js_read_u_escaped(i8** %0)
%10 = and i32 %9, 1023
%11 = zext i32 %10 to i64
%12 = add nuw nsw i64 %8, 65536
%13 = or i64 %12, %11
br label %14
14: ; preds = %1, %6
%15 = phi i64 [ %13, %6 ], [ %3, %1 ]
ret i64 %15
}