// File: sangwoojun[P]rv32emulator/emulator.cpp
// Function: main
int
main(int argc, char** argv) {
	if ( argc < 2 ) {
		printf( "usage: %s asmfile\n", argv[0] );
		exit(1);
	}

	FILE* fin = fopen(argv[1], "r" );
	if ( !fin ) {
		printf( "%s: No such file\n", argv[1] );
		exit(2);
	}

	bool start_immediate = false;
	if ( argc >= 3 ) {
		start_immediate = true;
	}


	//ProcessorState* ps = new ProcessorState();
	
	int memoff = 0;
	uint8_t* mem = (uint8_t*)malloc(MEM_BYTES);
	instr* imem = (instr*)malloc(DATA_OFFSET*sizeof(instr)/4);
	label_loc* labels = (label_loc*)malloc(MAX_LABEL_COUNT*sizeof(label_loc));
	int label_count = 0;
	source src;
	src.offset = 0;
	src.src = (char*)malloc(sizeof(char)*MAX_SRC_LEN);

	if ( !mem || !labels || !imem || !src.src ) {
		printf( "Memory allocation failed\n" );
		exit(2);
	}

	for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
		imem[i].op = UNIMPL;
		imem[i].a1.type = OPTYPE_NONE;
		imem[i].a2.type = OPTYPE_NONE;
		imem[i].a3.type = OPTYPE_NONE;
	}

	parse(fin, mem, imem, memoff, labels, label_count, &src);
	normalize_labels(imem, labels, label_count, &src);
	
	execute(mem, imem, labels, label_count, start_immediate);

	printf( "Execution done!\n" );
	exit(0);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
jge 0x6bcb
movq -0x10(%rbp), %rax
movq (%rax), %rsi
leaq 0x4d7d(%rip), %rdi      # 0xb937
movb $0x0, %al
callq 0x2040
movl $0x1, %edi
callq 0x2250
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x4a6c(%rip), %rsi      # 0xb646
callq 0x2240
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x6c0a
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x4d51(%rip), %rdi      # 0xb94a
movb $0x0, %al
callq 0x2040
movl $0x2, %edi
callq 0x2250
movb $0x0, -0x19(%rbp)
cmpl $0x3, -0x8(%rbp)
jl 0x6c18
movb $0x1, -0x19(%rbp)
movl $0x0, -0x20(%rbp)
movl $0x10000, %edi          # imm = 0x10000
callq 0x22a0
movq %rax, -0x28(%rbp)
movl $0x130000, %edi         # imm = 0x130000
callq 0x22a0
movq %rax, -0x30(%rbp)
movl $0x1200, %edi           # imm = 0x1200
callq 0x22a0
movq %rax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x48(%rbp)
movl $0x100000, %edi         # imm = 0x100000
callq 0x22a0
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x6c81
cmpq $0x0, -0x38(%rbp)
je 0x6c81
cmpq $0x0, -0x30(%rbp)
je 0x6c81
cmpq $0x0, -0x50(%rbp)
jne 0x6c99
leaq 0x4cd4(%rip), %rdi      # 0xb95c
movb $0x0, %al
callq 0x2040
movl $0x2, %edi
callq 0x2250
movl $0x0, -0x54(%rbp)
cmpl $0x2000, -0x54(%rbp)    # imm = 0x2000
jge 0x6d17
movq -0x30(%rbp), %rax
movslq -0x54(%rbp), %rcx
imulq $0x98, %rcx, %rcx
addq %rcx, %rax
movl $0x0, (%rax)
movq -0x30(%rbp), %rax
movslq -0x54(%rbp), %rcx
imulq $0x98, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x4(%rax)
movq -0x30(%rbp), %rax
movslq -0x54(%rbp), %rcx
imulq $0x98, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x30(%rax)
movq -0x30(%rbp), %rax
movslq -0x54(%rbp), %rcx
imulq $0x98, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x5c(%rax)
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x6ca0
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %r8
leaq -0x20(%rbp), %rcx
leaq -0x3c(%rbp), %r9
leaq -0x50(%rbp), %rax
movq %rax, (%rsp)
callq 0x5490
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x3c(%rbp), %edx
leaq -0x50(%rbp), %rcx
callq 0x6880
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movl -0x3c(%rbp), %ecx
movb -0x19(%rbp), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x5840
leaq 0x4c02(%rip), %rdi      # 0xb976
movb $0x0, %al
callq 0x2040
xorl %edi, %edi
callq 0x2250
nopw %cs:(%rax,%rax)