// File: jkingan[P]ladyheather/heathmsc.cpp
// Function: fft(COMPLEX*, int)
void fft(COMPLEX *x, int m)
{
static int mstore = 0;       /* stores m for future reference */
static int n = 1;            /* length of fft stored for future */

COMPLEX u,temp,tm;
COMPLEX *xi, *xip, *xj, *wptr;

int i,j,k,l,le,windex;

double arg,w_real,w_imag,wrecur_real,wrecur_imag,wtemp_real;

    if(m != mstore) {  // fft size changed,  redo w array
        /* free previously allocated storage and set new m */
        mstore = m;
        if(m == 0) return;       /* if m=0 then done */

        /* n = 2**m = fft length */
        n = 1 << m;
        le = n/2;

        /* calculate the w values recursively */
        arg = 4.0*atan(1.0)/le;         /* PI/le calculation */
        wrecur_real = w_real = cos(arg);
        wrecur_imag = w_imag = -sin(arg);
        xj = w;
        for(j=1; j<le; j++) {
            xj->real = (float) wrecur_real;
            xj->imag = (float) wrecur_imag;
            xj++;
            wtemp_real = wrecur_real*w_real - wrecur_imag*w_imag;
            wrecur_imag = wrecur_real*w_imag + wrecur_imag*w_real;
            wrecur_real = wtemp_real;
        }
    }

    /* start fft */
    le = n;
    windex = 1;
    for(l=0; l<m; l++) {
       le = le/2;

       /* first iteration with no multiplies */
       for(i=0; i<n; i=i+2*le) {
           xi = x + i;
           xip = xi + le;
           temp.real = xi->real + xip->real;
           temp.imag = xi->imag + xip->imag;
           xip->real = xi->real - xip->real;
           xip->imag = xi->imag - xip->imag;
           *xi = temp;
       }

       /* remaining iterations use stored w */
       wptr = w + windex - 1;
       for(j=1; j<le; j++) {
          u = *wptr;
          for(i=j; i<n; i=i+2*le) {
             xi = x + i;
             xip = xi + le;
             temp.real = xi->real + xip->real;
             temp.imag = xi->imag + xip->imag;
             tm.real = xi->real - xip->real;
             tm.imag = xi->imag - xip->imag;
             xip->real = tm.real*u.real - tm.imag*u.imag;
             xip->imag = tm.real*u.imag + tm.imag*u.real;
             *xi = temp;
          }
          wptr = wptr + windex;
       }
       windex = 2*windex;
    }

    /* rearrange data by bit reversing */
    j = 0;
    for(i=1; i<(n-1); i++) {
        k = n/2;
        while(k <= j) {
           j = j - k;
           k = k/2;
        }
        j = j + k;
        if(i < j) {
           xi = x + i;
           xj = x + j;
           temp = *xj;
           *xj = *xi;
           *xi = temp;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl -0xc(%rbp), %eax
cmpl 0x34a4d9(%rip), %eax    # 0x4b6544
je 0x16c1e7
movl -0xc(%rbp), %eax
movl %eax, 0x34a4ca(%rip)    # 0x4b6544
cmpl $0x0, -0xc(%rbp)
jne 0x16c085
jmp 0x16c507
movl -0xc(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0x63d93(%rip)     # 0x1cfe28
movl 0x63d8d(%rip), %eax     # 0x1cfe28
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x5c(%rbp)
movsd 0x2fba(%rip), %xmm0     # 0x16f068
callq 0x92e0
movaps %xmm0, %xmm1
movsd 0x5612(%rip), %xmm0     # 0x1716d0
mulsd %xmm1, %xmm0
cvtsi2sdl -0x5c(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x68(%rbp)
movsd -0x68(%rbp), %xmm0
callq 0x96f0
movsd %xmm0, -0x70(%rbp)
movsd %xmm0, -0x80(%rbp)
movsd -0x68(%rbp), %xmm0
callq 0x9080
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x78(%rbp)
movsd %xmm0, -0x88(%rbp)
leaq 0x232e6f(%rip), %rax    # 0x39ef88
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movl $0x1, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x5c(%rbp), %eax
jge 0x16c1e5
movsd -0x80(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq -0x40(%rbp), %rax
movss %xmm0, (%rax)
movsd -0x88(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq -0x40(%rbp), %rax
movss %xmm0, 0x4(%rax)
movq -0x40(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x40(%rbp)
movsd -0x80(%rbp), %xmm0
movsd -0x70(%rbp), %xmm2
movsd -0x88(%rbp), %xmm1
mulsd -0x78(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x80(%rbp), %xmm0
movsd -0x78(%rbp), %xmm2
movsd -0x88(%rbp), %xmm1
mulsd -0x70(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x16c127
jmp 0x16c1e7
movl 0x63c3b(%rip), %eax     # 0x1cfe28
movl %eax, -0x5c(%rbp)
movl $0x1, -0x60(%rbp)
movl $0x0, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x16c448
movl -0x5c(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x5c(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl 0x63c00(%rip), %eax     # 0x1cfe28
jge 0x16c2d0
movq -0x8(%rbp), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movslq -0x5c(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movss (%rax), %xmm0
movq -0x38(%rbp), %rax
addss (%rax), %xmm0
movss %xmm0, -0x1c(%rbp)
movq -0x30(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
addss 0x4(%rax), %xmm0
movss %xmm0, -0x18(%rbp)
movq -0x30(%rbp), %rax
movss (%rax), %xmm0
movq -0x38(%rbp), %rax
subss (%rax), %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, (%rax)
movq -0x30(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
subss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, 0x4(%rax)
movq -0x30(%rbp), %rax
movq -0x1c(%rbp), %rcx
movq %rcx, (%rax)
movl -0x4c(%rbp), %eax
movl -0x5c(%rbp), %ecx
shll %ecx
addl %ecx, %eax
movl %eax, -0x4c(%rbp)
jmp 0x16c21f
leaq 0x232cb1(%rip), %rax    # 0x39ef88
movq (%rax), %rax
movslq -0x60(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
addq $-0x8, %rax
movq %rax, -0x48(%rbp)
movl $0x1, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x5c(%rbp), %eax
jge 0x16c432
movq -0x48(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x14(%rbp)
movl -0x50(%rbp), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl 0x63b0e(%rip), %eax     # 0x1cfe28
jge 0x16c411
movq -0x8(%rbp), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movslq -0x5c(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movss (%rax), %xmm0
movq -0x38(%rbp), %rax
addss (%rax), %xmm0
movss %xmm0, -0x1c(%rbp)
movq -0x30(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
addss 0x4(%rax), %xmm0
movss %xmm0, -0x18(%rbp)
movq -0x30(%rbp), %rax
movss (%rax), %xmm0
movq -0x38(%rbp), %rax
subss (%rax), %xmm0
movss %xmm0, -0x24(%rbp)
movq -0x30(%rbp), %rax
movss 0x4(%rax), %xmm0
movq -0x38(%rbp), %rax
subss 0x4(%rax), %xmm0
movss %xmm0, -0x20(%rbp)
movss -0x24(%rbp), %xmm0
movss -0x14(%rbp), %xmm2
movss -0x20(%rbp), %xmm1
mulss -0x10(%rbp), %xmm1
movd %xmm1, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, (%rax)
movss -0x24(%rbp), %xmm0
movss -0x10(%rbp), %xmm2
movss -0x20(%rbp), %xmm1
mulss -0x14(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x38(%rbp), %rax
movss %xmm0, 0x4(%rax)
movq -0x30(%rbp), %rax
movq -0x1c(%rbp), %rcx
movq %rcx, (%rax)
movl -0x4c(%rbp), %eax
movl -0x5c(%rbp), %ecx
shll %ecx
addl %ecx, %eax
movl %eax, -0x4c(%rbp)
jmp 0x16c311
movq -0x48(%rbp), %rax
movslq -0x60(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x16c2f4
movl -0x60(%rbp), %eax
shll %eax
movl %eax, -0x60(%rbp)
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x16c1fe
movl $0x0, -0x50(%rbp)
movl $0x1, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movl 0x639c9(%rip), %ecx     # 0x1cfe28
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x16c507
movl 0x639b8(%rip), %eax     # 0x1cfe28
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x50(%rbp), %eax
jg 0x16c49c
movl -0x50(%rbp), %eax
subl -0x54(%rbp), %eax
movl %eax, -0x50(%rbp)
movl -0x54(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x54(%rbp)
jmp 0x16c47b
movl -0x50(%rbp), %eax
addl -0x54(%rbp), %eax
movl %eax, -0x50(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0x16c4f7
movq -0x8(%rbp), %rax
movslq -0x4c(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movslq -0x50(%rbp), %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1c(%rbp)
movq -0x30(%rbp), %rcx
movq -0x40(%rbp), %rax
movq (%rcx), %rcx
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq -0x1c(%rbp), %rcx
movq %rcx, (%rax)
jmp 0x16c4f9
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x16c456
addq $0x90, %rsp
popq %rbp
retq