#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 */
struct feed_tty {
  int dummy;
};
struct feed_buf {
  int dummy;
};

/* Variables and functions */
char feed_buf_write_character(struct feed_buf *const, unsigned char);
char feed_tty_read_character(struct feed_tty *const, unsigned char *);
char feed_tty_read_unicode_character(struct feed_tty *const p_tty,
                                     struct feed_buf *const p_buf,
                                     unsigned long int *const p_value) {
  char b_result;
  unsigned char c_data;
  unsigned long int i_value;
  i_value = 0ul;
  b_result = feed_tty_read_character(p_tty, &(c_data));
  if (b_result) {
    b_result = feed_buf_write_character(p_buf, c_data);
    if (b_result) {
      unsigned char i_count;
      if (0x00u == (c_data & 0x80u)) {
        i_value = (c_data & 0x7Fu);
        i_count = 1u;
      } else if (0xC0u == (c_data & 0xE0u)) {
        i_value = (c_data & 0x1Fu);
        i_count = 2u;
      } else if (0xE0u == (c_data & 0xF0u)) {
        i_value = (c_data & 0x0Fu);
        i_count = 3u;
      } else if (0xF0u == (c_data & 0xF8u)) {
        i_value = (c_data & 0x07u);
        i_count = 4u;
      } else if (0xF8u == (c_data & 0xFCu)) {
        i_value = (c_data & 0x03u);
        i_count = 5u;
      } else if (0xFCu == (c_data & 0xFEu)) {
        i_value = (c_data & 0x01u);
        i_count = 6u;
      } else {
        i_value = (c_data);
        i_count = 1u;
      }
      if (b_result) {
        i_count--;
        while (b_result && i_count) {
          b_result = feed_tty_read_character(p_tty, &(c_data));
          if (b_result) {
            b_result = feed_buf_write_character(p_buf, c_data);
            if (b_result) {
              if (0x80u == (c_data & 0xC0u)) {
                i_value = (i_value << 6u) | (c_data & 0x3Fu);
              } else {
                b_result = 0;
              }
              i_count--;
            }
          }
        }
      }
    }
  }
  if (b_result) {
    *(p_value) = i_value;
  }
  return b_result;
}


x86 assembly (clang, -O0):
<feed_tty_read_unicode_character>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x1a(%rbp),%rsi
call   1040 <feed_tty_read_character@plt>
mov    %al,-0x19(%rbp)
cmpb   $0x0,-0x19(%rbp)
je     136e <feed_tty_read_unicode_character+0x24e>
mov    -0x10(%rbp),%rdi
movzbl -0x1a(%rbp),%esi
call   1030 <feed_buf_write_character@plt>
mov    %al,-0x19(%rbp)
cmpb   $0x0,-0x19(%rbp)
je     1369 <feed_tty_read_unicode_character+0x249>
movzbl -0x1a(%rbp),%ecx
and    $0x80,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
jne    119a <feed_tty_read_unicode_character+0x7a>
movzbl -0x1a(%rbp),%eax
and    $0x7f,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x1,-0x29(%rbp)
jmp    12a0 <feed_tty_read_unicode_character+0x180>
movzbl -0x1a(%rbp),%ecx
and    $0xe0,%ecx
mov    $0xc0,%eax
cmp    %ecx,%eax
jne    11c7 <feed_tty_read_unicode_character+0xa7>
movzbl -0x1a(%rbp),%eax
and    $0x1f,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x2,-0x29(%rbp)
jmp    129b <feed_tty_read_unicode_character+0x17b>
movzbl -0x1a(%rbp),%ecx
and    $0xf0,%ecx
mov    $0xe0,%eax
cmp    %ecx,%eax
jne    11f4 <feed_tty_read_unicode_character+0xd4>
movzbl -0x1a(%rbp),%eax
and    $0xf,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x3,-0x29(%rbp)
jmp    1296 <feed_tty_read_unicode_character+0x176>
movzbl -0x1a(%rbp),%ecx
and    $0xf8,%ecx
mov    $0xf0,%eax
cmp    %ecx,%eax
jne    1221 <feed_tty_read_unicode_character+0x101>
movzbl -0x1a(%rbp),%eax
and    $0x7,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x4,-0x29(%rbp)
jmp    1291 <feed_tty_read_unicode_character+0x171>
movzbl -0x1a(%rbp),%ecx
and    $0xfc,%ecx
mov    $0xf8,%eax
cmp    %ecx,%eax
jne    124e <feed_tty_read_unicode_character+0x12e>
movzbl -0x1a(%rbp),%eax
and    $0x3,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x5,-0x29(%rbp)
jmp    128c <feed_tty_read_unicode_character+0x16c>
movzbl -0x1a(%rbp),%ecx
and    $0xfe,%ecx
mov    $0xfc,%eax
cmp    %ecx,%eax
jne    127b <feed_tty_read_unicode_character+0x15b>
movzbl -0x1a(%rbp),%eax
and    $0x1,%eax
mov    %eax,%eax
mov    %rax,-0x28(%rbp)
movb   $0x6,-0x29(%rbp)
jmp    1287 <feed_tty_read_unicode_character+0x167>
movzbl -0x1a(%rbp),%eax
mov    %rax,-0x28(%rbp)
movb   $0x1,-0x29(%rbp)
jmp    128c <feed_tty_read_unicode_character+0x16c>
jmp    1291 <feed_tty_read_unicode_character+0x171>
jmp    1296 <feed_tty_read_unicode_character+0x176>
jmp    129b <feed_tty_read_unicode_character+0x17b>
jmp    12a0 <feed_tty_read_unicode_character+0x180>
cmpb   $0x0,-0x19(%rbp)
je     1364 <feed_tty_read_unicode_character+0x244>
mov    -0x29(%rbp),%al
add    $0xff,%al
mov    %al,-0x29(%rbp)
movsbl -0x19(%rbp),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x2a(%rbp)
je     12d1 <feed_tty_read_unicode_character+0x1b1>
movzbl -0x29(%rbp),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x2a(%rbp)
mov    -0x2a(%rbp),%al
test   $0x1,%al
jne    12e1 <feed_tty_read_unicode_character+0x1c1>
jmp    135f <feed_tty_read_unicode_character+0x23f>
mov    -0x8(%rbp),%rdi
lea    -0x1a(%rbp),%rsi
call   1040 <feed_tty_read_character@plt>
mov    %al,-0x19(%rbp)
cmpb   $0x0,-0x19(%rbp)
je     135a <feed_tty_read_unicode_character+0x23a>
mov    -0x10(%rbp),%rdi
movzbl -0x1a(%rbp),%esi
call   1030 <feed_buf_write_character@plt>
mov    %al,-0x19(%rbp)
cmpb   $0x0,-0x19(%rbp)
je     1355 <feed_tty_read_unicode_character+0x235>
movzbl -0x1a(%rbp),%ecx
and    $0xc0,%ecx
mov    $0x80,%eax
cmp    %ecx,%eax
jne    1349 <feed_tty_read_unicode_character+0x229>
mov    -0x28(%rbp),%rax
shl    $0x6,%rax
movzbl -0x1a(%rbp),%ecx
and    $0x3f,%ecx
mov    %ecx,%ecx
or     %rcx,%rax
mov    %rax,-0x28(%rbp)
jmp    134d <feed_tty_read_unicode_character+0x22d>
movb   $0x0,-0x19(%rbp)
mov    -0x29(%rbp),%al
add    $0xff,%al
mov    %al,-0x29(%rbp)
jmp    135a <feed_tty_read_unicode_character+0x23a>
jmp    12b2 <feed_tty_read_unicode_character+0x192>
jmp    1364 <feed_tty_read_unicode_character+0x244>
jmp    1369 <feed_tty_read_unicode_character+0x249>
jmp    136e <feed_tty_read_unicode_character+0x24e>
cmpb   $0x0,-0x19(%rbp)
je     1383 <feed_tty_read_unicode_character+0x263>
mov    -0x28(%rbp),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
movsbl -0x19(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<feed_tty_read_unicode_character>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%r13
lea    0x7(%rsp),%rsi
call   1040 <feed_tty_read_character@plt>
test   %al,%al
je     1253 <feed_tty_read_unicode_character+0x133>
movzbl 0x7(%rsp),%esi
mov    %r15,%rdi
call   1030 <feed_buf_write_character@plt>
test   %al,%al
je     1253 <feed_tty_read_unicode_character+0x133>
movzbl 0x7(%rsp),%ebp
test   $0x80,%bpl
jne    1171 <feed_tty_read_unicode_character+0x51>
and    $0x7f,%ebp
mov    %rbp,(%r14)
jmp    1255 <feed_tty_read_unicode_character+0x135>
mov    %ebp,%ecx
and    $0xffffffe0,%ecx
cmp    $0xc0,%ecx
jne    1187 <feed_tty_read_unicode_character+0x67>
mov    $0x1,%bl
mov    $0x1f,%eax
jmp    11e1 <feed_tty_read_unicode_character+0xc1>
mov    %ebp,%ecx
and    $0xfffffff0,%ecx
cmp    $0xe0,%ecx
jne    119d <feed_tty_read_unicode_character+0x7d>
mov    $0x2,%bl
mov    $0xf,%eax
jmp    11e1 <feed_tty_read_unicode_character+0xc1>
mov    %ebp,%ecx
and    $0xfffffff8,%ecx
cmp    $0xf0,%ecx
jne    11b3 <feed_tty_read_unicode_character+0x93>
mov    $0x3,%bl
mov    $0x7,%eax
jmp    11e1 <feed_tty_read_unicode_character+0xc1>
mov    %ebp,%ecx
and    $0xfffffffc,%ecx
cmp    $0xf8,%ecx
jne    11c9 <feed_tty_read_unicode_character+0xa9>
mov    $0x4,%bl
mov    $0x3,%eax
jmp    11e1 <feed_tty_read_unicode_character+0xc1>
mov    %ebp,%ecx
and    $0xfffffffe,%ecx
cmp    $0xfc,%ecx
jne    1264 <feed_tty_read_unicode_character+0x144>
mov    $0x5,%bl
mov    $0x1,%eax
and    %eax,%ebp
add    $0xff,%bl
lea    0x7(%rsp),%r12
nopl   0x0(%rax,%rax,1)
mov    %r13,%rdi
mov    %r12,%rsi
call   1040 <feed_tty_read_character@plt>
test   %al,%al
je     1253 <feed_tty_read_unicode_character+0x133>
movzbl 0x7(%rsp),%esi
mov    %r15,%rdi
call   1030 <feed_buf_write_character@plt>
test   %al,%al
je     1253 <feed_tty_read_unicode_character+0x133>
movzbl 0x7(%rsp),%esi
mov    %esi,%ecx
and    $0xffffffc0,%ecx
mov    %rbp,%rdx
shl    $0x6,%rdx
and    $0x3f,%esi
or     %rdx,%rsi
add    $0xff,%bl
setb   %dl
cmp    $0x80,%ecx
cmove  %rsi,%rbp
jne    123d <feed_tty_read_unicode_character+0x11d>
test   %dl,%dl
jne    11f0 <feed_tty_read_unicode_character+0xd0>
xor    %edx,%edx
cmp    $0x80,%ecx
movzbl %al,%eax
cmovne %edx,%eax
test   %al,%al
jne    1169 <feed_tty_read_unicode_character+0x49>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %ebp,%ebp
jmp    1169 <feed_tty_read_unicode_character+0x49>

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

LLVM IR (-O2):
%struct.feed_tty = type { i32 }
%struct.feed_buf = type { i32 }
define signext i8 @feed_tty_read_unicode_character(%struct.feed_tty* %0, %struct.feed_buf* %1, i64* nocapture writeonly %2) {
%4 = alloca i8
%5 = call signext i8 @feed_tty_read_character(%struct.feed_tty* %0, i8* %4)
%6 = icmp eq i8 %5, 0
br i1 %6, label %69, label %7
7: ; preds = %3
%8 = load i8, i8* %4
%9 = call signext i8 @feed_buf_write_character(%struct.feed_buf* %1, i8 zeroext %8)
%10 = icmp eq i8 %9, 0
br i1 %10, label %69, label %11
11: ; preds = %7
%12 = load i8, i8* %4
%13 = zext i8 %12 to i32
%14 = and i32 %13, 128
%15 = icmp eq i32 %14, 0
br i1 %15, label %16, label %19
16: ; preds = %11
%17 = and i32 %13, 127
%18 = zext i32 %17 to i64
br label %66
19: ; preds = %11
%20 = and i32 %13, 224
%21 = icmp eq i32 %20, 192
br i1 %21, label %36, label %22
22: ; preds = %19
%23 = and i32 %13, 240
%24 = icmp eq i32 %23, 224
br i1 %24, label %36, label %25
25: ; preds = %22
%26 = and i32 %13, 248
%27 = icmp eq i32 %26, 240
br i1 %27, label %36, label %28
28: ; preds = %25
%29 = and i32 %13, 252
%30 = icmp eq i32 %29, 248
br i1 %30, label %36, label %31
31: ; preds = %28
%32 = and i32 %13, 254
%33 = icmp eq i32 %32, 252
br i1 %33, label %36, label %34
34: ; preds = %31
%35 = zext i8 %12 to i64
br label %66
36: ; preds = %31, %28, %25, %22, %19
%37 = phi i32 [ 31, %19 ], [ 15, %22 ], [ 7, %25 ], [ 3, %28 ], [ 1, %31 ]
%38 = phi i8 [ 1, %19 ], [ 2, %22 ], [ 3, %25 ], [ 4, %28 ], [ 5, %31 ]
%39 = and i32 %37, %13
%40 = zext i32 %39 to i64
br label %41
41: ; preds = %36, %50
%42 = phi i8 [ %60, %50 ], [ %38, %36 ]
%43 = phi i64 [ %59, %50 ], [ %40, %36 ]
%44 = call signext i8 @feed_tty_read_character(%struct.feed_tty* %0, i8* %4)
%45 = icmp eq i8 %44, 0
br i1 %45, label %69, label %46
46: ; preds = %41
%47 = load i8, i8* %4
%48 = call signext i8 @feed_buf_write_character(%struct.feed_buf* %1, i8 zeroext %47)
%49 = icmp eq i8 %48, 0
br i1 %49, label %69, label %50
50: ; preds = %46
%51 = load i8, i8* %4
%52 = zext i8 %51 to i32
%53 = and i32 %52, 192
%54 = icmp eq i32 %53, 128
%55 = shl i64 %43, 6
%56 = and i32 %52, 63
%57 = zext i32 %56 to i64
%58 = or i64 %55, %57
%59 = select i1 %54, i64 %58, i64 %43
%60 = add i8 %42, -1
%61 = icmp ne i8 %60, 0
%62 = select i1 %54, i1 %61, i1 false
br i1 %62, label %41, label %63
63: ; preds = %50
%64 = select i1 %54, i8 %48, i8 0
%65 = icmp eq i8 %64, 0
br i1 %65, label %69, label %66
66: ; preds = %34, %16, %63
%67 = phi i64 [ %59, %63 ], [ %35, %34 ], [ %18, %16 ]
%68 = phi i8 [ %64, %63 ], [ %9, %34 ], [ %9, %16 ]
store i64 %67, i64* %2
br label %69
69: ; preds = %46, %41, %3, %7, %66, %63
%70 = phi i8 [ %68, %66 ], [ 0, %63 ], [ 0, %7 ], [ 0, %3 ], [ 0, %41 ], [ 0, %46 ]
ret i8 %70
}