// File: /workspace/github_c_makefile_star2_O0/cyb70289[P]tt/tests/dft.c
// Function: main
int main(void)
{
	double in[8][2] = {
		{ 0.3535, 0 },
		{ 0.3535, 0 },
		{ 0.6464, 0 },
		{ 1.0607, 0 },
		{ 0.3535, 0 },
		{ -1.0607, 0 },
		{ -1.3535, 0 },
		{ -0.3535, 0 },
	};

	double out[8][2];
	tt_fft(out, in, 8);
	printf("DFT:\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", out[i][0], out[i][1]);

	double in2[8];
	for (int i = 0; i < 8; i++)
		in2[i] = in[i][0];
	tt_fft_real(out, in2, 8);
	printf("\nDFT(real):\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", out[i][0], out[i][1]);

	tt_ifft(in, out, 8);

	printf("\nIDFT:\n");
	for (int i = 0; i < 8; i++)
		printf("%.4f + %.4fj\n", in[i][0], in[i][1]);

	printf("\nDFT Leakage(peak at 6.2):\n");
	double sample[32][2];
	sample_sine(1000, 5000, 32, sample);	/* 32 / (5000 / 1000) = 6.2 */

	double dft[32][2];
	tt_fft(dft, sample, 32);

	double max = 0, mag[32];
	for (int i = 0; i < 32; i++) {
		mag[i] = sqrt(dft[i][0] * dft[i][0] + dft[i][1] * dft[i][1]);
		if (mag[i] > max)
			max = mag[i];
	}

	double ratio = 77 / max;
	for (int i = 0; i < 32; i++) {
		printf("%02d", i);
		int l = (int)round(mag[i] * ratio);
		while (l--)
			putchar('-');
		putchar('\n');
	};

	printf("\nSINC(5 ones):\n");
	sample_rect(5, 32, sample);
	tt_fft(dft, sample, 32);

	max = 0;
	for (int i = 0; i < 32; i++) {
		mag[i] = sqrt(dft[i][0] * dft[i][0] + dft[i][1] * dft[i][1]);
		if (mag[i] > max)
			max = mag[i];
	}

	ratio = 77 / max;
	for (int i = 0; i < 32; i++) {
		printf("%02d", i);
		int l = (int)round(mag[i] * ratio);
		while (l--)
			putchar('-');
		putchar('\n');
	};

#if 0
	/* FFT fast multiplication */
	uint ai = 12345678, bi = 87654321;
	double a[4] = { ai & 0xFFFF, ai >> 16, 0 , 0 };
	double b[4] = { bi & 0xFFFF, bi >> 16, 0 , 0 };
	double c[4][2];
	double A[4][2], B[4][2], C[4][2];
	tt_fft_real(A, a, 4);
	tt_fft_real(B, b, 4);
	for (int i = 0; i < 4; i++)
		tt_complex_mul(C[i], A[i], B[i]);
	tt_ifft(c, C, 4);
	printf("%u * %u = ", ai, bi);
	for (int i = 2; i >= 0; i--) {
		printf("(%.0f << %d)", c[i][0], 16 * i);
		if (i)
			printf(" + ");
	}
	printf("\n");
#endif

#if 0
	/* FFT rounding error */
	#define N	1024
	double a[N*2], b[N*2], c[N*2][2];
	double A[N*2][2], B[N*2][2], C[N*2][2];
	for (int i = 0; i < N; i++)
		a[i] = b[i] = 65535;
	for (int i = N; i < N*2; i++)
		a[i] = b[i] = 0;
	tt_fft_real(A, a, N*2);
	tt_fft_real(B, b, N*2);
	for (int i = 0; i < N*2; i++)
		tt_complex_mul(C[i], A[i], B[i]);
	tt_ifft(c, C, N*2);
	for (int i = 0; i < N*2; i++)
		if (fabs(c[i][1]) >  0.4)
			printf("%f %f\n", c[i][0], c[i][1]);
#endif

	return 0;
}

// Assembly:
subq $0x6a8, %rsp            # imm = 0x6A8
movl $0x0, 0x6a4(%rsp)
leaq 0x620(%rsp), %rdi
leaq 0x6d7f(%rip), %rsi      # 0x8030
movl $0x80, %edx
callq 0x1120
leaq 0x5a0(%rsp), %rdi
leaq 0x620(%rsp), %rsi
movl $0x8, %edx
callq 0x2db0
leaq 0x6df1(%rip), %rdi      # 0x80cd
movb $0x0, %al
callq 0x10b0
movl $0x0, 0x59c(%rsp)
cmpl $0x8, 0x59c(%rsp)
jge 0x1350
movslq 0x59c(%rsp), %rcx
leaq 0x5a0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x59c(%rsp), %rcx
leaq 0x5a0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
leaq 0x6d7a(%rip), %rdi      # 0x80b0
movb $0x2, %al
callq 0x10b0
movl 0x59c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x59c(%rsp)
jmp 0x12ee
movl $0x0, 0x54c(%rsp)
cmpl $0x8, 0x54c(%rsp)
jge 0x13a4
movslq 0x54c(%rsp), %rcx
leaq 0x620(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x54c(%rsp), %rax
movsd %xmm0, 0x550(%rsp,%rax,8)
movl 0x54c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54c(%rsp)
jmp 0x135b
leaq 0x5a0(%rsp), %rdi
leaq 0x550(%rsp), %rsi
movl $0x8, %edx
callq 0x34d0
leaq 0x6cf9(%rip), %rdi      # 0x80be
movb $0x0, %al
callq 0x10b0
movl $0x0, 0x548(%rsp)
cmpl $0x8, 0x548(%rsp)
jge 0x1439
movslq 0x548(%rsp), %rcx
leaq 0x5a0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x548(%rsp), %rcx
leaq 0x5a0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
leaq 0x6c91(%rip), %rdi      # 0x80b0
movb $0x2, %al
callq 0x10b0
movl 0x548(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x548(%rsp)
jmp 0x13d7
leaq 0x620(%rsp), %rdi
leaq 0x5a0(%rsp), %rsi
movl $0x8, %edx
callq 0x3160
leaq 0x6c71(%rip), %rdi      # 0x80cb
movb $0x0, %al
callq 0x10b0
movl $0x0, 0x544(%rsp)
cmpl $0x8, 0x544(%rsp)
jge 0x14ce
movslq 0x544(%rsp), %rcx
leaq 0x620(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x544(%rsp), %rcx
leaq 0x620(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
leaq 0x6bfc(%rip), %rdi      # 0x80b0
movb $0x2, %al
callq 0x10b0
movl 0x544(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x544(%rsp)
jmp 0x146c
leaq 0x6bfe(%rip), %rdi      # 0x80d3
movb $0x0, %al
callq 0x10b0
leaq 0x340(%rsp), %rsi
movsd 0x6b1c(%rip), %xmm0     # 0x8008
movsd 0x6b1c(%rip), %xmm1     # 0x8010
movl $0x20, %edi
callq 0x1830
leaq 0x140(%rsp), %rdi
leaq 0x340(%rsp), %rsi
movl $0x20, %edx
callq 0x2db0
xorps %xmm0, %xmm0
movsd %xmm0, 0x138(%rsp)
movl $0x0, 0x2c(%rsp)
cmpl $0x20, 0x2c(%rsp)
jge 0x15ed
movslq 0x2c(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x2c(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm2
movslq 0x2c(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
movslq 0x2c(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
mulsd 0x8(%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x1170
movslq 0x2c(%rsp), %rax
movsd %xmm0, 0x30(%rsp,%rax,8)
movslq 0x2c(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
ucomisd 0x138(%rsp), %xmm0
jbe 0x15db
movslq 0x2c(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x138(%rsp)
jmp 0x15dd
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x152c
movsd 0x6a23(%rip), %xmm0     # 0x8018
divsd 0x138(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
cmpl $0x20, 0x1c(%rsp)
jge 0x1678
movl 0x1c(%rsp), %esi
leaq 0x6ad1(%rip), %rdi      # 0x80ef
movb $0x0, %al
callq 0x10b0
movslq 0x1c(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
mulsd 0x20(%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0x18(%rsp)
cmpl $0x0, %eax
je 0x1661
movl $0x2d, %edi
callq 0x1040
jmp 0x1643
movl $0xa, %edi
callq 0x1040
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x160c
leaq 0x6a75(%rip), %rdi      # 0x80f4
movb $0x0, %al
callq 0x10b0
leaq 0x340(%rsp), %rdx
movl $0x5, %edi
movl $0x20, %esi
callq 0x18e0
leaq 0x140(%rsp), %rdi
leaq 0x340(%rsp), %rsi
movl $0x20, %edx
callq 0x2db0
xorps %xmm0, %xmm0
movsd %xmm0, 0x138(%rsp)
movl $0x0, 0x14(%rsp)
cmpl $0x20, 0x14(%rsp)
jge 0x178c
movslq 0x14(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movslq 0x14(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd (%rax), %xmm2
movslq 0x14(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
movslq 0x14(%rsp), %rcx
leaq 0x140(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
mulsd 0x8(%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x1170
movslq 0x14(%rsp), %rax
movsd %xmm0, 0x30(%rsp,%rax,8)
movslq 0x14(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
ucomisd 0x138(%rsp), %xmm0
jbe 0x177a
movslq 0x14(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x138(%rsp)
jmp 0x177c
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x16cb
movsd 0x6884(%rip), %xmm0     # 0x8018
divsd 0x138(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x0, 0x10(%rsp)
cmpl $0x20, 0x10(%rsp)
jge 0x1817
movl 0x10(%rsp), %esi
leaq 0x6932(%rip), %rdi      # 0x80ef
movb $0x0, %al
callq 0x10b0
movslq 0x10(%rsp), %rax
movsd 0x30(%rsp,%rax,8), %xmm0
mulsd 0x20(%rsp), %xmm0
callq 0x1060
cvttsd2si %xmm0, %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, 0xc(%rsp)
cmpl $0x0, %eax
je 0x1800
movl $0x2d, %edi
callq 0x1040
jmp 0x17e2
movl $0xa, %edi
callq 0x1040
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x17ab
xorl %eax, %eax
addq $0x6a8, %rsp            # imm = 0x6A8
retq
nopw %cs:(%rax,%rax)