#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;

/* Variables and functions */
void i2c_init() {
  *(volatile uint8_t *)0x5210 &= ~(1 << 0);
  *(volatile uint8_t *)0x5212 = 16;
  *(volatile uint8_t *)0x521C = 0x00;
  *(volatile uint8_t *)0x521B = 0x50;
  *(volatile uint8_t *)0x521D = 0x11;
  ;
  *(volatile uint8_t *)0x5214 |= (1 << 6);
  *(volatile uint8_t *)0x5214 &= ~(1 << 7);
  *(volatile uint8_t *)0x521A |= ((1 << 2) | (1 << 0) | (1 << 1));
  *(volatile uint8_t *)0x5210 |= (1 << 0);
}


x86 assembly (clang, -O0):
<i2c_init>:
push   %rbp
mov    %rsp,%rbp
mov    $0x5210,%eax
mov    (%rax),%ecx
and    $0xfffffffe,%ecx
mov    $0x5210,%eax
mov    %ecx,(%rax)
mov    $0x5212,%eax
movl   $0x10,(%rax)
mov    $0x521c,%eax
movl   $0x0,(%rax)
mov    $0x521b,%eax
movl   $0x50,(%rax)
mov    $0x521d,%eax
movl   $0x11,(%rax)
mov    $0x5214,%eax
mov    (%rax),%ecx
or     $0x40,%ecx
mov    $0x5214,%eax
mov    %ecx,(%rax)
mov    $0x5214,%eax
mov    (%rax),%ecx
and    $0xffffff7f,%ecx
mov    $0x5214,%eax
mov    %ecx,(%rax)
mov    $0x521a,%eax
mov    (%rax),%ecx
or     $0x7,%ecx
mov    $0x521a,%eax
mov    %ecx,(%rax)
mov    $0x5210,%eax
mov    (%rax),%ecx
or     $0x1,%ecx
mov    $0x5210,%eax
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<i2c_init>:
andl   $0xfffffffe,0x5210
fe
movl   $0x10,0x5212
movl   $0x0,0x521c
movl   $0x50,0x521b
movl   $0x11,0x521d
orl    $0x40,0x5214
40
andl   $0xffffff7f,0x5214
7f ff ff ff
orl    $0x7,0x521a
07
orl    $0x1,0x5210
01
ret

LLVM IR (-O0):
define void @i2c_init() {
%1 = load volatile i32, i32* inttoptr (i64 21008 to i32*)
%2 = and i32 %1, -2
store volatile i32 %2, i32* inttoptr (i64 21008 to i32*)
store volatile i32 16, i32* inttoptr (i64 21010 to i32*)
store volatile i32 0, i32* inttoptr (i64 21020 to i32*)
store volatile i32 80, i32* inttoptr (i64 21019 to i32*)
store volatile i32 17, i32* inttoptr (i64 21021 to i32*)
%3 = load volatile i32, i32* inttoptr (i64 21012 to i32*)
%4 = or i32 %3, 64
store volatile i32 %4, i32* inttoptr (i64 21012 to i32*)
%5 = load volatile i32, i32* inttoptr (i64 21012 to i32*)
%6 = and i32 %5, -129
store volatile i32 %6, i32* inttoptr (i64 21012 to i32*)
%7 = load volatile i32, i32* inttoptr (i64 21018 to i32*)
%8 = or i32 %7, 7
store volatile i32 %8, i32* inttoptr (i64 21018 to i32*)
%9 = load volatile i32, i32* inttoptr (i64 21008 to i32*)
%10 = or i32 %9, 1
store volatile i32 %10, i32* inttoptr (i64 21008 to i32*)
ret void
}

LLVM IR (-O2):
define void @i2c_init() {
%1 = load volatile i32, i32* inttoptr (i64 21008 to i32*)
%2 = and i32 %1, -2
store volatile i32 %2, i32* inttoptr (i64 21008 to i32*)
store volatile i32 16, i32* inttoptr (i64 21010 to i32*)
store volatile i32 0, i32* inttoptr (i64 21020 to i32*)
store volatile i32 80, i32* inttoptr (i64 21019 to i32*)
store volatile i32 17, i32* inttoptr (i64 21021 to i32*)
%3 = load volatile i32, i32* inttoptr (i64 21012 to i32*)
%4 = or i32 %3, 64
store volatile i32 %4, i32* inttoptr (i64 21012 to i32*)
%5 = load volatile i32, i32* inttoptr (i64 21012 to i32*)
%6 = and i32 %5, -129
store volatile i32 %6, i32* inttoptr (i64 21012 to i32*)
%7 = load volatile i32, i32* inttoptr (i64 21018 to i32*)
%8 = or i32 %7, 7
store volatile i32 %8, i32* inttoptr (i64 21018 to i32*)
%9 = load volatile i32, i32* inttoptr (i64 21008 to i32*)
%10 = or i32 %9, 1
store volatile i32 %10, i32* inttoptr (i64 21008 to i32*)
ret void
}