// File: /workspace/github_c_makefile_star2_O3/minkcv[P]vm/assembler.c
// Function: main
int main (int argc, char** argv)
{
    char* filename = NULL;
    char* romfilename = NULL;
    FILE* romSrc = NULL;
    uint16_t romSize = 0;
    for (int i = 1; i < argc; i++)
    {
        if (!strcmp(argv[i], "-f") && i + 1 < argc)
        {
	    filename = argv[i + 1];
	    i++;
	    continue;
        }

	if (!strcmp(argv[i], "-r") && i + 1 < argc)
        {
	    romfilename = argv[i + 1];
	    i++;
	    continue;
        }
    }
    if (filename == NULL)
    {
        printf("Usage: assember -f sourcefile.asm\n");
        exit(1);
    }

    FILE* src = fopen(filename, "r");
    if (!src)
    {
        printf("Failed to open file %s: %s\n", filename, strerror(errno));
        return 0;
    }

    if (romfilename) {
	romSrc = fopen(romfilename, "r");
	if (!romSrc)
	{
	    printf("Failed to open file %s: %s\n", romfilename, strerror(errno));
	    return 0;
	}

	fseek(romSrc, 0, SEEK_END);
	long romsize_full = ftell(romSrc);
	fseek(romSrc, 0, SEEK_SET);
	if (romsize_full > 128 * 256) {
	    printf("ROM is too large: %d > %d", romsize_full, 128 * 256);
	    return 0;
	}
	romSize = romsize_full;
    }

    uint16_t numInstructions = countInstructions(src); 
    printf("counted %d instructions\n", numInstructions);
    uint16_t* binary = malloc(sizeof(uint16_t) * numInstructions);
    char* line = NULL; // Causes getline to use malloc, we free this for every line
    size_t toRead = 0; // Passing 0 to getline reads until \n
    ssize_t charsRead;
    int instrIndex = 0;
    int lineCount = 0; // Used for error printing
    LabelAddress** labelMap = malloc(sizeof(LabelAddress*) * MAX_LABELS);
    createLabelMap(src, &labelMap);

    // Read each line in the file
    while ((charsRead = getline(&line, &toRead, src)) != -1)
    {
	lineCount++;
	// If line is not a command and we haven't reached the end of the non comment code.
	if (line[0] != '\n' && line[0] != ';' && line[0] != '@' && instrIndex < numInstructions)
	{
	    // Parse tokens separated by a space or comment
	    char* token = strtok(line, " ;\n");
	    uint16_t instr; // Assembled instruction
	    int arg = 0; // Which arg we are currently parsing
	    while (token != NULL && arg < 4)
	    {
		if (arg == 0)
		{
		    if (!strcmp(token, "LRL")) // Special assembler macro "Load Registers Label"
		    {
			uint8_t segAddr = 0;
			uint8_t offsetAddr = 0;
			uint8_t reg1;
			uint8_t reg2;
			token = strtok(NULL, " "); // Get the next token
			if (token != NULL && token[0] == 'r')
			    reg1 = atoi(token + 1);
			token = strtok(NULL, " "); // Get the next token
			if (token != NULL && token[0] == 'r')
			    reg2 = atoi(token + 1);
			token = strtok(NULL, " "); // Get the next token
			if (token[0] == '@')
			{
			    char* label = token;
			    strsep(&label, "@");
			    char* labelName = strsep(&label, " ;\n"); // Trim any comments or other text off the end
			    getAddressesOfLabel(labelName, labelMap, &segAddr, &offsetAddr);
			    instr = LRC << 12;
			    instr |= reg1 << 8;
			    instr |= segAddr;
			    binary[instrIndex] = instr; // Save the assembled instruction
			    instrIndex++;
			    instr = LRC << 12;
			    instr |= reg2 << 8;
			    instr |= offsetAddr;
			}
			arg += 3; // Parsed the entire instruction here
		    }
		    else if (!strcmp(token, "HALT"))
		    {
			instr = EXT << 12;
			instr |= EXT_HALT << 8;
			arg++;
		    }
		    else if (!strcmp(token, "CPY"))
		    {
			instr = EXT << 12;
			instr |= EXT_CPY << 8;
			arg++;
		    }
		    else if (!strcmp(token, "NOT"))
		    {
			instr = EXT << 12;
			instr |= EXT_NOT << 8;
			arg++;
		    }
		    else if (!strcmp(token, "LSL"))
		    {
			instr = EXT << 12;
			instr |= EXT_LSL << 8;
			arg++;
		    }
		    else if (!strcmp(token, "LSR"))
		    {
			instr = EXT << 12;
			instr |= EXT_LSR << 8;
			arg++;
		    }
		    else if (!strcmp(token, "JMP"))
		    {
			instr = EXT << 12;
			instr |= EXT_JMP << 8;
			arg++;
		    }
		    else if (!strcmp(token, "NOP"))
		    {
			instr = EXT << 12;
			instr |= EXT_NOP << 8;
			arg++;
		    }
		    else if (!strcmp(token, "BRKP"))
		    {
			instr = EXT << 12;
			instr |= EXT_BRKP << 8;
			arg++;
		    }
		    else if (!strcmp(token, "ADD"))
			instr = ADD << 12;
		    else if (!strcmp(token, "SUB"))
			instr = SUB << 12;
		    else if (!strcmp(token, "ADDC"))
			instr = ADDC << 12;
		    else if (!strcmp(token, "SUBC"))
			instr = SUBC << 12;
		    else if (!strcmp(token, "CMP"))
			instr = CMP << 12;
		    else if (!strcmp(token, "JLT"))
			instr = JLT << 12;
		    else if (!strcmp(token, "JGT"))
			instr = JGT << 12;
		    else if (!strcmp(token, "JEQ"))
			instr = JEQ << 12;
		    else if (!strcmp(token, "LDR"))
			instr = LDR << 12;
		    else if (!strcmp(token, "STR"))
			instr = STR << 12;
		    else if (!strcmp(token, "LRC"))
			instr = LRC << 12;
		    else if (!strcmp(token, "AND"))
			instr = AND << 12;
		    else if (!strcmp(token, "OR"))
			instr = OR << 12;
		    else if (!strcmp(token, "XOR"))
			instr = XOR << 12;
		    else
		    {
			printf("Not a known instruction on line %d\n", lineCount);
			exit(1);
		    }
		    arg++;
		}
		else if (arg < 4)
		{
		    if (token[0] == 'r')
		    {
			int shift = 0;
			if (arg == 1)
			    shift = 8;
			if (arg == 2)
			    shift = 4;
			if (arg == 3)
			    shift = 0;
			instr |= (atoi(token + 1) << shift);
		    }
		    else if (token[0] == '#' || token[0] == '$') // Token is a constant
		    {
			char* num = token;
			uint8_t constant;
			if (token[0] == '#') // A constant in base 10
			{
			    // Remove the # from the string
			    strsep(&num, "#");
			    // Convert to integer
			    constant = (uint8_t)atoi(num);
			}
			else if (token[0] == '$')
			{
			    // Remove the $ from the string
			    strsep(&num, "$");
			    // Convert to base 16
			    constant = (uint8_t)strtol(num, NULL, 16);
			}
			instr |= constant;
			arg++;
		    }
		    arg++;
		}
		token = strtok(NULL, " "); // Get the next token
	    }
	    binary[instrIndex] = retro_cpu_to_le16(instr); // Save the assembled instruction
	    instrIndex++;
	}
	// Free and null the line pointer. getline will reallocate for us
	free(line);
	line = NULL;
    }

    // Free the label map
    for (int i = 0; i < MAX_LABELS; i++)
    {
	if (labelMap[i] != NULL)
	{
	    if (labelMap[i]->label != NULL)
	    {
		free(labelMap[i]->label);
	    }
	    free(labelMap[i]);
	}
    }
    free(labelMap);

    char* filenameNoExtension = strsep(&filename, ".");
    if (filenameNoExtension != NULL)
	filename = filenameNoExtension;

    // Now write the binary array out to a file with .vaporbin appended to the name
    FILE* bin = fopen(strcat(filename, ".vaporbin"), "wb");
    uint16_t numInstructionsLe = retro_cpu_to_le16(numInstructions);
    // Prefix binary with length
    fwrite(&numInstructionsLe, sizeof(uint16_t), 1, bin);
    size_t written = fwrite(binary, sizeof(uint16_t), numInstructions, bin);
    uint16_t romSizeLe = retro_cpu_to_le16(romSize);
    fwrite(&romSizeLe, sizeof(uint16_t), 1, bin);
    if (romSize)
    {
	uint8_t *buf = malloc(romSize);
	fread(buf, sizeof(uint8_t), romSize, romSrc);
	fwrite(buf, sizeof(uint16_t), romSize, bin);
	free(buf);
    }
    fclose(bin);
    free(binary);
    binary = NULL;
    // Check that the instructions were written correctly
    if (written != numInstructions)
    {
	printf("Error writing binary file\n");
    }
    else
    {
	printf("%zd instructions written to %s\n", written, filename);
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq $0x0, -0x50(%rbp)
cmpl $0x2, %edi
jl 0x1b42
movl $0x1, %eax
xorl %r14d, %r14d
xorl %ebx, %ebx
movslq %eax, %rcx
movq (%rsi,%rcx,8), %rdx
cmpb $0x2d, (%rdx)
jne 0x1303
cmpb $0x66, 0x1(%rdx)
jne 0x12e7
cmpb $0x0, 0x2(%rdx)
jne 0x12e7
leal 0x1(%rax), %ecx
cmpl %edi, %ecx
jge 0x12e7
movslq %ecx, %rax
movq (%rsi,%rax,8), %r14
movq %r14, -0x50(%rbp)
jmp 0x1305
cmpb $0x72, 0x1(%rdx)
jne 0x1303
cmpb $0x0, 0x2(%rdx)
jne 0x1303
leal 0x1(%rax), %ecx
cmpl %edi, %ecx
jge 0x1303
movslq %ecx, %rax
movq (%rsi,%rax,8), %rbx
jmp 0x1305
movl %eax, %ecx
incl %ecx
movl %ecx, %eax
cmpl %edi, %ecx
jl 0x12bb
testq %r14, %r14
je 0x1b42
leaq 0xce7(%rip), %rsi       # 0x2004
movq %r14, %rdi
callq 0x1120
movq %rax, -0x88(%rbp)
testq %rax, %rax
je 0x138e
testq %rbx, %rbx
je 0x13a9
leaq 0xcc7(%rip), %rsi       # 0x2004
movq %rbx, %rdi
callq 0x1120
testq %rax, %rax
je 0x19f7
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x1110
movq %r14, %rdi
callq 0x10d0
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1110
cmpq $0x8000, %rbx           # imm = 0x8000
jg 0x1b18
movq %rbx, -0x70(%rbp)
movq %r14, -0x80(%rbp)
jmp 0x13b9
callq 0x1040
movl (%rax), %edi
callq 0x1180
leaq 0xc65(%rip), %rdi       # 0x2006
movq %r14, %rsi
jmp 0x1a0d
movq $0x0, -0x70(%rbp)
movq $0x0, -0x80(%rbp)
movq -0x88(%rbp), %r12
movq %r12, %rdi
callq 0x1b6b
movl %eax, %ebx
leaq 0xc6b(%rip), %rdi       # 0x203c
xorl %r15d, %r15d
movl %eax, %esi
xorl %eax, %eax
callq 0x10a0
movl %ebx, -0x74(%rbp)
movl %ebx, %r13d
leaq (,%r13,2), %rdi
callq 0x10f0
movq %rax, -0x68(%rbp)
leaq -0x48(%rbp), %rbx
movq %r15, (%rbx)
leaq -0xa0(%rbp), %r14
movq %r15, (%r14)
movl $0x2000, %edi           # imm = 0x2000
callq 0x10f0
movq %rax, %r15
leaq -0xa8(%rbp), %rsi
movq %rax, (%rsi)
movq %r12, %rdi
callq 0x1c31
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rbx
movq %r12, %rdx
callq 0x1150
cmpq $-0x1, %rax
je 0x19a0
leaq -0x48(%rbp), %r14
movq %rax, -0x90(%rbp)
movl %eax, -0x58(%rbp)
movl %eax, -0x54(%rbp)
xorl %ecx, %ecx
movq $0x0, -0x40(%rbp)
movq %r13, -0x98(%rbp)
incl %ecx
movq -0x48(%rbp), %rdi
movzbl (%rdi), %eax
addl $-0xa, %eax
cmpl $0x36, %eax
movl %ecx, -0x5c(%rbp)
ja 0x14b2
movabsq $0x42000000000001, %rdx # imm = 0x42000000000001
btq %rax, %rdx
jae 0x14b2
callq 0x1030
movq $0x0, -0x48(%rbp)
movq %r14, %rdi
leaq -0xa0(%rbp), %rsi
movq %rbx, %rdx
callq 0x1150
cmpq $-0x1, %rax
movl -0x5c(%rbp), %ecx
jne 0x1461
jmp 0x19a0
cmpl %r13d, -0x40(%rbp)
jge 0x1485
leaq 0xb96(%rip), %rsi       # 0x2055
callq 0x1130
testq %rax, %rax
je 0x196f
movq %rax, %r13
xorl %r14d, %r14d
leaq 0xb83(%rip), %rbx       # 0x205d
testl %r14d, %r14d
je 0x1530
movzbl (%r13), %eax
leal -0x23(%rax), %ecx
cmpl $0x2, %ecx
jae 0x1759
movq %r13, -0x38(%rbp)
movzbl (%r13), %eax
cmpl $0x24, %eax
je 0x186e
cmpl $0x23, %eax
movq -0x90(%rbp), %rax
jne 0x188e
leaq -0x38(%rbp), %rdi
leaq 0xbc0(%rip), %rsi       # 0x20dd
callq 0x1100
movq -0x38(%rbp), %rdi
callq 0x1140
jmp 0x188e
movq %r13, %rdi
leaq 0xb1f(%rip), %rsi       # 0x2059
callq 0x10c0
testl %eax, %eax
je 0x1797
movq %r13, %rdi
leaq 0xb10(%rip), %rsi       # 0x2061
callq 0x10c0
movl $0x2, %r14d
testl %eax, %eax
je 0x18c6
movq %r13, %rdi
leaq 0xaf8(%rip), %rsi       # 0x2066
callq 0x10c0
testl %eax, %eax
je 0x18cb
movq %r13, %rdi
leaq 0xae5(%rip), %rsi       # 0x206a
callq 0x10c0
testl %eax, %eax
je 0x18d2
movq %r13, %rdi
leaq 0xad2(%rip), %rsi       # 0x206e
callq 0x10c0
testl %eax, %eax
je 0x18d9
movq %r13, %rdi
leaq 0xabf(%rip), %rsi       # 0x2072
callq 0x10c0
testl %eax, %eax
je 0x18e0
movq %r13, %rdi
leaq 0xaac(%rip), %rsi       # 0x2076
callq 0x10c0
testl %eax, %eax
je 0x18e7
movq %r13, %rdi
leaq 0xa99(%rip), %rsi       # 0x207a
callq 0x10c0
testl %eax, %eax
je 0x18ee
movq %r13, %rdi
leaq 0xa86(%rip), %rsi       # 0x207e
callq 0x10c0
testl %eax, %eax
je 0x18f5
movq %r13, %rdi
leaq 0xa74(%rip), %rsi       # 0x2083
callq 0x10c0
movl $0x1, %r14d
testl %eax, %eax
je 0x18fc
movq %r13, %rdi
leaq 0xa5b(%rip), %rsi       # 0x2087
callq 0x10c0
testl %eax, %eax
je 0x1903
movq %r13, %rdi
leaq 0xa48(%rip), %rsi       # 0x208b
callq 0x10c0
testl %eax, %eax
je 0x190a
movq %r13, %rdi
leaq 0xa36(%rip), %rsi       # 0x2090
callq 0x10c0
testl %eax, %eax
je 0x1911
movq %r13, %rdi
leaq 0xa24(%rip), %rsi       # 0x2095
callq 0x10c0
testl %eax, %eax
je 0x1918
movq %r13, %rdi
leaq 0xa11(%rip), %rsi       # 0x2099
callq 0x10c0
testl %eax, %eax
je 0x191f
movq %r13, %rdi
leaq 0x9fe(%rip), %rsi       # 0x209d
callq 0x10c0
testl %eax, %eax
je 0x1929
movq %r13, %rdi
leaq 0x9eb(%rip), %rsi       # 0x20a1
callq 0x10c0
testl %eax, %eax
je 0x1933
movq %r13, %rdi
leaq 0x9d8(%rip), %rsi       # 0x20a5
callq 0x10c0
testl %eax, %eax
je 0x193d
movq %r13, %rdi
leaq 0x9c5(%rip), %rsi       # 0x20a9
callq 0x10c0
testl %eax, %eax
je 0x1947
movq %r13, %rdi
leaq 0x9b2(%rip), %rsi       # 0x20ad
callq 0x10c0
testl %eax, %eax
je 0x1951
movq %r13, %rdi
leaq 0x99f(%rip), %rsi       # 0x20b1
callq 0x10c0
testl %eax, %eax
je 0x195b
cmpb $0x4f, (%r13)
jne 0x1738
cmpb $0x52, 0x1(%r13)
jne 0x1738
cmpb $0x0, 0x2(%r13)
je 0x1965
movq %r13, %rdi
leaq 0x973(%rip), %rsi       # 0x20b5
callq 0x10c0
movw $0xe000, %r12w          # imm = 0xE000
testl %eax, %eax
je 0x18a1
jmp 0x1b58
cmpl $0x72, %eax
jne 0x189e
cmpl $0x1, %r14d
sete %bl
shlb $0x3, %bl
incq %r13
movq %r13, %rdi
callq 0x1140
cmpl $0x2, %r14d
movzbl %bl, %ecx
leaq 0x8d8(%rip), %rbx       # 0x205d
movl $0x4, %edx
cmovel %edx, %ecx
shll %cl, %eax
orl %eax, %r12d
jmp 0x189e
xorl %eax, %eax
movb %al, -0x2c(%rbp)
movb %al, -0x29(%rbp)
xorl %edi, %edi
movq %rbx, %rsi
callq 0x1130
testq %rax, %rax
je 0x17c1
cmpb $0x72, (%rax)
jne 0x17c1
incq %rax
movq %rax, %rdi
callq 0x1140
movl %eax, -0x54(%rbp)
xorl %edi, %edi
movq %rbx, %rsi
callq 0x1130
testq %rax, %rax
je 0x17e3
cmpb $0x72, (%rax)
jne 0x17e3
incq %rax
movq %rax, %rdi
callq 0x1140
movl %eax, -0x58(%rbp)
xorl %edi, %edi
movq %rbx, %rsi
callq 0x1130
cmpb $0x40, (%rax)
jne 0x1866
movq %rax, -0x38(%rbp)
leaq -0x38(%rbp), %r14
movq %r14, %rdi
leaq 0x85b(%rip), %rsi       # 0x205f
callq 0x1100
movq %r14, %rdi
leaq 0x842(%rip), %rsi       # 0x2055
callq 0x1100
movq %rax, %rdi
movq %r15, %rsi
leaq -0x2c(%rbp), %rdx
leaq -0x29(%rbp), %rcx
callq 0x1d91
movzbl -0x54(%rbp), %eax
shll $0x8, %eax
movzbl -0x2c(%rbp), %ecx
orl %eax, %ecx
movl $0xb000, %edx           # imm = 0xB000
orl %edx, %ecx
movq -0x40(%rbp), %rsi
movslq %esi, %rsi
movq -0x68(%rbp), %rax
movw %cx, (%rax,%rsi,2)
incl %esi
movq %rsi, -0x40(%rbp)
movzbl -0x58(%rbp), %eax
shll $0x8, %eax
movzbl -0x29(%rbp), %r12d
orl %eax, %r12d
orl %edx, %r12d
movl $0x4, %r14d
jmp 0x18a1
leaq -0x38(%rbp), %rdi
leaq 0x866(%rip), %rsi       # 0x20df
callq 0x1100
movq -0x38(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x10e0
movq %rax, -0x90(%rbp)
movzbl %al, %eax
orl %eax, %r12d
incl %r14d
incl %r14d
xorl %edi, %edi
movq %rbx, %rsi
callq 0x1130
testq %rax, %rax
je 0x196f
movq %rax, %r13
cmpl $0x4, %r14d
jl 0x14da
jmp 0x196f
xorl %r12d, %r12d
jmp 0x18a1
movw $0x100, %r12w           # imm = 0x100
jmp 0x18a1
movw $0x200, %r12w           # imm = 0x200
jmp 0x18a1
movw $0x300, %r12w           # imm = 0x300
jmp 0x18a1
movw $0x400, %r12w           # imm = 0x400
jmp 0x18a1
movw $0x500, %r12w           # imm = 0x500
jmp 0x18a1
movw $0x600, %r12w           # imm = 0x600
jmp 0x18a1
movw $0x700, %r12w           # imm = 0x700
jmp 0x18a1
movw $0x1000, %r12w          # imm = 0x1000
jmp 0x18a1
movw $0x2000, %r12w          # imm = 0x2000
jmp 0x18a1
movw $0x3000, %r12w          # imm = 0x3000
jmp 0x18a1
movw $0x4000, %r12w          # imm = 0x4000
jmp 0x18a1
movw $0x5000, %r12w          # imm = 0x5000
jmp 0x18a1
movw $0x6000, %r12w          # imm = 0x6000
jmp 0x18a1
movw $0x7000, %r12w          # imm = 0x7000
jmp 0x18a1
movw $0x8000, %r12w          # imm = 0x8000
jmp 0x18a1
movw $0x9000, %r12w          # imm = 0x9000
jmp 0x18a1
movw $0xa000, %r12w          # imm = 0xA000
jmp 0x18a1
movw $0xb000, %r12w          # imm = 0xB000
jmp 0x18a1
movw $0xc000, %r12w          # imm = 0xC000
jmp 0x18a1
movw $0xd000, %r12w          # imm = 0xD000
jmp 0x18a1
movq -0x40(%rbp), %rcx
movslq %ecx, %rcx
movq -0x68(%rbp), %rax
movw %r12w, (%rax,%rcx,2)
incl %ecx
movq %rcx, -0x40(%rbp)
movq -0x48(%rbp), %rdi
movq -0x98(%rbp), %r13
movq -0x88(%rbp), %rbx
leaq -0x48(%rbp), %r14
jmp 0x1485
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rdi
testq %rdi, %rdi
je 0x19c5
movq 0x8(%rdi), %rax
testq %rax, %rax
je 0x19c0
movq %rax, %rdi
callq 0x1030
movq (%r15,%rbx,8), %rdi
callq 0x1030
incq %rbx
cmpq $0x400, %rbx            # imm = 0x400
jne 0x19a2
movq %r15, %rdi
callq 0x1030
leaq 0x701(%rip), %rsi       # 0x20e1
leaq -0x50(%rbp), %rdi
callq 0x1100
testq %rax, %rax
je 0x1a15
movq %rax, %rbx
movq %rax, -0x50(%rbp)
jmp 0x1a19
callq 0x1040
movl (%rax), %edi
callq 0x1180
leaq 0x5fc(%rip), %rdi       # 0x2006
movq %rbx, %rsi
movq %rax, %rdx
jmp 0x1b01
movq -0x50(%rbp), %rbx
movq -0x70(%rbp), %r15
movq %rbx, %rdi
callq 0x1090
movabsq $0x6962726f7061762e, %rcx # imm = 0x6962726F7061762E
movq %rcx, (%rbx,%rax)
movw $0x6e, 0x8(%rbx,%rax)
leaq 0x6ac(%rip), %rsi       # 0x20ed
movq %rbx, %rdi
callq 0x1120
movq %rax, %rbx
leaq -0x38(%rbp), %rdi
movl -0x74(%rbp), %eax
movw %ax, (%rdi)
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x1170
movl $0x2, %esi
movq -0x68(%rbp), %rdi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1170
movq %rax, %r14
leaq -0x2c(%rbp), %rdi
movw %r15w, (%rdi)
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x1170
testw %r15w, %r15w
je 0x1add
movzwl %r15w, %r15d
movq %r15, %rdi
callq 0x10f0
movq %rax, %r12
movl $0x1, %esi
movq %rax, %rdi
movq %r15, %rdx
movq -0x80(%rbp), %rcx
callq 0x1070
movl $0x2, %esi
movq %r12, %rdi
movq %r15, %rdx
movq %rbx, %rcx
callq 0x1170
movq %r12, %rdi
callq 0x1030
movq %rbx, %rdi
callq 0x1080
movq -0x68(%rbp), %rdi
callq 0x1030
cmpq %r13, %r14
jne 0x1b0a
movq -0x50(%rbp), %rdx
leaq 0x5f2(%rip), %rdi       # 0x20f0
movq %r13, %rsi
xorl %eax, %eax
callq 0x10a0
jmp 0x1b2e
leaq 0x61e(%rip), %rdi       # 0x212f
callq 0x1060
jmp 0x1b2e
leaq 0x503(%rip), %rdi       # 0x2022
movq %rbx, %rsi
movl $0x8000, %edx           # imm = 0x8000
xorl %eax, %eax
callq 0x10a0
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x600(%rip), %rdi       # 0x2149
callq 0x1060
movl $0x1, %edi
callq 0x1160
leaq 0x55a(%rip), %rdi       # 0x20b9
movl -0x5c(%rbp), %esi
xorl %eax, %eax
callq 0x10a0
jmp 0x1b4e