BITS 64

SECTION .note.GNU-stack noalloc noexec nowrite progbits

SECTION .text

GLOBAL dft_avx2_2

; rdi -> output
; rsi -> input
; rdx -> costab
; ecx -> fft_size
dft_avx2_2:
    push rbx
    push r12
    push r13
    push r14
    push r15

    vxorpd ymm0, ymm0
    xor rbx, rbx
dft_avx2_2_memset:
    vmovupd [rdi + rbx * 8], ymm0
    vmovupd [rdi + rbx * 8 + 32], ymm0
    add rbx, 8
    cmp rbx, rcx
    jb dft_avx2_2_memset

    mov r12d, ecx
    shl r12, 2

    vmovd xmm15, ecx
    vpbroadcastd ymm15, xmm15

    mov eax, ecx
    shr eax, 2
    vmovd xmm14, eax
    vpbroadcastd ymm14, xmm14

    mov eax, ecx
    dec eax
    vmovd xmm13, eax
    vpbroadcastd ymm13, xmm13

    xor ebx, ebx
dft_avx2_2_loop1:
    mov eax, ebx
    shl rax, 32
    vmovq xmm0, rax
    add rax, rbx
    vmovq xmm1, rax
    vpslld xmm1, 1
    vpaddd xmm1, xmm0
    mov r8, rbx
    vpunpcklqdq xmm0, xmm1
    shl r8, 3
    vmovdqa xmm1, xmm0

    vmovapd ymm4, [rsi + r8]
    vpaddd xmm1, xmm14
    vinserti128 ymm0, ymm0, xmm1, 1
    vinserti128 ymm2, ymm0, xmm0, 1

    xor r11, r11
dft_avx2_2_loop2:
    vmovdqa ymm6, ymm0
    vpcmpgtd ymm6, ymm13
    vpand ymm6, ymm15
    vpsubd ymm0, ymm6

    vmovdqa ymm6, ymm0
    vpcmpgtd ymm6, ymm13
    vpand ymm6, ymm15
    vpsubd ymm0, ymm6

    vmovdqa ymm6, ymm0
    vpcmpgtd ymm6, ymm13
    vpand ymm6, ymm15
    vpsubd ymm0, ymm6

    vmovdqa ymm6, ymm0
    vpcmpgtd ymm6, ymm13
    vpand ymm6, ymm15
    vpsubd ymm0, ymm6

    vpcmpeqd ymm12, ymm12
    vmovdqa ymm11, ymm0
    vgatherdpd ymm6, [rdx+8*xmm0], ymm12
    vpcmpeqd ymm12, ymm12
    vextracti128 xmm11, ymm0, 1
    vgatherdpd ymm8, [rdx+8*xmm11], ymm12

    mov r9, r11
    vmulpd ymm6, ymm4
    add r9, r12
    vmovupd ymm7, [rdi + r11]
    vmulpd ymm8, ymm4
    vmovupd ymm9, [rdi + r9]
    vaddpd ymm7, ymm6
    vaddpd ymm9, ymm8
    vmovupd [rdi + r11], ymm7
    vmovupd [rdi + r9], ymm9

    vpaddd ymm0, ymm2
    add r11, 32
    cmp r11, r12
    jb dft_avx2_2_loop2

    add rbx, 4
    cmp rbx, rcx
    jb dft_avx2_2_loop1

dft_avx2_2_end:
    pop r15
    pop r14
    pop r13
    pop r12
    pop rbx
    ret
