// File: /workspace/github_cpp_makefile_star2_O3/xbai0624[P]dnn/src/ConstructLayer.cpp
// Function: ConstructLayer::UpdateWeightsAndBiasFC()
void ConstructLayer::UpdateWeightsAndBiasFC()
{
    //cout<<__func__<<" started..."<<endl;
    // after finishing one batch, update weights and bias, for FC layer
    size_t M = __imageDeltaFull.size(); // batch size
    if( M != __wGradient.size() ) {
        std::cout<<__func__<<" Error: update FC weights, batch size not match."<<std::endl;
        std::cout<<"           weight gradient batch size: "<<__wGradient.size()<<std::endl;
        std::cout<<"           delta image batch size: "<<__imageDeltaFull.size()<<std::endl;
        exit(0);
    }
    if( __wGradient[0].OutputImageFromKernel.size() != 1 || __bGradient[0].OutputImageFromKernel.size()!=1) 
    {
        std::cout<<__func__<<" Error: update FC weiths, more than 1 w gradient matrix found."
            <<std::endl;
        exit(0);
    }

    // gradient descent
    if(__weightMatrix.size() != __neuronDim.k) {
        std::cout<<__func__<<" Error: update FC layer weights, more than 1 weight matrix found."<<std::endl;
        std::cout<<"__weightMatrix size: "<<__weightMatrix.size()<<std::endl;
        std::cout<<"neuron dimension: "<<__neuronDim<<std::endl;
        exit(0);
    }
    Matrix dw((__weightMatrix[0]).Dimension(), 0); 
    for(size_t i=0;i<M;i++){ // sum x (batches)
        dw  = dw + __wGradient[i].OutputImageFromKernel[0];
        //cout<<__wGradient[i].OutputImageFromKernel[0]<<endl;
        //cout<<i<<" before sum"<<endl;
        //getchar();
    }

    if(__weights_optimizer == WeightsOptimizer::SGD)
    {
        // standard SGD 
        dw = dw * double(__learningRate/(double)M); // over batch 
    }
    else if(__weights_optimizer == WeightsOptimizer::Adam)
    {
        // Adam optimizer
        dw = dw * (1./ (double)M );

        //Matrix tmp = dw * __learningRate;
        //cout<<"Before adam: "<<endl<<dw<<endl;
        dw = AdamOptimizer(dw, 0);
        //cout<<"after adam: "<<endl<<dw<<endl;
        //getchar();
    }
    else
    {
        std::cout<<__func__<<" Error: unsupported optimization method."<<std::endl;
        exit(0);
    }
    //cout<<"learning rate: "<<double(__learningRate/(double)M)<<endl;

    // Get filter Matrix for masking Regularization item
    assert(__activeFlag.size() == 1);
    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;
    };
    Matrix currentLayerFilter = convertFilterToMatrix(__activeFlag[0]);
    //cout<<currentLayerFilter.Dimension()<<endl;
    Matrix prevLayerFilter(1, dw.Dimension().second, 1);
    //cout<<"before: "<<endl<<prevLayerFilter<<endl;

    if(__prevLayer->GetType() == LayerType::input) // only fc layer need this, other layers won't affect
    {
        auto & prevLayerFilters = __prevLayer->GetActiveFlag();
        assert(prevLayerFilters.size() == 1);
        assert(prevLayerFilters[0].Dimension().first == (size_t)__prevLayer->GetNumberOfNeurons());

        Matrix filter = convertFilterToMatrix(prevLayerFilters[0]);
        prevLayerFilter = filter.Transpose();
        //cout<<"after: "<<endl<<prevLayerFilter<<endl;
    }

    // following is two flag matrix (dim[n,1] x dim[1, m], with bool elements) product
    // all the elements of the product will be either 0 or 1
    // this product can be used to mask out disabled elements in weight matrix regularization
    Matrix F = currentLayerFilter * prevLayerFilter;
    //cout<<F<<endl;
    //cout<<prevLayerFilter<<endl;
    //cout<<dw<<endl;
    //getchar();

    assert(F.Dimension() == (__weightMatrix[0]).Dimension());
    // Regularization
    //double f_regularization = 0.;
    if(__regularizationMethod == Regularization::L2) 
    {
        // obsolete
        //f_regularization = 1 - __learningRate * __regularizationParameter / M;
        //(__weightMatrix[0]) = (__weightMatrix[0]) * f_regularization - dw;

        // new
        // hadamard multiply with F to maks out all inactive elements
        Matrix regularization_M = (__weightMatrix[0]^F) *(__learningRate * __regularizationParameter/((double)M)); 
        Matrix total_correction_M = regularization_M + dw; // dw already include learning rate during generation
        __weightMatrix[0] = __weightMatrix[0] - total_correction_M;
    } 
    else if(__regularizationMethod == Regularization::L1) 
    {
        Matrix _t = (__weightMatrix[0]); // make a copy of weight matrix
        _t(&SGN); // get the sign for each element in weight matrix
        _t = _t^F; // hadamard operation to mask out all inactive elements
        _t = _t * (__learningRate*__regularizationParameter/(double)M); // L1 regularization part
        (__weightMatrix[0]) = (__weightMatrix[0]) -  _t; // apply L1 regularization to weight matrix
        (__weightMatrix[0]) = (__weightMatrix[0]) - dw; // apply gradient decsent part
    } 
    else 
    {
        std::cout<<__func__<<" Error: update FC weights, unsupported regularization."<<std::endl;
        exit(0);
    }

    //cout<<"reached hrere..."<<endl;

    if(!__use_batch_normalization || 
            (__type != LayerType::cnn && __type != LayerType::fullyConnected && __type != LayerType::output))
    {
        // for cnn, fc, output layers, if BN is not used, one need to update b paramter.
        // if BN is used, b parameter is discarded (combined into \beta parameter)
        // bias
        Matrix db(__biasVector[0].Dimension());
        for(size_t i=0;i<M;i++){
            db = db + __bGradient[i].OutputImageFromKernel[0];
        }
        db = db / (double)M;
        db = db * __learningRate;
        __biasVector[0] = __biasVector[0] - db;
    }
    //cout<<__func__<<" ended.."<<endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdi, %rbx
movq 0x1e8(%rdi), %r14
movq 0x1e0(%rdi), %r12
movq %r14, %r13
subq %r12, %r13
movabsq $-0x5555555555555555, %r15 # imm = 0xAAAAAAAAAAAAAAAB
movq 0x90(%rdi), %rax
movq 0x98(%rdi), %rcx
subq %rax, %rcx
cmpq %rcx, %r13
jne 0xf20a
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq $0x18, %rcx
jne 0xf1e3
movq 0xa8(%rbx), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq $0x18, %rcx
jne 0xf1e3
movq 0x60(%rbx), %rdi
movq 0x68(%rbx), %rax
subq %rdi, %rax
sarq $0x3, %rax
imulq %r15, %rax
cmpq 0x3a8(%rbx), %rax
jne 0xf29b
sarq $0x3, %r13
imulq %r15, %r13
callq 0x1abb8
leaq 0x48(%rsp), %rdi
xorpd %xmm0, %xmm0
movq %rax, %rsi
callq 0x1a92c
movq %r14, 0x78(%rsp)
movq %r12, 0x90(%rsp)
cmpq %r12, %r14
je 0xec80
cmpq $0x1, %r13
movq %r13, %r12
adcq $0x0, %r12
xorl %ebp, %ebp
leaq 0x30(%rsp), %r14
leaq 0x48(%rsp), %r15
movq 0x90(%rbx), %rax
movq (%rax,%rbp), %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0x1ae34
movq %r15, %rdi
movq %r14, %rsi
callq 0x14e2c
movq %r14, %rdi
callq 0x1abf2
addq $0x18, %rbp
decq %r12
jne 0xec4e
movl 0x440(%rbx), %eax
movq %r13, %xmm1
testl %eax, %eax
movdqa %xmm1, 0x80(%rsp)
je 0xed31
cmpl $0x1, %eax
jne 0xf365
movapd 0x80(%rsp), %xmm0
unpcklps 0x1838b(%rip), %xmm0    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x18393(%rip), %xmm0    # 0x27050
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x188af(%rip), %xmm0    # 0x27580
divsd %xmm1, %xmm0
leaq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x1b70c
leaq 0x48(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x14e2c
movq 0x78(%rsp), %rbp
leaq 0x30(%rsp), %rdi
callq 0x1abf2
leaq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rdx
movq %rbx, %rsi
xorl %ecx, %ecx
callq 0x107d2
leaq 0x48(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x14e2c
leaq 0x30(%rsp), %rdi
callq 0x1abf2
jmp 0xed86
movsd 0xc0(%rbx), %xmm0
punpckldq 0x182ff(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x18307(%rip), %xmm1    # 0x27050
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
leaq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x1b70c
leaq 0x48(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x14e2c
leaq 0x30(%rsp), %rdi
callq 0x1abf2
movq 0x78(%rsp), %rbp
movq 0x108(%rbx), %rsi
movq 0x110(%rbx), %rax
subq %rsi, %rax
cmpq $0x18, %rax
jne 0xf327
leaq 0x30(%rsp), %rdi
callq 0x10d26
leaq 0x48(%rsp), %rdi
callq 0x1abb8
leaq 0x98(%rsp), %rdi
movsd 0x187bb(%rip), %xmm0    # 0x27580
movl $0x1, %esi
callq 0x1a892
movq 0x3f0(%rbx), %rdi
movq (%rdi), %rax
callq *0x250(%rax)
cmpl $0x3, %eax
jne 0xee88
movq 0x3f0(%rbx), %rdi
movq (%rdi), %rax
callq *0x268(%rax)
movq %rax, %r14
movq (%rax), %rax
movq 0x8(%r14), %rcx
subq %rax, %rcx
cmpq $0x18, %rcx
jne 0xf3a6
movq (%rax), %r12
movq 0x8(%rax), %r15
movq 0x3f0(%rbx), %rdi
movq (%rdi), %rax
callq *0x278(%rax)
subq %r12, %r15
sarq $0x3, %r15
movabsq $-0x3333333333333333, %rcx # imm = 0xCCCCCCCCCCCCCCCD
imulq %r15, %rcx
cltq
cmpq %rax, %rcx
jne 0xf3c5
movq (%r14), %rsi
leaq 0x60(%rsp), %rdi
callq 0x10d26
leaq 0x18(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x1c5e2
leaq 0x98(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x14e2c
leaq 0x18(%rsp), %rdi
callq 0x1abf2
leaq 0x60(%rsp), %rdi
callq 0x1abf2
leaq 0x60(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x1ac04
leaq 0x60(%rsp), %rdi
callq 0x1abb8
movq %rax, %r14
movq %rdx, %r15
movq 0x60(%rbx), %rdi
callq 0x1abb8
movq %rdx, %rcx
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x1a5e0
testb %al, %al
je 0xf346
movl 0xc8(%rbx), %eax
cmpl $0x1, %eax
je 0xef8f
testl %eax, %eax
jne 0xf3e4
movq 0x60(%rbx), %rsi
movq %rsp, %rdi
leaq 0x60(%rsp), %rdx
callq 0x1b1ee
movsd 0xc0(%rbx), %xmm0
mulsd 0xd0(%rbx), %xmm0
movapd 0x80(%rsp), %xmm1
unpcklps 0x18127(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1812f(%rip), %xmm1    # 0x27050
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
leaq 0x18(%rsp), %rdi
movq %rsp, %rsi
callq 0x1b70c
movq %rsp, %rdi
callq 0x1abf2
movq %rsp, %rdi
leaq 0x18(%rsp), %rsi
leaq 0x48(%rsp), %rdx
callq 0x1ae34
movq 0x60(%rbx), %rsi
leaq 0xb0(%rsp), %rdi
movq %rsp, %rdx
callq 0x1b0ec
movq 0x60(%rbx), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x14e2c
leaq 0xb0(%rsp), %rdi
callq 0x1abf2
jmp 0xf071
movq 0x60(%rbx), %rsi
leaq 0x18(%rsp), %rdi
callq 0x1aa3e
leaq 0x1ec1(%rip), %rsi      # 0x10e65
leaq 0x18(%rsp), %rdi
callq 0x1bf18
movq %rsp, %rdi
leaq 0x18(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x1b1ee
leaq 0x18(%rsp), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
movsd 0xc0(%rbx), %xmm0
mulsd 0xd0(%rbx), %xmm0
movapd 0x80(%rsp), %xmm1
unpcklps 0x1804b(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x18053(%rip), %xmm1    # 0x27050
movapd %xmm1, %xmm2
unpckhpd %xmm1, %xmm2            # xmm2 = xmm2[1],xmm1[1]
addsd %xmm1, %xmm2
divsd %xmm2, %xmm0
movq %rsp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x1b70c
leaq 0x18(%rsp), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
movq 0x60(%rbx), %rsi
movq %rsp, %rdi
leaq 0x18(%rsp), %rdx
callq 0x1b0ec
movq 0x60(%rbx), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
movq 0x60(%rbx), %rsi
movq %rsp, %rdi
leaq 0x48(%rsp), %rdx
callq 0x1b0ec
movq 0x60(%rbx), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
leaq 0x18(%rsp), %rdi
callq 0x1abf2
cmpb $0x1, 0x210(%rbx)
jne 0xf0a2
movl 0xc(%rbx), %eax
cmpl $0x4, %eax
ja 0xf0a2
movl $0x13, %ecx
btl %eax, %ecx
jb 0xf1a6
movq 0x78(%rbx), %rdi
callq 0x1abb8
leaq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x1a800
cmpq 0x90(%rsp), %rbp
je 0xf107
cmpq $0x1, %r13
adcq $0x0, %r13
xorl %r12d, %r12d
movq %rsp, %r14
leaq 0x18(%rsp), %r15
movq 0xa8(%rbx), %rax
movq (%rax,%r12), %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0x1ae34
movq %r15, %rdi
movq %r14, %rsi
callq 0x14e2c
movq %r14, %rdi
callq 0x1abf2
addq $0x18, %r12
decq %r13
jne 0xf0d5
movapd 0x80(%rsp), %xmm1
unpcklps 0x17f29(%rip), %xmm1    # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x17f31(%rip), %xmm1    # 0x27050
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movq %rsp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x1b7c8
leaq 0x18(%rsp), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
movsd 0xc0(%rbx), %xmm0
movq %rsp, %rdi
leaq 0x18(%rsp), %rsi
callq 0x1b70c
leaq 0x18(%rsp), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
movq 0x78(%rbx), %rsi
movq %rsp, %rdi
leaq 0x18(%rsp), %rdx
callq 0x1b0ec
movq 0x78(%rbx), %rdi
movq %rsp, %rsi
callq 0x14e2c
movq %rsp, %rdi
callq 0x1abf2
leaq 0x18(%rsp), %rdi
callq 0x1abf2
leaq 0x60(%rsp), %rdi
callq 0x1abf2
leaq 0x98(%rsp), %rdi
callq 0x1abf2
leaq 0x30(%rsp), %rdi
callq 0x1abf2
leaq 0x48(%rsp), %rdi
callq 0x1abf2
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x27dee(%rip), %rdi     # 0x36fd8
leaq 0x198d4(%rip), %rsi     # 0x28ac5
callq 0x4260
leaq 0x1995c(%rip), %rsi     # 0x28b59
movq %rax, %rdi
callq 0x4260
jmp 0xf318
movq 0x27dc7(%rip), %r14     # 0x36fd8
leaq 0x198ad(%rip), %rsi     # 0x28ac5
movq %r14, %rdi
callq 0x4260
leaq 0x198b5(%rip), %rsi     # 0x28adc
movq %rax, %rdi
callq 0x4260
movq %rax, %rdi
callq 0x4100
leaq 0x198cf(%rip), %rsi     # 0x28b0d
movq %r14, %rdi
callq 0x4260
movq 0x98(%rbx), %rsi
subq 0x90(%rbx), %rsi
sarq $0x3, %rsi
imulq %r15, %rsi
movq %rax, %rdi
callq 0x4090
movq %rax, %rdi
callq 0x4100
leaq 0x198c2(%rip), %rsi     # 0x28b35
movq %r14, %rdi
callq 0x4260
movq 0x1e8(%rbx), %rsi
subq 0x1e0(%rbx), %rsi
sarq $0x3, %rsi
imulq %r15, %rsi
movq %rax, %rdi
callq 0x4090
jmp 0xf318
leaq 0x398(%rbx), %r14
movq 0x27d2f(%rip), %r12     # 0x36fd8
leaq 0x19815(%rip), %rsi     # 0x28ac5
movq %r12, %rdi
callq 0x4260
leaq 0x198d9(%rip), %rsi     # 0x28b98
movq %rax, %rdi
callq 0x4260
movq %rax, %rdi
callq 0x4100
leaq 0x19904(%rip), %rsi     # 0x28bda
movq %r12, %rdi
callq 0x4260
movq 0x68(%rbx), %rsi
subq 0x60(%rbx), %rsi
sarq $0x3, %rsi
imulq %r15, %rsi
movq %rax, %rdi
callq 0x4090
movq %rax, %rdi
callq 0x4100
leaq 0x198eb(%rip), %rsi     # 0x28bf0
movq %r12, %rdi
callq 0x4260
movq %rax, %rdi
movq %r14, %rsi
callq 0x1a33e
movq %rax, %rdi
callq 0x4100
xorl %edi, %edi
callq 0x4290
leaq 0x18ff9(%rip), %rdi     # 0x28327
leaq 0x18415(%rip), %rsi     # 0x2774a
leaq 0x198f0(%rip), %rcx     # 0x28c2c
movl $0xd4a, %edx            # imm = 0xD4A
callq 0x4160
leaq 0x1997d(%rip), %rdi     # 0x28cca
leaq 0x183f6(%rip), %rsi     # 0x2774a
leaq 0x198d1(%rip), %rcx     # 0x28c2c
movl $0xd71, %edx            # imm = 0xD71
callq 0x4160
movq 0x27c6c(%rip), %rdi     # 0x36fd8
leaq 0x19752(%rip), %rsi     # 0x28ac5
movl $0x16, %edx
callq 0x4280
movq 0x27c54(%rip), %rdi     # 0x36fd8
leaq 0x19878(%rip), %rsi     # 0x28c03
movl $0x28, %edx
callq 0x4280
movq 0x27c3c(%rip), %rdi     # 0x36fd8
callq 0x4100
jmp 0xf320
leaq 0x198ad(%rip), %rdi     # 0x28c5a
leaq 0x18396(%rip), %rsi     # 0x2774a
leaq 0x19871(%rip), %rcx     # 0x28c2c
movl $0xd60, %edx            # imm = 0xD60
callq 0x4160
leaq 0x198ab(%rip), %rdi     # 0x28c77
leaq 0x18377(%rip), %rsi     # 0x2774a
leaq 0x19852(%rip), %rcx     # 0x28c2c
movl $0xd61, %edx            # imm = 0xD61
callq 0x4160
movq 0x27bed(%rip), %rdi     # 0x36fd8
leaq 0x196d3(%rip), %rsi     # 0x28ac5
movl $0x16, %edx
callq 0x4280
movq 0x27bd5(%rip), %rdi     # 0x36fd8
leaq 0x198f1(%rip), %rsi     # 0x28cfb
movl $0x36, %edx
callq 0x4280
movq 0x27bbd(%rip), %rdi     # 0x36fd8
callq 0x4100
jmp 0xf320
jmp 0xf4c5
jmp 0xf497
jmp 0xf492
jmp 0xf497
jmp 0xf492
jmp 0xf497
jmp 0xf492
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x1abf2
jmp 0xf49a
jmp 0xf497
jmp 0xf497
jmp 0xf492
jmp 0xf492
jmp 0xf492
movq %rax, %rbx
movq %rsp, %rdi
jmp 0xf4a7
jmp 0xf48d
jmp 0xf48d
jmp 0xf492
jmp 0xf48d
jmp 0xf482
jmp 0xf482
jmp 0xf482
jmp 0xf4ca
jmp 0xf4c5
jmp 0xf4ca
jmp 0xf4ca
jmp 0xf4c5
jmp 0xf4c5
jmp 0xf497
jmp 0xf492
jmp 0xf497
jmp 0xf492
jmp 0xf497
jmp 0xf492
jmp 0xf482
movq %rax, %rbx
jmp 0xf4b6
jmp 0xf4c5
jmp 0xf48d
jmp 0xf4ca
movq %rax, %rbx
jmp 0xf4ac
movq %rax, %rbx
jmp 0xf4a2
movq %rax, %rbx
movq %rsp, %rdi
callq 0x1abf2
leaq 0x18(%rsp), %rdi
callq 0x1abf2
leaq 0x60(%rsp), %rdi
callq 0x1abf2
leaq 0x98(%rsp), %rdi
callq 0x1abf2
jmp 0xf4cd
movq %rax, %rbx
jmp 0xf4d7
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x1abf2
leaq 0x48(%rsp), %rdi
callq 0x1abf2
movq %rbx, %rdi
callq 0x43e0
nop