Correct the addend flag: it picks immediate or register, not present or absent - #25
Merged
Conversation
…or absent A flag landed under the wrong name, and the wrong name came from a reading that had already survived a prediction, which is the interesting part. It was ADDEND_ENABLE, described as including the addend or not, because clearing it turned a*m+d into a*m on four inputs. Clearing it actually switches the addend slot from an immediate to a register. The synthesised instruction that verified "a*m" had an ordinary encoded constant left in the slot, 0xb0, and with the immediate bit clear that byte names register 88 -- above the sixteen the field reaches, so it reads zero. The addend was never absent. It was zero, by accident, and the prediction passed because zero and absent are indistinguishable in a sum. The slot uses the same shape as the register field elsewhere, `r << 1` with the low bit ignored. Verified by rewriting instructions to `rd = rd * m + rs` for every ordered pair of three live registers at two multipliers, predicting all four threads each: eighteen rewrites, seventy-two exact values. That gives the register-plus-register add, as `rd * 1 + rs`, which no immediate form can express. `encode_fma` now takes either an immediate addend or an `addend_register` and refuses both at once, and a zero addend is stated for what it is: a register index chosen because it cannot be reached, with a test asserting that property so a future part with more registers cannot silently turn it into whatever that register holds. One more prediction miss worth recording, because the encoding was right and my model was wrong. The register-addend rewrites first matched on thread 0 and failed on the other three: thread gid reads x[gid], x[gid+1] and x[gid+2], and the prediction used thread 0's inputs throughout. 18 of 18 once the shift was applied. When a hypothesis matches exactly on one thread and misses on the rest, the harness is the suspect, not the field map. 29 ISA tests. Lint clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A flag landed under the wrong name, and the wrong name came from a reading that had already
survived a prediction — which is the interesting part.
It was
ADDEND_ENABLE, described as including the addend or not, because clearing it turneda*m+dintoa*mon four inputs.Clearing it actually switches the addend slot from an immediate to a register. The synthesised
instruction that verified "a*m" had an ordinary encoded constant left in the slot,
0xb0, and withthe immediate bit clear that byte names register 88 — above the sixteen the field reaches, so it
reads zero. The addend was never absent. It was zero, by accident, and the prediction passed
because zero and absent are indistinguishable in a sum.
The register form
Same shape as the register field elsewhere:
r << 1, low bit ignored. Verified by rewritinginstructions to
rd = rd * m + rsfor every ordered pair of three live registers at twomultipliers, predicting all four threads each — 18 rewrites, 72 exact values.
That gives the register-plus-register add, as
rd * 1 + rs, which no immediate form canexpress.
encode_fmanow takes either an immediateaddendor anaddend_registerand refusesboth at once. A zero addend is stated for what it is — a register index chosen because it cannot
be reached — with a test asserting that property, so a future part with more registers cannot
silently turn it into whatever that register holds.
One more prediction miss, where the encoding was right and my model was wrong
The register-addend rewrites first matched on thread 0 and failed on the other three: thread
gidreads
x[gid],x[gid+1],x[gid+2], and my prediction used thread 0's inputs throughout. 18 of18 once the shift was applied. When a hypothesis matches exactly on one thread and misses on the
rest, the harness is the suspect, not the field map.
29 ISA tests. Lint clean.
🤖 Generated with Claude Code