// File: MPSLab-ASU[P]DiRAC/./src/controller.cc
// Function: controller::inc_SPM_pass()
void controller::inc_SPM_pass()
{
  // Move to next SPM pass only if PEs are done processing previous data
  // i.e., execution in all RF passes of an SPM pass.
  if ((current_RF_pass == RF_passes + WB_delay_RF_pass) || (current_SPM_pass == 0) || (current_SPM_pass == SPM_passes + 1))
  {
    current_SPM_pass += 1;
    current_operand_prefetch = 0;
    current_operand_writeback = 0;
    current_RF_pass = 0;

    for(uint8_t i=0; i < total_operands; i++)
    {
      bool update_idx_buffer_comm = false;
      bool update_idx_buffer_comp = false;

      // We need to update buffer idx responsible for communication in two cases:
      // 1) DMA is going to prefetch some data in the upcoming pass.
      // 2) DMA will write-back in the upcoming pass.
      // In either cases, need to communicate data between SPM and DRAM
      // via different buffer.
      if(current_SPM_pass < SPM_passes)
        if(read_operand_SPM_pass[current_SPM_pass][i])
          update_idx_buffer_comm = true;

      if((current_SPM_pass < SPM_passes + WB_delay_SPM_pass) && write_operand_SPM_pass[current_SPM_pass][i])
        update_idx_buffer_comm = true;

      if(update_idx_buffer_comm)
      {
        spm_buffer_number_op_prefetch[i] = (spm_buffer_number_op_prefetch[i] + 1) % 2;
        spm_buffer_number_op_writeback[i] = (spm_buffer_number_op_writeback[i] + 1) % 2;
      }

      // We need to update buffer idx responsible for computation in two cases:
      // 1) DMA prefetched some data in previous pass.
      //    Need to compute from different buffer.
      // 2) DMA will write-back in the upcoming pass.
      //    PE-array should write output in the different scratchpad buffer.

      if(current_SPM_pass > 0 && current_SPM_pass < SPM_passes + 1)
      {
        if(read_operand_SPM_pass[current_SPM_pass-1][i])
        {
          update_idx_buffer_comp = true;
        }
      }

      if((current_SPM_pass < SPM_passes + WB_delay_SPM_pass) && write_operand_SPM_pass[current_SPM_pass][i])
        update_idx_buffer_comp = true;

      if(update_idx_buffer_comp)
      {
        spm_buffer_number_op_comp_read[i] = (spm_buffer_number_op_comp_read[i] + 1) % 2;
        spm_buffer_number_op_comp_write[i] = (spm_buffer_number_op_comp_write[i] + 1) % 2;
      }
    }

  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq $0x61e738, %rax         # imm = 0x61E738
movzwl (%rax), %eax
movq $0x61e552, %rcx         # imm = 0x61E552
movzwl (%rcx), %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
je 0x4170d9
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x4170d9
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
movq $0x61e554, %rcx         # imm = 0x61E554
movzwl (%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x417322
movq -0x18(%rbp), %rax
movq $0x61e73a, %rcx         # imm = 0x61E73A
movzwl (%rcx), %ecx
addl $0x1, %ecx
movw %cx, %dx
movq $0x61e73a, %rcx         # imm = 0x61E73A
movw %dx, (%rcx)
movb $0x0, 0xca(%rax)
movb $0x0, 0xcb(%rax)
movq $0x61e738, %rax         # imm = 0x61E738
movw $0x0, (%rax)
movb $0x0, -0x9(%rbp)
movzbl -0x9(%rbp), %eax
movq $0x61e556, %rcx         # imm = 0x61E556
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417320
movb $0x0, -0xa(%rbp)
movb $0x0, -0xb(%rbp)
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
movq $0x61e554, %rcx         # imm = 0x61E554
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x417173
movq $0x61e648, %rax         # imm = 0x61E648
movq (%rax), %rax
movq $0x61e73a, %rcx         # imm = 0x61E73A
movzwl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movzbl -0x9(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x417171
movb $0x1, -0xa(%rbp)
jmp 0x417173
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
movq $0x61e554, %rcx         # imm = 0x61E554
movzwl (%rcx), %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
jge 0x4171b4
movq $0x61e668, %rax         # imm = 0x61E668
movq (%rax), %rax
movq $0x61e73a, %rcx         # imm = 0x61E73A
movzwl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movzbl -0x9(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x4171b4
movb $0x1, -0xa(%rbp)
testb $0x1, -0xa(%rbp)
je 0x417216
movq $0x61e718, %rax         # imm = 0x61E718
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movzbl (%rax,%rcx), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq $0x61e718, %rax         # imm = 0x61E718
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movb %dl, (%rax,%rcx)
movq $0x61e720, %rax         # imm = 0x61E720
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movzbl (%rax,%rcx), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq $0x61e720, %rax         # imm = 0x61E720
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movb %dl, (%rax,%rcx)
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
cmpl $0x0, %eax
jle 0x41726e
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
movq $0x61e554, %rcx         # imm = 0x61E554
movzwl (%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jge 0x41726e
movq $0x61e648, %rax         # imm = 0x61E648
movq (%rax), %rax
movq $0x61e73a, %rcx         # imm = 0x61E73A
movzwl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movzbl -0x9(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x41726c
movb $0x1, -0xb(%rbp)
jmp 0x41726e
movq $0x61e73a, %rax         # imm = 0x61E73A
movzwl (%rax), %eax
movq $0x61e554, %rcx         # imm = 0x61E554
movzwl (%rcx), %ecx
addl $0x2, %ecx
cmpl %ecx, %eax
jge 0x4172af
movq $0x61e668, %rax         # imm = 0x61E668
movq (%rax), %rax
movq $0x61e73a, %rcx         # imm = 0x61E73A
movzwl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movzbl -0x9(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x4172af
movb $0x1, -0xb(%rbp)
testb $0x1, -0xb(%rbp)
je 0x417311
movq $0x61e728, %rax         # imm = 0x61E728
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movzbl (%rax,%rcx), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq $0x61e728, %rax         # imm = 0x61E728
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movb %dl, (%rax,%rcx)
movq $0x61e730, %rax         # imm = 0x61E730
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movzbl (%rax,%rcx), %eax
addl $0x1, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movq $0x61e730, %rax         # imm = 0x61E730
movq (%rax), %rax
movzbl -0x9(%rbp), %ecx
movb %dl, (%rax,%rcx)
jmp 0x417313
movb -0x9(%rbp), %al
addb $0x1, %al
movb %al, -0x9(%rbp)
jmp 0x417115
jmp 0x417322
popq %rbp
retq
nopw %cs:(%rax,%rax)