void uart_init() {
  unsigned divisor = (((50000000) / 8 + (115200)) / (115200) / 2);
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 3)) = 0x03 | 0x80;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 1)) = divisor >> 8;
  *(volatile unsigned char *)(0x14000000 + (0x3f8)) = divisor;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 3)) = 0x03;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 7)) = 0;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 1)) = 0;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 6)) = 0;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 4)) = 0x01 | 0x02 | 0x08;
  *(volatile unsigned char *)(0x14000000 + (0x3f8 + 2)) = 0x02 | 0x04 | 0x01;
  (void)*(volatile unsigned char *)(0x14000000 + (0x3f8 + 5));
  (void)*(volatile unsigned char *)(0x14000000 + (0x3f8 + 6));
  (void)*(volatile unsigned char *)(0x14000000 + (0x3f8));
  (void)*(volatile unsigned char *)(0x14000000 + (0x3f8 + 2));
}


x86 assembly (clang, -O0):
<uart_init>:
push   %rbp
mov    %rsp,%rbp
movl   $0x1b,-0x4(%rbp)
mov    $0x140003fb,%eax
movb   $0x83,(%rax)
mov    -0x4(%rbp),%eax
shr    $0x8,%eax
mov    %al,%cl
mov    $0x140003f9,%eax
mov    %cl,(%rax)
mov    -0x4(%rbp),%eax
mov    %al,%cl
mov    $0x140003f8,%eax
mov    %cl,(%rax)
mov    $0x140003fb,%eax
movb   $0x3,(%rax)
mov    $0x140003ff,%eax
movb   $0x0,(%rax)
mov    $0x140003f9,%eax
movb   $0x0,(%rax)
mov    $0x140003fe,%eax
movb   $0x0,(%rax)
mov    $0x140003fc,%eax
movb   $0xb,(%rax)
mov    $0x140003fa,%eax
movb   $0x7,(%rax)
mov    $0x140003fd,%eax
mov    (%rax),%al
mov    $0x140003fe,%eax
mov    (%rax),%al
mov    $0x140003f8,%eax
mov    (%rax),%al
mov    $0x140003fa,%eax
mov    (%rax),%al
pop    %rbp
ret

x86 assembly (clang, -O2):
<uart_init>:
movb   $0x83,0x140003fb
83
movb   $0x0,0x140003f9
movb   $0x1b,0x140003f8
1b
movb   $0x3,0x140003fb
03
movb   $0x0,0x140003ff
movb   $0x0,0x140003f9
movb   $0x0,0x140003fe
movb   $0xb,0x140003fc
0b
movb   $0x7,0x140003fa
07
mov    0x140003fd,%al
mov    0x140003fe,%al
mov    0x140003f8,%al
mov    0x140003fa,%al
ret

LLVM IR (-O0):
define void @uart_init() {
%1 = alloca i32
store i32 27, i32* %1
store volatile i8 -125, i8* inttoptr (i64 335545339 to i8*)
%2 = load i32, i32* %1
%3 = lshr i32 %2, 8
%4 = trunc i32 %3 to i8
store volatile i8 %4, i8* inttoptr (i64 335545337 to i8*)
%5 = load i32, i32* %1
%6 = trunc i32 %5 to i8
store volatile i8 %6, i8* inttoptr (i64 335545336 to i8*)
store volatile i8 3, i8* inttoptr (i64 335545339 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545343 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545337 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545342 to i8*)
store volatile i8 11, i8* inttoptr (i64 335545340 to i8*)
store volatile i8 7, i8* inttoptr (i64 335545338 to i8*)
%7 = load volatile i8, i8* inttoptr (i64 335545341 to i8*)
%8 = load volatile i8, i8* inttoptr (i64 335545342 to i8*)
%9 = load volatile i8, i8* inttoptr (i64 335545336 to i8*)
%10 = load volatile i8, i8* inttoptr (i64 335545338 to i8*)
ret void
}

LLVM IR (-O2):
define void @uart_init() {
store volatile i8 -125, i8* inttoptr (i64 335545339 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545337 to i8*)
store volatile i8 27, i8* inttoptr (i64 335545336 to i8*)
store volatile i8 3, i8* inttoptr (i64 335545339 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545343 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545337 to i8*)
store volatile i8 0, i8* inttoptr (i64 335545342 to i8*)
store volatile i8 11, i8* inttoptr (i64 335545340 to i8*)
store volatile i8 7, i8* inttoptr (i64 335545338 to i8*)
%1 = load volatile i8, i8* inttoptr (i64 335545341 to i8*)
%2 = load volatile i8, i8* inttoptr (i64 335545342 to i8*)
%3 = load volatile i8, i8* inttoptr (i64 335545336 to i8*)
%4 = load volatile i8, i8* inttoptr (i64 335545338 to i8*)
ret void
}