void main() {
  unsigned long dat;
  (*(volatile unsigned long *)0xE0200280) =
      (1 << (0 * 4)) | (1 << (1 * 4)) | (1 << (2 * 4)) | (1 << (3 * 4));
  (*(volatile unsigned long *)0xE0200C40) =
      ~(0xf << (0 * 4)) & ~(0xf << (1 * 4)) & ~(0xf << (2 * 4)) &
      ~(0xf << (3 * 4));
  while (1) {
    dat = (*(volatile unsigned long *)0xE0200C44);
    if (dat & (1 << 0))
      (*(volatile unsigned long *)0xE0200284) |= 1 << 0;
    else
      (*(volatile unsigned long *)0xE0200284) &= ~(1 << 0);
    if (dat & (1 << 1))
      (*(volatile unsigned long *)0xE0200284) |= 1 << 1;
    else
      (*(volatile unsigned long *)0xE0200284) &= ~(1 << 1);
    if (dat & (1 << 2))
      (*(volatile unsigned long *)0xE0200284) |= (1 << 2);
    else
      (*(volatile unsigned long *)0xE0200284) &= ~(1 << 2);
    if (dat & (1 << 3))
      (*(volatile unsigned long *)0xE0200284) |= 1 << 3;
    else
      (*(volatile unsigned long *)0xE0200284) &= ~(1 << 3);
  }
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
mov    $0xe0200280,%eax
movq   $0x1111,(%rax)
mov    $0xe0200c40,%eax
movq   $0xffffffffffff0000,(%rax)
mov    $0xe0200c44,%eax
mov    (%rax),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     1153 <main+0x53>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
or     $0x1,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
jmp    1167 <main+0x67>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffffe,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
and    $0x2,%rax
cmp    $0x0,%rax
je     1192 <main+0x92>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
or     $0x2,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
jmp    11a6 <main+0xa6>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffffd,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     11d1 <main+0xd1>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
or     $0x4,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
jmp    11e5 <main+0xe5>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffffb,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     1210 <main+0x110>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
or     $0x8,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
jmp    1224 <main+0x124>
mov    $0xe0200284,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffff7,%rcx
mov    $0xe0200284,%eax
mov    %rcx,(%rax)
jmp    111c <main+0x1c>

x86 assembly (clang, -O2):
<main>:
mov    $0xe0200284,%eax
movq   $0x1111,-0x4(%rax)
movq   $0xffffffffffff0000,0x9bc(%rax)
nopl   0x0(%rax,%rax,1)
mov    0x9c0(%rax),%rcx
mov    %ecx,%edx
and    $0x1,%edx
mov    (%rax),%rsi
and    $0xfffffffffffffffe,%rsi
or     %rdx,%rsi
mov    %rsi,(%rax)
mov    %ecx,%edx
and    $0x2,%edx
mov    (%rax),%rsi
and    $0xfffffffffffffffd,%rsi
or     %rdx,%rsi
mov    %rsi,(%rax)
mov    %ecx,%edx
and    $0x4,%edx
mov    (%rax),%rsi
and    $0xfffffffffffffffb,%rsi
or     %rdx,%rsi
mov    %rsi,(%rax)
and    $0x8,%ecx
mov    (%rax),%rdx
and    $0xfffffffffffffff7,%rdx
or     %rcx,%rdx
mov    %rdx,(%rax)
jmp    1120 <main+0x20>

LLVM IR (-O0):
define void @main() {
%1 = alloca i64
store volatile i64 4369, i64* inttoptr (i64 3760194176 to i64*)
store volatile i64 -65536, i64* inttoptr (i64 3760196672 to i64*)
br label %2
2: ; preds = %0, %43
%3 = load volatile i64, i64* inttoptr (i64 3760196676 to i64*)
store i64 %3, i64* %1
%4 = load i64, i64* %1
%5 = and i64 %4, 1
%6 = icmp ne i64 %5, 0
br i1 %6, label %7, label %10
7: ; preds = %2
%8 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%9 = or i64 %8, 1
store volatile i64 %9, i64* inttoptr (i64 3760194180 to i64*)
br label %13
10: ; preds = %2
%11 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%12 = and i64 %11, -2
store volatile i64 %12, i64* inttoptr (i64 3760194180 to i64*)
br label %13
13: ; preds = %10, %7
%14 = load i64, i64* %1
%15 = and i64 %14, 2
%16 = icmp ne i64 %15, 0
br i1 %16, label %17, label %20
17: ; preds = %13
%18 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%19 = or i64 %18, 2
store volatile i64 %19, i64* inttoptr (i64 3760194180 to i64*)
br label %23
20: ; preds = %13
%21 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%22 = and i64 %21, -3
store volatile i64 %22, i64* inttoptr (i64 3760194180 to i64*)
br label %23
23: ; preds = %20, %17
%24 = load i64, i64* %1
%25 = and i64 %24, 4
%26 = icmp ne i64 %25, 0
br i1 %26, label %27, label %30
27: ; preds = %23
%28 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%29 = or i64 %28, 4
store volatile i64 %29, i64* inttoptr (i64 3760194180 to i64*)
br label %33
30: ; preds = %23
%31 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%32 = and i64 %31, -5
store volatile i64 %32, i64* inttoptr (i64 3760194180 to i64*)
br label %33
33: ; preds = %30, %27
%34 = load i64, i64* %1
%35 = and i64 %34, 8
%36 = icmp ne i64 %35, 0
br i1 %36, label %37, label %40
37: ; preds = %33
%38 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%39 = or i64 %38, 8
store volatile i64 %39, i64* inttoptr (i64 3760194180 to i64*)
br label %43
40: ; preds = %33
%41 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%42 = and i64 %41, -9
store volatile i64 %42, i64* inttoptr (i64 3760194180 to i64*)
br label %43
43: ; preds = %40, %37
br label %2
}

LLVM IR (-O2):
define void @main() {
store volatile i64 4369, i64* inttoptr (i64 3760194176 to i64*)
store volatile i64 -65536, i64* inttoptr (i64 3760196672 to i64*)
br label %1
1: ; preds = %1, %0
%2 = load volatile i64, i64* inttoptr (i64 3760196676 to i64*)
%3 = and i64 %2, 1
%4 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%5 = and i64 %4, -2
%6 = or i64 %5, %3
store volatile i64 %6, i64* inttoptr (i64 3760194180 to i64*)
%7 = and i64 %2, 2
%8 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%9 = and i64 %8, -3
%10 = or i64 %9, %7
store volatile i64 %10, i64* inttoptr (i64 3760194180 to i64*)
%11 = and i64 %2, 4
%12 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%13 = and i64 %12, -5
%14 = or i64 %13, %11
store volatile i64 %14, i64* inttoptr (i64 3760194180 to i64*)
%15 = and i64 %2, 8
%16 = load volatile i64, i64* inttoptr (i64 3760194180 to i64*)
%17 = and i64 %16, -9
%18 = or i64 %17, %15
store volatile i64 %18, i64* inttoptr (i64 3760194180 to i64*)
br label %1
}