// File: /workspace/github_c_makefile_star2_O2/jsummers[P]deark/src/deark-util.c
// Function: de_gmtime
void de_gmtime(const struct de_timestamp *ts, struct de_struct_tm *tm2)
{
	// Let's define an "eon" to be a 400-year period. Eons begin at the start
	// of the year 1601, 2001, 2401, etc.
	static const i64 secs_per_eon = 12622780800LL;
	i64 eon;
	i64 secs_since_start_of_1601;
	i64 secs_since_start_of_eon;
	i64 days_since_start_of_eon;
	i64 secs_since_start_of_day;
	i64 yr_tmp; // years, since start of eon, accounted for so far
	i64 days_tmp; // number of days not accounted for in yr_tmp
	i64 count;
	int is_leapyear;
	int k;

	de_zeromem(tm2, sizeof(struct de_struct_tm));
	if(!ts->is_valid || ts->ts_FILETIME<=0) {
		return;
	}

	secs_since_start_of_1601 = ts->ts_FILETIME / 10000000;
	tm2->tm_subsec = ts->ts_FILETIME % 10000000;
	eon = secs_since_start_of_1601 / secs_per_eon;
	secs_since_start_of_eon = secs_since_start_of_1601 % secs_per_eon;
	days_since_start_of_eon = secs_since_start_of_eon / 86400;
	secs_since_start_of_day = secs_since_start_of_eon % 86400;
	tm2->tm_hour = (int)(secs_since_start_of_day / 3600);
	tm2->tm_min = (int)((secs_since_start_of_day % 3600)/60);
	tm2->tm_sec = (int)(secs_since_start_of_day % 60);

	days_tmp = days_since_start_of_eon;
	yr_tmp = 0;

	// The first 3 100-year periods in this eon have
	// 100*365 + 24 days each.
	count = days_tmp / (100*365 + 24);
	if(count>3) count = 3;
	days_tmp -= (100*365 + 24)*count;
	yr_tmp += 100*count;

	// The first 24 4-year periods in this 100-year period have
	// 1 leap day each.
	count = days_tmp / (4*365 + 1);
	if(count>24) count = 24;
	days_tmp -= (4*365 + 1)*count;
	yr_tmp += 4*count;

	// The first 3 years in this 4-year period are not leap years.
	count = days_tmp / 365;
	if(count>3) count = 3;
	days_tmp -= 365*count;
	yr_tmp += count;

	tm2->tm_fullyear = (int)(1601 + eon*400 + yr_tmp);
	is_leapyear = ((yr_tmp%4)==3 &&
		yr_tmp!=99 && yr_tmp!=199 && yr_tmp!=299);

	for(k=0; k<11; k++) {
		static const u8 days_in_month[11] = // (Don't need December)
			{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 };
		i64 days_in_this_month = (i64)days_in_month[k];
		if(k==1 && is_leapyear) days_in_this_month++;
		if(days_tmp >= days_in_this_month) {
			days_tmp -= days_in_this_month;
			tm2->tm_mon++;
		}
		else {
			break;
		}
	}

	tm2->tm_mday = (int)(1+days_tmp);
	tm2->is_valid = 1;
}

// Assembly:
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rsi)
movups %xmm0, (%rsi)
cmpb $0x0, (%rdi)
je 0xe0643
movq 0x8(%rdi), %rcx
testq %rcx, %rcx
jle 0xe0643
movl $0x989680, %edi         # imm = 0x989680
movq %rcx, %rax
xorl %edx, %edx
divq %rdi
movq %rax, %rdi
movl %edx, 0x1c(%rsi)
movabsq $0x1c07385c89dc000, %r8 # imm = 0x1C07385C89DC000
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rax, %rcx
movabsq $0x2f0605980, %r8       # imm = 0x2F0605980
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movq %rdx, %r8
movl $0x15180, %edi          # imm = 0x15180
movq %rdx, %rax
xorl %edx, %edx
divq %rdi
movq %rax, %rdi
movq %rdx, %r9
movl $0xe10, %r10d           # imm = 0xE10
movl %r9d, %eax
xorl %edx, %edx
divl %r10d
xorl %r10d, %r10d
movl %eax, 0x10(%rsi)
movw $0x3c, %r11w
movl %edx, %eax
xorl %edx, %edx
divw %r11w
movzwl %ax, %eax
movl %eax, 0x14(%rsi)
pushq $0x3c
popq %r11
movl %r9d, %eax
xorl %edx, %edx
divl %r11d
movl %edx, 0x18(%rsi)
movl $0xbc17c200, %r9d       # imm = 0xBC17C200
movq %r8, %rax
xorl %edx, %edx
divq %r9
cmpq $0x3, %rax
pushq $0x3
popq %rdx
cmovbq %rax, %rdx
imulq $-0x8eac, %rdx, %r8     # imm = 0xFFFF7154
addq %rdi, %r8
imulq $0x64, %rdx, %r9
movl $0x5b5, %edi            # imm = 0x5B5
movl %r8d, %eax
cltd
idivl %edi
cmpl $0x18, %eax
pushq $0x18
popq %rdx
cmovll %eax, %edx
movslq %edx, %rax
imulq $-0x5b5, %rax, %rdi     # imm = 0xFA4B
addq %r8, %rdi
leaq (%r9,%rax,4), %r8
movl $0x16d, %r9d            # imm = 0x16D
movl %edi, %eax
cltd
idivl %r9d
cmpl $0x3, %eax
pushq $0x3
popq %rdx
cmovll %eax, %edx
movslq %edx, %rdx
imulq $-0x16d, %rdx, %rax     # imm = 0xFE93
addq %rdx, %r8
imull $0x190, %ecx, %ecx      # imm = 0x190
addl %r8d, %ecx
addl $0x641, %ecx            # imm = 0x641
movl %ecx, 0x4(%rsi)
movabsq $-0x7ffffffffffffffd, %rcx # imm = 0x8000000000000003
andq %r8, %rcx
cmpq $0x3, %rcx
jne 0xe05fd
xorl %r10d, %r10d
cmpq $0x63, %r8
je 0xe05fd
cmpq $0xc7, %r8
je 0xe05fd
cmpq $0x12b, %r8             # imm = 0x12B
je 0xe05fd
movb $0x1, %r10b
addq %rdi, %rax
xorl %ecx, %ecx
leaq 0x58817(%rip), %rdx     # 0x138e20
cmpq $0xb, %rcx
je 0xe0638
movzbl (%rcx,%rdx), %edi
cmpq $0x1, %rcx
sete %r8b
andb %r10b, %r8b
movzbl %r8b, %r8d
addq %rdi, %r8
movq %rax, %rdi
subq %r8, %rdi
jl 0xe0638
incq %rcx
movl %ecx, 0x8(%rsi)
movq %rdi, %rax
jmp 0xe0609
incl %eax
movl %eax, 0xc(%rsi)
movl $0x1, (%rsi)
retq