// File: /workspace/github_cpp_makefile_star2_O1/NishadSaraf[P]Championship-Simulator/src/dram_controller.cc
// Function: MEMORY_CONTROLLER::operate()
void MEMORY_CONTROLLER::operate()
{
    if (do_write == 0) {
        if (WQ.occupancy >= DRAM_WRITE_HIGH_WM) {
            do_write = 1;
            processed_writes = 0;

            // reset scheduled RQ requests
            reset_remain_requests(&RQ);

            for (uint32_t i=0; i<DRAM_CHANNELS; i++) {
                // add data bus turnaround time
                dbus_cycle_available[i] += DRAM_DBUS_TURN_AROUND_TIME;
            }
        }
    }
    else {
        if (WQ.occupancy == 0)
            do_write = 0;
        else if (RQ.occupancy && (WQ.occupancy < DRAM_WRITE_LOW_WM))
            do_write = 0;
        else if (RQ.occupancy && (MIN_DRAM_WRITES_PER_SWITCH <= processed_writes))
            do_write = 0;

        if (do_write == 0) {
            processed_writes = 0;

            // reset scheduled WQ requests
            reset_remain_requests(&WQ);

            for (uint32_t i=0; i<DRAM_CHANNELS; i++) {
                // add data bus turnaround time
                dbus_cycle_available[i] += DRAM_DBUS_TURN_AROUND_TIME;
            }
        }
    }

    // do FR-FCFS scheduling

    // handle write
    // schedule new entry
    if (do_write && (WQ.next_schedule_index < WQ.SIZE)) {
        if (WQ.next_schedule_cycle <= current_core_cycle[WQ.entry[WQ.next_schedule_index].cpu])
            schedule(&WQ);
    }

    // process DRAM requests
    if (do_write && (WQ.next_process_index < WQ.SIZE)) {
        if (WQ.next_process_cycle <= current_core_cycle[WQ.entry[WQ.next_process_index].cpu])
            process(&WQ);
    }

    // handle read
    // schedule new entry
    if ((do_write == 0) && (RQ.next_schedule_index < RQ.SIZE)) {
        if (RQ.next_schedule_cycle <= current_core_cycle[RQ.entry[RQ.next_schedule_index].cpu])
            schedule(&RQ);
    }

    // process DRAM requests
    if ((do_write == 0) && (RQ.next_process_index < RQ.SIZE)) {
        if (RQ.next_process_cycle <= current_core_cycle[RQ.entry[RQ.next_process_index].cpu])
            process(&RQ);
    }
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
cmpb $0x0, 0x7840(%rdi)
je 0xb8f2
movl 0x828c(%rbx), %ecx
testl %ecx, %ecx
je 0xb8cf
movl 0x9f2c(%rbx), %eax
testl %eax, %eax
setne %dl
cmpl $0xc, %ecx
setb %cl
testb %dl, %cl
jne 0xb8cf
testl %eax, %eax
je 0xb8d6
cmpl $0xc, 0x7844(%rbx)
jb 0xb8d6
movb $0x0, 0x7840(%rbx)
cmpb $0x0, 0x7840(%rbx)
jne 0xb923
leaq 0x8258(%rbx), %rsi
movl $0x0, 0x7844(%rbx)
jmp 0xb913
cmpl $0x24, 0x828c(%rbx)
jb 0xb923
movb $0x1, 0x7840(%rbx)
movl $0x0, 0x7844(%rbx)
leaq 0x9ef8(%rbx), %rsi
movq %rbx, %rdi
callq 0xb550
addq $0x18, 0x7568(%rbx)
cmpb $0x0, 0x7840(%rbx)
je 0xb972
movl 0x8298(%rbx), %eax
cmpl 0x8278(%rbx), %eax
jae 0xb972
movq 0x82a8(%rbx), %rcx
movq 0x82f0(%rbx), %rdx
imulq $0x380, %rax, %rax      # imm = 0x380
movl 0x330(%rdx,%rax), %eax
leaq 0x75563(%rip), %rdx     # 0x80ec0
cmpq (%rdx,%rax,8), %rcx
ja 0xb972
leaq 0x8258(%rbx), %rsi
movq %rbx, %rdi
callq 0xba62
cmpb $0x0, 0x7840(%rbx)
je 0xb9c1
movl 0x829c(%rbx), %eax
cmpl 0x8278(%rbx), %eax
jae 0xb9c1
movq 0x82b0(%rbx), %rcx
movq 0x82f0(%rbx), %rdx
imulq $0x380, %rax, %rax      # imm = 0x380
movl 0x330(%rdx,%rax), %eax
leaq 0x75514(%rip), %rdx     # 0x80ec0
cmpq (%rdx,%rax,8), %rcx
ja 0xb9c1
leaq 0x8258(%rbx), %rsi
movq %rbx, %rdi
callq 0xbcfe
cmpb $0x0, 0x7840(%rbx)
jne 0xba10
movl 0x9f38(%rbx), %eax
cmpl 0x9f18(%rbx), %eax
jae 0xba10
movq 0x9f48(%rbx), %rcx
movq 0x9f90(%rbx), %rdx
imulq $0x380, %rax, %rax      # imm = 0x380
movl 0x330(%rdx,%rax), %eax
leaq 0x754c5(%rip), %rdx     # 0x80ec0
cmpq (%rdx,%rax,8), %rcx
ja 0xba10
leaq 0x9ef8(%rbx), %rsi
movq %rbx, %rdi
callq 0xba62
cmpb $0x0, 0x7840(%rbx)
jne 0xba50
movl 0x9f3c(%rbx), %eax
cmpl 0x9f18(%rbx), %eax
jae 0xba50
movq 0x9f50(%rbx), %rcx
movq 0x9f90(%rbx), %rdx
imulq $0x380, %rax, %rax      # imm = 0x380
movl 0x330(%rdx,%rax), %eax
leaq 0x75476(%rip), %rdx     # 0x80ec0
cmpq (%rdx,%rax,8), %rcx
jbe 0xba52
popq %rbx
retq
leaq 0x9ef8(%rbx), %rsi
movq %rbx, %rdi
popq %rbx
jmp 0xbcfe