void uart_poll_tx_byte(unsigned int uart, unsigned char byte) {
  unsigned int data;
  if (!uart) {
    data = (*((volatile unsigned int *)(0xF1000000 + 0x20)) & ~0xFF) | byte;
    *((volatile unsigned int *)(0xF1000000 + 0x20)) = data;
    while (!(*((volatile unsigned int *)(0xF1000000 + 0x60)) & 2))
      *((volatile unsigned int *)(0xF1000000 + 0x70)) |= 2;
  } else {
    data = (*((volatile unsigned int *)(0xF1800000 + 0x20)) & ~0xFF) | byte;
    *((volatile unsigned int *)(0xF1800000 + 0x20)) = data;
    while (!(*((volatile unsigned int *)(0xF1800000 + 0x60)) & 2))
      ;
    *((volatile unsigned int *)(0xF1800000 + 0x70)) |= 2;
  }
}


x86 assembly (clang, -O0):
<uart_poll_tx_byte>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %edi,-0x4(%rbp)
mov    %al,-0x5(%rbp)
cmpl   $0x0,-0x4(%rbp)
jne    1170 <uart_poll_tx_byte+0x70>
mov    $0xf1000020,%eax
mov    (%rax),%eax
and    $0xffffff00,%eax
movzbl -0x5(%rbp),%ecx
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%ecx
mov    $0xf1000020,%eax
mov    %ecx,(%rax)
mov    $0xf1000060,%eax
mov    (%rax),%eax
and    $0x2,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    1155 <uart_poll_tx_byte+0x55>
jmp    116b <uart_poll_tx_byte+0x6b>
mov    $0xf1000070,%eax
mov    (%rax),%ecx
or     $0x2,%ecx
mov    $0xf1000070,%eax
mov    %ecx,(%rax)
jmp    1136 <uart_poll_tx_byte+0x36>
jmp    11c4 <uart_poll_tx_byte+0xc4>
mov    $0xf1800020,%eax
mov    (%rax),%eax
and    $0xffffff00,%eax
movzbl -0x5(%rbp),%ecx
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%ecx
mov    $0xf1800020,%eax
mov    %ecx,(%rax)
mov    $0xf1800060,%eax
mov    (%rax),%eax
and    $0x2,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    11ae <uart_poll_tx_byte+0xae>
jmp    11b3 <uart_poll_tx_byte+0xb3>
jmp    118f <uart_poll_tx_byte+0x8f>
mov    $0xf1800070,%eax
mov    (%rax),%ecx
or     $0x2,%ecx
mov    $0xf1800070,%eax
mov    %ecx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<uart_poll_tx_byte>:
mov    $0xf1000020,%eax
mov    $0xffffff00,%ecx
test   %edi,%edi
je     1134 <uart_poll_tx_byte+0x34>
and    0x800000(%rax),%ecx
movzbl %sil,%edx
or     %ecx,%edx
mov    %edx,0x800000(%rax)
testl  $0x2,0x800040(%rax)
je     1120 <uart_poll_tx_byte+0x20>
orl    $0x2,0x800050(%rax)
ret
and    (%rax),%ecx
movzbl %sil,%edx
or     %ecx,%edx
mov    %edx,(%rax)
xchg   %ax,%ax
testl  $0x2,0x40(%rax)
jne    1133 <uart_poll_tx_byte+0x33>
orl    $0x2,0x50(%rax)
jmp    1140 <uart_poll_tx_byte+0x40>

LLVM IR (-O0):
define void @uart_poll_tx_byte(i32 %0, i8 zeroext %1) {
%3 = alloca i32
%4 = alloca i8
%5 = alloca i32
store i32 %0, i32* %3
store i8 %1, i8* %4
%6 = load i32, i32* %3
%7 = icmp ne i32 %6, 0
br i1 %7, label %24, label %8
8: ; preds = %2
%9 = load volatile i32, i32* inttoptr (i64 4043309088 to i32*)
%10 = and i32 %9, -256
%11 = load i8, i8* %4
%12 = zext i8 %11 to i32
%13 = or i32 %10, %12
store i32 %13, i32* %5
%14 = load i32, i32* %5
store volatile i32 %14, i32* inttoptr (i64 4043309088 to i32*)
br label %15
15: ; preds = %20, %8
%16 = load volatile i32, i32* inttoptr (i64 4043309152 to i32*)
%17 = and i32 %16, 2
%18 = icmp ne i32 %17, 0
%19 = xor i1 %18, true
br i1 %19, label %20, label %23
20: ; preds = %15
%21 = load volatile i32, i32* inttoptr (i64 4043309168 to i32*)
%22 = or i32 %21, 2
store volatile i32 %22, i32* inttoptr (i64 4043309168 to i32*)
br label %15
23: ; preds = %15
br label %40
24: ; preds = %2
%25 = load volatile i32, i32* inttoptr (i64 4051697696 to i32*)
%26 = and i32 %25, -256
%27 = load i8, i8* %4
%28 = zext i8 %27 to i32
%29 = or i32 %26, %28
store i32 %29, i32* %5
%30 = load i32, i32* %5
store volatile i32 %30, i32* inttoptr (i64 4051697696 to i32*)
br label %31
31: ; preds = %36, %24
%32 = load volatile i32, i32* inttoptr (i64 4051697760 to i32*)
%33 = and i32 %32, 2
%34 = icmp ne i32 %33, 0
%35 = xor i1 %34, true
br i1 %35, label %36, label %37
36: ; preds = %31
br label %31
37: ; preds = %31
%38 = load volatile i32, i32* inttoptr (i64 4051697776 to i32*)
%39 = or i32 %38, 2
store volatile i32 %39, i32* inttoptr (i64 4051697776 to i32*)
br label %40
40: ; preds = %37, %23
ret void
}

LLVM IR (-O2):
define void @uart_poll_tx_byte(i32 %0, i8 zeroext %1) {
%3 = icmp eq i32 %0, 0
br i1 %3, label %4, label %18
4: ; preds = %2
%5 = load volatile i32, i32* inttoptr (i64 4043309088 to i32*)
%6 = and i32 %5, -256
%7 = zext i8 %1 to i32
%8 = or i32 %6, %7
store volatile i32 %8, i32* inttoptr (i64 4043309088 to i32*)
%9 = load volatile i32, i32* inttoptr (i64 4043309152 to i32*)
%10 = and i32 %9, 2
%11 = icmp eq i32 %10, 0
br i1 %11, label %12, label %30
12: ; preds = %4, %12
%13 = load volatile i32, i32* inttoptr (i64 4043309168 to i32*)
%14 = or i32 %13, 2
store volatile i32 %14, i32* inttoptr (i64 4043309168 to i32*)
%15 = load volatile i32, i32* inttoptr (i64 4043309152 to i32*)
%16 = and i32 %15, 2
%17 = icmp eq i32 %16, 0
br i1 %17, label %12, label %30
18: ; preds = %2
%19 = load volatile i32, i32* inttoptr (i64 4051697696 to i32*)
%20 = and i32 %19, -256
%21 = zext i8 %1 to i32
%22 = or i32 %20, %21
store volatile i32 %22, i32* inttoptr (i64 4051697696 to i32*)
br label %23
23: ; preds = %23, %18
%24 = load volatile i32, i32* inttoptr (i64 4051697760 to i32*)
%25 = and i32 %24, 2
%26 = icmp eq i32 %25, 0
br i1 %26, label %23, label %27
27: ; preds = %23
%28 = load volatile i32, i32* inttoptr (i64 4051697776 to i32*)
%29 = or i32 %28, 2
store volatile i32 %29, i32* inttoptr (i64 4051697776 to i32*)
br label %30
30: ; preds = %12, %4, %27
ret void
}