// File: /workspace/github_cpp_makefile_star2_O1/NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::operate_lsq()
void O3_CPU::operate_lsq()
{
    // handle store
    uint32_t store_issued = 0, num_iteration = 0;

    while (store_issued < SQ_WIDTH) {
        if (RTS0[RTS0_head] < SQ_SIZE) {
            uint32_t sq_index = RTS0[RTS0_head];
            if (SQ.entry[sq_index].event_cycle <= current_core_cycle[cpu]) {

                // add it to DTLB
                PACKET data_packet;

                data_packet.tlb_access = 1;
                data_packet.fill_level = FILL_L1;
                data_packet.cpu = cpu;
                data_packet.data_index = SQ.entry[sq_index].data_index;
                data_packet.sq_index = sq_index;
                if (knob_cloudsuite)
                    data_packet.address = ((SQ.entry[sq_index].virtual_address >> LOG2_PAGE_SIZE) << 9) | SQ.entry[sq_index].asid[1];
                else
                    data_packet.address = SQ.entry[sq_index].virtual_address >> LOG2_PAGE_SIZE;
                data_packet.full_addr = SQ.entry[sq_index].virtual_address;
                data_packet.instr_id = SQ.entry[sq_index].instr_id;
                data_packet.rob_index = SQ.entry[sq_index].rob_index;
                data_packet.ip = SQ.entry[sq_index].ip;
                data_packet.type = RFO;
                data_packet.asid[0] = SQ.entry[sq_index].asid[0];
                data_packet.asid[1] = SQ.entry[sq_index].asid[1];
                data_packet.event_cycle = SQ.entry[sq_index].event_cycle;

                DP (if (warmup_complete[cpu]) {
                cout << "[RTS0] " << __func__ << " instr_id: " << SQ.entry[sq_index].instr_id << " rob_index: " << SQ.entry[sq_index].rob_index << " is popped from to RTS0";
                cout << " head: " << RTS0_head << " tail: " << RTS0_tail << endl; }); 

                int rq_index = DTLB.add_rq(&data_packet);

                if (rq_index == -2)
                    break; 
                else 
                    SQ.entry[sq_index].translated = INFLIGHT;

                RTS0[RTS0_head] = SQ_SIZE;
                RTS0_head++;
                if (RTS0_head == SQ_SIZE)
                    RTS0_head = 0;

                store_issued++;
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTS0] is empty head: " << RTS0_head << " tail: " << RTS0_tail << endl; });
            break;
        }

        num_iteration++;
        if (num_iteration == (SQ_SIZE-1))
            break;
    }

    num_iteration = 0;
    while (store_issued < SQ_WIDTH) {
        if (RTS1[RTS1_head] < SQ_SIZE) {
            uint32_t sq_index = RTS1[RTS1_head];
            if (SQ.entry[sq_index].event_cycle <= current_core_cycle[cpu]) {
                execute_store(SQ.entry[sq_index].rob_index, sq_index, SQ.entry[sq_index].data_index);

                RTS1[RTS1_head] = SQ_SIZE;
                RTS1_head++;
                if (RTS1_head == SQ_SIZE)
                    RTS1_head = 0;

                store_issued++;
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTS1] is empty head: " << RTS1_head << " tail: " << RTS1_tail << endl; });
            break;
        }

        num_iteration++;
        if (num_iteration == (SQ_SIZE-1))
            break;
    }

    unsigned load_issued = 0;
    num_iteration = 0;
    while (load_issued < LQ_WIDTH) {
        if (RTL0[RTL0_head] < LQ_SIZE) {
            uint32_t lq_index = RTL0[RTL0_head];
            if (LQ.entry[lq_index].event_cycle <= current_core_cycle[cpu]) {

                // add it to DTLB
                PACKET data_packet;
                data_packet.fill_level = FILL_L1;
                data_packet.cpu = cpu;
                data_packet.data_index = LQ.entry[lq_index].data_index;
                data_packet.lq_index = lq_index;
                if (knob_cloudsuite)
                    data_packet.address = ((LQ.entry[lq_index].virtual_address >> LOG2_PAGE_SIZE) << 9) | LQ.entry[lq_index].asid[1];
                else
                    data_packet.address = LQ.entry[lq_index].virtual_address >> LOG2_PAGE_SIZE;
                data_packet.full_addr = LQ.entry[lq_index].virtual_address;
                data_packet.instr_id = LQ.entry[lq_index].instr_id;
                data_packet.rob_index = LQ.entry[lq_index].rob_index;
                data_packet.ip = LQ.entry[lq_index].ip;
                data_packet.type = LOAD;
                data_packet.asid[0] = LQ.entry[lq_index].asid[0];
                data_packet.asid[1] = LQ.entry[lq_index].asid[1];
                data_packet.event_cycle = LQ.entry[lq_index].event_cycle;

                DP (if (warmup_complete[cpu]) {
                cout << "[RTL0] " << __func__ << " instr_id: " << LQ.entry[lq_index].instr_id << " rob_index: " << LQ.entry[lq_index].rob_index << " is popped to RTL0";
                cout << " head: " << RTL0_head << " tail: " << RTL0_tail << endl; }); 

                int rq_index = DTLB.add_rq(&data_packet);

                if (rq_index == -2)
                    break; // break here
                else  
                    LQ.entry[lq_index].translated = INFLIGHT;

                RTL0[RTL0_head] = LQ_SIZE;
                RTL0_head++;
                if (RTL0_head == LQ_SIZE)
                    RTL0_head = 0;

                load_issued++;
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTL0] is empty head: " << RTL0_head << " tail: " << RTL0_tail << endl; });
            break;
        }

        num_iteration++;
        if (num_iteration == (LQ_SIZE-1))
            break;
    }

    num_iteration = 0;
    while (load_issued < LQ_WIDTH) {
        if (RTL1[RTL1_head] < LQ_SIZE) {
            uint32_t lq_index = RTL1[RTL1_head];
            if (LQ.entry[lq_index].event_cycle <= current_core_cycle[cpu]) {
                int rq_index = execute_load(LQ.entry[lq_index].rob_index, lq_index, LQ.entry[lq_index].data_index);

                if (rq_index != -2) {
                    RTL1[RTL1_head] = LQ_SIZE;
                    RTL1_head++;
                    if (RTL1_head == LQ_SIZE)
                        RTL1_head = 0;

                    load_issued++;
                }
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTL1] is empty head: " << RTL1_head << " tail: " << RTL1_tail << endl; });
            break;
        }

        num_iteration++;
        if (num_iteration == (LQ_SIZE-1))
            break;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x398, %rsp            # imm = 0x398
movq %rdi, %rbx
leaq 0x13a38(%rdi), %rax
movq %rax, 0x10(%rsp)
movl $0x36, %edx
leaq 0x73130(%rip), %rdi     # 0x80ec0
movl 0x3580(%rbx), %eax
movl 0x34a0(%rbx,%rax,4), %r14d
cmpq $0x37, %r14
ja 0xdf87
movq 0xa28(%rbx), %r13
leaq (%r14,%r14,4), %r12
shlq $0x6, %r12
movq 0x28(%r13,%r12), %rax
movl (%rbx), %ebp
cmpq (%rdi,%rbp,8), %rax
jbe 0xddcd
xorl %ecx, %ecx
movb $0x1, %al
jmp 0xdf74
movl %edx, 0x8(%rsp)
xorl %eax, %eax
movl %eax, 0x1b(%rsp)
movl %eax, 0x18(%rsp)
movl $0xffff00, 0x344(%rsp) # imm = 0xFFFF00
leaq 0x20(%rsp), %r15
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, (%r15)
movl $0x314, %edx            # imm = 0x314
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x3130
movl $0x1, %eax
movl %eax, 0x348(%rsp)
pxor %xmm0, %xmm0
movdqu %xmm0, 0x32c(%r15)
movdqu %xmm0, 0x33c(%r15)
xorl %ecx, %ecx
movl %ecx, 0x34c(%r15)
movdqu %xmm0, 0x358(%r15)
movq $0x0, 0x368(%r15)
movq $-0x1, 0x390(%rsp)
movb $0x1, 0x19(%rsp)
movl %eax, 0x20(%rsp)
movl %ebp, 0x348(%rsp)
movl 0x34(%r13,%r12), %eax
movl %eax, 0x34c(%rsp)
movl %r14d, 0x354(%rsp)
leaq 0xc4ca(%rip), %rax      # 0x1a345
cmpb $0x0, (%rax)
je 0xdea9
movq 0x10(%r13,%r12), %rax
shrq $0x3, %rax
movabsq $0x1ffffffffffffe00, %rcx # imm = 0x1FFFFFFFFFFFFE00
andq %rcx, %rax
movzbl 0x3f(%r13,%r12), %ecx
orq %rax, %rcx
movq %rcx, 0x358(%rsp)
jmp 0xdeba
movq 0x10(%r13,%r12), %rax
shrq $0xc, %rax
movq %rax, 0x358(%rsp)
leaq (%r12,%r13), %rax
addq $0x28, %rax
movq -0x18(%rax), %rcx
movq %rcx, 0x360(%rsp)
movq -0x28(%rax), %rcx
movq %rcx, 0x380(%rsp)
movl 0x8(%rax), %ecx
movl %ecx, 0x28(%rsp)
movq -0x8(%rax), %rcx
movq %rcx, 0x388(%rsp)
movb $0x1, 0x347(%rsp)
movb 0x16(%rax), %cl
movb %cl, 0x345(%rsp)
movb 0x17(%rax), %cl
movb %cl, 0x346(%rsp)
movq (%rax), %rax
movq %rax, 0x390(%rsp)
movq 0x10(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x5a80
xorl %ecx, %ecx
cmpl $-0x2, %eax
setne %al
je 0xdf69
movq 0xa28(%rbx), %rcx
movb $0x1, 0x3c(%rcx,%r12)
movl 0x3580(%rbx), %ecx
movl $0x38, 0x34a0(%rbx,%rcx,4)
movl 0x3580(%rbx), %ecx
incl %ecx
cmpl $0x38, %ecx
movl $0x0, %edx
cmovel %edx, %ecx
movl %ecx, 0x3580(%rbx)
movl $0x1, %ecx
leaq 0x72f50(%rip), %rdi     # 0x80ec0
movl 0x8(%rsp), %edx
testb %al, %al
je 0xdf89
addl $-0x1, %edx
jae 0xdf89
testl %ecx, %ecx
je 0xdd90
jmp 0xdf89
xorl %ecx, %ecx
testl %ecx, %ecx
je 0xe24b
movl $0x46, %edx
xorl %esi, %esi
movl 0x3370(%rbx), %eax
movl 0x3250(%rbx,%rax,4), %ebp
cmpq $0x47, %rbp
ja 0xe19d
movq 0x9f0(%rbx), %r12
leaq (,%rbp,4), %r13
addq %rbp, %r13
shlq $0x6, %r13
movq 0x28(%r12,%r13), %rcx
movl (%rbx), %r15d
movb $0x1, %al
cmpq (%rdi,%r15,8), %rcx
ja 0xe18b
movl %edx, 0xc(%rsp)
movl %esi, 0x8(%rsp)
xorl %eax, %eax
movl %eax, 0x1b(%rsp)
movl %eax, 0x18(%rsp)
movl $0xffff00, 0x344(%rsp) # imm = 0xFFFF00
leaq 0x20(%rsp), %r14
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, (%r14)
movl $0x314, %edx            # imm = 0x314
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x3130
movl $0x1, %eax
movl %eax, 0x348(%rsp)
pxor %xmm0, %xmm0
movdqu %xmm0, 0x32c(%r14)
movdqu %xmm0, 0x33c(%r14)
xorl %ecx, %ecx
movl %ecx, 0x34c(%r14)
movdqu %xmm0, 0x358(%r14)
movq $0x0, 0x368(%r14)
movq $-0x1, 0x390(%rsp)
movl %eax, 0x20(%rsp)
movl %r15d, 0x348(%rsp)
movl 0x34(%r12,%r13), %eax
movl %eax, 0x34c(%rsp)
movl %ebp, 0x350(%rsp)
leaq 0xc2bf(%rip), %rax      # 0x1a345
cmpb $0x0, (%rax)
je 0xe0b4
movq 0x10(%r12,%r13), %rax
shrq $0x3, %rax
movabsq $0x1ffffffffffffe00, %rcx # imm = 0x1FFFFFFFFFFFFE00
andq %rcx, %rax
movzbl 0x3f(%r12,%r13), %ecx
orq %rax, %rcx
movq %rcx, 0x358(%rsp)
jmp 0xe0c5
movq 0x10(%r12,%r13), %rax
shrq $0xc, %rax
movq %rax, 0x358(%rsp)
leaq (%r12,%r13), %rax
addq $0x28, %rax
movq -0x18(%rax), %rcx
movq %rcx, 0x360(%rsp)
movq -0x28(%rax), %rcx
movq %rcx, 0x380(%rsp)
movl 0x8(%rax), %ecx
movl %ecx, 0x28(%rsp)
movq -0x8(%rax), %rcx
movq %rcx, 0x388(%rsp)
movb $0x0, 0x347(%rsp)
movb 0x16(%rax), %cl
movb %cl, 0x345(%rsp)
movb 0x17(%rax), %cl
movb %cl, 0x346(%rsp)
movq (%rax), %rax
movq %rax, 0x390(%rsp)
movq 0x10(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x5a80
cmpl $-0x2, %eax
setne %al
je 0xe17c
movq 0x9f0(%rbx), %rcx
movb $0x1, 0x3c(%rcx,%r13)
movl 0x3370(%rbx), %ecx
movl $0x48, 0x3250(%rbx,%rcx,4)
movl 0x3370(%rbx), %ecx
incl %ecx
cmpl $0x48, %ecx
movl $0x0, %edx
cmovel %edx, %ecx
movl %ecx, 0x3370(%rbx)
movl 0x8(%rsp), %esi
incl %esi
leaq 0x72d46(%rip), %rdi     # 0x80ec0
jmp 0xe187
leaq 0x72d3d(%rip), %rdi     # 0x80ec0
movl 0x8(%rsp), %esi
movl 0xc(%rsp), %edx
testb %al, %al
je 0xe19d
addl $-0x1, %edx
jae 0xe19d
cmpl $0x2, %esi
jb 0xdf98
cmpl $0x1, %esi
ja 0xe239
movl $0x46, %ebp
xorl %r14d, %r14d
movl 0x3498(%rbx), %eax
movl 0x3378(%rbx,%rax,4), %edx
cmpq $0x47, %rdx
ja 0xe239
movq 0x9f0(%rbx), %rax
leaq (%rdx,%rdx,4), %rcx
shlq $0x6, %rcx
movq 0x28(%rax,%rcx), %rax
movl (%rbx), %ecx
cmpq (%rdi,%rcx,8), %rax
ja 0xe22b
movl %esi, %r15d
movq %rbx, %rdi
callq 0xef1e
cmpl $-0x2, %eax
jne 0xe1f9
leaq 0x72ccc(%rip), %rdi     # 0x80ec0
movl %r15d, %esi
jmp 0xe22b
movl 0x3498(%rbx), %eax
movl $0x48, 0x3378(%rbx,%rax,4)
movl 0x3498(%rbx), %eax
incl %eax
cmpl $0x48, %eax
cmovel %r14d, %eax
movl %eax, 0x3498(%rbx)
movl %r15d, %esi
incl %esi
leaq 0x72c95(%rip), %rdi     # 0x80ec0
addl $-0x1, %ebp
jae 0xe239
cmpl $0x2, %esi
jb 0xe1ae
addq $0x398, %rsp            # imm = 0x398
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x36, %r14d
xorl %r15d, %r15d
movl 0x3668(%rbx), %eax
movl 0x3588(%rbx,%rax,4), %edx
cmpq $0x37, %rdx
ja 0xdf91
movq 0xa28(%rbx), %rax
leaq (%rdx,%rdx,4), %rcx
shlq $0x6, %rcx
movq 0x28(%rax,%rcx), %r12
movl (%rbx), %esi
movq (%rdi,%rsi,8), %r13
cmpq %r13, %r12
ja 0xe2c5
addq %rcx, %rax
movl 0x30(%rax), %esi
movq %rbx, %rdi
callq 0xeba4
leaq 0x72c21(%rip), %rdi     # 0x80ec0
movl 0x3668(%rbx), %eax
movl $0x38, 0x3588(%rbx,%rax,4)
movl 0x3668(%rbx), %eax
incl %eax
cmpl $0x38, %eax
cmovel %r15d, %eax
movl %eax, 0x3668(%rbx)
addl $-0x1, %r14d
jae 0xdf91
cmpq %r13, %r12
ja 0xe254
jmp 0xdf91
nop