#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 */
int /*<<< orphan*/ putc(unsigned short, int /*<<< orphan*/ *);
void utf8_putc(unsigned short ch, FILE *fout) {
  static int initialized = 0;
  if (!initialized) {
    putc(0xEF, fout);
    putc(0xBB, fout);
    putc(0xBF, fout);
    initialized = 1;
  }
  if (ch < 0x80) {
    putc(ch, fout);
    return;
  }
  if (ch < 0x800) {
    putc(ch >> 6 | 0xc0, fout);
    putc((ch & 0x3f) | 0x80, fout);
    return;
  }
  putc(ch >> 12 | 0xe0, fout);
  putc(((ch >> 6) & 0x3f) | 0x80, fout);
  putc((ch & 0x3f) | 0x80, fout);
}


x86 assembly (clang, -O0):
<utf8_putc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %di,%ax
mov    %ax,-0x2(%rbp)
mov    %rsi,-0x10(%rbp)
cmpl   $0x0,0x2f02(%rip)
jne    1164 <utf8_putc+0x54>
mov    -0x10(%rbp),%rsi
mov    $0xef,%edi
call   1030 <putc@plt>
mov    -0x10(%rbp),%rsi
mov    $0xbb,%edi
call   1030 <putc@plt>
mov    -0x10(%rbp),%rsi
mov    $0xbf,%edi
call   1030 <putc@plt>
movl   $0x1,0x2ec8(%rip)
movzwl -0x2(%rbp),%eax
cmp    $0x80,%eax
jge    1188 <utf8_putc+0x78>
mov    -0x2(%rbp),%ax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
jmp    1217 <utf8_putc+0x107>
movzwl -0x2(%rbp),%eax
cmp    $0x800,%eax
jge    11cc <utf8_putc+0xbc>
movzwl -0x2(%rbp),%eax
sar    $0x6,%eax
or     $0xc0,%eax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
movzwl -0x2(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
jmp    1217 <utf8_putc+0x107>
movzwl -0x2(%rbp),%eax
sar    $0xc,%eax
or     $0xe0,%eax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
movzwl -0x2(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
movzwl -0x2(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    -0x10(%rbp),%rsi
movzwl %ax,%edi
call   1030 <putc@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8_putc>:
push   %rbp
push   %r14
push   %rbx
mov    %rsi,%r14
mov    %edi,%ebp
cmpb   $0x0,0x2f0c(%rip)
jne    1150 <utf8_putc+0x40>
mov    $0xef,%edi
mov    %r14,%rsi
call   1030 <putc@plt>
mov    $0xbb,%edi
mov    %r14,%rsi
call   1030 <putc@plt>
mov    $0xbf,%edi
mov    %r14,%rsi
call   1030 <putc@plt>
movb   $0x1,0x2edc(%rip)
movzwl %bp,%ebx
cmp    $0x80,%ebx
jb     11a1 <utf8_putc+0x91>
cmp    $0x7ff,%ebx
ja     116e <utf8_putc+0x5e>
shr    $0x6,%ebx
or     $0xc0,%ebx
jmp    118d <utf8_putc+0x7d>
mov    %ebx,%edi
shr    $0xc,%edi
or     $0xe0,%edi
mov    %r14,%rsi
call   1030 <putc@plt>
shr    $0x6,%ebx
and    $0x3f,%ebx
or     $0x80,%ebx
movzwl %bx,%edi
mov    %r14,%rsi
call   1030 <putc@plt>
and    $0x3f,%ebp
or     $0x80,%ebp
movzwl %bp,%edi
mov    %r14,%rsi
pop    %rbx
pop    %r14
pop    %rbp
jmp    1030 <putc@plt>

LLVM IR (-O0):
@utf8_putc.initialized = internal global i32 0
define void @utf8_putc(i16 zeroext %0, i32* %1) {
%3 = alloca i16
%4 = alloca i32*
store i16 %0, i16* %3
store i32* %1, i32** %4
%5 = load i32, i32* @utf8_putc.initialized
%6 = icmp ne i32 %5, 0
br i1 %6, label %14, label %7
7: ; preds = %2
%8 = load i32*, i32** %4
%9 = call i32 @putc(i16 zeroext 239, i32* %8)
%10 = load i32*, i32** %4
%11 = call i32 @putc(i16 zeroext 187, i32* %10)
%12 = load i32*, i32** %4
%13 = call i32 @putc(i16 zeroext 191, i32* %12)
store i32 1, i32* @utf8_putc.initialized
br label %14
14: ; preds = %7, %2
%15 = load i16, i16* %3
%16 = zext i16 %15 to i32
%17 = icmp slt i32 %16, 128
br i1 %17, label %18, label %22
18: ; preds = %14
%19 = load i16, i16* %3
%20 = load i32*, i32** %4
%21 = call i32 @putc(i16 zeroext %19, i32* %20)
br label %64
22: ; preds = %14
%23 = load i16, i16* %3
%24 = zext i16 %23 to i32
%25 = icmp slt i32 %24, 2048
br i1 %25, label %26, label %41
26: ; preds = %22
%27 = load i16, i16* %3
%28 = zext i16 %27 to i32
%29 = ashr i32 %28, 6
%30 = or i32 %29, 192
%31 = trunc i32 %30 to i16
%32 = load i32*, i32** %4
%33 = call i32 @putc(i16 zeroext %31, i32* %32)
%34 = load i16, i16* %3
%35 = zext i16 %34 to i32
%36 = and i32 %35, 63
%37 = or i32 %36, 128
%38 = trunc i32 %37 to i16
%39 = load i32*, i32** %4
%40 = call i32 @putc(i16 zeroext %38, i32* %39)
br label %64
41: ; preds = %22
%42 = load i16, i16* %3
%43 = zext i16 %42 to i32
%44 = ashr i32 %43, 12
%45 = or i32 %44, 224
%46 = trunc i32 %45 to i16
%47 = load i32*, i32** %4
%48 = call i32 @putc(i16 zeroext %46, i32* %47)
%49 = load i16, i16* %3
%50 = zext i16 %49 to i32
%51 = ashr i32 %50, 6
%52 = and i32 %51, 63
%53 = or i32 %52, 128
%54 = trunc i32 %53 to i16
%55 = load i32*, i32** %4
%56 = call i32 @putc(i16 zeroext %54, i32* %55)
%57 = load i16, i16* %3
%58 = zext i16 %57 to i32
%59 = and i32 %58, 63
%60 = or i32 %59, 128
%61 = trunc i32 %60 to i16
%62 = load i32*, i32** %4
%63 = call i32 @putc(i16 zeroext %61, i32* %62)
br label %64
64: ; preds = %41, %26, %18
ret void
}

LLVM IR (-O2):
@utf8_putc.initialized = internal unnamed_addr global i1 false
define void @utf8_putc(i16 zeroext %0, i32* nocapture %1) {
%3 = load i1, i1* @utf8_putc.initialized
br i1 %3, label %8, label %4
4: ; preds = %2
%5 = tail call i32 @putc(i16 zeroext 239, i32* %1)
%6 = tail call i32 @putc(i16 zeroext 187, i32* %1)
%7 = tail call i32 @putc(i16 zeroext 191, i32* %1)
store i1 true, i1* @utf8_putc.initialized
br label %8
8: ; preds = %4, %2
%9 = icmp ult i16 %0, 128
br i1 %9, label %27, label %10
10: ; preds = %8
%11 = icmp ult i16 %0, 2048
br i1 %11, label %12, label %15
12: ; preds = %10
%13 = lshr i16 %0, 6
%14 = or i16 %13, 192
br label %22
15: ; preds = %10
%16 = lshr i16 %0, 12
%17 = or i16 %16, 224
%18 = tail call i32 @putc(i16 zeroext %17, i32* %1)
%19 = lshr i16 %0, 6
%20 = and i16 %19, 63
%21 = or i16 %20, 128
br label %22
22: ; preds = %12, %15
%23 = phi i16 [ %21, %15 ], [ %14, %12 ]
%24 = tail call i32 @putc(i16 zeroext %23, i32* %1)
%25 = and i16 %0, 63
%26 = or i16 %25, 128
br label %27
27: ; preds = %22, %8
%28 = phi i16 [ %0, %8 ], [ %26, %22 ]
%29 = tail call i32 @putc(i16 zeroext %28, i32* %1)
ret void
}