#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 */
typedef char wchar_t;

/* Variables and functions */
int Utf8ToWide(wchar_t *dest, const char *src, int destLen) {
  int di, si, si2, si3;
  int conv;
  conv = 0;
  di = 0;
  si = 0;
  destLen--;
  while ((src[si] != '\0') && (di < destLen)) {
    si2 = si + 1;
    si3 = si2 + 1;
    if ((unsigned char)src[si] <= 0x7F) {
      dest[di++] = src[si++];
      conv++;
    } else if ((unsigned char)src[si] <= 0xDF) {
      dest[di++] = ((src[si] & 0x1F) << 6) | (src[si2] & 0x3F);
      conv++;
      si += 2;
    } else if ((unsigned char)src[si] <= 0xEF) {
      dest[di++] = ((src[si] & 0x0F) << 12) | ((src[si2] & 0x3F) << 6) |
                   (src[si3] & 0x3F);
      conv++;
      si += 3;
    } else if ((unsigned char)src[si] <= 0xF7) {
      si += 4;
    }
  }
  dest[di] = '\0';
  return conv;
}


x86 assembly (clang, -O0):
<Utf8ToWide>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x28(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x29(%rbp)
je     1153 <Utf8ToWide+0x53>
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
setl   %al
mov    %al,-0x29(%rbp)
mov    -0x29(%rbp),%al
test   $0x1,%al
jne    1163 <Utf8ToWide+0x63>
jmp    12da <Utf8ToWide+0x1da>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x7f,%eax
jg     11c2 <Utf8ToWide+0xc2>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x1c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    12d5 <Utf8ToWide+0x1d5>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xdf,%eax
jg     122a <Utf8ToWide+0x12a>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0x1f,%eax
shl    $0x6,%eax
mov    -0x10(%rbp),%rcx
movslq -0x20(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x1c(%rbp)
jmp    12d0 <Utf8ToWide+0x1d0>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xef,%eax
jg     12a6 <Utf8ToWide+0x1a6>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf,%eax
shl    $0xc,%eax
mov    -0x10(%rbp),%rcx
movslq -0x20(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x1c(%rbp)
jmp    12cb <Utf8ToWide+0x1cb>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xf7,%eax
jg     12c6 <Utf8ToWide+0x1c6>
mov    -0x1c(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x1c(%rbp)
jmp    12cb <Utf8ToWide+0x1cb>
jmp    12d0 <Utf8ToWide+0x1d0>
jmp    12d5 <Utf8ToWide+0x1d5>
jmp    112d <Utf8ToWide+0x2d>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x28(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<Utf8ToWide>:
mov    (%rsi),%cl
xor    %r8d,%r8d
test   %cl,%cl
je     11d6 <Utf8ToWide+0xd6>
mov    $0x0,%eax
cmp    $0x2,%edx
jl     11d8 <Utf8ToWide+0xd8>
add    $0xffffffff,%edx
xor    %eax,%eax
xor    %r8d,%r8d
xor    %r9d,%r9d
cs nopw 0x0(%rax,%rax,1)
movslq %r9d,%r10
lea    0x1(%r10),%r11
test   %cl,%cl
js     1150 <Utf8ToWide+0x50>
movslq %r8d,%r9
add    $0x1,%r8d
mov    %cl,(%rdi,%r9,1)
add    $0x1,%eax
mov    %r11d,%r9d
jmp    11c0 <Utf8ToWide+0xc0>
xchg   %ax,%ax
add    $0x2,%r10
cmp    $0xdf,%cl
ja     117b <Utf8ToWide+0x7b>
shl    $0x6,%cl
movzbl (%rsi,%r11,1),%r9d
and    $0x3f,%r9b
or     %cl,%r9b
movslq %r8d,%rcx
add    $0x1,%r8d
mov    %r9b,(%rdi,%rcx,1)
add    $0x1,%eax
mov    %r10d,%r9d
jmp    11c0 <Utf8ToWide+0xc0>
cmp    $0xef,%cl
ja     11a8 <Utf8ToWide+0xa8>
movzbl (%rsi,%r11,1),%r11d
shl    $0x6,%r11b
movzbl (%rsi,%r10,1),%ecx
and    $0x3f,%cl
or     %r11b,%cl
movslq %r8d,%r10
add    $0x1,%r8d
mov    %cl,(%rdi,%r10,1)
add    $0x1,%eax
add    $0x3,%r9d
jmp    11c0 <Utf8ToWide+0xc0>
cmp    $0xf8,%cl
jae    11c0 <Utf8ToWide+0xc0>
add    $0x4,%r9d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movslq %r9d,%rcx
movzbl (%rsi,%rcx,1),%ecx
test   %cl,%cl
je     11d8 <Utf8ToWide+0xd8>
cmp    %edx,%r8d
jl     1130 <Utf8ToWide+0x30>
jmp    11d8 <Utf8ToWide+0xd8>
xor    %eax,%eax
movslq %r8d,%rcx
movb   $0x0,(%rdi,%rcx,1)
ret

LLVM IR (-O0):
define i32 @Utf8ToWide(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
store i32 0, i32* %11
store i32 0, i32* %7
store i32 0, i32* %8
%12 = load i32, i32* %6
%13 = add nsw i32 %12, -1
store i32 %13, i32* %6
br label %14
14: ; preds = %147, %3
%15 = load i8*, i8** %5
%16 = load i32, i32* %8
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = icmp ne i32 %20, 0
br i1 %21, label %22, label %26
22: ; preds = %14
%23 = load i32, i32* %7
%24 = load i32, i32* %6
%25 = icmp slt i32 %23, %24
br label %26
26: ; preds = %22, %14
%27 = phi i1 [ false, %14 ], [ %25, %22 ]
br i1 %27, label %28, label %148
28: ; preds = %26
%29 = load i32, i32* %8
%30 = add nsw i32 %29, 1
store i32 %30, i32* %9
%31 = load i32, i32* %9
%32 = add nsw i32 %31, 1
store i32 %32, i32* %10
%33 = load i8*, i8** %5
%34 = load i32, i32* %8
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %33, i64 %35
%37 = load i8, i8* %36
%38 = zext i8 %37 to i32
%39 = icmp sle i32 %38, 127
br i1 %39, label %40, label %54
40: ; preds = %28
%41 = load i8*, i8** %5
%42 = load i32, i32* %8
%43 = add nsw i32 %42, 1
store i32 %43, i32* %8
%44 = sext i32 %42 to i64
%45 = getelementptr inbounds i8, i8* %41, i64 %44
%46 = load i8, i8* %45
%47 = load i8*, i8** %4
%48 = load i32, i32* %7
%49 = add nsw i32 %48, 1
store i32 %49, i32* %7
%50 = sext i32 %48 to i64
%51 = getelementptr inbounds i8, i8* %47, i64 %50
store i8 %46, i8* %51
%52 = load i32, i32* %11
%53 = add nsw i32 %52, 1
store i32 %53, i32* %11
br label %147
54: ; preds = %28
%55 = load i8*, i8** %5
%56 = load i32, i32* %8
%57 = sext i32 %56 to i64
%58 = getelementptr inbounds i8, i8* %55, i64 %57
%59 = load i8, i8* %58
%60 = zext i8 %59 to i32
%61 = icmp sle i32 %60, 223
br i1 %61, label %62, label %89
62: ; preds = %54
%63 = load i8*, i8** %5
%64 = load i32, i32* %8
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds i8, i8* %63, i64 %65
%67 = load i8, i8* %66
%68 = sext i8 %67 to i32
%69 = and i32 %68, 31
%70 = shl i32 %69, 6
%71 = load i8*, i8** %5
%72 = load i32, i32* %9
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds i8, i8* %71, i64 %73
%75 = load i8, i8* %74
%76 = sext i8 %75 to i32
%77 = and i32 %76, 63
%78 = or i32 %70, %77
%79 = trunc i32 %78 to i8
%80 = load i8*, i8** %4
%81 = load i32, i32* %7
%82 = add nsw i32 %81, 1
store i32 %82, i32* %7
%83 = sext i32 %81 to i64
%84 = getelementptr inbounds i8, i8* %80, i64 %83
store i8 %79, i8* %84
%85 = load i32, i32* %11
%86 = add nsw i32 %85, 1
store i32 %86, i32* %11
%87 = load i32, i32* %8
%88 = add nsw i32 %87, 2
store i32 %88, i32* %8
br label %146
89: ; preds = %54
%90 = load i8*, i8** %5
%91 = load i32, i32* %8
%92 = sext i32 %91 to i64
%93 = getelementptr inbounds i8, i8* %90, i64 %92
%94 = load i8, i8* %93
%95 = zext i8 %94 to i32
%96 = icmp sle i32 %95, 239
br i1 %96, label %97, label %133
97: ; preds = %89
%98 = load i8*, i8** %5
%99 = load i32, i32* %8
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds i8, i8* %98, i64 %100
%102 = load i8, i8* %101
%103 = sext i8 %102 to i32
%104 = and i32 %103, 15
%105 = shl i32 %104, 12
%106 = load i8*, i8** %5
%107 = load i32, i32* %9
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds i8, i8* %106, i64 %108
%110 = load i8, i8* %109
%111 = sext i8 %110 to i32
%112 = and i32 %111, 63
%113 = shl i32 %112, 6
%114 = or i32 %105, %113
%115 = load i8*, i8** %5
%116 = load i32, i32* %10
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds i8, i8* %115, i64 %117
%119 = load i8, i8* %118
%120 = sext i8 %119 to i32
%121 = and i32 %120, 63
%122 = or i32 %114, %121
%123 = trunc i32 %122 to i8
%124 = load i8*, i8** %4
%125 = load i32, i32* %7
%126 = add nsw i32 %125, 1
store i32 %126, i32* %7
%127 = sext i32 %125 to i64
%128 = getelementptr inbounds i8, i8* %124, i64 %127
store i8 %123, i8* %128
%129 = load i32, i32* %11
%130 = add nsw i32 %129, 1
store i32 %130, i32* %11
%131 = load i32, i32* %8
%132 = add nsw i32 %131, 3
store i32 %132, i32* %8
br label %145
133: ; preds = %89
%134 = load i8*, i8** %5
%135 = load i32, i32* %8
%136 = sext i32 %135 to i64
%137 = getelementptr inbounds i8, i8* %134, i64 %136
%138 = load i8, i8* %137
%139 = zext i8 %138 to i32
%140 = icmp sle i32 %139, 247
br i1 %140, label %141, label %144
141: ; preds = %133
%142 = load i32, i32* %8
%143 = add nsw i32 %142, 4
store i32 %143, i32* %8
br label %144
144: ; preds = %141, %133
br label %145
145: ; preds = %144, %97
br label %146
146: ; preds = %145, %62
br label %147
147: ; preds = %146, %40
br label %14
148: ; preds = %26
%149 = load i8*, i8** %4
%150 = load i32, i32* %7
%151 = sext i32 %150 to i64
%152 = getelementptr inbounds i8, i8* %149, i64 %151
store i8 0, i8* %152
%153 = load i32, i32* %11
ret i32 %153
}

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