// File: NishadSaraf[P]Championship-Simulator/src/drc_controller.cc
// Function: DRC_MEMORY_CONTROLLER::drc_check_hit(PACKET_QUEUE*, unsigned long, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int)
uint32_t DRC_MEMORY_CONTROLLER::drc_check_hit(PACKET_QUEUE *queue, uint64_t address, uint32_t cpu, uint32_t channel, uint32_t rank, uint32_t bank, uint32_t row)
{
    // determine DRC set index for this row
    // TODO: check if this modulo works okay or not
    uint32_t set = address % DRC_SETS_PER_ROW; 

    if (drc_array[channel][rank][bank][row].block == NULL) { // never accessed this row, dynamically allocate DRC blocks
        drc_array[channel][rank][bank][row].block = new BLOCK* [DRC_SETS_PER_ROW];
        for (uint32_t i=0; i<DRC_SETS_PER_ROW; i++) {
            drc_array[channel][rank][bank][row].block[i] = new BLOCK[DRC_WAY];
            drc_blocks += DRC_WAY;
        }

        return DRC_WAY; // never accessed this row, this is a miss
    }

    for (uint32_t i=0; i<DRC_WAY; i++) {
        if (drc_array[channel][rank][bank][row].block[set][i].tag == address) {
            DP ( if (warmup_complete[cpu]) {
            cout << "[" << queue->NAME << "] " << __func__ << " found matching address: " << hex << address << dec << " set: " << set << " way: " << i << endl; });

            return i;
        }
    }

    return DRC_WAY; // cannot find any matching tag, this is a miss
}

// Assembly:
subq $0x78, %rsp
movl 0x88(%rsp), %eax
movl 0x80(%rsp), %eax
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq %rdx, 0x58(%rsp)
movl %ecx, 0x54(%rsp)
movl %r8d, 0x50(%rsp)
movl %r9d, 0x4c(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x58(%rsp), %rax
movl $0x1c, %ecx
xorl %edx, %edx
divq %rcx
movq 0x28(%rsp), %rax
movl %edx, %ecx
movl %ecx, 0x48(%rsp)
addq $0x7370, %rax           # imm = 0x7370
movl 0x50(%rsp), %ecx
shlq $0x14, %rcx
addq %rcx, %rax
movl 0x4c(%rsp), %ecx
shlq $0x13, %rcx
addq %rcx, %rax
movl 0x80(%rsp), %ecx
shlq $0xf, %rcx
addq %rcx, %rax
movl 0x88(%rsp), %ecx
cmpq $0x0, (%rax,%rcx,8)
jne 0x21615
movl $0xe0, %edi
callq 0x3030
movq %rax, %rdx
movq 0x28(%rsp), %rax
addq $0x7370, %rax           # imm = 0x7370
movl 0x50(%rsp), %ecx
shlq $0x14, %rcx
addq %rcx, %rax
movl 0x4c(%rsp), %ecx
shlq $0x13, %rcx
addq %rcx, %rax
movl 0x80(%rsp), %ecx
shlq $0xf, %rcx
addq %rcx, %rax
movl 0x88(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movl $0x0, 0x44(%rsp)
cmpl $0x1c, 0x44(%rsp)
jae 0x21608
movl $0x50, %edi
callq 0x3030
movq %rax, 0x10(%rsp)
movq %rax, %rcx
addq $0x50, %rcx
movq %rcx, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x1da10
jmp 0x2156a
movq 0x18(%rsp), %rcx
movq 0x8(%rsp), %rax
addq $0x50, %rax
cmpq %rcx, %rax
movq %rax, 0x20(%rsp)
jne 0x21559
movq 0x10(%rsp), %rdx
movq 0x28(%rsp), %rax
addq $0x7370, %rax           # imm = 0x7370
movl 0x50(%rsp), %ecx
shlq $0x14, %rcx
addq %rcx, %rax
movl 0x4c(%rsp), %ecx
shlq $0x13, %rcx
addq %rcx, %rax
movl 0x80(%rsp), %ecx
shlq $0xf, %rcx
addq %rcx, %rax
movl 0x88(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movl 0x44(%rsp), %ecx
movq %rdx, (%rax,%rcx,8)
movq 0x8a868(%rip), %rax     # 0xabe38
addq $0x1, %rax
movq %rax, 0x8a85d(%rip)     # 0xabe38
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x2152e
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
callq 0x32b0
jmp 0x216a6
movl $0x1, 0x74(%rsp)
jmp 0x2169d
movl $0x0, 0x30(%rsp)
cmpl $0x1, 0x30(%rsp)
jae 0x21695
movq 0x28(%rsp), %rax
addq $0x7370, %rax           # imm = 0x7370
movl 0x50(%rsp), %ecx
shlq $0x14, %rcx
addq %rcx, %rax
movl 0x4c(%rsp), %ecx
shlq $0x13, %rcx
addq %rcx, %rax
movl 0x80(%rsp), %ecx
shlq $0xf, %rcx
addq %rcx, %rax
movl 0x88(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movl 0x48(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movl 0x30(%rsp), %ecx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x28(%rax), %rax
cmpq 0x58(%rsp), %rax
jne 0x21686
movl 0x30(%rsp), %eax
movl %eax, 0x74(%rsp)
jmp 0x2169d
jmp 0x21688
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x2161d
movl $0x1, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0x33c0