// File: matteotiziano[P]simple-wavelet/wavelet.cpp
// Function: Wavelet<double>::Convdown(Matrix<double> const&, std::vector<double, std::allocator<double>> const&, Matrix<double>&, Matrix<double>&) const
void Wavelet<T>::Convdown(const Matrix<T>& x, const std::vector<T>& f, Matrix<T>& xL, Matrix<T>& xH) const {
  // Compute size of subbands
  const size_t num_rows_subband = static_cast<size_t>(std::ceil(static_cast<double>(x.GetNumRows()) / 2.0));
  const size_t num_cols_subband = static_cast<size_t>(std::ceil(static_cast<double>(x.GetNumColumns()) / 2.0));
  // Convolve and decimate each row with the chosen filter
  Matrix<T> tmp(x.GetNumRows(), num_cols_subband);
  for (size_t i = 0; i < x.GetNumRows(); i++) {
    const std::vector<T> row = Convdown(x.GetRow(i), f);
    tmp.SetRow(row, i);
  }
  // Compute high-pass subband of pre-filtered tmp matrix
  xH = Matrix<T>(num_rows_subband, num_cols_subband);
  for (size_t j = 0; j < tmp.GetNumColumns(); j++) {
    const std::vector<T> column = Convdown(tmp.GetColumn(j), Hi_D_);
    xH.SetColumn(column, j);
  }
  // Compute low-pass subband of pre-filtered tmp matrix
  xL = Matrix<T>(num_rows_subband, num_cols_subband);
  for (size_t j = 0; j < tmp.GetNumColumns(); j++) {
    const std::vector<T> column = Convdown(tmp.GetColumn(j), Lo_D_);
    xL.SetColumn(column, j);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x10(%rbp), %rdi
callq 0xca40
movq %rax, %xmm0
movaps 0xb6a1(%rip), %xmm1     # 0x12130
movaps %xmm1, -0x1a0(%rbp)
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0xb69e(%rip), %xmm1     # 0x12140
movaps %xmm1, -0x190(%rbp)
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0xb690(%rip), %xmm1     # 0x12150
movsd %xmm1, -0x178(%rbp)
mulsd %xmm1, %xmm0
callq 0x2050
movaps %xmm0, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movsd 0xb670(%rip), %xmm1     # 0x12158
movsd %xmm1, -0x170(%rbp)
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0xca60
movaps -0x1a0(%rbp), %xmm3
movaps -0x190(%rbp), %xmm2
movsd -0x178(%rbp), %xmm1
movq %rax, %xmm0
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
subpd %xmm2, %xmm0
movaps %xmm0, %xmm2
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm2, %xmm0
mulsd %xmm1, %xmm0
callq 0x2050
movsd -0x170(%rbp), %xmm1
movaps %xmm0, %xmm2
cvttsd2si %xmm2, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0xca40
movq %rax, %rsi
movq -0x38(%rbp), %rdx
leaq -0x60(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0xc7e0
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x10(%rbp), %rdi
callq 0xca40
movq %rax, -0x1b0(%rbp)
jmp 0x6bae
movq -0x1b8(%rbp), %rax
movq -0x1b0(%rbp), %rcx
cmpq %rcx, %rax
jae 0x6c85
movq -0x10(%rbp), %rsi
movq -0x68(%rbp), %rdx
leaq -0xa8(%rbp), %rdi
callq 0xd240
jmp 0x6bdb
movq -0x1a8(%rbp), %rsi
movq -0x18(%rbp), %rcx
leaq -0x90(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
callq 0x5e00
jmp 0x6bfb
leaq -0xa8(%rbp), %rdi
callq 0x3430
movq -0x68(%rbp), %rdx
leaq -0x60(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0xcf80
jmp 0x6c1d
leaq -0x90(%rbp), %rdi
callq 0x3430
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x6b91
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x3430
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x3430
jmp 0x6f32
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0xd0(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0xc7e0
jmp 0x6c9e
movq -0x28(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x5790
jmp 0x6cb0
leaq -0xd0(%rbp), %rdi
callq 0xca20
movq $0x0, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x1c8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xca60
movq %rax, -0x1c0(%rbp)
jmp 0x6ce7
movq -0x1c8(%rbp), %rax
movq -0x1c0(%rbp), %rcx
cmpq %rcx, %rax
jae 0x6dd9
movq -0xd8(%rbp), %rdx
leaq -0x108(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xd320
jmp 0x6d17
movq -0x1a8(%rbp), %rsi
movq %rsi, %rcx
addq $0x18, %rcx
leaq -0xf0(%rbp), %rdi
leaq -0x108(%rbp), %rdx
callq 0x5e00
jmp 0x6d3a
leaq -0x108(%rbp), %rdi
callq 0x3430
movq -0x28(%rbp), %rdi
movq -0xd8(%rbp), %rdx
leaq -0xf0(%rbp), %rsi
callq 0xd080
jmp 0x6d5f
leaq -0xf0(%rbp), %rdi
callq 0x3430
movq -0xd8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd8(%rbp)
jmp 0x6cc7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0xca20
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x3430
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x3430
jmp 0x6f32
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x130(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0xc7e0
jmp 0x6df2
movq -0x20(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x5790
jmp 0x6e04
leaq -0x130(%rbp), %rdi
callq 0xca20
movq $0x0, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq %rax, -0x1d8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xca60
movq %rax, -0x1d0(%rbp)
jmp 0x6e3b
movq -0x1d8(%rbp), %rax
movq -0x1d0(%rbp), %rcx
cmpq %rcx, %rax
jae 0x6f20
movq -0x138(%rbp), %rdx
leaq -0x168(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xd320
jmp 0x6e6b
movq -0x1a8(%rbp), %rcx
leaq -0x150(%rbp), %rdi
leaq -0x168(%rbp), %rdx
movq %rcx, %rsi
callq 0x5e00
jmp 0x6e8a
leaq -0x168(%rbp), %rdi
callq 0x3430
movq -0x20(%rbp), %rdi
movq -0x138(%rbp), %rdx
leaq -0x150(%rbp), %rsi
callq 0xd080
jmp 0x6eaf
leaq -0x150(%rbp), %rdi
callq 0x3430
movq -0x138(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x138(%rbp)
jmp 0x6e1b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x130(%rbp), %rdi
callq 0xca20
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x3430
jmp 0x6f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x3430
jmp 0x6f32
leaq -0x60(%rbp), %rdi
callq 0xca20
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
leaq -0x60(%rbp), %rdi
callq 0xca20
movq -0x70(%rbp), %rdi
callq 0x2350
nopw %cs:(%rax,%rax)
nop