long FlashProtectSave(void) {
  int ulTemp, ulLimit;
  ulLimit = ((((*((volatile unsigned long *)(0x400FE000))) & 0x70000000) ==
              0x00000000) ||
             (((*((volatile unsigned long *)(0x400FE000))) &
               (0x70000000 | 0x00FF0000)) == (0x10000000 | 0x00000000)))
                ? 2
                : 8;
  for (ulTemp = 0; ulTemp < ulLimit; ulTemp++) {
    (*((volatile unsigned long *)(0x400FD000))) = ulTemp;
    (*((volatile unsigned long *)(0x400FD008))) = 0xA4420000 | 0x00000008;
    while ((*((volatile unsigned long *)(0x400FD008))) & 0x00000008) {
    }
  }
  return (0);
}


x86 assembly (clang, -O0):
<FlashProtectSave>:
push   %rbp
mov    %rsp,%rbp
mov    $0x400fe000,%eax
mov    (%rax),%rcx
and    $0x70000000,%rcx
mov    $0x1,%al
cmp    $0x0,%rcx
mov    %al,-0x9(%rbp)
je     113c <FlashProtectSave+0x3c>
mov    $0x400fe000,%eax
mov    (%rax),%rax
and    $0x70ff0000,%rax
cmp    $0x10000000,%rax
sete   %al
mov    %al,-0x9(%rbp)
mov    -0x9(%rbp),%dl
mov    $0x8,%eax
mov    $0x2,%ecx
test   $0x1,%dl
cmovne %ecx,%eax
mov    %eax,-0x8(%rbp)
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    11ac <FlashProtectSave+0xac>
movslq -0x4(%rbp),%rcx
mov    $0x400fd000,%eax
mov    %rcx,(%rax)
mov    $0x400fd008,%eax
mov    $0xa4420008,%ecx
mov    %rcx,(%rax)
mov    $0x400fd008,%eax
mov    (%rax),%rax
and    $0x8,%rax
cmp    $0x0,%rax
je     1199 <FlashProtectSave+0x99>
jmp    117e <FlashProtectSave+0x7e>
jmp    119e <FlashProtectSave+0x9e>
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4(%rbp)
jmp    1159 <FlashProtectSave+0x59>
xor    %eax,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<FlashProtectSave>:
testq  $0x70000000,0x400fe000
je     1130 <FlashProtectSave+0x30>
mov    0x400fe000,%rax
40
and    $0x70ff0000,%eax
cmp    $0x10000000,%eax
mov    $0x2,%ecx
mov    $0x8,%eax
cmove  %rcx,%rax
jmp    1135 <FlashProtectSave+0x35>
mov    $0x2,%eax
mov    $0xa4420008,%ecx
xor    %edx,%edx
nopl   0x0(%rax)
mov    %rdx,0x400fd000
40
mov    %rcx,0x400fd008
40
testq  $0x8,0x400fd008
jne    1150 <FlashProtectSave+0x50>
mov    %rdx,%rsi
or     $0x1,%rsi
mov    %rsi,0x400fd000
40
mov    %rcx,0x400fd008
40
cs nopw 0x0(%rax,%rax,1)
nop
testq  $0x8,0x400fd008
jne    1180 <FlashProtectSave+0x80>
add    $0x2,%rdx
cmp    %rax,%rdx
jne    1140 <FlashProtectSave+0x40>
xor    %eax,%eax
ret

LLVM IR (-O0):
define i64 @FlashProtectSave() {
%1 = alloca i32
%2 = alloca i32
%3 = load volatile i64, i64* inttoptr (i64 1074782208 to i64*)
%4 = and i64 %3, 1879048192
%5 = icmp eq i64 %4, 0
br i1 %5, label %10, label %6
6: ; preds = %0
%7 = load volatile i64, i64* inttoptr (i64 1074782208 to i64*)
%8 = and i64 %7, 1895759872
%9 = icmp eq i64 %8, 268435456
br label %10
10: ; preds = %6, %0
%11 = phi i1 [ true, %0 ], [ %9, %6 ]
%12 = zext i1 %11 to i64
%13 = select i1 %11, i32 2, i32 8
store i32 %13, i32* %2
store i32 0, i32* %1
br label %14
14: ; preds = %27, %10
%15 = load i32, i32* %1
%16 = load i32, i32* %2
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %30
18: ; preds = %14
%19 = load i32, i32* %1
%20 = sext i32 %19 to i64
store volatile i64 %20, i64* inttoptr (i64 1074778112 to i64*)
store volatile i64 2755788808, i64* inttoptr (i64 1074778120 to i64*)
br label %21
21: ; preds = %25, %18
%22 = load volatile i64, i64* inttoptr (i64 1074778120 to i64*)
%23 = and i64 %22, 8
%24 = icmp ne i64 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %21
br label %21
26: ; preds = %21
br label %27
27: ; preds = %26
%28 = load i32, i32* %1
%29 = add nsw i32 %28, 1
store i32 %29, i32* %1
br label %14
30: ; preds = %14
ret i64 0
}

LLVM IR (-O2):
define i64 @FlashProtectSave() {
%1 = load volatile i64, i64* inttoptr (i64 1074782208 to i64*)
%2 = and i64 %1, 1879048192
%3 = icmp eq i64 %2, 0
br i1 %3, label %9, label %4
4: ; preds = %0
%5 = load volatile i64, i64* inttoptr (i64 1074782208 to i64*)
%6 = and i64 %5, 1895759872
%7 = icmp eq i64 %6, 268435456
%8 = select i1 %7, i64 2, i64 8
br label %9
9: ; preds = %4, %0
%10 = phi i64 [ 2, %0 ], [ %8, %4 ]
br label %11
11: ; preds = %23, %9
%12 = phi i64 [ 0, %9 ], [ %24, %23 ]
store volatile i64 %12, i64* inttoptr (i64 1074778112 to i64*)
store volatile i64 2755788808, i64* inttoptr (i64 1074778120 to i64*)
br label %13
13: ; preds = %13, %11
%14 = load volatile i64, i64* inttoptr (i64 1074778120 to i64*)
%15 = and i64 %14, 8
%16 = icmp eq i64 %15, 0
br i1 %16, label %17, label %13
17: ; preds = %13
%18 = or i64 %12, 1
store volatile i64 %18, i64* inttoptr (i64 1074778112 to i64*)
store volatile i64 2755788808, i64* inttoptr (i64 1074778120 to i64*)
br label %19
19: ; preds = %19, %17
%20 = load volatile i64, i64* inttoptr (i64 1074778120 to i64*)
%21 = and i64 %20, 8
%22 = icmp eq i64 %21, 0
br i1 %22, label %23, label %19
23: ; preds = %19
%24 = add nuw nsw i64 %12, 2
%25 = icmp eq i64 %24, %10
br i1 %25, label %26, label %11
26: ; preds = %23
ret i64 0
}