// File: zgimbutas[P]mwrap/src/mwrap-cgen.cc
// Function: mex_marshal_array(_IO_FILE*, Var*)
void mex_marshal_array(FILE* fp, Var* v)
{
    if (v->devicespec != 'g'){
    Expr* e = v->qual->args;
    char namebuf[128];
    const char* mtype = complex_tinfo(v) ? "mxCOMPLEX" : "mxREAL";
    const char* ws = "    ";

    if (v->tinfo == VT_rarray) {
        ws = "        ";
        fprintf(fp, "    if (out%d_ == NULL) {\n", v->output_label);
        fprintf(fp, "        plhs[%d] = mxCreateDoubleMatrix(0,0, mxREAL);\n",
                v->output_label);
        fprintf(fp, "    } else {\n");
    }

    if (!e) {

        // No dimension info -- must be an inout array
        if (strcmp(v->basetype, "float") == 0 || strcmp(v->basetype, "fcomplex") == 0)
	  {
        fprintf(fp, "%splhs[%d] = mxCreateNumericMatrix("
                "mxGetM(prhs[%d]), mxGetN(prhs[%d]), mxSINGLE_CLASS, %s);\n", ws,
                v->output_label, v->input_label, v->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_single_%s(plhs[%d], in%d_, ", ws,
                v->basetype, v->output_label, v->input_label);
	  }
	else
	  {
        fprintf(fp, "%splhs[%d] = mxCreateDoubleMatrix("
                "mxGetM(prhs[%d]), mxGetN(prhs[%d]), %s);\n", ws,
                v->output_label, v->input_label, v->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_%s(plhs[%d], in%d_, ", ws,
                v->basetype, v->output_label, v->input_label);
	  }
        fprintf(fp, "mxGetM(prhs[%d])*mxGetN(prhs[%d])",
                v->input_label, v->input_label);
        fprintf(fp, ");\n");

    } else if (!(e->next)) {

        // Only size given
        if (strcmp(v->basetype, "float") == 0 || strcmp(v->basetype, "fcomplex") == 0)
	  {
        fprintf(fp, "%splhs[%d] = mxCreateNumericMatrix(dim%d_, 1, mxSINGLE_CLASS, %s);\n", ws,
                v->output_label, e->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_single_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
	else
	  {
        fprintf(fp, "%splhs[%d] = mxCreateDoubleMatrix(dim%d_, 1, %s);\n", ws,
                v->output_label, e->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
        fprintf(fp, "dim%d_",
                e->input_label);
        fprintf(fp, ");\n");

    } else if (!(e->next->next)) {

        // Two dimensions given
        if (strcmp(v->basetype, "float") == 0 || strcmp(v->basetype, "fcomplex") == 0)
	  {
        fprintf(fp, "%splhs[%d] = mxCreateNumericMatrix("
                "dim%d_, dim%d_, mxSINGLE_CLASS, %s);\n", ws,
                v->output_label, e->input_label, e->next->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_single_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
	else
	  {
        fprintf(fp, "%splhs[%d] = mxCreateDoubleMatrix("
                "dim%d_, dim%d_, %s);\n", ws,
                v->output_label, e->input_label, e->next->input_label, mtype);
        fprintf(fp, "%smxWrapCopy_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
        fprintf(fp, "dim%d_*dim%d_",
                e->input_label, e->next->input_label);
        fprintf(fp, ");\n");

    } else {

        // Three or more dimensions given -- punt and make it 1D
        if (strcmp(v->basetype, "float") == 0 || strcmp(v->basetype, "fcomplex") == 0)
	  {
        fprintf(fp, "%splhs[%d] = mxCreateNumericMatrix(", ws,
                v->output_label);
        mex_alloc_size(fp, e);
        fprintf(fp, ", 1, mxSINGLE_CLASS, %s);\n", mtype);
        fprintf(fp, "%smxWrapCopy_single_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
	else
	  {
        fprintf(fp, "%splhs[%d] = mxCreateDoubleMatrix(", ws,
                v->output_label);
        mex_alloc_size(fp, e);
        fprintf(fp, ", 1, %s);\n", mtype);
        fprintf(fp, "%smxWrapCopy_%s(plhs[%d], %s, ", ws,
                v->basetype, v->output_label, vname(v, namebuf));
	  }
        mex_alloc_size(fp, e);
        fprintf(fp, ");\n");

    }

    if (v->tinfo == VT_rarray) {
        fprintf(fp, "    }\n");
    }
    }

    if (v->devicespec == 'g'){
        if (v->iospec == 'b') {
            fprintf(fp, "    plhs[%d] = prhs[%d];\n", v->output_label, v->input_label);
        }
        if (v->iospec == 'o') {
            fprintf(fp, "    plhs[%d] = mxGPUCreateMxArrayOnGPU(mxGPUArray_out%d_);\n", v->output_label, v->output_label);
        }
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movsbl 0x9(%rax), %eax
cmpl $0x67, %eax
je 0x10b45
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0xce00
movb %al, %dl
leaq 0xc2c7(%rip), %rax      # 0x1c6bd
leaq 0xc2b6(%rip), %rcx      # 0x1c6b3
testb $0x1, %dl
cmovneq %rcx, %rax
movq %rax, -0xa8(%rbp)
leaq 0xc46d(%rip), %rax      # 0x1c87f
movq %rax, -0xb0(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x5, 0x20(%rax)
jne 0x10475
leaq 0xc5ac(%rip), %rax      # 0x1c9d6
movq %rax, -0xb0(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edx
leaq 0xc59c(%rip), %rsi      # 0x1c9df
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edx
leaq 0xc59e(%rip), %rsi      # 0x1c9fa
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
leaq 0xc5c3(%rip), %rsi      # 0x1ca31
movb $0x0, %al
callq 0x33a0
cmpq $0x0, -0x18(%rbp)
jne 0x105bb
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x4694(%rip), %rsi      # 0x14b23
callq 0x3390
cmpl $0x0, %eax
je 0x104b2
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x3fdd(%rip), %rsi      # 0x14485
callq 0x3390
cmpl $0x0, %eax
jne 0x1051d
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x10(%rbp), %rax
movl (%rax), %r8d
movq -0x10(%rbp), %rax
movl (%rax), %r9d
movq -0xa8(%rbp), %rax
leaq 0xc55f(%rip), %rsi      # 0x1ca3f
movq %rax, (%rsp)
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %r8d
movq -0x10(%rbp), %rax
movl (%rax), %r9d
leaq 0xc588(%rip), %rsi      # 0x1ca9c
movb $0x0, %al
callq 0x33a0
jmp 0x10586
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x10(%rbp), %rax
movl (%rax), %r8d
movq -0x10(%rbp), %rax
movl (%rax), %r9d
movq -0xa8(%rbp), %rax
leaq 0xc57a(%rip), %rsi      # 0x1cac5
movq %rax, (%rsp)
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %r8d
movq -0x10(%rbp), %rax
movl (%rax), %r9d
leaq 0xc592(%rip), %rsi      # 0x1cb11
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movl (%rax), %ecx
leaq 0xc596(%rip), %rsi      # 0x1cb33
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
leaq 0xd25a(%rip), %rsi      # 0x1d809
movb $0x0, %al
callq 0x33a0
jmp 0x10b27
movq -0x18(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x10774
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x454a(%rip), %rsi      # 0x14b23
callq 0x3390
cmpl $0x0, %eax
je 0x10600
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x3e93(%rip), %rsi      # 0x14485
callq 0x3390
cmpl $0x0, %eax
jne 0x106a5
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x18(%rbp), %rax
movl (%rax), %r8d
movq -0xa8(%rbp), %r9
leaq 0xc52e(%rip), %rsi      # 0x1cb55
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0xb4(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0xd0(%rbp), %rdi
movq -0xc8(%rbp), %rdx
movq -0xc0(%rbp), %rcx
movl -0xb4(%rbp), %r8d
movq %rax, %r9
leaq 0xc500(%rip), %rsi      # 0x1cb99
movb $0x0, %al
callq 0x33a0
jmp 0x10745
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x18(%rbp), %rax
movl (%rax), %r8d
movq -0xa8(%rbp), %r9
leaq 0xc4f3(%rip), %rsi      # 0x1cbbf
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0xd4(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0xf0(%rbp), %rdi
movq -0xe8(%rbp), %rdx
movq -0xe0(%rbp), %rcx
movl -0xd4(%rbp), %r8d
movq %rax, %r9
leaq 0xc4b4(%rip), %rsi      # 0x1cbf2
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %edx
leaq 0xc543(%rip), %rsi      # 0x1cc99
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
leaq 0xd0a1(%rip), %rsi      # 0x1d809
movb $0x0, %al
callq 0x33a0
jmp 0x10b25
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
cmpq $0x0, 0x10(%rax)
jne 0x10959
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x438d(%rip), %rsi      # 0x14b23
callq 0x3390
cmpl $0x0, %eax
je 0x107bd
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x3cd6(%rip), %rsi      # 0x14485
callq 0x3390
cmpl $0x0, %eax
jne 0x10871
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x18(%rbp), %rax
movl (%rax), %r8d
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl (%rax), %r9d
movq -0xa8(%rbp), %rax
leaq 0xc422(%rip), %rsi      # 0x1cc11
movq %rax, (%rsp)
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x100(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0xf4(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0x110(%rbp), %rdi
movq -0x108(%rbp), %rdx
movq -0x100(%rbp), %rcx
movl -0xf4(%rbp), %r8d
movq %rax, %r9
leaq 0xc334(%rip), %rsi      # 0x1cb99
movb $0x0, %al
callq 0x33a0
jmp 0x10920
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x18(%rbp), %rax
movl (%rax), %r8d
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl (%rax), %r9d
movq -0xa8(%rbp), %rax
leaq 0xc3b7(%rip), %rsi      # 0x1cc5a
movq %rax, (%rsp)
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x128(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x120(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x114(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0x130(%rbp), %rdi
movq -0x128(%rbp), %rdx
movq -0x120(%rbp), %rcx
movl -0x114(%rbp), %r8d
movq %rax, %r9
leaq 0xc2d9(%rip), %rsi      # 0x1cbf2
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %edx
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl (%rax), %ecx
leaq 0xc357(%rip), %rsi      # 0x1cc92
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
leaq 0xcebc(%rip), %rsi      # 0x1d809
movb $0x0, %al
callq 0x33a0
jmp 0x10b23
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x41bb(%rip), %rsi      # 0x14b23
callq 0x3390
cmpl $0x0, %eax
je 0x1098f
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x3b04(%rip), %rsi      # 0x14485
callq 0x3390
cmpl $0x0, %eax
jne 0x10a4c
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
leaq 0xc2f8(%rip), %rsi      # 0x1cca0
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xf140
movq -0x8(%rbp), %rdi
movq -0xa8(%rbp), %rdx
leaq 0xc1b0(%rip), %rsi      # 0x1cb7e
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x140(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x134(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0x150(%rbp), %rdi
movq -0x148(%rbp), %rdx
movq -0x140(%rbp), %rcx
movl -0x134(%rbp), %r8d
movq %rax, %r9
leaq 0xc159(%rip), %rsi      # 0x1cb99
movb $0x0, %al
callq 0x33a0
jmp 0x10b04
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rdx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
leaq 0xc25f(%rip), %rsi      # 0x1ccc4
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xf140
movq -0x8(%rbp), %rdi
movq -0xa8(%rbp), %rdx
leaq 0xc15c(%rip), %rsi      # 0x1cbe7
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x160(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x154(%rbp)
movq -0x10(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xcd60
movq -0x170(%rbp), %rdi
movq -0x168(%rbp), %rdx
movq -0x160(%rbp), %rcx
movl -0x154(%rbp), %r8d
movq %rax, %r9
leaq 0xc0f5(%rip), %rsi      # 0x1cbf2
movb $0x0, %al
callq 0x33a0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xf140
movq -0x8(%rbp), %rdi
leaq 0xcced(%rip), %rsi      # 0x1d809
movb $0x0, %al
callq 0x33a0
jmp 0x10b25
jmp 0x10b27
movq -0x10(%rbp), %rax
cmpl $0x5, 0x20(%rax)
jne 0x10b43
movq -0x8(%rbp), %rdi
leaq 0xbd32(%rip), %rsi      # 0x1c86e
movb $0x0, %al
callq 0x33a0
jmp 0x10b45
movq -0x10(%rbp), %rax
movsbl 0x9(%rax), %eax
cmpl $0x67, %eax
jne 0x10bad
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x62, %eax
jne 0x10b7e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edx
movq -0x10(%rbp), %rax
movl (%rax), %ecx
leaq 0xc170(%rip), %rsi      # 0x1cce7
movb $0x0, %al
callq 0x33a0
movq -0x10(%rbp), %rax
movsbl 0x8(%rax), %eax
cmpl $0x6f, %eax
jne 0x10bab
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edx
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
leaq 0xc15d(%rip), %rsi      # 0x1cd01
movb $0x0, %al
callq 0x33a0
jmp 0x10bad
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
nopw %cs:(%rax,%rax)