#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 */
typedef scalar_t__ uint8_t;
typedef int uint16_t;

/* Variables and functions */
int /*<<< orphan*/ eeprom_lock();
int /*<<< orphan*/ eeprom_unlock_data();
uint8_t eeprom_save_data(uint8_t *dst, uint8_t *src, uint8_t len) {
  uint16_t timeout;
  uint8_t sr;
  if (!eeprom_unlock_data())
    return 0;
  for (; len > 0; len--, dst++, src++) {
    *dst = *src;
    *(unsigned char *)0x50E0 = 0xAA;
  }
  for (timeout = 0xFFFF; timeout > 0; timeout--) {
    *(unsigned char *)0x50E0 = 0xAA;
    sr = *(unsigned char *)0x505F;
    if (sr & (1 << 2))
      break;
  }
  if (sr & (1 << 0))
    timeout = 0;
  eeprom_lock();
  return (timeout > 0);
}


x86 assembly (clang, -O0):
<eeprom_save_data>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    $0x0,%al
call   1030 <eeprom_unlock_data@plt>
cmp    $0x0,%eax
jne    1151 <eeprom_save_data+0x31>
movq   $0x0,-0x8(%rbp)
jmp    1221 <eeprom_save_data+0x101>
jmp    1156 <eeprom_save_data+0x36>
cmpq   $0x0,-0x20(%rbp)
jle    11a0 <eeprom_save_data+0x80>
mov    -0x18(%rbp),%rax
mov    (%rax),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    $0x50e0,%eax
movb   $0xaa,(%rax)
mov    -0x20(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x18(%rbp)
jmp    1156 <eeprom_save_data+0x36>
movl   $0xffff,-0x24(%rbp)
cmpl   $0x0,-0x24(%rbp)
jle    11ef <eeprom_save_data+0xcf>
mov    $0x50e0,%eax
movb   $0xaa,(%rax)
mov    $0x505f,%eax
movzbl (%rax),%eax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
and    $0x4,%rax
cmp    $0x0,%rax
je     11dc <eeprom_save_data+0xbc>
jmp    11ef <eeprom_save_data+0xcf>
jmp    11e1 <eeprom_save_data+0xc1>
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    11a7 <eeprom_save_data+0x87>
mov    -0x30(%rbp),%rax
and    $0x1,%rax
cmp    $0x0,%rax
je     1208 <eeprom_save_data+0xe8>
movl   $0x0,-0x24(%rbp)
mov    $0x0,%al
call   1040 <eeprom_lock@plt>
cmpl   $0x0,-0x24(%rbp)
setg   %al
and    $0x1,%al
movzbl %al,%eax
cltq
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<eeprom_save_data>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %rdx,%rbx
mov    %rsi,%r14
mov    %rdi,%r15
xor    %r12d,%r12d
xor    %eax,%eax
call   1030 <eeprom_unlock_data@plt>
test   %eax,%eax
je     1349 <eeprom_save_data+0x229>
test   %rbx,%rbx
jle    12ce <eeprom_save_data+0x1ae>
cmp    $0x4,%rbx
jb     12a3 <eeprom_save_data+0x183>
lea    (%r15,%rbx,8),%rcx
lea    (%r14,%rbx,8),%rsi
cmp    $0x50e1,%r15
setb   %r8b
cmp    $0x50e1,%rcx
setae  %dl
cmp    %r15,%rsi
seta   %al
cmp    %r14,%rcx
seta   %dil
cmp    $0x50e1,%rsi
setae  %cl
cmp    $0x50e1,%r14
setb   %sil
test   %dl,%r8b
jne    12a3 <eeprom_save_data+0x183>
and    %dil,%al
jne    12a3 <eeprom_save_data+0x183>
and    %sil,%cl
jne    12a3 <eeprom_save_data+0x183>
mov    %rbx,%rax
and    $0xfffffffffffffffc,%rax
lea    -0x4(%rax),%rdx
mov    %rdx,%rsi
shr    $0x2,%rsi
add    $0x1,%rsi
mov    %esi,%ecx
and    $0x3,%ecx
cmp    $0xc,%rdx
jae    11d8 <eeprom_save_data+0xb8>
xor    %edx,%edx
jmp    1250 <eeprom_save_data+0x130>
and    $0xfffffffffffffffc,%rsi
xor    %edx,%edx
xchg   %ax,%ax
movups (%r14,%rdx,8),%xmm0
movups 0x10(%r14,%rdx,8),%xmm1
movups %xmm0,(%r15,%rdx,8)
movups %xmm1,0x10(%r15,%rdx,8)
movups 0x20(%r14,%rdx,8),%xmm0
movups 0x30(%r14,%rdx,8),%xmm1
movups %xmm0,0x20(%r15,%rdx,8)
movups %xmm1,0x30(%r15,%rdx,8)
movups 0x40(%r14,%rdx,8),%xmm0
movups 0x50(%r14,%rdx,8),%xmm1
movups %xmm0,0x40(%r15,%rdx,8)
movups %xmm1,0x50(%r15,%rdx,8)
movups 0x60(%r14,%rdx,8),%xmm0
movups 0x70(%r14,%rdx,8),%xmm1
movups %xmm0,0x60(%r15,%rdx,8)
movups %xmm1,0x70(%r15,%rdx,8)
add    $0x10,%rdx
add    $0xfffffffffffffffc,%rsi
jne    11e0 <eeprom_save_data+0xc0>
movb   $0xaa,0x50e0
aa
test   %rcx,%rcx
je     1293 <eeprom_save_data+0x173>
lea    (%r15,%rdx,8),%rsi
add    $0x10,%rsi
lea    (%r14,%rdx,8),%rdx
add    $0x10,%rdx
shl    $0x5,%rcx
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movups -0x10(%rdx,%rdi,1),%xmm0
movups (%rdx,%rdi,1),%xmm1
movups %xmm0,-0x10(%rsi,%rdi,1)
movups %xmm1,(%rsi,%rdi,1)
add    $0x20,%rdi
cmp    %rdi,%rcx
jne    1270 <eeprom_save_data+0x150>
movb   $0xaa,0x50e0
aa
cmp    %rbx,%rax
je     12ce <eeprom_save_data+0x1ae>
and    $0x3,%ebx
lea    (%r14,%rax,8),%r14
lea    (%r15,%rax,8),%r15
add    $0x1,%rbx
xor    %eax,%eax
nopl   0x0(%rax)
mov    (%r14,%rax,1),%rcx
mov    %rcx,(%r15,%rax,1)
movb   $0xaa,0x50e0
aa
add    $0xffffffffffffffff,%rbx
add    $0x8,%rax
cmp    $0x1,%rbx
ja     12b0 <eeprom_save_data+0x190>
mov    $0x10000,%ebx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movb   $0xaa,0x50e0
aa
movzbl 0x505f,%eax
test   $0x4,%al
jne    1328 <eeprom_save_data+0x208>
movb   $0xaa,0x50e0
aa
movzbl 0x505f,%eax
test   $0x4,%al
jne    132d <eeprom_save_data+0x20d>
movb   $0xaa,0x50e0
aa
movzbl 0x505f,%eax
add    $0xfffffffd,%ebx
test   $0x4,%al
jne    1330 <eeprom_save_data+0x210>
cmp    $0x1,%ebx
ja     12e0 <eeprom_save_data+0x1c0>
xor    %ebx,%ebx
jmp    1330 <eeprom_save_data+0x210>
add    $0xffffffff,%ebx
jmp    1330 <eeprom_save_data+0x210>
add    $0xfffffffe,%ebx
test   $0x1,%al
sete   %bpl
xor    %eax,%eax
call   1040 <eeprom_lock@plt>
test   %ebx,%ebx
setg   %al
and    %bpl,%al
movzbl %al,%r12d
mov    %r12,%rax
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i64 @eeprom_save_data(i64* %0, i64* %1, i64 %2) {
%4 = alloca i64
%5 = alloca i64*
%6 = alloca i64*
%7 = alloca i64
%8 = alloca i32
%9 = alloca i64
store i64* %0, i64** %5
store i64* %1, i64** %6
store i64 %2, i64* %7
%10 = call i32 (...) @eeprom_unlock_data()
%11 = icmp ne i32 %10, 0
br i1 %11, label %13, label %12
12: ; preds = %3
store i64 0, i64* %4
br label %54
13: ; preds = %3
br label %14
14: ; preds = %21, %13
%15 = load i64, i64* %7
%16 = icmp sgt i64 %15, 0
br i1 %16, label %17, label %28
17: ; preds = %14
%18 = load i64*, i64** %6
%19 = load i64, i64* %18
%20 = load i64*, i64** %5
store i64 %19, i64* %20
store i8 -86, i8* inttoptr (i64 20704 to i8*)
br label %21
21: ; preds = %17
%22 = load i64, i64* %7
%23 = add nsw i64 %22, -1
store i64 %23, i64* %7
%24 = load i64*, i64** %5
%25 = getelementptr inbounds i64, i64* %24, i32 1
store i64* %25, i64** %5
%26 = load i64*, i64** %6
%27 = getelementptr inbounds i64, i64* %26, i32 1
store i64* %27, i64** %6
br label %14
28: ; preds = %14
store i32 65535, i32* %8
br label %29
29: ; preds = %40, %28
%30 = load i32, i32* %8
%31 = icmp sgt i32 %30, 0
br i1 %31, label %32, label %43
32: ; preds = %29
store i8 -86, i8* inttoptr (i64 20704 to i8*)
%33 = load i8, i8* inttoptr (i64 20575 to i8*)
%34 = zext i8 %33 to i64
store i64 %34, i64* %9
%35 = load i64, i64* %9
%36 = and i64 %35, 4
%37 = icmp ne i64 %36, 0
br i1 %37, label %38, label %39
38: ; preds = %32
br label %43
39: ; preds = %32
br label %40
40: ; preds = %39
%41 = load i32, i32* %8
%42 = add nsw i32 %41, -1
store i32 %42, i32* %8
br label %29
43: ; preds = %38, %29
%44 = load i64, i64* %9
%45 = and i64 %44, 1
%46 = icmp ne i64 %45, 0
br i1 %46, label %47, label %48
47: ; preds = %43
store i32 0, i32* %8
br label %48
48: ; preds = %47, %43
%49 = call i32 (...) @eeprom_lock()
%50 = load i32, i32* %8
%51 = icmp sgt i32 %50, 0
%52 = zext i1 %51 to i32
%53 = sext i32 %52 to i64
store i64 %53, i64* %4
br label %54
54: ; preds = %48, %12
%55 = load i64, i64* %4
ret i64 %55
}

LLVM IR (-O2):
define i64 @eeprom_save_data(i64* nocapture writeonly %0, i64* nocapture %1, i64 %2) {
%4 = tail call i32 (...) @eeprom_unlock_data()
%5 = icmp eq i32 %4, 0
br i1 %5, label %150, label %6
6: ; preds = %3
%7 = icmp sgt i64 %2, 0
br i1 %7, label %8, label %121
8: ; preds = %6
%9 = icmp ult i64 %2, 4
br i1 %9, label %108, label %10
10: ; preds = %8
%11 = getelementptr i64, i64* %0, i64 %2
%12 = getelementptr i64, i64* %1, i64 %2
%13 = icmp ult i64* %0, inttoptr (i64 20705 to i64*)
%14 = icmp ugt i64* %11, inttoptr (i64 20704 to i64*)
%15 = and i1 %13, %14
%16 = icmp ugt i64* %12, %0
%17 = icmp ugt i64* %11, %1
%18 = and i1 %16, %17
%19 = or i1 %15, %18
%20 = icmp ugt i64* %12, inttoptr (i64 20704 to i64*)
%21 = icmp ult i64* %1, inttoptr (i64 20705 to i64*)
%22 = and i1 %20, %21
%23 = or i1 %19, %22
br i1 %23, label %108, label %24
24: ; preds = %10
%25 = and i64 %2, -4
%26 = and i64 %2, 3
%27 = getelementptr i64, i64* %1, i64 %25
%28 = getelementptr i64, i64* %0, i64 %25
%29 = add i64 %25, -4
%30 = lshr exact i64 %29, 2
%31 = add nuw nsw i64 %30, 1
%32 = and i64 %31, 3
%33 = icmp ult i64 %29, 12
br i1 %33, label %86, label %34
34: ; preds = %24
%35 = and i64 %31, 9223372036854775804
br label %36
36: ; preds = %36, %34
%37 = phi i64 [ 0, %34 ], [ %82, %36 ]
%38 = phi i64 [ 0, %34 ], [ %83, %36 ]
%39 = getelementptr i64, i64* %1, i64 %37
%40 = getelementptr i64, i64* %0, i64 %37
%41 = bitcast i64* %39 to <2 x i64>*
%42 = load <2 x i64>, <2 x i64>* %41
%43 = getelementptr i64, i64* %39, i64 2
%44 = bitcast i64* %43 to <2 x i64>*
%45 = load <2 x i64>, <2 x i64>* %44
%46 = bitcast i64* %40 to <2 x i64>*
store <2 x i64> %42, <2 x i64>* %46
%47 = getelementptr i64, i64* %40, i64 2
%48 = bitcast i64* %47 to <2 x i64>*
store <2 x i64> %45, <2 x i64>* %48
%49 = or i64 %37, 4
%50 = getelementptr i64, i64* %1, i64 %49
%51 = getelementptr i64, i64* %0, i64 %49
%52 = bitcast i64* %50 to <2 x i64>*
%53 = load <2 x i64>, <2 x i64>* %52
%54 = getelementptr i64, i64* %50, i64 2
%55 = bitcast i64* %54 to <2 x i64>*
%56 = load <2 x i64>, <2 x i64>* %55
%57 = bitcast i64* %51 to <2 x i64>*
store <2 x i64> %53, <2 x i64>* %57
%58 = getelementptr i64, i64* %51, i64 2
%59 = bitcast i64* %58 to <2 x i64>*
store <2 x i64> %56, <2 x i64>* %59
%60 = or i64 %37, 8
%61 = getelementptr i64, i64* %1, i64 %60
%62 = getelementptr i64, i64* %0, i64 %60
%63 = bitcast i64* %61 to <2 x i64>*
%64 = load <2 x i64>, <2 x i64>* %63
%65 = getelementptr i64, i64* %61, i64 2
%66 = bitcast i64* %65 to <2 x i64>*
%67 = load <2 x i64>, <2 x i64>* %66
%68 = bitcast i64* %62 to <2 x i64>*
store <2 x i64> %64, <2 x i64>* %68
%69 = getelementptr i64, i64* %62, i64 2
%70 = bitcast i64* %69 to <2 x i64>*
store <2 x i64> %67, <2 x i64>* %70
%71 = or i64 %37, 12
%72 = getelementptr i64, i64* %1, i64 %71
%73 = getelementptr i64, i64* %0, i64 %71
%74 = bitcast i64* %72 to <2 x i64>*
%75 = load <2 x i64>, <2 x i64>* %74
%76 = getelementptr i64, i64* %72, i64 2
%77 = bitcast i64* %76 to <2 x i64>*
%78 = load <2 x i64>, <2 x i64>* %77
%79 = bitcast i64* %73 to <2 x i64>*
store <2 x i64> %75, <2 x i64>* %79
%80 = getelementptr i64, i64* %73, i64 2
%81 = bitcast i64* %80 to <2 x i64>*
store <2 x i64> %78, <2 x i64>* %81
%82 = add nuw i64 %37, 16
%83 = add nuw i64 %38, 4
%84 = icmp eq i64 %83, %35
br i1 %84, label %85, label %36
85: ; preds = %36
store i8 -86, i8* inttoptr (i64 20704 to i8*)
br label %86
86: ; preds = %85, %24
%87 = phi i64 [ 0, %24 ], [ %82, %85 ]
%88 = icmp eq i64 %32, 0
br i1 %88, label %106, label %89
89: ; preds = %86, %89
%90 = phi i64 [ %102, %89 ], [ %87, %86 ]
%91 = phi i64 [ %103, %89 ], [ 0, %86 ]
%92 = getelementptr i64, i64* %1, i64 %90
%93 = getelementptr i64, i64* %0, i64 %90
%94 = bitcast i64* %92 to <2 x i64>*
%95 = load <2 x i64>, <2 x i64>* %94
%96 = getelementptr i64, i64* %92, i64 2
%97 = bitcast i64* %96 to <2 x i64>*
%98 = load <2 x i64>, <2 x i64>* %97
%99 = bitcast i64* %93 to <2 x i64>*
store <2 x i64> %95, <2 x i64>* %99
%100 = getelementptr i64, i64* %93, i64 2
%101 = bitcast i64* %100 to <2 x i64>*
store <2 x i64> %98, <2 x i64>* %101
%102 = add nuw i64 %90, 4
%103 = add i64 %91, 1
%104 = icmp eq i64 %103, %32
br i1 %104, label %105, label %89
105: ; preds = %89
store i8 -86, i8* inttoptr (i64 20704 to i8*)
br label %106
106: ; preds = %86, %105
%107 = icmp eq i64 %25, %2
br i1 %107, label %121, label %108
108: ; preds = %10, %8, %106
%109 = phi i64 [ %2, %10 ], [ %2, %8 ], [ %26, %106 ]
%110 = phi i64* [ %1, %10 ], [ %1, %8 ], [ %27, %106 ]
%111 = phi i64* [ %0, %10 ], [ %0, %8 ], [ %28, %106 ]
br label %112
112: ; preds = %108, %112
%113 = phi i64 [ %117, %112 ], [ %109, %108 ]
%114 = phi i64* [ %119, %112 ], [ %110, %108 ]
%115 = phi i64* [ %118, %112 ], [ %111, %108 ]
%116 = load i64, i64* %114
store i64 %116, i64* %115
store i8 -86, i8* inttoptr (i64 20704 to i8*)
%117 = add nsw i64 %113, -1
%118 = getelementptr inbounds i64, i64* %115, i64 1
%119 = getelementptr inbounds i64, i64* %114, i64 1
%120 = icmp ugt i64 %113, 1
br i1 %120, label %112, label %121
121: ; preds = %112, %106, %6
br label %122
122: ; preds = %136, %121
%123 = phi i32 [ 65535, %121 ], [ %137, %136 ]
store i8 -86, i8* inttoptr (i64 20704 to i8*)
%124 = load i8, i8* inttoptr (i64 20575 to i8*)
%125 = and i8 %124, 4
%126 = icmp eq i8 %125, 0
br i1 %126, label %127, label %141
127: ; preds = %122
store i8 -86, i8* inttoptr (i64 20704 to i8*)
%128 = load i8, i8* inttoptr (i64 20575 to i8*)
%129 = and i8 %128, 4
%130 = icmp eq i8 %129, 0
br i1 %130, label %131, label %139
131: ; preds = %127
%132 = add nsw i32 %123, -2
store i8 -86, i8* inttoptr (i64 20704 to i8*)
%133 = load i8, i8* inttoptr (i64 20575 to i8*)
%134 = and i8 %133, 4
%135 = icmp eq i8 %134, 0
br i1 %135, label %136, label %141
136: ; preds = %131
%137 = add nsw i32 %123, -3
%138 = icmp ugt i32 %132, 1
br i1 %138, label %122, label %141
139: ; preds = %127
%140 = add nsw i32 %123, -1
br label %141
141: ; preds = %122, %131, %136, %139
%142 = phi i8 [ %128, %139 ], [ %133, %136 ], [ %133, %131 ], [ %124, %122 ]
%143 = phi i32 [ %140, %139 ], [ 0, %136 ], [ %132, %131 ], [ %123, %122 ]
%144 = and i8 %142, 1
%145 = icmp eq i8 %144, 0
%146 = tail call i32 (...) @eeprom_lock()
%147 = icmp sgt i32 %143, 0
%148 = select i1 %145, i1 %147, i1 false
%149 = zext i1 %148 to i64
br label %150
150: ; preds = %3, %141
%151 = phi i64 [ %149, %141 ], [ 0, %3 ]
ret i64 %151
}