// File: cannam[P]mini-cpp-convnet/flower.cpp
// Function: dense(std::vector<float, std::allocator<float>> const&, std::vector<std::vector<float, std::allocator<float>>, std::allocator<std::vector<float, std::allocator<float>>>> const&, std::vector<float, std::allocator<float>> const&)
vector<float>
dense(const vector<float> &in,
      const vector<vector<float>> &weights,
      const vector<float> &biases)
{
    size_t in_size = in.size();
    if (in_size != weights.size() || in_size == 0) {
        cerr << "dense: in_size = " << in_size
             << " but we expected " << weights.size() << endl;
        throw runtime_error("Input size mismatch in dense");
    }

    size_t out_size = weights[0].size();
    if (out_size != biases.size() || out_size == 0) {
        cerr << "dense: out_size = " << out_size
             << " but we expected " << biases.size() << endl;
        throw runtime_error("Output size mismatch in dense");
    }
    
#ifdef VERBOSE
    cerr << "dense: input length " << in_size << ", output length "
         << out_size << endl;
#endif

    vector<float> out(out_size, 0.f);

    for (size_t i = 0; i < in_size; ++i) {
        for (size_t j = 0; j < out_size; ++j) {
            out[j] += weights[i][j] * in[i];
        }
    }

    for (size_t j = 0; j < out_size; ++j) {
        out[j] += biases[j];
    }

    return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x80(%rbp)
movq %rdi, %rax
movq %rax, -0x78(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4a7b0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4a7d0
movq %rax, %rcx
movq -0x70(%rbp), %rax
cmpq %rcx, %rax
jne 0x484bb
cmpq $0x0, -0x28(%rbp)
jne 0x48573
movq 0xa0b26(%rip), %rdi     # 0xe8fe8
leaq 0xac1b(%rip), %rsi      # 0x530e4
callq 0x3250
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x3080
movq %rax, %rdi
leaq 0xab82(%rip), %rsi      # 0x53066
callq 0x3250
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rdi
callq 0x4a7d0
movq -0x90(%rbp), %rdi
movq %rax, %rsi
callq 0x3080
movq %rax, %rdi
movq 0xa0a8e(%rip), %rsi     # 0xe8fa0
callq 0x3290
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x88(%rbp)
leaq 0xabc1(%rip), %rsi      # 0x530f6
callq 0x30d0
jmp 0x4853c
movq -0x88(%rbp), %rdi
movq 0xa0aa6(%rip), %rsi     # 0xe8ff0
movq 0xa0a5f(%rip), %rdx     # 0xe8fb0
callq 0x3390
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x31d0
jmp 0x48809
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4a790
movq %rax, %rdi
callq 0x4a7b0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4a7b0
movq %rax, %rcx
movq -0x98(%rbp), %rax
cmpq %rcx, %rax
jne 0x485ba
cmpq $0x0, -0x40(%rbp)
jne 0x48672
movq 0xa0a27(%rip), %rdi     # 0xe8fe8
leaq 0xab4b(%rip), %rsi      # 0x53113
callq 0x3250
movq %rax, %rdi
movq -0x40(%rbp), %rsi
callq 0x3080
movq %rax, %rdi
leaq 0xaa83(%rip), %rsi      # 0x53066
callq 0x3250
movq %rax, -0xa8(%rbp)
movq -0x20(%rbp), %rdi
callq 0x4a7b0
movq -0xa8(%rbp), %rdi
movq %rax, %rsi
callq 0x3080
movq %rax, %rdi
movq 0xa098f(%rip), %rsi     # 0xe8fa0
callq 0x3290
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa0(%rbp)
leaq 0xaaf2(%rip), %rsi      # 0x53126
callq 0x30d0
jmp 0x4863b
movq -0xa0(%rbp), %rdi
movq 0xa09a7(%rip), %rsi     # 0xe8ff0
movq 0xa0960(%rip), %rdx     # 0xe8fb0
callq 0x3390
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x31d0
jmp 0x48809
movb $0x0, -0x41(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl $0x0, -0x48(%rbp)
leaq -0x49(%rbp), %rdi
movq %rdi, -0xb0(%rbp)
callq 0x4a800
movq -0x80(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq -0xb0(%rbp), %rcx
leaq -0x48(%rbp), %rdx
callq 0x4a820
jmp 0x486b5
leaq -0x49(%rbp), %rdi
callq 0x4aae0
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x48793
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x48780
movq -0x18(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x4a790
movq %rax, %rdi
movq -0x60(%rbp), %rsi
callq 0x4ab00
movss (%rax), %xmm0
movss %xmm0, -0xc0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x4ab00
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0xbc(%rbp)
movq -0x60(%rbp), %rsi
callq 0x4ab60
movss -0xc0(%rbp), %xmm0
movss -0xbc(%rbp), %xmm2
movss (%rax), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, (%rax)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x486dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x49(%rbp), %rdi
callq 0x4aae0
jmp 0x48809
jmp 0x48782
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x486c6
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x487e9
movq -0x20(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x4ab00
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0xc4(%rbp)
movq -0x68(%rbp), %rsi
callq 0x4ab60
movss -0xc4(%rbp), %xmm0
addss (%rax), %xmm0
movss %xmm0, (%rax)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x4879b
movb $0x1, -0x41(%rbp)
testb $0x1, -0x41(%rbp)
jne 0x487fc
movq -0x80(%rbp), %rdi
callq 0x4aa80
movq -0x78(%rbp), %rax
addq $0xd0, %rsp
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x33b0
nopw %cs:(%rax,%rax)