void initUart0(unsigned short div_factor, unsigned char mode,
               unsigned char fifo_mode) {
  volatile unsigned int dummy;
  (*((volatile unsigned long *)0xE002C000)) =
      ((*((volatile unsigned long *)0xE002C000)) & 0xfffffff0) | 0x00000005;
  (*((volatile unsigned long *)0xE000C004)) = 0x00;
  dummy = (*((volatile unsigned long *)0xE000C008));
  dummy = (*((volatile unsigned long *)0xE000C000));
  dummy = (*((volatile unsigned long *)0xE000C014));
  (*((volatile unsigned long *)0xE000C00C)) = 0x80;
  (*((volatile unsigned long *)0xE000C000)) = (unsigned char)div_factor;
  (*((volatile unsigned long *)0xE000C004)) = (unsigned char)(div_factor >> 8);
  (*((volatile unsigned long *)0xE000C00C)) = (mode & ~0x80);
  (*((volatile unsigned long *)0xE000C008)) = fifo_mode;
}


x86 assembly (clang, -O0):
<initUart0>:
push   %rbp
mov    %rsp,%rbp
mov    %dl,%al
mov    %sil,%cl
mov    %di,%dx
mov    %dx,-0x2(%rbp)
mov    %cl,-0x3(%rbp)
mov    %al,-0x4(%rbp)
mov    $0xe002c000,%eax
mov    (%rax),%rcx
movabs $0xfffffff0,%rax
and    %rax,%rcx
or     $0x5,%rcx
mov    $0xe002c000,%eax
mov    %rcx,(%rax)
mov    $0xe000c004,%eax
movq   $0x0,(%rax)
mov    $0xe000c008,%eax
mov    (%rax),%rax
mov    %eax,-0x8(%rbp)
mov    $0xe000c000,%eax
mov    (%rax),%rax
mov    %eax,-0x8(%rbp)
mov    $0xe000c014,%eax
mov    (%rax),%rax
mov    %eax,-0x8(%rbp)
mov    $0xe000c00c,%eax
movq   $0x80,(%rax)
mov    -0x2(%rbp),%ax
movzbl %al,%eax
mov    %eax,%ecx
mov    $0xe000c000,%eax
mov    %rcx,(%rax)
movzwl -0x2(%rbp),%eax
sar    $0x8,%eax
movzbl %al,%eax
mov    %eax,%ecx
mov    $0xe000c004,%eax
mov    %rcx,(%rax)
movzbl -0x3(%rbp),%eax
and    $0xffffff7f,%eax
movslq %eax,%rcx
mov    $0xe000c00c,%eax
mov    %rcx,(%rax)
movzbl -0x4(%rbp),%eax
mov    %eax,%ecx
mov    $0xe000c008,%eax
mov    %rcx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<initUart0>:
mov    $0xe000c000,%eax
mov    0x20000(%rax),%rcx
and    $0xfffffff0,%ecx
or     $0x5,%rcx
mov    %rcx,0x20000(%rax)
movq   $0x0,0x4(%rax)
mov    0x8(%rax),%rcx
mov    %ecx,-0x4(%rsp)
mov    (%rax),%rcx
mov    %ecx,-0x4(%rsp)
mov    0x14(%rax),%rcx
mov    %ecx,-0x4(%rsp)
movq   $0x80,0xc(%rax)
movzbl %dil,%ecx
mov    %rcx,(%rax)
shr    $0x8,%edi
mov    %rdi,0x4(%rax)
and    $0x7f,%esi
mov    %rsi,0xc(%rax)
mov    %edx,%ecx
mov    %rcx,0x8(%rax)
ret

LLVM IR (-O0):
define void @initUart0(i16 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = alloca i16
%5 = alloca i8
%6 = alloca i8
%7 = alloca i32
store i16 %0, i16* %4
store i8 %1, i8* %5
store i8 %2, i8* %6
%8 = load volatile i64, i64* inttoptr (i64 3758276608 to i64*)
%9 = and i64 %8, 4294967280
%10 = or i64 %9, 5
store volatile i64 %10, i64* inttoptr (i64 3758276608 to i64*)
store volatile i64 0, i64* inttoptr (i64 3758145540 to i64*)
%11 = load volatile i64, i64* inttoptr (i64 3758145544 to i64*)
%12 = trunc i64 %11 to i32
store volatile i32 %12, i32* %7
%13 = load volatile i64, i64* inttoptr (i64 3758145536 to i64*)
%14 = trunc i64 %13 to i32
store volatile i32 %14, i32* %7
%15 = load volatile i64, i64* inttoptr (i64 3758145556 to i64*)
%16 = trunc i64 %15 to i32
store volatile i32 %16, i32* %7
store volatile i64 128, i64* inttoptr (i64 3758145548 to i64*)
%17 = load i16, i16* %4
%18 = trunc i16 %17 to i8
%19 = zext i8 %18 to i64
store volatile i64 %19, i64* inttoptr (i64 3758145536 to i64*)
%20 = load i16, i16* %4
%21 = zext i16 %20 to i32
%22 = ashr i32 %21, 8
%23 = trunc i32 %22 to i8
%24 = zext i8 %23 to i64
store volatile i64 %24, i64* inttoptr (i64 3758145540 to i64*)
%25 = load i8, i8* %5
%26 = zext i8 %25 to i32
%27 = and i32 %26, -129
%28 = sext i32 %27 to i64
store volatile i64 %28, i64* inttoptr (i64 3758145548 to i64*)
%29 = load i8, i8* %6
%30 = zext i8 %29 to i64
store volatile i64 %30, i64* inttoptr (i64 3758145544 to i64*)
ret void
}

LLVM IR (-O2):
define void @initUart0(i16 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = alloca i32
%5 = bitcast i32* %4 to i8*
%6 = load volatile i64, i64* inttoptr (i64 3758276608 to i64*)
%7 = and i64 %6, 4294967280
%8 = or i64 %7, 5
store volatile i64 %8, i64* inttoptr (i64 3758276608 to i64*)
store volatile i64 0, i64* inttoptr (i64 3758145540 to i64*)
%9 = load volatile i64, i64* inttoptr (i64 3758145544 to i64*)
%10 = trunc i64 %9 to i32
store volatile i32 %10, i32* %4
%11 = load volatile i64, i64* inttoptr (i64 3758145536 to i64*)
%12 = trunc i64 %11 to i32
store volatile i32 %12, i32* %4
%13 = load volatile i64, i64* inttoptr (i64 3758145556 to i64*)
%14 = trunc i64 %13 to i32
store volatile i32 %14, i32* %4
store volatile i64 128, i64* inttoptr (i64 3758145548 to i64*)
%15 = and i16 %0, 255
%16 = zext i16 %15 to i64
store volatile i64 %16, i64* inttoptr (i64 3758145536 to i64*)
%17 = lshr i16 %0, 8
%18 = zext i16 %17 to i64
store volatile i64 %18, i64* inttoptr (i64 3758145540 to i64*)
%19 = and i8 %1, 127
%20 = zext i8 %19 to i64
store volatile i64 %20, i64* inttoptr (i64 3758145548 to i64*)
%21 = zext i8 %2 to i64
store volatile i64 %21, i64* inttoptr (i64 3758145544 to i64*)
ret void
}