// File: /workspace/github_cpp_makefile_star2_O1/MPSLab-ASU[P]DiRAC/./src/controller.cc
// Function: controller::trigger_PEs()
void controller::trigger_PEs()
{
  // Trigger execution of PEs at the beginning of RF pass.
  if(cnt_bus_trigger == 0)
  {
    for(uint16_t rowID=0; rowID < nRows_PE_Array; rowID++) {
      for(uint16_t colID=0; colID < nCols_PE_Array; colID++) {
        bus_trigger_PEs_exec[rowID][colID]            = trigger_exec_pass_PEs_exec[current_SPM_pass][current_RF_pass];
        bus_trigger_PEs_zero_initialize[rowID][colID] = trigger_exec_pass_zero_init[current_SPM_pass][current_RF_pass];
        bus_trigger_PEs_update_buf_num_Op1[rowID][colID] = trigger_exec_pass_update_buf_num_Op1[current_SPM_pass][current_RF_pass];
        bus_trigger_PEs_update_buf_num_Op2[rowID][colID] = trigger_exec_pass_update_buf_num_Op2[current_SPM_pass][current_RF_pass];
        bus_trigger_PEs_update_buf_num_Op3[rowID][colID] = trigger_exec_pass_update_buf_num_Op3[current_SPM_pass][current_RF_pass];
      }
    }
  }
  else
  {
    for(uint16_t rowID=0; rowID < nRows_PE_Array; rowID++) {
      for(uint16_t colID=0; colID < nCols_PE_Array; colID++) {
        bus_trigger_PEs_exec[rowID][colID]            = 0;
        bus_trigger_PEs_zero_initialize[rowID][colID] = 0;
        bus_trigger_PEs_update_buf_num_Op1[rowID][colID] = 0;
        bus_trigger_PEs_update_buf_num_Op2[rowID][colID] = 0;
        bus_trigger_PEs_update_buf_num_Op3[rowID][colID] = 0;
      }
    }
  }


  assert(PE_trigger_latency > 0 && "PE trigger latency cannot be zero!");

  // Trigger write-back and spatial_reduce differently
  // PEs need to be triggered at certain offset-cycles for correct
  // communication via interconnect network.
  if((cnt_bus_trigger % PE_trigger_latency == 0) && (cnt_bus_trigger < PE_trigger_latency*total_PEs))
  {
    uint16_t rowID = (cnt_bus_trigger / (PE_trigger_latency * nCols_PE_Array)) % nRows_PE_Array;
    uint16_t colID = (cnt_bus_trigger / PE_trigger_latency) % nCols_PE_Array;
    assert(rowID < nRows_PE_Array && "Invalid rowID for a PE to be triggered.");
    assert(colID < nCols_PE_Array && "Invalid colID for a PE to be triggered.");
    bus_trigger_PEs_write_back[rowID][colID]      = trigger_exec_pass_writeback[current_SPM_pass][current_RF_pass];
    bus_trigger_PEs_spatial_reduce[rowID][colID]  = trigger_exec_pass_spatial_reduce[current_SPM_pass][current_RF_pass];
  }
  else {
    for(auto i=0; i < nRows_PE_Array; i++) {
      for(auto j=0; j < nCols_PE_Array; j++) {
        bus_trigger_PEs_write_back[i][j]      = 0;
        bus_trigger_PEs_spatial_reduce[i][j]  = 0;
      }
    }
  }
  if(cnt_bus_trigger < PE_trigger_latency*total_PEs)
    cnt_bus_trigger += 1;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdi, 0x8(%rsp)
movl 0xf8(%rdi), %eax
movq $0x60b5ac, %rcx         # imm = 0x60B5AC
movzwl (%rcx), %ebp
movl %eax, 0x14(%rsp)
testl %eax, %eax
je 0x41079a
testq %rbp, %rbp
je 0x4108fb
movq $0x60b5ae, %rax         # imm = 0x60B5AE
movzwl (%rax), %ecx
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdx
movq 0x18(%rax), %rsi
movq 0x30(%rax), %rdi
movq 0x38(%rax), %r8
movq 0x40(%rax), %r9
xorl %r10d, %r10d
xorl %r11d, %r11d
testq %rcx, %rcx
je 0x41078d
movq (%rdx,%r11,8), %rbx
movq (%rsi,%r11,8), %r14
movq (%rdi,%r11,8), %r15
movq (%r8,%r11,8), %rax
movq (%r9,%r11,8), %r12
xorl %r13d, %r13d
movb %r10b, (%rbx,%r13)
movb %r10b, (%r14,%r13)
movb %r10b, (%r15,%r13)
movb %r10b, (%rax,%r13)
movb %r10b, (%r12,%r13)
incq %r13
cmpq %r13, %rcx
jne 0x410771
incq %r11
cmpq %rbp, %r11
jne 0x410755
jmp 0x4108fb
testq %rbp, %rbp
je 0x4108fb
movq $0x60b5ae, %rax         # imm = 0x60B5AE
movzwl (%rax), %edx
movq $0x60b6e0, %rax         # imm = 0x60B6E0
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movq $0x60b73a, %rax         # imm = 0x60B73A
movzwl (%rax), %edi
movq $0x60b738, %rax         # imm = 0x60B738
movzwl (%rax), %r10d
movq 0x8(%rsp), %rcx
movq 0x10(%rcx), %rax
movq %rax, 0x58(%rsp)
movq 0x18(%rcx), %rax
movq %rax, 0x50(%rsp)
movq $0x60b6e8, %rax         # imm = 0x60B6E8
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq $0x60b700, %rax         # imm = 0x60B700
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x30(%rcx), %rax
movq %rax, 0x38(%rsp)
movq $0x60b708, %rax         # imm = 0x60B708
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rcx), %rax
movq %rax, 0x28(%rsp)
movq $0x60b710, %rax         # imm = 0x60B710
movq (%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x40(%rcx), %rax
movq %rax, 0x18(%rsp)
xorl %esi, %esi
shll $0x3, %edi
movq %rdi, 0x60(%rsp)
movq %rbp, 0x70(%rsp)
testq %rdx, %rdx
je 0x4108ea
movq 0x68(%rsp), %rax
movq 0x60(%rsp), %rcx
movq (%rax,%rcx), %rdi
movq 0x58(%rsp), %rax
movq (%rax,%rsi,8), %r11
movq 0x48(%rsp), %rax
movq (%rax,%rcx), %rbx
movq 0x50(%rsp), %rax
movq (%rax,%rsi,8), %r14
movq 0x40(%rsp), %rax
movq (%rax,%rcx), %r15
movq 0x38(%rsp), %rax
movq (%rax,%rsi,8), %r12
movq 0x30(%rsp), %rax
movq (%rax,%rcx), %r13
movq 0x28(%rsp), %rax
movq (%rax,%rsi,8), %rbp
movq 0x20(%rsp), %rax
movq (%rax,%rcx), %r8
movq 0x18(%rsp), %rax
movq (%rax,%rsi,8), %rcx
xorl %eax, %eax
movb (%rdi,%r10), %r9b
movb %r9b, (%r11,%rax)
movb (%rbx,%r10), %r9b
movb %r9b, (%r14,%rax)
movb (%r15,%r10), %r9b
movb %r9b, (%r12,%rax)
movb (%r13,%r10), %r9b
movb %r9b, (%rbp,%rax)
movb (%r8,%r10), %r9b
movb %r9b, (%rcx,%rax)
incq %rax
cmpq %rax, %rdx
jne 0x4108b8
incq %rsi
movq 0x70(%rsp), %rbp
cmpq %rbp, %rsi
jne 0x41084e
movq $0x60b6d8, %rax         # imm = 0x60B6D8
movzwl (%rax), %r9d
testl %r9d, %r9d
je 0x410a3e
movl 0x14(%rsp), %ebp
movl %ebp, %eax
xorl %edx, %edx
divl %r9d
testl %edx, %edx
jne 0x4109c0
movl %eax, %esi
movq $0x60b5a8, %rax         # imm = 0x60B5A8
movl (%rax), %eax
imull %r9d, %eax
cmpl %eax, %ebp
jae 0x4109c0
movq $0x60b5ae, %rax         # imm = 0x60B5AE
movzwl (%rax), %ecx
movl %ecx, %edi
imull %r9d, %edi
movl %ebp, %eax
xorl %edx, %edx
divl %edi
movq $0x60b5ac, %rdx         # imm = 0x60B5AC
movzwl (%rdx), %edi
xorl %edx, %edx
divl %edi
movl %edx, %r8d
movl %esi, %eax
xorl %edx, %edx
divl %ecx
movq $0x60b6f0, %rax         # imm = 0x60B6F0
movq (%rax), %rax
movq $0x60b73a, %rcx         # imm = 0x60B73A
movzwl (%rcx), %ecx
shll $0x3, %ecx
movq (%rax,%rcx), %rax
movq $0x60b738, %rsi         # imm = 0x60B738
movzwl (%rsi), %esi
movb (%rax,%rsi), %al
movq 0x8(%rsp), %r10
movq 0x20(%r10), %rdi
shll $0x3, %r8d
movq (%rdi,%r8), %rdi
movb %al, (%rdi,%rdx)
movq $0x60b6f8, %rax         # imm = 0x60B6F8
movq (%rax), %rax
movq (%rax,%rcx), %rax
movb (%rax,%rsi), %al
movq 0x28(%r10), %rcx
movq (%rcx,%r8), %rcx
movb %al, (%rcx,%rdx)
jmp 0x410a12
movq $0x60b5ac, %rax         # imm = 0x60B5AC
movzwl (%rax), %eax
testq %rax, %rax
je 0x410a12
movq $0x60b5ae, %rcx         # imm = 0x60B5AE
movzwl (%rcx), %ecx
movq 0x8(%rsp), %rsi
movq 0x20(%rsi), %rdx
movq 0x28(%rsi), %rsi
xorl %edi, %edi
xorl %r8d, %r8d
testq %rcx, %rcx
je 0x410a0a
movq (%rdx,%r8,8), %r10
movq (%rsi,%r8,8), %r11
xorl %ebx, %ebx
movb %dil, (%r10,%rbx)
movb %dil, (%r11,%rbx)
incq %rbx
cmpq %rbx, %rcx
jne 0x4109fa
incq %r8
cmpq %rax, %r8
jne 0x4109eb
movq $0x60b5a8, %rax         # imm = 0x60B5A8
imull (%rax), %r9d
cmpl %r9d, %ebp
jae 0x410a2f
incl %ebp
movq 0x8(%rsp), %rax
movl %ebp, 0xf8(%rax)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1853ae(%rip), %rdi    # 0x595df3
leaq 0x18511e(%rip), %rsi    # 0x595b6a
leaq 0x1853df(%rip), %rcx    # 0x595e32
movl $0x2c8, %edx            # imm = 0x2C8
callq 0x4d75c0
nop