// File: /workspace/github_cpp_makefile_star2_O3/ushitora-anqou[P]aqtfhe2/./aqtfhe2.hpp
// Function: aqtfhe2::detail::fft_processor<1024ul>::fft(aqtfhe2::detail::array_slice<double, 1024ul>)
void fft(array_slice<double, N> out)
    {
        constexpr size_t n = N * 2, ns4 = n / 4;
        double tmp0[4], tmp1[4], tmp2[4], tmp3[4];
        auto itre = out.begin(), itim = out.begin() + ns4;

        // size 2
        for (size_t block = 0; block < ns4; block += 4) {
            auto re = itre + block;
            auto im = itim + block;

            tmp0[0] = re[0] + re[1];
            tmp0[1] = re[0] - re[1];
            tmp0[2] = re[2] + re[3];
            tmp0[3] = re[2] - re[3];
            copy4(re, tmp0);

            tmp1[0] = im[0] + im[1];
            tmp1[1] = im[0] - im[1];
            tmp1[2] = im[2] + im[3];
            tmp1[3] = im[2] - im[3];
            copy4(im, tmp1);
        }

        // size 4
        for (size_t block = 0; block < ns4; block += 4) {
            auto re = itre + block;
            auto im = itim + block;

            tmp0[0] = re[0] + re[2];
            tmp0[1] = re[1] + im[3];
            tmp0[2] = re[0] - re[2];
            tmp0[3] = re[1] - im[3];

            tmp1[0] = im[0] + im[2];
            tmp1[1] = im[1] - re[3];
            tmp1[2] = im[0] - im[2];
            tmp1[3] = im[1] + re[3];

            copy4(re, tmp0);
            copy4(im, tmp1);
        }

        // general loop
        auto cur_tt = tables_direct_.cbegin();
        for (size_t halfnn = 4; halfnn < ns4; halfnn *= 2) {
            size_t nn = 2 * halfnn;
            for (size_t block = 0; block < ns4; block += nn) {
                for (size_t off = 0; off < halfnn; off += 4) {
                    auto re0 = itre + block + off;
                    auto im0 = itim + block + off;
                    auto re1 = itre + block + halfnn + off;
                    auto im1 = itim + block + halfnn + off;
                    auto tcs = cur_tt + 2 * off;
                    auto tsn = tcs + 4;

                    dotp4(tmp0, re1, tcs);   // re*cos
                    dotp4(tmp1, re1, tsn);   // re*sin
                    dotp4(tmp2, im1, tcs);   // im*cos
                    dotp4(tmp3, im1, tsn);   // im*sin
                    sub4(tmp0, tmp0, tmp3);  // re2
                    add4(tmp1, tmp1, tmp2);  // im2
                    add4(tmp2, re0, tmp0);   // re + re
                    add4(tmp3, im0, tmp1);   // im + im
                    sub4(tmp0, re0, tmp0);   // re - re
                    sub4(tmp1, im0, tmp1);   // im - im
                    copy4(re0, tmp2);
                    copy4(im0, tmp3);
                    copy4(re1, tmp0);
                    copy4(im1, tmp1);
                }
            }
            cur_tt += nn;
        }

        // multiply by omb^j
        for (size_t j = 0; j < ns4; j += 4) {
            auto r0 = cur_tt + 2 * j;
            auto r1 = r0 + 4;
            //(re*cos-im*sin) + i (im*cos+re*sin)
            auto d0 = itre + j;
            auto d1 = itim + j;

            dotp4(tmp0, d0, r0);  // re*cos
            dotp4(tmp1, d1, r0);  // im*cos
            dotp4(tmp2, d0, r1);  // re*sin
            dotp4(tmp3, d1, r1);  // im*sin
            sub4(d0, tmp0, tmp3);
            add4(d1, tmp1, tmp2);
        }
    }

// Assembly:
leaq 0x1000(%rsi), %rcx
movq $-0x1000, %rax          # imm = 0xF000
vmovupd (%rcx,%rax), %ymm0
vhaddpd %ymm0, %ymm0, %ymm1
vhsubpd %ymm0, %ymm0, %ymm0
vunpcklpd %ymm0, %ymm1, %ymm0 # ymm0 = ymm1[0],ymm0[0],ymm1[2],ymm0[2]
vmovupd %ymm0, (%rcx,%rax)
vmovupd 0x1000(%rcx,%rax), %ymm0
vhaddpd %ymm0, %ymm0, %ymm1
vhsubpd %ymm0, %ymm0, %ymm0
vunpcklpd %ymm0, %ymm1, %ymm0 # ymm0 = ymm1[0],ymm0[0],ymm1[2],ymm0[2]
vmovupd %ymm0, 0x1000(%rcx,%rax)
addq $0x20, %rax
jne 0x4d02
movq $-0x1000, %rax          # imm = 0xF000
vmovsd 0x1010(%rsi,%rax), %xmm1
vmovupd 0x1000(%rsi,%rax), %xmm0
vmovupd 0x2000(%rsi,%rax), %xmm3
vmovsd 0x2008(%rsi,%rax), %xmm5
vmovddup 0x1018(%rsi,%rax), %xmm6 # xmm6 = mem[0,0]
vmovhpd 0x2018(%rsi,%rax), %xmm1, %xmm1 # xmm1 = xmm1[0],mem[0]
vsubsd %xmm6, %xmm5, %xmm5
vaddpd %xmm0, %xmm1, %xmm2
vsubpd %xmm1, %xmm0, %xmm0
vmovsd 0x2010(%rsi,%rax), %xmm1
vmovupd %xmm2, 0x1000(%rsi,%rax)
vmovupd %xmm0, 0x1010(%rsi,%rax)
vaddsd %xmm3, %xmm1, %xmm4
vsubpd %xmm1, %xmm3, %xmm1
vaddpd %xmm6, %xmm3, %xmm3
vunpcklpd %xmm5, %xmm4, %xmm4 # xmm4 = xmm4[0],xmm5[0]
vmovsd %xmm1, %xmm3, %xmm1     # xmm1 = xmm1[0],xmm3[1]
vmovupd %xmm1, 0x2010(%rsi,%rax)
vmovupd %xmm4, 0x2000(%rsi,%rax)
addq $0x20, %rax
jne 0x4d43
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl $0x4, %r8d
leaq (%r8,%r8), %r11
movl $0x1ff, %eax            # imm = 0x1FF
xorl %edx, %edx
leaq -0x1(%r8), %rbx
movq %rdi, %r9
leaq (,%r8,8), %rdi
movq %r8, %r10
shlq $0x4, %r10
xorl %r14d, %r14d
divq %r11
shrq $0x2, %rbx
movq %rcx, %rdx
shlq $0x5, %rbx
addq $0x20, %rbx
leaq (%rdx,%rdi), %r15
xorl %r12d, %r12d
vmovupd -0x1000(%r15,%r12), %ymm0
vmovupd 0x20(%r9,%r12,2), %ymm2
vmovupd (%r15,%r12), %ymm4
vmovupd (%r9,%r12,2), %ymm1
vmulpd %ymm0, %ymm2, %ymm3
vmulpd %ymm4, %ymm2, %ymm2
vfmsub231pd %ymm0, %ymm1, %ymm2 # ymm2 = (ymm1 * ymm0) - ymm2
vfmadd231pd %ymm4, %ymm1, %ymm3 # ymm3 = (ymm1 * ymm4) + ymm3
vmovupd -0x1000(%rdx,%r12), %ymm0
vmovupd (%rdx,%r12), %ymm4
vaddpd %ymm0, %ymm2, %ymm1
vsubpd %ymm2, %ymm0, %ymm0
vaddpd %ymm4, %ymm3, %ymm5
vsubpd %ymm3, %ymm4, %ymm2
vmovupd %ymm1, -0x1000(%rdx,%r12)
vmovupd %ymm5, (%rdx,%r12)
vmovupd %ymm0, -0x1000(%r15,%r12)
vmovupd %ymm2, (%r15,%r12)
addq $0x20, %r12
cmpq %r12, %rbx
jne 0x4e1a
addq %r10, %rdx
leaq 0x1(%r14), %r15
cmpq %rax, %r14
movq %r15, %r14
jne 0x4e13
leaq (%r9,%r11,8), %rdi
cmpq $0x100, %r8             # imm = 0x100
movq %r11, %r8
jb 0x4ddd
leaq 0x20(%r9,%r10), %rax
movq $-0x4, %rcx
vmovupd 0x1020(%rsi,%rcx,8), %ymm1
vmovupd -0x20(%rax), %ymm2
vmovupd (%rax), %ymm3
vmovupd 0x20(%rsi,%rcx,8), %ymm0
addq $0x40, %rax
vmulpd %ymm1, %ymm2, %ymm4
vmulpd %ymm1, %ymm3, %ymm1
vfmsub231pd %ymm2, %ymm0, %ymm1 # ymm1 = (ymm0 * ymm2) - ymm1
vfmadd231pd %ymm0, %ymm3, %ymm4 # ymm4 = (ymm3 * ymm0) + ymm4
vmovupd %ymm1, 0x20(%rsi,%rcx,8)
vmovupd %ymm4, 0x1020(%rsi,%rcx,8)
addq $0x4, %rcx
cmpq $0x1fc, %rcx            # imm = 0x1FC
jb 0x4ec5
popq %rbx
popq %r12
popq %r14
popq %r15
vzeroupper
retq