// File: MPSLab-ASU[P]DiRAC/./src/controller.cc
// Function: controller::write_back_DRAM(unsigned short)
void controller::write_back_DRAM(uint16_t current_SPM_pass)
{
  assert(current_operand_writeback < total_operands && "invalid operand for write back!");
  if(write_operand_SPM_pass[current_SPM_pass][current_operand_writeback])
  {
    // schedule write-back of operand from SPM to DRAM
    if(current_DMAC_invocation_operand_writeback < write_operand_offset_base_addr_SPM[current_SPM_pass][current_operand_writeback].size())
    {
      uint8_t buffer_number_comm = spm_buffer_number_op_writeback[current_operand_writeback];
      uint32_t offset_SPM = write_operand_offset_base_addr_SPM[current_SPM_pass][current_operand_writeback][current_DMAC_invocation_operand_writeback];
      uint32_t offset_DRAM = write_operand_offset_base_addr_DRAM[current_SPM_pass][current_operand_writeback][current_DMAC_invocation_operand_writeback];
      uint32_t burst_size = write_operand_burst_width_bytes_SPM_pass[current_SPM_pass][current_operand_writeback][current_DMAC_invocation_operand_writeback];
      assert(burst_size > 0 && "burst size for DMAC request must be greater than zero.");
      data_type *address_operand_DRAM = tensor_operands[current_operand_writeback] + (offset_DRAM / sizeof(data_type));
      data_type *address_operand_SPM = scratchpad_mem->get_ptr() + ((operand_start_addr_SPM_buffer[buffer_number_comm][current_operand_writeback] + offset_SPM) / sizeof(data_type));
      bus_req_DMA = true;
      data_mov_SPM_DRAM_in_prog = true;
      DMAC->write_back<data_type>(address_operand_SPM, address_operand_DRAM, burst_size);
      current_DMAC_invocation_operand_writeback += 1;
    }
    else {
      current_DMAC_invocation_operand_writeback = 0;
      current_operand_writeback += 1;
    }
  }
  else
    current_operand_writeback += 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 0xcb(%rax), %ecx
movq $0x61e556, %rax         # imm = 0x61E556
movzbl (%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x29(%rbp)
jge 0x416e0c
movb $0x1, %al
movb %al, -0x29(%rbp)
jmp 0x416e0c
movb -0x29(%rbp), %al
testb $0x1, %al
jne 0x416e15
jmp 0x416e17
jmp 0x416e36
leaq 0x18c9d0(%rip), %rdi    # 0x5a37ee
leaq 0x18c8e8(%rip), %rsi    # 0x5a370d
movl $0x180, %edx            # imm = 0x180
leaq 0x18ca0d(%rip), %rcx    # 0x5a383e
callq 0x4e53d0
movq -0x38(%rbp), %rcx
movq $0x61e668, %rax         # imm = 0x61E668
movq (%rax), %rax
movzwl -0xa(%rbp), %edx
movq (%rax,%rdx,8), %rax
movzbl 0xcb(%rcx), %ecx
testb $0x1, (%rax,%rcx)
je 0x417061
movq -0x38(%rbp), %rax
movzbl 0xcd(%rax), %ecx
movq %rcx, -0x40(%rbp)
movq $0x61e670, %rcx         # imm = 0x61E670
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xcb(%rax), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x413200
movq %rax, %rcx
movq -0x40(%rbp), %rax
cmpq %rcx, %rax
jae 0x417044
movq -0x38(%rbp), %rax
movq $0x61e720, %rcx         # imm = 0x61E720
movq (%rcx), %rcx
movzbl 0xcb(%rax), %edx
movb (%rcx,%rdx), %cl
movb %cl, -0xb(%rbp)
movq $0x61e670, %rcx         # imm = 0x61E670
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xcb(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcd(%rax), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x10(%rbp)
movq $0x61e680, %rcx         # imm = 0x61E680
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xcb(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcd(%rax), %eax
movl %eax, %esi
callq 0x4189e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x14(%rbp)
movq $0x61e678, %rcx         # imm = 0x61E678
movq (%rcx), %rcx
movzwl -0xa(%rbp), %edx
movq (%rcx,%rdx,8), %rdi
movzbl 0xcb(%rax), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rdi
movzbl 0xcd(%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 0x416f75
movb $0x1, %al
movb %al, -0x41(%rbp)
jmp 0x416f75
movb -0x41(%rbp), %al
testb $0x1, %al
jne 0x416f7e
jmp 0x416f80
jmp 0x416f9f
leaq 0x18c7fc(%rip), %rdi    # 0x5a3783
leaq 0x18c77f(%rip), %rsi    # 0x5a370d
movl $0x18a, %edx            # imm = 0x18A
leaq 0x18c8a4(%rip), %rcx    # 0x5a383e
callq 0x4e53d0
movq -0x38(%rbp), %rax
movq $0x61e560, %rcx         # imm = 0x61E560
movq (%rcx), %rcx
movzbl 0xcb(%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 0xcb(%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 -0x28(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl -0x18(%rbp), %ecx
callq 0x418b30
movq -0x38(%rbp), %rax
movzbl 0xcd(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xcd(%rax)
jmp 0x41705f
movq -0x38(%rbp), %rax
movb $0x0, 0xcd(%rax)
movzbl 0xcb(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xcb(%rax)
jmp 0x417075
movq -0x38(%rbp), %rax
movzbl 0xcb(%rax), %ecx
addl $0x1, %ecx
movb %cl, 0xcb(%rax)
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)