#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 void *uint8_t;
typedef int uint32_t;

/* Variables and functions */
int /*<<< orphan*/ dmc_unrar_unicode_utf32_is_valid(int);
bool dmc_unrar_unicode_utf8_put(uint8_t *data, uint32_t code) {
  if (!data || !dmc_unrar_unicode_utf32_is_valid(code))
    return false;
  if (code < 0x80) {
    *(data++) = (uint8_t)(code);
  } else if (code < 0x800) {
    *(data++) = (uint8_t)((code >> 6) | 0xC0);
    *(data++) = (uint8_t)((code & 0x3f) | 0x80);
  } else if (code < 0x10000) {
    *(data++) = (uint8_t)((code >> 12) | 0xE0);
    *(data++) = (uint8_t)(((code >> 6) & 0x3F) | 0x80);
    *(data++) = (uint8_t)((code & 0x3F) | 0x80);
  } else {
    *(data++) = (uint8_t)((code >> 18) | 0xF0);
    *(data++) = (uint8_t)(((code >> 12) & 0x3F) | 0x80);
    *(data++) = (uint8_t)(((code >> 6) & 0x3F) | 0x80);
    *(data++) = (uint8_t)((code & 0x3F) | 0x80);
  }
  return true;
}


x86 assembly (clang, -O0):
<dmc_unrar_unicode_utf8_put>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     113b <dmc_unrar_unicode_utf8_put+0x2b>
mov    -0x14(%rbp),%edi
call   1030 <dmc_unrar_unicode_utf32_is_valid@plt>
cmp    $0x0,%eax
jne    1147 <dmc_unrar_unicode_utf8_put+0x37>
movl   $0x0,-0x4(%rbp)
jmp    12cd <dmc_unrar_unicode_utf8_put+0x1bd>
cmpl   $0x80,-0x14(%rbp)
jge    116f <dmc_unrar_unicode_utf8_put+0x5f>
movslq -0x14(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
jmp    12c6 <dmc_unrar_unicode_utf8_put+0x1b6>
cmpl   $0x800,-0x14(%rbp)
jge    11c1 <dmc_unrar_unicode_utf8_put+0xb1>
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
or     $0xc0,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
jmp    12c1 <dmc_unrar_unicode_utf8_put+0x1b1>
cmpl   $0x10000,-0x14(%rbp)
jge    1236 <dmc_unrar_unicode_utf8_put+0x126>
mov    -0x14(%rbp),%eax
sar    $0xc,%eax
or     $0xe0,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
jmp    12bc <dmc_unrar_unicode_utf8_put+0x1ac>
mov    -0x14(%rbp),%eax
sar    $0x12,%eax
or     $0xf0,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
sar    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
mov    -0x14(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
movslq %eax,%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
jmp    12c1 <dmc_unrar_unicode_utf8_put+0x1b1>
jmp    12c6 <dmc_unrar_unicode_utf8_put+0x1b6>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dmc_unrar_unicode_utf8_put>:
push   %rbp
push   %r14
push   %rbx
xor    %ebp,%ebp
test   %rdi,%rdi
je     11c4 <dmc_unrar_unicode_utf8_put+0xb4>
mov    %esi,%ebx
mov    %rdi,%r14
mov    %esi,%edi
call   1030 <dmc_unrar_unicode_utf32_is_valid@plt>
test   %eax,%eax
je     11c4 <dmc_unrar_unicode_utf8_put+0xb4>
cmp    $0x7f,%ebx
jg     113d <dmc_unrar_unicode_utf8_put+0x2d>
movslq %ebx,%rbx
jmp    11bc <dmc_unrar_unicode_utf8_put+0xac>
mov    %ebx,%eax
cmp    $0x7ff,%ebx
ja     1158 <dmc_unrar_unicode_utf8_put+0x48>
shr    $0x6,%eax
or     $0xc0,%eax
mov    %rax,(%r14)
add    $0x8,%r14
jmp    11b3 <dmc_unrar_unicode_utf8_put+0xa3>
cmp    $0xffff,%ebx
ja     1182 <dmc_unrar_unicode_utf8_put+0x72>
shr    $0xc,%eax
or     $0xe0,%eax
mov    %rax,(%r14)
mov    %ebx,%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %rax,0x8(%r14)
add    $0x10,%r14
jmp    11b3 <dmc_unrar_unicode_utf8_put+0xa3>
shr    $0x12,%eax
or     $0xf0,%eax
mov    %rax,(%r14)
mov    %ebx,%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %rax,0x8(%r14)
mov    %ebx,%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %rax,0x10(%r14)
add    $0x18,%r14
and    $0x3f,%ebx
or     $0x80,%ebx
mov    %rbx,(%r14)
mov    $0x1,%ebp
mov    %ebp,%eax
pop    %rbx
pop    %r14
pop    %rbp
ret

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

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