// File: 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:
movq %rdi, -0x8(%rsp)
movq %rsi, -0x10(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x20(%rsp)
movq -0x10(%rsp), %rax
cmpb $0x0, 0x32b(%rax)
je 0x1ab8a
movl $0x0, -0x14(%rsp)
movq -0x20(%rsp), %rcx
movl -0x14(%rsp), %eax
cmpl 0xa18(%rcx), %eax
jae 0x1ab88
movq -0x10(%rsp), %rax
movl -0x14(%rsp), %ecx
cmpb $0x0, 0x229(%rax,%rcx)
je 0x1ab76
movq -0x20(%rsp), %rax
movq 0xa28(%rax), %rcx
movl -0x14(%rsp), %edx
imulq $0x140, %rdx, %rdx      # imm = 0x140
addq %rdx, %rcx
movb $0x2, 0x3c(%rcx)
movq -0x10(%rsp), %rcx
movq 0x358(%rcx), %rdx
shlq $0xc, %rdx
movq 0xa28(%rax), %rcx
movl -0x14(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq 0x10(%rcx), %rcx
andq $0xfff, %rcx            # imm = 0xFFF
orq %rcx, %rdx
movq 0xa28(%rax), %rcx
movl -0x14(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq %rdx, 0x18(%rcx)
movl (%rax), %ecx
movl %ecx, %edx
leaq 0x753a1(%rip), %rcx     # 0x8fec0
movq (%rcx,%rdx,8), %rdx
movq 0xa28(%rax), %rcx
movl -0x14(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq %rdx, 0x28(%rcx)
movl -0x14(%rsp), %edx
movl 0x366c(%rax), %ecx
movl %edx, 0x3588(%rax,%rcx,4)
movl 0x366c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x366c(%rax)
cmpl $0x38, 0x366c(%rax)
jne 0x1ab74
movq -0x20(%rsp), %rax
movl $0x0, 0x366c(%rax)
jmp 0x1ab76
jmp 0x1ab78
movl -0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rsp)
jmp 0x1aa7e
jmp 0x1ab8a
movq -0x10(%rsp), %rax
cmpb $0x0, 0x32a(%rax)
je 0x1acb0
movl $0x0, -0x18(%rsp)
movq -0x20(%rsp), %rcx
movl -0x18(%rsp), %eax
cmpl 0x9e0(%rcx), %eax
jae 0x1acae
movq -0x10(%rsp), %rax
movl -0x18(%rsp), %ecx
cmpb $0x0, 0x129(%rax,%rcx)
je 0x1ac9c
movq -0x20(%rsp), %rax
movq 0x9f0(%rax), %rcx
movl -0x18(%rsp), %edx
imulq $0x140, %rdx, %rdx      # imm = 0x140
addq %rdx, %rcx
movb $0x2, 0x3c(%rcx)
movq -0x10(%rsp), %rcx
movq 0x358(%rcx), %rdx
shlq $0xc, %rdx
movq 0x9f0(%rax), %rcx
movl -0x18(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq 0x10(%rcx), %rcx
andq $0xfff, %rcx            # imm = 0xFFF
orq %rcx, %rdx
movq 0x9f0(%rax), %rcx
movl -0x18(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq %rdx, 0x18(%rcx)
movl (%rax), %ecx
movl %ecx, %edx
leaq 0x7527b(%rip), %rcx     # 0x8fec0
movq (%rcx,%rdx,8), %rdx
movq 0x9f0(%rax), %rcx
movl -0x18(%rsp), %esi
imulq $0x140, %rsi, %rsi      # imm = 0x140
addq %rsi, %rcx
movq %rdx, 0x28(%rcx)
movl -0x18(%rsp), %edx
movl 0x349c(%rax), %ecx
movl %edx, 0x3378(%rax,%rcx,4)
movl 0x349c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x349c(%rax)
cmpl $0x48, 0x349c(%rax)
jne 0x1ac9a
movq -0x20(%rsp), %rax
movl $0x0, 0x349c(%rax)
jmp 0x1ac9c
jmp 0x1ac9e
movl -0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rsp)
jmp 0x1aba4
jmp 0x1acb0
retq
nopw %cs:(%rax,%rax)