P3.1: extract FFT code from rt snap (extract_fft.py); decode cplx_mul 0x8440 = in-place elementwise double mult, twiddle loader 0x39b00 stride copy, dispatcher 0x535a70->0x140a10/70->jumptable[0x1826159a0]=4; implement cplx_mul_scalar_inplace

This commit is contained in:
2026-08-20 02:25:59 +03:00
parent 22e4599e0a
commit 88422034f5
4 changed files with 101 additions and 0 deletions
+32
View File
@@ -55,3 +55,35 @@ outer while (uVar24 < (iVar25-1+iVar33)/iVar33)
- Copied to scratch by FUN_180039b00( log2N, dst ): step lVar18 = 1 << (10 - log2N) for N<=1024.
- So for N = 2^m: twiddle angles sampled from table with stride 2^(10-m). For N>1024 separate (two-pass) branch (unresolved).
- Stage kernels (FUN_18000bfc0/18000c5e0) consume these with 0x40-complex chunks, cplx-mul=180008440, acc=FUN_1800437c0/180044700.
## ============ UPDATE 2026-08-20 (P3: code extracted from rt snap, objdump) ============
Raw code extracted from /tmp/snap_rt.bin via handoff/extract_fft.py → /tmp/fft/*.bin.
### cplx_mul 0x180008440 = IN-PLACE ELEMENTWISE DOUBLE MULTIPLY (not complex!):
signature (rcx=dst, rdx=src, r8d=count): dst[i] *= src[i] (double).
kernel 0x18003fa20: scalar path mulsd, vector path mulpd (4-wide). Corrects the
"cplx-mul=180008440" label — the complex multiply is done via SEPARATE re/im passes
(interleaved layout), 0x8440 is the scalar elementwise multiply.
### twiddle loader FUN_180039b00 (log2N=ecx, dst=rdx):
N = 1<<log2N; count = N/4 (sar $2 after N/2 sar).
if log2N > 10: separate two-pass branch (0x180039dc9).
else stride = 1 << (10-log2N); copy sin_table[0x182616800 + k*stride*8] -> dst[k], k=0..N/4-1.
sin_table DAT_182616800 = sin(k·2π/1024) for k=0..256 (257 valid doubles, then garbage).
=> twiddle[k] = sin(k·stride·2π/1024), the quarter-period sample set.
### stage kernels FUN_18000bfc0 / 18000c5e0 (butterfly):
prologue stack 0x470 (scratch 0x200×2 doubles). Per 0x40-complex chunk:
0x180140c40(src, scratch, scratch+0x200, 0x40) — load/format twiddle into scratch
0x8440(dst, scratch, 0x40) — dst *= scratch (elementwise)
0x8440(dst, scratch+0x200, 0x40) — dst *= scratch+0x200
then butterfly arithmetic + acc (FUN_1800437c0/044700). Full loop still to transcribe.
### dispatcher 0x535a70 → 0x140a10 (scalar) / 0x140a70 (vector) (per NOTES:166).
Second-level dispatch: 0x140a10/140a70 read global index [0x1826159a0] (=4 at capture)
then jump through tables:
scalar 0x182617548 = {0x180141380, 0x1801413a0, ..., 0x1801414a0} (12 entries, [4]=0x180141400)
vector 0x182617588 = {0x180141440, ..., 0x180141560} ([4]=0x1801414c0)
These are the per-size/per-type stage kernels (0x1801413xx/1415xx family).