#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 /*<<< orphan*/ printf(char *, unsigned int);
int unicoder_utf8_decode(unsigned int *result, unsigned char *p) {
  int i;
  int numBytes = 0;
  unsigned int decoded = 0;
  unsigned char currByte;
  const int debug_utf8_decode = 0;
  if (result == NULL)
    return -1;
  if (p == NULL)
    return -1;
  currByte = *p;
  if ((numBytes == 0) && ((currByte & 0x80) == 0x00))
    numBytes = 1;
  if ((numBytes == 0) && ((currByte & 0xe0) == 0xc0))
    numBytes = 2;
  if ((numBytes == 0) && ((currByte & 0xf0) == 0xe0))
    numBytes = 3;
  if ((numBytes == 0) && ((currByte & 0xf8) == 0xf0))
    numBytes = 4;
  if (numBytes == 0)
    return -8;
  for (i = 0; i < numBytes; i++) {
    currByte = *(p + i);
    if (i == 0) {
      switch (numBytes) {
      case 1:
        decoded = (0x7f & currByte);
        break;
      case 2:
        decoded = (0x1f & currByte);
        break;
      case 3:
        decoded = (0x0f & currByte);
        break;
      case 4:
        decoded = (0x07 & currByte);
        break;
      default:
        return -1024;
      };
    } else {
      if ((currByte & 0xc0) != 0x80)
        return -8;
      if (debug_utf8_decode == 1)
        printf("\t%08x\n", decoded);
      decoded <<= 6;
      if (debug_utf8_decode == 1)
        printf("\t%08x\n", decoded);
      decoded |= (currByte & 0x3f);
      if (debug_utf8_decode == 1)
        printf("\t%08x\n", decoded);
    }
    if (debug_utf8_decode == 1)
      printf("%08x\n", decoded);
  }
  if (decoded > 0x10ffff)
    return -16;
  if (0xd800 <= decoded && decoded <= 0xdfff)
    return -16;
  *result = decoded;
  return numBytes;
}


x86 assembly (clang, -O0):
<unicoder_utf8_decode>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x2c(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1138 <unicoder_utf8_decode+0x38>
movl   $0xffffffff,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
cmpq   $0x0,-0x18(%rbp)
jne    114f <unicoder_utf8_decode+0x4f>
movl   $0xffffffff,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
mov    -0x18(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x25(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    117b <unicoder_utf8_decode+0x7b>
movzbl -0x25(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
jne    117b <unicoder_utf8_decode+0x7b>
movl   $0x1,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    11a0 <unicoder_utf8_decode+0xa0>
movzbl -0x25(%rbp),%eax
and    $0xe0,%eax
cmp    $0xc0,%eax
jne    11a0 <unicoder_utf8_decode+0xa0>
movl   $0x2,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    11c5 <unicoder_utf8_decode+0xc5>
movzbl -0x25(%rbp),%eax
and    $0xf0,%eax
cmp    $0xe0,%eax
jne    11c5 <unicoder_utf8_decode+0xc5>
movl   $0x3,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    11ea <unicoder_utf8_decode+0xea>
movzbl -0x25(%rbp),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    11ea <unicoder_utf8_decode+0xea>
movl   $0x4,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    1200 <unicoder_utf8_decode+0x100>
movl   $0xfffffff8,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    12ea <unicoder_utf8_decode+0x1ea>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x25(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jne    12a1 <unicoder_utf8_decode+0x1a1>
mov    -0x20(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x38(%rbp)
sub    $0x3,%eax
ja     1290 <unicoder_utf8_decode+0x190>
mov    -0x38(%rbp),%rax
lea    0xdb5(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movzbl -0x25(%rbp),%eax
and    $0x7f,%eax
mov    %eax,-0x24(%rbp)
jmp    129c <unicoder_utf8_decode+0x19c>
movzbl -0x25(%rbp),%eax
and    $0x1f,%eax
mov    %eax,-0x24(%rbp)
jmp    129c <unicoder_utf8_decode+0x19c>
movzbl -0x25(%rbp),%eax
and    $0xf,%eax
mov    %eax,-0x24(%rbp)
jmp    129c <unicoder_utf8_decode+0x19c>
movzbl -0x25(%rbp),%eax
and    $0x7,%eax
mov    %eax,-0x24(%rbp)
jmp    129c <unicoder_utf8_decode+0x19c>
movl   $0xfffffc00,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
jmp    12d7 <unicoder_utf8_decode+0x1d7>
movzbl -0x25(%rbp),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     12c1 <unicoder_utf8_decode+0x1c1>
movl   $0xfffffff8,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
mov    -0x24(%rbp),%eax
shl    $0x6,%eax
mov    %eax,-0x24(%rbp)
movzbl -0x25(%rbp),%eax
and    $0x3f,%eax
or     -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    12dc <unicoder_utf8_decode+0x1dc>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1207 <unicoder_utf8_decode+0x107>
cmpl   $0x10ffff,-0x24(%rbp)
jbe    1303 <unicoder_utf8_decode+0x203>
movl   $0xfffffff0,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
mov    $0xd800,%eax
cmp    -0x24(%rbp),%eax
ja     132a <unicoder_utf8_decode+0x22a>
cmpl   $0xdfff,-0x24(%rbp)
ja     132a <unicoder_utf8_decode+0x22a>
movl   $0xfffffff0,-0x4(%rbp)
jmp    1339 <unicoder_utf8_decode+0x239>
mov    -0x24(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unicoder_utf8_decode>:
push   %rbx
mov    $0xffffffff,%eax
test   %rdi,%rdi
je     1207 <unicoder_utf8_decode+0x107>
test   %rsi,%rsi
je     1207 <unicoder_utf8_decode+0x107>
mov    (%rsi),%al
mov    $0x1,%r8d
test   %al,%al
jns    1169 <unicoder_utf8_decode+0x69>
mov    %eax,%ecx
and    $0xe0,%cl
mov    %eax,%edx
and    $0xf0,%dl
xor    %r8d,%r8d
cmp    $0xe0,%dl
sete   %r8b
cmp    $0xc0,%cl
lea    (%r8,%r8,2),%ecx
mov    $0x2,%edx
cmovne %ecx,%edx
mov    %eax,%ecx
and    $0xf8,%cl
xor    %r8d,%r8d
cmp    $0xf0,%cl
sete   %r8b
shl    $0x2,%r8d
test   %edx,%edx
cmovne %edx,%r8d
test   %r8d,%r8d
je     1209 <unicoder_utf8_decode+0x109>
mov    %r8d,%r11d
add    $0xffffffffffffffff,%r11
xor    %ecx,%ecx
lea    -0x1(%r8),%r9d
lea    0xe83(%rip),%r10
xor    %edx,%edx
test   %rcx,%rcx
je     11ba <unicoder_utf8_decode+0xba>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl %al,%eax
mov    %eax,%ebx
and    $0xffffffc0,%ebx
cmp    $0x80,%ebx
jne    1209 <unicoder_utf8_decode+0x109>
shl    $0x6,%edx
and    $0x3f,%eax
or     %eax,%edx
cmp    %rcx,%r11
je     11e5 <unicoder_utf8_decode+0xe5>
mov    0x1(%rsi,%rcx,1),%al
add    $0x1,%rcx
test   %rcx,%rcx
jne    1190 <unicoder_utf8_decode+0x90>
cmp    $0x3,%r9d
ja     1210 <unicoder_utf8_decode+0x110>
movslq (%r10,%r9,4),%rdx
add    %r10,%rdx
jmp    *%rdx
and    $0x7f,%al
movzbl %al,%edx
jmp    11a8 <unicoder_utf8_decode+0xa8>
and    $0x1f,%al
movzbl %al,%edx
jmp    11a8 <unicoder_utf8_decode+0xa8>
and    $0xf,%al
movzbl %al,%edx
jmp    11a8 <unicoder_utf8_decode+0xa8>
and    $0x7,%al
movzbl %al,%edx
jmp    11a8 <unicoder_utf8_decode+0xa8>
mov    $0xfffffff0,%eax
cmp    $0x10ffff,%edx
ja     1207 <unicoder_utf8_decode+0x107>
mov    %edx,%ecx
and    $0xfffff800,%ecx
cmp    $0xd800,%ecx
je     1207 <unicoder_utf8_decode+0x107>
mov    %edx,(%rdi)
mov    %r8d,%eax
pop    %rbx
ret
mov    $0xfffffff8,%eax
pop    %rbx
ret
mov    $0xfffffc00,%eax
pop    %rbx
ret

LLVM IR (-O0):
define i32 @unicoder_utf8_decode(i32* %0, i8* %1) {
%3 = alloca i32
%4 = alloca i32*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8
%10 = alloca i32
store i32* %0, i32** %4
store i8* %1, i8** %5
store i32 0, i32* %7
store i32 0, i32* %8
store i32 0, i32* %10
%11 = load i32*, i32** %4
%12 = icmp eq i32* %11, null
br i1 %12, label %13, label %14
13: ; preds = %2
store i32 -1, i32* %3
br label %126
14: ; preds = %2
%15 = load i8*, i8** %5
%16 = icmp eq i8* %15, null
br i1 %16, label %17, label %18
17: ; preds = %14
store i32 -1, i32* %3
br label %126
18: ; preds = %14
%19 = load i8*, i8** %5
%20 = load i8, i8* %19
store i8 %20, i8* %9
%21 = load i32, i32* %7
%22 = icmp eq i32 %21, 0
br i1 %22, label %23, label %29
23: ; preds = %18
%24 = load i8, i8* %9
%25 = zext i8 %24 to i32
%26 = and i32 %25, 128
%27 = icmp eq i32 %26, 0
br i1 %27, label %28, label %29
28: ; preds = %23
store i32 1, i32* %7
br label %29
29: ; preds = %28, %23, %18
%30 = load i32, i32* %7
%31 = icmp eq i32 %30, 0
br i1 %31, label %32, label %38
32: ; preds = %29
%33 = load i8, i8* %9
%34 = zext i8 %33 to i32
%35 = and i32 %34, 224
%36 = icmp eq i32 %35, 192
br i1 %36, label %37, label %38
37: ; preds = %32
store i32 2, i32* %7
br label %38
38: ; preds = %37, %32, %29
%39 = load i32, i32* %7
%40 = icmp eq i32 %39, 0
br i1 %40, label %41, label %47
41: ; preds = %38
%42 = load i8, i8* %9
%43 = zext i8 %42 to i32
%44 = and i32 %43, 240
%45 = icmp eq i32 %44, 224
br i1 %45, label %46, label %47
46: ; preds = %41
store i32 3, i32* %7
br label %47
47: ; preds = %46, %41, %38
%48 = load i32, i32* %7
%49 = icmp eq i32 %48, 0
br i1 %49, label %50, label %56
50: ; preds = %47
%51 = load i8, i8* %9
%52 = zext i8 %51 to i32
%53 = and i32 %52, 248
%54 = icmp eq i32 %53, 240
br i1 %54, label %55, label %56
55: ; preds = %50
store i32 4, i32* %7
br label %56
56: ; preds = %55, %50, %47
%57 = load i32, i32* %7
%58 = icmp eq i32 %57, 0
br i1 %58, label %59, label %60
59: ; preds = %56
store i32 -8, i32* %3
br label %126
60: ; preds = %56
store i32 0, i32* %6
br label %61
61: ; preds = %108, %60
%62 = load i32, i32* %6
%63 = load i32, i32* %7
%64 = icmp slt i32 %62, %63
br i1 %64, label %65, label %111
65: ; preds = %61
%66 = load i8*, i8** %5
%67 = load i32, i32* %6
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds i8, i8* %66, i64 %68
%70 = load i8, i8* %69
store i8 %70, i8* %9
%71 = load i32, i32* %6
%72 = icmp eq i32 %71, 0
br i1 %72, label %73, label %93
73: ; preds = %65
%74 = load i32, i32* %7
switch i32 %74, label %91 [
i32 1, label %75
i32 2, label %79
i32 3, label %83
i32 4, label %87
]
75: ; preds = %73
%76 = load i8, i8* %9
%77 = zext i8 %76 to i32
%78 = and i32 127, %77
store i32 %78, i32* %8
br label %92
79: ; preds = %73
%80 = load i8, i8* %9
%81 = zext i8 %80 to i32
%82 = and i32 31, %81
store i32 %82, i32* %8
br label %92
83: ; preds = %73
%84 = load i8, i8* %9
%85 = zext i8 %84 to i32
%86 = and i32 15, %85
store i32 %86, i32* %8
br label %92
87: ; preds = %73
%88 = load i8, i8* %9
%89 = zext i8 %88 to i32
%90 = and i32 7, %89
store i32 %90, i32* %8
br label %92
91: ; preds = %73
store i32 -1024, i32* %3
br label %126
92: ; preds = %87, %83, %79, %75
br label %107
93: ; preds = %65
%94 = load i8, i8* %9
%95 = zext i8 %94 to i32
%96 = and i32 %95, 192
%97 = icmp ne i32 %96, 128
br i1 %97, label %98, label %99
98: ; preds = %93
store i32 -8, i32* %3
br label %126
99: ; preds = %93
%100 = load i32, i32* %8
%101 = shl i32 %100, 6
store i32 %101, i32* %8
%102 = load i8, i8* %9
%103 = zext i8 %102 to i32
%104 = and i32 %103, 63
%105 = load i32, i32* %8
%106 = or i32 %105, %104
store i32 %106, i32* %8
br label %107
107: ; preds = %99, %92
br label %108
108: ; preds = %107
%109 = load i32, i32* %6
%110 = add nsw i32 %109, 1
store i32 %110, i32* %6
br label %61
111: ; preds = %61
%112 = load i32, i32* %8
%113 = icmp ugt i32 %112, 1114111
br i1 %113, label %114, label %115
114: ; preds = %111
store i32 -16, i32* %3
br label %126
115: ; preds = %111
%116 = load i32, i32* %8
%117 = icmp ule i32 55296, %116
br i1 %117, label %118, label %122
118: ; preds = %115
%119 = load i32, i32* %8
%120 = icmp ule i32 %119, 57343
br i1 %120, label %121, label %122
121: ; preds = %118
store i32 -16, i32* %3
br label %126
122: ; preds = %118, %115
%123 = load i32, i32* %8
%124 = load i32*, i32** %4
store i32 %123, i32* %124
%125 = load i32, i32* %7
store i32 %125, i32* %3
br label %126
126: ; preds = %122, %121, %114, %98, %91, %59, %17, %13
%127 = load i32, i32* %3
ret i32 %127
}

LLVM IR (-O2):
define i32 @unicoder_utf8_decode(i32* writeonly %0, i8* %1) {
%3 = icmp eq i32* %0, null
%4 = icmp eq i8* %1, null
%5 = or i1 %3, %4
br i1 %5, label %64, label %6
6: ; preds = %2
%7 = load i8, i8* %1
%8 = icmp sgt i8 %7, -1
br i1 %8, label %22, label %9
9: ; preds = %6
%10 = and i8 %7, -32
%11 = icmp eq i8 %10, -64
%12 = and i8 %7, -16
%13 = icmp eq i8 %12, -32
%14 = select i1 %13, i32 3, i32 0
%15 = select i1 %11, i32 2, i32 %14
%16 = icmp eq i32 %15, 0
%17 = and i8 %7, -8
%18 = icmp eq i8 %17, -16
%19 = select i1 %18, i32 4, i32 0
%20 = select i1 %16, i32 %19, i32 %15
%21 = icmp eq i32 %20, 0
br i1 %21, label %64, label %22
22: ; preds = %6, %9
%23 = phi i32 [ %20, %9 ], [ 1, %6 ]
%24 = zext i32 %23 to i64
br label %25
25: ; preds = %55, %22
%26 = phi i8 [ %7, %22 ], [ %57, %55 ]
%27 = phi i64 [ 0, %22 ], [ %53, %55 ]
%28 = phi i32 [ 0, %22 ], [ %52, %55 ]
%29 = icmp eq i64 %27, 0
br i1 %29, label %30, label %43
30: ; preds = %25
switch i32 %23, label %64 [
i32 1, label %31
i32 2, label %34
i32 3, label %37
i32 4, label %40
]
31: ; preds = %30
%32 = and i8 %26, 127
%33 = zext i8 %32 to i32
br label %51
34: ; preds = %30
%35 = and i8 %26, 31
%36 = zext i8 %35 to i32
br label %51
37: ; preds = %30
%38 = and i8 %26, 15
%39 = zext i8 %38 to i32
br label %51
40: ; preds = %30
%41 = and i8 %26, 7
%42 = zext i8 %41 to i32
br label %51
43: ; preds = %25
%44 = zext i8 %26 to i32
%45 = and i32 %44, 192
%46 = icmp eq i32 %45, 128
br i1 %46, label %47, label %64
47: ; preds = %43
%48 = shl i32 %28, 6
%49 = and i32 %44, 63
%50 = or i32 %49, %48
br label %51
51: ; preds = %47, %40, %37, %34, %31
%52 = phi i32 [ %42, %40 ], [ %39, %37 ], [ %36, %34 ], [ %33, %31 ], [ %50, %47 ]
%53 = add nuw nsw i64 %27, 1
%54 = icmp eq i64 %53, %24
br i1 %54, label %58, label %55
55: ; preds = %51
%56 = getelementptr inbounds i8, i8* %1, i64 %53
%57 = load i8, i8* %56
br label %25
58: ; preds = %51
%59 = icmp ugt i32 %52, 1114111
%60 = and i32 %52, -2048
%61 = icmp eq i32 %60, 55296
%62 = or i1 %59, %61
br i1 %62, label %64, label %63
63: ; preds = %58
store i32 %52, i32* %0
br label %64
64: ; preds = %43, %30, %58, %9, %2, %63
%65 = phi i32 [ %23, %63 ], [ -1, %2 ], [ -8, %9 ], [ -16, %58 ], [ -8, %43 ], [ -1024, %30 ]
ret i32 %65
}