mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-22 10:56:20 +08:00
3005babab8
Completes the fused-FMA slice deferred by the VOP3P first slice (#145). v_pk_fma_f16 previously failed emission loudly because an f32 multiply-add followed by an f16 pack rounds twice; the pinned miss is fma(0x4100, 0x7522, 0x04EA) = 0x7A6B fused vs 0x7A6A via f32. The f32 product of two f16 values is exact, so only the addition needs correcting: compute sum = RN(product + addend), recover the exact residual with Knuth 2Sum, and if the sum is inexact with an even significand, step one ulp towards the true value. That is round-to-odd, and rounding the f32 result to f16 with round-to-nearest-even then matches a true fused f16 FMA exactly (24 significand bits >= 11 + 2). Inf/NaN inputs turn the residual into NaN, the ordered compare skips the parity fix, and IEEE special behaviour passes through unchanged. The op_sel/op_sel_hi/neg_lo/neg_hi source modifiers apply to src2 through the existing operand path; clamp stays rejected like the other packed ops. Every op in the 2Sum chain is decorated NoContraction: without it the AMD RDNA3 Windows driver folds the sequence, collapses the residual to zero, and the midpoint case decays to the double-rounded result. This was caught by running the emitted shader on a real device (see below). Verification: - A mirror of the emitted sequence was checked against an exact integer reference (every finite f16 is m * 2^-24, so a*b + c is an exact Int128 multiple of 2^-48, rounded once to f16 RNE) across 34M cases: directed midpoint pins, random sweeps over all operand classes, tiny-addend midpoint stress, subnormal products, and Inf/NaN propagation. 0 mismatches. - ShaderDump gains a pk-f16 program covering all five packed opcodes, both fma modifier paths, and the pinned constants; all programs decode and emit. - The executable exec program now computes the pinned fma and its negated-addend twin (0x7A6B7A6B / 0x7A6A7A6A, straddling an f16 midpoint) and stores them at offsets 20/24; GpuConformance checks both on device. All values match on an AMD Radeon RX 7700 XT.