// File: /workspace/github_cpp_makefile_star2_O3/NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::handle_merged_translation(PACKET*)
void O3_CPU::handle_merged_translation(PACKET *provider)
{
    if (provider->store_merged) {
        for (uint32_t merged=0; merged<SQ.SIZE; merged++) {
            if (provider->sq_index_depend_on_me[merged]) {
                SQ.entry[merged].translated = COMPLETED;
                SQ.entry[merged].physical_address = (provider->data_pa << PAGE_SHIFT) | (SQ.entry[merged].virtual_address & ((1 << PAGE_SHIFT) - 1)); // translated address
                SQ.entry[merged].event_cycle = current_core_cycle[cpu];

                RTS1[RTS1_tail] = merged;
                RTS1_tail++;
                if (RTS1_tail == SQ_SIZE)
                    RTS1_tail = 0;

                DP (if (warmup_complete[cpu]) {
                cout << "[ROB] " << __func__ << " store instr_id: " << SQ.entry[merged].instr_id;
                cout << " DTLB_FETCH_DONE translation: " << +SQ.entry[merged].translated << hex << " page: " << (SQ.entry[merged].physical_address>>LOG2_PAGE_SIZE);
                cout << " full_addr: " << SQ.entry[merged].physical_address << dec << " by instr_id: " << +provider->instr_id << endl; });
            }
        }
    }
    if (provider->load_merged) {
        for (uint32_t merged=0; merged<LQ.SIZE; merged++) {
            if (provider->lq_index_depend_on_me[merged]) {
                LQ.entry[merged].translated = COMPLETED;
                LQ.entry[merged].physical_address = (provider->data_pa << PAGE_SHIFT) | (LQ.entry[merged].virtual_address & ((1 << PAGE_SHIFT) - 1)); // translated address
                LQ.entry[merged].event_cycle = current_core_cycle[cpu];

                RTL1[RTL1_tail] = merged;
                RTL1_tail++;
                if (RTL1_tail == LQ_SIZE)
                    RTL1_tail = 0;

                DP (if (warmup_complete[cpu]) {
                cout << "[RTL1] " << __func__ << " instr_id: " << LQ.entry[merged].instr_id << " rob_index: " << LQ.entry[merged].rob_index << " is added to RTL1";
                cout << " head: " << RTL1_head << " tail: " << RTL1_tail << endl; }); 

                DP (if (warmup_complete[cpu]) {
                cout << "[ROB] " << __func__ << " load instr_id: " << LQ.entry[merged].instr_id;
                cout << " DTLB_FETCH_DONE translation: " << +LQ.entry[merged].translated << hex << " page: " << (LQ.entry[merged].physical_address>>LOG2_PAGE_SIZE);
                cout << " full_addr: " << LQ.entry[merged].physical_address << dec << " by instr_id: " << +provider->instr_id << endl; });
            }
        }
    }
}

// Assembly:
pushq %rbx
cmpb $0x0, 0x32b(%rsi)
je 0xf68e
movl 0xa18(%rdi), %eax
testq %rax, %rax
je 0xf68e
movq 0xa28(%rdi), %rcx
movl (%rdi), %edx
addq $0x10, %rcx
xorl %r8d, %r8d
leaq 0x7189e(%rip), %r9      # 0x80ec0
xorl %r10d, %r10d
cmpb $0x0, 0x229(%rsi,%r10)
je 0xf67f
movb $0x2, 0x2c(%rcx)
movq 0x358(%rsi), %r11
shlq $0xc, %r11
movq (%rcx), %rbx
andl $0xfff, %ebx            # imm = 0xFFF
orq %r11, %rbx
movq %rbx, 0x8(%rcx)
movq (%r9,%rdx,8), %r11
movq %r11, 0x18(%rcx)
movl 0x366c(%rdi), %r11d
movl %r10d, 0x3588(%rdi,%r11,4)
movl 0x366c(%rdi), %r11d
incl %r11d
cmpl $0x38, %r11d
cmovel %r8d, %r11d
movl %r11d, 0x366c(%rdi)
incq %r10
addq $0x140, %rcx            # imm = 0x140
cmpq %r10, %rax
jne 0xf625
cmpb $0x0, 0x32a(%rsi)
je 0xf72d
movl 0x9e0(%rdi), %eax
testq %rax, %rax
je 0xf72d
movq 0x9f0(%rdi), %rcx
movl (%rdi), %edx
addq $0x10, %rcx
xorl %r8d, %r8d
leaq 0x717ff(%rip), %r9      # 0x80ec0
xorl %r10d, %r10d
cmpb $0x0, 0x129(%rsi,%r10)
je 0xf71e
movb $0x2, 0x2c(%rcx)
movq 0x358(%rsi), %r11
shlq $0xc, %r11
movq (%rcx), %rbx
andl $0xfff, %ebx            # imm = 0xFFF
orq %r11, %rbx
movq %rbx, 0x8(%rcx)
movq (%r9,%rdx,8), %r11
movq %r11, 0x18(%rcx)
movl 0x349c(%rdi), %r11d
movl %r10d, 0x3378(%rdi,%r11,4)
movl 0x349c(%rdi), %r11d
incl %r11d
cmpl $0x48, %r11d
cmovel %r8d, %r11d
movl %r11d, 0x349c(%rdi)
incq %r10
addq $0x140, %rcx            # imm = 0x140
cmpq %r10, %rax
jne 0xf6c4
popq %rbx
retq
nop