// File: MPSLab-ASU[P]DiRAC/./src/pe.cc
// Function: PE::determine_next_state()
void PE::determine_next_state()
{
  // Execution events to occur when PE is in execution mode.
  if(PE_State == execute)
  {
    counter_PE_exec += 1;

    // If execution of an RF pass finishes, change current state as next state.
    if (counter_PE_exec == total_cycles_RF_pass)
    {
      PE_State = PE_Next_State;
      if(PE_Next_State == execute)
      {
        update_trigger_states();
        update_reg_idx_Ops();
      }
      else
      {
        state_fetch = false;
      }

      counter_PE_exec = 0;
    }
    // If compute cycles are less than total cycles for an RF pass, stall!
    else if((counter_PE_exec == total_compute_cycles_RF_pass) && (counter_PE_exec < total_cycles_RF_pass))
    {
      state_fetch = false;
    }
  }
  // When PE is idle, check whether it needs to execute.
  else if((PE_Next_State == execute) && (counter_PE_exec == 0))
  {
    update_trigger_states();
    update_reg_idx_Ops();
  }
  // PE waiting for an execution pass to perform write-back.
  else if((PE_WB_next_pass == true) && (counter_PE_exec == 0))
  {
    update_trigger_states();
    update_reg_idx_Ops();
  }
  // PE does not execute on new data, just writeback to interconnect.
  // else if((sig_write_back_current_RF_Pass == true) && (counter_PE_exec == 0))
  // {
  //   // do nothing
  // }

  // Since Write-Back is triggered separately than PE-execution or
  // prefetching data via network, we need to monitor states for write-back
  // continuously and update the states upon the trigger.
  update_trigger_states_write_data();

  // Bits/Word for trigger:
  // i) PE execution (Bit0),
  // ii) Write back (Bit1),
  // iii) Zero-Initialize current RF pass (Bit2)
  // iii) reduction (Bit3).
  PE_Next_State   = (*trigger_from_controller_PE_exec == 1) ? execute : PE_Next_State;
  PE_WB_next_pass = (*trigger_from_controller_write_back == 1) ? true : PE_WB_next_pass;
  PE_zero_initialize_next_pass  = (*trigger_from_controller_zero_initialize == 1) ? true : PE_zero_initialize_next_pass;
  PE_spatial_reduce_next_pass   = (*trigger_from_controller_spatial_reduce == 1) ? true : PE_spatial_reduce_next_pass;
  sig_update_buffer_num_Op1_next_pass = (*trigger_from_controller_update_buf_num_Op1 == 1) ? true : sig_update_buffer_num_Op1_next_pass;
  sig_update_buffer_num_Op2_next_pass = (*trigger_from_controller_update_buf_num_Op2 == 1) ? true : sig_update_buffer_num_Op2_next_pass;
  sig_update_buffer_num_Op3_next_pass = (*trigger_from_controller_update_buf_num_Op3 == 1) ? true : sig_update_buffer_num_Op3_next_pass;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x10(%rbp)
cmpl $0x1, 0x8(%rax)
jne 0x4236d7
movq -0x10(%rbp), %rax
movzwl 0x9c(%rax), %ecx
addl $0x1, %ecx
movw %cx, 0x9c(%rax)
movzwl 0x9c(%rax), %eax
movq $0x61e5e0, %rcx         # imm = 0x61E5E0
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x423696
movq -0x10(%rbp), %rax
movl 0xc(%rax), %ecx
movl %ecx, 0x8(%rax)
cmpl $0x1, 0xc(%rax)
jne 0x42367c
movq -0x10(%rbp), %rdi
callq 0x423950
movq -0x10(%rbp), %rdi
callq 0x423aa0
jmp 0x423687
movq -0x10(%rbp), %rax
movb $0x0, 0x80(%rax)
movq -0x10(%rbp), %rax
movw $0x0, 0x9c(%rax)
jmp 0x4236d5
movq -0x10(%rbp), %rax
movzwl 0x9c(%rax), %eax
movq $0x61e5e2, %rcx         # imm = 0x61E5E2
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x4236d3
movq -0x10(%rbp), %rax
movzwl 0x9c(%rax), %eax
movq $0x61e5e0, %rcx         # imm = 0x61E5E0
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x4236d3
movq -0x10(%rbp), %rax
movb $0x0, 0x80(%rax)
jmp 0x4236d5
jmp 0x42373f
movq -0x10(%rbp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x423705
movq -0x10(%rbp), %rax
movzwl 0x9c(%rax), %eax
cmpl $0x0, %eax
jne 0x423705
movq -0x10(%rbp), %rdi
callq 0x423950
movq -0x10(%rbp), %rdi
callq 0x423aa0
jmp 0x42373d
movq -0x10(%rbp), %rax
movb 0xd8(%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x42373b
movq -0x10(%rbp), %rax
movzwl 0x9c(%rax), %eax
cmpl $0x0, %eax
jne 0x42373b
movq -0x10(%rbp), %rdi
callq 0x423950
movq -0x10(%rbp), %rdi
callq 0x423aa0
jmp 0x42373d
jmp 0x42373f
movq -0x10(%rbp), %rdi
callq 0x423b40
movq -0x10(%rbp), %rax
movq 0xa0(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x423769
movl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x423773
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl %ecx, 0xc(%rax)
movq 0xb0(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x423797
movb $0x1, %al
movb %al, -0x15(%rbp)
jmp 0x4237a4
movq -0x10(%rbp), %rax
movb 0xd8(%rax), %al
movb %al, -0x15(%rbp)
movq -0x10(%rbp), %rax
movb -0x15(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xd8(%rax)
movq 0xa8(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x4237ce
movb $0x1, %al
movb %al, -0x16(%rbp)
jmp 0x4237db
movq -0x10(%rbp), %rax
movb 0xd9(%rax), %al
movb %al, -0x16(%rbp)
movq -0x10(%rbp), %rax
movb -0x16(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xd9(%rax)
movq 0xb8(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x423805
movb $0x1, %al
movb %al, -0x17(%rbp)
jmp 0x423812
movq -0x10(%rbp), %rax
movb 0xda(%rax), %al
movb %al, -0x17(%rbp)
movq -0x10(%rbp), %rax
movb -0x17(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xda(%rax)
movq 0xc0(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x42383c
movb $0x1, %al
movb %al, -0x18(%rbp)
jmp 0x423849
movq -0x10(%rbp), %rax
movb 0xdb(%rax), %al
movb %al, -0x18(%rbp)
movq -0x10(%rbp), %rax
movb -0x18(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xdb(%rax)
movq 0xc8(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x423873
movb $0x1, %al
movb %al, -0x19(%rbp)
jmp 0x423880
movq -0x10(%rbp), %rax
movb 0xdc(%rax), %al
movb %al, -0x19(%rbp)
movq -0x10(%rbp), %rax
movb -0x19(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xdc(%rax)
movq 0xd0(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x4238aa
movb $0x1, %al
movb %al, -0x1a(%rbp)
jmp 0x4238b7
movq -0x10(%rbp), %rax
movb 0xdd(%rax), %al
movb %al, -0x1a(%rbp)
movq -0x10(%rbp), %rax
movb -0x1a(%rbp), %cl
andb $0x1, %cl
movb %cl, 0xdd(%rax)
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)