// File: NishadSaraf[P]Championship-Simulator/src/ooo_cpu.cc
// Function: O3_CPU::execute_instruction()
void O3_CPU::execute_instruction()
{
    if ((ROB.head == ROB.tail) && ROB.occupancy == 0)
        return;

    // out-of-order execution for non-memory instructions
    // memory instructions are handled by memory_instruction()
    uint32_t exec_issued = 0, num_iteration = 0;

    while (exec_issued < EXEC_WIDTH) {
        if (RTE0[RTE0_head] < ROB_SIZE) {
            uint32_t exec_index = RTE0[RTE0_head];
            if (ROB.entry[exec_index].event_cycle <= current_core_cycle[cpu]) {
                do_execution(exec_index);

                RTE0[RTE0_head] = ROB_SIZE;
                RTE0_head++;
                if (RTE0_head == ROB_SIZE)
                    RTE0_head = 0;
                exec_issued++;
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTE0] is empty head: " << RTE0_head << " tail: " << RTE0_tail << endl; });
            break;
        }

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

    num_iteration = 0;
    while (exec_issued < EXEC_WIDTH) {
        if (RTE1[RTE1_head] < ROB_SIZE) {
            uint32_t exec_index = RTE1[RTE1_head];
            if (ROB.entry[exec_index].event_cycle <= current_core_cycle[cpu]) {
                do_execution(exec_index);

                RTE1[RTE1_head] = ROB_SIZE;
                RTE1_head++;
                if (RTE1_head == ROB_SIZE)
                    RTE1_head = 0;
                exec_issued++;
            }
        }
        else {
            //DP (if (warmup_complete[cpu]) {
            //cout << "[RTE1] is empty head: " << RTE1_head << " tail: " << RTE1_tail << endl; });
            break;
        }

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

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq 0x20(%rsp), %rcx
movq %rcx, 0x8(%rsp)
movl 0x958(%rcx), %eax
cmpl 0x95c(%rcx), %eax
jne 0x171a4
movq 0x8(%rsp), %rax
cmpl $0x0, 0x960(%rax)
jne 0x171a4
jmp 0x1737c
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x18(%rsp)
cmpl $0x6, 0x1c(%rsp)
jae 0x17294
movq 0x8(%rsp), %rax
movl 0x2e40(%rax), %ecx
cmpl $0x100, 0x2a40(%rax,%rcx,4) # imm = 0x100
jae 0x17276
movq 0x8(%rsp), %rcx
movl 0x2e40(%rcx), %eax
movl 0x2a40(%rcx,%rax,4), %eax
movl %eax, 0x14(%rsp)
movq 0x9b8(%rcx), %rax
movl 0x14(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rax
movq 0x40(%rax), %rax
movl (%rcx), %ecx
movl %ecx, %edx
leaq 0x78cab(%rip), %rcx     # 0x8fec0
cmpq (%rcx,%rdx,8), %rax
ja 0x17274
movq 0x8(%rsp), %rdi
movl 0x14(%rsp), %esi
callq 0x17390
movq 0x8(%rsp), %rax
movl 0x2e40(%rax), %ecx
movl $0x100, 0x2a40(%rax,%rcx,4) # imm = 0x100
movl 0x2e40(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x2e40(%rax)
cmpl $0x100, 0x2e40(%rax)    # imm = 0x100
jne 0x17269
movq 0x8(%rsp), %rax
movl $0x0, 0x2e40(%rax)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x17278
jmp 0x17294
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
cmpl $0xff, 0x18(%rsp)
jne 0x1728f
jmp 0x17294
jmp 0x171b4
movl $0x0, 0x18(%rsp)
cmpl $0x6, 0x1c(%rsp)
jae 0x1737c
movq 0x8(%rsp), %rax
movl 0x3248(%rax), %ecx
cmpl $0x100, 0x2e48(%rax,%rcx,4) # imm = 0x100
jae 0x1735e
movq 0x8(%rsp), %rcx
movl 0x3248(%rcx), %eax
movl 0x2e48(%rcx,%rax,4), %eax
movl %eax, 0x10(%rsp)
movq 0x9b8(%rcx), %rax
movl 0x10(%rsp), %edx
imulq $0x758, %rdx, %rdx      # imm = 0x758
addq %rdx, %rax
movq 0x40(%rax), %rax
movl (%rcx), %ecx
movl %ecx, %edx
leaq 0x78bc3(%rip), %rcx     # 0x8fec0
cmpq (%rcx,%rdx,8), %rax
ja 0x1735c
movq 0x8(%rsp), %rdi
movl 0x10(%rsp), %esi
callq 0x17390
movq 0x8(%rsp), %rax
movl 0x3248(%rax), %ecx
movl $0x100, 0x2e48(%rax,%rcx,4) # imm = 0x100
movl 0x3248(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x3248(%rax)
cmpl $0x100, 0x3248(%rax)    # imm = 0x100
jne 0x17351
movq 0x8(%rsp), %rax
movl $0x0, 0x3248(%rax)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x17360
jmp 0x1737c
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
cmpl $0xff, 0x18(%rsp)
jne 0x17377
jmp 0x1737c
jmp 0x1729c
addq $0x28, %rsp
retq
nopw %cs:(%rax,%rax)