#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*/ delay_ms(int);
unsigned short eeprom_read(short);
unsigned long read_code() {
  short idx;
  unsigned long code;
  unsigned short *_code = (unsigned short *)(&code);
  for (idx = 0; idx < 4; idx++) {
    delay_ms(20);
    _code[idx] = eeprom_read(idx);
  }
  return code;
}


x86 assembly (clang, -O0):
<read_code>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
lea    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
movw   $0x0,-0x2(%rbp)
movswl -0x2(%rbp),%eax
cmp    $0x4,%eax
jge    1177 <read_code+0x57>
mov    $0x14,%edi
call   1030 <delay_ms@plt>
movswl -0x2(%rbp),%edi
call   1040 <eeprom_read@plt>
mov    %ax,%dx
mov    -0x18(%rbp),%rax
movswq -0x2(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
mov    -0x2(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x2(%rbp)
jmp    1136 <read_code+0x16>
mov    -0x10(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<read_code>:
push   %rbp
push   %r14
push   %rbx
mov    $0x14,%edi
call   1030 <delay_ms@plt>
xor    %edi,%edi
call   1040 <eeprom_read@plt>
mov    %eax,%r14d
mov    $0x14,%edi
call   1030 <delay_ms@plt>
mov    $0x1,%edi
call   1040 <eeprom_read@plt>
mov    %eax,%ebp
mov    $0x14,%edi
call   1030 <delay_ms@plt>
mov    $0x2,%edi
call   1040 <eeprom_read@plt>
mov    %eax,%ebx
mov    $0x14,%edi
call   1030 <delay_ms@plt>
mov    $0x3,%edi
call   1040 <eeprom_read@plt>
movzwl %ax,%eax
shl    $0x30,%rax
movzwl %bx,%ecx
shl    $0x20,%rcx
or     %rax,%rcx
movzwl %bp,%edx
shl    $0x10,%rdx
or     %rcx,%rdx
movzwl %r14w,%eax
or     %rdx,%rax
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define i64 @read_code() {
%1 = alloca i16
%2 = alloca i64
%3 = alloca i16*
%4 = bitcast i64* %2 to i16*
store i16* %4, i16** %3
store i16 0, i16* %1
br label %5
5: ; preds = %17, %0
%6 = load i16, i16* %1
%7 = sext i16 %6 to i32
%8 = icmp slt i32 %7, 4
br i1 %8, label %9, label %20
9: ; preds = %5
%10 = call i32 @delay_ms(i32 20)
%11 = load i16, i16* %1
%12 = call zeroext i16 @eeprom_read(i16 signext %11)
%13 = load i16*, i16** %3
%14 = load i16, i16* %1
%15 = sext i16 %14 to i64
%16 = getelementptr inbounds i16, i16* %13, i64 %15
store i16 %12, i16* %16
br label %17
17: ; preds = %9
%18 = load i16, i16* %1
%19 = add i16 %18, 1
store i16 %19, i16* %1
br label %5
20: ; preds = %5
%21 = load i64, i64* %2
ret i64 %21
}

LLVM IR (-O2):
define i64 @read_code() {
%1 = tail call i32 @delay_ms(i32 20)
%2 = tail call zeroext i16 @eeprom_read(i16 signext 0)
%3 = tail call i32 @delay_ms(i32 20)
%4 = tail call zeroext i16 @eeprom_read(i16 signext 1)
%5 = tail call i32 @delay_ms(i32 20)
%6 = tail call zeroext i16 @eeprom_read(i16 signext 2)
%7 = tail call i32 @delay_ms(i32 20)
%8 = tail call zeroext i16 @eeprom_read(i16 signext 3)
%9 = zext i16 %8 to i64
%10 = shl nuw i64 %9, 48
%11 = zext i16 %6 to i64
%12 = shl nuw nsw i64 %11, 32
%13 = or i64 %10, %12
%14 = zext i16 %4 to i64
%15 = shl nuw nsw i64 %14, 16
%16 = or i64 %13, %15
%17 = zext i16 %2 to i64
%18 = or i64 %16, %17
ret i64 %18
}