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

/* Variables and functions */
int /*<<< orphan*/ put_char(int);
int /*<<< orphan*/ put_word(unsigned int);
void detect_dram(void) {
  volatile unsigned *p;
  (*(volatile unsigned long *)(0x80000000 + (0x1100))) &= ~0x00000004;
  p = (unsigned *)((unsigned *)0xc0000000);
  p[0] = 0x12345678;
  p[1] = 0;
  if (p[0] != 0x12345678) {
    (*(volatile unsigned long *)(0x80000000 + (0x1100))) |= 0x00000004;
    put_char(16);
  } else {
    put_char(32);
  }
  put_word((256 * 1024));
  p = ((unsigned *)0xe0000000);
  while (p > ((unsigned *)0xc0000000)) {
    p -= ((256 * 1024) / 4);
    *p = (unsigned)p;
  }
  while (p < ((unsigned *)0xe0000000)) {
    if (*p == (unsigned)p) {
      put_word((unsigned)p);
    }
    p += ((256 * 1024) / 4);
  }
  put_word(0);
}


x86 assembly (clang, -O0):
<detect_dram>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    $0x80001100,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffffb,%rcx
mov    $0x80001100,%eax
mov    %rcx,(%rax)
mov    $0xc0000000,%eax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
movl   $0x12345678,(%rax)
mov    -0x8(%rbp),%rax
movl   $0x0,0x4(%rax)
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
cmp    $0x12345678,%eax
je     118e <detect_dram+0x6e>
mov    $0x80001100,%eax
mov    (%rax),%rcx
or     $0x4,%rcx
mov    $0x80001100,%eax
mov    %rcx,(%rax)
mov    $0x10,%edi
call   1030 <put_char@plt>
jmp    1198 <detect_dram+0x78>
mov    $0x20,%edi
call   1030 <put_char@plt>
mov    $0x40000,%edi
call   1040 <put_word@plt>
mov    $0xe0000000,%eax
mov    %rax,-0x8(%rbp)
mov    $0xc0000000,%eax
cmp    %rax,-0x8(%rbp)
jbe    11d9 <detect_dram+0xb9>
mov    -0x8(%rbp),%rax
add    $0xfffffffffffc0000,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %eax,%ecx
mov    -0x8(%rbp),%rax
mov    %ecx,(%rax)
jmp    11ab <detect_dram+0x8b>
jmp    11de <detect_dram+0xbe>
mov    $0xe0000000,%eax
cmp    %rax,-0x8(%rbp)
jae    121d <detect_dram+0xfd>
mov    -0x8(%rbp),%rax
mov    (%rax),%eax
mov    -0x8(%rbp),%rcx
cmp    %ecx,%eax
jne    120a <detect_dram+0xea>
mov    -0x8(%rbp),%rax
mov    %eax,%edi
call   1040 <put_word@plt>
mov    -0x8(%rbp),%rax
add    $0x40000,%rax
mov    %rax,-0x8(%rbp)
jmp    11de <detect_dram+0xbe>
xor    %edi,%edi
call   1040 <put_word@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<detect_dram>:
push   %r15
push   %r14
push   %rbx
mov    $0xe0000000,%r14d
andq   $0xfffffffffffffffb,-0x5fffef00(%r14)
fb
movl   $0x12345678,-0x20000000(%r14)
78 56 34 12
movl   $0x0,-0x1ffffffc(%r14)
mov    -0x20000000(%r14),%eax
mov    $0x20,%edi
cmp    $0x12345678,%eax
je     1169 <detect_dram+0x49>
orq    $0x4,-0x5fffef00(%r14)
04
mov    $0x10,%edi
call   1030 <put_char@plt>
mov    $0x40000,%edi
call   1040 <put_word@plt>
xor    %ebx,%ebx
lea    -0x20000000(%r14),%rax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    (%r14,%rbx,1),%ecx
add    $0xfffc0000,%ecx
mov    %ecx,-0x40000(%r14,%rbx,1)
ff
lea    (%r14,%rbx,1),%rcx
add    $0xfffffffffffc0000,%rcx
add    $0xfffffffffffc0000,%rbx
cmp    %rax,%rcx
ja     1190 <detect_dram+0x70>
lea    (%r14,%rbx,1),%r15
cmp    %r14,%r15
jae    11f0 <detect_dram+0xd0>
add    $0xffffffffe0000000,%rbx
jmp    11e2 <detect_dram+0xc2>
nopl   0x0(%rax,%rax,1)
add    $0x40000,%r15
add    $0x40000,%ebx
cmp    %r14,%r15
jae    11f0 <detect_dram+0xd0>
mov    (%r15),%edi
cmp    %edi,%ebx
jne    11d0 <detect_dram+0xb0>
call   1040 <put_word@plt>
jmp    11d0 <detect_dram+0xb0>
xor    %edi,%edi
pop    %rbx
pop    %r14
pop    %r15
jmp    1040 <put_word@plt>

LLVM IR (-O0):
define void @detect_dram() {
%1 = alloca i32*
%2 = load volatile i64, i64* inttoptr (i64 2147488000 to i64*)
%3 = and i64 %2, -5
store volatile i64 %3, i64* inttoptr (i64 2147488000 to i64*)
store i32* inttoptr (i64 3221225472 to i32*), i32** %1
%4 = load i32*, i32** %1
%5 = getelementptr inbounds i32, i32* %4, i64 0
store volatile i32 305419896, i32* %5
%6 = load i32*, i32** %1
%7 = getelementptr inbounds i32, i32* %6, i64 1
store volatile i32 0, i32* %7
%8 = load i32*, i32** %1
%9 = getelementptr inbounds i32, i32* %8, i64 0
%10 = load volatile i32, i32* %9
%11 = icmp ne i32 %10, 305419896
br i1 %11, label %12, label %16
12: ; preds = %0
%13 = load volatile i64, i64* inttoptr (i64 2147488000 to i64*)
%14 = or i64 %13, 4
store volatile i64 %14, i64* inttoptr (i64 2147488000 to i64*)
%15 = call i32 @put_char(i32 16)
br label %18
16: ; preds = %0
%17 = call i32 @put_char(i32 32)
br label %18
18: ; preds = %16, %12
%19 = call i32 @put_word(i32 262144)
store i32* inttoptr (i64 3758096384 to i32*), i32** %1
br label %20
20: ; preds = %23, %18
%21 = load i32*, i32** %1
%22 = icmp ugt i32* %21, inttoptr (i64 3221225472 to i32*)
br i1 %22, label %23, label %29
23: ; preds = %20
%24 = load i32*, i32** %1
%25 = getelementptr inbounds i32, i32* %24, i64 -65536
store i32* %25, i32** %1
%26 = load i32*, i32** %1
%27 = ptrtoint i32* %26 to i32
%28 = load i32*, i32** %1
store volatile i32 %27, i32* %28
br label %20
29: ; preds = %20
br label %30
30: ; preds = %43, %29
%31 = load i32*, i32** %1
%32 = icmp ult i32* %31, inttoptr (i64 3758096384 to i32*)
br i1 %32, label %33, label %46
33: ; preds = %30
%34 = load i32*, i32** %1
%35 = load volatile i32, i32* %34
%36 = load i32*, i32** %1
%37 = ptrtoint i32* %36 to i32
%38 = icmp eq i32 %35, %37
br i1 %38, label %39, label %43
39: ; preds = %33
%40 = load i32*, i32** %1
%41 = ptrtoint i32* %40 to i32
%42 = call i32 @put_word(i32 %41)
br label %43
43: ; preds = %39, %33
%44 = load i32*, i32** %1
%45 = getelementptr inbounds i32, i32* %44, i64 65536
store i32* %45, i32** %1
br label %30
46: ; preds = %30
%47 = call i32 @put_word(i32 0)
ret void
}

LLVM IR (-O2):
define void @detect_dram() {
%1 = load volatile i64, i64* inttoptr (i64 2147488000 to i64*)
%2 = and i64 %1, -5
store volatile i64 %2, i64* inttoptr (i64 2147488000 to i64*)
store volatile i32 305419896, i32* inttoptr (i64 3221225472 to i32*)
store volatile i32 0, i32* inttoptr (i64 3221225476 to i32*)
%3 = load volatile i32, i32* inttoptr (i64 3221225472 to i32*)
%4 = icmp eq i32 %3, 305419896
br i1 %4, label %8, label %5
5: ; preds = %0
%6 = load volatile i64, i64* inttoptr (i64 2147488000 to i64*)
%7 = or i64 %6, 4
store volatile i64 %7, i64* inttoptr (i64 2147488000 to i64*)
br label %8
8: ; preds = %0, %5
%9 = phi i32 [ 16, %5 ], [ 32, %0 ]
%10 = tail call i32 @put_char(i32 %9)
%11 = tail call i32 @put_word(i32 262144)
br label %14
12: ; preds = %14
%13 = icmp ult i32* %16, inttoptr (i64 3758096384 to i32*)
br i1 %13, label %20, label %31
14: ; preds = %8, %14
%15 = phi i32* [ inttoptr (i64 3758096384 to i32*), %8 ], [ %16, %14 ]
%16 = getelementptr inbounds i32, i32* %15, i64 -65536
%17 = ptrtoint i32* %16 to i64
%18 = trunc i64 %17 to i32
store volatile i32 %18, i32* %16
%19 = icmp ugt i32* %16, inttoptr (i64 3221225472 to i32*)
br i1 %19, label %14, label %12
20: ; preds = %12, %28
%21 = phi i32* [ %29, %28 ], [ %16, %12 ]
%22 = load volatile i32, i32* %21
%23 = ptrtoint i32* %21 to i64
%24 = trunc i64 %23 to i32
%25 = icmp eq i32 %22, %24
br i1 %25, label %26, label %28
26: ; preds = %20
%27 = tail call i32 @put_word(i32 %22)
br label %28
28: ; preds = %26, %20
%29 = getelementptr inbounds i32, i32* %21, i64 65536
%30 = icmp ult i32* %29, inttoptr (i64 3758096384 to i32*)
br i1 %30, label %20, label %31
31: ; preds = %28, %12
%32 = tail call i32 @put_word(i32 0)
ret void
}