// File: /workspace/github_c_makefile_star2_O3/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 $0x88, %rsp
movq %rdi, %rbx
xorl %r15d, %r15d
leaq 0x24(%rsp), %rdx
leaq 0x20(%rsp), %rcx
leaq 0x4c(%rsp), %r8
leaq 0x4(%rsp), %r9
movl %esi, %edi
movl $0x4, %esi
xorl %eax, %eax
callq 0x7157
testl %eax, %eax
je 0x9d76
movl 0x24(%rsp), %edi
movl 0x20(%rsp), %esi
callq 0x6ec9
testl %eax, %eax
je 0x9d76
movl 0x4(%rsp), %esi
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r14)
je 0x9d76
movl %eax, %ebp
movl 0x4(%rsp), %esi
addl $0x4, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movl %eax, %r14d
movl 0x4(%rsp), %esi
addl $0x8, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movl %eax, %r13d
movl 0x4(%rsp), %esi
addl $0xc, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movl %eax, 0x14(%rsp)
movl 0x4(%rsp), %esi
addl $0x10, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movq %rax, 0x38(%rsp)
movl 0x4(%rsp), %esi
addl $0x14, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movq %rax, 0x30(%rsp)
movl 0x4(%rsp), %esi
addl $0x18, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movl %eax, 0x10(%rsp)
movl 0x4(%rsp), %esi
addl $0x1c, %esi
leaq 0x8(%rsp), %r12
movq %r12, %rdi
movl $0x4, %edx
callq 0x704d
cmpl $0x0, (%r12)
je 0x9d76
movl %eax, 0x1c(%rsp)
movl 0x4c(%rsp), %edi
callq 0x70d9
testq %rax, %rax
je 0x9d76
movq %rax, 0x28(%rsp)
movl %r13d, 0x18(%rsp)
movl 0x20(%rsp), %r12d
movq %r12, %rdi
callq 0x1100
testq %rax, %rax
je 0x9d6c
movq %rax, %r13
xorl %r11d, %r11d
movl $0x0, %r15d
testq %r12, %r12
je 0x9d2e
movq 0x30(%rsp), %rcx
leal 0x76c(%rcx), %r8d
movl %ecx, %eax
imulq $0x51eb851f, %rax, %rax # imm = 0x51EB851F
shrq $0x25, %rax
imull $0x64, %eax, %eax
subl %eax, %ecx
movq %rcx, 0x30(%rsp)
movl 0x10(%rsp), %edi
testl %edi, %edi
movl $0x7, %eax
cmovnel %edi, %eax
movl %eax, 0x48(%rsp)
movl 0x18(%rsp), %edx
cmpl $0xc, %edx
leaq 0x462d(%rip), %rax      # 0xdf5c
leaq 0x4629(%rip), %rcx      # 0xdf5f
cmovaeq %rax, %rcx
movq %rcx, 0x78(%rsp)
movq 0x38(%rsp), %rsi
leal 0x1(%rsi), %eax
movl %eax, 0x44(%rsp)
incl 0x1c(%rsp)
movl %edx, %eax
movl $0xaaaaaaab, %ecx       # imm = 0xAAAAAAAB
imulq %rax, %rcx
shrq $0x23, %rcx
shll $0x2, %ecx
leal (%rcx,%rcx,2), %eax
movl %edx, %ecx
subl %eax, %ecx
movl $0xc, %eax
cmovnel %ecx, %eax
movl %eax, 0x40(%rsp)
movl 0x14(%rsp), %eax
orb $0x30, %al
movb %al, 0xf(%rsp)
movq %r8, 0x80(%rsp)
imulq $0x51eb851f, %r8, %rax  # imm = 0x51EB851F
shrq $0x25, %rax
movq %rax, 0x70(%rsp)
movl %esi, %eax
leaq 0x9381(%rip), %rcx      # 0x12d20
leaq (%rcx,%rax,8), %rcx
movq %rcx, 0x68(%rsp)
leaq 0x93d1(%rip), %rcx      # 0x12d80
leaq (%rcx,%rax,8), %rax
movq %rax, 0x60(%rsp)
movl %edi, %eax
leaq 0x92df(%rip), %rcx      # 0x12ca0
leaq (%rcx,%rax,8), %rcx
movq %rcx, 0x58(%rsp)
leaq 0x930f(%rip), %rcx      # 0x12ce0
leaq (%rcx,%rax,8), %rax
movq %rax, 0x50(%rsp)
xorl %edi, %edi
xorl %r15d, %r15d
xorl %r8d, %r8d
xorl %r9d, %r9d
movq 0x28(%rsp), %rax
testl %r8d, %r8d
movq %rax, %rcx
cmovneq %r9, %rcx
cmpb $0x0, (%rax)
cmovneq %rax, %rcx
cmovel %edi, %r8d
movzbl (%rcx), %eax
cmpl $0x25, %eax
je 0x9a25
testl %eax, %eax
je 0x9d2e
incq %rcx
movl %r15d, %edx
incl %r15d
movb %al, (%r13,%rdx)
movq %rcx, %rax
jmp 0x9c62
movzbl 0x1(%rcx), %eax
cmpl $0x4f, %eax
je 0x9a33
cmpl $0x45, %eax
jne 0x9a3d
movb 0x2(%rcx), %al
movl $0x2, %edx
jmp 0x9a42
movl $0x1, %edx
testb %al, %al
je 0x9d2e
leaq (%rcx,%rdx), %r10
incq %r10
movzbl %al, %ecx
addl $-0x25, %ecx
cmpl $0x55, %ecx
ja 0x9c5f
movl $0x2, %eax
leaq 0x4294(%rip), %rsi      # 0xdd00
movslq (%rsi,%rcx,4), %rdx
addq %rsi, %rdx
leaq 0x44dc(%rip), %rcx      # 0xdf56
jmpq *%rdx
movl $0x1, %r8d
leaq 0x44bb(%rip), %rax      # 0xdf44
jmp 0x9c65
movl $0x1, %r8d
leaq 0x44db(%rip), %rax      # 0xdf76
jmp 0x9c65
movq 0x80(%rsp), %rcx
jmp 0x9bf2
movq 0x60(%rsp), %rax
jmp 0x9ba4
movl $0x1, %r8d
leaq 0x4495(%rip), %rax      # 0xdf59
jmp 0x9c65
movl %r14d, %ecx
jmp 0x9c7f
movl 0x14(%rsp), %ecx
jmp 0x9c7f
movl $0x1, %eax
movl 0x10(%rsp), %ecx
jmp 0x9c7f
leaq 0x39bf(%rip), %rcx      # 0xd4ae
jmp 0x9c2e
movl %ebp, %ecx
jmp 0x9c7f
movq 0x58(%rsp), %rax
jmp 0x9c05
movl $0x1, %r8d
leaq 0x441d(%rip), %rax      # 0xdf2f
jmp 0x9c65
movl $0x1, %r8d
leaq 0x444a(%rip), %rax      # 0xdf6e
jmp 0x9c65
leaq 0x445e(%rip), %rcx      # 0xdf8e
jmp 0x9c2e
movq 0x78(%rsp), %rcx
jmp 0x9c2e
leaq 0x442e(%rip), %rcx      # 0xdf74
jmp 0x9c2e
leaq 0x4440(%rip), %rcx      # 0xdf92
jmp 0x9c2e
movl 0x14(%rsp), %edx
movl %edx, %ecx
cmpl $0x9, %edx
ja 0x9c7f
movl %r15d, %ecx
movb $0x20, (%r13,%rcx)
incq %rcx
cmpl %r12d, %ecx
jae 0x9d20
addl $0x2, %r15d
movb 0xf(%rsp), %al
movb %al, (%r13,%rcx)
jmp 0x9c5f
movl $0x1, %r8d
leaq 0x43b3(%rip), %rax      # 0xdf4d
jmp 0x9c65
movq 0x68(%rsp), %rax
cmpl $0xc, 0x38(%rsp)
jb 0x9c0c
jmp 0x9c5f
movq 0x70(%rsp), %rcx
jmp 0x9bf2
leaq 0x43c1(%rip), %rcx      # 0xdf7f
jmp 0x9c2e
movl $0x1, %r8d
leaq 0x4395(%rip), %rax      # 0xdf62
jmp 0x9c65
movl 0x40(%rsp), %ecx
jmp 0x9c7f
movl 0x18(%rsp), %ecx
jmp 0x9c7f
leaq 0x439a(%rip), %rcx      # 0xdf85
jmp 0x9c2e
movq 0x30(%rsp), %rcx
jmp 0x9c7f
leaq 0x4384(%rip), %rcx      # 0xdf82
jmp 0x9c2e
movq 0x50(%rsp), %rax
cmpl $0x7, 0x10(%rsp)
jae 0x9c5f
movq (%rax), %rcx
testq %rcx, %rcx
jne 0x9c2e
jmp 0x9c5f
movl 0x44(%rsp), %ecx
jmp 0x9c7f
movl $0x3, %eax
movl 0x1c(%rsp), %ecx
jmp 0x9c7f
leaq 0x435a(%rip), %rcx      # 0xdf88
movb (%rcx), %al
testb %al, %al
je 0x9c5f
cmpl %r12d, %r15d
jae 0x9c5f
movl %r15d, %edx
incq %rdx
incq %rcx
movb %al, -0x1(%r13,%rdx)
movb (%rcx), %al
incl %r15d
testb %al, %al
je 0x9c5f
leaq 0x1(%rdx), %rsi
incq %rcx
cmpq %r12, %rdx
movq %rsi, %rdx
jb 0x9c42
movq %r10, %rax
movq %r9, %r10
movq %r10, %r9
cmpl %r12d, %r15d
jb 0x99ea
jmp 0x9d2e
movl $0x1, %eax
movl 0x48(%rsp), %ecx
movl %ecx, %ecx
movl $0x1, %esi
movl $0x1, %edx
movl %edx, %edi
addq %rsi, %rsi
leaq (%rsi,%rsi,4), %rsi
leal 0x1(%rdi), %edx
cmpl %eax, %edi
jb 0x9c8b
cmpq %rcx, %rsi
jbe 0x9c8b
cmpl %r12d, %r15d
setb %al
cmpq $0xa, %rsi
setae %dl
andb %al, %dl
cmpb $0x1, %dl
jne 0x9d13
movl %r15d, %r11d
incq %r11
movabsq $-0x3333333333333333, %rdx # imm = 0xCCCCCCCCCCCCCCCD
movq %rsi, %rax
mulq %rdx
movq %rdx, %rdi
shrq $0x3, %rdi
movq %rcx, %rax
xorl %edx, %edx
divq %rdi
movl $0xcccccccd, %edx       # imm = 0xCCCCCCCD
imulq %rax, %rdx
shrq $0x23, %rdx
addl %edx, %edx
leal (%rdx,%rdx,4), %edx
subl %edx, %eax
orb $0x30, %al
movb %al, -0x1(%r13,%r11)
incl %r15d
cmpq %r12, %r11
jae 0x9d08
incq %r11
cmpq $0x63, %rsi
movq %rdi, %rsi
ja 0x9cba
movq %r10, %rax
movq %r9, %r10
xorl %r11d, %r11d
jmp 0x9d19
movq %r10, %rax
movq %r9, %r10
xorl %edi, %edi
jmp 0x9c65
movq %r10, %rax
movq %r9, %r10
movl %ecx, %r15d
jmp 0x9c65
cmpl %r12d, %r15d
jae 0x9d4f
movl %r15d, %eax
movb $0x0, (%r13,%rax)
movl 0x24(%rsp), %esi
leal 0x1(%r15), %edx
movq %r13, %rdi
callq 0x6b71
movl %r15d, %r11d
movl %r11d, (%rbx)
movq 0x28(%rsp), %rdi
callq 0x1030
movq %r13, %rdi
callq 0x1030
movl $0x1, %r15d
jmp 0x9d76
movq 0x28(%rsp), %rdi
callq 0x1030
movl %r15d, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop