Repository navigation
feat(isa): t27a mnemonic table and strict decoder for 47 TRI-27 opcodes (Closes #6516) - #6765
Merged
Merged
Conversation
…es (Closes #6516) New module T27aMnemonics (specs/isa/t27a_mnemonics.t27, uses isa::ternary_encoding): - opcode_at(i): table index 0..46 -> opcode byte in OPCODE_VALUES order, 256 otherwise (if-chain over the OP_ constants, no array indexing) - index_of(op): its inverse, 47 for an undefined byte - strict_decode(byte): the byte for a defined opcode, 256 otherwise, so the 209 undefined bytes are rejected instead of aliasing NOP Tests: index_of(opcode_at(i)) == i for all 47, order agrees with OPCODE_VALUES, 47 accepted / 209 rejected, and a negative control where decode_opcode(1) is NOP while strict_decode(1) is 256. Refs #6488 #6507 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
October 6, 2026 11:48
This was referenced Oct 6, 2026
Merged
This was referenced Oct 6, 2026
Contributor
This was referenced Oct 6, 2026
gHashTag
added a commit
that referenced
this pull request
Oct 6, 2026
…6507) (#6789) * feat(isa): t27a mnemonic table and strict decoder for 47 TRI-27 opcodes (Closes #6516) New module T27aMnemonics (specs/isa/t27a_mnemonics.t27, uses isa::ternary_encoding): - opcode_at(i): table index 0..46 -> opcode byte in OPCODE_VALUES order, 256 otherwise (if-chain over the OP_ constants, no array indexing) - index_of(op): its inverse, 47 for an undefined byte - strict_decode(byte): the byte for a defined opcode, 256 otherwise, so the 209 undefined bytes are rejected instead of aliasing NOP Tests: index_of(opcode_at(i)) == i for all 47, order agrees with OPCODE_VALUES, 47 accepted / 209 rejected, and a negative control where decode_opcode(1) is NOP while strict_decode(1) is 256. Refs #6488 #6507 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(isa): t27a MVP -- TRI-27 assembler/disassembler round-trip (Refs #6507) - specs/isa/ternary_encoding.t27: adopt the T736 field table side by side with the pinned one (t27a_imm_form, t27a_src2_form, t27a_encode, t27a_src1, t27a_src2, t27a_imm). The pinned table stays, because decoder.zig at PINNED_REVISION and the replay tool still read it (T27A_CONSUMER_GAP). Both bare-expression invariants are now `assert` blocks, so the generated Zig no longer rejects them and the spec's tests run in the reference path. Three new tests: the t27a forms partition the 47 opcodes, keep what the pinned table loses, and move no pinned word. - specs/compiler/theory/isa_round_trip.t27: drop the proposal copy of the table; T736 now checks the adopted copy through `use` (one home for the rule). - specs/isa/t27a.t27 (new, module T27a): the spec-level t27a entry point. assemble / assemble_status read one line of text into a word; listing_char / listing_len / listing_is print a word back. Non-canonical words (209 undefined bytes, stray bits, registers 27..31) list as `.word N`, the explicit invalid marker, and `.word` assembles, so every 32-bit word round-trips. Tests: every one of the 47 opcodes over a 3^4 x 5 operand grid (word -> text -> word, operands preserved), all 256 one-byte words, 4096 LCG words, and 30 ill-formed inputs with their status codes. - Seals: ternary_encoding and isa_round_trip resealed, t27a sealed. Parked (foreign code, no owner-approved-foreign label): a t27c asm/disasm CLI subcommand (Rust) and the same table in gHashTag/trinity decoder.zig (Zig, other repository). Depends on #6765 (specs/isa/t27a_mnemonics.t27). Refs #6488. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
added a commit
that referenced
this pull request
Oct 6, 2026
…#6442) (#6924) Two things on master that #6879 did not cover: - quiet census (cli-tri `tri census pin --gate`): "named a path but not quiet" 159 -> 160. `tri census explain` puts it on one file alone, .github/workflows/queen-export-push.yml from #6847: its new env line `GH_TOKEN: ${{ secrets.GH_AGENT_TOKEN || github.token }}` (line 66) is one more excluded, non-quiet line; the two lines below it only shifted by three. tools/census/quiet.txt re-recorded with `tri census pin --bless`; fetches and shell did not move. - specs/isa/t27a_mnemonics.t27 (#6765) had no saved seal. Sealed on the t27c lab with zig on PATH (`PATH=/opt/zig:$PATH t27c seal --save`): tests 5/5 pass, `seal --verify` all hashes MATCH, `tri seals sync-twins` wrote nothing, check_seal_coverage OK 1331 hold. Refs #6507 Refs #6488 Co-authored-by: Claude Opus 5.5 <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.
Closes #6516
Refs #6488 #6507
What
New file
specs/isa/t27a_mnemonics.t27, moduleT27aMnemonics,use isa::ternary_encoding;. Nothing else changes.opcode_at(i: u32) -> u32-- table index 0..46 to opcode byte, inOPCODE_VALUESorder; 256 for any other index. Written as an if-chain over theOP_constants, no array indexing.index_of(op: u32) -> u32-- the inverse; 47 for an undefined byte.strict_decode(byte: u32) -> u32-- the byte for one of the 47 opcodes, 256 (INVALID_OPCODE) for the other 209.decode_opcodeis left as it is; it appears only in the negative control.Tests (run time, through
use)index_of_inverts_opcode_at_for_all_47--index_of(opcode_at(i)) == ifor every i in 0..46; out-of-range index gives 256.opcode_at_follows_opcode_values--opcode_at(i) == OPCODE_VALUES[i]for all 47, strictly increasing (so no byte appears twice).opcode_at_inverts_index_of_on_defined_bytes-- the other direction over all 256 bytes; 209 bytes have no index.strict_decode_accepts_47_and_rejects_209-- 47 accepted, 209 rejected, and the accepted set equalsis_defined_opcode.undefined_byte_is_rejected_not_nop-- negative control:decode_opcode(1) == OP_NOPwhilestrict_decode(1) == 256; byte 0 (real NOP) is still accepted.the_bytes_split_into_opcodes_and_rejects-- 47 + 209 == 256.Checks run locally (t27c release binary at master 5bad205)
t27c typecheck specs/isa/t27a_mnemonics.t27->Typecheck OK (0 errors, 0 warnings)t27c gen-c specs/isa/t27a_mnemonics.t27 > /dev/null-> exit 0t27c test-report specs/isa/t27a_mnemonics.t27-> 5/5 pass, 1 invariantindex_of(OP_RET)from 32 to 33 fails 2 tests; changing<to<=instrict_decodefails 2 tests.grep -c '^test '-> 5;grep -c strict_decode-> 12tools/dupe_scan.py --like-> nothing in this file is written elsewhere🤖 Generated with Claude Code