The decode side is finished

Export and interpolation solved. 79 of 80 probed opcodes, and the silent-empty inventory is down from twelve entries to three.

Their operands are names rather than registers, so the codes were measured: assemble once per spelling holding everything else constant, and read the bits that moved. Fifty codes in one round trip, and enumerating spellings is not transcribing values - a spelling that does not exist is refused and drops out.

Surprises

The attribute field is five bits and I went looking to prove it was six. Probed attr47, attr52, attr61; the assembler refused all three as out of bounds. The assumption was wrong and the answer was better than the one being looked for.

A two-bit field could not be found because the search started at five. Register fields are five to nine bits, immediates were 16 and up, and a channel selector is neither. Three opcodes reported unsolvable for want of a width in the list - which reads as a gap in the probes and was a gap in the solver.

Width reconciliation was keyed by kind and therefore blind to its own disagreement. v_interp_p1 reads bits 7:0 as a register, v_interp_mov reads them as a selector with three legal values. Keyed by kind they never met; the consistency check ignores kind and reported a disagreement nothing could act on. Two parts of one tool disagreeing about what a field is.

The differential comparison had a defect the whole time and nothing could see it. normalise took the first word of each comma-piece to strip trailing modifiers, so exp mrt0 v0 lost v0. It could not fail while exports decoded no operands - there was nothing to compare. Solving the layout turned a silent omission into a red test on the first run. The D202 lesson from the other side: a vacuous pass can hide a fault in the check, not only in the thing checked.

And one loosening, recorded rather than hidden. null is an export target in an export and a special register in a vector instruction, and the reference prints it in both. Replacing the token with its code broke every instruction using the register sense, so the code is offered alongside the spelling - which accepts a decoded 9 where the reference said null. Real, small, and cheaper than threading the family through the comparison.