void uart_init(void) {
  int divisor;
  float float_divisor;
  *((volatile unsigned char *)(0x90000000 + 2)) = 0x01 | 0x02 | 0x04 | 0x40;
  *((volatile unsigned char *)(0x90000000 + 1)) = 0x00;
  *((volatile unsigned char *)(0x90000000 + 3)) = 0x03 & ~(0x04 | 0x08);
  float_divisor = (float)50000000 / (16 * 115200);
  float_divisor += 0.50f;
  divisor = (int)float_divisor;
  *((volatile unsigned char *)(0x90000000 + 3)) |= 0x80;
  *((volatile unsigned char *)(0x90000000 + 0)) = divisor & 0x000000ff;
  *((volatile unsigned char *)(0x90000000 + 1)) = (divisor >> 8) & 0x000000ff;
  *((volatile unsigned char *)(0x90000000 + 3)) &= ~(0x80);
}


x86 assembly (clang, -O0):
<uart_init>:
push   %rbp
mov    %rsp,%rbp
mov    $0x90000002,%eax
movb   $0x47,(%rax)
mov    $0x90000001,%eax
movb   $0x0,(%rax)
mov    $0x90000003,%eax
movb   $0x3,(%rax)
movss  0xee0(%rip),%xmm0
movss  %xmm0,-0x8(%rbp)
movss  0xecf(%rip),%xmm0
addss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
cvttss2si -0x8(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    $0x90000003,%eax
mov    (%rax),%al
movzbl %al,%eax
or     $0x80,%eax
mov    %al,%cl
mov    $0x90000003,%eax
mov    %cl,(%rax)
mov    -0x4(%rbp),%eax
and    $0xff,%eax
mov    %al,%cl
mov    $0x90000000,%eax
mov    %cl,(%rax)
mov    -0x4(%rbp),%eax
sar    $0x8,%eax
and    $0xff,%eax
mov    %al,%cl
mov    $0x90000001,%eax
mov    %cl,(%rax)
mov    $0x90000003,%eax
mov    (%rax),%al
movzbl %al,%eax
and    $0xffffff7f,%eax
mov    %al,%cl
mov    $0x90000003,%eax
mov    %cl,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<uart_init>:
mov    $0x90000003,%eax
movb   $0x47,-0x1(%rax)
movb   $0x0,-0x2(%rax)
movb   $0x3,(%rax)
orb    $0x80,(%rax)
movb   $0x1b,-0x3(%rax)
movb   $0x0,-0x2(%rax)
andb   $0x7f,(%rax)
ret

LLVM IR (-O0):
define void @uart_init() {
%1 = alloca i32
%2 = alloca float
store volatile i8 71, i8* inttoptr (i64 2415919106 to i8*)
store volatile i8 0, i8* inttoptr (i64 2415919105 to i8*)
store volatile i8 3, i8* inttoptr (i64 2415919107 to i8*)
store float 0x403B2071C0000000, float* %2
%3 = load float, float* %2
%4 = fadd float %3, 5.000000e-01
store float %4, float* %2
%5 = load float, float* %2
%6 = fptosi float %5 to i32
store i32 %6, i32* %1
%7 = load volatile i8, i8* inttoptr (i64 2415919107 to i8*)
%8 = zext i8 %7 to i32
%9 = or i32 %8, 128
%10 = trunc i32 %9 to i8
store volatile i8 %10, i8* inttoptr (i64 2415919107 to i8*)
%11 = load i32, i32* %1
%12 = and i32 %11, 255
%13 = trunc i32 %12 to i8
store volatile i8 %13, i8* inttoptr (i64 2415919104 to i8*)
%14 = load i32, i32* %1
%15 = ashr i32 %14, 8
%16 = and i32 %15, 255
%17 = trunc i32 %16 to i8
store volatile i8 %17, i8* inttoptr (i64 2415919105 to i8*)
%18 = load volatile i8, i8* inttoptr (i64 2415919107 to i8*)
%19 = zext i8 %18 to i32
%20 = and i32 %19, -129
%21 = trunc i32 %20 to i8
store volatile i8 %21, i8* inttoptr (i64 2415919107 to i8*)
ret void
}

LLVM IR (-O2):
define void @uart_init() {
store volatile i8 71, i8* inttoptr (i64 2415919106 to i8*)
store volatile i8 0, i8* inttoptr (i64 2415919105 to i8*)
store volatile i8 3, i8* inttoptr (i64 2415919107 to i8*)
%1 = load volatile i8, i8* inttoptr (i64 2415919107 to i8*)
%2 = or i8 %1, -128
store volatile i8 %2, i8* inttoptr (i64 2415919107 to i8*)
store volatile i8 27, i8* inttoptr (i64 2415919104 to i8*)
store volatile i8 0, i8* inttoptr (i64 2415919105 to i8*)
%3 = load volatile i8, i8* inttoptr (i64 2415919107 to i8*)
%4 = and i8 %3, 127
store volatile i8 %4, i8* inttoptr (i64 2415919107 to i8*)
ret void
}