// File: cannam[P]mini-cpp-convnet/flower.cpp
// Function: maxPool(std::vector<std::vector<std::vector<float, std::allocator<float>>, std::allocator<std::vector<float, std::allocator<float>>>>, std::allocator<std::vector<std::vector<float, std::allocator<float>>, std::allocator<std::vector<float, std::allocator<float>>>>>> const&, unsigned long, unsigned long)
vector<vector<vector<float>>>
maxPool(const vector<vector<vector<float>>> &in,
        size_t pool_y,
        size_t pool_x)
{
    size_t out_height = in.size() / pool_y;
    if (out_height < 1) {
        throw runtime_error("Input too small in maxPool");
    }

    size_t out_width = in[0].size() / pool_x;
    if (out_width < 1) {
        throw runtime_error("Input too small in maxPool");
    }
    
    size_t depth = in[0][0].size();
    
#ifdef VERBOSE
    cerr << "maxPool: input size " << in[0].size() << "x" << in.size()
         << "; pool size " << pool_x << "x" << pool_y << "; output size "
         << out_width << "x" << out_height << " and depth " << depth << endl;
#endif
    
    auto out =
        vector<vector<vector<float>>>
        (out_height,
         vector<vector<float>>
         (out_width,
          vector<float>
          (depth,
           -INFINITY)));

    for (size_t y = 0; y < out_height; ++y) {
        for (size_t x = 0; x < out_width; ++x) {
            for (size_t i = 0; i < pool_y; ++i) {
                for (size_t j = 0; j < pool_x; ++j) {
                    for (size_t c = 0; c < depth; ++c) {
                        float value = in[y * pool_y + i][x * pool_x + j][c];
                        out[y][x][c] = max(out[y][x][c], value);
                    }
                }
            }
        }
    }

    return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0xc8(%rbp)
movq %rdi, %rax
movq %rax, -0xc0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4a740
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x18(%rbp)
movq %rax, -0x28(%rbp)
cmpq $0x1, -0x28(%rbp)
jae 0x47964
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd0(%rbp)
leaq 0xb76d(%rip), %rsi      # 0x53093
callq 0x30d0
jmp 0x4792d
movq -0xd0(%rbp), %rdi
movq 0xa16b5(%rip), %rsi     # 0xe8ff0
movq 0xa166e(%rip), %rdx     # 0xe8fb0
callq 0x3390
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x31d0
jmp 0x47db6
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4a770
movq %rax, %rdi
callq 0x4a7d0
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x20(%rbp)
movq %rax, -0x40(%rbp)
cmpq $0x1, -0x40(%rbp)
jae 0x479e8
movl $0x10, %edi
callq 0x3120
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
leaq 0xb6e9(%rip), %rsi      # 0x53093
callq 0x30d0
jmp 0x479b1
movq -0xd8(%rbp), %rdi
movq 0xa1631(%rip), %rsi     # 0xe8ff0
movq 0xa15ea(%rip), %rdx     # 0xe8fb0
callq 0x3390
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x31d0
jmp 0x47db6
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x100(%rbp)
callq 0x4a770
movq -0x100(%rbp), %rsi
movq %rax, %rdi
callq 0x4a790
movq %rax, %rdi
callq 0x4a7b0
movq %rax, -0x48(%rbp)
movb $0x0, -0x49(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0xe8(%rbp)
movl $0xff800000, -0x84(%rbp) # imm = 0xFF800000
leaq -0x85(%rbp), %rdi
movq %rdi, -0xe0(%rbp)
callq 0x4a800
movq -0xe8(%rbp), %rsi
movq -0xe0(%rbp), %rcx
leaq -0x80(%rbp), %rdi
leaq -0x84(%rbp), %rdx
callq 0x4a820
jmp 0x47a79
leaq -0x86(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x4a8a0
movq -0xf0(%rbp), %rsi
movq -0x108(%rbp), %rcx
leaq -0x68(%rbp), %rdi
leaq -0x80(%rbp), %rdx
callq 0x4a8c0
jmp 0x47aa9
leaq -0x87(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0x4a940
movq -0xc8(%rbp), %rdi
movq -0xf8(%rbp), %rsi
movq -0x110(%rbp), %rcx
leaq -0x68(%rbp), %rdx
callq 0x4a960
jmp 0x47adc
leaq -0x87(%rbp), %rdi
callq 0x4a9e0
leaq -0x68(%rbp), %rdi
callq 0x4aa00
leaq -0x86(%rbp), %rdi
callq 0x4aa60
leaq -0x80(%rbp), %rdi
callq 0x4aa80
leaq -0x85(%rbp), %rdi
callq 0x4aae0
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x47d90
movq $0x0, -0x98(%rbp)
movq -0x98(%rbp), %rax
cmpq -0x40(%rbp), %rax
jae 0x47d77
movq $0x0, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x47d5e
movq $0x0, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x47d45
movq $0x0, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x47d2c
movq -0x10(%rbp), %rdi
movq -0x90(%rbp), %rsi
movq -0x18(%rbp), %rax
imulq %rax, %rsi
movq -0xa0(%rbp), %rax
addq %rax, %rsi
callq 0x4a770
movq %rax, %rdi
movq -0x98(%rbp), %rsi
movq -0x20(%rbp), %rax
imulq %rax, %rsi
movq -0xa8(%rbp), %rax
addq %rax, %rsi
callq 0x4a790
movq %rax, %rdi
movq -0xb0(%rbp), %rsi
callq 0x4ab00
movq -0xc8(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0xb4(%rbp)
movq -0x90(%rbp), %rsi
callq 0x4ab20
movq %rax, %rdi
movq -0x98(%rbp), %rsi
callq 0x4ab40
movq %rax, %rdi
movq -0xb0(%rbp), %rsi
callq 0x4ab60
movq %rax, %rdi
leaq -0xb4(%rbp), %rsi
callq 0x4abe0
movq %rax, -0x118(%rbp)
jmp 0x47c45
movq -0xc8(%rbp), %rdi
movq -0x118(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x11c(%rbp)
movq -0x90(%rbp), %rsi
callq 0x4ab20
movq %rax, %rdi
movq -0x98(%rbp), %rsi
callq 0x4ab40
movq %rax, %rdi
movq -0xb0(%rbp), %rsi
callq 0x4ab60
movss -0x11c(%rbp), %xmm0
movss %xmm0, (%rax)
movq -0xb0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
jmp 0x47b8d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x47cfe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x47ce9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x87(%rbp), %rdi
callq 0x4a9e0
leaq -0x68(%rbp), %rdi
callq 0x4aa00
leaq -0x86(%rbp), %rdi
callq 0x4aa60
leaq -0x80(%rbp), %rdi
callq 0x4aa80
leaq -0x85(%rbp), %rdi
callq 0x4aae0
jmp 0x47db6
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
callq 0x4ab80
jmp 0x47db6
jmp 0x47d2e
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x47b71
jmp 0x47d47
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x47b55
jmp 0x47d60
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x47b39
jmp 0x47d79
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x47b1d
movb $0x1, -0x49(%rbp)
testb $0x1, -0x49(%rbp)
jne 0x47da6
movq -0xc8(%rbp), %rdi
callq 0x4ab80
movq -0xc0(%rbp), %rax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x33b0
nop