// File: /workspace/github_c_makefile_star2_O1/SimpleDoger[P]Darknet_CPU_Only/lstm_layer.c
// Function: make_lstm_layer
layer make_lstm_layer(int batch, int inputs, int outputs, int steps, int batch_normalize, int adam)
{
    fprintf(stderr, "LSTM Layer: %d inputs, %d outputs\n", inputs, outputs);
    batch = batch / steps;
    layer l = { 0 };
    l.batch = batch;
    l.type = LSTM;
    l.steps = steps;
    l.inputs = inputs;

    l.uf = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.uf) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam);
    l.uf->batch = batch;

    l.ui = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.ui) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam);
    l.ui->batch = batch;

    l.ug = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.ug) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam);
    l.ug->batch = batch;

    l.uo = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.uo) = make_connected_layer(batch*steps, inputs, outputs, LINEAR, batch_normalize, adam);
    l.uo->batch = batch;

    l.wf = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.wf) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam);
    l.wf->batch = batch;

    l.wi = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.wi) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam);
    l.wi->batch = batch;

    l.wg = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.wg) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam);
    l.wg->batch = batch;

    l.wo = malloc(sizeof(layer));
    fprintf(stderr, "\t\t");
    *(l.wo) = make_connected_layer(batch*steps, outputs, outputs, LINEAR, batch_normalize, adam);
    l.wo->batch = batch;

    l.batch_normalize = batch_normalize;
    l.outputs = outputs;

    l.output = calloc(outputs*batch*steps, sizeof(float));
    l.state = calloc(outputs*batch, sizeof(float));

    l.forward = forward_lstm_layer;
    l.update = update_lstm_layer;

    l.prev_state_cpu =  calloc(batch*outputs, sizeof(float));
    l.prev_cell_cpu =   calloc(batch*outputs, sizeof(float));
    l.cell_cpu =        calloc(batch*outputs*steps, sizeof(float));

    l.f_cpu =           calloc(batch*outputs, sizeof(float));
    l.i_cpu =           calloc(batch*outputs, sizeof(float));
    l.g_cpu =           calloc(batch*outputs, sizeof(float));
    l.o_cpu =           calloc(batch*outputs, sizeof(float));
    l.c_cpu =           calloc(batch*outputs, sizeof(float));
    l.h_cpu =           calloc(batch*outputs, sizeof(float));
    l.temp_cpu =        calloc(batch*outputs, sizeof(float));
    l.temp2_cpu =       calloc(batch*outputs, sizeof(float));
    l.temp3_cpu =       calloc(batch*outputs, sizeof(float));
    l.dc_cpu =          calloc(batch*outputs, sizeof(float));
    l.dh_cpu =          calloc(batch*outputs, sizeof(float));


    return l;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movl %r9d, 0x14(%rsp)
movl %r8d, %ebp
movl %esi, %r15d
movq %rdi, %rbx
movq 0x61cca(%rip), %rax     # 0x69ff8
movq (%rax), %rdi
leaq 0x4fa5d(%rip), %rsi     # 0x57d95
movl %edx, %r13d
movl %ecx, %r14d
xorl %eax, %eax
callq 0x3280
movl %r15d, %eax
cltd
idivl %ebp
movl %eax, %r15d
movl $0x4a0, %edx            # imm = 0x4A0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x31d0
movl %r15d, 0x48(%rbx)
movl %r15d, %r12d
movl $0x11, (%rbx)
movl %ebp, 0xc0(%rbx)
movl %ebp, 0x24(%rsp)
movl %r13d, 0x54(%rbx)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x460(%rbx)
movq 0x61c65(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f857(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl %r12d, %esi
movl %r12d, 0x1c(%rsp)
imull %ebp, %esi
movl %esi, 0x10(%rsp)
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
pushq $0x3
popq %r8
movl %r13d, %edx
movl %r14d, %ecx
movl %r14d, 0x18(%rsp)
movl 0x14(%rsp), %ebp
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x470(%rbx)
movq 0x61be6(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f7d8(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
movl 0x10(%rsp), %esi
movl %r13d, %edx
movl %r13d, %r12d
movl %r13d, 0x20(%rsp)
movl %r14d, %ecx
pushq $0x3
popq %r8
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl 0x1c(%rsp), %r14d
movl %r14d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x480(%rbx)
movq 0x61b6e(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f760(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
movl 0x10(%rsp), %r13d
movl %r13d, %esi
movl %r12d, %edx
movl 0x18(%rsp), %ecx
pushq $0x3
popq %r8
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl %r14d, 0x48(%r15)
movl %r14d, %r12d
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x450(%rbx)
movq 0x61afb(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f6ed(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
movl %r13d, %esi
movl 0x20(%rsp), %edx
movl 0x18(%rsp), %r14d
movl %r14d, %ecx
pushq $0x3
popq %r8
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x468(%rbx)
movq 0x61a8b(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f67d(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
movl %r13d, %esi
movl %r14d, %edx
movl %r14d, %ecx
pushq $0x3
popq %r8
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x478(%rbx)
movq 0x61a21(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f613(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rdi
movl %r13d, %esi
movl %r14d, %edx
movl %r14d, %ecx
pushq $0x3
popq %r8
movl %ebp, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x488(%rbx)
movq 0x619b7(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f5a9(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rbp
movq %rbp, %rdi
movl %r13d, %esi
movl %r14d, %edx
movl %r14d, %ecx
pushq $0x3
popq %r8
movl 0x14(%rsp), %r13d
movl %r13d, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
movq %rbp, %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl $0x4a0, %edi            # imm = 0x4A0
callq 0x3310
movq %rax, %r15
movq %rax, 0x458(%rbx)
movq 0x61947(%rip), %rax     # 0x69ff8
movq (%rax), %rcx
leaq 0x4f539(%rip), %rdi     # 0x57bf4
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
callq 0x3450
movl 0x500(%rsp), %eax
movl %eax, (%rsp)
leaq 0x28(%rsp), %rbp
movq %rbp, %rdi
movl 0x10(%rsp), %esi
movl %r14d, %edx
movl %r14d, %ecx
pushq $0x3
popq %r8
movl %r13d, %r9d
callq 0x4ab2
movl $0x4a0, %edx            # imm = 0x4A0
movq %r15, %rdi
movq %rbp, %rsi
callq 0x32c0
movl %r12d, 0x48(%r15)
movl %r13d, 0x40(%rbx)
movl %r14d, 0x58(%rbx)
imull %r14d, %r12d
movl 0x24(%rsp), %eax
imull %r12d, %eax
movslq %eax, %r13
pushq $0x4
popq %r14
movq %r13, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x268(%rbx)
movslq %r12d, %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x1e0(%rbx)
leaq 0x3493d(%rip), %rax     # 0x3d088
movq %rax, 0x10(%rbx)
leaq 0x35277(%rip), %rax     # 0x3d9cd
movq %rax, 0x20(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x318(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x348(%rbx)
movq %r13, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x350(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x358(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x360(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x368(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x370(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x378(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x310(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x320(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x328(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x330(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x380(%rbx)
movq %r15, %rdi
movq %r14, %rsi
callq 0x3260
movq %rax, 0x338(%rbx)
movq %rbx, %rax
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq