// File: /workspace/github_cpp_makefile_star2_O1/myudelson[P]hmm-scalable/HMMProblemSt.cpp
// Function: HMMProblemSt::doLinearStep(FitBitSt*, bool)
void HMMProblemSt::doLinearStep(FitBitSt *fb, bool direction) {
    NPAR i;
    NCAT l,k, nK = this->task->nK, skill1_n = this->skill1_n;
   // NDAT c = 0;
    
    // MOVED TO Cycle Bit
    // fb->scaleGradients(direction, this->active_set_block); // it knows whether to scale gradient or direction
    
    fb->PARAMcopy = init1D<NUMBER>(fb->nPARAM);
    fb->GRADcopy = init1D<NUMBER>(fb->nPARAM); // copy of gradient or direction, we will need just the grad's copy saved
    NUMBER * save_GRAD = init1D<NUMBER>((NDAT)fb->nPARAM); // save GRAD since while stepping it would be recomputed
    
    // all of the variables were single value, now we ad `_s` suffix and make them arrays
    NUMBER* e_s = initToValue1D<NUMBER>(nK,this->task->ArmijoSeed); // step seed
    bool* compliesArmijo_s = initToValue1D<bool>(nK, false);
    bool* compliesWolfe2_s = initToValue1D<bool>(nK, false); // second wolfe condition is turned on, if satisfied - honored, if not, just the 1st is used
//    NCAT n_compliesArmijo_or_Wolfe2 = 0;
//    NCAT n_e_lt_ArmijoMinStep = 0;
    NCAT n_compliesArmijo_or_compliesWolfe2_or_n_e_lt_ArmijoMinStep = 0;

    NUMBER* e_Armijo_s = initToValue1D<NUMBER>(nK,-1); // e (step size) at which Armijo (Wolfe 1) criterion is satisfied, 'cos both criterions are sometimes not met.
    NUMBER* f_xkplus1_Armijo_s = initToValue1D<NUMBER>(nK,0); // f_xkplus1_Armijo at which Armijo (Wolfe 1) criterion is satisfied, 'cos both criterions are sometimes not met.
    NUMBER* f_xk_s = initToValue1D<NUMBER>(nK,0);
    for(k=0; k<nK; k++) f_xk_s[k] = this->loglik_k[k];
    NUMBER* f_xkplus1_s = initToValue1D<NUMBER>(nK,0);
    NUMBER* p_k_by_neg_p_k_s = initToValue1D<NUMBER>(nK,0);
    NUMBER* p_k_by_neg_p_kp1_s = initToValue1D<NUMBER>(nK,0);

    cpy1D(fb->PARAM,fb->PARAMcopy,fb->nPARAM);
    if(!direction)
        cpy1D(fb->GRAD,fb->GRADcopy,fb->nPARAM);
    else {
        cpy1D(fb->DIR,fb->GRADcopy,fb->nPARAM); // in case we are using DIR, GRADcopy is the DIR
        // negate1D(fb->GRADcopy, fb->nPARAM); // negate, because we treat is as GRADient, direction has inverse direction
        // ^^ was already negated in the Conjugate part
    }
    cpy1D(fb->GRAD, save_GRAD, fb->nPARAM); // copy grads
    // compute p_k * -p_k for all k
    
    NCAT nK_active = 0, nK_active_local = 0 /*set to 1 later to be changed*/;
    
    for(k=0; k<nK; k++) {
        nK_active += this->active_set_block[k]>0;
        if(this->active_set_block[k]>0) {
            for(i=0; i<skill1_n; i++) {
                l = skill1_n*k + i;
                p_k_by_neg_p_k_s[k] -= fb->GRAD[l] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
            }
        }
    } // vvvv REDO
//    for(l=0; l<fb->nPARAM; l++) {
//        k = fb->param_blocks[l];
//        nK_active += this->active_set_block[k]>0;
//        if(this->active_set_block[k]>0) {
//            p_k_by_neg_p_k_s[k] -= fb->GRAD[l] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
//        }
//    }
    nK_active_local = nK_active;
    
    // copy active set for original values would be used locally
    NPAR * active_set_block_local = init1D<NPAR>((NDAT)nK);
    cpy1D(this->active_set_block, active_set_block_local, nK);
    
    int iter = 0; // limit iter steps to 20, via ArmijoMinStep (now 10)
    //while( n_compliesArmijo_or_Wolfe2<nK_active/*nK*/ && n_e_lt_ArmijoMinStep<nK_active/*nK*/ ) {
    while( nK_active_local > 0) { // n_compliesArmijo_or_compliesWolfe2_or_n_e_lt_ArmijoMinStep < nK_active/*nK*/) {
        nK_active_local = 0;
        // n_compliesArmijo_or_Wolfe2 = 0;
        // n_e_lt_ArmijoMinStep = 0;
        //n_compliesArmijo_or_compliesWolfe2_or_n_e_lt_ArmijoMinStep = 0;
        // step
//        c = 0;
//        for(k=0; k<nK; k++) {
//            if(this->active_set_block[k]>0) {
//                for(i=0; i<skill1_n; i++) {
//                    l = skill1_n*k + i;
//                    fb->PARAM[l] = fb->PARAMcopy[l] - e_s[k] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
////                    if(fb->PARAM[l]<0 || fb->PARAM[l]>1) {
////                        c++;
////                    }
//                }
//            }
//        } // vvvv REDO
        for(l=0; l<fb->nPARAM; l++) {
            k = fb->param_blocks[l];
            if(this->active_set_block[k]>0) {
                fb->PARAM[l] = fb->PARAMcopy[l] - e_s[k] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
            }
        }
        
//        if(c>0) {
//            fprintf(stderr, "ERROR! %d values are not within [0, 1] range!\n",c);
//        }

        // project parameters to simplex if needs be --- it's necessary here, since we might make frequent step back-tracks
        fb->projectToSimplex( this->non01constraints, this->active_set_block );
        
        // recompute gradients
        computeGradients();
        fb->scaleGradients(false, this->active_set_block);
        
        NCAT nK_deactiv = 0;
        NCAT nK_reactiv = 0;
        for(k=0; k<nK; k++) {
            if(this->active_set_block[k]>0) {
                // compute f(x_{k+1})
                f_xkplus1_s[k] = this->loglik_k[k];
                // compute Armijo compliance
                compliesArmijo_s[k] = (f_xkplus1_s[k] <= (f_xk_s[k] + (this->task->ArmijoC1 * e_s[k] * p_k_by_neg_p_k_s[k])));
                // compute Wolfe 2
                for(i=0; i<skill1_n; i++) {
                    l = skill1_n*k + i;
                    p_k_by_neg_p_kp1_s[k] -= fb->GRAD[l] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
                }
                compliesWolfe2_s[k] = (p_k_by_neg_p_kp1_s[k] >= this->task->ArmijoC2 * p_k_by_neg_p_k_s[k]);
                
                // decide
                if( compliesArmijo_s[k] && e_Armijo_s[k]==-1 ){
                    e_Armijo_s[k] = e_s[k]; // save the first time Armijo is statisfied, in case we'll roll back to it when Wolfe 2 is finally not satisfied
                    f_xkplus1_Armijo_s[k] = f_xkplus1_s[k];
                }
                // n_compliesArmijo_or_Wolfe2 += (compliesArmijo_s[k] || compliesWolfe2_s[k]);
                // n_e_lt_ArmijoMinStep += (e_s[k] <= this->task->ArmijoMinStep);
                if(compliesArmijo_s[k] || (compliesArmijo_s[k] && compliesWolfe2_s[k]) || (e_s[k] <= this->task->ArmijoMinStep)) {
                    this->active_set_block[k] = 0;
                    //nK_active--;
                    nK_deactiv++;
                    n_compliesArmijo_or_compliesWolfe2_or_n_e_lt_ArmijoMinStep++;// += (compliesArmijo_s[k] || compliesWolfe2_s[k] || (e_s[k] <= this->task->ArmijoMinStep));
                }
                else
                    e_s[k] /= this->task->ArmijoReduceFactor;
            }// if active
        }
        // rehash active set using reachability/connectivity
        // decide on active set (propagate dependencies)
        // this->task->connectivities[0] skill-skill
        for(k=0; k<nK; k++) {
            if(this->active_set_block[k]>0) {
                for(NCAT l=0; l<=nK; l++) {
                    if(l!=k && this->task->connectivities[0][k][l]==1 && this->active_set_block[l]==0) {
                        this->active_set_block[l] = 1;
                        //nK_active++;
                        nK_reactiv++;
                    }
                } // for all potential skills
            }
        }
        // coun active
        for(k=0; k<nK; k++) nK_active_local += this->active_set_block[k]>0;

        iter++;
    } // armijo loop
    
    // reinstate original active set
    cpy1D(active_set_block_local, this->active_set_block, nK);
    // reinstate original gradients
    cpy1D(save_GRAD, fb->GRAD, nK);

//    c = 0;
    for(k=0; k<nK; k++) {
        if(this->active_set_block[k]>0) {
            if(!compliesArmijo_s[k]) { // we couldn't step away from current, copy the inital point back
                e_s[k] = 0;
                f_xkplus1_s[k] = f_xk_s[k];
                cpy1D(&fb->PARAMcopy[k*skill1_n],&fb->PARAM[k*skill1_n],skill1_n);
            } else {
                if(compliesArmijo_s[k] && !compliesWolfe2_s[k]) { // we couldn't step away from current, copy the inital point back
                    e_s[k] = e_Armijo_s[k]; // return the first Armijo-compliant e
                    f_xkplus1_s[k] = f_xkplus1_Armijo_s[k]; // return the first Armijo-compliant f_xkplus1
                    // create new versions of FBS_PAR using e_Armijo as a step
//                    if(!direction) { // if step on GRAD not on DIR -- this is useless, why do it here
//                        cpy1D(&fb->GRADcopy[k*skill1_n],&fb->GRAD[k*skill1_n],skill1_n);
//                    }
                    // step
                    for(i=0; i<skill1_n; i++) {
                        l = skill1_n*k + i;
                        fb->PARAM[l] = fb->PARAMcopy[l] - e_s[k] * fb->GRADcopy[l]; // in case we are using DIR, GRADcopy is the DIR
//                        if(fb->PARAM[l]<0 || fb->PARAM[l]>1) {
//                            c++;
//                        }
                    }
                    // ^^^^^ end of create new versions of FBS_PAR using e_Armijo as a step
                }
            }
        }// if in active set
    }
    // project to simplex
//    if(c>0) {
//        fprintf(stderr, "ERROR! %d values are not within [0, 1] range!\n",c);
//    }
    fb->projectToSimplex( this->non01constraints, this->active_set_block );

//    nK_active = 0;                                                // DEBUG check for reinstatement
//    for(k=0; k<nK; k++) nK_active += this->active_set_block[k]>0; // DEBUG check for reinstatement
    
    // free memory (1)
    free(e_s);
    free(compliesArmijo_s);
    free(compliesWolfe2_s);
    free(e_Armijo_s);
    free(f_xkplus1_Armijo_s);
    free(f_xk_s);
    free(f_xkplus1_s);
    free(p_k_by_neg_p_k_s);
    free(p_k_by_neg_p_kp1_s);
    // free memory (2)
    free(active_set_block_local);
    free(fb->PARAMcopy);
    free(fb->GRADcopy);
    free(save_GRAD);
    fb->PARAMcopy = NULL;
    fb->GRADcopy = NULL;
    return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edx, 0x18(%rsp)
movq %rsi, %rbx
movq %rdi, %r15
movq 0x68(%rdi), %r14
movslq 0x908(%r14), %rbp
movslq 0x38(%rdi), %r13
movslq 0xc(%rsi), %r12
movl $0x8, %esi
movq %r12, %rdi
callq 0x2110
movq %rax, 0x50(%rsp)
movq %rax, 0x28(%rbx)
movl $0x8, %esi
movq %r12, %rdi
callq 0x2110
movq %rax, 0x38(%rsp)
movq %rax, 0x40(%rbx)
movl $0x8, %esi
movq %r12, 0x40(%rsp)
movq %r12, %rdi
callq 0x2110
movq %rax, %r12
movsd 0x970(%r14), %xmm0
movsd %xmm0, 0x10(%rsp)
movl $0x8, %esi
movq %rbp, %rdi
callq 0x2110
movsd 0x10(%rsp), %xmm0
testq %rbp, %rbp
jle 0xf370
xorl %ecx, %ecx
movsd %xmm0, (%rax,%rcx,8)
incq %rcx
cmpq %rcx, %rbp
jne 0xf363
movq %rax, 0x8(%rsp)
movl $0x1, %esi
movq %rbp, %rdi
movq %rbp, (%rsp)
callq 0x2110
movq (%rsp), %rdx
movq %rax, %r14
testl %edx, %edx
jle 0xf39f
movq %r14, %rdi
xorl %esi, %esi
callq 0x2100
movq (%rsp), %rdx
movq %r14, 0x30(%rsp)
movl $0x1, %esi
movq %rdx, %rdi
callq 0x2110
movq (%rsp), %rdx
movq %rax, %r14
testl %edx, %edx
jle 0xf3ca
movq %r14, %rdi
xorl %esi, %esi
callq 0x2100
movq (%rsp), %rdx
movq %r14, 0x28(%rsp)
movl $0x8, %esi
movq %rdx, %rdi
callq 0x2110
movq (%rsp), %rdi
testl %edi, %edi
jle 0xf3fc
xorl %edx, %edx
movabsq $-0x4010000000000000, %rcx # imm = 0xBFF0000000000000
movq %rcx, (%rax,%rdx,8)
incq %rdx
cmpq %rdx, %rdi
jne 0xf3f0
movq %rax, 0x20(%rsp)
movl $0x8, %esi
callq 0x2110
movq (%rsp), %rdi
movq %rax, %r14
testl %edi, %edi
jle 0xf42c
leaq (,%rdi,8), %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x2100
movq (%rsp), %rdi
testl %edi, %edi
jle 0xf44b
movq 0x80(%r15), %rsi
leaq (,%rdi,8), %rdx
movq %r14, %rdi
callq 0x2180
movq (%rsp), %rdi
movl $0x8, %esi
callq 0x2110
movq (%rsp), %rdi
movq %rax, %rbp
testl %edi, %edi
jle 0xf476
leaq (,%rdi,8), %rdx
movq %rbp, %rdi
xorl %esi, %esi
callq 0x2100
movq (%rsp), %rdi
movq %rbp, 0x10(%rsp)
movq %r14, 0x48(%rsp)
movl $0x8, %esi
movq %rdi, %r14
callq 0x2110
movq %rax, %rbp
testl %r14d, %r14d
jle 0xf4a7
leaq (,%r14,8), %rdx
movq %rbp, %rdi
xorl %esi, %esi
callq 0x2100
movq 0x10(%rbx), %rsi
movq 0x40(%rsp), %r14
shlq $0x3, %r14
movq 0x50(%rsp), %rdi
movq %r14, %rdx
callq 0x2180
leaq 0x48(%rbx), %rax
leaq 0x30(%rbx), %rcx
cmpb $0x0, 0x18(%rsp)
cmovneq %rax, %rcx
movq (%rcx), %rsi
movq 0x38(%rsp), %rdi
movq %r14, %rdx
callq 0x2180
movq 0x30(%rbx), %r14
movslq 0xc(%rbx), %rdx
shlq $0x3, %rdx
movq %r12, 0x38(%rsp)
movq %r12, %rdi
movq %r14, %rsi
callq 0x2180
xorl %r12d, %r12d
movq (%rsp), %rdi
testl %edi, %edi
jle 0xf587
movq 0x58(%r15), %rax
xorl %ecx, %ecx
movq 0x10(%rsp), %r9
testl %r13d, %r13d
setg %r8b
xorl %edx, %edx
cmpb $0x0, (%rax,%rcx)
setg %sil
andb %sil, %r8b
cmpb $0x1, %r8b
jne 0xf572
movq 0x40(%rbx), %r11
movsd (%r9,%rcx,8), %xmm0
movl %ecx, %r8d
imull %r13d, %r8d
xorl %r10d, %r10d
movb $0x1, %r9b
addl %r8d, %r10d
movslq %r10d, %r10
movsd (%r14,%r10,8), %xmm1
mulsd (%r11,%r10,8), %xmm1
subsd %xmm1, %xmm0
movsbl %r9b, %r10d
incb %r9b
cmpl %r10d, %r13d
jg 0xf545
movq 0x10(%rsp), %r9
movsd %xmm0, (%r9,%rcx,8)
movb %sil, %dl
addl %edx, %r12d
incq %rcx
cmpq %rdi, %rcx
jne 0xf514
testl %r12d, %r12d
setne %r12b
movl $0x1, %esi
callq 0x2110
movq 0x58(%r15), %rsi
movq %rax, 0x18(%rsp)
movq %rax, %rdi
movq (%rsp), %rdx
callq 0x2180
movq (%rsp), %rdx
testb %r12b, %r12b
movq 0x8(%rsp), %r10
je 0xf7ed
leal 0x1(%rdx), %r14d
movl %edx, %r12d
movslq 0xc(%rbx), %rax
testq %rax, %rax
jle 0xf60e
movq 0xb8(%rbx), %rcx
movq 0x58(%r15), %rdx
xorl %esi, %esi
movslq (%rcx,%rsi,4), %rdi
cmpb $0x0, (%rdx,%rdi)
jle 0xf606
movq 0x10(%rbx), %r8
movq 0x28(%rbx), %r9
movsd (%r9,%rsi,8), %xmm0
movsd (%r10,%rdi,8), %xmm1
movq 0x40(%rbx), %rdi
mulsd (%rdi,%rsi,8), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%r8,%rsi,8)
incq %rsi
cmpq %rsi, %rax
jne 0xf5d5
movzbl 0x50(%r15), %esi
movq 0x58(%r15), %rdx
movq %rbx, %rdi
callq 0x808a
movq (%r15), %rax
movq %r15, %rdi
callq *0x80(%rax)
movq 0x58(%r15), %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x7fda
movsd 0x2307(%rip), %xmm6     # 0x11948
movq 0x8(%rsp), %r10
movq (%rsp), %rdx
testl %edx, %edx
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %r8
movq 0x20(%rsp), %r9
jle 0xf778
xorl %eax, %eax
movq 0x58(%r15), %rcx
cmpb $0x0, (%rcx,%rax)
jle 0xf76c
movq 0x68(%r15), %r11
movq 0x80(%r15), %rsi
movsd (%rsi,%rax,8), %xmm1
movsd (%r10,%rax,8), %xmm0
movsd 0x958(%r11), %xmm2
mulsd %xmm0, %xmm2
movq 0x10(%rsp), %rsi
movsd (%rsi,%rax,8), %xmm3
mulsd %xmm3, %xmm2
movq 0x48(%rsp), %rsi
addsd (%rsi,%rax,8), %xmm2
ucomisd %xmm1, %xmm2
setae (%rdi,%rax)
testl %r13d, %r13d
jle 0xf710
movq 0x30(%rbx), %rsi
movq 0x40(%rbx), %rdi
movsd (%rbp,%rax,8), %xmm4
movl %eax, %r8d
imull %r13d, %r8d
xorl %r10d, %r10d
movb $0x1, %r9b
addl %r8d, %r10d
movslq %r10d, %r10
movsd (%rsi,%r10,8), %xmm5
mulsd (%rdi,%r10,8), %xmm5
subsd %xmm5, %xmm4
movsbl %r9b, %r10d
incb %r9b
cmpl %r10d, %r13d
jg 0xf6d4
movsd %xmm4, (%rbp,%rax,8)
movq 0x8(%rsp), %r10
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %r8
movq 0x20(%rsp), %r9
movsd (%rbp,%rax,8), %xmm4
mulsd 0x960(%r11), %xmm3
ucomisd %xmm3, %xmm4
setae (%r8,%rax)
ucomisd %xmm1, %xmm2
jb 0xf748
movsd (%r9,%rax,8), %xmm3
ucomisd %xmm6, %xmm3
jne 0xf742
jp 0xf742
movsd %xmm0, (%r9,%rax,8)
ucomisd %xmm1, %xmm2
jae 0xf768
movsd 0x978(%r11), %xmm1
ucomisd %xmm0, %xmm1
jae 0xf768
divsd 0x968(%r11), %xmm0
movsd %xmm0, (%r10,%rax,8)
jmp 0xf76c
movb $0x0, (%rcx,%rax)
incq %rax
cmpq %r12, %rax
jne 0xf663
testl %edx, %edx
jle 0xf7c5
xorl %eax, %eax
movq 0x58(%r15), %rcx
cmpb $0x0, (%rcx,%rax)
jle 0xf7bd
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0xf7b5
movq 0x68(%r15), %rsi
movq 0x8f0(%rsi), %rsi
movq (%rsi), %rsi
movq (%rsi,%rax,8), %rsi
cmpb $0x1, (%rsi,%rcx)
jne 0xf7b5
movq 0x58(%r15), %rsi
cmpb $0x0, (%rsi,%rcx)
jne 0xf7b5
movb $0x1, (%rsi,%rcx)
incq %rcx
cmpq %rcx, %r14
jne 0xf78a
incq %rax
cmpq %rdx, %rax
jne 0xf77e
testl %edx, %edx
jle 0xf7ed
movq 0x58(%r15), %rax
xorl %ecx, %ecx
xorl %edi, %edi
xorl %esi, %esi
cmpb $0x0, (%rax,%rcx)
setg %sil
addl %esi, %edi
incq %rcx
cmpq %rcx, %r12
jne 0xf7d1
testl %edi, %edi
jne 0xf5bf
movq 0x58(%r15), %rdi
movq 0x18(%rsp), %rsi
callq 0x2180
movq 0x30(%rbx), %rdi
movq (%rsp), %rdx
shlq $0x3, %rdx
movq 0x38(%rsp), %r12
movq %r12, %rsi
callq 0x2180
movq (%rsp), %r9
testl %r9d, %r9d
jle 0xf8ff
leaq (,%r13,8), %rax
movq %rax, 0x40(%rsp)
xorl %r14d, %r14d
movq 0x58(%r15), %rax
cmpb $0x0, (%rax,%r14)
jle 0xf8f3
movq 0x30(%rsp), %rax
cmpb $0x0, (%rax,%r14)
je 0xf8c2
movq 0x28(%rsp), %rax
cmpb $0x0, (%rax,%r14)
jne 0xf8f3
movq 0x20(%rsp), %rax
movsd (%rax,%r14,8), %xmm0
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax,%r14,8)
testl %r13d, %r13d
jle 0xf8f3
movq %r14, %rax
imulq %r13, %rax
movq 0x10(%rbx), %rcx
movq 0x28(%rbx), %rdx
movq 0x40(%rbx), %rsi
xorpd 0x210e(%rip), %xmm0     # 0x119a0
xorl %r8d, %r8d
movb $0x1, %dil
movslq %r8d, %r8
addq %rax, %r8
movsd (%rsi,%r8,8), %xmm1
mulsd %xmm0, %xmm1
addsd (%rdx,%r8,8), %xmm1
movsd %xmm1, (%rcx,%r8,8)
movsbl %dil, %r8d
incb %dil
cmpl %r8d, %r13d
jg 0xf898
jmp 0xf8f3
movq 0x8(%rsp), %rax
movq $0x0, (%rax,%r14,8)
movq %r14, %rdi
imulq %r13, %rdi
shlq $0x3, %rdi
movq 0x28(%rbx), %rsi
addq %rdi, %rsi
addq 0x10(%rbx), %rdi
movq 0x40(%rsp), %rdx
callq 0x2180
movq (%rsp), %r9
incq %r14
cmpq %r9, %r14
jne 0xf831
movzbl 0x50(%r15), %esi
movq 0x58(%r15), %rdx
movq %rbx, %rdi
callq 0x808a
movq 0x8(%rsp), %rdi
callq 0x2240
movq 0x30(%rsp), %rdi
callq 0x2240
movq 0x28(%rsp), %rdi
callq 0x2240
movq 0x20(%rsp), %rdi
callq 0x2240
movq 0x48(%rsp), %rdi
callq 0x2240
movq 0x10(%rsp), %rdi
callq 0x2240
movq %rbp, %rdi
callq 0x2240
movq 0x18(%rsp), %rdi
callq 0x2240
movq 0x28(%rbx), %rdi
callq 0x2240
movq 0x40(%rbx), %rdi
callq 0x2240
movq %r12, %rdi
callq 0x2240
xorl %eax, %eax
movq %rax, 0x28(%rbx)
movq %rax, 0x40(%rbx)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop