#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 int time_t;
typedef int /*<<< orphan*/ date1970;
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
int getushort(int /*<<< orphan*/ *);
int /*<<< orphan*/ memset(int *, int /*<<< orphan*/, int);
time_t readdate(FILE *ttf) {
  int date[4], date1970[4], year[2];
  int i;
  date[3] = getushort(ttf);
  date[2] = getushort(ttf);
  date[1] = getushort(ttf);
  date[0] = getushort(ttf);
  memset(date1970, 0, sizeof(date1970));
  year[0] = (60 * 60 * 24 * 365L) & 0xffff;
  year[1] = (60 * 60 * 24 * 365L) >> 16;
  for (i = 1904; i < 1970; ++i) {
    date1970[0] += year[0];
    date1970[1] += year[1];
    if ((i & 3) == 0 && (i % 100 != 0 || i % 400 == 0))
      date1970[0] += 24 * 60 * 60L;
    date1970[1] += (date1970[0] >> 16);
    date1970[0] &= 0xffff;
    date1970[2] += date1970[1] >> 16;
    date1970[1] &= 0xffff;
    date1970[3] += date1970[2] >> 16;
    date1970[2] &= 0xffff;
  }
  for (i = 0; i < 3; ++i) {
    date[i] -= date1970[i];
    date[i + 1] += date[i] >> 16;
    date[i] &= 0xffff;
  }
  date[3] -= date1970[3];
  return ((date[1] << 16) | date[0]);
}


x86 assembly (clang, -O0):
<readdate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <getushort@plt>
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <getushort@plt>
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <getushort@plt>
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <getushort@plt>
mov    %eax,-0x20(%rbp)
lea    -0x30(%rbp),%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1030 <memset@plt>
movl   $0x3380,-0x38(%rbp)
movl   $0x1e1,-0x34(%rbp)
movl   $0x770,-0x3c(%rbp)
cmpl   $0x7b2,-0x3c(%rbp)
jge    1237 <readdate+0x117>
mov    -0x38(%rbp),%eax
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x3c(%rbp),%eax
and    $0x3,%eax
cmp    $0x0,%eax
jne    11e4 <readdate+0xc4>
mov    -0x3c(%rbp),%eax
mov    $0x64,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11d7 <readdate+0xb7>
mov    -0x3c(%rbp),%eax
mov    $0x190,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11e4 <readdate+0xc4>
movslq -0x30(%rbp),%rax
add    $0x15180,%rax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
add    -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x30(%rbp),%eax
and    $0xffff,%eax
mov    %eax,-0x30(%rbp)
mov    -0x2c(%rbp),%eax
sar    $0x10,%eax
add    -0x28(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
and    $0xffff,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x28(%rbp),%eax
sar    $0x10,%eax
add    -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x28(%rbp),%eax
and    $0xffff,%eax
mov    %eax,-0x28(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1181 <readdate+0x61>
movl   $0x0,-0x3c(%rbp)
cmpl   $0x3,-0x3c(%rbp)
jge    1299 <readdate+0x179>
movslq -0x3c(%rbp),%rax
mov    -0x30(%rbp,%rax,4),%edx
movslq -0x3c(%rbp),%rax
mov    -0x20(%rbp,%rax,4),%ecx
sub    %edx,%ecx
mov    %ecx,-0x20(%rbp,%rax,4)
movslq -0x3c(%rbp),%rax
mov    -0x20(%rbp,%rax,4),%ecx
sar    $0x10,%ecx
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
cltq
add    -0x20(%rbp,%rax,4),%ecx
mov    %ecx,-0x20(%rbp,%rax,4)
movslq -0x3c(%rbp),%rax
mov    -0x20(%rbp,%rax,4),%ecx
and    $0xffff,%ecx
mov    %ecx,-0x20(%rbp,%rax,4)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    123e <readdate+0x11e>
mov    -0x24(%rbp),%ecx
mov    -0x14(%rbp),%eax
sub    %ecx,%eax
mov    %eax,-0x14(%rbp)
mov    -0x1c(%rbp),%eax
shl    $0x10,%eax
or     -0x20(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<readdate>:
push   %rbp
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%rbp
call   1040 <getushort@plt>
mov    %rbp,%rdi
call   1040 <getushort@plt>
mov    %rbp,%rdi
call   1040 <getushort@plt>
mov    %eax,%ebx
mov    %rbp,%rdi
call   1040 <getushort@plt>
mov    %eax,%r14d
mov    %rsp,%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1030 <memset@plt>
mov    (%rsp),%edx
mov    0x4(%rsp),%ecx
mov    $0x770,%eax
jmp    1187 <readdate+0x67>
nopw   0x0(%rax,%rax,1)
mov    %esi,%edi
sar    $0x10,%edi
add    %ecx,%edi
movzwl %si,%edx
movzwl %di,%ecx
add    $0x1,%eax
cmp    $0x7b2,%eax
je     11d1 <readdate+0xb1>
lea    0x3380(%rdx),%esi
add    $0x1e1,%ecx
test   $0x3,%al
jne    1170 <readdate+0x50>
movzwl %ax,%ebp
mov    %ebp,%edi
shr    $0x4,%edi
imul   $0xa3e,%edi,%edi
shr    $0x10,%edi
imul   $0xfffffe70,%edi,%edi
shr    $0x2,%ebp
imul   $0x147b,%ebp,%ebp
shr    $0x11,%ebp
imul   $0xffffff9c,%ebp,%ebp
add    $0x18500,%edx
add    %ax,%di
cmove  %edx,%esi
add    %ax,%bp
cmovne %edx,%esi
jmp    1170 <readdate+0x50>
sub    %edx,%r14d
mov    %r14d,%eax
shr    $0x10,%eax
add    %eax,%ebx
movzwl %r14w,%eax
sub    %edi,%ebx
shl    $0x10,%ebx
or     %eax,%ebx
mov    %ebx,%eax
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define i32 @readdate(i32* %0) {
%2 = alloca i32*
%3 = alloca [4 x i32]
%4 = alloca [4 x i32]
%5 = alloca [2 x i32]
%6 = alloca i32
store i32* %0, i32** %2
%7 = load i32*, i32** %2
%8 = call i32 @getushort(i32* %7)
%9 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 3
store i32 %8, i32* %9
%10 = load i32*, i32** %2
%11 = call i32 @getushort(i32* %10)
%12 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 2
store i32 %11, i32* %12
%13 = load i32*, i32** %2
%14 = call i32 @getushort(i32* %13)
%15 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 1
store i32 %14, i32* %15
%16 = load i32*, i32** %2
%17 = call i32 @getushort(i32* %16)
%18 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 0
store i32 %17, i32* %18
%19 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%20 = call i32 @memset(i32* %19, i32 0, i32 16)
%21 = getelementptr inbounds [2 x i32], [2 x i32]* %5, i64 0, i64 0
store i32 13184, i32* %21
%22 = getelementptr inbounds [2 x i32], [2 x i32]* %5, i64 0, i64 1
store i32 481, i32* %22
store i32 1904, i32* %6
br label %23
23: ; preds = %82, %1
%24 = load i32, i32* %6
%25 = icmp slt i32 %24, 1970
br i1 %25, label %26, label %85
26: ; preds = %23
%27 = getelementptr inbounds [2 x i32], [2 x i32]* %5, i64 0, i64 0
%28 = load i32, i32* %27
%29 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%30 = load i32, i32* %29
%31 = add nsw i32 %30, %28
store i32 %31, i32* %29
%32 = getelementptr inbounds [2 x i32], [2 x i32]* %5, i64 0, i64 1
%33 = load i32, i32* %32
%34 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 1
%35 = load i32, i32* %34
%36 = add nsw i32 %35, %33
store i32 %36, i32* %34
%37 = load i32, i32* %6
%38 = and i32 %37, 3
%39 = icmp eq i32 %38, 0
br i1 %39, label %40, label %54
40: ; preds = %26
%41 = load i32, i32* %6
%42 = srem i32 %41, 100
%43 = icmp ne i32 %42, 0
br i1 %43, label %48, label %44
44: ; preds = %40
%45 = load i32, i32* %6
%46 = srem i32 %45, 400
%47 = icmp eq i32 %46, 0
br i1 %47, label %48, label %54
48: ; preds = %44, %40
%49 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%50 = load i32, i32* %49
%51 = sext i32 %50 to i64
%52 = add nsw i64 %51, 86400
%53 = trunc i64 %52 to i32
store i32 %53, i32* %49
br label %54
54: ; preds = %48, %44, %26
%55 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%56 = load i32, i32* %55
%57 = ashr i32 %56, 16
%58 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 1
%59 = load i32, i32* %58
%60 = add nsw i32 %59, %57
store i32 %60, i32* %58
%61 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 0
%62 = load i32, i32* %61
%63 = and i32 %62, 65535
store i32 %63, i32* %61
%64 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 1
%65 = load i32, i32* %64
%66 = ashr i32 %65, 16
%67 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 2
%68 = load i32, i32* %67
%69 = add nsw i32 %68, %66
store i32 %69, i32* %67
%70 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 1
%71 = load i32, i32* %70
%72 = and i32 %71, 65535
store i32 %72, i32* %70
%73 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 2
%74 = load i32, i32* %73
%75 = ashr i32 %74, 16
%76 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 3
%77 = load i32, i32* %76
%78 = add nsw i32 %77, %75
store i32 %78, i32* %76
%79 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 2
%80 = load i32, i32* %79
%81 = and i32 %80, 65535
store i32 %81, i32* %79
br label %82
82: ; preds = %54
%83 = load i32, i32* %6
%84 = add nsw i32 %83, 1
store i32 %84, i32* %6
br label %23
85: ; preds = %23
store i32 0, i32* %6
br label %86
86: ; preds = %115, %85
%87 = load i32, i32* %6
%88 = icmp slt i32 %87, 3
br i1 %88, label %89, label %118
89: ; preds = %86
%90 = load i32, i32* %6
%91 = sext i32 %90 to i64
%92 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 %91
%93 = load i32, i32* %92
%94 = load i32, i32* %6
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 %95
%97 = load i32, i32* %96
%98 = sub nsw i32 %97, %93
store i32 %98, i32* %96
%99 = load i32, i32* %6
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 %100
%102 = load i32, i32* %101
%103 = ashr i32 %102, 16
%104 = load i32, i32* %6
%105 = add nsw i32 %104, 1
%106 = sext i32 %105 to i64
%107 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 %106
%108 = load i32, i32* %107
%109 = add nsw i32 %108, %103
store i32 %109, i32* %107
%110 = load i32, i32* %6
%111 = sext i32 %110 to i64
%112 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 %111
%113 = load i32, i32* %112
%114 = and i32 %113, 65535
store i32 %114, i32* %112
br label %115
115: ; preds = %89
%116 = load i32, i32* %6
%117 = add nsw i32 %116, 1
store i32 %117, i32* %6
br label %86
118: ; preds = %86
%119 = getelementptr inbounds [4 x i32], [4 x i32]* %4, i64 0, i64 3
%120 = load i32, i32* %119
%121 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 3
%122 = load i32, i32* %121
%123 = sub nsw i32 %122, %120
store i32 %123, i32* %121
%124 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 1
%125 = load i32, i32* %124
%126 = shl i32 %125, 16
%127 = getelementptr inbounds [4 x i32], [4 x i32]* %3, i64 0, i64 0
%128 = load i32, i32* %127
%129 = or i32 %126, %128
ret i32 %129
}

LLVM IR (-O2):
define i32 @readdate(i32* %0) {
%2 = alloca [4 x i32]
%3 = bitcast [4 x i32]* %2 to i8*
%4 = tail call i32 @getushort(i32* %0)
%5 = tail call i32 @getushort(i32* %0)
%6 = tail call i32 @getushort(i32* %0)
%7 = tail call i32 @getushort(i32* %0)
%8 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 0
%9 = call i32 @memset(i32* %8, i32 0, i32 16)
%10 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 1
%11 = getelementptr inbounds [4 x i32], [4 x i32]* %2, i64 0, i64 2
%12 = load i32, i32* %8
%13 = load i32, i32* %10
%14 = load i32, i32* %11
br label %23
15: ; preds = %41
%16 = sub nsw i32 %7, %45
%17 = lshr i32 %16, 16
%18 = add i32 %6, %17
%19 = and i32 %16, 65535
%20 = sub i32 %18, %44
%21 = shl i32 %20, 16
%22 = or i32 %21, %19
ret i32 %22
23: ; preds = %1, %41
%24 = phi i32 [ 1904, %1 ], [ %50, %41 ]
%25 = phi i32 [ %12, %1 ], [ %45, %41 ]
%26 = phi i32 [ %13, %1 ], [ %48, %41 ]
%27 = phi i32 [ %14, %1 ], [ %49, %41 ]
%28 = add nsw i32 %25, 13184
%29 = add nsw i32 %26, 481
%30 = and i32 %24, 3
%31 = icmp eq i32 %30, 0
br i1 %31, label %32, label %41
32: ; preds = %23
%33 = trunc i32 %24 to i16
%34 = urem i16 %33, 100
%35 = icmp ne i16 %34, 0
%36 = urem i16 %33, 400
%37 = icmp eq i16 %36, 0
%38 = or i1 %35, %37
%39 = add i32 %25, 99584
%40 = select i1 %38, i32 %39, i32 %28
br label %41
41: ; preds = %32, %23
%42 = phi i32 [ %28, %23 ], [ %40, %32 ]
%43 = ashr i32 %42, 16
%44 = add nsw i32 %43, %29
%45 = and i32 %42, 65535
%46 = lshr i32 %44, 16
%47 = add i32 %27, %46
%48 = and i32 %44, 65535
%49 = and i32 %47, 65535
%50 = add nuw nsw i32 %24, 1
%51 = icmp eq i32 %50, 1970
br i1 %51, label %15, label %23
}