#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 int /*<<< orphan*/ FILE;

/* Variables and functions */
char EOF;
char getc(int /*<<< orphan*/ *);
int /*<<< orphan*/ memset(char *, int /*<<< orphan*/, int);
unsigned short u_getc(FILE *stream, char *bytes) {
  static unsigned short mask[] = {192, 224, 240};
  unsigned short i, j;
  memset(bytes, 0, 4 + 1);
  bytes[0] = getc(stream);
  if (bytes[0] == EOF) {
    return 0;
  }
  i = 0;
  if ((bytes[0] & mask[0]) == mask[0])
    i++;
  if ((bytes[0] & mask[1]) == mask[1])
    i++;
  if ((bytes[0] & mask[2]) == mask[2])
    i++;
  j = 0;
  while (j < i) {
    j++;
    bytes[j] = getc(stream);
  }
  return i + 1;
}


x86 assembly (clang, -O0):
<u_getc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
xor    %esi,%esi
mov    $0x5,%edx
call   1030 <memset@plt>
mov    -0x10(%rbp),%rdi
call   1040 <getc@plt>
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %cl,(%rax)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
mov    0x2e89(%rip),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
jne    1175 <u_getc+0x55>
movw   $0x0,-0x2(%rbp)
jmp    1244 <u_getc+0x124>
movw   $0x0,-0x1a(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
movzwl 0x2ea7(%rip),%ecx
and    %ecx,%eax
movzwl 0x2e9e(%rip),%ecx
cmp    %ecx,%eax
jne    11a6 <u_getc+0x86>
mov    -0x1a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x1a(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
movzwl 0x2e7e(%rip),%ecx
and    %ecx,%eax
movzwl 0x2e75(%rip),%ecx
cmp    %ecx,%eax
jne    11d1 <u_getc+0xb1>
mov    -0x1a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x1a(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
movzwl 0x2e55(%rip),%ecx
and    %ecx,%eax
movzwl 0x2e4c(%rip),%ecx
cmp    %ecx,%eax
jne    11fc <u_getc+0xdc>
mov    -0x1a(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x1a(%rbp)
movw   $0x0,-0x1c(%rbp)
movzwl -0x1c(%rbp),%eax
movzwl -0x1a(%rbp),%ecx
cmp    %ecx,%eax
jge    1239 <u_getc+0x119>
mov    -0x1c(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x1c(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <getc@plt>
mov    %al,%dl
mov    -0x18(%rbp),%rax
movzwl -0x1c(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
jmp    1202 <u_getc+0xe2>
movzwl -0x1a(%rbp),%eax
add    $0x1,%eax
mov    %ax,-0x2(%rbp)
movzwl -0x2(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<u_getc>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r12
mov    %rdi,%r14
xor    %r15d,%r15d
mov    %rsi,%rdi
xor    %esi,%esi
mov    $0x5,%edx
call   1030 <memset@plt>
mov    %r14,%rdi
call   1040 <getc@plt>
mov    %al,(%r12)
mov    0x2e92(%rip),%rcx
cmp    (%rcx),%al
je     119d <u_getc+0x7d>
xor    %ecx,%ecx
cmp    $0xc0,%al
setae  %cl
lea    0x1(%rcx),%edx
cmp    $0xe0,%al
cmovb  %ecx,%edx
xor    %r15d,%r15d
cmp    $0xf0,%al
setae  %r15b
add    %dx,%r15w
je     1199 <u_getc+0x79>
movzwl %r15w,%r13d
xor    %ebx,%ebx
xchg   %ax,%ax
lea    0x1(%rbx),%rbp
mov    %r14,%rdi
call   1040 <getc@plt>
mov    %al,0x1(%r12,%rbx,1)
mov    %rbp,%rbx
cmp    %rbp,%r13
jne    1180 <u_getc+0x60>
add    $0x1,%r15d
mov    %r15d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@u_getc.mask = internal global [3 x i16] [i16 192, i16 224, i16 240]
@EOF = global i8 0
define zeroext i16 @u_getc(i32* %0, i8* %1) {
%3 = alloca i16
%4 = alloca i32*
%5 = alloca i8*
%6 = alloca i16
%7 = alloca i16
store i32* %0, i32** %4
store i8* %1, i8** %5
%8 = load i8*, i8** %5
%9 = call i32 @memset(i8* %8, i32 0, i32 5)
%10 = load i32*, i32** %4
%11 = call signext i8 @getc(i32* %10)
%12 = load i8*, i8** %5
%13 = getelementptr inbounds i8, i8* %12, i64 0
store i8 %11, i8* %13
%14 = load i8*, i8** %5
%15 = getelementptr inbounds i8, i8* %14, i64 0
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = load i8, i8* @EOF
%19 = sext i8 %18 to i32
%20 = icmp eq i32 %17, %19
br i1 %20, label %21, label %22
21: ; preds = %2
store i16 0, i16* %3
br label %85
22: ; preds = %2
store i16 0, i16* %6
%23 = load i8*, i8** %5
%24 = getelementptr inbounds i8, i8* %23, i64 0
%25 = load i8, i8* %24
%26 = sext i8 %25 to i32
%27 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 0)
%28 = zext i16 %27 to i32
%29 = and i32 %26, %28
%30 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 0)
%31 = zext i16 %30 to i32
%32 = icmp eq i32 %29, %31
br i1 %32, label %33, label %36
33: ; preds = %22
%34 = load i16, i16* %6
%35 = add i16 %34, 1
store i16 %35, i16* %6
br label %36
36: ; preds = %33, %22
%37 = load i8*, i8** %5
%38 = getelementptr inbounds i8, i8* %37, i64 0
%39 = load i8, i8* %38
%40 = sext i8 %39 to i32
%41 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 1)
%42 = zext i16 %41 to i32
%43 = and i32 %40, %42
%44 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 1)
%45 = zext i16 %44 to i32
%46 = icmp eq i32 %43, %45
br i1 %46, label %47, label %50
47: ; preds = %36
%48 = load i16, i16* %6
%49 = add i16 %48, 1
store i16 %49, i16* %6
br label %50
50: ; preds = %47, %36
%51 = load i8*, i8** %5
%52 = getelementptr inbounds i8, i8* %51, i64 0
%53 = load i8, i8* %52
%54 = sext i8 %53 to i32
%55 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 2)
%56 = zext i16 %55 to i32
%57 = and i32 %54, %56
%58 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @u_getc.mask, i64 0, i64 2)
%59 = zext i16 %58 to i32
%60 = icmp eq i32 %57, %59
br i1 %60, label %61, label %64
61: ; preds = %50
%62 = load i16, i16* %6
%63 = add i16 %62, 1
store i16 %63, i16* %6
br label %64
64: ; preds = %61, %50
store i16 0, i16* %7
br label %65
65: ; preds = %71, %64
%66 = load i16, i16* %7
%67 = zext i16 %66 to i32
%68 = load i16, i16* %6
%69 = zext i16 %68 to i32
%70 = icmp slt i32 %67, %69
br i1 %70, label %71, label %80
71: ; preds = %65
%72 = load i16, i16* %7
%73 = add i16 %72, 1
store i16 %73, i16* %7
%74 = load i32*, i32** %4
%75 = call signext i8 @getc(i32* %74)
%76 = load i8*, i8** %5
%77 = load i16, i16* %7
%78 = zext i16 %77 to i64
%79 = getelementptr inbounds i8, i8* %76, i64 %78
store i8 %75, i8* %79
br label %65
80: ; preds = %65
%81 = load i16, i16* %6
%82 = zext i16 %81 to i32
%83 = add nsw i32 %82, 1
%84 = trunc i32 %83 to i16
store i16 %84, i16* %3
br label %85
85: ; preds = %80, %21
%86 = load i16, i16* %3
ret i16 %86
}

LLVM IR (-O2):
@EOF = global i8 0
define zeroext i16 @u_getc(i32* nocapture %0, i8* %1) {
%3 = tail call i32 @memset(i8* %1, i32 0, i32 5)
%4 = tail call signext i8 @getc(i32* %0)
store i8 %4, i8* %1
%5 = load i8, i8* @EOF
%6 = icmp eq i8 %4, %5
br i1 %6, label %27, label %7
7: ; preds = %2
%8 = icmp ugt i8 %4, -65
%9 = zext i1 %8 to i16
%10 = icmp ugt i8 %4, -33
%11 = select i1 %8, i16 2, i16 1
%12 = select i1 %10, i16 %11, i16 %9
%13 = icmp ugt i8 %4, -17
%14 = zext i1 %13 to i16
%15 = add nuw nsw i16 %12, %14
%16 = icmp eq i16 %15, 0
br i1 %16, label %25, label %17
17: ; preds = %7
%18 = zext i16 %15 to i64
br label %19
19: ; preds = %17, %19
%20 = phi i64 [ 0, %17 ], [ %21, %19 ]
%21 = add nuw nsw i64 %20, 1
%22 = tail call signext i8 @getc(i32* %0)
%23 = getelementptr inbounds i8, i8* %1, i64 %21
store i8 %22, i8* %23
%24 = icmp eq i64 %21, %18
br i1 %24, label %25, label %19
25: ; preds = %19, %7
%26 = add nuw nsw i16 %15, 1
br label %27
27: ; preds = %2, %25
%28 = phi i16 [ %26, %25 ], [ 0, %2 ]
ret i16 %28
}