#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*/ uint8_t;

/* Variables and functions */
int /*<<< orphan*/ memcpy(int /*<<< orphan*/ *, int /*<<< orphan*/ *, int);
int /*<<< orphan*/ memset(int /*<<< orphan*/ *, int /*<<< orphan*/, int);
void stub1();
void tinyc_init() {
  extern uint8_t __etext;
  extern uint8_t __data_start__;
  extern uint8_t __data_end__;
  memcpy(&__data_start__, &__etext, &__data_end__ - &__data_start__);
  extern uint8_t __bss_start__;
  extern uint8_t __bss_end__;
  memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__);
  extern void (*__init_array_start)();
  extern void (*__init_array_end)();
  void (**func)();
  for (func = &__init_array_start; func < &__init_array_end; ++func) {
    (**func)();
  }
}


x86 assembly (clang, -O0):
<tinyc_init>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    0x2e99(%rip),%rdi
mov    0x2e8a(%rip),%rax
sub    %rdi,%rax
shr    $0x2,%rax
mov    %eax,%edx
mov    0x2e9a(%rip),%rsi
call   1040 <memcpy@plt>
mov    0x2e5e(%rip),%rdi
mov    0x2e5f(%rip),%rax
sub    %rdi,%rax
shr    $0x2,%rax
mov    %eax,%edx
xor    %esi,%esi
call   1030 <memset@plt>
mov    0x2e78(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    0x2e5d(%rip),%rax
cmp    %rax,-0x8(%rbp)
jae    119e <tinyc_init+0x7e>
mov    -0x8(%rbp),%rcx
mov    $0x0,%al
call   *(%rcx)
mov    -0x8(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
jmp    1174 <tinyc_init+0x54>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<tinyc_init>:
push   %r14
push   %rbx
push   %rax
mov    0x2e9d(%rip),%rdi
mov    0x2e8e(%rip),%rax
sub    %rdi,%rax
lea    0x3(%rax),%rdx
test   %rax,%rax
cmovns %rax,%rdx
shr    $0x2,%rdx
mov    0x2e95(%rip),%rsi
call   1040 <memcpy@plt>
mov    0x2e59(%rip),%rdi
mov    0x2e5a(%rip),%rax
sub    %rdi,%rax
lea    0x3(%rax),%rdx
test   %rax,%rax
cmovns %rax,%rdx
shr    $0x2,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
mov    0x2e6a(%rip),%rbx
cmp    0x2e53(%rip),%rbx
jae    119d <tinyc_init+0x7d>
mov    0x2e4a(%rip),%r14
xchg   %ax,%ax
xor    %eax,%eax
call   *(%rbx)
add    $0x8,%rbx
cmp    %r14,%rbx
jb     1190 <tinyc_init+0x70>
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@__data_start__ = external global i32
@__etext = external global i32
@__data_end__ = external global i32
@__bss_start__ = external global i32
@__bss_end__ = external global i32
@__init_array_start = external global void (...)*
@__init_array_end = external global void (...)*
define void @tinyc_init() {
%1 = alloca void (...)**
%2 = call i32 @memcpy(i32* @__data_start__, i32* @__etext, i32 trunc (i64 sdiv exact (i64 sub (i64 ptrtoint (i32* @__data_end__ to i64), i64 ptrtoint (i32* @__data_start__ to i64)), i64 4) to i32))
%3 = call i32 @memset(i32* @__bss_start__, i32 0, i32 trunc (i64 sdiv exact (i64 sub (i64 ptrtoint (i32* @__bss_end__ to i64), i64 ptrtoint (i32* @__bss_start__ to i64)), i64 4) to i32))
store void (...)** @__init_array_start, void (...)*** %1
br label %4
4: ; preds = %10, %0
%5 = load void (...)**, void (...)*** %1
%6 = icmp ult void (...)** %5, @__init_array_end
br i1 %6, label %7, label %13
7: ; preds = %4
%8 = load void (...)**, void (...)*** %1
%9 = load void (...)*, void (...)** %8
br label %10
10: ; preds = %7
%11 = load void (...)**, void (...)*** %1
%12 = getelementptr inbounds void (...)*, void (...)** %11, i32 1
store void (...)** %12, void (...)*** %1
br label %4
13: ; preds = %4
ret void
}

LLVM IR (-O2):
@__data_start__ = external global i32
@__etext = external global i32
@__data_end__ = external global i32
@__bss_start__ = external global i32
@__bss_end__ = external global i32
@__init_array_start = external global void (...)*
@__init_array_end = external global void (...)*
define void @tinyc_init() {
%1 = tail call i32 @memcpy(i32* @__data_start__, i32* @__etext, i32 trunc (i64 sdiv (i64 sub (i64 ptrtoint (i32* @__data_end__ to i64), i64 ptrtoint (i32* @__data_start__ to i64)), i64 4) to i32))
%2 = tail call i32 @memset(i32* @__bss_start__, i32 0, i32 trunc (i64 sdiv (i64 sub (i64 ptrtoint (i32* @__bss_end__ to i64), i64 ptrtoint (i32* @__bss_start__ to i64)), i64 4) to i32))
br i1 icmp ult (void (...)** @__init_array_start, void (...)** @__init_array_end), label %3, label %8
3: ; preds = %0, %3
%4 = phi void (...)** [ %6, %3 ], [ @__init_array_start, %0 ]
%5 = load void (...)*, void (...)** %4
tail call void (...) %5()
%6 = getelementptr inbounds void (...)*, void (...)** %4, i64 1
%7 = icmp ult void (...)** %6, @__init_array_end
br i1 %7, label %3, label %8
8: ; preds = %3, %0
ret void
}