// File: /workspace/github_cpp_makefile_star2_O2/sangwoojun[P]rv32emulator/emulator.cpp
// Function: normalize_labels(instr*, label_loc*, int, source*)
void normalize_labels(instr* imem, label_loc* labels, int label_count, source* src) {
	for ( int i = 0; i < DATA_OFFSET/4; i++ ) {
		instr* ii = &imem[i];
		if ( ii->op == UNIMPL ) continue;

		if ( ii->a1.type == OPTYPE_LABEL ) {
			ii->a1.type = OPTYPE_IMM;
			ii->a1.imm = label_addr(ii->a1.label, labels, label_count, ii->orig_line);
		}
		if ( ii->a2.type == OPTYPE_LABEL ) {
			ii->a2.type = OPTYPE_IMM;
			ii->a2.imm = label_addr(ii->a2.label, labels, label_count, ii->orig_line);
			switch (ii->op) {
				case LUI: {
					ii->a2.imm = (ii->a2.imm>>12); 
					char areg[4]; sprintf(areg, "x%02d", ii->a1.reg);
					char immu[12]; sprintf(immu, "0x%08x" , ii->a2.imm);
					//printf( "LUI %d 0x%x %s\n", ii->a1.reg, ii->a2.imm, immu );
					append_source("lui", areg, immu, NULL, src, ii);
					break;
				}
				case JAL:
				int pc = (i*4);
				int target = ii->a3.imm;
				int diff = pc - target;
				if ( diff < 0 ) diff = -diff;

				if ( diff >= (1<<21) ) {
					printf( "JAL instruction target out of bounds\n" );
					exit(3);
				}
				break;
			}
		}
		if ( ii->a3.type == OPTYPE_LABEL ) {
			ii->a3.type = OPTYPE_IMM;
			ii->a3.imm = label_addr(ii->a3.label, labels, label_count, ii->orig_line);
			switch(ii->op) {
				case ADDI: {
					ii->a3.imm = ii->a3.imm&((1<<12)-1);
					char a1reg[4]; sprintf(a1reg, "x%02d", ii->a1.reg);
					char a2reg[4]; sprintf(a2reg, "x%02d", ii->a2.reg);
					char immd[12]; sprintf(immd, "0x%08x" , ii->a3.imm);
					//printf( "ADDI %d %d 0x%x %s\n", ii->a1.reg, ii->a2.reg, ii->a3.imm, immd );
					append_source("addi", a1reg, a2reg, immd, src, ii);
					break;
				}
				case BEQ: case BGE: case BGEU: case BLT: case BLTU: case BNE: {
					int pc = (i*4);
					int target = ii->a3.imm;
					int diff = pc - target;
					if ( diff < 0 ) diff = -diff;

					if ( diff >= (1<<13) ) {
						printf( "Branch instruction target out of bounds\n" );
						exit(3);
					}
					break;
				}
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, -0x48(%rbp)
movl %edx, -0x2c(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdi, %r12
xorl %r14d, %r14d
xorl %r15d, %r15d
cmpq $0x130000, %r14         # imm = 0x130000
je 0x50fb
cmpl $0x0, (%r12,%r14)
je 0x506c
cmpl $0x3, 0x4(%r12,%r14)
jne 0x4f68
leaq (%r12,%r14), %r13
addq $0x8, %r13
movl $0x2, -0x4(%r13)
movl 0x88(%r13), %ecx
movq %r13, %rdi
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x338c
movl %eax, 0x24(%r13)
leaq (%r12,%r14), %r13
cmpl $0x3, 0x30(%r12,%r14)
jne 0x501e
leaq (%r12,%r14), %rbx
addq $0x34, %rbx
movl $0x2, -0x4(%rbx)
movl 0x5c(%rbx), %ecx
movq %rbx, %rdi
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x338c
movl %eax, 0x24(%rbx)
movl -0x34(%rbx), %ecx
cmpl $0xc, %ecx
je 0x5000
cmpl $0x12, %ecx
jne 0x501e
shrl $0xc, %eax
movl %eax, 0x58(%r12,%r14)
movl 0x28(%r12,%r14), %edx
leaq -0x30(%rbp), %rdi
leaq 0x5811(%rip), %rsi      # 0xa7d2
xorl %eax, %eax
callq 0x2060
movl 0x58(%r12,%r14), %edx
leaq -0x54(%rbp), %rbx
movq %rbx, %rdi
leaq 0x57fd(%rip), %rsi      # 0xa7d8
xorl %eax, %eax
callq 0x2060
leaq 0x5612(%rip), %rdi      # 0xa5fb
leaq -0x30(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
movq -0x48(%rbp), %r8
movq %r13, %r9
callq 0x3280
jmp 0x501e
movl %r15d, %eax
subl 0x84(%r12,%r14), %eax
movl %eax, %ecx
negl %ecx
cmovsl %eax, %ecx
cmpl $0x200000, %ecx         # imm = 0x200000
jae 0x5113
cmpl $0x3, 0x5c(%r12,%r14)
jne 0x506c
leaq (%r12,%r14), %rbx
addq $0x60, %rbx
movl $0x2, -0x4(%rbx)
movl 0x30(%rbx), %ecx
movq %rbx, %rdi
movq -0x38(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x338c
movl %eax, 0x24(%rbx)
movl -0x60(%rbx), %ecx
leal -0x6(%rcx), %edx
cmpl $0x6, %edx
jae 0x507c
movl %r15d, %ecx
subl %eax, %ecx
movl %ecx, %eax
negl %eax
cmovsl %ecx, %eax
cmpl $0x2000, %eax           # imm = 0x2000
jae 0x510a
addl $0x4, %r15d
addq $0x98, %r14
jmp 0x4f1e
cmpl $0x2, %ecx
jne 0x506c
andl $0xfff, %eax            # imm = 0xFFF
movl %eax, 0x84(%r12,%r14)
movl 0x28(%r12,%r14), %edx
leaq -0x30(%rbp), %rdi
leaq 0x5734(%rip), %rbx      # 0xa7d2
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2060
movl 0x54(%r12,%r14), %edx
leaq -0x3c(%rbp), %rdi
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2060
movl 0x84(%r12,%r14), %edx
leaq -0x54(%rbp), %rbx
movq %rbx, %rdi
leaq 0x5707(%rip), %rsi      # 0xa7d8
xorl %eax, %eax
callq 0x2060
leaq 0x54b0(%rip), %rdi      # 0xa58f
leaq -0x30(%rbp), %rsi
leaq -0x3c(%rbp), %rdx
movq %rbx, %rcx
movq -0x48(%rbp), %r8
movq %r13, %r9
callq 0x3280
jmp 0x506c
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x5a26(%rip), %rdi      # 0xab37
jmp 0x511a
leaq 0x59f8(%rip), %rdi      # 0xab12
callq 0x2300
pushq $0x3
popq %rdi
callq 0x2200