// File: /workspace/github_c_makefile_star2_O2/mikecat[P]x86_interpreter/dmem_libc_time.c
// Function: dmem_libc_strftime
int dmem_libc_strftime(uint32_t* ret, uint32_t esp) {
	static const char* const weekday_name_full[] = {
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	};
	static const char* const weekday_name_abb[] = {
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
	};
	static const char* month_name_full[] = {
		"January", "February", "March", "April", "May", "June",
		"July", "August", "September", "October", "November", "December"
	};
	static const char* month_name_abb[] = {
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	};
	uint32_t out_ptr, out_max, format_ptr, tm_ptr;
	uint32_t sec, min, hour, mday, mon, year, wday, yday;
	char* format;
	char* out_data;
	const char* format_itr = NULL;
	const char* format_itr_ret = NULL;
	int alt_format = 0;
	uint32_t out_count = 0;
	int ok;
	if (!dmem_get_args(esp, 4, &out_ptr, &out_max, &format_ptr, &tm_ptr)) return 0;
	if (!dmemory_is_allocated(out_ptr, out_max)) return 0;

	sec = dmem_read_uint(&ok, tm_ptr + 0, 4); if (!ok) return 0;
	min = dmem_read_uint(&ok, tm_ptr + 4, 4); if (!ok) return 0;
	hour = dmem_read_uint(&ok, tm_ptr + 8, 4); if (!ok) return 0;
	mday = dmem_read_uint(&ok, tm_ptr + 12, 4); if (!ok) return 0;
	mon = dmem_read_uint(&ok, tm_ptr + 16, 4); if (!ok) return 0;
	year = dmem_read_uint(&ok, tm_ptr + 20, 4); if (!ok) return 0;
	wday = dmem_read_uint(&ok, tm_ptr + 24, 4); if (!ok) return 0;
	yday = dmem_read_uint(&ok, tm_ptr + 28, 4); if (!ok) return 0;

	format = dmem_read_string(format_ptr);
	if (format == NULL) return 0;
	out_data = malloc(out_max);
	if (out_data == NULL) {
		free(format);
		return 0;
	}

	for (format_itr = format; out_count < out_max;) {
		if (*format_itr == '\0' && alt_format) {
			format_itr = format_itr_ret;
			alt_format = 0;
		}
		if (*format_itr == '\0') {
			break;
		} else if (*format_itr == '%') {
			const char* append_str = NULL;
			int do_append_int = 0;
			uint32_t append_int_digits = 0;
			uint32_t append_int = 0;
			format_itr++;
			if (*format_itr == 'E' || *format_itr == 'O') format_itr++;
			if (*format_itr == '\0') break;
			switch (*(format_itr++)) {
			case 'a':
				if (wday < 7) append_str = weekday_name_abb[wday];
				break;
			case 'A':
				if (wday < 7) append_str = weekday_name_full[wday];
				break;
			case 'b':
				if (mon < 12) append_str = month_name_abb[mon];
				break;
			case 'B':
				if (mon < 12) append_str = month_name_full[mon];
				break;
			case 'c':
				format_itr_ret = format_itr;
				format_itr = "%a %b %e %H:%M:%S %Y"; /* "%a %b %e %T %Y" with %T expanded */
				alt_format = 1;
				break;
			case 'C':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = (year + 1900) / 100;
				break;
			case 'd':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = mday;
				break;
			case 'D':
				format_itr_ret = format_itr;
				format_itr = "%m/%d/%y";
				alt_format = 1;
				break;
			case 'e':
				if (mday < 10) {
					out_data[out_count++] = ' ';
					if (out_count < out_max) out_data[out_count++] = '0' + mday;
				} else {
					do_append_int = 1;
					append_int_digits = 2;
					append_int = mday;
				}
				break;
			case 'F':
				format_itr_ret = format_itr;
				format_itr = "%Y-%m-%d";
				alt_format = 1;
				break;
			case 'G':
				/* TODO (not supported) */
				append_str = "%G";
				break;
			case 'h':
				format_itr_ret = format_itr;
				format_itr = "%b";
				alt_format = 1;
				break;
			case 'H':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = hour;
				break;
			case 'I':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = hour % 12 == 0 ? 12 : hour % 12;
				break;
			case 'j':
				do_append_int = 1;
				append_int_digits = 3;
				append_int = yday + 1;
				break;
			case 'm':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = mon + 1;
				break;
			case 'M':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = min;
				break;
			case 'n':
				append_str = "\n";
				break;
			case 'p':
				append_str = hour >= 12 ? "PM" : "AM";
				break;
			case 'r':
				format_itr_ret = format_itr;
				format_itr = "%I:%M:%S %p";
				alt_format = 1;
				break;
			case 'R':
				format_itr_ret = format_itr;
				format_itr = "%H:%M";
				alt_format = 1;
				break;
			case 'S':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = sec;
				break;
			case 't':
				append_str = "\t";
				break;
			case 'T':
				format_itr_ret = format_itr;
				format_itr = "%H:%M:%S";
				alt_format = 1;
				break;
			case 'u':
				do_append_int = 1;
				append_int_digits = 1;
				append_int = wday == 0 ? 7 : wday;
				break;
			case 'U':
				/* TODO (not supported) */
				append_str = "%U";
				break;
			case 'V':
				/* TODO (not supported) */
				append_str = "%V";
				break;
			case 'w':
				do_append_int = 1;
				append_int_digits = 1;
				append_int = wday;
				break;
			case 'W':
				/* TODO (not supported) */
				append_str = "%W";
				break;
			case 'x':
				format_itr_ret = format_itr;
				format_itr = "%m/%d/%y";
				alt_format = 1;
				break;
			case 'X':
				format_itr_ret = format_itr;
				format_itr = "%H:%M:%S"; /* "%T" with %T expanded */
				alt_format = 1;
				break;
			case 'y':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = year % 100;
				break;
			case 'Y':
				do_append_int = 1;
				append_int_digits = 2;
				append_int = year + 1900;
				break;
			case 'z':
				append_str = "+0900";
				break;
			case 'Z':
				append_str = "JST";
				break;
			case '%':
				append_str = "%";
				break;
			}
			if (append_str != NULL) {
				const char* as_ptr = append_str;
				while (*as_ptr != '\0' && out_count < out_max) {
					out_data[out_count++] = *(as_ptr++);
				}
			}
			if (do_append_int) {
				uint64_t pos = 1;
				uint32_t i;
				for (i = 0; i < append_int_digits || pos <= append_int; i++) pos *= 10;
				for (pos /= 10; out_count < out_max && pos > 0; pos /= 10) {
					out_data[out_count++] = '0' + ((uint32_t)(append_int / pos) % 10);
				}
			}
		} else {
			out_data[out_count++] = *(format_itr++);
		}
	}

	if (out_count < out_max) {
		out_data[out_count] = '\0';
		dmemory_write(out_data, out_ptr, out_count + 1);
		*ret = out_count;
	} else {
		*ret = 0;
	}

	free(format);
	free(out_data);
	return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl %esi, %eax
movq %rdi, %rbx
xorl %r15d, %r15d
pushq $0x4
popq %rsi
leaq 0x3c(%rsp), %rdx
leaq 0x38(%rsp), %rcx
leaq 0x6c(%rsp), %r8
leaq 0xc(%rsp), %r9
movl %eax, %edi
xorl %eax, %eax
callq 0x626c
testl %eax, %eax
je 0x8ba6
movl 0x3c(%rsp), %edi
movl 0x38(%rsp), %esi
callq 0x606d
testl %eax, %eax
je 0x8ba6
movl 0xc(%rsp), %esi
leaq 0x10(%rsp), %r14
pushq $0x4
popq %rdx
movq %r14, %rdi
callq 0x616c
cmpl $0x0, (%r14)
je 0x8ba6
movl %eax, %ebp
movl 0xc(%rsp), %esi
addl $0x4, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, %r14d
movl 0xc(%rsp), %esi
addl $0x8, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, %r13d
movl 0xc(%rsp), %esi
addl $0xc, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, 0x2c(%rsp)
movl 0xc(%rsp), %esi
addl $0x10, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movq %rax, 0x48(%rsp)
movl 0xc(%rsp), %esi
addl $0x14, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, 0x28(%rsp)
movl 0xc(%rsp), %esi
addl $0x18, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, 0x24(%rsp)
movl 0xc(%rsp), %esi
addl $0x1c, %esi
leaq 0x10(%rsp), %r12
pushq $0x4
popq %rdx
movq %r12, %rdi
callq 0x616c
cmpl $0x0, (%r12)
je 0x8ba6
movl %eax, 0x34(%rsp)
movl 0x6c(%rsp), %edi
callq 0x61ee
movq %rax, 0x40(%rsp)
testq %rax, %rax
je 0x8ba6
movl %r13d, 0x30(%rsp)
movl 0x38(%rsp), %r12d
movq %r12, %rdi
callq 0x1100
testq %rax, %rax
je 0x8b6e
movq %rax, %r13
movl %r14d, 0x64(%rsp)
movl %ebp, 0x68(%rsp)
movl 0x28(%rsp), %r8d
movl %r8d, %eax
addl $0x76c, %r8d            # imm = 0x76C
pushq $0x64
popq %rcx
xorl %edx, %edx
divl %ecx
movl %edx, 0x60(%rsp)
movl 0x24(%rsp), %r9d
testl %r9d, %r9d
pushq $0x7
popq %rax
cmovnel %r9d, %eax
movl %eax, 0x5c(%rsp)
movl 0x30(%rsp), %eax
cmpl $0xc, %eax
leaq 0x4739(%rip), %rdx      # 0xceec
leaq 0x4735(%rip), %rsi      # 0xceef
cmovaeq %rdx, %rsi
movq %rsi, 0x90(%rsp)
movq 0x48(%rsp), %rdi
leal 0x1(%rdi), %edx
movl %edx, 0x58(%rsp)
incl 0x34(%rsp)
pushq $0xc
popq %rsi
xorl %edx, %edx
divl %esi
testl %edx, %edx
cmovel %esi, %edx
movl %edx, 0x54(%rsp)
movl 0x2c(%rsp), %eax
orb $0x30, %al
movb %al, 0x17(%rsp)
movl %r8d, 0x28(%rsp)
movl %r8d, %eax
xorl %edx, %edx
divl %ecx
movl %eax, 0x50(%rsp)
movl %edi, %eax
leaq 0x9517(%rip), %rcx      # 0x11d20
leaq (%rcx,%rax,8), %rcx
movq %rcx, 0x88(%rsp)
leaq 0x9564(%rip), %rcx      # 0x11d80
leaq (%rcx,%rax,8), %rax
movq %rax, 0x80(%rsp)
movl %r9d, %eax
leaq 0x946e(%rip), %rcx      # 0x11ca0
leaq (%rcx,%rax,8), %rcx
movq %rcx, 0x78(%rsp)
leaq 0x949e(%rip), %rcx      # 0x11ce0
leaq (%rcx,%rax,8), %rax
movq %rax, 0x70(%rsp)
movq 0x40(%rsp), %rdx
movq $0x0, 0x18(%rsp)
xorl %ecx, %ecx
xorl %r14d, %r14d
leaq 0x46a1(%rip), %r10      # 0xcf06
cmpl %r12d, %r14d
jae 0x8b75
movl %r14d, %ebp
testl %ecx, %ecx
movq %rdx, %rsi
cmovneq 0x18(%rsp), %rsi
cmpb $0x0, (%rdx)
cmovneq %rdx, %rsi
movl $0x0, %eax
cmovel %eax, %ecx
movzbl (%rsi), %edx
movl %r14d, %eax
cmpl $0x25, %edx
je 0x88b0
testl %edx, %edx
je 0x8b79
incq %rsi
incl %ebp
movb %dl, (%r13,%rax)
movq %rsi, %rdx
movl %ebp, %r14d
jmp 0x8865
movzbl 0x1(%rsi), %edx
cmpl $0x4f, %edx
je 0x88c1
pushq $0x1
popq %rdi
cmpl $0x45, %edx
jne 0x88c7
movb 0x2(%rsi), %dl
pushq $0x2
popq %rdi
testb %dl, %dl
je 0x8b79
addq %rdi, %rsi
incq %rsi
movzbl %dl, %edi
addl $-0x25, %edi
movq %rsi, %rdx
movl %ebp, %r14d
cmpl $0x55, %edi
ja 0x8865
leaq 0x439f(%rip), %rdx      # 0xcc90
movslq (%rdx,%rdi,4), %r11
addq %rdx, %r11
leaq 0x45d5(%rip), %rdi      # 0xced4
movq %rsi, %rdx
movl %ebp, %r14d
pushq $0x2
popq %r15
movl 0x2c(%rsp), %r9d
leaq 0x45d1(%rip), %r8       # 0xcee6
jmpq *%r11
pushq $0x1
popq %rcx
movq %rdi, %rdx
jmp 0x8ac8
pushq $0x1
popq %rcx
movq %r10, %rdx
jmp 0x8ac8
leaq 0x45e3(%rip), %r8       # 0xcf18
jmp 0x8af3
movl 0x58(%rsp), %r9d
jmp 0x8b13
movl 0x60(%rsp), %r9d
jmp 0x8b13
leaq 0x45ba(%rip), %r8       # 0xcf0f
jmp 0x8af3
pushq $0x1
popq %r15
movl 0x24(%rsp), %r9d
jmp 0x8b13
movl 0x64(%rsp), %r9d
jmp 0x8b13
pushq $0x1
popq %rcx
leaq 0x4582(%rip), %rdx      # 0xcefe
jmp 0x8ac8
movl 0x30(%rsp), %r9d
jmp 0x8b13
pushq $0x1
popq %rcx
leaq 0x4554(%rip), %rdx      # 0xcee9
jmp 0x8ac8
movl 0x2c(%rsp), %edx
movl %edx, %r9d
cmpl $0x9, %edx
ja 0x8b13
movb $0x20, (%r13,%rax)
incq %rax
movq %rsi, %rdx
movl %eax, %r14d
cmpl %r12d, %eax
jae 0x8865
addl $0x2, %ebp
movb 0x17(%rsp), %dl
movb %dl, (%r13,%rax)
jmp 0x88a8
movq %rsi, %rdx
movl %ebp, %r14d
movq 0x78(%rsp), %r8
jmp 0x8a58
movq %rsi, %rdx
movl %ebp, %r14d
movq 0x88(%rsp), %r8
jmp 0x8a99
leaq 0x4528(%rip), %r8       # 0xcf22
jmp 0x8af3
leaq 0x44fe(%rip), %r8       # 0xcf04
jmp 0x8af3
leaq 0x4500(%rip), %r8       # 0xcf12
jmp 0x8af3
movl 0x68(%rsp), %r9d
jmp 0x8b13
movl 0x50(%rsp), %r9d
jmp 0x8b13
leaq 0x44ec(%rip), %r8       # 0xcf1e
jmp 0x8af3
movl 0x54(%rsp), %r9d
jmp 0x8b13
pushq $0x1
popq %rcx
leaq 0x4492(%rip), %rdx      # 0xcedd
jmp 0x8ac8
movq %rsi, %rdx
movl %ebp, %r14d
movq 0x70(%rsp), %r8
cmpl $0x7, 0x24(%rsp)
jae 0x8865
jmp 0x8aa4
leaq 0x44a9(%rip), %r8       # 0xcf15
jmp 0x8af3
pushq $0x1
popq %rcx
leaq 0x4477(%rip), %rdx      # 0xcef2
jmp 0x8ac8
pushq $0x1
popq %r15
movl 0x5c(%rsp), %r9d
jmp 0x8b13
movq %rsi, %rdx
movl %ebp, %r14d
movq 0x80(%rsp), %r8
cmpl $0xc, 0x48(%rsp)
jae 0x8865
movq (%r8), %r8
movq %rsi, %rdx
movl %ebp, %r14d
testq %r8, %r8
jne 0x8af3
jmp 0x8865
movl 0x28(%rsp), %r9d
jmp 0x8b13
pushq $0x1
popq %rcx
leaq 0x43f7(%rip), %rdx      # 0xcebf
movq %rsi, 0x18(%rsp)
movl %ebp, %r14d
jmp 0x8865
leaq 0x3992(%rip), %r8       # 0xc46e
jmp 0x8af3
movq 0x90(%rsp), %r8
jmp 0x8af3
incq %r8
movb %dl, (%r13,%rax)
incq %rax
movb (%r8), %dl
testb %dl, %dl
je 0x8aff
cmpq %r12, %rax
jb 0x8ae8
movq %rsi, %rdx
movl %eax, %r14d
jmp 0x8865
pushq $0x3
popq %r15
movl 0x34(%rsp), %r9d
movl %r9d, %r8d
xorl %edx, %edx
pushq $0x1
popq %r9
cmpl %r15d, %edx
jb 0x8b26
cmpq %r8, %r9
ja 0x8b2e
imulq $0xa, %r9, %r9
incl %edx
jmp 0x8b1c
movq %rax, %r14
cmpq %r12, %r14
jae 0x8b66
cmpq $0xa, %r9
jb 0x8b66
pushq $0xa
popq %rdi
movq %r9, %rax
xorl %edx, %edx
divq %rdi
movq %rax, %r9
movq %r8, %rax
xorl %edx, %edx
divq %r9
pushq $0xa
popq %rdi
xorl %edx, %edx
divl %edi
orb $0x30, %dl
movb %dl, (%r13,%r14)
incq %r14
jmp 0x8b31
movq %rsi, %rdx
jmp 0x8865
movq 0x40(%rsp), %rdi
jmp 0x8ba1
xorl %ebp, %ebp
jmp 0x8b8e
movb $0x0, (%r13,%rax)
movl 0x3c(%rsp), %esi
leal 0x1(%rbp), %edx
movq %r13, %rdi
callq 0x5d3e
pushq $0x1
popq %r15
movl %ebp, (%rbx)
movq 0x40(%rsp), %rdi
callq 0x1030
movq %r13, %rdi
callq 0x1030
movl %r15d, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop