// File: /workspace/github_cpp_makefile_star2_O3/NishadSaraf[P]Championship-Simulator/src/drc_controller.cc
// Function: DRC_MEMORY_CONTROLLER::add_rq(PACKET*)
int DRC_MEMORY_CONTROLLER::add_rq(PACKET *packet)
{
    // check for the latest wirtebacks in the write queue
    //int wq_index = WQ.check_queue(packet);
    int wq_index = check_drc_queue(&WQ, packet);
    if (wq_index != -1) {
        
        // check fill level
        if (packet->fill_level < fill_level) {

            packet->data = WQ.entry[wq_index].data;
            if (packet->instruction) 
                upper_level_icache[packet->cpu]->return_data(packet);
            else // data
                upper_level_dcache[packet->cpu]->return_data(packet);
        }

        DP ( if (packet->cpu) {
        cout << "[" << NAME << "_RQ] " << __func__ << " instr_id: " << packet->instr_id << " found recent writebacks";
        cout << hex << " read: " << packet->address << " writeback: " << WQ.entry[wq_index].address << dec << endl; });

        ACCESS[1]++;
        HIT[1]++;

        WQ.FORWARD++;
        RQ.ACCESS++;
        //assert(0);

        return -1;
    }

    // check for duplicates in the read queue
    int index = check_drc_queue(&RQ, packet);
    if (index != -1)
        return index; // merged index

    // search for the empty index
    for (index=0; index<DRC_RQ_SIZE; index++) {
        if (RQ.entry[index].address == 0) {
            
            memcpy(&RQ.entry[index], packet, sizeof(PACKET));
            RQ.occupancy++;

#ifdef DEBUG_PRINT
            uint32_t channel = drc_get_channel(packet->address),
                     rank = drc_get_rank(packet->address),
                     bank = drc_get_bank(packet->address),
                     row = drc_get_row(packet->address),
                     column = drc_get_column(packet->address); 
#endif

            DP ( if(warmup_complete[packet->cpu]) {
            cout << "[" << NAME << "_RQ] " <<  __func__ << " instr_id: " << packet->instr_id << " address: " << hex << packet->address;
            cout << " full_addr: " << packet->full_addr << dec << " ch: " << channel;
            cout << " rank: " << rank << " bank: " << bank << " row: " << row << " col: " << column;
            cout << " occupancy: " << RQ.occupancy << " current: " << current_core_cycle[packet->cpu] << " event: " << packet->event_cycle << endl; });

            break;
        }
    }

    update_schedule_cycle(&RQ);

    return -1;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x40a890(%rdi), %ecx
testq %rcx, %rcx
je 0x12f31
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq 0x40a908(%rbx), %rax
movq 0x340(%rsi), %r8
imulq $0x380, %rcx, %r9       # imm = 0x380
xorl %edi, %edi
xorl %ecx, %ecx
cmpq %r8, 0x340(%rax,%rdi)
je 0x12f1e
addq %rdx, %rcx
incq %rcx
addq $0x380, %rdi            # imm = 0x380
cmpq %rdi, %r9
jne 0x12f00
jmp 0x12f31
movabsq $0x37ffffffc80, %rdx    # imm = 0x37FFFFFFC80
cmpq %rdx, %rdi
jne 0x12fc4
movl 0x40c530(%rbx), %ecx
testq %rcx, %rcx
je 0x12f71
movq 0x340(%rsi), %rdx
movl $0x340, %edi            # imm = 0x340
addq 0x40c5a8(%rbx), %rdi
xorl %eax, %eax
cmpq %rdx, (%rdi)
je 0x12f67
incq %rax
addq $0x380, %rdi            # imm = 0x380
cmpq %rax, %rcx
jne 0x12f51
jmp 0x12f71
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jne 0x12fbc
leaq 0x40c510(%rbx), %r14
movq 0x40c5a8(%rbx), %rdi
xorl %eax, %eax
cmpq $0x0, 0x340(%rdi,%rax)
je 0x12f9c
addq $0x380, %rax            # imm = 0x380
cmpq $0xa800, %rax           # imm = 0xA800
jne 0x12f81
jmp 0x12faf
addq %rax, %rdi
movl $0x380, %edx            # imm = 0x380
callq 0x31c0
incl 0x40c544(%rbx)
movq %r14, %rsi
callq 0x11996
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movl 0x8(%rsi), %edx
cmpl 0x40946c(%rbx), %edx
jge 0x13006
sarq $0x20, %rcx
imulq $0x380, %rcx, %rcx      # imm = 0x380
movq 0x360(%rax,%rcx), %rax
movq %rax, 0x360(%rsi)
xorl %eax, %eax
cmpb $0x0, (%rsi)
sete %al
movl 0x330(%rsi), %ecx
leaq (%rbx,%rax,8), %rax
movq 0x8(%rax,%rcx,8), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
incq 0x72b0(%rbx)
incq 0x72d0(%rbx)
incq 0x40a8d8(%rbx)
incq 0x40c570(%rbx)
jmp 0x12fb7