feat(isa): Add 32-bit CAS and DMA instructions to v0.56 - #139
Conversation
- Add CASB/CASH/CASW/CASD atomic compare-and-swap instructions * Encoding: 6..4=3'b001, 3..1=3'b101 (new CAS group) * Width: 14..12 distinguishes B/H/W/D (000/001/010/011) * 4 independent 5-bit register operands (SrcL/SrcR/SrcD/RegDst) * Supports aq/rl memory ordering (no far flag - use 48-bit HL.CAS*) - Add DMA transfer operation instruction * Encoding: 6..4=3'b000, 3..1=3'b101, 14..12=3'b111 * Separate from CAS group, fills previously unused slot * Two operands: [SrcL] address, SrcR control parameters - Update atomic.md: uncomment and translate CAS section to English - Update instlist.md: add CAS and DMA to instruction list - Fix gen_instruction_fragments.py: support 32-bit CAS descriptions - Add comprehensive changelog: update_v0.56_cas_dma.md - Generate instruction reference docs (.adoc format) Validation: ✅ No encoding conflicts (validate_spec.py passed) ✅ JSON spec compiled successfully with all 5 new instructions ✅ Auto-generated documentation complete Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces 32-bit atomic Compare-And-Swap (CAS) instructions (CASB, CASH, CASW, CASD) and a DMA operation instruction to LinxISA v0.56, updating core opcode definitions, metadata, and documentation. The review feedback highlights a logic bug in the reference counting assembly example where the retry label is placed after the load instruction, as well as minor formatting and syntax inconsistencies in the documentation tables.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| incr_refcount: | ||
| ld [refcount], ->x10 | ||
| retry: | ||
| addi x10, 1, ->x11 # Increment | ||
| casd.aq [refcount], x10, x11, ->x12 | ||
| b.ne x10, x12, retry # Retry if value changed |
There was a problem hiding this comment.
The reference counting CAS loop example contains a logic bug. The retry label is placed after the ld instruction, which means if the CAS operation fails (due to another thread modifying the refcount), the loop will retry without reloading the updated refcount value from memory into x10. This will result in an infinite loop or incorrect behavior under contention. Moving the retry label before the ld instruction resolves this issue.
| incr_refcount: | |
| ld [refcount], ->x10 | |
| retry: | |
| addi x10, 1, ->x11 # Increment | |
| casd.aq [refcount], x10, x11, ->x12 | |
| b.ne x10, x12, retry # Retry if value changed | |
| incr_refcount: | |
| retry: | |
| ld [refcount], ->x10 | |
| addi x10, 1, ->x11 # Increment | |
| casd.aq [refcount], x10, x11, ->x12 | |
| b.ne x10, x12, retry # Retry if value changed |
| | **Atomic Compare-And-Swap** | CASB, CASH, CASW, CASD | | ||
| | **DMA Operation** | DMA | |
There was a problem hiding this comment.
The newly added instructions CASB, CASH, CASW, CASD and DMA are listed as plain text, which is inconsistent with the other instructions in the table that link to their respective reference markdown files. They should be formatted as links to maintain consistency and completeness.
| | **Atomic Compare-And-Swap** | CASB, CASH, CASW, CASD | | |
| | **DMA Operation** | DMA | | |
| | **Atomic Compare-And-Swap** | [CASB](../../inst/misa_s/CASB.md), [CASH](../../inst/misa_s/CASH.md), [CASW](../../inst/misa_s/CASW.md), [CASD](../../inst/misa_s/CASD.md) | | |
| | **DMA Operation** | [DMA](../../inst/misa_s/DMA.md) | |
| | CASB | casb<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **byte** | | ||
| | CASH | cash<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **halfword** | | ||
| | CASW | casw<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **word** | | ||
| | CASD | casd<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **doubleword** | |
There was a problem hiding this comment.
The assembly format for the new CAS instructions in the table uses <{.aq,.rl,.aqrl}> instead of the official syntax <.{aq, rl, aqrl}> defined in lx_32.opc and the generated .adoc reference files. Updating this will ensure consistency across the documentation and the ISA specification.
| | CASB | casb<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **byte** | | |
| | CASH | cash<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **halfword** | | |
| | CASW | casw<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **word** | | |
| | CASD | casd<{.aq,.rl,.aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **doubleword** | | |
| | CASB | casb<.{aq, rl, aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **byte** | | |
| | CASH | cash<.{aq, rl, aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **halfword** | | |
| | CASW | casw<.{aq, rl, aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **word** | | |
| | CASD | casd<.{aq, rl, aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd} | Memory-register compare-and-swap **doubleword** | |
- change_log: move retry label before ld in CAS refcount loop (fix infinite-loop under contention — CAS failure left x10 stale)
- atomic.md: fix CAS asm syntax <{.aq,.rl,.aqrl}> -> <.{aq, rl, aqrl}> to match lx_32.opc / generated .adoc
- instlist.md: link CASB/CASH/CASW/CASD/DMA to reference pages; add CASB/CASH/CASW/CASD stub pages under misa_s/
Summary
This PR adds 5 new 32-bit instructions to LinxISA v0.56:
New Instructions
Atomic Compare-And-Swap (CAS)
6..4=001, 3..1=101, 14..12=0006..4=001, 3..1=101, 14..12=0016..4=001, 3..1=101, 14..12=0106..4=001, 3..1=101, 14..12=011Assembly format:
casb<.{aq, rl, aqrl}> [SrcL], SrcR, SrcD, ->{t, u, Rd}Semantics:
Features:
aq(acquire) andrl(release) memory orderingfarflag (use 48-bit HL.CAS* for remote cache operations)DMA Operation
6..4=000, 3..1=101, 14..12=111Assembly format:
dma [SrcL], SrcREncoding Space Allocation
The new instructions use previously unused encoding slots:
6..4=3'b001, 3..1=3'b101(new allocation, separate from existing atomics)6..4=3'b000, 3..1=3'b101, 14..12=3'b111(fills gap in atomic group)No conflicts with existing instructions:
14..12=00014..12=00114..12=01014..12=10014..12=10114..12=110Changes
Core Definition Files
isa/v0.56/opcodes/lx_32.opc- Added instruction definitionsisa/v0.56/meta.json- Updated version notesisa/v0.56/linxisa-v0.56.json- Recompiled instruction catalogTools
tools/isa/gen_instruction_fragments.py- Fixed 32-bit CAS description generationDocumentation
docs/isa/blockIntro/sys_block/atomic.md- Uncommented and updated CAS sectiondocs/isa/blockIntro/sys_block/instlist.md- Added instruction list entriesdocs/change_log/update_v0.56_cas_dma.md- Comprehensive changelogdocs/architecture/isa-manual/src/generated/instructions/*.adoc- Auto-generated reference docsValidation
✅ Encoding conflict check passed (
validate_spec.py)✅ JSON spec compiled successfully with all 5 new instructions
✅ Auto-generated documentation complete
✅ All register operands use full 5-bit encoding (r0-r31 accessible)
Comparison with 48-bit HL.CAS*
Recommendation: Use 32-bit CAS for typical single-node synchronization; use 48-bit HL.CAS* when
farflag is required.Testing
Please verify:
📋 Detailed changelog: update_v0.56_cas_dma.md