// File: NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::reg_RAW_dependency(unsigned int, unsigned int, unsigned int)
void O3_CPU::reg_RAW_dependency(uint32_t prior, uint32_t current, uint32_t source_index)
{
    for (uint32_t i=0; i<MAX_INSTR_DESTINATIONS; i++) {
        if (ROB.entry[prior].destination_registers[i] == 0)
            continue;

        if (ROB.entry[prior].destination_registers[i] == ROB.entry[current].source_registers[source_index]) {

            // we need to mark this dependency in the ROB since the producer might not be added in the store queue yet
            ROB.entry[prior].registers_instrs_depend_on_me[current] = 1;   // this load cannot be executed until the prior store gets executed
            ROB.entry[prior].registers_index_depend_on_me[current][source_index] = 1;   // this load cannot be executed until the prior store gets executed
            ROB.entry[prior].reg_RAW_producer = 1;

            ROB.entry[current].reg_ready = 0;
            ROB.entry[current].producer_id = ROB.entry[prior].instr_id; 
            ROB.entry[current].num_reg_dependent++;
            ROB.entry[current].reg_RAW_checked[source_index] = 1;

            DP (if(warmup_complete[cpu]) {
            cout << "[ROB] " << __func__ << " instr_id: " << ROB.entry[current].instr_id << " is_memory: " << +ROB.entry[current].is_memory;
            cout << " RAW reg_index: " << +ROB.entry[current].source_registers[source_index];
            cout << " producer_id: " << ROB.entry[prior].instr_id << endl; });

            return;
        }
    }
}

// Assembly:
movq %rdi, -0x8(%rsp)
movl %esi, -0xc(%rsp)
movl %edx, -0x10(%rsp)
movl %ecx, -0x14(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x20(%rsp)
movl $0x0, -0x18(%rsp)
movl -0x18(%rsp), %eax
leaq 0x12232(%rip), %rcx     # 0x29210
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jae 0x1716a
movq -0x20(%rsp), %rax
movq 0x9b8(%rax), %rax
movl -0xc(%rsp), %ecx
imulq $0x758, %rcx, %rcx      # imm = 0x758
addq %rcx, %rax
movl -0x18(%rsp), %ecx
movzbl 0x7c(%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x17016
jmp 0x1715a
movq -0x20(%rsp), %rcx
movq 0x9b8(%rcx), %rax
movl -0xc(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rax
movl -0x18(%rsp), %edx
movzbl 0x7c(%rax,%rdx), %eax
movq 0x9b8(%rcx), %rcx
movl -0x10(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movl -0x14(%rsp), %edx
movzbl 0x80(%rcx,%rdx), %ecx
cmpl %ecx, %eax
jne 0x17158
movq -0x20(%rsp), %rax
movq 0x9b8(%rax), %rcx
movl -0xc(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movl -0x10(%rsp), %edx
movb $0x1, 0x84(%rcx,%rdx)
movq 0x9b8(%rax), %rcx
movl -0xc(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
addq $0x184, %rcx            # imm = 0x184
movl -0x10(%rsp), %edx
shlq $0x2, %rdx
addq %rdx, %rcx
movl -0x14(%rsp), %edx
movb $0x1, (%rcx,%rdx)
movq 0x9b8(%rax), %rcx
movl -0xc(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movb $0x1, 0x58(%rcx)
movq 0x9b8(%rax), %rcx
movl -0x10(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movb $0x0, 0x59(%rcx)
movq 0x9b8(%rax), %rcx
movl -0xc(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movq (%rcx), %rdx
movq 0x9b8(%rax), %rcx
movl -0x10(%rsp), %esi
imulq $0x758, %rsi, %rsi      # imm = 0x758
addq %rsi, %rcx
movq %rdx, 0x18(%rcx)
movq 0x9b8(%rax), %rcx
movl -0x10(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rcx
movl 0x74(%rcx), %edx
addl $0x1, %edx
movl %edx, 0x74(%rcx)
movq 0x9b8(%rax), %rax
movl -0x10(%rsp), %ecx
imulq $0x758, %rcx, %rcx      # imm = 0x758
addq %rcx, %rax
movl -0x14(%rsp), %ecx
movb $0x1, 0x5d(%rax,%rcx)
jmp 0x1716a
jmp 0x1715a
movl -0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rsp)
jmp 0x16fd3
retq
nopl (%rax,%rax)