#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 uint8_t;
typedef int uint32_t;

/* Variables and functions */
uint8_t writedata(uint8_t c) {
  while (((*((volatile uint32_t *)0x4000A00C)) & 0x00000010) == 0x00000010) {
  };
  (*((volatile uint32_t *)0x40004040)) = 0x00;
  (*((volatile uint32_t *)0x40025040)) = 0x10;
  (*((volatile uint32_t *)0x4000A008)) = c;
  while (((*((volatile uint32_t *)0x4000A00C)) & 0x00000004) == 0) {
  };
  (*((volatile uint32_t *)0x40004040)) = 0x10;
  return (uint8_t)(*((volatile uint32_t *)0x4000A008));
}


x86 assembly (clang, -O0):
<writedata>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    $0x4000a00c,%eax
mov    (%rax),%eax
and    $0x10,%eax
cmp    $0x10,%eax
jne    111f <writedata+0x1f>
jmp    1107 <writedata+0x7>
mov    $0x40004040,%eax
movl   $0x0,(%rax)
mov    $0x40025040,%eax
movl   $0x10,(%rax)
mov    -0x4(%rbp),%ecx
mov    $0x4000a008,%eax
mov    %ecx,(%rax)
mov    $0x4000a00c,%eax
mov    (%rax),%eax
and    $0x4,%eax
cmp    $0x0,%eax
jne    1157 <writedata+0x57>
jmp    113f <writedata+0x3f>
mov    $0x40004040,%eax
movl   $0x10,(%rax)
mov    $0x4000a008,%eax
mov    (%rax),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<writedata>:
testl  $0x10,0x4000a00c
jne    1100 <writedata>
movl   $0x0,0x40004040
movl   $0x10,0x40025040
mov    %edi,0x4000a008
nopw   0x0(%rax,%rax,1)
testl  $0x4,0x4000a00c
je     1130 <writedata+0x30>
movl   $0x10,0x40004040
mov    0x4000a008,%eax
ret

LLVM IR (-O0):
define i32 @writedata(i32 %0) {
%2 = alloca i32
store i32 %0, i32* %2
br label %3
3: ; preds = %7, %1
%4 = load volatile i32, i32* inttoptr (i64 1073782796 to i32*)
%5 = and i32 %4, 16
%6 = icmp eq i32 %5, 16
br i1 %6, label %7, label %8
7: ; preds = %3
br label %3
8: ; preds = %3
store volatile i32 0, i32* inttoptr (i64 1073758272 to i32*)
store volatile i32 16, i32* inttoptr (i64 1073893440 to i32*)
%9 = load i32, i32* %2
store volatile i32 %9, i32* inttoptr (i64 1073782792 to i32*)
br label %10
10: ; preds = %14, %8
%11 = load volatile i32, i32* inttoptr (i64 1073782796 to i32*)
%12 = and i32 %11, 4
%13 = icmp eq i32 %12, 0
br i1 %13, label %14, label %15
14: ; preds = %10
br label %10
15: ; preds = %10
store volatile i32 16, i32* inttoptr (i64 1073758272 to i32*)
%16 = load volatile i32, i32* inttoptr (i64 1073782792 to i32*)
ret i32 %16
}

LLVM IR (-O2):
define i32 @writedata(i32 %0) {
br label %2
2: ; preds = %2, %1
%3 = load volatile i32, i32* inttoptr (i64 1073782796 to i32*)
%4 = and i32 %3, 16
%5 = icmp eq i32 %4, 0
br i1 %5, label %6, label %2
6: ; preds = %2
store volatile i32 0, i32* inttoptr (i64 1073758272 to i32*)
store volatile i32 16, i32* inttoptr (i64 1073893440 to i32*)
store volatile i32 %0, i32* inttoptr (i64 1073782792 to i32*)
br label %7
7: ; preds = %7, %6
%8 = load volatile i32, i32* inttoptr (i64 1073782796 to i32*)
%9 = and i32 %8, 4
%10 = icmp eq i32 %9, 0
br i1 %10, label %7, label %11
11: ; preds = %7
store volatile i32 16, i32* inttoptr (i64 1073758272 to i32*)
%12 = load volatile i32, i32* inttoptr (i64 1073782792 to i32*)
ret i32 %12
}