void IpcSync(volatile unsigned int flag) {
  (*((volatile unsigned long *)(0x400FB700 + 0x000000008))) |= flag;
  while (((*((volatile unsigned long *)(0x400FB700 + 0x000000004))) & flag) ==
         0) {
  }
  (*((volatile unsigned long *)(0x400FB700 + 0x000000000))) |= flag;
  while ((*((volatile unsigned long *)(0x400FB700 + 0x000000010))) & flag) {
  }
}


x86 assembly (clang, -O0):
<IpcSync>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,%eax
mov    $0x400fb708,%ecx
mov    (%rcx),%rcx
or     %rax,%rcx
mov    $0x400fb708,%eax
mov    %rcx,(%rax)
mov    $0x400fb704,%eax
mov    (%rax),%rax
mov    -0x4(%rbp),%ecx
mov    %ecx,%ecx
and    %rcx,%rax
cmp    $0x0,%rax
jne    113e <IpcSync+0x3e>
jmp    111f <IpcSync+0x1f>
mov    -0x4(%rbp),%eax
mov    %eax,%eax
mov    $0x400fb700,%ecx
mov    (%rcx),%rcx
or     %rax,%rcx
mov    $0x400fb700,%eax
mov    %rcx,(%rax)
mov    $0x400fb710,%eax
mov    (%rax),%rax
mov    -0x4(%rbp),%ecx
mov    %ecx,%ecx
and    %rcx,%rax
cmp    $0x0,%rax
je     1175 <IpcSync+0x75>
jmp    1156 <IpcSync+0x56>
pop    %rbp
ret

x86 assembly (clang, -O2):
<IpcSync>:
mov    %edi,-0x4(%rsp)
mov    -0x4(%rsp),%eax
or     %rax,0x400fb708
40
mov    0x400fb704,%rax
40
and    -0x4(%rsp),%eax
je     1110 <IpcSync+0x10>
mov    -0x4(%rsp),%eax
or     %rax,0x400fb700
40
nopw   0x0(%rax,%rax,1)
mov    0x400fb710,%rax
40
and    -0x4(%rsp),%eax
jne    1130 <IpcSync+0x30>
ret

LLVM IR (-O0):
define void @IpcSync(i32 %0) {
%2 = alloca i32
store volatile i32 %0, i32* %2
%3 = load volatile i32, i32* %2
%4 = zext i32 %3 to i64
%5 = load volatile i64, i64* inttoptr (i64 1074771720 to i64*)
%6 = or i64 %5, %4
store volatile i64 %6, i64* inttoptr (i64 1074771720 to i64*)
br label %7
7: ; preds = %13, %1
%8 = load volatile i64, i64* inttoptr (i64 1074771716 to i64*)
%9 = load volatile i32, i32* %2
%10 = zext i32 %9 to i64
%11 = and i64 %8, %10
%12 = icmp eq i64 %11, 0
br i1 %12, label %13, label %14
13: ; preds = %7
br label %7
14: ; preds = %7
%15 = load volatile i32, i32* %2
%16 = zext i32 %15 to i64
%17 = load volatile i64, i64* inttoptr (i64 1074771712 to i64*)
%18 = or i64 %17, %16
store volatile i64 %18, i64* inttoptr (i64 1074771712 to i64*)
br label %19
19: ; preds = %25, %14
%20 = load volatile i64, i64* inttoptr (i64 1074771728 to i64*)
%21 = load volatile i32, i32* %2
%22 = zext i32 %21 to i64
%23 = and i64 %20, %22
%24 = icmp ne i64 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %19
br label %19
26: ; preds = %19
ret void
}

LLVM IR (-O2):
define void @IpcSync(i32 %0) {
%2 = alloca i32
store volatile i32 %0, i32* %2
%3 = load volatile i32, i32* %2
%4 = zext i32 %3 to i64
%5 = load volatile i64, i64* inttoptr (i64 1074771720 to i64*)
%6 = or i64 %5, %4
store volatile i64 %6, i64* inttoptr (i64 1074771720 to i64*)
br label %7
7: ; preds = %7, %1
%8 = load volatile i64, i64* inttoptr (i64 1074771716 to i64*)
%9 = load volatile i32, i32* %2
%10 = zext i32 %9 to i64
%11 = and i64 %8, %10
%12 = icmp eq i64 %11, 0
br i1 %12, label %7, label %13
13: ; preds = %7
%14 = load volatile i32, i32* %2
%15 = zext i32 %14 to i64
%16 = load volatile i64, i64* inttoptr (i64 1074771712 to i64*)
%17 = or i64 %16, %15
store volatile i64 %17, i64* inttoptr (i64 1074771712 to i64*)
br label %18
18: ; preds = %18, %13
%19 = load volatile i64, i64* inttoptr (i64 1074771728 to i64*)
%20 = load volatile i32, i32* %2
%21 = zext i32 %20 to i64
%22 = and i64 %19, %21
%23 = icmp eq i64 %22, 0
br i1 %23, label %24, label %18
24: ; preds = %18
ret void
}