// File: MPSLab-ASU[P]DiRAC/./src/controller.cc
// Function: controller::prefetch_to_SPM(unsigned short)
void controller::prefetch_to_SPM(uint16_t current_SPM_pass)
{
  assert(current_operand_prefetch < total_operands && "invalid operand to be prefetched!");
  if(read_operand_SPM_pass[current_SPM_pass][current_operand_prefetch])
  {
    // schedule prefetch of operand to SPM
    if(current_DMAC_invocation_operand_prefetch < read_operand_offset_base_addr_SPM[current_SPM_pass][current_operand_prefetch].size())
    {
      uint8_t buffer_number_comm = spm_buffer_number_op_prefetch[current_operand_prefetch];
      uint32_t offset_SPM = read_operand_offset_base_addr_SPM[current_SPM_pass][current_operand_prefetch][current_DMAC_invocation_operand_prefetch];
      uint32_t offset_DRAM = read_operand_offset_base_addr_DRAM[current_SPM_pass][current_operand_prefetch][current_DMAC_invocation_operand_prefetch];
      uint32_t burst_size = read_operand_burst_width_bytes_SPM_pass[current_SPM_pass][current_operand_prefetch][current_DMAC_invocation_operand_prefetch];
      assert(burst_size > 0 && "burst size for DMAC request must be greater than zero.");
      data_type *address_operand_DRAM = tensor_operands[current_operand_prefetch] + (offset_DRAM / sizeof(data_type));
      data_type *address_operand_SPM = scratchpad_mem->get_ptr() + ((operand_start_addr_SPM_buffer[buffer_number_comm][current_operand_prefetch] + offset_SPM) / sizeof(data_type));
      bus_req_DMA = true;
      data_mov_SPM_DRAM_in_prog = true;
      DMAC->prefetch<data_type>(address_operand_DRAM, address_operand_SPM, burst_size);
      current_DMAC_invocation_operand_prefetch += 1;
    }
    else {
      current_DMAC_invocation_operand_prefetch = 0;
      current_operand_prefetch += 1;
    }
  }
  else
    current_operand_prefetch += 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movw %si, %ax
movq %rdi, -0x8(%rbp)
movw %ax, -0xa(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movzbl 0xca(%rax), %ecx
movq $0x61e556, %rax         # imm = 0x61E556
movzbl (%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x29(%rbp)
jge 0x41736c
movb $0x1, %al
movb %al, -0x29(%rbp)
jmp 0x41736c
movb -0x29(%rbp), %al
testb $0x1, %al
jne 0x417375
jmp 0x417377
jmp 0x417396
leaq 0x18c33e(%rip), %rdi    # 0x5a36bc
leaq 0x18c388(%rip), %rsi    # 0x5a370d
movl $0x162, %edx            # imm = 0x162
leaq 0x18c390(%rip), %rcx    # 0x5a3721
callq 0x4e53d0
movq -0x38(%rbp), %rcx
movq $0x61e648, %rax         # imm = 0x61E648
movq (%rax), %rax
movzwl -0xa(%rbp), %edx
movq (%rax,%rdx,8), %rax
movzbl 0xca(%rcx), %ecx
testb $0x1, (%rax,%rcx)
je 0x4175c1
movq -0x38(%rbp), %rax
movzbl 0xcc(%rax), %ecx
movq %rcx, -0x40(%rbp)
movq $0x61e650, %rcx         # imm = 0x61E650
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xca(%rax), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x413200
movq %rax, %rcx
movq -0x40(%rbp), %rax
cmpq %rcx, %rax
jae 0x4175a4
movq -0x38(%rbp), %rax
movq $0x61e718, %rcx         # imm = 0x61E718
movq (%rcx), %rcx
movzbl 0xca(%rax), %edx
movb (%rcx,%rdx), %cl
movb %cl, -0xb(%rbp)
movq $0x61e650, %rcx         # imm = 0x61E650
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xca(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcc(%rax), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x10(%rbp)
movq $0x61e660, %rcx         # imm = 0x61E660
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xca(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcc(%rax), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x14(%rbp)
movq $0x61e658, %rcx         # imm = 0x61E658
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xca(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcc(%rax), %eax
movl %eax, %esi
callq 0x4189e0
movl (%rax), %eax
movl %eax, -0x18(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x18(%rbp)
movb %al, -0x41(%rbp)
jbe 0x4174d5
movb $0x1, %al
movb %al, -0x41(%rbp)
jmp 0x4174d5
movb -0x41(%rbp), %al
testb $0x1, %al
jne 0x4174de
jmp 0x4174e0
jmp 0x4174ff
leaq 0x18c29c(%rip), %rdi    # 0x5a3783
leaq 0x18c21f(%rip), %rsi    # 0x5a370d
movl $0x16c, %edx            # imm = 0x16C
leaq 0x18c227(%rip), %rcx    # 0x5a3721
callq 0x4e53d0
movq -0x38(%rbp), %rax
movq $0x61e560, %rcx         # imm = 0x61E560
movq (%rcx), %rcx
movzbl 0xca(%rax), %edx
movq (%rcx,%rdx,8), %rcx
movl -0x14(%rbp), %edx
shrq %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, -0x20(%rbp)
movq 0xb0(%rax), %rdi
callq 0x4245a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq $0x61e640, %rdx         # imm = 0x61E640
movq (%rdx), %rdx
movzbl -0xb(%rbp), %esi
movq (%rdx,%rsi,8), %rdx
movzbl 0xca(%rax), %esi
movl (%rdx,%rsi,4), %edx
addl -0x10(%rbp), %edx
movl %edx, %edx
shrq %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, -0x28(%rbp)
movb $0x1, 0xb8(%rax)
movb $0x1, 0xc9(%rax)
movq 0xa8(%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl -0x18(%rbp), %ecx
callq 0x418a00
movq -0x38(%rbp), %rax
movzbl 0xcc(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xcc(%rax)
jmp 0x4175bf
movq -0x38(%rbp), %rax
movb $0x0, 0xcc(%rax)
movzbl 0xca(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xca(%rax)
jmp 0x4175d5
movq -0x38(%rbp), %rax
movzbl 0xca(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xca(%rax)
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)