// File: /workspace/github_cpp_makefile_star2_O1/NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::check_and_add_lsq(unsigned int)
uint32_t O3_CPU::check_and_add_lsq(uint32_t rob_index) 
{
    uint32_t num_mem_ops = 0, num_added = 0;

    // load
    for (uint32_t i=0; i<NUM_INSTR_SOURCES; i++) {
        if (ROB.entry[rob_index].source_memory[i]) {
            num_mem_ops++;
            if (ROB.entry[rob_index].source_added[i])
                num_added++;
            else if (LQ.occupancy < LQ.SIZE) {
                add_load_queue(rob_index, i);
                num_added++;
            }
            else {
                DP(if(warmup_complete[cpu]) {
                cout << "[LQ] " << __func__ << " instr_id: " << ROB.entry[rob_index].instr_id;
                cout << " cannot be added in the load queue occupancy: " << LQ.occupancy << " cycle: " << current_core_cycle[cpu] << endl; });
            }
        }
    }

    // store
    for (uint32_t i=0; i<MAX_INSTR_DESTINATIONS; i++) {
        if (ROB.entry[rob_index].destination_memory[i]) {
            num_mem_ops++;
            if (ROB.entry[rob_index].destination_added[i])
                num_added++;
            else if (SQ.occupancy < SQ.SIZE) {
                if (STA[STA_head] == ROB.entry[rob_index].instr_id) {
                    add_store_queue(rob_index, i);
                    num_added++;
                }
                //add_store_queue(rob_index, i);
                //num_added++;
            }
            else {
                DP(if(warmup_complete[cpu]) {
                cout << "[SQ] " << __func__ << " instr_id: " << ROB.entry[rob_index].instr_id;
                cout << " cannot be added in the store queue occupancy: " << SQ.occupancy << " cycle: " << current_core_cycle[cpu] << endl; });
            }
        }
    }

    if (num_added == num_mem_ops)
        return 0;

    uint32_t not_available = num_mem_ops - num_added;
    if (not_available > num_mem_ops) {
        cerr << "instr_id: " << ROB.entry[rob_index].instr_id << endl;
        assert(0);
    }

    return not_available;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl %esi, 0xc(%rsp)
movl %esi, %ebp
imulq $0x758, %rbp, %r15      # imm = 0x758
xorl %r14d, %r14d
xorl %r13d, %r13d
xorl %r12d, %r12d
movq 0x9b8(%rbx), %rax
addq %r15, %rax
cmpq $0x0, 0x5c8(%rax,%r14,8)
je 0xe391
incl %r12d
cmpb $0x0, 0x4e(%r14,%rax)
jne 0xe38e
movl 0x9e4(%rbx), %eax
cmpl 0x9e0(%rbx), %eax
jae 0xe391
movq %rbx, %rdi
movl 0xc(%rsp), %esi
movl %r14d, %edx
callq 0xe48c
incl %r13d
incq %r14
cmpq $0x4, %r14
jne 0xe351
leaq 0xbe6f(%rip), %r15      # 0x1a210
cmpb $0x0, (%r15)
movq %rbp, 0x10(%rsp)
je 0xe41a
imulq $0x758, %rbp, %rbp      # imm = 0x758
xorl %r14d, %r14d
movq 0x9b8(%rbx), %rax
addq %rbp, %rax
cmpq $0x0, 0x5a8(%rax,%r14,8)
je 0xe40e
incl %r12d
cmpb $0x0, 0x52(%r14,%rax)
je 0xe3db
incl %r13d
jmp 0xe40e
movl 0xa1c(%rbx), %ecx
cmpl 0xa18(%rbx), %ecx
jae 0xe40e
movq 0x2a30(%rbx), %rcx
movq 0xa30(%rbx,%rcx,8), %rcx
cmpq (%rax), %rcx
jne 0xe40e
movq %rbx, %rdi
movl 0xc(%rsp), %esi
movl %r14d, %edx
callq 0xe952
jmp 0xe3d6
incq %r14
movzbl (%r15), %eax
cmpq %rax, %r14
jb 0xe3b6
xorl %eax, %eax
subl %r13d, %r12d
je 0xe426
jb 0xe435
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xbbb4(%rip), %rdi      # 0x19ff0
leaq 0x6ade(%rip), %rsi      # 0x14f21
callq 0x3250
movq 0x9b8(%rbx), %rcx
imulq $0x758, 0x10(%rsp), %rdx # imm = 0x758
movq (%rcx,%rdx), %rsi
movq %rax, %rdi
callq 0x3090
movq %rax, %rdi
callq 0x3110
leaq 0x5bf4(%rip), %rdi      # 0x14067
leaq 0x683c(%rip), %rsi      # 0x14cb6
leaq 0x6974(%rip), %rcx      # 0x14df5
movl $0x355, %edx            # imm = 0x355
callq 0x3160
nop