// File: /workspace/github_cpp_makefile_star2_O1/NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::complete_instr_fetch(PACKET_QUEUE*, unsigned char)
void O3_CPU::complete_instr_fetch(PACKET_QUEUE *queue, uint8_t is_it_tlb)
{
    uint32_t index = queue->head,
             rob_index = queue->entry[index].rob_index,
             num_fetched = 0;

#ifdef SANITY_CHECK
    if (rob_index != check_rob(queue->entry[index].instr_id))
        assert(0);
#endif

    // update ROB entry
    if (is_it_tlb) {
        ROB.entry[rob_index].translated = COMPLETED;
        ROB.entry[rob_index].instruction_pa = (queue->entry[index].instruction_pa << PAGE_SHIFT) | (ROB.entry[rob_index].ip & ((1 << PAGE_SHIFT) - 1)); // translated address
    }
    else
        ROB.entry[rob_index].fetched = COMPLETED;
    ROB.entry[rob_index].event_cycle = current_core_cycle[cpu];
    num_fetched++;

    DP ( if (warmup_complete[cpu]) {
    cout << "[" << queue->NAME << "] " << __func__ << " cpu: " << cpu <<  " instr_id: " << ROB.entry[rob_index].instr_id;
    cout << " ip: " << hex << ROB.entry[rob_index].ip << " address: " << ROB.entry[rob_index].instruction_pa << dec;
    cout << " translated: " << +ROB.entry[rob_index].translated << " fetched: " << +ROB.entry[rob_index].fetched;
    cout << " event_cycle: " << ROB.entry[rob_index].event_cycle << endl; });

    // check if other instructions were merged
    if (queue->entry[index].instr_merged) {
        for (uint32_t i=0; i<ROB_SIZE; i++) {
            if (queue->entry[index].rob_index_depend_on_me[i]) {

                // update ROB entry
                if (is_it_tlb) {
                    ROB.entry[i].translated = COMPLETED;
                    ROB.entry[i].instruction_pa = (queue->entry[index].instruction_pa << PAGE_SHIFT) | (ROB.entry[i].ip & ((1 << PAGE_SHIFT) - 1)); // translated address
                }
                else
                    ROB.entry[i].fetched = COMPLETED;
                ROB.entry[i].event_cycle = current_core_cycle[cpu] + (num_fetched / FETCH_WIDTH);
                num_fetched++;

                DP ( if (warmup_complete[cpu]) {
                cout << "[" << queue->NAME << "] " << __func__ << " cpu: " << cpu <<  " instr_id: " << ROB.entry[i].instr_id;
                cout << " ip: " << hex << ROB.entry[i].ip << " address: " << ROB.entry[i].instruction_pa << dec;
                cout << " translated: " << +ROB.entry[i].translated << " fetched: " << +ROB.entry[i].fetched << " provider: " << ROB.entry[rob_index].instr_id;
                cout << " event_cycle: " << ROB.entry[i].event_cycle << endl; });
            }
        }
    }

    // remove this entry
    queue->remove_queue(&queue->entry[index]);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movq %rsi, %rbx
movq %rdi, %r14
movl 0x2c(%rsi), %eax
movq 0x98(%rsi), %rcx
imulq $0x380, %rax, %r15      # imm = 0x380
movl 0x10(%rcx,%r15), %r12d
movq 0x368(%rcx,%r15), %rsi
callq 0xce2c
cmpl %eax, %r12d
jne 0xf4ea
movq 0x9b8(%r14), %rax
imulq $0x758, %r12, %rcx      # imm = 0x758
testb %bpl, %bpl
je 0xf427
movb $0x2, 0x4c(%rax,%rcx)
movq 0x98(%rbx), %rdx
movq 0x350(%rdx,%r15), %rdx
shlq $0xc, %rdx
movq 0x8(%rax,%rcx), %rsi
andl $0xfff, %esi            # imm = 0xFFF
orq %rdx, %rsi
movq %rsi, 0x588(%rax,%rcx)
jmp 0xf42f
movl $0x2, 0x64(%rax,%rcx)
movl (%r14), %eax
leaq 0x71a87(%rip), %rcx     # 0x80ec0
movq (%rcx,%rax,8), %rsi
movq 0x9b8(%r14), %rdx
imulq $0x758, %r12, %rdi      # imm = 0x758
movq %rsi, 0x40(%rdx,%rdi)
movq 0x98(%rbx), %rsi
cmpb $0x0, 0x329(%rsi,%r15)
je 0xf4d7
leaq (%rsi,%r15), %rdi
addq $0x350, %rdi            # imm = 0x350
addq $0x8, %rdx
movl $0x1, %r8d
xorl %r9d, %r9d
cmpb $0x0, -0x327(%rdi,%r9)
je 0xf4c4
testb %bpl, %bpl
je 0xf4ab
movb $0x2, 0x44(%rdx)
movq (%rdi), %r10
shlq $0xc, %r10
movq (%rdx), %r11
andl $0xfff, %r11d           # imm = 0xFFF
orq %r10, %r11
movq %r11, 0x580(%rdx)
jmp 0xf4b2
movl $0x2, 0x5c(%rdx)
movl %r8d, %r10d
shrl $0x2, %r10d
addq (%rcx,%rax,8), %r10
movq %r10, 0x38(%rdx)
incl %r8d
incq %r9
addq $0x758, %rdx            # imm = 0x758
cmpq $0x100, %r9             # imm = 0x100
jne 0xf47a
addq %r15, %rsi
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0xc3e6
leaq 0x4b76(%rip), %rdi      # 0x14067
leaq 0x57be(%rip), %rsi      # 0x14cb6
leaq 0x5a54(%rip), %rcx      # 0x14f53
movl $0x5e2, %edx            # imm = 0x5E2
callq 0x3160
nop