void __attribute__((always_)) arch_init_ram() {
  extern unsigned long _etext, __data_start, _edata, __bss_start, __bss_end;
  unsigned long *src, *dest, *limit;
  src = &_etext;
  dest = &__data_start;
  limit = &_edata;
  while (dest < limit)
    *dest++ = *src++;
  dest = &__bss_start;
  limit = &__bss_end;
  while (dest < limit)
    *dest++ = 0;
}


x86 assembly (clang, -O0):
<arch_init_ram>:
push   %rbp
mov    %rsp,%rbp
mov    0x2ec5(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    0x2eb2(%rip),%rax
mov    %rax,-0x10(%rbp)
mov    0x2e9f(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    115c <arch_init_ram+0x5c>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x8(%rbp)
mov    (%rax),%rcx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x10(%rbp)
mov    %rcx,(%rax)
jmp    1125 <arch_init_ram+0x25>
mov    0x2e85(%rip),%rax
mov    %rax,-0x10(%rbp)
mov    0x2e72(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    119b <arch_init_ram+0x9b>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x10(%rbp)
movq   $0x0,(%rax)
jmp    1172 <arch_init_ram+0x72>
pop    %rbp
ret

x86 assembly (clang, -O2):
<arch_init_ram>:
push   %rax
mov    0x2ea0(%rip),%rdi
cmp    0x2e91(%rip),%rdi
jae    1161 <arch_init_ram+0x41>
lea    0x8(%rdi),%rax
mov    0x2e84(%rip),%rcx
cmp    %rax,%rcx
cmova  %rcx,%rax
mov    %rdi,%rcx
not    %rcx
lea    (%rcx,%rax,1),%rdx
add    $0x8,%rdx
and    $0xfffffffffffffff8,%rdx
mov    0x2e74(%rip),%rsi
call   1040 <memcpy@plt>
mov    0x2e80(%rip),%rdi
cmp    0x2e71(%rip),%rdi
jae    119c <arch_init_ram+0x7c>
lea    0x8(%rdi),%rax
mov    0x2e64(%rip),%rcx
cmp    %rax,%rcx
cmova  %rcx,%rax
mov    %rdi,%rcx
not    %rcx
lea    (%rcx,%rax,1),%rdx
add    $0x8,%rdx
and    $0xfffffffffffffff8,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
pop    %rax
ret

LLVM IR (-O0):
@_etext = external global i64
@__data_start = external global i64
@_edata = external global i64
@__bss_start = external global i64
@__bss_end = external global i64
define void @arch_init_ram() {
%1 = alloca i64*
%2 = alloca i64*
%3 = alloca i64*
store i64* @_etext, i64** %1
store i64* @__data_start, i64** %2
store i64* @_edata, i64** %3
br label %4
4: ; preds = %8, %0
%5 = load i64*, i64** %2
%6 = load i64*, i64** %3
%7 = icmp ult i64* %5, %6
br i1 %7, label %8, label %14
8: ; preds = %4
%9 = load i64*, i64** %1
%10 = getelementptr inbounds i64, i64* %9, i32 1
store i64* %10, i64** %1
%11 = load i64, i64* %9
%12 = load i64*, i64** %2
%13 = getelementptr inbounds i64, i64* %12, i32 1
store i64* %13, i64** %2
store i64 %11, i64* %12
br label %4
14: ; preds = %4
store i64* @__bss_start, i64** %2
store i64* @__bss_end, i64** %3
br label %15
15: ; preds = %19, %14
%16 = load i64*, i64** %2
%17 = load i64*, i64** %3
%18 = icmp ult i64* %16, %17
br i1 %18, label %19, label %22
19: ; preds = %15
%20 = load i64*, i64** %2
%21 = getelementptr inbounds i64, i64* %20, i32 1
store i64* %21, i64** %2
store i64 0, i64* %20
br label %15
22: ; preds = %15
ret void
}

LLVM IR (-O2):
@_etext = external global i64
@__data_start = external global i64
@_edata = external global i64
@__bss_start = external global i64
@__bss_end = external global i64
define void @arch_init_ram() {
br i1 icmp ult (i64* @__data_start, i64* @_edata), label %1, label %5
1: ; preds = %0
%2 = call i64 @llvm.umax.i64(i64 ptrtoint (i64* @_edata to i64), i64 add (i64 ptrtoint (i64* @__data_start to i64), i64 8))
%3 = add i64 %2, add (i64 xor (i64 ptrtoint (i64* @__data_start to i64), i64 -1), i64 8)
%4 = and i64 %3, -8
br label %5
5: ; preds = %1, %0
br i1 icmp ult (i64* @__bss_start, i64* @__bss_end), label %6, label %10
6: ; preds = %5
%7 = call i64 @llvm.umax.i64(i64 ptrtoint (i64* @__bss_end to i64), i64 add (i64 ptrtoint (i64* @__bss_start to i64), i64 8))
%8 = add i64 %7, add (i64 xor (i64 ptrtoint (i64* @__bss_start to i64), i64 -1), i64 8)
%9 = and i64 %8, -8
br label %10
10: ; preds = %6, %5
ret void
}