// File: /workspace/github_cpp_makefile_star2_O3/NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::add_store_queue(unsigned int, unsigned int)
void O3_CPU::add_store_queue(uint32_t rob_index, uint32_t data_index)
{
    uint32_t sq_index = SQ.tail;
#ifdef SANITY_CHECK
    if (SQ.entry[sq_index].virtual_address)
        assert(0);
#endif

    /*
    // search for an empty slot 
    uint32_t sq_index = SQ.SIZE;
    for (uint32_t i=0; i<SQ.SIZE; i++) {
        if (SQ.entry[i].virtual_address == 0) {
            sq_index = i;
            break;
        }
    }

    // sanity check
    if (sq_index == SQ.SIZE) {
        cerr << "instr_id: " << ROB.entry[rob_index].instr_id << " no empty slot in the store queue!!!" << endl;
        assert(0);
    }
    */

    // add it to the store queue
    ROB.entry[rob_index].sq_index[data_index] = sq_index;
    SQ.entry[sq_index].instr_id = ROB.entry[rob_index].instr_id;
    SQ.entry[sq_index].virtual_address = ROB.entry[rob_index].destination_memory[data_index];
    SQ.entry[sq_index].ip = ROB.entry[rob_index].ip;
    SQ.entry[sq_index].data_index = data_index;
    SQ.entry[sq_index].rob_index = rob_index;
    SQ.entry[sq_index].asid[0] = ROB.entry[rob_index].asid[0];
    SQ.entry[sq_index].asid[1] = ROB.entry[rob_index].asid[1];
    SQ.entry[sq_index].event_cycle = current_core_cycle[cpu] + SCHEDULING_LATENCY;

    SQ.occupancy++;
    SQ.tail++;
    if (SQ.tail == SQ.SIZE)
        SQ.tail = 0;

    // succesfully added to the store queue
    ROB.entry[rob_index].destination_added[data_index] = 1;
    
    STA[STA_head] = UINT64_MAX;
    STA_head++;
    if (STA_head == STA_SIZE)
        STA_head = 0;

    RTS0[RTS0_tail] = sq_index;
    RTS0_tail++;
    if (RTS0_tail == SQ_SIZE)
        RTS0_tail = 0;

    DP(if(warmup_complete[cpu]) {
    cout << "[SQ] " << __func__ << " instr_id: " << SQ.entry[sq_index].instr_id;
    cout << " is added in the SQ translated: " << +SQ.entry[sq_index].translated << " fetched: " << +SQ.entry[sq_index].fetched << " is_producer: " << +ROB.entry[rob_index].is_producer;
    cout << " cycle: " << current_core_cycle[cpu] << endl; });
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movl 0xa24(%rdi), %eax
movq 0xa28(%rdi), %r9
leaq (%rax,%rax,4), %rcx
shlq $0x6, %rcx
cmpq $0x0, 0x10(%r9,%rcx)
jne 0xe8a1
leaq (%r9,%rcx), %r10
addq $0x10, %r10
movq 0x9b8(%rdi), %r11
movl %esi, %r8d
movl %edx, %ecx
imulq $0x758, %r8, %r8        # imm = 0x758
leaq (%r11,%r8), %rbx
movl %eax, 0x738(%rbx,%rcx,4)
movq (%r11,%r8), %r14
movq %rax, %r15
shlq $0x6, %r15
leaq (%r15,%r15,4), %r15
movq %r14, (%r9,%r15)
movq 0x5a8(%rbx,%rcx,8), %rbx
movq %rbx, (%r10)
movq 0x8(%r11,%r8), %r10
movq %r10, 0x20(%r9,%r15)
movl %edx, 0x34(%r9,%r15)
movl %esi, 0x30(%r9,%r15)
movb 0x5b(%r11,%r8), %dl
movb %dl, 0x3e(%r9,%r15)
movq 0x9b8(%rdi), %rdx
movq 0xa28(%rdi), %rsi
movb 0x5c(%rdx,%r8), %dl
movb %dl, 0x3f(%rsi,%r15)
movl (%rdi), %edx
leaq 0x726bd(%rip), %rsi     # 0x80ec0
movl 0x726c6(%rip), %r9d     # 0x80ed0
addq (%rsi,%rdx,8), %r9
movq 0xa28(%rdi), %rdx
movq %r9, 0x28(%rdx,%r15)
incl 0xa1c(%rdi)
movl 0xa24(%rdi), %edx
incl %edx
xorl %esi, %esi
cmpl 0xa18(%rdi), %edx
cmovel %esi, %edx
movl %edx, 0xa24(%rdi)
addq 0x9b8(%rdi), %r8
movb $0x1, 0x52(%rcx,%r8)
movq 0x2a30(%rdi), %rcx
movq $-0x1, 0xa30(%rdi,%rcx,8)
movq 0x2a30(%rdi), %rcx
incq %rcx
cmpq $0x400, %rcx            # imm = 0x400
movl $0x0, %edx
cmovneq %rcx, %rdx
movq %rdx, 0x2a30(%rdi)
movl 0x3584(%rdi), %ecx
movl %eax, 0x34a0(%rdi,%rcx,4)
movl 0x3584(%rdi), %eax
incl %eax
cmpl $0x38, %eax
cmovel %esi, %eax
movl %eax, 0x3584(%rdi)
popq %rbx
popq %r14
popq %r15
retq
leaq 0x57bf(%rip), %rdi      # 0x14067
leaq 0x6437(%rip), %rsi      # 0x14ce6
leaq 0x65f0(%rip), %rcx      # 0x14ea6
movl $0x410, %edx            # imm = 0x410
callq 0x3160