// File: /workspace/github_cpp_makefile_star2_O3/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 0xce20
cmpl %eax, %r12d
jne 0xf2c2
movq 0x9b8(%r14), %rax
imulq $0x758, %r12, %rcx      # imm = 0x758
testb %bpl, %bpl
je 0xf207
movb $0x2, 0x4c(%rax,%rcx)
movq 0x98(%rbx), %rsi
movq 0x350(%rsi,%r15), %rdx
shlq $0xc, %rdx
movq 0x8(%rax,%rcx), %rdi
andl $0xfff, %edi            # imm = 0xFFF
orq %rdx, %rdi
movq %rdi, 0x588(%rax,%rcx)
jmp 0xf216
movl $0x2, 0x64(%rax,%rcx)
movq 0x98(%rbx), %rsi
movl (%r14), %ecx
leaq 0x71ca0(%rip), %rdx     # 0x80ec0
movq (%rdx,%rcx,8), %rdi
imulq $0x758, %r12, %r8       # imm = 0x758
movq %rdi, 0x40(%rax,%r8)
cmpb $0x0, 0x329(%rsi,%r15)
je 0xf2af
leaq (%rsi,%r15), %rdi
addq $0x350, %rdi            # imm = 0x350
addq $0x8, %rax
movl $0x1, %r8d
xorl %r9d, %r9d
cmpb $0x0, -0x327(%rdi,%r9)
je 0xf29d
testb %bpl, %bpl
je 0xf284
movb $0x2, 0x44(%rax)
movq (%rdi), %r10
shlq $0xc, %r10
movq (%rax), %r11
andl $0xfff, %r11d           # imm = 0xFFF
orq %r10, %r11
movq %r11, 0x580(%rax)
jmp 0xf28b
movl $0x2, 0x5c(%rax)
movl %r8d, %r10d
shrl $0x2, %r10d
addq (%rdx,%rcx,8), %r10
movq %r10, 0x38(%rax)
incl %r8d
incq %r9
addq $0x758, %rax            # imm = 0x758
cmpq $0x100, %r9             # imm = 0x100
jne 0xf253
addq %r15, %rsi
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0xc41a
leaq 0x4d9e(%rip), %rdi      # 0x14067
leaq 0x5a16(%rip), %rsi      # 0x14ce6
leaq 0x5cac(%rip), %rcx      # 0x14f83
movl $0x5e2, %edx            # imm = 0x5E2
callq 0x3160
nop