void YM2612_writeRegSafe(const unsigned short part, const unsigned char reg,
                         const unsigned char data) {
  volatile unsigned char *pb;
  unsigned short port;
  pb = (unsigned char *)0xA04000;
  port = (part << 1) & 2;
  while (*pb & 0x80)
    ;
  pb[port + 0] = reg;
  while (*pb & 0x80)
    ;
  pb[port + 1] = data;
}


x86 assembly (clang, -O0):
<YM2612_writeRegSafe>:
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    $0xa04000,%eax
mov    %rax,-0x10(%rbp)
movzwl -0x2(%rbp),%eax
shl    $0x1,%eax
and    $0x2,%eax
mov    %ax,-0x12(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%al
movzbl %al,%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     1149 <YM2612_writeRegSafe+0x49>
jmp    112d <YM2612_writeRegSafe+0x2d>
mov    -0x3(%rbp),%dl
mov    -0x10(%rbp),%rax
movzwl -0x12(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
mov    (%rax),%al
movzbl %al,%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     1179 <YM2612_writeRegSafe+0x79>
jmp    115d <YM2612_writeRegSafe+0x5d>
mov    -0x4(%rbp),%dl
mov    -0x10(%rbp),%rax
movzwl -0x12(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<YM2612_writeRegSafe>:
add    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmpb   $0x0,0xa04000
js     1110 <YM2612_writeRegSafe+0x10>
mov    $0xa04000,%eax
movzwl %di,%ecx
and    $0x2,%ecx
mov    %sil,0xa04000(%rcx)
nopl   0x0(%rax)
cmpb   $0x0,0xa04000
js     1130 <YM2612_writeRegSafe+0x30>
movzwl %cx,%ecx
or     $0x1,%rcx
mov    %dl,(%rax,%rcx,1)
ret

LLVM IR (-O0):
define void @YM2612_writeRegSafe(i16 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = alloca i16
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8*
%8 = alloca i16
store i16 %0, i16* %4
store i8 %1, i8* %5
store i8 %2, i8* %6
store i8* inttoptr (i64 10502144 to i8*), i8** %7
%9 = load i16, i16* %4
%10 = zext i16 %9 to i32
%11 = shl i32 %10, 1
%12 = and i32 %11, 2
%13 = trunc i32 %12 to i16
store i16 %13, i16* %8
br label %14
14: ; preds = %20, %3
%15 = load i8*, i8** %7
%16 = load volatile i8, i8* %15
%17 = zext i8 %16 to i32
%18 = and i32 %17, 128
%19 = icmp ne i32 %18, 0
br i1 %19, label %20, label %21
20: ; preds = %14
br label %14
21: ; preds = %14
%22 = load i8, i8* %5
%23 = load i8*, i8** %7
%24 = load i16, i16* %8
%25 = zext i16 %24 to i32
%26 = add nsw i32 %25, 0
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i8, i8* %23, i64 %27
store volatile i8 %22, i8* %28
br label %29
29: ; preds = %35, %21
%30 = load i8*, i8** %7
%31 = load volatile i8, i8* %30
%32 = zext i8 %31 to i32
%33 = and i32 %32, 128
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %36
35: ; preds = %29
br label %29
36: ; preds = %29
%37 = load i8, i8* %6
%38 = load i8*, i8** %7
%39 = load i16, i16* %8
%40 = zext i16 %39 to i32
%41 = add nsw i32 %40, 1
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i8, i8* %38, i64 %42
store volatile i8 %37, i8* %43
ret void
}

LLVM IR (-O2):
define void @YM2612_writeRegSafe(i16 zeroext %0, i8 zeroext %1, i8 zeroext %2) {
%4 = shl i16 %0, 1
br label %5
5: ; preds = %5, %3
%6 = load volatile i8, i8* inttoptr (i64 10502144 to i8*)
%7 = icmp sgt i8 %6, -1
br i1 %7, label %8, label %5
8: ; preds = %5
%9 = and i16 %4, 2
%10 = zext i16 %9 to i64
%11 = getelementptr inbounds i8, i8* inttoptr (i64 10502144 to i8*), i64 %10
store volatile i8 %1, i8* %11
br label %12
12: ; preds = %12, %8
%13 = load volatile i8, i8* inttoptr (i64 10502144 to i8*)
%14 = icmp sgt i8 %13, -1
br i1 %14, label %15, label %12
15: ; preds = %12
%16 = or i16 %9, 1
%17 = zext i16 %16 to i64
%18 = getelementptr inbounds i8, i8* inttoptr (i64 10502144 to i8*), i64 %17
store volatile i8 %2, i8* %18
ret void
}