#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 __uidiv__(int, unsigned long volatile);
void uart_init(void) {
  int pll1_clk, asic_clk, clk_div;
  (*(volatile unsigned long *)(0x0800000c)) &= ~(0x1 << 8);
  (*(volatile unsigned long *)(0x08000078)) |= (0x1 << 14);
  (*(volatile unsigned long *)(0x08000074)) |= (0x1 << 1);
  (*(volatile unsigned long *)(0x0800009c)) |= (0x1 << 25) | (0x1 << 24);
  (*(volatile unsigned long *)(0x080000d4)) |= (0x1 << 22) | (0x1 << 23);
  (*(volatile unsigned long *)(0x080000d4)) &= ~(0x1 << 11);
  (*(volatile unsigned long *)(0x080000d4)) |= (0x1 << 10);
  pll1_clk = __uidiv__(
      4 * (((*(volatile unsigned long *)(0x08000004)) & 0x3f) + 45),
      ((((*(volatile unsigned long *)(0x08000004)) >> 17) & 0xf) + 1));
  asic_clk =
      (pll1_clk >> (((*(volatile unsigned long *)(0x08000004)) >> 6) & 0x7)) *
      1000 * 1000;
  clk_div = __uidiv__(asic_clk, 115200) - 1;
  (*(volatile unsigned long *)(0x20029000 + 0x0)) =
      (0x1 << 28) | (0x1 << 29) | clk_div;
  (*(volatile unsigned long *)(0x20029000 + 0x0)) |= (0x1 << 18) | (0x1 << 19);
  (*(volatile unsigned long *)(0x20029000 + 0x0)) |= (0x1 << 21);
}


x86 assembly (clang, -O0):
<uart_init>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    $0x800000c,%eax
mov    (%rax),%rcx
and    $0xfffffffffffffeff,%rcx
mov    $0x800000c,%eax
mov    %rcx,(%rax)
mov    $0x8000078,%eax
mov    (%rax),%rcx
or     $0x4000,%rcx
mov    $0x8000078,%eax
mov    %rcx,(%rax)
mov    $0x8000074,%eax
mov    (%rax),%rcx
or     $0x2,%rcx
mov    $0x8000074,%eax
mov    %rcx,(%rax)
mov    $0x800009c,%eax
mov    (%rax),%rcx
or     $0x3000000,%rcx
mov    $0x800009c,%eax
mov    %rcx,(%rax)
mov    $0x80000d4,%eax
mov    (%rax),%rcx
or     $0xc00000,%rcx
mov    $0x80000d4,%eax
mov    %rcx,(%rax)
mov    $0x80000d4,%eax
mov    (%rax),%rcx
and    $0xfffffffffffff7ff,%rcx
mov    $0x80000d4,%eax
mov    %rcx,(%rax)
mov    $0x80000d4,%eax
mov    (%rax),%rcx
or     $0x400,%rcx
mov    $0x80000d4,%eax
mov    %rcx,(%rax)
mov    $0x8000004,%eax
mov    (%rax),%rax
and    $0x3f,%rax
add    $0x2d,%rax
shl    $0x2,%rax
mov    %eax,%edi
mov    $0x8000004,%eax
mov    (%rax),%rsi
shr    $0x11,%rsi
and    $0xf,%rsi
add    $0x1,%rsi
call   1030 <__uidiv__@plt>
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    $0x8000004,%ecx
mov    (%rcx),%rcx
shr    $0x6,%rcx
and    $0x7,%rcx
sar    %cl,%eax
imul   $0x3e8,%eax,%eax
imul   $0x3e8,%eax,%eax
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%edi
mov    $0x1c200,%esi
call   1030 <__uidiv__@plt>
sub    $0x1,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
or     $0x30000000,%eax
movslq %eax,%rcx
mov    $0x20029000,%eax
mov    %rcx,(%rax)
mov    $0x20029000,%eax
mov    (%rax),%rcx
or     $0xc0000,%rcx
mov    $0x20029000,%eax
mov    %rcx,(%rax)
mov    $0x20029000,%eax
mov    (%rax),%rcx
or     $0x200000,%rcx
mov    $0x20029000,%eax
mov    %rcx,(%rax)
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<uart_init>:
push   %rax
andq   $0xfffffffffffffeff,0x800000c
08 ff fe ff ff
orq    $0x4000,0x8000078
orq    $0x2,0x8000074
08 02
orq    $0x3000000,0x800009c
orq    $0xc00000,0x80000d4
andq   $0xfffffffffffff7ff,0x80000d4
08 ff f7 ff ff
orq    $0x400,0x80000d4
mov    0x8000004,%rax
08
and    $0x3f,%eax
lea    0xb4(,%rax,4),%edi
mov    0x8000004,%rsi
08
shr    $0x11,%esi
and    $0xf,%esi
add    $0x1,%rsi
call   1030 <__uidiv__@plt>
mov    0x8000004,%rcx
08
shr    $0x6,%ecx
and    $0x7,%cl
sar    %cl,%eax
imul   $0xf4240,%eax,%edi
mov    $0x1c200,%esi
call   1030 <__uidiv__@plt>
add    $0xffffffff,%eax
or     $0x30000000,%eax
cltq
mov    %rax,0x20029000
20
orq    $0xc0000,0x20029000
orq    $0x200000,0x20029000
pop    %rax
ret

LLVM IR (-O0):
define void @uart_init() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = load volatile i64, i64* inttoptr (i64 134217740 to i64*)
%5 = and i64 %4, -257
store volatile i64 %5, i64* inttoptr (i64 134217740 to i64*)
%6 = load volatile i64, i64* inttoptr (i64 134217848 to i64*)
%7 = or i64 %6, 16384
store volatile i64 %7, i64* inttoptr (i64 134217848 to i64*)
%8 = load volatile i64, i64* inttoptr (i64 134217844 to i64*)
%9 = or i64 %8, 2
store volatile i64 %9, i64* inttoptr (i64 134217844 to i64*)
%10 = load volatile i64, i64* inttoptr (i64 134217884 to i64*)
%11 = or i64 %10, 50331648
store volatile i64 %11, i64* inttoptr (i64 134217884 to i64*)
%12 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%13 = or i64 %12, 12582912
store volatile i64 %13, i64* inttoptr (i64 134217940 to i64*)
%14 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%15 = and i64 %14, -2049
store volatile i64 %15, i64* inttoptr (i64 134217940 to i64*)
%16 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%17 = or i64 %16, 1024
store volatile i64 %17, i64* inttoptr (i64 134217940 to i64*)
%18 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%19 = and i64 %18, 63
%20 = add i64 %19, 45
%21 = mul i64 4, %20
%22 = trunc i64 %21 to i32
%23 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%24 = lshr i64 %23, 17
%25 = and i64 %24, 15
%26 = add i64 %25, 1
%27 = call i32 @__uidiv__(i32 %22, i64 %26)
store i32 %27, i32* %1
%28 = load i32, i32* %1
%29 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%30 = lshr i64 %29, 6
%31 = and i64 %30, 7
%32 = trunc i64 %31 to i32
%33 = ashr i32 %28, %32
%34 = mul nsw i32 %33, 1000
%35 = mul nsw i32 %34, 1000
store i32 %35, i32* %2
%36 = load i32, i32* %2
%37 = call i32 @__uidiv__(i32 %36, i64 115200)
%38 = sub nsw i32 %37, 1
store i32 %38, i32* %3
%39 = load i32, i32* %3
%40 = or i32 805306368, %39
%41 = sext i32 %40 to i64
store volatile i64 %41, i64* inttoptr (i64 537038848 to i64*)
%42 = load volatile i64, i64* inttoptr (i64 537038848 to i64*)
%43 = or i64 %42, 786432
store volatile i64 %43, i64* inttoptr (i64 537038848 to i64*)
%44 = load volatile i64, i64* inttoptr (i64 537038848 to i64*)
%45 = or i64 %44, 2097152
store volatile i64 %45, i64* inttoptr (i64 537038848 to i64*)
ret void
}

LLVM IR (-O2):
define void @uart_init() {
%1 = load volatile i64, i64* inttoptr (i64 134217740 to i64*)
%2 = and i64 %1, -257
store volatile i64 %2, i64* inttoptr (i64 134217740 to i64*)
%3 = load volatile i64, i64* inttoptr (i64 134217848 to i64*)
%4 = or i64 %3, 16384
store volatile i64 %4, i64* inttoptr (i64 134217848 to i64*)
%5 = load volatile i64, i64* inttoptr (i64 134217844 to i64*)
%6 = or i64 %5, 2
store volatile i64 %6, i64* inttoptr (i64 134217844 to i64*)
%7 = load volatile i64, i64* inttoptr (i64 134217884 to i64*)
%8 = or i64 %7, 50331648
store volatile i64 %8, i64* inttoptr (i64 134217884 to i64*)
%9 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%10 = or i64 %9, 12582912
store volatile i64 %10, i64* inttoptr (i64 134217940 to i64*)
%11 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%12 = and i64 %11, -2049
store volatile i64 %12, i64* inttoptr (i64 134217940 to i64*)
%13 = load volatile i64, i64* inttoptr (i64 134217940 to i64*)
%14 = or i64 %13, 1024
store volatile i64 %14, i64* inttoptr (i64 134217940 to i64*)
%15 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%16 = trunc i64 %15 to i32
%17 = shl i32 %16, 2
%18 = and i32 %17, 252
%19 = add nuw nsw i32 %18, 180
%20 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%21 = lshr i64 %20, 17
%22 = and i64 %21, 15
%23 = add nuw nsw i64 %22, 1
%24 = tail call i32 @__uidiv__(i32 %19, i64 %23)
%25 = load volatile i64, i64* inttoptr (i64 134217732 to i64*)
%26 = trunc i64 %25 to i32
%27 = lshr i32 %26, 6
%28 = and i32 %27, 7
%29 = ashr i32 %24, %28
%30 = mul i32 %29, 1000000
%31 = tail call i32 @__uidiv__(i32 %30, i64 115200)
%32 = add nsw i32 %31, -1
%33 = or i32 %32, 805306368
%34 = sext i32 %33 to i64
store volatile i64 %34, i64* inttoptr (i64 537038848 to i64*)
%35 = load volatile i64, i64* inttoptr (i64 537038848 to i64*)
%36 = or i64 %35, 786432
store volatile i64 %36, i64* inttoptr (i64 537038848 to i64*)
%37 = load volatile i64, i64* inttoptr (i64 537038848 to i64*)
%38 = or i64 %37, 2097152
store volatile i64 %38, i64* inttoptr (i64 537038848 to i64*)
ret void
}