#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 wchar_t;
typedef int /*<<< orphan*/ mbstate_t;

/* Variables and functions */
int /*<<< orphan*/ EILSEQ;
int /*<<< orphan*/ errno;
size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict ps) {
  (void)ps;
  if (!s)
    return 1;
  if ((wc >= 0xD800 && wc <= 0xDFFF) || wc > 0x10FFFF) {
    errno = EILSEQ;
    return -1;
  }
  if (wc <= 0x7F) {
    s[0] = wc;
    return 1;
  } else if (wc <= 0x7FF) {
    s[0] = 0b11000000 | ((wc >> 6) & 0b00011111);
    s[1] = 0b10000000 | (wc & 0b00111111);
    return 2;
  } else if (wc <= 0xFFFF) {
    s[0] = 0b11100000 | ((wc >> 12) & 0b00001111);
    s[1] = 0b10000000 | ((wc >> 6) & 0b00111111);
    s[2] = 0b10000000 | (wc & 0b00111111);
    return 3;
  } else {
    s[0] = 0b11110000 | ((wc >> 18) & 0b00000111);
    s[1] = 0b10000000 | ((wc >> 12) & 0b00111111);
    s[2] = 0b10000000 | ((wc >> 6) & 0b00111111);
    s[3] = 0b10000000 | (wc & 0b00111111);
    return 4;
  }
}


x86 assembly (clang, -O0):
<wcrtomb>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1127 <wcrtomb+0x27>
movq   $0x1,-0x8(%rbp)
jmp    128e <wcrtomb+0x18e>
cmpl   $0xd800,-0x14(%rbp)
jl     1141 <wcrtomb+0x41>
cmpl   $0xdfff,-0x14(%rbp)
jle    114e <wcrtomb+0x4e>
cmpl   $0x10ffff,-0x14(%rbp)
jle    116d <wcrtomb+0x6d>
mov    0x2e9b(%rip),%rax
mov    (%rax),%ecx
mov    0x2e7a(%rip),%rax
mov    %ecx,(%rax)
movq   $0xffffffffffffffff,-0x8(%rbp)
ff
jmp    128e <wcrtomb+0x18e>
cmpl   $0x7f,-0x14(%rbp)
jg     118f <wcrtomb+0x8f>
mov    -0x14(%rbp),%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
movq   $0x1,-0x8(%rbp)
jmp    128e <wcrtomb+0x18e>
cmpl   $0x7ff,-0x14(%rbp)
jg     11d3 <wcrtomb+0xd3>
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
and    $0x1f,%eax
or     $0xc0,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x1(%rax)
movq   $0x2,-0x8(%rbp)
jmp    128e <wcrtomb+0x18e>
cmpl   $0xffff,-0x14(%rbp)
jg     122e <wcrtomb+0x12e>
mov    -0x14(%rbp),%eax
sar    $0xc,%eax
and    $0xf,%eax
or     $0xe0,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x2(%rax)
movq   $0x3,-0x8(%rbp)
jmp    128e <wcrtomb+0x18e>
mov    -0x14(%rbp),%eax
sar    $0x12,%eax
and    $0x7,%eax
or     $0xf0,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
sar    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x3(%rax)
movq   $0x4,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<wcrtomb>:
mov    $0x1,%eax
test   %rdi,%rdi
je     11c9 <wcrtomb+0xc9>
cmp    $0x10ffff,%esi
jg     112f <wcrtomb+0x2f>
mov    %esi,%ecx
and    $0xfffff800,%ecx
cmp    $0xd800,%ecx
je     112f <wcrtomb+0x2f>
cmp    $0x7f,%esi
jg     1149 <wcrtomb+0x49>
mov    %sil,(%rdi)
ret
mov    0x2eba(%rip),%rax
mov    (%rax),%eax
mov    0x2e99(%rip),%rcx
mov    %eax,(%rcx)
mov    $0xffffffffffffffff,%rax
ret
mov    %esi,%eax
cmp    $0x7ff,%esi
ja     116c <wcrtomb+0x6c>
shr    $0x6,%eax
or     $0xc0,%al
mov    %al,(%rdi)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x1(%rdi)
mov    $0x2,%eax
ret
cmp    $0xffff,%esi
ja     1199 <wcrtomb+0x99>
shr    $0xc,%eax
or     $0xe0,%al
mov    %al,(%rdi)
mov    %esi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rdi)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x2(%rdi)
mov    $0x3,%eax
ret
shr    $0x12,%eax
or     $0xf0,%al
mov    %al,(%rdi)
mov    %esi,%eax
shr    $0xc,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rdi)
mov    %esi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x2(%rdi)
and    $0x3f,%sil
or     $0x80,%sil
mov    %sil,0x3(%rdi)
mov    $0x4,%eax
ret

LLVM IR (-O0):
@EILSEQ = global i32 0
@errno = global i32 0
define i64 @wcrtomb(i8* noalias %0, i32 %1, i32* noalias %2) {
%4 = alloca i64
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32*
store i8* %0, i8** %5
store i32 %1, i32* %6
store i32* %2, i32** %7
%8 = load i32*, i32** %7
%9 = load i8*, i8** %5
%10 = icmp ne i8* %9, null
br i1 %10, label %12, label %11
11: ; preds = %3
store i64 1, i64* %4
br label %100
12: ; preds = %3
%13 = load i32, i32* %6
%14 = icmp sge i32 %13, 55296
br i1 %14, label %15, label %18
15: ; preds = %12
%16 = load i32, i32* %6
%17 = icmp sle i32 %16, 57343
br i1 %17, label %21, label %18
18: ; preds = %15, %12
%19 = load i32, i32* %6
%20 = icmp sgt i32 %19, 1114111
br i1 %20, label %21, label %23
21: ; preds = %18, %15
%22 = load i32, i32* @EILSEQ
store i32 %22, i32* @errno
store i64 -1, i64* %4
br label %100
23: ; preds = %18
%24 = load i32, i32* %6
%25 = icmp sle i32 %24, 127
br i1 %25, label %26, label %31
26: ; preds = %23
%27 = load i32, i32* %6
%28 = trunc i32 %27 to i8
%29 = load i8*, i8** %5
%30 = getelementptr inbounds i8, i8* %29, i64 0
store i8 %28, i8* %30
store i64 1, i64* %4
br label %100
31: ; preds = %23
%32 = load i32, i32* %6
%33 = icmp sle i32 %32, 2047
br i1 %33, label %34, label %48
34: ; preds = %31
%35 = load i32, i32* %6
%36 = ashr i32 %35, 6
%37 = and i32 %36, 31
%38 = or i32 192, %37
%39 = trunc i32 %38 to i8
%40 = load i8*, i8** %5
%41 = getelementptr inbounds i8, i8* %40, i64 0
store i8 %39, i8* %41
%42 = load i32, i32* %6
%43 = and i32 %42, 63
%44 = or i32 128, %43
%45 = trunc i32 %44 to i8
%46 = load i8*, i8** %5
%47 = getelementptr inbounds i8, i8* %46, i64 1
store i8 %45, i8* %47
store i64 2, i64* %4
br label %100
48: ; preds = %31
%49 = load i32, i32* %6
%50 = icmp sle i32 %49, 65535
br i1 %50, label %51, label %72
51: ; preds = %48
%52 = load i32, i32* %6
%53 = ashr i32 %52, 12
%54 = and i32 %53, 15
%55 = or i32 224, %54
%56 = trunc i32 %55 to i8
%57 = load i8*, i8** %5
%58 = getelementptr inbounds i8, i8* %57, i64 0
store i8 %56, i8* %58
%59 = load i32, i32* %6
%60 = ashr i32 %59, 6
%61 = and i32 %60, 63
%62 = or i32 128, %61
%63 = trunc i32 %62 to i8
%64 = load i8*, i8** %5
%65 = getelementptr inbounds i8, i8* %64, i64 1
store i8 %63, i8* %65
%66 = load i32, i32* %6
%67 = and i32 %66, 63
%68 = or i32 128, %67
%69 = trunc i32 %68 to i8
%70 = load i8*, i8** %5
%71 = getelementptr inbounds i8, i8* %70, i64 2
store i8 %69, i8* %71
store i64 3, i64* %4
br label %100
72: ; preds = %48
%73 = load i32, i32* %6
%74 = ashr i32 %73, 18
%75 = and i32 %74, 7
%76 = or i32 240, %75
%77 = trunc i32 %76 to i8
%78 = load i8*, i8** %5
%79 = getelementptr inbounds i8, i8* %78, i64 0
store i8 %77, i8* %79
%80 = load i32, i32* %6
%81 = ashr i32 %80, 12
%82 = and i32 %81, 63
%83 = or i32 128, %82
%84 = trunc i32 %83 to i8
%85 = load i8*, i8** %5
%86 = getelementptr inbounds i8, i8* %85, i64 1
store i8 %84, i8* %86
%87 = load i32, i32* %6
%88 = ashr i32 %87, 6
%89 = and i32 %88, 63
%90 = or i32 128, %89
%91 = trunc i32 %90 to i8
%92 = load i8*, i8** %5
%93 = getelementptr inbounds i8, i8* %92, i64 2
store i8 %91, i8* %93
%94 = load i32, i32* %6
%95 = and i32 %94, 63
%96 = or i32 128, %95
%97 = trunc i32 %96 to i8
%98 = load i8*, i8** %5
%99 = getelementptr inbounds i8, i8* %98, i64 3
store i8 %97, i8* %99
store i64 4, i64* %4
br label %100
100: ; preds = %72, %51, %34, %26, %21, %11
%101 = load i64, i64* %4
ret i64 %101
}

LLVM IR (-O2):
@EILSEQ = global i32 0
@errno = global i32 0
define i64 @wcrtomb(i8* noalias writeonly %0, i32 %1, i32* noalias nocapture readnone %2) {
%4 = icmp eq i8* %0, null
br i1 %4, label %59, label %5
5: ; preds = %3
%6 = and i32 %1, -2048
%7 = icmp eq i32 %6, 55296
%8 = icmp sgt i32 %1, 1114111
%9 = or i1 %8, %7
br i1 %9, label %10, label %12
10: ; preds = %5
%11 = load i32, i32* @EILSEQ
store i32 %11, i32* @errno
br label %59
12: ; preds = %5
%13 = icmp slt i32 %1, 128
br i1 %13, label %14, label %16
14: ; preds = %12
%15 = trunc i32 %1 to i8
store i8 %15, i8* %0
br label %59
16: ; preds = %12
%17 = icmp ult i32 %1, 2048
br i1 %17, label %18, label %26
18: ; preds = %16
%19 = lshr i32 %1, 6
%20 = trunc i32 %19 to i8
%21 = or i8 %20, -64
store i8 %21, i8* %0
%22 = trunc i32 %1 to i8
%23 = and i8 %22, 63
%24 = or i8 %23, -128
%25 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %24, i8* %25
br label %59
26: ; preds = %16
%27 = icmp ult i32 %1, 65536
br i1 %27, label %28, label %41
28: ; preds = %26
%29 = lshr i32 %1, 12
%30 = trunc i32 %29 to i8
%31 = or i8 %30, -32
store i8 %31, i8* %0
%32 = lshr i32 %1, 6
%33 = trunc i32 %32 to i8
%34 = and i8 %33, 63
%35 = or i8 %34, -128
%36 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %35, i8* %36
%37 = trunc i32 %1 to i8
%38 = and i8 %37, 63
%39 = or i8 %38, -128
%40 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %39, i8* %40
br label %59
41: ; preds = %26
%42 = lshr i32 %1, 18
%43 = trunc i32 %42 to i8
%44 = or i8 %43, -16
store i8 %44, i8* %0
%45 = lshr i32 %1, 12
%46 = trunc i32 %45 to i8
%47 = and i8 %46, 63
%48 = or i8 %47, -128
%49 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %48, i8* %49
%50 = lshr i32 %1, 6
%51 = trunc i32 %50 to i8
%52 = and i8 %51, 63
%53 = or i8 %52, -128
%54 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %53, i8* %54
%55 = trunc i32 %1 to i8
%56 = and i8 %55, 63
%57 = or i8 %56, -128
%58 = getelementptr inbounds i8, i8* %0, i64 3
store i8 %57, i8* %58
br label %59
59: ; preds = %3, %41, %28, %18, %14, %10
%60 = phi i64 [ -1, %10 ], [ 1, %14 ], [ 2, %18 ], [ 3, %28 ], [ 4, %41 ], [ 1, %3 ]
ret i64 %60
}