// File: xbai0624[P]dnn/src/ConstructLayer.cpp
// Function: ConstructLayer::UpdateWeightsAndBiasCNN()
void ConstructLayer::UpdateWeightsAndBiasCNN()
{
    // after finishing one training batch, update weights and bias gradient, (CNN layer)
    // cnn layer is different with FC layer. For FC layer, different 
    // neurons have different weights, however, for CNN layer, different
    // neurons in one image share the same weights and bias.
    // so when you are
    // using this function in layer class, you need to loop over every 
    // neuron for FC layer, but you should not loop over neruons in 
    // the same image for CNN layer, you should just use only one neuron,
    // any neuron would be fine, instead you need to loop over images. --- This is old design

    // after finishing one batch, update weights and bias, CNN layer
    size_t M = __imageDeltaFull.size(); // batch size
    if( M != __wGradient.size() ) {
        std::cout<<"Error: update FC weights, batch size not match."<<std::endl;
        exit(0);
    }

    // in case use drop out, need to filter out all inactive elements
    // Get filter Matrix from Filter2D structure
    assert(__activeFlag.size() == __weightMatrix.size());
    auto convertFilterToMatrix = [&](Filter2D & F) -> Matrix
    {
        auto dim = F.Dimension();
        Matrix _M(dim, 0);
        for(size_t i=0;i<dim.first;i++)
        {
            for(size_t j=0;j<dim.second;j++)
            {
                if(F[i][j]) _M[i][j] = 1;
            }
        }
        return _M;
    };

    // loop for kernel
    size_t nKernel = __weightMatrix.size();
    for(size_t k=0;k<nKernel;k++)
    {
        // 1) get gradient
        // gradient descent
        Matrix dw(__weightMatrix[k].Dimension());
        // loop for batch
        for(size_t i=0;i<M;i++){ 
            dw  = dw + __wGradient[i].OutputImageFromKernel[k];
        }
        if(__weights_optimizer == WeightsOptimizer::SGD)
        {
            // stochastic gradient descent
            dw = dw * double(__learningRate/(double)M); // gradients average over batch size
        }
        else if(__weights_optimizer == WeightsOptimizer::Adam)
        {
            // adam optimize
            dw = dw * (1./(double)M);
            dw = AdamOptimizer(dw, k);
        }
        else
        {
            std::cout<<__func__<<" Error: unsupported weights optimizer."<<std::endl;
            exit(0);
        }

        // Hadamard F to mask out all inactive elements
        Matrix F = convertFilterToMatrix(__activeFlag[k]);
        assert(F.Dimension() == (__weightMatrix[k]).Dimension());
        dw = dw^F; // for safe reason, mask out all inactive elements

        // regularization part
        //double f_regularization = 0;
        if(__regularizationMethod == Regularization::L2)
        {
            // obsolete
            //f_regularization = 1 - __learningRate * __regularizationParameter / (double)M;
            //(__weightMatrix[k]) = (__weightMatrix[k])*f_regularization;
            //(__weightMatrix[k]) = (__weightMatrix[k]) - dw;

            Matrix regularization_M = (__weightMatrix[k]^F) * (__learningRate * __regularizationParameter/((double)M));
            Matrix total_correction_M = regularization_M + dw; // dw already have learing rate multiplied
            __weightMatrix[k] = __weightMatrix[k] - total_correction_M;
        }
        else if(__regularizationMethod == Regularization::L1)
        {
            Matrix tmp = (__weightMatrixActive[k]);
            tmp(&SGN);
            tmp = tmp^F; // hadamard operation to mask out all inactive elements
            tmp = tmp * (__learningRate*__regularizationParameter/(double)M);
            //(*__w) = (*__w) - tmp - dw;
            (__weightMatrix[k]) = (__weightMatrix[k]) - dw;
            (__weightMatrix[k]) = (__weightMatrix[k]) - tmp;
        }
        else {
            std::cout<<"Error: update CNN weights, unsupported regularizaton method."<<std::endl;
            exit(0);
        }

        if(!__use_batch_normalization || 
                (__type != LayerType::cnn && __type != LayerType::fullyConnected && __type != LayerType::output))
        {
            // for cnn, output fc layers, if BN is not used, one need to update b paramter
            // if BN is used, then b prameter is discarded (combined into \beta paramter), no need to update b parmater
            // update bias
            Matrix db(1, 1);
            // loop for batch
            for(size_t i=0;i<M;i++){
                db = db + __bGradient[i].OutputImageFromKernel[k];
            }
            db = db * double(__learningRate / (double)M);
            __biasVector[k] = __biasVector[k] - db;
        }
    }
}

// Assembly:
subq $0x2b8, %rsp            # imm = 0x2B8
movq %rdi, 0x2b0(%rsp)
movq 0x2b0(%rsp), %rdi
movq %rdi, 0x50(%rsp)
addq $0x1e0, %rdi            # imm = 0x1E0
callq 0x1ff40
movq 0x50(%rsp), %rdi
movq %rax, 0x2a8(%rsp)
movq 0x2a8(%rsp), %rax
movq %rax, 0x58(%rsp)
addq $0x90, %rdi
callq 0x1ff40
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
je 0x17474
movq 0x53b86(%rip), %rdi     # 0x6afd8
leaq 0x3c14b(%rip), %rsi     # 0x535a4
callq 0x4230
movq %rax, %rdi
movq 0x53b48(%rip), %rsi     # 0x6afb0
callq 0x4260
xorl %edi, %edi
callq 0x4290
movq 0x50(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x1ffd0
movq 0x50(%rsp), %rdi
movq %rax, 0x48(%rsp)
addq $0x60, %rdi
callq 0x1f9c0
movq %rax, %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
jne 0x174a7
jmp 0x174c6
leaq 0x3c38a(%rip), %rdi     # 0x53838
leaq 0x3ad1d(%rip), %rsi     # 0x521d2
movl $0xe04, %edx            # imm = 0xE04
leaq 0x3c3a4(%rip), %rcx     # 0x53865
callq 0x4170
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
callq 0x1f9c0
movq %rax, 0x298(%rsp)
movq $0x0, 0x290(%rsp)
movq 0x290(%rsp), %rax
cmpq 0x298(%rsp), %rax
jae 0x18135
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
callq 0x3bae0
movq %rax, 0x268(%rsp)
movq %rdx, 0x270(%rsp)
movq 0x268(%rsp), %rsi
movq 0x270(%rsp), %rdx
leaq 0x278(%rsp), %rdi
callq 0x3b4a0
movq $0x0, 0x260(%rsp)
movq 0x260(%rsp), %rax
cmpq 0x2a8(%rsp), %rax
jae 0x1762a
movq 0x50(%rsp), %rdi
addq $0x90, %rdi
movq 0x260(%rsp), %rsi
callq 0x1fd40
movq %rax, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdx
leaq 0x248(%rsp), %rdi
leaq 0x278(%rsp), %rsi
callq 0x3bf90
jmp 0x175ae
leaq 0x278(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x1fa20
jmp 0x175c5
leaq 0x248(%rsp), %rdi
callq 0x3bb80
movq 0x260(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x260(%rsp)
jmp 0x17555
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x18126
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x248(%rsp), %rdi
callq 0x3bb80
jmp 0x18126
movq 0x50(%rsp), %rax
cmpl $0x0, 0x440(%rax)
jne 0x176de
movq 0x50(%rsp), %rax
movsd 0xc0(%rax), %xmm0
movaps 0x3aa10(%rip), %xmm2    # 0x52060
movq 0x2a8(%rsp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x3aa0b(%rip), %xmm2    # 0x52070
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
leaq 0x220(%rsp), %rdi
leaq 0x278(%rsp), %rsi
callq 0x3cfd0
jmp 0x1768f
leaq 0x278(%rsp), %rdi
leaq 0x220(%rsp), %rsi
callq 0x1fa20
jmp 0x176a6
leaq 0x220(%rsp), %rdi
callq 0x3bb80
jmp 0x17848
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x220(%rsp), %rdi
callq 0x3bb80
jmp 0x18126
movq 0x50(%rsp), %rax
cmpl $0x1, 0x440(%rax)
jne 0x177fa
movaps 0x3a969(%rip), %xmm0    # 0x52060
movq 0x2a8(%rsp), %xmm1
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movapd 0x3a964(%rip), %xmm0    # 0x52070
subpd %xmm0, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movsd 0x3a8e5(%rip), %xmm0    # 0x52008
divsd %xmm1, %xmm0
leaq 0x208(%rsp), %rdi
leaq 0x278(%rsp), %rsi
callq 0x3cfd0
jmp 0x1773e
leaq 0x278(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x1fa20
jmp 0x17755
leaq 0x208(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rsi
movl 0x290(%rsp), %ecx
leaq 0x1f0(%rsp), %rdi
leaq 0x278(%rsp), %rdx
callq 0x19340
jmp 0x17785
leaq 0x278(%rsp), %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x1fa20
jmp 0x1779c
leaq 0x1f0(%rsp), %rdi
callq 0x3bb80
jmp 0x17846
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x3bb80
jmp 0x18126
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x1f0(%rsp), %rdi
callq 0x3bb80
jmp 0x18126
movq 0x537d7(%rip), %rdi     # 0x6afd8
leaq 0x3c08c(%rip), %rsi     # 0x53894
callq 0x4230
movq %rax, 0x40(%rsp)
jmp 0x17814
movq 0x40(%rsp), %rdi
leaq 0x3c08c(%rip), %rsi     # 0x538ac
callq 0x4230
movq %rax, 0x38(%rsp)
jmp 0x1782c
movq 0x38(%rsp), %rdi
movq 0x53778(%rip), %rsi     # 0x6afb0
callq 0x4260
jmp 0x1783f
xorl %edi, %edi
callq 0x4290
jmp 0x17848
movq 0x50(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq 0x290(%rsp), %rsi
callq 0x1ff80
movq %rax, %rdx
leaq 0x1d8(%rsp), %rdi
leaq 0x2a7(%rsp), %rsi
callq 0x19fe0
jmp 0x1787b
leaq 0x1d8(%rsp), %rdi
callq 0x3bae0
movq %rdx, 0x28(%rsp)
movq %rax, 0x30(%rsp)
jmp 0x17894
movq 0x50(%rsp), %rdi
movq 0x28(%rsp), %rax
movq 0x30(%rsp), %rcx
movq %rcx, 0x1c8(%rsp)
movq %rax, 0x1d0(%rsp)
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
callq 0x3bae0
movq %rdx, 0x18(%rsp)
movq %rax, 0x20(%rsp)
jmp 0x178d8
movq 0x18(%rsp), %rax
movq 0x20(%rsp), %rcx
movq %rcx, 0x1b8(%rsp)
movq %rax, 0x1c0(%rsp)
movq 0x1c8(%rsp), %rdi
movq 0x1d0(%rsp), %rsi
movq 0x1b8(%rsp), %rdx
movq 0x1c0(%rsp), %rcx
callq 0x3b180
movb %al, 0x17(%rsp)
jmp 0x1791d
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0x17927
jmp 0x17929
jmp 0x17961
leaq 0x3bfa3(%rip), %rdi     # 0x538d3
leaq 0x3a89b(%rip), %rsi     # 0x521d2
movl $0xe31, %edx            # imm = 0xE31
leaq 0x3bf22(%rip), %rcx     # 0x53865
callq 0x4170
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x18119
leaq 0x1a0(%rsp), %rdi
leaq 0x278(%rsp), %rsi
leaq 0x1d8(%rsp), %rdx
callq 0x3c680
jmp 0x17980
leaq 0x278(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x1fa20
jmp 0x17997
leaq 0x1a0(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rax
cmpl $0x0, 0xc8(%rax)
jne 0x17bad
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0x170(%rsp), %rdi
leaq 0x1d8(%rsp), %rdx
callq 0x3c680
jmp 0x179e6
movq 0x50(%rsp), %rax
movsd 0xc0(%rax), %xmm0
movsd 0xd0(%rax), %xmm1
mulsd %xmm1, %xmm0
movaps 0x3a65a(%rip), %xmm2    # 0x52060
movq 0x2a8(%rsp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x3a655(%rip), %xmm2    # 0x52070
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
leaq 0x188(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x3cfd0
jmp 0x17a45
leaq 0x170(%rsp), %rdi
callq 0x3bb80
leaq 0x158(%rsp), %rdi
leaq 0x188(%rsp), %rsi
leaq 0x278(%rsp), %rdx
callq 0x3bf90
jmp 0x17a71
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0x140(%rsp), %rdi
leaq 0x158(%rsp), %rdx
callq 0x3c480
jmp 0x17aa1
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
leaq 0x140(%rsp), %rsi
callq 0x1fa20
jmp 0x17ac9
leaq 0x140(%rsp), %rdi
callq 0x3bb80
leaq 0x158(%rsp), %rdi
callq 0x3bb80
leaq 0x188(%rsp), %rdi
callq 0x3bb80
jmp 0x17e8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x1a0(%rsp), %rdi
callq 0x3bb80
jmp 0x18119
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x3bb80
jmp 0x18119
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x17b9b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x17b8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x3bb80
leaq 0x158(%rsp), %rdi
callq 0x3bb80
leaq 0x188(%rsp), %rdi
callq 0x3bb80
jmp 0x18119
movq 0x50(%rsp), %rax
cmpl $0x1, 0xc8(%rax)
jne 0x17e57
movq 0x50(%rsp), %rdi
addq $0xd8, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0x128(%rsp), %rdi
callq 0x3b810
jmp 0x17bea
leaq 0x239f(%rip), %rsi      # 0x19f90
leaq 0x128(%rsp), %rdi
callq 0x3dc20
jmp 0x17c00
leaq 0x110(%rsp), %rdi
leaq 0x128(%rsp), %rsi
leaq 0x1d8(%rsp), %rdx
callq 0x3c680
jmp 0x17c1f
leaq 0x128(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x1fa20
jmp 0x17c36
leaq 0x110(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rax
movsd 0xc0(%rax), %xmm0
movsd 0xd0(%rax), %xmm1
mulsd %xmm1, %xmm0
movaps 0x3a3fd(%rip), %xmm2    # 0x52060
movq 0x2a8(%rsp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x3a3f8(%rip), %xmm2    # 0x52070
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
leaq 0xf8(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x3cfd0
jmp 0x17ca2
leaq 0x128(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x1fa20
jmp 0x17cb9
leaq 0xf8(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0xe0(%rsp), %rdi
leaq 0x278(%rsp), %rdx
callq 0x3c480
jmp 0x17cf6
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
leaq 0xe0(%rsp), %rsi
callq 0x1fa20
jmp 0x17d1e
leaq 0xe0(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0xc8(%rsp), %rdi
leaq 0x128(%rsp), %rdx
callq 0x3c480
jmp 0x17d5b
movq 0x50(%rsp), %rdi
addq $0x60, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
leaq 0xc8(%rsp), %rsi
callq 0x1fa20
jmp 0x17d83
leaq 0xc8(%rsp), %rdi
callq 0x3bb80
leaq 0x128(%rsp), %rdi
callq 0x3bb80
jmp 0x17e8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x17e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x3bb80
jmp 0x17e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0x3bb80
jmp 0x17e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x3bb80
jmp 0x17e45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0x3bb80
leaq 0x128(%rsp), %rdi
callq 0x3bb80
jmp 0x18119
movq 0x5317a(%rip), %rdi     # 0x6afd8
leaq 0x3ba9f(%rip), %rsi     # 0x53904
callq 0x4230
movq %rax, 0x8(%rsp)
jmp 0x17e71
movq 0x8(%rsp), %rdi
movq 0x53133(%rip), %rsi     # 0x6afb0
callq 0x4260
jmp 0x17e84
xorl %edi, %edi
callq 0x4290
jmp 0x17e8d
movq 0x50(%rsp), %rax
testb $0x1, 0x210(%rax)
je 0x17ec8
movq 0x50(%rsp), %rax
cmpl $0x1, 0xc(%rax)
je 0x180e6
movq 0x50(%rsp), %rax
cmpl $0x0, 0xc(%rax)
je 0x180e6
movq 0x50(%rsp), %rax
cmpl $0x4, 0xc(%rax)
je 0x180e6
leaq 0xb0(%rsp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x3b3b0
jmp 0x17edf
movq $0x0, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
cmpq 0x2a8(%rsp), %rax
jae 0x17fc0
movq 0x50(%rsp), %rdi
addq $0xa8, %rdi
movq 0xa8(%rsp), %rsi
callq 0x1fd40
movq %rax, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdx
leaq 0x90(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x3bf90
jmp 0x17f44
leaq 0xb0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x1fa20
jmp 0x17f5b
leaq 0x90(%rsp), %rdi
callq 0x3bb80
movq 0xa8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa8(%rsp)
jmp 0x17eeb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
jmp 0x180d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x3bb80
jmp 0x180d7
movq 0x50(%rsp), %rax
movsd 0xc0(%rax), %xmm0
movaps 0x3a08c(%rip), %xmm2    # 0x52060
movq 0x2a8(%rsp), %xmm1
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x3a087(%rip), %xmm2    # 0x52070
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
leaq 0x78(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x3cfd0
jmp 0x18010
leaq 0xb0(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x1fa20
jmp 0x18024
leaq 0x78(%rsp), %rdi
callq 0x3bb80
movq 0x50(%rsp), %rdi
addq $0x78, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rsi
leaq 0x60(%rsp), %rdi
leaq 0xb0(%rsp), %rdx
callq 0x3c480
jmp 0x1805b
movq 0x50(%rsp), %rdi
addq $0x78, %rdi
movq 0x290(%rsp), %rsi
callq 0x1f9e0
movq %rax, %rdi
leaq 0x60(%rsp), %rsi
callq 0x1fa20
jmp 0x18080
leaq 0x60(%rsp), %rdi
callq 0x3bb80
leaq 0xb0(%rsp), %rdi
callq 0x3bb80
jmp 0x180e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x3bb80
jmp 0x180d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x240(%rsp)
movl %eax, 0x23c(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x3bb80
leaq 0xb0(%rsp), %rdi
callq 0x3bb80
jmp 0x18119
leaq 0x1d8(%rsp), %rdi
callq 0x3bb80
leaq 0x278(%rsp), %rdi
callq 0x3bb80
movq 0x290(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x290(%rsp)
jmp 0x174e8
leaq 0x1d8(%rsp), %rdi
callq 0x3bb80
leaq 0x278(%rsp), %rdi
callq 0x3bb80
jmp 0x1813d
addq $0x2b8, %rsp            # imm = 0x2B8
retq
movq 0x240(%rsp), %rdi
callq 0x43f0
nopw (%rax,%rax)