void EEPROMRead(unsigned long *pulData, unsigned long ulAddress,
                unsigned long ulCount) {
  ;
  ;
  ;
  ;
  ;
  (*((volatile unsigned long *)(0x400AF004))) = ((ulAddress) >> 6);
  (*((volatile unsigned long *)(0x400AF008))) = (((ulAddress) >> 2) & 0x0F);
  ulCount /= 4;
  while (ulCount) {
    *pulData = (*((volatile unsigned long *)(0x400AF014)));
    pulData++;
    ulCount--;
    if ((*((volatile unsigned long *)(0x400AF008))) == 0) {
      (*((volatile unsigned long *)(0x400AF004))) += 1;
    }
  }
}


x86 assembly (clang, -O0):
<EEPROMRead>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rcx
shr    $0x6,%rcx
mov    $0x400af004,%eax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rcx
shr    $0x2,%rcx
and    $0xf,%rcx
mov    $0x400af008,%eax
mov    %rcx,(%rax)
mov    -0x18(%rbp),%rax
shr    $0x2,%rax
mov    %rax,-0x18(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     119d <EEPROMRead+0x9d>
mov    $0x400af014,%eax
mov    (%rax),%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
mov    $0x400af008,%eax
mov    (%rax),%rax
cmp    $0x0,%rax
jne    1198 <EEPROMRead+0x98>
mov    $0x400af004,%eax
mov    (%rax),%rcx
add    $0x1,%rcx
mov    $0x400af004,%eax
mov    %rcx,(%rax)
jmp    1140 <EEPROMRead+0x40>
pop    %rbp
ret

x86 assembly (clang, -O2):
<EEPROMRead>:
mov    %rsi,%rax
shr    $0x6,%rax
mov    %rax,0x400af004
40
shr    $0x2,%esi
and    $0xf,%esi
mov    %rsi,0x400af008
40
cmp    $0x4,%rdx
jb     115e <EEPROMRead+0x5e>
mov    %rdx,%rcx
shr    $0x2,%rcx
test   $0x4,%dl
jne    113a <EEPROMRead+0x3a>
mov    %rcx,%rax
cmp    $0x1,%rcx
je     115e <EEPROMRead+0x5e>
jmp    116e <EEPROMRead+0x6e>
mov    0x400af014,%rax
40
mov    %rax,(%rdi)
add    $0x8,%rdi
lea    -0x1(%rcx),%rax
cmpq   $0x0,0x400af008
je     115f <EEPROMRead+0x5f>
cmp    $0x1,%rcx
jne    116e <EEPROMRead+0x6e>
ret
addq   $0x1,0x400af004
40 01
cmp    $0x1,%rcx
je     115e <EEPROMRead+0x5e>
xor    %ecx,%ecx
jmp    1189 <EEPROMRead+0x89>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
add    $0x2,%rcx
cmp    %rcx,%rax
je     115e <EEPROMRead+0x5e>
mov    0x400af014,%rdx
40
mov    %rdx,(%rdi,%rcx,8)
cmpq   $0x0,0x400af008
jne    11a9 <EEPROMRead+0xa9>
addq   $0x1,0x400af004
40 01
mov    0x400af014,%rdx
40
mov    %rdx,0x8(%rdi,%rcx,8)
cmpq   $0x0,0x400af008
jne    1180 <EEPROMRead+0x80>
addq   $0x1,0x400af004
40 01
jmp    1180 <EEPROMRead+0x80>

LLVM IR (-O0):
define void @EEPROMRead(i64* %0, i64 %1, i64 %2) {
%4 = alloca i64*
%5 = alloca i64
%6 = alloca i64
store i64* %0, i64** %4
store i64 %1, i64* %5
store i64 %2, i64* %6
%7 = load i64, i64* %5
%8 = lshr i64 %7, 6
store volatile i64 %8, i64* inttoptr (i64 1074458628 to i64*)
%9 = load i64, i64* %5
%10 = lshr i64 %9, 2
%11 = and i64 %10, 15
store volatile i64 %11, i64* inttoptr (i64 1074458632 to i64*)
%12 = load i64, i64* %6
%13 = udiv i64 %12, 4
store i64 %13, i64* %6
br label %14
14: ; preds = %29, %3
%15 = load i64, i64* %6
%16 = icmp ne i64 %15, 0
br i1 %16, label %17, label %30
17: ; preds = %14
%18 = load volatile i64, i64* inttoptr (i64 1074458644 to i64*)
%19 = load i64*, i64** %4
store i64 %18, i64* %19
%20 = load i64*, i64** %4
%21 = getelementptr inbounds i64, i64* %20, i32 1
store i64* %21, i64** %4
%22 = load i64, i64* %6
%23 = add i64 %22, -1
store i64 %23, i64* %6
%24 = load volatile i64, i64* inttoptr (i64 1074458632 to i64*)
%25 = icmp eq i64 %24, 0
br i1 %25, label %26, label %29
26: ; preds = %17
%27 = load volatile i64, i64* inttoptr (i64 1074458628 to i64*)
%28 = add i64 %27, 1
store volatile i64 %28, i64* inttoptr (i64 1074458628 to i64*)
br label %29
29: ; preds = %26, %17
br label %14
30: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @EEPROMRead(i64* nocapture writeonly %0, i64 %1, i64 %2) {
%4 = lshr i64 %1, 6
store volatile i64 %4, i64* inttoptr (i64 1074458628 to i64*)
%5 = lshr i64 %1, 2
%6 = and i64 %5, 15
store volatile i64 %6, i64* inttoptr (i64 1074458632 to i64*)
%7 = icmp ult i64 %2, 4
br i1 %7, label %46, label %8
8: ; preds = %3
%9 = lshr i64 %2, 2
%10 = and i64 %2, 4
%11 = icmp eq i64 %10, 0
br i1 %11, label %21, label %12
12: ; preds = %8
%13 = load volatile i64, i64* inttoptr (i64 1074458644 to i64*)
store i64 %13, i64* %0
%14 = getelementptr inbounds i64, i64* %0, i64 1
%15 = add nsw i64 %9, -1
%16 = load volatile i64, i64* inttoptr (i64 1074458632 to i64*)
%17 = icmp eq i64 %16, 0
br i1 %17, label %18, label %21
18: ; preds = %12
%19 = load volatile i64, i64* inttoptr (i64 1074458628 to i64*)
%20 = add i64 %19, 1
store volatile i64 %20, i64* inttoptr (i64 1074458628 to i64*)
br label %21
21: ; preds = %12, %18, %8
%22 = phi i64 [ %9, %8 ], [ %15, %18 ], [ %15, %12 ]
%23 = phi i64* [ %0, %8 ], [ %14, %18 ], [ %14, %12 ]
%24 = icmp eq i64 %9, 1
br i1 %24, label %46, label %25
25: ; preds = %21, %44
%26 = phi i64 [ %38, %44 ], [ %22, %21 ]
%27 = phi i64* [ %37, %44 ], [ %23, %21 ]
%28 = load volatile i64, i64* inttoptr (i64 1074458644 to i64*)
store i64 %28, i64* %27
%29 = getelementptr inbounds i64, i64* %27, i64 1
%30 = load volatile i64, i64* inttoptr (i64 1074458632 to i64*)
%31 = icmp eq i64 %30, 0
br i1 %31, label %32, label %35
32: ; preds = %25
%33 = load volatile i64, i64* inttoptr (i64 1074458628 to i64*)
%34 = add i64 %33, 1
store volatile i64 %34, i64* inttoptr (i64 1074458628 to i64*)
br label %35
35: ; preds = %32, %25
%36 = load volatile i64, i64* inttoptr (i64 1074458644 to i64*)
store i64 %36, i64* %29
%37 = getelementptr inbounds i64, i64* %27, i64 2
%38 = add nsw i64 %26, -2
%39 = load volatile i64, i64* inttoptr (i64 1074458632 to i64*)
%40 = icmp eq i64 %39, 0
br i1 %40, label %41, label %44
41: ; preds = %35
%42 = load volatile i64, i64* inttoptr (i64 1074458628 to i64*)
%43 = add i64 %42, 1
store volatile i64 %43, i64* inttoptr (i64 1074458628 to i64*)
br label %44
44: ; preds = %41, %35
%45 = icmp eq i64 %38, 0
br i1 %45, label %46, label %25
46: ; preds = %21, %44, %3
ret void
}