#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 */
void putc(char c) {
  unsigned long base;
  if ((*(volatile unsigned long *)(0x100a00 + 0x14)) & (1 << 0))
    base = 0x100a00;
  else if ((*(volatile unsigned long *)(0x100a80 + 0x14)) & (1 << 0))
    base = 0x100a80;
  else
    return;
  while ((*(volatile unsigned long *)(base + 0x18)) & (1 << 5))
    ;
  (*(volatile unsigned long *)(base + 0x0)) = c;
}


x86 assembly (clang, -O0):
<putc>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x1(%rbp)
mov    $0x100a14,%eax
mov    (%rax),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     112d <putc+0x2d>
movq   $0x100a00,-0x10(%rbp)
jmp    115a <putc+0x5a>
mov    $0x100a94,%eax
mov    (%rax),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     1150 <putc+0x50>
movq   $0x100a80,-0x10(%rbp)
jmp    1155 <putc+0x55>
jmp    1186 <putc+0x86>
jmp    115a <putc+0x5a>
jmp    115f <putc+0x5f>
mov    -0x10(%rbp),%rax
mov    0x18(%rax),%rax
and    $0x20,%rax
cmp    $0x0,%rax
je     117a <putc+0x7a>
jmp    115f <putc+0x5f>
movsbq -0x1(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<putc>:
mov    0x100a14,%rcx
mov    $0x100a00,%eax
test   $0x1,%cl
jne    1125 <putc+0x25>
mov    $0x100a80,%eax
testq  $0x1,0x100a94
je     1140 <putc+0x40>
mov    %rax,%rcx
or     $0x18,%rcx
nopl   0x0(%rax)
testq  $0x20,(%rcx)
jne    1130 <putc+0x30>
movsbq %dil,%rcx
mov    %rcx,(%rax)
ret

LLVM IR (-O0):
define void @putc(i8 signext %0) {
%2 = alloca i8
%3 = alloca i64
store i8 %0, i8* %2
%4 = load volatile i64, i64* inttoptr (i64 1051156 to i64*)
%5 = and i64 %4, 1
%6 = icmp ne i64 %5, 0
br i1 %6, label %7, label %8
7: ; preds = %1
store i64 1051136, i64* %3
br label %15
8: ; preds = %1
%9 = load volatile i64, i64* inttoptr (i64 1051284 to i64*)
%10 = and i64 %9, 1
%11 = icmp ne i64 %10, 0
br i1 %11, label %12, label %13
12: ; preds = %8
store i64 1051264, i64* %3
br label %14
13: ; preds = %8
br label %30
14: ; preds = %12
br label %15
15: ; preds = %14, %7
br label %16
16: ; preds = %23, %15
%17 = load i64, i64* %3
%18 = add i64 %17, 24
%19 = inttoptr i64 %18 to i64*
%20 = load volatile i64, i64* %19
%21 = and i64 %20, 32
%22 = icmp ne i64 %21, 0
br i1 %22, label %23, label %24
23: ; preds = %16
br label %16
24: ; preds = %16
%25 = load i8, i8* %2
%26 = sext i8 %25 to i64
%27 = load i64, i64* %3
%28 = add i64 %27, 0
%29 = inttoptr i64 %28 to i64*
store volatile i64 %26, i64* %29
br label %30
30: ; preds = %24, %13
ret void
}

LLVM IR (-O2):
define void @putc(i8 signext %0) {
%2 = load volatile i64, i64* inttoptr (i64 1051156 to i64*)
%3 = and i64 %2, 1
%4 = icmp eq i64 %3, 0
br i1 %4, label %5, label %9
5: ; preds = %1
%6 = load volatile i64, i64* inttoptr (i64 1051284 to i64*)
%7 = and i64 %6, 1
%8 = icmp eq i64 %7, 0
br i1 %8, label %20, label %9
9: ; preds = %5, %1
%10 = phi i64 [ 1051136, %1 ], [ 1051264, %5 ]
%11 = or i64 %10, 24
%12 = inttoptr i64 %11 to i64*
br label %13
13: ; preds = %13, %9
%14 = load volatile i64, i64* %12
%15 = and i64 %14, 32
%16 = icmp eq i64 %15, 0
br i1 %16, label %17, label %13
17: ; preds = %13
%18 = sext i8 %0 to i64
%19 = inttoptr i64 %10 to i64*
store volatile i64 %18, i64* %19
br label %20
20: ; preds = %5, %17
ret void
}