diff --git a/handoff/BLOCKMAP_529fe0.md b/handoff/BLOCKMAP_529fe0.md index 9075f92..d066d33 100644 --- a/handoff/BLOCKMAP_529fe0.md +++ b/handoff/BLOCKMAP_529fe0.md @@ -213,6 +213,66 @@ xmm8; затем xmm12−xmm8) [ср. decomp 184-185: A=[0x540874]−expf(K), we кривые; ни одна не достигает нужных 3.89×@171 (11.82 дБ) ⇒ применённый фильтр ≠ поточечная копия любой из живых кривых (подтверждение разрыва 22y) +## ДОПОЛНЕНИЕ 24l: точный декод FIR-цикла по дизасму (52b550–52b8bb) + константы + +Инструмент: scripts/disasm.py (capstone, base 0x180000000 над soothe_mem.bin). +ILT-резолв bigkernel-стабов даёт impl в 141100..141940 — все они IAT-thunk +массивы (`mov rax,[rip+..]; jmp rax`) вне дампа ⇒ тела за импортами; НО +последовательность и КОНСТАНТЫ цикла видны полностью: + +### Пошагово (float-ветка, флаг 0x540890==0): +``` +52b5a3: xmm6 = xmm8 · [ctx+0x540888] +52b5bf: th2030(bands[i], xmm6, n) ; bands *= 1.0·s888 (xmm8=double 1.0!) +52b5f6: th2270(bands[i], xmm7, n) ; scalar-transform-2 +52b62f: 535a70(scratch@540628, bands[i], n/2+1) ; DESIGN: swap→scratch=log(bands) +52b644: th2210(rcx=scratch, rdx=0, r8=FIR, r9=n/2+1) ; копия (+упаковка?) +52b696: FIR[n]=0 ; float-индекс n=4096 +52b69e: 52d920(&FIR[1], xmm13=-1.0, n/2-1) ; РАЗДЕЛЕНИЕ НА −1 ⇒ ИНВЕРСИЯ ЗНАКА бинов 1..n/2! +52b6ab: 52db50(&FIR[n/2+1], xmm9=0, n/2-1) ; ОБНУЛЕНИЕ верхней половины до exp! +52b6e1: opB = th1a90(FIR, buf548, mask598, n/2-1) ; FMA-complex (twiddle!) +52b716: BIGKERNEL 140b30(FIR, FIR, n/2+1) ; EXP in-place (тело за IAT) +52b74b: opC = th2180(FIR, buf548, mask598, n/2-1) +52b76d: FIR[n]=0 +52b77c: 52d990(FIR, WINfreq+n/2, n/2) ; окно: th2000-класс (FMA axpy!) +52b78c: 52db50(&FIR[n/2], xmm9=0, n/2) ; верхняя половина ×0 снова +52b7ba: opD = th1a90(...) +52b7d4: FIR[0]=1.0f; FIR[1]=0 + если флаг f890!=0: +52b803: th1880(FIR, {xmm10,xmm9}, n) ; парно-скалярный с (−1|0.8, 0) +52b81f: th1ca0(FIR, {xmm12,xmm9}, n) ; парно-скалярный с (1.0, 0) +52b857: th2030(FIR, s888, 2n) ; ×wet (=1 live) +52b893: final df0(FIR, track_i, n) +``` + +### Константы (статические значения из дампа): +| reg | адрес | значение | роль | +|-----|-------|----------|------| +| xmm8 | 1824c4140 (double) | 1.0 | множитель шага 1 = NO-OP при s888=1 | +| xmm13 | 1824c46a0 (double) | −1.0 | делитель бинов 1..n/2 (ИНВЕРСИЯ!) | +| xmm9 | xorps | 0.0 | обнуление верхних половин | +| xmm10 | 1824c4680 / 1824c3e28 | −1.0 / **0.8** | парный скаляр (0.8 активен в цикле) | +| xmm12 | 1824c3ea4 | 1.0 | парный скаляр 2 | +| xmm14 | 1824c4674 | −0.7 | (использование вне FIR) | +| xmm15 | 1824c4670 | −0.5 | (использование вне FIR) | +| xmm7 | вычисл. | sens·[540870]-цепочка | аргумент th2270 | + +### СЛЕДСТВИЯ (меняют понимание построения кернела): +1. Перед EXP: бины 1..n/2 = −log(bands) ⇒ после exp = **1/bands** (обратная + величина!), бины выше = exp(0)=1. Экспонента применяется НЕ к спектру маски + напрямую — вокруг неё twiddle-FMA стадии (ops B/C/D = радиальные проходы + FFT-класса над упакованным вещественным спектром; buf548 = cos/sin таблица, + mask598 = lane-select). +2. «×0.984» из 23d НЕ найден как константа цикла — либо внутри exp-IAT-обёртки, + либо следствие нормировки twiddle-стадий. Требуется численная репликация + пайплайна против живых захватов (rendersnap2 ph*.npz содержат готовые пары). +3. Шаг 1 и шаг ×s888 — no-op при дефолтных параметрах (s888=1, live 24j). +4. 52d920/52d990/52db50 = тонкие обёртки: 920→th2030/1d30 (scalar-op), + 990→th2000/1c40 (axpy!), db50→то же. «УМНОЖЕНИЕ на окно» реализовано + axpy-кернелом, «деление» — scalar-op. +5. Ops A–D работают над дескрипторными векторами (проверка тега [obj]==6 в + 4ca80; ошибка 0xfffffff3 при несоответствии). + ### Динамика (попытки перехвата; окружение) - realtime-playback НЕ тикает DSP (нет аудио-девайса; треды спят в futex); кривые 22y = результат инициализации при загрузке проекта diff --git a/scripts/disasm.py b/scripts/disasm.py new file mode 100644 index 0000000..d5d5e65 --- /dev/null +++ b/scripts/disasm.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +"""dis.py — quick capstone disassembler for soothe_mem.bin (base 0x180000000). +Usage: dis.py [len] [va2 len2 ...] +""" +import sys +from capstone import Cs, CS_ARCH_X86, CS_MODE_64 + +BASE = 0x180000000 +_data = open('/home/m/re-tools/soothe_mem.bin', 'rb').read() + +def dis(va, n=256): + off = va - BASE + code = _data[off:off + n] + md = Cs(CS_ARCH_X86, CS_MODE_64) + md.detail = False + out = [] + for ins in md.disasm(code, va): + s = '%08x %-24s %s %s' % (ins.address, ins.bytes.hex(), + ins.mnemonic, ins.op_str) + out.append(s) + if ins.mnemonic == 'ret': + break + return '\n'.join(out) + +if __name__ == '__main__': + a = sys.argv[1:] + for i in range(0, len(a), 2): + va = int(a[i], 16) + n = int(a[i + 1], 16) if i + 1 < len(a) else 256 + print('==== %x (len %x) ====' % (va, n)) + print(dis(va, n))