// File: /workspace/github_c_makefile_star2_O3/truenas[P]binaries/src/ixnvdimm.c
// Function: firmware_update
static void
firmware_update(int fd, struct ixnvdimm_info *info, const char *f, int I)
{
	int b, ffd, r, rbs, regions, t, timeout, atimeout, try;
	struct stat sb;
	off_t size;
	uint8_t *image, status[4], buf[7 + BLOCK_SIZE];

	/* Firmware commands timeout in milliseconds. */
	timeout = i2c_read16(fd, 0x00, 0x22);
	if (timeout & 0x8000)
		timeout = (timeout & 0x7fff) * 1000;

	/* Abort commands timeout in milliseconds. */
	atimeout = i2c_read(fd, 0x00, 0x24);
	if (i2c_read(fd, 0x00, 0x11) & 0x02)
		atimeout = atimeout * 1000;

	/* Region size in blocks. */
	rbs = i2c_read(fd, 0x00, 0x32);

	if ((ffd = open(f, O_RDONLY)) < 0)
		err(EX_NOINPUT, "Can't open firmware file '%s'", f);
	if (fstat(ffd, &sb) < 0)
		err(EX_NOINPUT, "Can't stat firmware file '%s'", f);
	size = roundup(sb.st_size, rbs * BLOCK_SIZE);
	regions = size / (rbs * BLOCK_SIZE);
	if (size < BLOCK_SIZE)
		errx(EX_NOINPUT, "Firmware file '%s' is too small", f);
	image = calloc(1, size);
	if (image == NULL)
		err(EX_OSERR, "Can't allocate firmware memory");
	if (read(ffd, image, sb.st_size) != sb.st_size)
		err(EX_OSERR, "Can't read firmware file '%s'", f);
	close(ffd);

	/* Validate firmware image header. */
	if (I)
		t = 0;		/* Ignore any identifiers difference. */
	else if (image[31] == 0)
		t = 0x03;
	else if (image[31] == 1)
		t = image[19];
	else
		errx(EX_NOINPUT, "Unknown Firmware Image Header Format %u", image[31]);
	if ((t & 0x01) && le16dec(&image[0]) != info->VendorId)
		errx(EX_NOINPUT, "Module Manufacturer ID Code does not match");
	if ((t & 0x02) && le16dec(&image[2]) != info->DeviceId)
		errx(EX_NOINPUT, "Module Product Identifier does not match");
	if ((t & 0x04) && le16dec(&image[4]) != info->SubsystemVendorId)
		errx(EX_NOINPUT, "Non-Volatile Memory Subsystem Controller Module Manufacturer ID Code does not match");
	if ((t & 0x08) && le16dec(&image[6]) != info->SubsystemDeviceId)
		errx(EX_NOINPUT, "Non-Volatile Memory Subsystem Controller Module Product Identifier does not match");
	if ((t & 0x10) && image[8] != info->RevisionId)
		errx(EX_NOINPUT, "Module Revision Code does not match");
	if ((t & 0x20) && image[9] != info->SubsystemRevisionId)
		errx(EX_NOINPUT, "Non-Volatile Memory Subsystem Controller Revision Code does not match");
	if (be32dec(&image[20]) != sb.st_size)
		errx(EX_NOINPUT, "Size in firmware header does not match");
	if (be16dec(&image[24]) !=
	    Crc16((char *)image + BLOCK_SIZE, sb.st_size - BLOCK_SIZE))
		errx(EX_NOINPUT, "Checksum in firmware header does not match");

	/* Wait for the Operation In Progress bit in the NVDIMM_CMD_STATUS0 register to be clear. */
	if (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) {
		printf("Waiting for Operation In Progress to clear\n");
		for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
			usleep(1000);
		if (t >= timeout) {
			errx(EX_PROTOCOL, "NVDIMM has operation in progress: %02x",
			    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
		}
	}

	/* Start firmware update via DSM. */
	i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
	buf[0] = 1;	/* Firmware Slot */
	memset(&status, 0xff, sizeof(status));
	if (calldsm(fd, 22, buf, 1, status, sizeof(status)) != 4)
		err(EX_NOINPUT, "Can't call Start Firmware Update DSM");
	if (le32dec(&status[0]) != 0)
		errx(EX_NOINPUT, "Start Firmware Update DSM failed: %x",
		    le32dec(&status[0]));
	printf("Start Firmware Update succeeded\n");
	fflush(stdout);

	/*
	 * Wait for the Operation In Progress bit in the NVDIMM_CMD_STATUS0
	 * register to be clear.  I have no clue why ACPI DSM does not do it.
	 */
	for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
		usleep(1000);
	if (t >= timeout) {
		warnx("Start Firmware Update DSM timeout: %04x",
		    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
		goto timeout;
	}

	/* Check ACPI enabled firmware update mode. */
	if ((i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x04) == 0) {
		warnx("Firmware update mode is not enabled: %02x",
		    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
		goto error;
	}

	/* Clear firmware region. */
	i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
	i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0x02);
	for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
		usleep(1000);
	if (t >= timeout) {
		warnx("Clear Firmware timeout: %04x",
		    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
		goto timeout;
	}
	if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x02) {
		warnx("Clear Firmware failed: %02x",
		    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
		goto error2;
	}

	/* Send firmware one region at a time */
	i2c_write(fd, 3, TYPED_BLOCK_DATA, 0x01);
	for (r = 0; r < regions; r++) {
		printf("\r%d/%d ", r, regions);
		fflush(stdout);
		try = 0;

retry:
		/* Send region blocks via Send Firmware Update Data DSM. */
		for (b = 0; b < rbs; b++) {
			le32enc(&buf[0], BLOCK_SIZE);
			le16enc(&buf[4], r);
			buf[6] = b;
			memcpy(&buf[7], &image[(r * rbs + b) * BLOCK_SIZE], BLOCK_SIZE);
			memset(&status, 0xff, sizeof(status));
			if (calldsm(fd, 23, buf, sizeof(buf), status, sizeof(status)) != 4) {
				warn("Can't call Send Firmware Update Data DSM");
				goto error2;
			}
			if (le32dec(&status[0]) != 0) {
				warnx("Send Firmware Update Data DSM failed: %x",
				    le32dec(&status[0]));
				goto error2;
			}
		}

		/* Verify region checksum. */
		i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
		i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0x04);
		for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
			usleep(1000);
		if (t >= timeout) {
			warnx("Generate Firmware Checksum timeout: %04x",
			    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
			goto timeout;
		}
		if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x02) {
			warnx("Generate Firmware Checksum failed: %02x",
			    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
			goto error2;
		}
		if (i2c_read16(fd, 3, FW_REGION_CRC0) !=
		    Crc16((char *)image + r * rbs * BLOCK_SIZE, rbs * BLOCK_SIZE)) {
			if (++try < 3) {
				printf("Region checksum mismatch, retrying\n");
				goto retry;
			} else {
				warnx("Region checksum mismatch");
				goto error2;
			}
		}

		/*
		 * After sending the first region with the header in it ask
		 * the module to check that the new image really applies.
		 */
		if (r == 0) {
			i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
			i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0x10);
			for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
				usleep(1000);
			if (t >= timeout) {
				warnx("Validate Firmware Header timeout: %04x",
				    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
				goto timeout;
			}
			if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x02) {
				warnx("Validate Firmware Header failed: %02x",
				    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
				goto error2;
			}
			printf("\rValidate Firmware Header succeeded\n");
		}

		/* The region seems to be correct, commit it. */
		i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
		i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0x08);
		for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
			usleep(1000);
		if (t >= timeout) {
			warnx("Commit Firmware timeout: %04x",
			    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
			goto timeout;
		}
		if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x02) {
			warnx("Commit Firmware failed: %02x",
			    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
			goto error2;
		}
	}
	i2c_write(fd, 3, TYPED_BLOCK_DATA, 0x00);
	printf("\rSend Firmware Update Data succeeded\n");
	fflush(stdout);

	/* Validate firmware image. */
	printf("Validating firmware image... ");
	fflush(stdout);
	i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
	i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0x20);
	for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
		usleep(1000);
	if (t >= timeout) {
		warnx("Validate Firmware Image timeout: %02x",
		    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
timeout:
		/* Send Abort command. */
		i2c_write(fd, 0, 0x43, 0x10);
		for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < atimeout; t++)
			usleep(1000);
		if (t >= atimeout)
			warnx("Abort command timeout: %04x",
			    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
		else if ((i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x10) == 0)
			warnx("Abort command haven't succeeded: %02x",
			    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
		goto error2;
	}
	if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x02) {
		warnx("Validate Firmware Image failed: %02x",
		    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
error2:
		/* Disable firmware update mode. */
		i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
		i2c_write(fd, 0, FIRMWARE_OPS_CMD, 0);
		for (t = 0; (i2c_read(fd, 0, NVDIMM_CMD_STATUS0) & 1) && t < timeout; t++)
			usleep(1000);
		if (t >= timeout)
			warnx("Disable firmware update mode timeout: %04x",
			    i2c_read16(fd, 0, NVDIMM_CMD_STATUS0));
		else if (i2c_read(fd, 0, FIRMWARE_OPS_STATUS) & 0x04)
			warnx("Firmware update mode disable error: %02x",
			    i2c_read(fd, 0, FIRMWARE_OPS_STATUS));
error:
		goto done;
	}
	printf("\rValidate Firmware Image succeeded\n");
	fflush(stdout);

	/* Finish firmware update via DSM. */
	i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
	memset(&status, 0xff, sizeof(status));
	if (calldsm(fd, 24, NULL, 0, status, sizeof(status)) != 4)
		err(EX_NOINPUT, "Can't call Finish Firmware Update DSM");
	if (le32dec(&status[0]) != 0)
		errx(EX_NOINPUT, "Finish Firmware Update DSM status: %x",
		    le32dec(&status[0]));
	printf("Finish Firmware Update succeeded\n");
	fflush(stdout);

	/* Select firmware image slot 1 */
	i2c_write(fd, 0, NVDIMM_MGT_CMD1, 1 << 1);
	buf[0] = 1;	/* Firmware Slot 1 */
	memset(&status, 0xff, sizeof(status));
	if (calldsm(fd, 25, buf, 1, status, sizeof(status)) != 4)
		err(EX_NOINPUT, "Can't call Select Firmware Image Slot DSM");
	if (le32dec(&status[0]) != 0)
		errx(EX_NOINPUT, "Select Firmware Image Slot DSM failed: %x",
		    le32dec(&status[0]));
	printf("Select Firmware Image Slot 1 succeeded\n");
	fflush(stdout);

done:
	free(image);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movl %ecx, 0x18(%rsp)
movq %rdx, %r15
movq %rsi, 0x30(%rsp)
movl %edi, %ebx
xorl %esi, %esi
movl $0x22, %edx
callq 0x2af0
movzbl %al, %ebp
movl %ebx, %edi
xorl %esi, %esi
movl $0x23, %edx
callq 0x2af0
movzbl %al, %eax
shll $0x8, %eax
movl %eax, %ecx
orl %ebp, %ecx
movzwl %cx, %edx
andl $0x7fff, %ecx           # imm = 0x7FFF
imull $0x3e8, %ecx, %r12d     # imm = 0x3E8
testw %ax, %ax
cmovnsl %edx, %r12d
movl %ebx, %edi
xorl %esi, %esi
movl $0x24, %edx
callq 0x2af0
movzbl %al, %r14d
movl %ebx, %edi
xorl %esi, %esi
movl $0x11, %edx
callq 0x2af0
imull $0x3e8, %r14d, %ebp     # imm = 0x3E8
testb $0x2, %al
cmovel %r14d, %ebp
movl %ebx, %edi
xorl %esi, %esi
movl $0x32, %edx
callq 0x2af0
movl %eax, %r13d
movq %r15, 0x10(%rsp)
movq %r15, %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x2170
testl %eax, %eax
js 0x392a
movl %eax, %r14d
leaq 0x88(%rsp), %rsi
movl %eax, %edi
callq 0x21b0
testl %eax, %eax
js 0x3933
movzbl %r13b, %eax
movl %eax, 0xc(%rsp)
movl %eax, %ecx
shll $0x5, %ecx
movq 0xb8(%rsp), %r13
leaq (%rcx,%r13), %rsi
decq %rsi
movq %rsi, %rax
cqto
movq %rcx, 0x40(%rsp)
idivq %rcx
movq %rax, 0x48(%rsp)
subq %rdx, %rsi
cmpq $0x1f, %rsi
jle 0x3941
movl $0x1, %edi
callq 0x2110
testq %rax, %rax
je 0x3959
movl %r14d, %edi
movq %rax, 0x20(%rsp)
movq %rax, %rsi
movq %r13, %rdx
callq 0x2100
cmpq %r13, %rax
jne 0x3967
movl %r14d, %edi
callq 0x20f0
cmpl $0x0, 0x18(%rsp)
movq 0x20(%rsp), %rsi
jne 0x2dd4
movzbl 0x1f(%rsi), %edx
movl $0x3, %eax
testl %edx, %edx
movq 0x30(%rsp), %rdi
je 0x2d69
cmpl $0x1, %edx
jne 0x39e5
movzbl 0x13(%rsi), %eax
testb $0x1, %al
je 0x2d75
movzwl (%rsi), %ecx
cmpw (%rdi), %cx
jne 0x39dc
testb $0x2, %al
je 0x2d87
movzwl 0x2(%rsi), %ecx
cmpw 0x2(%rdi), %cx
jne 0x39ee
testb $0x4, %al
je 0x2d99
movzwl 0x4(%rsi), %ecx
cmpw 0x6(%rdi), %cx
jne 0x39f7
testb $0x8, %al
je 0x2dab
movzwl 0x6(%rsi), %ecx
cmpw 0x8(%rdi), %cx
jne 0x3a00
testb $0x10, %al
je 0x2dbd
movzbl 0x8(%rsi), %ecx
cmpw %cx, 0x4(%rdi)
jne 0x3a09
testb $0x20, %al
je 0x2dd4
movzbl 0x9(%rsi), %eax
movq 0x30(%rsp), %rcx
cmpw %ax, 0xa(%rcx)
jne 0x3a12
movl 0x14(%rsi), %eax
bswapl %eax
cmpq %rax, %r13
jne 0x397f
movzwl 0x18(%rsi), %eax
rolw $0x8, %ax
movzwl %ax, %eax
addl $-0x20, %r13d
testl %r13d, %r13d
jle 0x2e39
leaq 0x20(%rsi), %rdx
xorl %ecx, %ecx
movsbl (%rdx), %esi
shll $0x8, %esi
xorl %esi, %ecx
movl $0x8, %esi
movl %ecx, %edi
addl %ecx, %edi
movl %edi, %r8d
xorl $0x1021, %r8d           # imm = 0x1021
testw %cx, %cx
movl %r8d, %ecx
cmovnsl %edi, %ecx
decl %esi
jne 0x2e09
leal -0x1(%r13), %esi
incq %rdx
cmpl $0x2, %r13d
movl %esi, %r13d
jge 0x2dfc
movzwl %cx, %ecx
jmp 0x2e3b
xorl %ecx, %ecx
cmpl %eax, %ecx
jne 0x398b
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
testb $0x1, %al
je 0x2eba
leaq 0x3c2d(%rip), %rdi      # 0x6a89
callq 0x2070
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
testl %r12d, %r12d
setne %cl
testb $0x1, %al
je 0x2eb2
testl %r12d, %r12d
je 0x2eb2
movl $0x1, %r14d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r14d
setb %cl
testb $0x1, %al
je 0x2eb2
leal 0x1(%r14), %eax
cmpl %r12d, %r14d
movl %eax, %r14d
jb 0x2e84
testb %cl, %cl
je 0x39b8
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
leaq 0x60(%rsp), %rdx
movb $0x1, (%rdx)
leaq 0x8(%rsp), %r8
movl $0xffffffff, (%r8)      # imm = 0xFFFFFFFF
movl $0x1, %ecx
movl $0x4, %r9d
movl %ebx, %edi
movl $0x16, %esi
callq 0x45b8
cmpq $0x4, %rax
jne 0x3997
movl 0x8(%rsp), %edx
testl %edx, %edx
jne 0x39aa
leaq 0x3b9f(%rip), %rdi      # 0x6ab4
callq 0x2070
movq 0x609f(%rip), %r13      # 0x8fc0
movq (%r13), %rdi
callq 0x2160
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
testl %r12d, %r12d
setne %r14b
movl %r14d, %ecx
testb $0x1, %al
je 0x2f82
movl %r14d, %ecx
testl %r12d, %r12d
je 0x2f82
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x2f82
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x2f54
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x2fb9
movl $0x71, %edx
callq 0x2af0
testb $0x4, %al
jne 0x319b
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x254a(%rip), %rdi      # 0x54fe
jmp 0x3179
movl $0x61, %edx
callq 0x2af0
movzbl %al, %r15d
movl %ebx, %edi
xorl %esi, %esi
movl $0x62, %edx
callq 0x2af0
movzbl %al, %esi
shll $0x8, %esi
orl %r15d, %esi
leaq 0x24f1(%rip), %rdi      # 0x54d6
xorl %eax, %eax
callq 0x20b0
movl %ebx, %edi
xorl %esi, %esi
movl $0x43, %edx
movl $0x10, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
testl %ebp, %ebp
setne %cl
testb $0x1, %al
je 0x304e
testl %ebp, %ebp
je 0x304e
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %ebp, %r15d
setb %cl
testb $0x1, %al
je 0x304e
leal 0x1(%r15), %eax
cmpl %ebp, %r15d
movl %eax, %r15d
jb 0x3020
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x307e
movl $0x71, %edx
callq 0x2af0
testb $0x10, %al
jne 0x30af
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x2691(%rip), %rdi      # 0x570d
jmp 0x30a8
movl $0x61, %edx
callq 0x2af0
movzbl %al, %ebp
movl %ebx, %edi
xorl %esi, %esi
movl $0x62, %edx
callq 0x2af0
movzbl %al, %esi
shll $0x8, %esi
orl %ebp, %esi
leaq 0x2649(%rip), %rdi      # 0x56f1
xorl %eax, %eax
callq 0x20b0
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
xorl %ecx, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
testb $0x1, %al
je 0x311e
testl %r12d, %r12d
je 0x311e
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %r14b
testb $0x1, %al
je 0x311e
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x30ef
movl %ebx, %edi
xorl %esi, %esi
testb %r14b, %r14b
je 0x314f
movl $0x71, %edx
callq 0x2af0
testb $0x4, %al
je 0x3180
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x2636(%rip), %rdi      # 0x5783
jmp 0x3179
movl $0x61, %edx
callq 0x2af0
movzbl %al, %ebp
movl %ebx, %edi
xorl %esi, %esi
movl $0x62, %edx
callq 0x2af0
movzbl %al, %esi
shll $0x8, %esi
orl %ebp, %esi
leaq 0x25df(%rip), %rdi      # 0x5758
xorl %eax, %eax
callq 0x20b0
movq 0x20(%rsp), %rdi
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2030
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
movl %r14d, %ecx
testb $0x1, %al
je 0x3212
movl %r14d, %ecx
testl %r12d, %r12d
je 0x3212
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x3212
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x31e4
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x37d6
movl $0x71, %edx
callq 0x2af0
movl %ebx, %edi
testb $0x2, %al
jne 0x3807
movl $0x3, %esi
movl $0x4, %edx
movl $0x1, %ecx
callq 0x3b30
movq 0x48(%rsp), %rdx
testl %edx, %edx
jle 0x361f
movl 0xc(%rsp), %eax
movq %rax, 0x10(%rsp)
movl %edx, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, 0x50(%rsp)
leaq 0x22f2(%rip), %rdi      # 0x5561
movq $0x0, 0x38(%rsp)
xorl %esi, %esi
xorl %eax, %eax
movq %rsi, %r15
callq 0x20a0
movq (%r13), %rdi
callq 0x2160
movq 0x40(%rsp), %rax
imull %r15d, %eax
movq %r15, 0x18(%rsp)
movl %r15d, %ecx
shrl $0x8, %ecx
movl %ecx, 0x30(%rsp)
movq 0x20(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x58(%rsp)
movl $0x0, 0x2c(%rsp)
cmpl $0x0, 0xc(%rsp)
je 0x335c
movq 0x38(%rsp), %r13
xorl %r15d, %r15d
movl $0x20, 0x60(%rsp)
movq 0x18(%rsp), %rax
movb %al, 0x64(%rsp)
movl 0x30(%rsp), %eax
movb %al, 0x65(%rsp)
movb %r15b, 0x66(%rsp)
movl %r13d, %eax
andl $-0x20, %eax
movups (%rcx,%rax), %xmm0
movups 0x10(%rcx,%rax), %xmm1
leaq 0x67(%rsp), %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movl $0xffffffff, 0x8(%rsp)  # imm = 0xFFFFFFFF
movl $0x27, %ecx
movl $0x4, %r9d
movl %ebx, %edi
movl $0x17, %esi
leaq 0x60(%rsp), %rdx
leaq 0x8(%rsp), %r8
callq 0x45b8
cmpq $0x4, %rax
jne 0x3822
movl 0x8(%rsp), %esi
testl %esi, %esi
jne 0x3835
incq %r15
addq $0x20, %r13
cmpq %r15, 0x10(%rsp)
movq 0x20(%rsp), %rcx
jne 0x32cd
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
movl $0x4, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
movl %r14d, %ecx
testb $0x1, %al
je 0x33d3
movl %r14d, %ecx
testl %r12d, %r12d
je 0x33d3
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x33d3
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x33a5
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x3877
movl $0x71, %edx
callq 0x2af0
movl %ebx, %edi
testb $0x2, %al
jne 0x3890
movl $0x3, %esi
movl $0x40, %edx
callq 0x2af0
movl %eax, %r15d
movl %ebx, %edi
movl $0x3, %esi
movl $0x41, %edx
callq 0x2af0
cmpl $0x0, 0xc(%rsp)
je 0x346d
xorl %ecx, %ecx
movq 0x40(%rsp), %rdx
movq 0x58(%rsp), %rsi
movq 0x5b90(%rip), %r13      # 0x8fc0
movsbl (%rsi), %edi
shll $0x8, %edi
xorl %edi, %ecx
movl $0x8, %edi
movl %ecx, %r8d
addl %ecx, %r8d
movl %r8d, %r9d
xorl $0x1021, %r9d           # imm = 0x1021
testw %cx, %cx
movl %r9d, %ecx
cmovnsl %r8d, %ecx
decl %edi
jne 0x343d
leal -0x1(%rdx), %edi
incq %rsi
cmpl $0x2, %edx
movl %edi, %edx
jge 0x3430
movzwl %cx, %ecx
jmp 0x3476
xorl %ecx, %ecx
movq 0x5b4a(%rip), %r13      # 0x8fc0
movzbl %r15b, %edx
movzbl %al, %eax
shll $0x8, %eax
orl %edx, %eax
cmpl %eax, %ecx
je 0x34af
movl 0x2c(%rsp), %eax
cmpl $0x2, %eax
je 0x38ab
incl %eax
movl %eax, 0x2c(%rsp)
leaq 0x36e8(%rip), %rdi      # 0x6b88
callq 0x2070
movq 0x20(%rsp), %rcx
jmp 0x32ba
cmpq $0x0, 0x18(%rsp)
jne 0x355c
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
movl $0x10, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
movl %r14d, %ecx
testb $0x1, %al
je 0x3532
movl %r14d, %ecx
testl %r12d, %r12d
je 0x3532
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x3532
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x3504
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x38f4
movl $0x71, %edx
callq 0x2af0
testb $0x2, %al
jne 0x390d
leaq 0x360d(%rip), %rdi      # 0x6b64
callq 0x2070
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
movl $0x8, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
movl %r14d, %ecx
testb $0x1, %al
je 0x35d3
movl %r14d, %ecx
testl %r12d, %r12d
je 0x35d3
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x35d3
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x35a5
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x38be
movl $0x71, %edx
callq 0x2af0
testb $0x2, %al
jne 0x38d7
movq 0x18(%rsp), %rsi
incq %rsi
movq 0x38(%rsp), %rax
addq 0x40(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq 0x50(%rsp), %rsi
movq 0x48(%rsp), %rdx
leaq 0x1f48(%rip), %rdi      # 0x5561
jne 0x327a
movl %ebx, %edi
movl $0x3, %esi
movl $0x4, %edx
xorl %ecx, %ecx
callq 0x3b30
leaq 0x349b(%rip), %rdi      # 0x6ad4
callq 0x2070
movq (%r13), %rdi
callq 0x2160
leaq 0x205f(%rip), %rdi      # 0x56ad
xorl %eax, %eax
callq 0x20a0
movq (%r13), %rdi
callq 0x2160
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x4a, %edx
movl $0x20, %ecx
callq 0x3b30
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
movl %r14d, %ecx
testb $0x1, %al
je 0x36d5
movl %r14d, %ecx
testl %r12d, %r12d
je 0x36d5
movl $0x1, %r15d
movl $0x3e8, %edi            # imm = 0x3E8
callq 0x21c0
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x2af0
cmpl %r12d, %r15d
setb %cl
testb $0x1, %al
je 0x36d5
leal 0x1(%r15), %eax
cmpl %r12d, %r15d
movl %eax, %r15d
jb 0x36a7
movl %ebx, %edi
xorl %esi, %esi
testb %cl, %cl
je 0x3841
movl $0x71, %edx
callq 0x2af0
testb $0x2, %al
jne 0x385a
leaq 0x33ff(%rip), %rdi      # 0x6af9
callq 0x2070
movq (%r13), %rdi
callq 0x2160
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
leaq 0x8(%rsp), %r8
movl $0xffffffff, (%r8)      # imm = 0xFFFFFFFF
movl $0x4, %r9d
movl %ebx, %edi
movl $0x18, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x45b8
cmpq $0x4, %rax
jne 0x3a25
movl 0x8(%rsp), %edx
testl %edx, %edx
jne 0x3a31
leaq 0x33c2(%rip), %rdi      # 0x6b1c
callq 0x2070
movq (%r13), %rdi
callq 0x2160
movl %ebx, %edi
xorl %esi, %esi
movl $0x41, %edx
movl $0x2, %ecx
callq 0x3b30
leaq 0x60(%rsp), %rdx
movb $0x1, (%rdx)
leaq 0x8(%rsp), %r8
movl $0xffffffff, (%r8)      # imm = 0xFFFFFFFF
movl $0x1, %ecx
movl $0x4, %r9d
movl %ebx, %edi
movl $0x19, %esi
callq 0x45b8
cmpq $0x4, %rax
jne 0x3a3d
movl 0x8(%rsp), %edx
testl %edx, %edx
jne 0x3a49
leaq 0x337a(%rip), %rdi      # 0x6b3d
callq 0x2070
movq (%r13), %rdi
callq 0x2160
jmp 0x3180
movl $0x61, %edx
callq 0x2af0
movzbl %al, %r15d
movl %ebx, %edi
xorl %esi, %esi
movl $0x62, %edx
callq 0x2af0
movzbl %al, %esi
shll $0x8, %esi
orl %r15d, %esi
leaq 0x1d26(%rip), %rdi      # 0x5528
jmp 0x2fe5
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x1d28(%rip), %rdi      # 0x5545
jmp 0x30a8
leaq 0x1d40(%rip), %rdi      # 0x5569
xorl %eax, %eax
callq 0x2060
jmp 0x30af
leaq 0x1d56(%rip), %rdi      # 0x5592
jmp 0x30a8
movl $0x61, %edx
callq 0x4667
movzwl %ax, %esi
leaq 0x1e76(%rip), %rdi      # 0x56cb
jmp 0x2fe5
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x1ec1(%rip), %rdi      # 0x5733
jmp 0x30a8
movl $0x61, %edx
callq 0x4667
movzwl %ax, %esi
leaq 0x1d30(%rip), %rdi      # 0x55bb
jmp 0x2fe5
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x1d3e(%rip), %rdi      # 0x55e4
jmp 0x30a8
leaq 0x1d5a(%rip), %rdi      # 0x560c
xorl %eax, %eax
callq 0x20b0
jmp 0x30af
movl $0x61, %edx
callq 0x4667
movzwl %ax, %esi
leaq 0x1da0(%rip), %rdi      # 0x5672
jmp 0x2fe5
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x1da1(%rip), %rdi      # 0x5690
jmp 0x30a8
movl $0x61, %edx
callq 0x4667
movzwl %ax, %esi
leaq 0x1d1d(%rip), %rdi      # 0x5625
jmp 0x2fe5
movl %ebx, %edi
xorl %esi, %esi
movl $0x71, %edx
callq 0x2af0
movzbl %al, %esi
leaq 0x1d27(%rip), %rdi      # 0x564c
jmp 0x30a8
leaq 0x1911(%rip), %rsi      # 0x5242
jmp 0x393a
leaq 0x1926(%rip), %rsi      # 0x5260
movl $0x42, %edi
jmp 0x3973
leaq 0x1936(%rip), %rsi      # 0x527e
movl $0x42, %edi
movq 0x10(%rsp), %rdx
xorl %eax, %eax
callq 0x2090
leaq 0x193e(%rip), %rsi      # 0x529e
movl $0x47, %edi
jmp 0x39a3
leaq 0x194f(%rip), %rsi      # 0x52bd
movl $0x47, %edi
movq 0x10(%rsp), %rdx
xorl %eax, %eax
callq 0x2150
leaq 0x1a8d(%rip), %rsi      # 0x5413
jmp 0x3a19
leaq 0x1aa8(%rip), %rsi      # 0x543a
jmp 0x3a19
leaq 0x1aee(%rip), %rsi      # 0x548c
movl $0x42, %edi
xorl %eax, %eax
callq 0x2150
leaq 0x1b00(%rip), %rsi      # 0x54b1
movl $0x42, %edi
jmp 0x39d5
movl %ebx, %edi
xorl %esi, %esi
movl $0x61, %edx
callq 0x4667
movzwl %ax, %edx
leaq 0x1a95(%rip), %rsi      # 0x5465
movl $0x4c, %edi
xorl %eax, %eax
callq 0x2090
leaq 0x1949(%rip), %rsi      # 0x532c
jmp 0x3a19
leaq 0x18ef(%rip), %rsi      # 0x52db
jmp 0x39b1
leaq 0x198b(%rip), %rsi      # 0x5380
jmp 0x3a19
leaq 0x1905(%rip), %rsi      # 0x5303
jmp 0x3a19
leaq 0x1950(%rip), %rsi      # 0x5357
jmp 0x3a19
leaq 0x1999(%rip), %rsi      # 0x53a9
jmp 0x3a19
leaq 0x19b4(%rip), %rsi      # 0x53cd
movl $0x42, %edi
xorl %eax, %eax
callq 0x2090
leaq 0x1d80(%rip), %rsi      # 0x57ac
jmp 0x399e
leaq 0x1d9a(%rip), %rsi      # 0x57d2
jmp 0x39b1
leaq 0x1db4(%rip), %rsi      # 0x57f8
jmp 0x399e
leaq 0x1dd2(%rip), %rsi      # 0x5822
jmp 0x39b1