#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_buf {
  int dummy;
};

/* Variables and functions */
char feed_buf_write_character(struct feed_buf *const, unsigned char);
char feed_buf_write_character_array(struct feed_buf *const, unsigned char *,
                                    unsigned char *);
char feed_buf_write_unicode_character(struct feed_buf *const p_buf,
                                      unsigned long int const i_code) {
  char b_result;
  unsigned char a_byte[4u];
  if (i_code < 128ul) {
    b_result =
        feed_buf_write_character(p_buf, (unsigned char)(i_code & 0x7Ful));
  } else if (i_code < (1ul << 11ul)) {
    a_byte[0u] = (unsigned char)(0xC0u | ((i_code >> 6u) & 0x1Fu));
    a_byte[1u] = (unsigned char)(0x80u | ((i_code >> 0u) & 0x3Fu));
    b_result = feed_buf_write_character_array(p_buf, a_byte, a_byte + 2u);
  } else if (i_code < (1ul << 16ul)) {
    a_byte[0u] = (unsigned char)(0xC0u | ((i_code >> 12u) & 0x0Fu));
    a_byte[1u] = (unsigned char)(0x80u | ((i_code >> 6u) & 0x3Fu));
    a_byte[2u] = (unsigned char)(0x80u | ((i_code >> 0u) & 0x3Fu));
    b_result = feed_buf_write_character_array(p_buf, a_byte, a_byte + 3u);
  } else if (i_code < (1ul << 21ul)) {
    a_byte[0u] = (unsigned char)(0xC0u | ((i_code >> 18u) & 0x07u));
    a_byte[1u] = (unsigned char)(0x80u | ((i_code >> 12u) & 0x3Fu));
    a_byte[2u] = (unsigned char)(0x80u | ((i_code >> 6u) & 0x3Fu));
    a_byte[3u] = (unsigned char)(0x80u | ((i_code >> 0u) & 0x3Fu));
    b_result = feed_buf_write_character_array(p_buf, a_byte, a_byte + 4u);
  } else {
    b_result = 0;
  }
  return b_result;
}


x86 assembly (clang, -O0):
<feed_buf_write_unicode_character>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
cmpq   $0x80,-0x10(%rbp)
jae    115a <feed_buf_write_unicode_character+0x3a>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rax
and    $0x7f,%rax
movzbl %al,%esi
call   1030 <feed_buf_write_character@plt>
mov    %al,-0x11(%rbp)
jmp    12ab <feed_buf_write_unicode_character+0x18b>
cmpq   $0x800,-0x10(%rbp)
jae    11af <feed_buf_write_unicode_character+0x8f>
mov    -0x10(%rbp),%rax
shr    $0x6,%rax
and    $0x1f,%rax
or     $0xc0,%rax
mov    %al,-0x15(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x0,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x15(%rbp),%rsi
lea    -0x15(%rbp),%rdx
add    $0x2,%rdx
call   1040 <feed_buf_write_character_array@plt>
mov    %al,-0x11(%rbp)
jmp    12a6 <feed_buf_write_unicode_character+0x186>
cmpq   $0x10000,-0x10(%rbp)
jae    1219 <feed_buf_write_unicode_character+0xf9>
mov    -0x10(%rbp),%rax
shr    $0xc,%rax
and    $0xf,%rax
or     $0xc0,%rax
mov    %al,-0x15(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x14(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x0,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x13(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x15(%rbp),%rsi
lea    -0x15(%rbp),%rdx
add    $0x3,%rdx
call   1040 <feed_buf_write_character_array@plt>
mov    %al,-0x11(%rbp)
jmp    12a1 <feed_buf_write_unicode_character+0x181>
cmpq   $0x200000,-0x10(%rbp)
jae    1298 <feed_buf_write_unicode_character+0x178>
mov    -0x10(%rbp),%rax
shr    $0x12,%rax
and    $0x7,%rax
or     $0xc0,%rax
mov    %al,-0x15(%rbp)
mov    -0x10(%rbp),%rax
shr    $0xc,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x14(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x13(%rbp)
mov    -0x10(%rbp),%rax
shr    $0x0,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %al,-0x12(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x15(%rbp),%rsi
lea    -0x15(%rbp),%rdx
add    $0x4,%rdx
call   1040 <feed_buf_write_character_array@plt>
mov    %al,-0x11(%rbp)
jmp    129c <feed_buf_write_unicode_character+0x17c>
movb   $0x0,-0x11(%rbp)
jmp    12a1 <feed_buf_write_unicode_character+0x181>
jmp    12a6 <feed_buf_write_unicode_character+0x186>
jmp    12ab <feed_buf_write_unicode_character+0x18b>
movsbl -0x11(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<feed_buf_write_unicode_character>:
cmp    $0x7f,%rsi
ja     112f <feed_buf_write_unicode_character+0xf>
movzbl %sil,%esi
jmp    1030 <feed_buf_write_character@plt>
push   %rax
cmp    $0x7ff,%rsi
ja     115a <feed_buf_write_unicode_character+0x3a>
mov    %rsi,%rax
shr    $0x6,%rax
or     $0xc0,%al
mov    %al,0x4(%rsp)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x5(%rsp)
lea    0x6(%rsp),%rdx
jmp    11d9 <feed_buf_write_unicode_character+0xb9>
cmp    $0xffff,%rsi
ja     1193 <feed_buf_write_unicode_character+0x73>
mov    %rsi,%rax
shr    $0xc,%rax
or     $0xc0,%al
mov    %al,0x4(%rsp)
mov    %rsi,%rax
shr    $0x6,%rax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x5(%rsp)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x6(%rsp)
lea    0x7(%rsp),%rdx
jmp    11d9 <feed_buf_write_unicode_character+0xb9>
cmp    $0x1fffff,%rsi
ja     11e5 <feed_buf_write_unicode_character+0xc5>
mov    %rsi,%rax
shr    $0x12,%rax
or     $0xc0,%al
mov    %al,0x4(%rsp)
mov    %rsi,%rax
shr    $0xc,%rax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x5(%rsp)
mov    %rsi,%rax
shr    $0x6,%rax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x6(%rsp)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x7(%rsp)
lea    0x8(%rsp),%rdx
lea    0x4(%rsp),%rsi
call   1040 <feed_buf_write_character_array@plt>
pop    %rcx
ret
xor    %eax,%eax
pop    %rcx
ret

LLVM IR (-O0):
%struct.feed_buf = type { i32 }
define signext i8 @feed_buf_write_unicode_character(%struct.feed_buf* %0, i64 %1) {
%3 = alloca %struct.feed_buf*
%4 = alloca i64
%5 = alloca i8
%6 = alloca [4 x i8]
store %struct.feed_buf* %0, %struct.feed_buf** %3
store i64 %1, i64* %4
%7 = load i64, i64* %4
%8 = icmp ult i64 %7, 128
br i1 %8, label %9, label %15
9: ; preds = %2
%10 = load %struct.feed_buf*, %struct.feed_buf** %3
%11 = load i64, i64* %4
%12 = and i64 %11, 127
%13 = trunc i64 %12 to i8
%14 = call signext i8 @feed_buf_write_character(%struct.feed_buf* %10, i8 zeroext %13)
store i8 %14, i8* %5
br label %100
15: ; preds = %2
%16 = load i64, i64* %4
%17 = icmp ult i64 %16, 2048
br i1 %17, label %18, label %36
18: ; preds = %15
%19 = load i64, i64* %4
%20 = lshr i64 %19, 6
%21 = and i64 %20, 31
%22 = or i64 192, %21
%23 = trunc i64 %22 to i8
%24 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
store i8 %23, i8* %24
%25 = load i64, i64* %4
%26 = lshr i64 %25, 0
%27 = and i64 %26, 63
%28 = or i64 128, %27
%29 = trunc i64 %28 to i8
%30 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 1
store i8 %29, i8* %30
%31 = load %struct.feed_buf*, %struct.feed_buf** %3
%32 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%33 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%34 = getelementptr inbounds i8, i8* %33, i64 2
%35 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %31, i8* %32, i8* %34)
store i8 %35, i8* %5
br label %99
36: ; preds = %15
%37 = load i64, i64* %4
%38 = icmp ult i64 %37, 65536
br i1 %38, label %39, label %63
39: ; preds = %36
%40 = load i64, i64* %4
%41 = lshr i64 %40, 12
%42 = and i64 %41, 15
%43 = or i64 192, %42
%44 = trunc i64 %43 to i8
%45 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
store i8 %44, i8* %45
%46 = load i64, i64* %4
%47 = lshr i64 %46, 6
%48 = and i64 %47, 63
%49 = or i64 128, %48
%50 = trunc i64 %49 to i8
%51 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 1
store i8 %50, i8* %51
%52 = load i64, i64* %4
%53 = lshr i64 %52, 0
%54 = and i64 %53, 63
%55 = or i64 128, %54
%56 = trunc i64 %55 to i8
%57 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 2
store i8 %56, i8* %57
%58 = load %struct.feed_buf*, %struct.feed_buf** %3
%59 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%60 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%61 = getelementptr inbounds i8, i8* %60, i64 3
%62 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %58, i8* %59, i8* %61)
store i8 %62, i8* %5
br label %98
63: ; preds = %36
%64 = load i64, i64* %4
%65 = icmp ult i64 %64, 2097152
br i1 %65, label %66, label %96
66: ; preds = %63
%67 = load i64, i64* %4
%68 = lshr i64 %67, 18
%69 = and i64 %68, 7
%70 = or i64 192, %69
%71 = trunc i64 %70 to i8
%72 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
store i8 %71, i8* %72
%73 = load i64, i64* %4
%74 = lshr i64 %73, 12
%75 = and i64 %74, 63
%76 = or i64 128, %75
%77 = trunc i64 %76 to i8
%78 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 1
store i8 %77, i8* %78
%79 = load i64, i64* %4
%80 = lshr i64 %79, 6
%81 = and i64 %80, 63
%82 = or i64 128, %81
%83 = trunc i64 %82 to i8
%84 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 2
store i8 %83, i8* %84
%85 = load i64, i64* %4
%86 = lshr i64 %85, 0
%87 = and i64 %86, 63
%88 = or i64 128, %87
%89 = trunc i64 %88 to i8
%90 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 3
store i8 %89, i8* %90
%91 = load %struct.feed_buf*, %struct.feed_buf** %3
%92 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%93 = getelementptr inbounds [4 x i8], [4 x i8]* %6, i64 0, i64 0
%94 = getelementptr inbounds i8, i8* %93, i64 4
%95 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %91, i8* %92, i8* %94)
store i8 %95, i8* %5
br label %97
96: ; preds = %63
store i8 0, i8* %5
br label %97
97: ; preds = %96, %66
br label %98
98: ; preds = %97, %39
br label %99
99: ; preds = %98, %18
br label %100
100: ; preds = %99, %9
%101 = load i8, i8* %5
ret i8 %101
}

LLVM IR (-O2):
%struct.feed_buf = type { i32 }
define signext i8 @feed_buf_write_unicode_character(%struct.feed_buf* %0, i64 %1) {
%3 = alloca [4 x i8]
%4 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 0
%5 = icmp ult i64 %1, 128
br i1 %5, label %6, label %9
6: ; preds = %2
%7 = trunc i64 %1 to i8
%8 = tail call signext i8 @feed_buf_write_character(%struct.feed_buf* %0, i8 zeroext %7)
br label %60
9: ; preds = %2
%10 = icmp ult i64 %1, 2048
br i1 %10, label %11, label %21
11: ; preds = %9
%12 = lshr i64 %1, 6
%13 = trunc i64 %12 to i8
%14 = or i8 %13, -64
store i8 %14, i8* %4
%15 = trunc i64 %1 to i8
%16 = and i8 %15, 63
%17 = or i8 %16, -128
%18 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 1
store i8 %17, i8* %18
%19 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 2
%20 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %0, i8* %4, i8* %19)
br label %60
21: ; preds = %9
%22 = icmp ult i64 %1, 65536
br i1 %22, label %23, label %38
23: ; preds = %21
%24 = lshr i64 %1, 12
%25 = trunc i64 %24 to i8
%26 = or i8 %25, -64
store i8 %26, i8* %4
%27 = lshr i64 %1, 6
%28 = trunc i64 %27 to i8
%29 = and i8 %28, 63
%30 = or i8 %29, -128
%31 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 1
store i8 %30, i8* %31
%32 = trunc i64 %1 to i8
%33 = and i8 %32, 63
%34 = or i8 %33, -128
%35 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 2
store i8 %34, i8* %35
%36 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 3
%37 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %0, i8* %4, i8* %36)
br label %60
38: ; preds = %21
%39 = icmp ult i64 %1, 2097152
br i1 %39, label %40, label %60
40: ; preds = %38
%41 = lshr i64 %1, 18
%42 = trunc i64 %41 to i8
%43 = or i8 %42, -64
store i8 %43, i8* %4
%44 = lshr i64 %1, 12
%45 = trunc i64 %44 to i8
%46 = and i8 %45, 63
%47 = or i8 %46, -128
%48 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 1
store i8 %47, i8* %48
%49 = lshr i64 %1, 6
%50 = trunc i64 %49 to i8
%51 = and i8 %50, 63
%52 = or i8 %51, -128
%53 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 2
store i8 %52, i8* %53
%54 = trunc i64 %1 to i8
%55 = and i8 %54, 63
%56 = or i8 %55, -128
%57 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 3
store i8 %56, i8* %57
%58 = getelementptr inbounds [4 x i8], [4 x i8]* %3, i64 0, i64 4
%59 = call signext i8 @feed_buf_write_character_array(%struct.feed_buf* %0, i8* %4, i8* %58)
br label %60
60: ; preds = %38, %11, %40, %23, %6
%61 = phi i8 [ %8, %6 ], [ %20, %11 ], [ %37, %23 ], [ %59, %40 ], [ 0, %38 ]
ret i8 %61
}