// File: mh0fm4[P]SCDC/src/lib/redirect/redirect/redirect_call.cc
// Function: void redirect_call_get_output_param_blocks_val<float>(_redirect_call_t*, char const*, float**, long, long, long*)
void redirect_call_get_output_param_blocks_val(redirect_call_t *rc, const char *id, T **b, rdint_t count, rdint_t size, rdint_t *stride)
{
  TRACE_F("rc: %p, id: '%s', b: %p, count: %" rdint_fmt ", size: %" rdint_fmt ", stride: %" rdint_fmt, rc, id, *b, count, size, *stride);

  if (rc->client) /* client */
  {
    bool transfer_dense = false;
    rdint_t transfer_stride;

    redirect_call_get_output_conf_rdint(rc, "stride", &transfer_stride);
    TRACE_F("transfer stride: %" rdint_fmt, transfer_stride);

    if (*stride == 0) *stride = transfer_stride;

    rdint_t alloc_stride, recv_stride;

#if REDIRECT_CALL_OUTPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PLAIN
    transfer_dense = true;
    alloc_stride = transfer_stride;
    recv_stride = transfer_stride;
#elif REDIRECT_CALL_OUTPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PACK_IP
    transfer_dense = true;
    alloc_stride = z_max(*stride, transfer_stride);
    recv_stride = transfer_stride;
#elif REDIRECT_CALL_OUTPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PACK_OP
    transfer_dense = true;
    alloc_stride = *stride;
    recv_stride = transfer_stride;
#elif REDIRECT_CALL_OUTPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PIECES
    transfer_dense = false;
    alloc_stride = *stride;
    recv_stride = *stride;
#endif

    TRACE_F("alloc stride: %" rdint_fmt ", recv stride: %" rdint_fmt, alloc_stride, recv_stride);

    if (*b == NULL) *b = static_cast<T *>(redirect_call_alloc_buf(rc, get_blocks_cont_size(count, size, alloc_stride) * sizeof(T)));

    T* b_recv = *b;

#if REDIRECT_CALL_INPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PACK_OP
    T *b_tmp = 0;
    if (recv_stride != *stride) b_recv = b_tmp = static_cast<T *>(malloc(get_blocks_cont_size(count, size, transfer_stride) * sizeof(T)));
#endif

    if (recv_stride == transfer_stride || transfer_dense)
    {
      TRACE_F("consume dense: %" rdint_fmt, get_blocks_cont_size(count, size, recv_stride));
      consume_output_dense<T>(rc, b_recv, get_blocks_cont_size(count, size, recv_stride));

    } else
    {
      TRACE_F("consume blocks: %" rdint_fmt " x %" rdint_fmt " / %" rdint_fmt, count, size, recv_stride);
      consume_output_blocks<T>(rc, b_recv, count, size, recv_stride);
    }

    if (recv_stride != *stride)
    {
#if REDIRECT_CALL_INPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PLAIN
      TRACE_F("set stride %" rdint_fmt, recv_stride);
      *stride = recv_stride;
#elif REDIRECT_CALL_INPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PACK_IP
      TRACE_F("transform in-place to stride %" rdint_fmt, *stride);
      redirect_data_blocks_transform_val<T>(count, size, recv_stride, b_recv, *stride, NULL);
#elif REDIRECT_CALL_INPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PACK_OP
      TRACE_F("transform out-of-place to stride: %" rdint_fmt, *stride);
      redirect_data_blocks_transform_val<T>(count, size, recv_stride, b_recv, *stride, *b);
      free(b_tmp);
#elif REDIRECT_CALL_INPUT_PARAM_BLOCKS == REDIRECT_CALL_BLOCKS_PIECES
      /* this should never occur, because pieces are received with the correct stride */
      ASSERT(false);
#endif
    }

  } else /* server */
  {
    if (*b == NULL)
    {
      /* default stride is size */
      if (*stride == 0) *stride = size;

      /* FIXME: use output instead of allocation */

      /* allocate buffer */
      *b = static_cast<T *>(redirect_call_alloc_buf(rc, get_blocks_cont_size(count, size, *stride) * sizeof(T)));
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq 0xb2e86(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x846dd(%rip), %rsi     # 0xa5811
leaq 0x84dde(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2e67(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x8(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq (%rax), %r8
movq -0x20(%rbp), %r9
movq -0x28(%rbp), %r10
movq -0x30(%rbp), %rax
movq (%rax), %rax
leaq 0x84bf6(%rip), %rsi     # 0xa5d67
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0xc9a0
movq 0xb2e28(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x84716(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x8(%rbp), %rax
cmpl $0x0, (%rax)
je 0x21472
movb $0x0, -0x31(%rbp)
movq -0x8(%rbp), %rdi
leaq 0x84c24(%rip), %rsi     # 0xa5dd9
leaq -0x40(%rbp), %rdx
callq 0x125e0
movq 0xb2deb(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x84642(%rip), %rsi     # 0xa5811
leaq 0x84d43(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2dcc(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x40(%rbp), %rdx
leaq 0x84bd2(%rip), %rsi     # 0xa5dc4
movb $0x0, %al
callq 0xc9a0
movq 0xb2db0(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x8469e(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x21226
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movb $0x1, -0x31(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq 0xb2d6f(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x845c6(%rip), %rsi     # 0xa5811
leaq 0x84cc7(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2d50(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
leaq 0x84bc0(%rip), %rsi     # 0xa5e32
movb $0x0, %al
callq 0xc9a0
movq 0xb2d30(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x8461e(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x212ce
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x48(%rbp), %rdx
callq 0x189e0
movq -0x60(%rbp), %rdi
movq %rax, %rsi
shlq $0x2, %rsi
callq 0x172d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
je 0x212ed
testb $0x1, -0x31(%rbp)
je 0x2138d
jmp 0x212ef
movq 0xb2cba(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x84511(%rip), %rsi     # 0xa5811
leaq 0x84c12(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2c9b(%rip), %rax     # 0xd3fb0
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x189e0
movq -0x68(%rbp), %rdi
movq %rax, %rdx
leaq 0x84b1b(%rip), %rsi     # 0xa5e56
movb $0x0, %al
callq 0xc9a0
movq 0xb2c67(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x84555(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x50(%rbp), %rdx
callq 0x189e0
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rsi
movq %rax, %rdx
callq 0x18260
jmp 0x21403
jmp 0x2138f
movq 0xb2c1a(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x84471(%rip), %rsi     # 0xa5811
leaq 0x84b72(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2bfb(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %r8
leaq 0x84a9e(%rip), %rsi     # 0xa5e69
movb $0x0, %al
callq 0xc9a0
movq 0xb2bd7(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x844c5(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %r8
callq 0x193a0
movq -0x50(%rbp), %rax
movq -0x30(%rbp), %rcx
cmpq (%rcx), %rax
je 0x21470
jmp 0x21412
movq 0xb2b97(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x843ee(%rip), %rsi     # 0xa5811
leaq 0x84aef(%rip), %rdx     # 0xa5f19
movb $0x0, %al
callq 0xc9a0
movq 0xb2b78(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
movq -0x50(%rbp), %rdx
leaq 0x84afd(%rip), %rsi     # 0xa5f43
movb $0x0, %al
callq 0xc9a0
movq 0xb2b5c(%rip), %rax     # 0xd3fb0
movq (%rax), %rdi
leaq 0x8444a(%rip), %rsi     # 0xa58a8
movb $0x0, %al
callq 0xc9a0
movq -0x50(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
jmp 0x214c9
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x214c7
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x21491
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rax
movq (%rax), %rdx
callq 0x189e0
movq -0x80(%rbp), %rdi
movq %rax, %rsi
shlq $0x2, %rsi
callq 0x172d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x214c9
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)