// File: sangwoojun[P]rv32emulator/emulator.cpp
// Function: parse(_IO_FILE*, unsigned char*, instr*, int&, label_loc*, int&, source*)
void parse(FILE* fin, uint8_t* mem, instr* imem, int& memoff, label_loc* labels, int& label_count, source* src) {
	int line = 0;

	printf( "Parsing input file\n" );

	//sectionType cur_section = SECTION_NONE;

	char rbuf[1024];
	while(!feof(fin)) {
		if ( !fgets(rbuf, 1024, fin) ) break;
		for (char* p = rbuf; *p; ++p) *p = tolower(*p);
		line++;

		char* ftok = strtok(rbuf, " \t\r\n");
		if ( !ftok ) continue;

		if ( ftok[0] == '#' ) continue;

		if ( ftok[strlen(ftok)-1] == ':' ) {
			ftok[strlen(ftok)-1] = 0;
			if ( strlen(ftok) >= MAX_LABEL_LEN ) {
				printf( "Exceeded maximum length of label: %s\n", ftok );
				exit(3);
			}
			if ( label_count >= MAX_LABEL_COUNT ) {
				printf( "Exceeded maximum number of supported labels" );
				exit(3);
			}
			strncpy(labels[label_count].label, ftok, MAX_LABEL_LEN);
			labels[label_count].loc = memoff;
			label_count++;
			//printf( "Parsing label %s at mem %x\n", ftok, memoff );

			char* ntok = strtok(NULL, " \t\r\n");
			// there is more code after label
			if ( ntok ) {
				if ( ntok[0] == '.' ) {
					memoff = parse_assembler_directive(line, ntok, mem, memoff);
				} else {
					int count = parse_instr(line, ntok, imem, memoff, labels, src);
					for ( int i = 0; i < count; i++ ) *(uint32_t*)&mem[memoff+(i*4)] = 0xcccccccc;
					memoff += count*4;
				}
			}
		} else if ( ftok[0] == '.' ) {
			memoff = parse_assembler_directive(line, ftok, mem, memoff);
		} else {
			int count = parse_instr(line, ftok, imem, memoff, labels, src);
			for ( int i = 0; i < count; i++ ) *(uint32_t*)&mem[memoff+(i*4)] = 0xcccccccc;
			memoff += count*4;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x480, %rsp            # imm = 0x480
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
leaq 0x61cc(%rip), %rdi      # 0xb691
movb $0x0, %al
callq 0x2040
movq -0x8(%rbp), %rdi
callq 0x2370
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x54e6
jmp 0x5830
leaq -0x440(%rbp), %rdi
movq -0x8(%rbp), %rdx
movl $0x400, %esi            # imm = 0x400
callq 0x23a0
cmpq $0x0, %rax
jne 0x5506
jmp 0x5830
leaq -0x440(%rbp), %rax
movq %rax, -0x448(%rbp)
movq -0x448(%rbp), %rax
cmpb $0x0, (%rax)
je 0x554e
movq -0x448(%rbp), %rax
movsbl (%rax), %edi
callq 0x2340
movb %al, %cl
movq -0x448(%rbp), %rax
movb %cl, (%rax)
movq -0x448(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x448(%rbp)
jmp 0x5514
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
leaq -0x440(%rbp), %rdi
leaq 0x5ff1(%rip), %rsi      # 0xb556
callq 0x2390
movq %rax, -0x450(%rbp)
cmpq $0x0, -0x450(%rbp)
jne 0x5580
jmp 0x54cc
movq -0x450(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0x5594
jmp 0x54cc
movq -0x450(%rbp), %rax
movq %rax, -0x470(%rbp)
movq -0x450(%rbp), %rdi
callq 0x2100
movq %rax, %rcx
movq -0x470(%rbp), %rax
subq $0x1, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x3a, %eax
jne 0x5774
movq -0x450(%rbp), %rax
movq %rax, -0x478(%rbp)
movq -0x450(%rbp), %rdi
callq 0x2100
movq %rax, %rcx
movq -0x478(%rbp), %rax
subq $0x1, %rcx
movb $0x0, (%rax,%rcx)
movq -0x450(%rbp), %rdi
callq 0x2100
cmpq $0x20, %rax
jb 0x5626
movq -0x450(%rbp), %rsi
leaq 0x6090(%rip), %rdi      # 0xb6a5
movb $0x0, %al
callq 0x2040
movl $0x3, %edi
callq 0x2250
movq -0x30(%rbp), %rax
cmpl $0x80, (%rax)
jl 0x564a
leaq 0x6092(%rip), %rdi      # 0xb6cb
movb $0x0, %al
callq 0x2040
movl $0x3, %edi
callq 0x2250
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rax
movslq (%rax), %rax
imulq $0x24, %rax, %rax
addq %rax, %rdi
movq -0x450(%rbp), %rsi
movl $0x20, %edx
callq 0x2120
movq -0x20(%rbp), %rax
movl (%rax), %ecx
movq -0x28(%rbp), %rax
movq -0x30(%rbp), %rdx
movslq (%rdx), %rdx
imulq $0x24, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x20(%rax)
movq -0x30(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
xorl %eax, %eax
movl %eax, %edi
leaq 0x5eb8(%rip), %rsi      # 0xb556
callq 0x2390
movq %rax, -0x458(%rbp)
cmpq $0x0, -0x458(%rbp)
je 0x576f
movq -0x458(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2e, %eax
jne 0x56ed
movl -0x34(%rbp), %edi
movq -0x458(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
callq 0x3ec0
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
jmp 0x576d
movl -0x34(%rbp), %edi
movq -0x458(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
movq -0x28(%rbp), %r8
movq 0x10(%rbp), %r9
callq 0x4ef0
movl %eax, -0x45c(%rbp)
movl $0x0, -0x460(%rbp)
movl -0x460(%rbp), %eax
cmpl -0x45c(%rbp), %eax
jge 0x575c
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
movl -0x460(%rbp), %edx
shll $0x2, %edx
addl %edx, %ecx
movslq %ecx, %rcx
movl $0xcccccccc, (%rax,%rcx) # imm = 0xCCCCCCCC
movl -0x460(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x460(%rbp)
jmp 0x571e
movl -0x45c(%rbp), %ecx
shll $0x2, %ecx
movq -0x20(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x576f
jmp 0x582b
movq -0x450(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2e, %eax
jne 0x57a9
movl -0x34(%rbp), %edi
movq -0x450(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
callq 0x3ec0
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
jmp 0x5829
movl -0x34(%rbp), %edi
movq -0x450(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
movq -0x28(%rbp), %r8
movq 0x10(%rbp), %r9
callq 0x4ef0
movl %eax, -0x464(%rbp)
movl $0x0, -0x468(%rbp)
movl -0x468(%rbp), %eax
cmpl -0x464(%rbp), %eax
jge 0x5818
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
movl -0x468(%rbp), %edx
shll $0x2, %edx
addl %edx, %ecx
movslq %ecx, %rcx
movl $0xcccccccc, (%rax,%rcx) # imm = 0xCCCCCCCC
movl -0x468(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x468(%rbp)
jmp 0x57da
movl -0x464(%rbp), %ecx
shll $0x2, %ecx
movq -0x20(%rbp), %rax
addl (%rax), %ecx
movl %ecx, (%rax)
jmp 0x582b
jmp 0x54cc
addq $0x480, %rsp            # imm = 0x480
popq %rbp
retq
nopl (%rax)