Skip to content

Lowering: LEA.HI with a constant base and no carry (40 vertex programs drawn again) - #1437

Merged
NotRexed merged 1 commit into
NotRexed:mainfrom
Joey-Magnus:fix/lea-hi-constant
Nov 10, 2026
Merged

NotRexed merged 1 commit into
NotRexed:mainfrom
Joey-Magnus:fix/lea-hi-constant

Conversation

@Joey-Magnus

Copy link
Copy Markdown
Contributor

What

LEA.HI Rd, Ra, c[bank][offset], RZ, s with no .X and no carry out (native op 0xa11) stopped the Ampere -> Maxwell lowering with "native constant LEA carry mode". A program that does not lower is never drawn, so 40 of OoT's vertex programs were missing. All three failing encodings in the log have words[2] = 0x078fd8ff, for example 0d007a11 00c03100 078fd8ff 000fe400 (programs e9274029dc836a07, 2d279e3ea5e7499f and others).

The instruction is the constant plus the high word of (Ra << s), that is c + (Ra >> (32 - s)). It now lowers the same way as the register form's high word (0x211):

  • the constant goes into R251, as every constant operand does (operand(1, false));
  • SHR R250 = Ra >> (32 - s), arithmetic when .SX32 (bit 73) is set;
  • IADD Rd = R250 + R251.

LEA.HI.X.SX32 keeps its existing lowering. A carry out, a high source (Rc not RZ) or a zero shift is still refused.

Tested

  • --prepare-shaders on the full shader list (Linux, RTX 4070 Ti, fresh caches): 83 -> 43 programs that do not lower. All 40 "native constant LEA carry mode" programs now lower and compile, and the other failure kinds are unchanged (17 formatted surface load, 3 integer min/max, 3 texel fetch, 3 scratch registers, and so on).
  • In game: the Water Temple save loads and draws normally with the new hookshot_vk.so.
  • tests/test_lower_lea_hi_constant.py (new, registered in run_all.py like the ATOMG test) checks the encodings from the log, an .SX32 case and the forms that must still be refused. It fails without this change. The full tests/run_all.py passes: 190 passed, 19 skipped for missing tools.

🤖 Generated with Claude Code

…s drawn again)

LEA.HI Rd, Ra, c[bank][offset], RZ, s with no .X and no carry out
(native op 0xa11) stopped the Ampere -> Maxwell lowering as "native
constant LEA carry mode", so 40 of OoT's vertex programs were never
drawn. It is the constant plus the high word of (Ra << s): the constant
in R251 as every constant operand, SHR R250 = Ra >> (32 - s) (arithmetic
with .SX32, bit 73) and IADD Rd = R250 + R251, the register form's
(0x211) high word. LEA.HI.X.SX32 keeps its own lowering; a carry out, a
high source or a zero shift is still refused.

--prepare-shaders on the full shader list: 83 -> 43 programs that do not
lower (all 40 "constant LEA carry mode" gone, the other kinds unchanged).
tests/test_lower_lea_hi_constant.py: the encodings from the log, .SX32,
and the forms still refused; it fails without this change.

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

Copy link
Copy Markdown
Owner

This landed in the v2.0.12 branch (merged there for testing; it reaches main with that release), so closing. Thanks!

@NotRexed

Copy link
Copy Markdown
Owner

Reopened: closing this was a mistake on my side. It was tested in the v2.0.12 branch, and it will be merged into main here, so it shows as merged. Sorry for the noise.

@NotRexed NotRexed reopened this Nov 10, 2026
@NotRexed
NotRexed merged commit 4c9d7bd into NotRexed:main Nov 10, 2026
20 checks passed
NotRexed added a commit that referenced this pull request Nov 10, 2026
#1447)

* Lowering: SULD.P on a 1D surface (17 compute programs translate again)

SULD.P with dimension code 0 (1D) stopped the Ampere -> Maxwell lowering
as "native formatted surface load mode": only 2D, 2D_ARRAY and 3D were
taken. 1D is Maxwell SULD.P.1D with one coordinate register; the Maxwell
frontend already reads it as a Color1D image and the back end binds
VK_IMAGE_VIEW_TYPE_1D. 1D_BUFFER and 1D_ARRAY (codes 1 and 2) are not
seen in the game and stay refused.

--prepare-shaders on the full shader list: 83 -> 66 programs that do not
lower (all 17 "formatted surface load" gone, no new compile errors; with
#1437 too it is 43 -> 26). In game (Water Temple) nothing changes for
the worse. tests/test_lower_suld_1d.py: both encodings from the log, 2D
as before, 1D_BUFFER/1D_ARRAY refused; it fails without this change.

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

* test_lower_suld_1d: size checks throughout, and the R254/R255 coordinate bound (review)

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

---------

Co-authored-by: Joey Magnus <joey.magnus@cxalloy.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: NotRexed <therealnothingfn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants