Skip to content

feat(shader): decode halt, trap return, code end, GWS and ordered count instructions - #1253

Merged
adriadam10 merged 5 commits into
boykopovar:mainfrom
popcoder565:feat/shader-system-opcodes
Oct 8, 2026
Merged

adriadam10 merged 5 commits into
boykopovar:mainfrom
popcoder565:feat/shader-system-opcodes

Conversation

@popcoder565

Copy link
Copy Markdown
Contributor

What

Decodes the 11 instructions from tools/rdna_isa.txt that the decoder did not recognize and that no open pull request covers. Shader instructions: 1139/1166 -> 1150/1166. The other 16 are in #697, #895, #1198, #1217, #1049 and #1053.

  • s_sethalt (SOPP 0x0d): with SIMM16[0] clear it is a no-op; with it set it throws at translation, as the wave would halt until a debugger resumes it.
  • s_sendmsghalt (SOPP 0x11) and s_rfe_b64 (SOP1 0x22) throw at translation: the first halts the wave, the second returns from a trap handler, which recompiled shaders do not run in.
  • s_code_end (SOPP 0x1f) throws if it is reached. Linear decoding stops at it like at s_endpgm when no branch targets past it, so a program whose last instruction is a backward branch followed by s_code_end padding decodes; it failed with unsupported SOPP opcode 31 before.
  • ds_gws_init, ds_gws_sema_v, ds_gws_sema_br, ds_gws_sema_p, ds_gws_sema_release_all, ds_gws_barrier (DS 0x19, 0x1a, 0x1b, 0x1c, 0x18, 0x1d) and ds_ordered_count (DS 0x3f) decode with their operands (the GWS data VGPR is in the ADDR field, no VGPR destination) and throw at translation: GWS barriers and semaphores shared by waves of different workgroups, and GDS counters updated in wave launch order, are not modeled.

Sources:

  • Encodings and operand fields: LLVM llvm/lib/Target/AMDGPU/SOPInstructions.td and llvm/lib/Target/AMDGPU/DSInstructions.td (has_gws_data0: "data0 is encoded as addr"), checked against llvm/test/MC/AMDGPU/gfx10_asm_sop.s and llvm/test/MC/AMDGPU/gfx10_asm_ds.s.
  • s_code_end as end-of-code padding: AMDGPUTargetAsmStreamer::EmitCodeEnd in llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp.
  • GWS barriers counted over waves: int_amdgcn_ds_gws_init and int_amdgcn_ds_gws_barrier in llvm/include/llvm/IR/IntrinsicsAMDGPU.td.
  • s_sethalt: RDNA 2 ISA guide, SOPP opcode table (SIMM16[0] = 1 halts the wave, 0 resumes it). The no-op for 0 is not measured on hardware and is recorded in TechnicalDebt.

Tested

Windows 10 (19045), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release, NVIDIA GeForce RTX 3060 Laptop GPU.

  • New agc_wave_control_decode: decodes every new opcode and checks its operands, checks the message each refused case throws, and recompiles a program padded with s_code_end after its last branch.
  • New agc_driver_scalar_sethalt: runs s_sethalt 0 and an s_code_end-padded program on the GPU and checks the stored results.
  • Full ctest passes except guest_system_font, which fails the same way on main on Windows (test(font): move the console font aside instead of deleting it while its face is mapped #1172).

No title or homebrew tested; not run on AMD hardware.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1217 core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp L1044
core/shader/recompiler/RdnaDecoder/src/RdnaScalarOpDecoder.cpp L41
#1306 core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaOpcode.hpp L1044

…nt instructions

s_sethalt with SIMM16[0] clear is a no-op; s_sethalt 1, s_sendmsghalt, a reached s_code_end, s_rfe_b64, the ds_gws_* instructions and ds_ordered_count throw with the reason at translation. Linear decoding stops at s_code_end like at s_endpgm, so code padded with s_code_end after a final backward branch decodes. Encodings from LLVM SOPInstructions.td and DSInstructions.td, checked against the gfx10 MC tests; semantics from the RDNA 2 ISA guide.
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Progress report (3069680 → 2e0b7bb)

📈 GPU shader instructions: 98.03% (+0.95%, +11 implemented instructions)

✅ 11 implemented
Encoding Name
DS DS_GWS_BARRIER
DS DS_GWS_INIT
DS DS_GWS_SEMA_BR
DS DS_GWS_SEMA_P
DS DS_GWS_SEMA_RELEASE_ALL
DS DS_GWS_SEMA_V
DS DS_ORDERED_COUNT
SOP1 S_RFE_B64
SOPP S_CODE_END
SOPP S_SENDMSGHALT
SOPP S_SETHALT

popcoder565 and others added 4 commits October 8, 2026 11:49
The test is added to ctest in its own BUILD_TESTING block, as agc_vop1_sdwa_move_decode is, instead of in the shared test list that boykopovar#1187 also extends.
… shared lines

boykopovar#1372 adds its test after the vop1 decode tests and boykopovar#1314 its debt entry after s_setkill, the places where this branch added its own. The wave control decode test now precedes the vop1 decode tests and the s_sethalt entry follows sceRtcParseDateTime, so either pull request can merge first without a conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
boykopovar#1398 and boykopovar#1399 both rewrite the sceRtcParseDateTime entry that the s_sethalt entry followed. It now follows the libSceAudio3d entries, which no open pull request edits, so either can merge first without a conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the decoder tables, the translation throws and both new tests against main: the decode test doesn't compile without the change and agc_driver_scalar_sethalt needs it to decode. Measured s_sethalt 0 on the HW oracle (gfx1035): the wave continues and the next VALU op gives the normal result, so the no-op is right. Full ctest green after the rebase.

Added on top of your branch (rebased onto current main, two conflicts in the agcTest list, resolved by keeping main's list since your later commit registers the test separately):

  • TechnicalDebt: the s_sethalt line now records the measurement instead of "not measured on hardware".

Merging once CI is green on the rebased head (the first runs were waiting for approval).

@adriadam10
adriadam10 force-pushed the feat/shader-system-opcodes branch from 3814fdf to 2e0b7bb Compare October 8, 2026 10:01
@adriadam10
adriadam10 merged commit e28fa01 into boykopovar:main Oct 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants