// File: MPSLab-ASU[P]DiRAC/./src/controller.cc
// Function: controller::prefetch_to_PE(unsigned short)
void controller::prefetch_to_PE(uint16_t current_RF_pass)
{
  assert(PE_prefetch_RF_incomplete == 1 && "Communication of data to PEs is incomplete.");
  bool prefetch_completed = true;

  for(uint8_t i=0; i < inNetworks; i++) {

    configNetwork[i] = 0;
    forwardDataToNetwork[i] = 0;
    network_read_op_comm_completed[i] = 1;

    if(read_data_RF_pass[current_RF_pass][i])
    {
      // schedule prefetch of operand to PE
      if(cnt_prefetch_via_network_RF_pass[i] < RF_pass_network_read_operand[current_RF_pass][i].size())
      {
        uint16_t burst_size_op = RF_pass_network_read_operand_burst_width_elements[current_RF_pass][i][cnt_prefetch_via_network_RF_pass[i]];
        network_read_op_comm_completed[i] = 0; // communication incomplete yet.
        if(idx_read_network_packet[i] < burst_size_op) {
          uint8_t operand = RF_pass_network_read_operand[current_RF_pass][i][cnt_prefetch_via_network_RF_pass[i]];
          uint8_t buffer_number_comp = spm_buffer_number_op_comp_read[operand];
          uint16_t idx_packet = RF_pass_network_read_operand_offset_network_packet[current_RF_pass][i][cnt_prefetch_via_network_RF_pass[i]];
          uint32_t offset_SPM = RF_pass_network_read_operand_offset_base_addr_SPM[current_RF_pass][i][cnt_prefetch_via_network_RF_pass[i]];
          uint32_t address_SPM = ((operand_start_addr_SPM_buffer[buffer_number_comp][operand] + offset_SPM) / sizeof(data_type)) + idx_read_network_packet[i];
          data_type data = scratchpad_mem->read(address_SPM);
          send_data_via_read_network(operand, i, idx_packet + idx_read_network_packet[i], data);
          idx_read_network_packet[i] += 1;
        }
        else {
          cnt_prefetch_via_network_RF_pass[i] += 1;
          idx_read_network_packet[i] = 0;
        }
      }
    }
    prefetch_completed &= (network_read_op_comm_completed[i] == 1);
  }

  counter_RF_pass_prefetch += 1;

  if ((counter_RF_pass_prefetch >= total_cycles_RF_pass) && (prefetch_completed)) {
    PE_prefetch_RF_incomplete = false;
    for(uint8_t i=0; i < inNetworks; i++)
      cnt_prefetch_via_network_RF_pass[i] = 0;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movw %si, %ax
movq %rdi, -0x8(%rbp)
movw %ax, -0xa(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movb 0xce(%rax), %al
andb $0x1, %al
movzbl %al, %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
movb %al, -0x20(%rbp)
jne 0x4184e7
movb $0x1, %al
movb %al, -0x20(%rbp)
jmp 0x4184e7
movb -0x20(%rbp), %al
testb $0x1, %al
jne 0x4184f0
jmp 0x4184f2
jmp 0x418511
leaq 0x18b39c(%rip), %rdi    # 0x5a3895
leaq 0x18b20d(%rip), %rsi    # 0x5a370d
movl $0x22f, %edx            # imm = 0x22F
leaq 0x18b3d9(%rip), %rcx    # 0x5a38e5
callq 0x4e53d0
movb $0x1, -0xb(%rbp)
movb $0x0, -0xc(%rbp)
movzbl -0xc(%rbp), %eax
movq $0x61c151, %rcx         # imm = 0x61C151
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x418814
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rcx
movzbl -0xc(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x60(%rax), %rcx
movzbl -0xc(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0x100(%rax), %rax
movzbl -0xc(%rbp), %ecx
movb $0x1, (%rax,%rcx)
movq $0x61e688, %rax         # imm = 0x61E688
movq (%rax), %rax
movzwl -0xa(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movzbl -0xc(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x4187d0
movq -0x28(%rbp), %rax
movq 0xd8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movq %rax, -0x30(%rbp)
movq $0x61e690, %rax         # imm = 0x61E690
movq (%rax), %rax
movzwl -0xa(%rbp), %ecx
movq (%rax,%rcx,8), %rdi
movzbl -0xc(%rbp), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x4143b0
movq %rax, %rcx
movq -0x30(%rbp), %rax
cmpq %rcx, %rax
jae 0x4187ce
movq -0x28(%rbp), %rax
movq $0x61e6a0, %rcx         # imm = 0x61E6A0
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl -0xc(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movq 0xd8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movl (%rcx), %ecx
movw %cx, -0xe(%rbp)
movq 0x100(%rax), %rcx
movzbl -0xc(%rbp), %edx
movb $0x0, (%rcx,%rdx)
movq 0xe8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzwl (%rax,%rcx,2), %eax
movzwl -0xe(%rbp), %ecx
cmpl %ecx, %eax
jge 0x4187a1
movq -0x28(%rbp), %rax
movq $0x61e690, %rcx         # imm = 0x61E690
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl -0xc(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movq 0xd8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, %esi
callq 0x418c60
movq %rax, %rcx
movq -0x28(%rbp), %rax
movb (%rcx), %cl
movb %cl, -0xf(%rbp)
movq $0x61e728, %rcx         # imm = 0x61E728
movq (%rcx), %rcx
movzbl -0xf(%rbp), %edx
movb (%rcx,%rdx), %cl
movb %cl, -0x10(%rbp)
movq $0x61e698, %rcx         # imm = 0x61E698
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl -0xc(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movq 0xd8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, %esi
callq 0x40f340
movq %rax, %rcx
movq -0x28(%rbp), %rax
movw (%rcx), %cx
movw %cx, -0x12(%rbp)
movq $0x61e6a8, %rcx         # imm = 0x61E6A8
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl -0xc(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movq 0xd8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x18(%rbp)
movq $0x61e640, %rcx         # imm = 0x61E640
movq (%rcx), %rcx
movzbl -0x10(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
movzbl -0xf(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
addl -0x18(%rbp), %ecx
movl %ecx, %ecx
shrq %rcx
movq 0xe8(%rax), %rdx
movzbl -0xc(%rbp), %esi
movzwl (%rdx,%rsi,2), %edx
addq %rdx, %rcx
movl %ecx, -0x1c(%rbp)
movq 0xb0(%rax), %rdi
movl -0x1c(%rbp), %esi
callq 0x424550
movq -0x28(%rbp), %rdi
movw %ax, -0x1e(%rbp)
movb -0xf(%rbp), %dl
movb -0xc(%rbp), %cl
movzwl -0x12(%rbp), %eax
movq 0xe8(%rdi), %rsi
movzbl -0xc(%rbp), %r8d
movzwl (%rsi,%r8,2), %esi
addl %esi, %eax
movzbl %dl, %esi
movzbl %cl, %edx
movzwl %ax, %ecx
movzwl -0x1e(%rbp), %r8d
callq 0x418890
movq -0x28(%rbp), %rax
movq 0xe8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movzwl (%rax,%rcx,2), %edx
addl $0x1, %edx
movw %dx, (%rax,%rcx,2)
jmp 0x4187cc
movq -0x28(%rbp), %rax
movq 0xd8(%rax), %rcx
movzbl -0xc(%rbp), %edx
movzbl (%rcx,%rdx), %esi
addl $0x1, %esi
movb %sil, (%rcx,%rdx)
movq 0xe8(%rax), %rax
movzbl -0xc(%rbp), %ecx
movw $0x0, (%rax,%rcx,2)
jmp 0x4187ce
jmp 0x4187d0
movq -0x28(%rbp), %rax
movq 0x100(%rax), %rax
movzbl -0xc(%rbp), %ecx
movb (%rax,%rcx), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
movb -0xb(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0xb(%rbp)
movb -0xc(%rbp), %al
addb $0x1, %al
movb %al, -0xc(%rbp)
jmp 0x418519
movq -0x28(%rbp), %rax
movzwl 0xd0(%rax), %ecx
addl $0x1, %ecx
movw %cx, 0xd0(%rax)
movzwl 0xd0(%rax), %eax
movq $0x61e5e0, %rcx         # imm = 0x61E5E0
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jl 0x418884
testb $0x1, -0xb(%rbp)
je 0x418884
movq -0x28(%rbp), %rax
movb $0x0, 0xce(%rax)
movb $0x0, -0x1f(%rbp)
movzbl -0x1f(%rbp), %eax
movq $0x61c151, %rcx         # imm = 0x61C151
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x418882
movq -0x28(%rbp), %rax
movq 0xd8(%rax), %rax
movzbl -0x1f(%rbp), %ecx
movb $0x0, (%rax,%rcx)
movb -0x1f(%rbp), %al
addb $0x1, %al
movb %al, -0x1f(%rbp)
jmp 0x418853
jmp 0x418884
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)