// File: 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
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpl $0x0, 0xf8(%rax)
jne 0x417d09
movw $0x0, -0xa(%rbp)
movzwl -0xa(%rbp), %eax
movq $0x61e5ac, %rcx         # imm = 0x61E5AC
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417d04
movw $0x0, -0xc(%rbp)
movzwl -0xc(%rbp), %eax
movq $0x61e5ae, %rcx         # imm = 0x61E5AE
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417cf1
movq -0x28(%rbp), %rax
movq $0x61e6e0, %rcx         # imm = 0x61E6E0
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %sil
movq 0x10(%rax), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0xc(%rbp), %edx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq $0x61e6e8, %rcx         # imm = 0x61E6E8
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %sil
movq 0x18(%rax), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0xc(%rbp), %edx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq $0x61e700, %rcx         # imm = 0x61E700
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %sil
movq 0x30(%rax), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0xc(%rbp), %edx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq $0x61e708, %rcx         # imm = 0x61E708
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %sil
movq 0x38(%rax), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0xc(%rbp), %edx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq $0x61e710, %rcx         # imm = 0x61E710
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %dl
movq 0x40(%rax), %rax
movzwl -0xa(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movzwl -0xc(%rbp), %ecx
andb $0x1, %dl
movb %dl, (%rax,%rcx)
movw -0xc(%rbp), %ax
addw $0x1, %ax
movw %ax, -0xc(%rbp)
jmp 0x417b93
jmp 0x417cf3
movw -0xa(%rbp), %ax
addw $0x1, %ax
movw %ax, -0xa(%rbp)
jmp 0x417b77
jmp 0x417dcb
movw $0x0, -0xe(%rbp)
movzwl -0xe(%rbp), %eax
movq $0x61e5ac, %rcx         # imm = 0x61E5AC
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417dc9
movw $0x0, -0x10(%rbp)
movzwl -0x10(%rbp), %eax
movq $0x61e5ae, %rcx         # imm = 0x61E5AE
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417db6
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rcx
movzwl -0xe(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0x10(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x18(%rax), %rcx
movzwl -0xe(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0x10(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x30(%rax), %rcx
movzwl -0xe(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0x10(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x38(%rax), %rcx
movzwl -0xe(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0x10(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x40(%rax), %rax
movzwl -0xe(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movzwl -0x10(%rbp), %ecx
movb $0x0, (%rax,%rcx)
movw -0x10(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x10(%rbp)
jmp 0x417d2b
jmp 0x417db8
movw -0xe(%rbp), %ax
addw $0x1, %ax
movw %ax, -0xe(%rbp)
jmp 0x417d0f
jmp 0x417dcb
movq $0x61e6d8, %rax         # imm = 0x61E6D8
movzwl (%rax), %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x29(%rbp)
jle 0x417de6
movb $0x1, %al
movb %al, -0x29(%rbp)
jmp 0x417de6
movb -0x29(%rbp), %al
testb $0x1, %al
jne 0x417def
jmp 0x417df1
jmp 0x417e10
leaq 0x18bc80(%rip), %rdi    # 0x5a3a78
leaq 0x18b90e(%rip), %rsi    # 0x5a370d
movl $0x2c8, %edx            # imm = 0x2C8
leaq 0x18bcac(%rip), %rcx    # 0x5a3ab7
callq 0x4e53d0
movq -0x28(%rbp), %rax
movl 0xf8(%rax), %eax
movq $0x61e6d8, %rcx         # imm = 0x61E6D8
movzwl (%rcx), %ecx
xorl %edx, %edx
divl %ecx
cmpl $0x0, %edx
jne 0x417fcd
movq -0x28(%rbp), %rax
movl 0xf8(%rax), %eax
movq $0x61e6d8, %rcx         # imm = 0x61E6D8
movzwl (%rcx), %ecx
movq $0x61e5a8, %rdx         # imm = 0x61E5A8
imull (%rdx), %ecx
cmpl %ecx, %eax
jae 0x417fcd
movq -0x28(%rbp), %rax
movl 0xf8(%rax), %eax
movq $0x61e6d8, %rcx         # imm = 0x61E6D8
movzwl (%rcx), %ecx
movq $0x61e5ae, %rdx         # imm = 0x61E5AE
movzwl (%rdx), %edx
imull %edx, %ecx
xorl %edx, %edx
divl %ecx
movq $0x61e5ac, %rcx         # imm = 0x61E5AC
movzwl (%rcx), %ecx
xorl %edx, %edx
divl %ecx
movq -0x28(%rbp), %rax
movw %dx, %cx
movw %cx, -0x12(%rbp)
movl 0xf8(%rax), %eax
movq $0x61e6d8, %rcx         # imm = 0x61E6D8
movzwl (%rcx), %ecx
xorl %edx, %edx
divl %ecx
movq $0x61e5ae, %rcx         # imm = 0x61E5AE
movzwl (%rcx), %ecx
xorl %edx, %edx
divl %ecx
movw %dx, %ax
movw %ax, -0x14(%rbp)
movzwl -0x12(%rbp), %ecx
movq $0x61e5ac, %rax         # imm = 0x61E5AC
movzwl (%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x2a(%rbp)
jge 0x417edc
movb $0x1, %al
movb %al, -0x2a(%rbp)
jmp 0x417edc
movb -0x2a(%rbp), %al
testb $0x1, %al
jne 0x417ee5
jmp 0x417ee7
jmp 0x417f06
leaq 0x18bc10(%rip), %rdi    # 0x5a3afe
leaq 0x18b818(%rip), %rsi    # 0x5a370d
movl $0x2d1, %edx            # imm = 0x2D1
leaq 0x18bbb6(%rip), %rcx    # 0x5a3ab7
callq 0x4e53d0
movzwl -0x14(%rbp), %ecx
movq $0x61e5ae, %rax         # imm = 0x61E5AE
movzwl (%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x2b(%rbp)
jge 0x417f24
movb $0x1, %al
movb %al, -0x2b(%rbp)
jmp 0x417f24
movb -0x2b(%rbp), %al
testb $0x1, %al
jne 0x417f2d
jmp 0x417f2f
jmp 0x417f4e
leaq 0x18bc34(%rip), %rdi    # 0x5a3b6a
leaq 0x18b7d0(%rip), %rsi    # 0x5a370d
movl $0x2d2, %edx            # imm = 0x2D2
leaq 0x18bb6e(%rip), %rcx    # 0x5a3ab7
callq 0x4e53d0
movq -0x28(%rbp), %rax
movq $0x61e6f0, %rcx         # imm = 0x61E6F0
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %sil
movq 0x20(%rax), %rcx
movzwl -0x12(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzwl -0x14(%rbp), %edx
andb $0x1, %sil
movb %sil, (%rcx,%rdx)
movq $0x61e6f8, %rcx         # imm = 0x61E6F8
movq (%rcx), %rcx
movq $0x61e73a, %rdx         # imm = 0x61E73A
movzwl (%rdx), %edx
movq (%rcx,%rdx,8), %rcx
movq $0x61e738, %rdx         # imm = 0x61E738
movzwl (%rdx), %edx
movb (%rcx,%rdx), %dl
movq 0x28(%rax), %rax
movzwl -0x12(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movzwl -0x14(%rbp), %ecx
andb $0x1, %dl
movb %dl, (%rax,%rcx)
jmp 0x418043
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq $0x61e5ac, %rcx         # imm = 0x61E5AC
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x418041
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq $0x61e5ae, %rcx         # imm = 0x61E5AE
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x418034
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rcx
movslq -0x18(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x1c(%rbp), %rdx
movb $0x0, (%rcx,%rdx)
movq 0x28(%rax), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x1c(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x417fec
jmp 0x418036
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x417fd4
jmp 0x418043
movq -0x28(%rbp), %rax
movl 0xf8(%rax), %eax
movq $0x61e6d8, %rcx         # imm = 0x61E6D8
movzwl (%rcx), %ecx
movq $0x61e5a8, %rdx         # imm = 0x61E5A8
imull (%rdx), %ecx
cmpl %ecx, %eax
jae 0x418078
movq -0x28(%rbp), %rax
movl 0xf8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xf8(%rax)
addq $0x30, %rsp
popq %rbp
retq
nop