#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*/ putchar(int);
void pututf8(unsigned long unichar) {
  if (unichar <= 0x7f)
    putchar(unichar % 0x80);
  else if (unichar <= 0x7ff) {
    putchar(0xC0 + (unichar >> 6) % 0x20);
    putchar(0x80 + unichar % 0x40);
  } else if (unichar <= 0xffff) {
    putchar(0xE0 + (unichar >> 12) % 0x10);
    putchar(0x80 + (unichar >> 6) % 0x40);
    putchar(0x80 + unichar % 0x40);
  } else if (unichar <= 0x1fffff) {
    putchar(0xF0 + (unichar >> 18) % 0x08);
    putchar(0x80 + (unichar >> 12) % 0x40);
    putchar(0x80 + (unichar >> 6) % 0x40);
    putchar(0x80 + unichar % 0x40);
  } else if (unichar <= 0x3ffffff) {
    putchar(0xF8 + (unichar >> 24) % 0x04);
    putchar(0x80 + (unichar >> 18) % 0x40);
    putchar(0x80 + (unichar >> 12) % 0x40);
    putchar(0x80 + (unichar >> 6) % 0x40);
    putchar(0x80 + unichar % 0x40);
  } else if (unichar <= 0x7fffffff) {
    putchar(0xFC + (unichar >> 30) % 0x02);
    putchar(0x80 + (unichar >> 24) % 0x40);
    putchar(0x80 + (unichar >> 18) % 0x40);
    putchar(0x80 + (unichar >> 12) % 0x40);
    putchar(0x80 + (unichar >> 6) % 0x40);
    putchar(0x80 + unichar % 0x40);
  }
}


x86 assembly (clang, -O0):
<pututf8>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %rdi,-0x8(%rbp)
cmpq   $0x7f,-0x8(%rbp)
ja     113b <pututf8+0x2b>
mov    -0x8(%rbp),%rax
and    $0x7f,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    138e <pututf8+0x27e>
cmpq   $0x7ff,-0x8(%rbp)
ja     117c <pututf8+0x6c>
mov    -0x8(%rbp),%rax
shr    $0x6,%rax
and    $0x1f,%rax
add    $0xc0,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    1389 <pututf8+0x279>
cmpq   $0xffff,-0x8(%rbp)
ja     11d6 <pututf8+0xc6>
mov    -0x8(%rbp),%rax
shr    $0xc,%rax
and    $0xf,%rax
add    $0xe0,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    1384 <pututf8+0x274>
cmpq   $0x1fffff,-0x8(%rbp)
ja     1249 <pututf8+0x139>
mov    -0x8(%rbp),%rax
shr    $0x12,%rax
and    $0x7,%rax
add    $0xf0,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0xc,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    137f <pututf8+0x26f>
cmpq   $0x3ffffff,-0x8(%rbp)
03
ja     12d5 <pututf8+0x1c5>
mov    -0x8(%rbp),%rax
shr    $0x18,%rax
and    $0x3,%rax
add    $0xf8,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x12,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0xc,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    137a <pututf8+0x26a>
cmpq   $0x7fffffff,-0x8(%rbp)
7f
ja     1375 <pututf8+0x265>
mov    -0x8(%rbp),%rax
shr    $0x1e,%rax
and    $0x1,%rax
add    $0xfc,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x18,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x12,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0xc,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
shr    $0x6,%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
mov    -0x8(%rbp),%rax
and    $0x3f,%rax
add    $0x80,%rax
mov    %eax,%edi
call   1030 <putchar@plt>
jmp    137a <pututf8+0x26a>
jmp    137f <pututf8+0x26f>
jmp    1384 <pututf8+0x274>
jmp    1389 <pututf8+0x279>
jmp    138e <pututf8+0x27e>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pututf8>:
push   %rbx
mov    %rdi,%rbx
cmp    $0x7f,%rdi
jbe    11e7 <pututf8+0xd7>
cmp    $0x7ff,%rbx
ja     1137 <pututf8+0x27>
mov    %ebx,%edi
shr    $0x6,%edi
or     $0xc0,%edi
jmp    11d9 <pututf8+0xc9>
cmp    $0xffff,%rbx
ja     114d <pututf8+0x3d>
mov    %ebx,%edi
shr    $0xc,%edi
or     $0xe0,%edi
jmp    11c6 <pututf8+0xb6>
cmp    $0x1fffff,%rbx
ja     1163 <pututf8+0x53>
mov    %ebx,%edi
shr    $0x12,%edi
or     $0xf0,%edi
jmp    11b3 <pututf8+0xa3>
cmp    $0x3ffffff,%rbx
ja     1179 <pututf8+0x69>
mov    %ebx,%edi
shr    $0x18,%edi
or     $0xf8,%edi
jmp    11a0 <pututf8+0x90>
cmp    $0x7fffffff,%rbx
ja     11ef <pututf8+0xdf>
mov    %ebx,%edi
shr    $0x1e,%edi
or     $0xfc,%edi
call   1030 <putchar@plt>
mov    %ebx,%edi
shr    $0x18,%edi
and    $0x3f,%edi
or     $0x80,%edi
call   1030 <putchar@plt>
mov    %ebx,%edi
shr    $0x12,%edi
and    $0x3f,%edi
or     $0x80,%edi
call   1030 <putchar@plt>
mov    %ebx,%edi
shr    $0xc,%edi
and    $0x3f,%edi
or     $0x80,%edi
call   1030 <putchar@plt>
mov    %ebx,%edi
shr    $0x6,%edi
and    $0x3f,%edi
or     $0x80,%edi
call   1030 <putchar@plt>
and    $0x3f,%ebx
or     $0x80,%ebx
mov    %ebx,%edi
pop    %rbx
jmp    1030 <putchar@plt>
pop    %rbx
ret

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

LLVM IR (-O2):
define void @pututf8(i64 %0) {
%2 = icmp ult i64 %0, 128
br i1 %2, label %3, label %5
3: ; preds = %1
%4 = trunc i64 %0 to i32
br label %90
5: ; preds = %1
%6 = icmp ult i64 %0, 2048
br i1 %6, label %7, label %14
7: ; preds = %5
%8 = trunc i64 %0 to i32
%9 = lshr i32 %8, 6
%10 = or i32 %9, 192
%11 = tail call i32 @putchar(i32 %10)
%12 = and i32 %8, 63
%13 = or i32 %12, 128
br label %90
14: ; preds = %5
%15 = icmp ult i64 %0, 65536
br i1 %15, label %16, label %27
16: ; preds = %14
%17 = trunc i64 %0 to i32
%18 = lshr i32 %17, 12
%19 = or i32 %18, 224
%20 = tail call i32 @putchar(i32 %19)
%21 = lshr i32 %17, 6
%22 = and i32 %21, 63
%23 = or i32 %22, 128
%24 = tail call i32 @putchar(i32 %23)
%25 = and i32 %17, 63
%26 = or i32 %25, 128
br label %90
27: ; preds = %14
%28 = icmp ult i64 %0, 2097152
br i1 %28, label %29, label %44
29: ; preds = %27
%30 = trunc i64 %0 to i32
%31 = lshr i32 %30, 18
%32 = or i32 %31, 240
%33 = tail call i32 @putchar(i32 %32)
%34 = lshr i32 %30, 12
%35 = and i32 %34, 63
%36 = or i32 %35, 128
%37 = tail call i32 @putchar(i32 %36)
%38 = lshr i32 %30, 6
%39 = and i32 %38, 63
%40 = or i32 %39, 128
%41 = tail call i32 @putchar(i32 %40)
%42 = and i32 %30, 63
%43 = or i32 %42, 128
br label %90
44: ; preds = %27
%45 = icmp ult i64 %0, 67108864
br i1 %45, label %46, label %65
46: ; preds = %44
%47 = trunc i64 %0 to i32
%48 = lshr i32 %47, 24
%49 = or i32 %48, 248
%50 = tail call i32 @putchar(i32 %49)
%51 = lshr i32 %47, 18
%52 = and i32 %51, 63
%53 = or i32 %52, 128
%54 = tail call i32 @putchar(i32 %53)
%55 = lshr i32 %47, 12
%56 = and i32 %55, 63
%57 = or i32 %56, 128
%58 = tail call i32 @putchar(i32 %57)
%59 = lshr i32 %47, 6
%60 = and i32 %59, 63
%61 = or i32 %60, 128
%62 = tail call i32 @putchar(i32 %61)
%63 = and i32 %47, 63
%64 = or i32 %63, 128
br label %90
65: ; preds = %44
%66 = icmp ult i64 %0, 2147483648
br i1 %66, label %67, label %93
67: ; preds = %65
%68 = trunc i64 %0 to i32
%69 = lshr i32 %68, 30
%70 = or i32 %69, 252
%71 = tail call i32 @putchar(i32 %70)
%72 = lshr i32 %68, 24
%73 = and i32 %72, 63
%74 = or i32 %73, 128
%75 = tail call i32 @putchar(i32 %74)
%76 = lshr i32 %68, 18
%77 = and i32 %76, 63
%78 = or i32 %77, 128
%79 = tail call i32 @putchar(i32 %78)
%80 = lshr i32 %68, 12
%81 = and i32 %80, 63
%82 = or i32 %81, 128
%83 = tail call i32 @putchar(i32 %82)
%84 = lshr i32 %68, 6
%85 = and i32 %84, 63
%86 = or i32 %85, 128
%87 = tail call i32 @putchar(i32 %86)
%88 = and i32 %68, 63
%89 = or i32 %88, 128
br label %90
90: ; preds = %3, %16, %46, %67, %29, %7
%91 = phi i32 [ %13, %7 ], [ %43, %29 ], [ %89, %67 ], [ %64, %46 ], [ %26, %16 ], [ %4, %3 ]
%92 = tail call i32 @putchar(i32 %91)
br label %93
93: ; preds = %90, %65
ret void
}