diff options
| author | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:41:29 -0500 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:54:48 -0500 |
| commit | a169391e6019d6356cc0492c5a25cf7dbfc22fa3 (patch) | |
| tree | 0dce3444db29d490bef16383491d0caeedc20d18 /src/tests/video_core | |
| parent | ef3ae4ae23b2148fac5b7b335c001b2802a9222b (diff) | |
shader: count only register writes in the callee link check
The check that a native callee keeps its link register read bits 16-23
of every instruction as a destination. RET was exempt, but BRA, NOP and
ISETP/FSETP (which write predicates) also have zero there, so callees
with an R0 link that compare or branch were rejected. IMAD.WIDE writes a
register pair, so its second register now counts as well.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
Diffstat (limited to 'src/tests/video_core')
| -rw-r--r-- | src/tests/video_core/ampere_returns.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/tests/video_core/ampere_returns.cpp b/src/tests/video_core/ampere_returns.cpp index 56b8b374da..163758e07e 100644 --- a/src/tests/video_core/ampere_returns.cpp +++ b/src/tests/video_core/ampere_returns.cpp @@ -48,4 +48,31 @@ TEST_CASE("Ampere callees still reject writes to the link", "[video_core][ampere REQUIRE(lowered.error == "native callee overwrites link register"); REQUIRE(lowered.error_offset == 0x30); } + +TEST_CASE("Ampere callees can compare into predicates with an R0 link", "[video_core][ampere]") { + // ISETP's zero destination field is not a write to R0. + const std::array<Instruction, 5> code{{ + {{0x00007802, 0x20, 0x00000f00, 0}}, + {{0x00007944, 0x10, 0x03c00000, 0}}, + {{0x0000794d, 0, 0x03800000, 0}}, + {{0x0100720c, 0x00000002, 0x03f06070, 0}}, + {{0x00007950, 0xffffffb0, 0x03c3ffff, 0}}, + }}; + REQUIRE(static_cast<bool>(LowerToMaxwell(code))); +} + +TEST_CASE("Ampere callees reject a wide multiply over the link", "[video_core][ampere]") { + // IMAD.WIDE.U32 R54:R55 writes the R55 link. + const std::array<Instruction, 5> code{{ + {{0x00377802, 0x20, 0x00000f00, 0}}, + {{0x00007944, 0x10, 0x03c00000, 0}}, + {{0x0000794d, 0, 0x03800000, 0}}, + {{0x01367225, 0x00000002, 0x078e00ff, 0}}, + {{0x37007950, 0xffffffb0, 0x03c3ffff, 0}}, + }}; + const auto lowered = LowerToMaxwell(code); + REQUIRE(!static_cast<bool>(lowered)); + REQUIRE(lowered.error == "native callee overwrites link register"); + REQUIRE(lowered.error_offset == 0x30); +} } // namespace |
