#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 size_t uint32_t;

/* Variables and functions */
__attribute__((always_)) __attribute__((__noreturn__)) void
__cmsis_start(void) {
  extern void _start(void) __attribute__((__noreturn__));
  typedef struct {
    uint32_t const *src;
    uint32_t *dest;
    uint32_t wlen;
  } __copy_table_t;
  typedef struct {
    uint32_t *dest;
    uint32_t wlen;
  } __zero_table_t;
  extern const __copy_table_t __copy_table_start__;
  extern const __copy_table_t __copy_table_end__;
  extern const __zero_table_t __zero_table_start__;
  extern const __zero_table_t __zero_table_end__;
  for (__copy_table_t const *pTable = &__copy_table_start__;
       pTable < &__copy_table_end__; ++pTable) {
    for (uint32_t i = 0u; i < pTable->wlen; ++i) {
      pTable->dest[i] = pTable->src[i];
    }
  }
  for (__zero_table_t const *pTable = &__zero_table_start__;
       pTable < &__zero_table_end__; ++pTable) {
    for (uint32_t i = 0u; i < pTable->wlen; ++i) {
      pTable->dest[i] = 0u;
    }
  }
  _start();
}


x86 assembly (clang, -O0):
<__cmsis_start>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    0x2ec1(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    0x2e9e(%rip),%rax
cmp    %rax,-0x8(%rbp)
jae    1194 <__cmsis_start+0x84>
movq   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
cmp    0x10(%rcx),%rax
jae    117e <__cmsis_start+0x6e>
mov    -0x8(%rbp),%rax
mov    (%rax),%rax
mov    -0x10(%rbp),%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%rax
mov    -0x10(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    113c <__cmsis_start+0x2c>
jmp    1183 <__cmsis_start+0x73>
mov    -0x8(%rbp),%rax
add    $0x18,%rax
mov    %rax,-0x8(%rbp)
jmp    1123 <__cmsis_start+0x13>
mov    0x2e4d(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    0x2e2a(%rip),%rax
cmp    %rax,-0x18(%rbp)
jae    1204 <__cmsis_start+0xf4>
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x18(%rbp),%rcx
cmp    0x8(%rcx),%rax
jae    11ee <__cmsis_start+0xde>
mov    -0x18(%rbp),%rax
mov    (%rax),%rax
mov    -0x20(%rbp),%rcx
movq   $0x0,(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    11b8 <__cmsis_start+0xa8>
jmp    11f3 <__cmsis_start+0xe3>
mov    -0x18(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x18(%rbp)
jmp    119f <__cmsis_start+0x8f>
call   1030 <_start@plt>

x86 assembly (clang, -O2):
<__cmsis_start>:
push   %rax
mov    0x2ec8(%rip),%rax
cmp    0x2ea9(%rip),%rax
jae    1164 <__cmsis_start+0x54>
mov    0x2ea0(%rip),%r8
jmp    1139 <__cmsis_start+0x29>
nopw   0x0(%rax,%rax,1)
add    $0x18,%rax
cmp    %r8,%rax
jae    1164 <__cmsis_start+0x54>
cmpq   $0x0,0x10(%rax)
je     1130 <__cmsis_start+0x20>
mov    (%rax),%rdx
mov    0x8(%rax),%rsi
xor    %edi,%edi
nopl   0x0(%rax)
mov    (%rdx,%rdi,8),%rcx
mov    %rcx,(%rsi,%rdi,8)
add    $0x1,%rdi
cmp    0x10(%rax),%rdi
jb     1150 <__cmsis_start+0x40>
jmp    1130 <__cmsis_start+0x20>
mov    0x2e7d(%rip),%rax
cmp    0x2e5e(%rip),%rax
jae    11b4 <__cmsis_start+0xa4>
mov    0x2e55(%rip),%rcx
jmp    1189 <__cmsis_start+0x79>
nopl   (%rax)
add    $0x10,%rax
cmp    %rcx,%rax
jae    11b4 <__cmsis_start+0xa4>
cmpq   $0x0,0x8(%rax)
je     1180 <__cmsis_start+0x70>
mov    (%rax),%rdx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nop
movq   $0x0,(%rdx,%rsi,8)
add    $0x1,%rsi
cmp    0x8(%rax),%rsi
jb     11a0 <__cmsis_start+0x90>
jmp    1180 <__cmsis_start+0x70>
call   1030 <_start@plt>

LLVM IR (-O0):
%struct.__copy_table_t = type { i64*, i64*, i64 }
%struct.__zero_table_t = type { i64*, i64 }
@__copy_table_start__ = external constant %struct.__copy_table_t
@__copy_table_end__ = external constant %struct.__copy_table_t
@__zero_table_start__ = external constant %struct.__zero_table_t
@__zero_table_end__ = external constant %struct.__zero_table_t
define void @__cmsis_start() {
%1 = alloca %struct.__copy_table_t*
%2 = alloca i64
%3 = alloca %struct.__zero_table_t*
%4 = alloca i64
store %struct.__copy_table_t* @__copy_table_start__, %struct.__copy_table_t** %1
br label %5
5: ; preds = %31, %0
%6 = load %struct.__copy_table_t*, %struct.__copy_table_t** %1
%7 = icmp ult %struct.__copy_table_t* %6, @__copy_table_end__
br i1 %7, label %8, label %34
8: ; preds = %5
store i64 0, i64* %2
br label %9
9: ; preds = %27, %8
%10 = load i64, i64* %2
%11 = load %struct.__copy_table_t*, %struct.__copy_table_t** %1
%12 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %11, i32 0, i32 2
%13 = load i64, i64* %12
%14 = icmp ult i64 %10, %13
br i1 %14, label %15, label %30
15: ; preds = %9
%16 = load %struct.__copy_table_t*, %struct.__copy_table_t** %1
%17 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %16, i32 0, i32 0
%18 = load i64*, i64** %17
%19 = load i64, i64* %2
%20 = getelementptr inbounds i64, i64* %18, i64 %19
%21 = load i64, i64* %20
%22 = load %struct.__copy_table_t*, %struct.__copy_table_t** %1
%23 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %22, i32 0, i32 1
%24 = load i64*, i64** %23
%25 = load i64, i64* %2
%26 = getelementptr inbounds i64, i64* %24, i64 %25
store i64 %21, i64* %26
br label %27
27: ; preds = %15
%28 = load i64, i64* %2
%29 = add i64 %28, 1
store i64 %29, i64* %2
br label %9
30: ; preds = %9
br label %31
31: ; preds = %30
%32 = load %struct.__copy_table_t*, %struct.__copy_table_t** %1
%33 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %32, i32 1
store %struct.__copy_table_t* %33, %struct.__copy_table_t** %1
br label %5
34: ; preds = %5
store %struct.__zero_table_t* @__zero_table_start__, %struct.__zero_table_t** %3
br label %35
35: ; preds = %55, %34
%36 = load %struct.__zero_table_t*, %struct.__zero_table_t** %3
%37 = icmp ult %struct.__zero_table_t* %36, @__zero_table_end__
br i1 %37, label %38, label %58
38: ; preds = %35
store i64 0, i64* %4
br label %39
39: ; preds = %51, %38
%40 = load i64, i64* %4
%41 = load %struct.__zero_table_t*, %struct.__zero_table_t** %3
%42 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %41, i32 0, i32 1
%43 = load i64, i64* %42
%44 = icmp ult i64 %40, %43
br i1 %44, label %45, label %54
45: ; preds = %39
%46 = load %struct.__zero_table_t*, %struct.__zero_table_t** %3
%47 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %46, i32 0, i32 0
%48 = load i64*, i64** %47
%49 = load i64, i64* %4
%50 = getelementptr inbounds i64, i64* %48, i64 %49
store i64 0, i64* %50
br label %51
51: ; preds = %45
%52 = load i64, i64* %4
%53 = add i64 %52, 1
store i64 %53, i64* %4
br label %39
54: ; preds = %39
br label %55
55: ; preds = %54
%56 = load %struct.__zero_table_t*, %struct.__zero_table_t** %3
%57 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %56, i32 1
store %struct.__zero_table_t* %57, %struct.__zero_table_t** %3
br label %35
58: ; preds = %35
unreachable
}

LLVM IR (-O2):
%struct.__copy_table_t = type { i64*, i64*, i64 }
%struct.__zero_table_t = type { i64*, i64 }
@__copy_table_start__ = external constant %struct.__copy_table_t
@__copy_table_end__ = external constant %struct.__copy_table_t
@__zero_table_start__ = external constant %struct.__zero_table_t
@__zero_table_end__ = external constant %struct.__zero_table_t
define void @__cmsis_start() {
br i1 icmp ult (%struct.__copy_table_t* @__copy_table_start__, %struct.__copy_table_t* @__copy_table_end__), label %1, label %11
1: ; preds = %0, %12
%2 = phi %struct.__copy_table_t* [ %13, %12 ], [ @__copy_table_start__, %0 ]
%3 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %2, i64 0, i32 2
%4 = load i64, i64* %3
%5 = icmp eq i64 %4, 0
br i1 %5, label %12, label %6
6: ; preds = %1
%7 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %2, i64 0, i32 0
%8 = load i64*, i64** %7
%9 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %2, i64 0, i32 1
%10 = load i64*, i64** %9
br label %15
11: ; preds = %12, %0
br i1 icmp ult (%struct.__zero_table_t* @__zero_table_start__, %struct.__zero_table_t* @__zero_table_end__), label %23, label %31
12: ; preds = %15, %1
%13 = getelementptr inbounds %struct.__copy_table_t, %struct.__copy_table_t* %2, i64 1
%14 = icmp ult %struct.__copy_table_t* %13, @__copy_table_end__
br i1 %14, label %1, label %11
15: ; preds = %6, %15
%16 = phi i64 [ 0, %6 ], [ %20, %15 ]
%17 = getelementptr inbounds i64, i64* %8, i64 %16
%18 = load i64, i64* %17
%19 = getelementptr inbounds i64, i64* %10, i64 %16
store i64 %18, i64* %19
%20 = add nuw i64 %16, 1
%21 = load i64, i64* %3
%22 = icmp ult i64 %20, %21
br i1 %22, label %15, label %12
23: ; preds = %11, %32
%24 = phi %struct.__zero_table_t* [ %33, %32 ], [ @__zero_table_start__, %11 ]
%25 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %24, i64 0, i32 1
%26 = load i64, i64* %25
%27 = icmp eq i64 %26, 0
br i1 %27, label %32, label %28
28: ; preds = %23
%29 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %24, i64 0, i32 0
%30 = load i64*, i64** %29
br label %35
31: ; preds = %32, %11
tail call void @_start()
unreachable
32: ; preds = %35, %23
%33 = getelementptr inbounds %struct.__zero_table_t, %struct.__zero_table_t* %24, i64 1
%34 = icmp ult %struct.__zero_table_t* %33, @__zero_table_end__
br i1 %34, label %23, label %31
35: ; preds = %28, %35
%36 = phi i64 [ 0, %28 ], [ %38, %35 ]
%37 = getelementptr inbounds i64, i64* %30, i64 %36
store i64 0, i64* %37
%38 = add nuw i64 %36, 1
%39 = load i64, i64* %25
%40 = icmp ult i64 %38, %39
br i1 %40, label %35, label %32
}