#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*/ blockUntilMessage();
int /*<<< orphan*/ delay(int);
char readIRBit();
unsigned short readInfraredMessage() {
  unsigned short message = 0x3000;
  blockUntilMessage();
  delay(1778 * 2);
  for (char i = 12; i > 0; i--) {
    message |= readIRBit() << i;
    delay(1778);
  }
  return message;
}


x86 assembly (clang, -O0):
<readInfraredMessage>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movw   $0x3000,-0x2(%rbp)
mov    $0x0,%al
call   1040 <blockUntilMessage@plt>
mov    $0xde4,%edi
call   1050 <delay@plt>
movb   $0xc,-0x3(%rbp)
movsbl -0x3(%rbp),%eax
cmp    $0x0,%eax
jle    1193 <readInfraredMessage+0x63>
mov    $0x0,%al
call   1030 <readIRBit@plt>
movsbl %al,%eax
movsbl -0x3(%rbp),%ecx
shl    %cl,%eax
mov    %eax,%ecx
movzwl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %ax,-0x2(%rbp)
mov    $0x6f2,%edi
call   1050 <delay@plt>
mov    -0x3(%rbp),%al
add    $0xff,%al
mov    %al,-0x3(%rbp)
jmp    1153 <readInfraredMessage+0x23>
movzwl -0x2(%rbp),%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<readInfraredMessage>:
push   %rbp
push   %r14
push   %rbx
xor    %eax,%eax
call   1040 <blockUntilMessage@plt>
mov    $0xde4,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movzbl %al,%ebp
shl    $0xc,%ebp
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movzbl %al,%ebx
shl    $0xb,%ebx
or     %ebp,%ebx
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movzbl %al,%r14d
shl    $0xa,%r14d
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movzbl %al,%ebp
shl    $0x9,%ebp
or     %r14d,%ebp
or     %ebx,%ebp
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movzbl %al,%r14d
shl    $0x8,%r14d
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebx
shl    $0x7,%ebx
or     %r14d,%ebx
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%r14d
shl    $0x6,%r14d
or     %ebx,%r14d
or     %ebp,%r14d
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebx
shl    $0x5,%ebx
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebp
shl    $0x4,%ebp
or     %ebx,%ebp
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebx
shl    $0x3,%ebx
or     %ebp,%ebx
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebp
shl    $0x2,%ebp
or     %ebx,%ebp
or     %r14d,%ebp
mov    $0x6f2,%edi
call   1050 <delay@plt>
xor    %eax,%eax
call   1030 <readIRBit@plt>
movsbl %al,%ebx
add    %ebx,%ebx
or     %ebp,%ebx
or     $0x3000,%ebx
mov    $0x6f2,%edi
call   1050 <delay@plt>
mov    %ebx,%eax
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define zeroext i16 @readInfraredMessage() {
%1 = alloca i16
%2 = alloca i8
store i16 12288, i16* %1
%3 = call i32 (...) @blockUntilMessage()
%4 = call i32 @delay(i32 3556)
store i8 12, i8* %2
br label %5
5: ; preds = %20, %0
%6 = load i8, i8* %2
%7 = sext i8 %6 to i32
%8 = icmp sgt i32 %7, 0
br i1 %8, label %9, label %23
9: ; preds = %5
%10 = call signext i8 (...) @readIRBit()
%11 = sext i8 %10 to i32
%12 = load i8, i8* %2
%13 = sext i8 %12 to i32
%14 = shl i32 %11, %13
%15 = load i16, i16* %1
%16 = zext i16 %15 to i32
%17 = or i32 %16, %14
%18 = trunc i32 %17 to i16
store i16 %18, i16* %1
%19 = call i32 @delay(i32 1778)
br label %20
20: ; preds = %9
%21 = load i8, i8* %2
%22 = add i8 %21, -1
store i8 %22, i8* %2
br label %5
23: ; preds = %5
%24 = load i16, i16* %1
ret i16 %24
}

LLVM IR (-O2):
define zeroext i16 @readInfraredMessage() {
%1 = tail call i32 (...) @blockUntilMessage()
%2 = tail call i32 @delay(i32 3556)
%3 = tail call signext i8 (...) @readIRBit()
%4 = zext i8 %3 to i16
%5 = shl i16 %4, 12
%6 = tail call i32 @delay(i32 1778)
%7 = tail call signext i8 (...) @readIRBit()
%8 = zext i8 %7 to i16
%9 = shl i16 %8, 11
%10 = or i16 %5, %9
%11 = tail call i32 @delay(i32 1778)
%12 = tail call signext i8 (...) @readIRBit()
%13 = zext i8 %12 to i16
%14 = shl i16 %13, 10
%15 = or i16 %10, %14
%16 = tail call i32 @delay(i32 1778)
%17 = tail call signext i8 (...) @readIRBit()
%18 = zext i8 %17 to i16
%19 = shl i16 %18, 9
%20 = or i16 %15, %19
%21 = tail call i32 @delay(i32 1778)
%22 = tail call signext i8 (...) @readIRBit()
%23 = zext i8 %22 to i16
%24 = shl nuw i16 %23, 8
%25 = or i16 %20, %24
%26 = tail call i32 @delay(i32 1778)
%27 = tail call signext i8 (...) @readIRBit()
%28 = sext i8 %27 to i16
%29 = shl nsw i16 %28, 7
%30 = or i16 %25, %29
%31 = tail call i32 @delay(i32 1778)
%32 = tail call signext i8 (...) @readIRBit()
%33 = sext i8 %32 to i16
%34 = shl nsw i16 %33, 6
%35 = or i16 %30, %34
%36 = tail call i32 @delay(i32 1778)
%37 = tail call signext i8 (...) @readIRBit()
%38 = sext i8 %37 to i16
%39 = shl nsw i16 %38, 5
%40 = or i16 %35, %39
%41 = tail call i32 @delay(i32 1778)
%42 = tail call signext i8 (...) @readIRBit()
%43 = sext i8 %42 to i16
%44 = shl nsw i16 %43, 4
%45 = or i16 %40, %44
%46 = tail call i32 @delay(i32 1778)
%47 = tail call signext i8 (...) @readIRBit()
%48 = sext i8 %47 to i16
%49 = shl nsw i16 %48, 3
%50 = or i16 %45, %49
%51 = tail call i32 @delay(i32 1778)
%52 = tail call signext i8 (...) @readIRBit()
%53 = sext i8 %52 to i16
%54 = shl nsw i16 %53, 2
%55 = or i16 %50, %54
%56 = tail call i32 @delay(i32 1778)
%57 = tail call signext i8 (...) @readIRBit()
%58 = sext i8 %57 to i16
%59 = shl nsw i16 %58, 1
%60 = or i16 %55, %59
%61 = or i16 %60, 12288
%62 = tail call i32 @delay(i32 1778)
ret i16 %61
}