// File: /workspace/github_c_makefile_star2_O2/diaxen[P]fft-garden/cp_dit_di_P.c
// Function: fft
void
fft(unsigned N, complex double * restrict out,
    const complex double * restrict in)
{
  unsigned log2_N = 31 - clz32(N);
  unsigned r = 32 - log2_N;
  uint32_t p = 0, q = 0;

  for (uint32_t hn, h = 0; h < N; h = hn) {

    /* eval binary carry sequence */
    hn = h + 2;
    unsigned c = 30 - clz32(h ^ hn);

    /* input indices */
    unsigned i0 = (p - q) >> r;
    unsigned i1 = i0 ^ (N >> 1);

    if (c & 1) {                /* stage 1 */
      out[h    ] = in[i0];
      out[h + 1] = in[i1];
      cp_dit_bf_0(1, out + h - 2);
    } else {			/* stage 0 */
      complex double a = in[i0];
      complex double b = in[i1];
      out[h    ] = a + b;
      out[h + 1] = a - b;
    }

    /* higher stages */
    for (unsigned j = 1 + (c & 1); j < c; j += 2)
      {
        unsigned s = 1 << j;
        unsigned r = h + 2 - 4 * s;
        unsigned t = log2_N - j - 2;

        if (s > 1)
          {
	    unsigned b;
            for (b = 1; b < s / 2; b++)
              cp_dit_bf(s, out + r + b, get_twiddle(b << t, log2_N));
            for (b++; b < s; b++)
              cp_dit_bf(s, out + r + b, get_twiddle(b << t, log2_N));
          }

        cp_dit_bf_pi4(s, out + r + s / 2);
        cp_dit_bf_0(s, out + r);
      }

    /* advance to next input index */
    uint32_t m2 = 0x20000000 >> c;
    uint32_t m1 = m2 - 1;
    uint32_t m  = p & m2;
    q = (q & m1) | m;
    p = (p & m1) | ((m ^ m2) << 1);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdx, 0x38(%rsp)
bsrl %edi, %eax
pushq $0x20
popq %rcx
movl %eax, 0x28(%rsp)
subl %eax, %ecx
movl %ecx, 0x1c(%rsp)
movl %edi, 0x20(%rsp)
shrl %edi
movl %edi, 0x18(%rsp)
leaq 0x10(%rsi), %rax
movq %rax, 0x48(%rsp)
movq %rsi, 0x10(%rsp)
leaq 0x20(%rsi), %rax
movq %rax, 0x40(%rsp)
xorl %eax, %eax
pushq $0x2
popq %rcx
movl %ecx, 0x8(%rsp)
movl $0x0, 0x4(%rsp)
xorl %edx, %edx
cmpl 0x20(%rsp), %eax
jae 0x1cc7
leal 0x2(%rax), %esi
movq %rsi, %rcx
movq %rsi, 0x30(%rsp)
xorl %eax, %ecx
bsrl %ecx, %ebx
xorl $-0x20, %ebx
addl $0x1f, %ebx
movl %edx, 0x24(%rsp)
subl 0x4(%rsp), %edx
movl 0x1c(%rsp), %ecx
shrl %cl, %edx
movl %edx, %ecx
xorl 0x18(%rsp), %ecx
shlq $0x4, %rdx
movl %ebx, 0xc(%rsp)
movq 0x38(%rsp), %rdi
movupd (%rdi,%rdx), %xmm0
movl %ecx, %ecx
movl %eax, %edx
andl $0x1, %ebx
jne 0x1a7b
shlq $0x4, %rcx
shlq $0x4, %rdx
movupd (%rdi,%rcx), %xmm1
movapd %xmm0, %xmm2
addpd %xmm1, %xmm2
movq 0x10(%rsp), %rcx
movupd %xmm2, (%rcx,%rdx)
orl $0x1, %eax
shlq $0x4, %rax
subpd %xmm1, %xmm0
movupd %xmm0, (%rcx,%rax)
jmp 0x1aaf
shlq $0x4, %rdx
movq 0x10(%rsp), %r8
leaq (%r8,%rdx), %rsi
addq $-0x20, %rsi
movupd %xmm0, 0x20(%rsi)
shlq $0x4, %rcx
orl $0x1, %eax
shlq $0x4, %rax
movupd (%rdi,%rcx), %xmm0
movupd %xmm0, (%r8,%rax)
pushq $0x1
popq %rdi
callq 0x1cd6
incl %ebx
cmpl 0xc(%rsp), %ebx
jae 0x1c8e
pushq $0x1
popq %rdi
movl %ebx, %ecx
shll %cl, %edi
pushq $-0x4
popq %rax
movl %eax, %ebp
shll %cl, %ebp
movq 0x30(%rsp), %rax
addl %ebp, %eax
movl %eax, %esi
testl %ebx, %ebx
je 0x1ba5
movq %rsi, 0x50(%rsp)
movl 0x28(%rsp), %r14d
movl %ebx, 0x2c(%rsp)
subl %ebx, %r14d
addl $-0x2, %r14d
movl %edi, (%rsp)
movl %edi, %ecx
shrl %ecx
addl 0x8(%rsp), %ebp
shlq $0x4, %rbp
movq 0x48(%rsp), %rax
leaq (%rax,%rbp), %r15
addq 0x40(%rsp), %rbp
pushq $0x2
popq %r13
pushq $0x1
popq %rbx
movq %rcx, %r12
cmpq %rcx, %rbx
jae 0x1b59
movl %ebx, %eax
movl %r14d, %ecx
shll %cl, %eax
leaq 0x3557(%rip), %rcx      # 0x5080
movq (%rcx), %rcx
shlq $0x4, %rax
movsd (%rcx,%rax), %xmm0
movsd 0x8(%rcx,%rax), %xmm1
movl (%rsp), %edi
movq %r15, %rsi
callq 0x1d47
incq %rbx
addq $0x10, %r15
incq %r13
addq $0x10, %rbp
movq %r12, %rcx
jmp 0x1b13
movl (%rsp), %r15d
movl 0x2c(%rsp), %ebx
cmpq %r15, %r13
jae 0x1b9b
movl %r13d, %eax
movl %r14d, %ecx
shll %cl, %eax
leaq 0x350b(%rip), %rcx      # 0x5080
movq (%rcx), %rcx
shlq $0x4, %rax
movsd (%rcx,%rax), %xmm0
movsd 0x8(%rcx,%rax), %xmm1
movl (%rsp), %edi
movq %rbp, %rsi
callq 0x1d47
incq %r13
addq $0x10, %rbp
jmp 0x1b61
movq 0x50(%rsp), %rsi
movl (%rsp), %edi
jmp 0x1bac
pushq $0x1
popq %r15
xorl %r12d, %r12d
shlq $0x4, %rsi
addq 0x10(%rsp), %rsi
shlq $0x4, %r12
pushq $0x2
popq %rax
movl %eax, %edx
movl %ebx, %ecx
shll %cl, %edx
leaq (%rsi,%r12), %rax
shlq $0x4, %r15
shlq $0x4, %rdx
pushq $0x3
popq %rcx
movl %ecx, %r8d
movl %ebx, %ecx
shll %cl, %r8d
shlq $0x4, %r8
movupd (%r12,%rsi), %xmm0
movsd (%rdx,%rax), %xmm1
movsd 0x8(%rdx,%rax), %xmm2
movhpd (%r8,%rax), %xmm1       # xmm1 = xmm1[0],mem[0]
movhpd 0x8(%r8,%rax), %xmm2    # xmm2 = xmm2[0],mem[0]
movapd 0x164d(%rip), %xmm3     # 0x3250
mulpd %xmm3, %xmm1
mulpd %xmm3, %xmm2
movapd %xmm1, %xmm3
shufpd $0x1, %xmm2, %xmm3      # xmm3 = xmm3[1],xmm2[0]
movapd %xmm2, %xmm4
shufpd $0x1, %xmm1, %xmm4      # xmm4 = xmm4[1],xmm1[0]
subpd %xmm4, %xmm3
addpd %xmm1, %xmm2
movapd %xmm2, %xmm1
addpd %xmm3, %xmm1
movupd (%r15,%rax), %xmm4
movapd %xmm3, %xmm5
shufpd $0x1, %xmm2, %xmm5      # xmm5 = xmm5[1],xmm2[0]
shufpd $0x1, %xmm3, %xmm2      # xmm2 = xmm2[1],xmm3[0]
subpd %xmm2, %xmm5
movapd %xmm0, %xmm2
addpd %xmm1, %xmm2
movupd %xmm2, (%r12,%rsi)
movapd %xmm4, %xmm2
addpd %xmm5, %xmm2
subpd %xmm5, %xmm4
movapd %xmm4, %xmm3
movsd %xmm2, %xmm3            # xmm3 = xmm2[0],xmm3[1]
movupd %xmm3, (%r15,%rax)
subpd %xmm1, %xmm0
movupd %xmm0, (%rdx,%rax)
shufpd $0x2, %xmm2, %xmm4      # xmm4 = xmm4[0],xmm2[1]
movupd %xmm4, (%r8,%rax)
callq 0x1cd6
addl $0x2, %ebx
jmp 0x1ab1
movl $0x20000000, %eax       # imm = 0x20000000
movl 0xc(%rsp), %ecx
shrl %cl, %eax
leal -0x1(%rax), %ecx
movl %eax, %edx
movl 0x24(%rsp), %edi
andl %edi, %edx
movl 0x4(%rsp), %esi
andl %ecx, %esi
orl %edx, %esi
movl %esi, 0x4(%rsp)
andl %edi, %ecx
xorl %eax, %edx
addl %edx, %edx
orl %ecx, %edx
addl $0x2, 0x8(%rsp)
movq 0x30(%rsp), %rax
jmp 0x19fb
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq