int flash_lock_block(volatile unsigned char *block) {
  volatile unsigned char *ROM;
  unsigned short stat;
  int timeout = 5000000;
  ROM = ((
      volatile unsigned char
          *)(((unsigned)((unsigned long)block & 0xFF800000) < 0x1000)
                 ? ((unsigned)((unsigned long)block & 0xFF800000) | 0xd0000000)
                 : (unsigned)((unsigned long)block & 0xFF800000)));
  ROM[0] = 0x50;
  ((volatile unsigned char *)(((unsigned)(block) < 0x1000)
                                  ? ((unsigned)(block) | 0xd0000000)
                                  : (unsigned)(block)))[0] = 0x60;
  ((volatile unsigned char *)(((unsigned)(block) < 0x1000)
                                  ? ((unsigned)(block) | 0xd0000000)
                                  : (unsigned)(block)))[0] = 0x01;
  while (((stat = ROM[0]) & 0x80) != 0x80) {
    if (--timeout == 0)
      break;
  }
  ROM[0] = 0xFF;
  return stat;
}


x86 assembly (clang, -O0):
<flash_lock_block>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x4c4b40,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movabs $0xff800000,%rcx
and    %rcx,%rax
cmp    $0x1000,%eax
jae    1149 <flash_lock_block+0x49>
mov    -0x8(%rbp),%rax
movabs $0xff800000,%rcx
and    %rcx,%rax
or     $0xd0000000,%eax
mov    %eax,-0x1c(%rbp)
jmp    115d <flash_lock_block+0x5d>
mov    -0x8(%rbp),%rax
movabs $0xff800000,%rcx
and    %rcx,%rax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,%eax
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movb   $0x50,(%rax)
mov    -0x8(%rbp),%rax
cmp    $0x1000,%eax
jae    118d <flash_lock_block+0x8d>
mov    -0x8(%rbp),%rax
or     $0xd0000000,%eax
mov    %eax,-0x20(%rbp)
jmp    1194 <flash_lock_block+0x94>
mov    -0x8(%rbp),%rax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,%eax
movb   $0x60,(%rax)
mov    -0x8(%rbp),%rax
cmp    $0x1000,%eax
jae    11bc <flash_lock_block+0xbc>
mov    -0x8(%rbp),%rax
or     $0xd0000000,%eax
mov    %eax,-0x24(%rbp)
jmp    11c3 <flash_lock_block+0xc3>
mov    -0x8(%rbp),%rax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,%eax
movb   $0x1,(%rax)
mov    -0x10(%rbp),%rax
mov    (%rax),%al
movzbl %al,%eax
mov    %ax,-0x12(%rbp)
movzwl %ax,%eax
and    $0x80,%eax
cmp    $0x80,%eax
je     1207 <flash_lock_block+0x107>
mov    -0x18(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x18(%rbp)
cmp    $0x0,%eax
jne    1202 <flash_lock_block+0x102>
jmp    1207 <flash_lock_block+0x107>
jmp    11cb <flash_lock_block+0xcb>
mov    -0x10(%rbp),%rax
movb   $0xff,(%rax)
movzwl -0x12(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<flash_lock_block>:
mov    %edi,%eax
and    $0xff800000,%eax
mov    $0xd0000000,%ecx
cmovne %eax,%ecx
movb   $0x50,(%rcx)
mov    %edi,%eax
or     $0xd0000000,%eax
test   $0xfffff000,%edi
cmovne %rdi,%rax
mov    %eax,%eax
movb   $0x60,(%rax)
movb   $0x1,(%rax)
mov    $0xffb3b4c1,%edx
movzbl (%rcx),%eax
test   %al,%al
js     1140 <flash_lock_block+0x40>
lea    0x1(%rdx),%esi
test   %edx,%edx
mov    %esi,%edx
jne    1130 <flash_lock_block+0x30>
movb   $0xff,(%rcx)
ret

LLVM IR (-O0):
define i32 @flash_lock_block(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i16
%5 = alloca i32
store i8* %0, i8** %2
store i32 5000000, i32* %5
%6 = load i8*, i8** %2
%7 = ptrtoint i8* %6 to i64
%8 = and i64 %7, 4286578688
%9 = trunc i64 %8 to i32
%10 = icmp ult i32 %9, 4096
br i1 %10, label %11, label %17
11: ; preds = %1
%12 = load i8*, i8** %2
%13 = ptrtoint i8* %12 to i64
%14 = and i64 %13, 4286578688
%15 = trunc i64 %14 to i32
%16 = or i32 %15, -805306368
br label %22
17: ; preds = %1
%18 = load i8*, i8** %2
%19 = ptrtoint i8* %18 to i64
%20 = and i64 %19, 4286578688
%21 = trunc i64 %20 to i32
br label %22
22: ; preds = %17, %11
%23 = phi i32 [ %16, %11 ], [ %21, %17 ]
%24 = zext i32 %23 to i64
%25 = inttoptr i64 %24 to i8*
store i8* %25, i8** %3
%26 = load i8*, i8** %3
%27 = getelementptr inbounds i8, i8* %26, i64 0
store volatile i8 80, i8* %27
%28 = load i8*, i8** %2
%29 = ptrtoint i8* %28 to i32
%30 = icmp ult i32 %29, 4096
br i1 %30, label %31, label %35
31: ; preds = %22
%32 = load i8*, i8** %2
%33 = ptrtoint i8* %32 to i32
%34 = or i32 %33, -805306368
br label %38
35: ; preds = %22
%36 = load i8*, i8** %2
%37 = ptrtoint i8* %36 to i32
br label %38
38: ; preds = %35, %31
%39 = phi i32 [ %34, %31 ], [ %37, %35 ]
%40 = zext i32 %39 to i64
%41 = inttoptr i64 %40 to i8*
%42 = getelementptr inbounds i8, i8* %41, i64 0
store volatile i8 96, i8* %42
%43 = load i8*, i8** %2
%44 = ptrtoint i8* %43 to i32
%45 = icmp ult i32 %44, 4096
br i1 %45, label %46, label %50
46: ; preds = %38
%47 = load i8*, i8** %2
%48 = ptrtoint i8* %47 to i32
%49 = or i32 %48, -805306368
br label %53
50: ; preds = %38
%51 = load i8*, i8** %2
%52 = ptrtoint i8* %51 to i32
br label %53
53: ; preds = %50, %46
%54 = phi i32 [ %49, %46 ], [ %52, %50 ]
%55 = zext i32 %54 to i64
%56 = inttoptr i64 %55 to i8*
%57 = getelementptr inbounds i8, i8* %56, i64 0
store volatile i8 1, i8* %57
br label %58
58: ; preds = %71, %53
%59 = load i8*, i8** %3
%60 = getelementptr inbounds i8, i8* %59, i64 0
%61 = load volatile i8, i8* %60
%62 = zext i8 %61 to i16
store i16 %62, i16* %4
%63 = zext i16 %62 to i32
%64 = and i32 %63, 128
%65 = icmp ne i32 %64, 128
br i1 %65, label %66, label %72
66: ; preds = %58
%67 = load i32, i32* %5
%68 = add nsw i32 %67, -1
store i32 %68, i32* %5
%69 = icmp eq i32 %68, 0
br i1 %69, label %70, label %71
70: ; preds = %66
br label %72
71: ; preds = %66
br label %58
72: ; preds = %70, %58
%73 = load i8*, i8** %3
%74 = getelementptr inbounds i8, i8* %73, i64 0
store volatile i8 -1, i8* %74
%75 = load i16, i16* %4
%76 = zext i16 %75 to i32
ret i32 %76
}

LLVM IR (-O2):
define i32 @flash_lock_block(i8* %0) {
%2 = ptrtoint i8* %0 to i64
%3 = trunc i64 %2 to i32
%4 = and i32 %3, -8388608
%5 = icmp eq i32 %4, 0
%6 = select i1 %5, i32 -805306368, i32 %4
%7 = zext i32 %6 to i64
%8 = inttoptr i64 %7 to i8*
store volatile i8 80, i8* %8
%9 = and i64 %2, 4294963200
%10 = icmp eq i64 %9, 0
%11 = or i64 %2, 3489660928
%12 = select i1 %10, i64 %11, i64 %2
%13 = and i64 %12, 4294967295
%14 = inttoptr i64 %13 to i8*
store volatile i8 96, i8* %14
store volatile i8 1, i8* %14
br label %15
15: ; preds = %15, %1
%16 = phi i32 [ 5000000, %1 ], [ %19, %15 ]
%17 = load volatile i8, i8* %8
%18 = icmp slt i8 %17, 0
%19 = add nsw i32 %16, -1
%20 = icmp eq i32 %19, 0
%21 = select i1 %18, i1 true, i1 %20
br i1 %21, label %22, label %15
22: ; preds = %15
%23 = zext i8 %17 to i32
store volatile i8 -1, i8* %8
ret i32 %23
}