#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ clear_RnB();
int /*<<< orphan*/ delete_chip();
int /*<<< orphan*/ select_chip();
int /*<<< orphan*/ send_addr(unsigned long);
int /*<<< orphan*/ send_cmd(int);
int /*<<< orphan*/ wait_RnB();
void NF_Page_Read(unsigned long addr, unsigned char *buff, int size) {
  int i, len;
  select_chip();
  clear_RnB();
  send_cmd(0x00);
  send_addr(0x00);
  send_addr(0x00);
  send_addr(addr & 0xFF);
  send_addr((addr >> 8) & (0xFF));
  send_addr((addr >> 16) & (0xFF));
  send_cmd(0x30);
  wait_RnB();
  if (size > 2048)
    len = size > 2048 * 4 ? 2048 * 4 : size;
  else if (size < 2048)
    len = size;
  else
    len = 2048;
  for (i = 0; i < len; i++) {
    *buff++ = (*(volatile unsigned char *)0x70200010);
  }
  delete_chip();
}


x86 assembly (clang, -O0):
<NF_Page_Read>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    $0x0,%al
call   1040 <select_chip@plt>
mov    $0x0,%al
call   1070 <clear_RnB@plt>
xor    %edi,%edi
call   1080 <send_cmd@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1030 <send_addr@plt>
xor    %eax,%eax
mov    %eax,%edi
call   1030 <send_addr@plt>
mov    -0x8(%rbp),%rdi
and    $0xff,%rdi
call   1030 <send_addr@plt>
mov    -0x8(%rbp),%rdi
shr    $0x8,%rdi
and    $0xff,%rdi
call   1030 <send_addr@plt>
mov    -0x8(%rbp),%rdi
shr    $0x10,%rdi
and    $0xff,%rdi
call   1030 <send_addr@plt>
mov    $0x30,%edi
call   1080 <send_cmd@plt>
mov    $0x0,%al
call   1050 <wait_RnB@plt>
cmpl   $0x800,-0x14(%rbp)
jle    121b <NF_Page_Read+0xbb>
cmpl   $0x2000,-0x14(%rbp)
jle    120a <NF_Page_Read+0xaa>
mov    $0x2000,%eax
mov    %eax,-0x20(%rbp)
jmp    1210 <NF_Page_Read+0xb0>
mov    -0x14(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    123f <NF_Page_Read+0xdf>
cmpl   $0x800,-0x14(%rbp)
jge    1233 <NF_Page_Read+0xd3>
mov    -0x14(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    123a <NF_Page_Read+0xda>
movl   $0x800,-0x1c(%rbp)
jmp    123f <NF_Page_Read+0xdf>
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1278 <NF_Page_Read+0x118>
mov    $0x70200010,%eax
mov    (%rax),%cl
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
mov    %cl,(%rax)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1246 <NF_Page_Read+0xe6>
mov    $0x0,%al
call   1060 <delete_chip@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<NF_Page_Read>:
push   %rbp
push   %r14
push   %rbx
mov    %edx,%r14d
mov    %rsi,%rbx
mov    %rdi,%rbp
xor    %eax,%eax
call   1040 <select_chip@plt>
xor    %eax,%eax
call   1070 <clear_RnB@plt>
xor    %edi,%edi
call   1080 <send_cmd@plt>
xor    %edi,%edi
call   1030 <send_addr@plt>
xor    %edi,%edi
call   1030 <send_addr@plt>
movzbl %bpl,%edi
call   1030 <send_addr@plt>
mov    %rbp,%rax
movzbl %ah,%edi
call   1030 <send_addr@plt>
shr    $0x10,%ebp
movzbl %bpl,%edi
call   1030 <send_addr@plt>
mov    $0x30,%edi
call   1080 <send_cmd@plt>
xor    %eax,%eax
call   1050 <wait_RnB@plt>
cmp    $0x2000,%r14d
mov    $0x2000,%eax
cmovl  %r14d,%eax
cmp    $0x801,%r14d
cmovl  %r14d,%eax
test   %eax,%eax
jle    1283 <NF_Page_Read+0x123>
lea    -0x1(%rax),%ecx
cmp    $0x7,%ecx
jb     1260 <NF_Page_Read+0x100>
mov    %eax,%ecx
and    $0xfffffff8,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl 0x70200010,%edx
70
mov    %dl,(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x1(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x2(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x3(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x4(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x5(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x6(%rbx)
movzbl 0x70200010,%edx
70
mov    %dl,0x7(%rbx)
add    $0x8,%rbx
add    $0xfffffff8,%ecx
jne    1200 <NF_Page_Read+0xa0>
test   $0x7,%al
je     1283 <NF_Page_Read+0x123>
and    $0x7,%eax
xor    %ecx,%ecx
nopl   0x0(%rax)
movzbl 0x70200010,%edx
70
mov    %dl,(%rbx,%rcx,1)
add    $0x1,%rcx
cmp    %ecx,%eax
jne    1270 <NF_Page_Read+0x110>
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %rbp
jmp    1060 <delete_chip@plt>

LLVM IR (-O0):
define void @NF_Page_Read(i64 %0, i8* %1, i32 %2) {
%4 = alloca i64
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i64 %0, i64* %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%9 = call i32 (...) @select_chip()
%10 = call i32 (...) @clear_RnB()
%11 = call i32 @send_cmd(i32 0)
%12 = call i32 @send_addr(i64 0)
%13 = call i32 @send_addr(i64 0)
%14 = load i64, i64* %4
%15 = and i64 %14, 255
%16 = call i32 @send_addr(i64 %15)
%17 = load i64, i64* %4
%18 = lshr i64 %17, 8
%19 = and i64 %18, 255
%20 = call i32 @send_addr(i64 %19)
%21 = load i64, i64* %4
%22 = lshr i64 %21, 16
%23 = and i64 %22, 255
%24 = call i32 @send_addr(i64 %23)
%25 = call i32 @send_cmd(i32 48)
%26 = call i32 (...) @wait_RnB()
%27 = load i32, i32* %6
%28 = icmp sgt i32 %27, 2048
br i1 %28, label %29, label %37
29: ; preds = %3
%30 = load i32, i32* %6
%31 = icmp sgt i32 %30, 8192
br i1 %31, label %32, label %33
32: ; preds = %29
br label %35
33: ; preds = %29
%34 = load i32, i32* %6
br label %35
35: ; preds = %33, %32
%36 = phi i32 [ 8192, %32 ], [ %34, %33 ]
store i32 %36, i32* %8
br label %44
37: ; preds = %3
%38 = load i32, i32* %6
%39 = icmp slt i32 %38, 2048
br i1 %39, label %40, label %42
40: ; preds = %37
%41 = load i32, i32* %6
store i32 %41, i32* %8
br label %43
42: ; preds = %37
store i32 2048, i32* %8
br label %43
43: ; preds = %42, %40
br label %44
44: ; preds = %43, %35
store i32 0, i32* %7
br label %45
45: ; preds = %53, %44
%46 = load i32, i32* %7
%47 = load i32, i32* %8
%48 = icmp slt i32 %46, %47
br i1 %48, label %49, label %56
49: ; preds = %45
%50 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%51 = load i8*, i8** %5
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %5
store i8 %50, i8* %51
br label %53
53: ; preds = %49
%54 = load i32, i32* %7
%55 = add nsw i32 %54, 1
store i32 %55, i32* %7
br label %45
56: ; preds = %45
%57 = call i32 (...) @delete_chip()
ret void
}

LLVM IR (-O2):
define void @NF_Page_Read(i64 %0, i8* nocapture writeonly %1, i32 %2) {
%4 = tail call i32 (...) @select_chip()
%5 = tail call i32 (...) @clear_RnB()
%6 = tail call i32 @send_cmd(i32 0)
%7 = tail call i32 @send_addr(i64 0)
%8 = tail call i32 @send_addr(i64 0)
%9 = and i64 %0, 255
%10 = tail call i32 @send_addr(i64 %9)
%11 = lshr i64 %0, 8
%12 = and i64 %11, 255
%13 = tail call i32 @send_addr(i64 %12)
%14 = lshr i64 %0, 16
%15 = and i64 %14, 255
%16 = tail call i32 @send_addr(i64 %15)
%17 = tail call i32 @send_cmd(i32 48)
%18 = tail call i32 (...) @wait_RnB()
%19 = icmp sgt i32 %2, 2048
%20 = icmp slt i32 %2, 8192
%21 = select i1 %20, i32 %2, i32 8192
%22 = select i1 %19, i32 %21, i32 %2
%23 = icmp sgt i32 %22, 0
br i1 %23, label %24, label %61
24: ; preds = %3
%25 = add i32 %22, -1
%26 = and i32 %22, 7
%27 = icmp ult i32 %25, 7
br i1 %27, label %51, label %28
28: ; preds = %24
%29 = and i32 %22, -8
br label %30
30: ; preds = %30, %28
%31 = phi i8* [ %1, %28 ], [ %48, %30 ]
%32 = phi i32 [ 0, %28 ], [ %49, %30 ]
%33 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%34 = getelementptr inbounds i8, i8* %31, i64 1
store i8 %33, i8* %31
%35 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%36 = getelementptr inbounds i8, i8* %31, i64 2
store i8 %35, i8* %34
%37 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%38 = getelementptr inbounds i8, i8* %31, i64 3
store i8 %37, i8* %36
%39 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%40 = getelementptr inbounds i8, i8* %31, i64 4
store i8 %39, i8* %38
%41 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%42 = getelementptr inbounds i8, i8* %31, i64 5
store i8 %41, i8* %40
%43 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%44 = getelementptr inbounds i8, i8* %31, i64 6
store i8 %43, i8* %42
%45 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%46 = getelementptr inbounds i8, i8* %31, i64 7
store i8 %45, i8* %44
%47 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%48 = getelementptr inbounds i8, i8* %31, i64 8
store i8 %47, i8* %46
%49 = add i32 %32, 8
%50 = icmp eq i32 %49, %29
br i1 %50, label %51, label %30
51: ; preds = %30, %24
%52 = phi i8* [ %1, %24 ], [ %48, %30 ]
%53 = icmp eq i32 %26, 0
br i1 %53, label %61, label %54
54: ; preds = %51, %54
%55 = phi i8* [ %58, %54 ], [ %52, %51 ]
%56 = phi i32 [ %59, %54 ], [ 0, %51 ]
%57 = load volatile i8, i8* inttoptr (i64 1881145360 to i8*)
%58 = getelementptr inbounds i8, i8* %55, i64 1
store i8 %57, i8* %55
%59 = add i32 %56, 1
%60 = icmp eq i32 %59, %26
br i1 %60, label %61, label %54
61: ; preds = %51, %54, %3
%62 = tail call i32 (...) @delete_chip()
ret void
}