Commit Graph
12196 Commits
Author SHA1 Message Date
Dean Galvin 04f12028dc fix(agc): run a wait-free submission of another queue after queue 0's earlier submissions
PPSA21564 submits the queue 0 work of each intro video frame F first, then 1
to 5 ms later a 12 MiB DMA_DATA on queue 0x3a that refills the video texture
F sampled, for frame F + 2 (two textures, used in turn). Nothing orders them
but time: no label, wait or flip lies between the copy and the draw, which
is the first packet of the frame's first submission. A GPU that keeps up
starts each submission as it arrives, so the draw reads its texture right
after the frame is submitted, and the copy submitted after it lands later,
every frame.

Here the queue workers record independently, so the copy was recorded either
before or after the draw depending on how far queue 0's worker lagged: the
video showed the new frame or the one before, and every switch between the
two was a frame shown backwards.

A submission with no waits on another queue now starts only after queue 0
has run every submission it received earlier, as on a GPU that keeps up.
While queue 0 is blocked in a wait, the held submission is released when its
queue stores the awaited label (it or a later submission of that queue), or
when nothing else could store it: no other worker is running and no recorded
GPU work or completion writes it. A GPU that keeps up would be blocked at
that wait too and run the other queue's submission meanwhile, so the order
holds only while queue 0 still has work it would already have done, and no
wait can deadlock on it.
2026-10-04 01:46:55 +13:00
Alberto RuizandClaude Opus 5.5 9879deca69 fix(audio): bound ATRAC9 decoding to the superframe
LibAtrac9 read its bitstream without a length, so a corrupt ATRAC9 frame
made the decoder read past the end of the guest's buffer. Update the
submodule to 946e05a ("Prevent bitstream overruns"), whose decode
functions take the buffer size, and pass the bytes left in the
superframe from NGS2, AJM and Audiodec. The callers already reject a
frame that consumes more than the superframe holds.

ngs2_atrac9 places a synthetic corrupt superframe right before an
inaccessible page and expects the render to report the decode failure;
with the previous LibAtrac9 it crashes with a segmentation fault.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
2026-10-03 14:25:49 +02:00
SP4C3B4R-8andClaude Opus 5.5 579db05081 fix(libSceAgcDriver): accept scissors that apply the zero window offset
PA_SC_WINDOW_OFFSET is already required to be zero, so a generic,
window or viewport scissor whose WINDOW_OFFSET_DISABLE bit is clear
selects the same rectangle as one that sets it. Only the reserved
bits are still rejected.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018m6Ad8zkQKPKZmyUQK9vfE
2026-10-03 13:15:28 +02:00
Adrià FranchandClaude b29fe003a1 feat(shader): implement the D16 format buffer stores
buffer_store_format_d16_{x,xy,xyz,xyzw}, buffer_store_format_d16_hi_x
and tbuffer_store_format_d16_{x,xy,xyz,xyzw} take one 16-bit half per
component (two per VGPR; hi_x takes the high half). As on hardware,
float, norm and scaled formats read the half as f16, widen it exactly
to f32 and then encode it like a 32-bit formatted store; uint formats
zero-extend it and sint formats sign-extend it before saturating, and
16-bit float components store it unchanged.

Co-Authored-By: Claude <[email protected]>
2026-10-03 11:37:15 +02:00
Adrià FranchandClaude 4d90c0bc8e fix(shader): convert formatted buffer stores to the element format
buffer_store_format_* and tbuffer_store_format_* wrote the register
bits as they were: an 8_UNORM store of 1.0f wrote 0x00 (the low byte of
0x3f800000), packed formats such as 2_10_10_10 overwrote the whole word
with each component, and the components the instruction does not
provide were left untouched. Each component is now encoded as the
hardware does: unorm/snorm (and uscaled/sscaled, which store the same
way) round x*M exactly to nearest even after clamping, with NaN as 0;
uint/sint saturate; f16 and the 11/10-bit floats truncate toward zero
and saturate. The whole element is written, with the missing components
as 0, and packed formats are composed into one word.

Co-Authored-By: Claude <[email protected]>
2026-10-03 11:37:12 +02:00
Adrià FranchandClaude 5c8c5d2578 feat(shader): implement the D16 format buffer loads
buffer_load_format_d16_{x,xy,xyz,xyzw}, buffer_load_format_d16_hi_x and
tbuffer_load_format_d16_{x,xy,xyz,xyzw} convert each component to 16
bits and pack two per VGPR. The conversions follow the hardware:
unorm/snorm round the exact value to nearest even, scaled integers
round to nearest even and saturate at 65504, 32-bit floats truncate
toward zero (saturating at 65504), and 32-bit integers saturate to 16
bits. All of it is done with integer ops so it does not depend on the
driver's f16 rounding. _x and _hi_x keep the other half, xyz keeps the
upper half of its second register, and a descriptor constant one is
f16 1.0 for non-integer formats.

Co-Authored-By: Claude <[email protected]>
2026-10-03 11:37:10 +02:00
Adrià FranchandClaude 504a2fd8af feat(shader): implement the D16 byte/short loads and high-half stores
buffer/flat/global/scratch_load_{ubyte,sbyte,short}_d16(_hi),
buffer/flat/global/scratch_store_{byte,short}_d16_hi and
ds_read_{u8,i8}_d16(_hi), ds_write_b8_d16_hi threw in the decoder. They use
the same 16-bit destination/source select as the existing ds_read_u16_d16
and ds_write_b16_d16_hi: a load writes one half and keeps the other, a
_d16_hi store takes its data from the high half.

Co-Authored-By: Claude <[email protected]>
2026-10-03 11:37:07 +02:00
Adrià FranchandClaude 1b7e0e487e feat(shader): implement v_movrelsd_b32, v_movrelsd_2_b32, v_swap_b32 and v_swaprel_b32
v_movrelsd moves VGPR[src + M0] to VGPR[dst + M0]. The _2 form and
v_swaprel take the source offset from M0[9:0] and the destination
offset from M0[25:16]; v_swaprel and v_swap exchange the two registers.
They reuse the select-over-registers lowering of v_movrels/v_movreld,
now shared as readRelativeVector/writeRelativeVector.

Co-Authored-By: Claude <[email protected]>
2026-10-03 11:37:02 +02:00
Dean Galvin fb6b131def perf(agc): read DCC keys behind the driver's own pending key store without a wait
A CB metadata pass (and a resident target's register-clear check) read the
DCC keys with CurrentDccKeys, which waited for the GPU whenever recorded
work wrote the key range. In the intro video of PPSA21564 about 800 passes
per 10 s waited about 1.8 ms each, and every one of those waits was behind
a key store whose result the driver already knew: its own uncompressed key
store, or a title fill of uniform keys recorded on the GPU.

Pending-write notes now carry a serial in recording order, and the key
memo remembers the note of the store it describes. When the newest
pending note over the keys is that store's own note, nothing recorded
after it writes the keys, so they read as the store's keys without a
wait. Any later writer, a range the store does not cover, or a unit
shadow over the keys waits as before.
2026-10-03 21:45:10 +13:00
Dean Galvin 8fafe96888 feat(agc): let agc_shader_replay write a request's code words for other disassemblers
--code writes the shader's code as <request name>.code in the working directory, as raw
little-endian words for llvm-mc -triple amdgcn -mcpu=gfx1030 --disassemble. --asm prints only
the first word of each instruction.
2026-10-03 21:45:10 +13:00
MichonandClaude Opus 5.5 057bcb1b42 fix(agc): refuse depth bounds outside [0, 1] without VK_EXT_depth_range_unrestricted
Clamping them changed the result where the stored depth is exactly 0 or 1.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-03 10:40:47 +02:00
MichonandClaude Opus 5.5 c15238ddc0 feat(agc): depth bounds test and depth bias
DB_DEPTH_CONTROL's DEPTH_BOUNDS_ENABLE now runs the Vulkan depth bounds
test with DB_DEPTH_BOUNDS_MIN/MAX, and PA_SU_SC_MODE_CNTL's
POLY_OFFSET_FRONT/BACK_ENABLE enable depth bias from
PA_SU_POLY_OFFSET_FRONT/BACK_SCALE/OFFSET and _CLAMP. Both are dynamic
state, so draws that differ only in their values share a pipeline.

The hardware slope scale is in 1/16 units. Depth bias with units other
than the depth format's (PA_SU_POLY_OFFSET_DB_FMT_CNTL), or that differs
between front and back faces that are both drawn, is refused. The
registers join the draw key. Depth-conditional color writes are still
refused.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-03 10:40:47 +02:00
Alexey d3ec1f15fb Merge pull request #371 from DotDebian/feat/smem-get-waveid-in-workgroup
feat(shader): implement s_get_waveid_in_workgroup
2026-10-03 11:16:32 +03:00
Alexey 87f016b0da Merge pull request #370 from DotDebian/fix/pthread-attr-get
fix(libkernel): report the thread's priority and affinity from scePthreadAttrGet
2026-10-03 11:02:46 +03:00
Alexey 5335ce0316 Merge pull request #368 from DotDebian/feat/mimg-image-atomics
feat(shader): implement the missing integer image atomics
2026-10-03 11:02:17 +03:00
Alexey 9e062154d3 Merge pull request #366 from DotDebian/feat/shader-vop1-pipeflush-clrexcp
feat(shader): decode v_pipeflush and v_clrexcp as no-ops
2026-10-03 11:01:34 +03:00
Alexey b4b261a806 Merge pull request #365 from DotDebian/feat/vopc-f64-compares
feat(shader): implement the VOPC f64 compares
2026-10-03 11:01:18 +03:00
Alexey e1bfb3973f Merge pull request #364 from DotDebian/feat/pthread-barrierattr
feat(libkernel): implement the pthread_barrierattr functions
2026-10-03 11:01:01 +03:00
Alexey a818beedf5 Merge pull request #341 from DotDebian/feat/kernel-cancel-sema
feat(libkernel): implement sceKernelCancelSema
2026-10-03 10:58:13 +03:00
Alexey 9f7e6499bd Merge pull request #335 from DotDebian/feat/kernel-event-accessors
feat(libkernel): implement the sceKernelGetEvent* field accessors
2026-10-03 10:50:28 +03:00
Dean Galvin 01bcab32d2 fix(agc): keep a surface's results in the 64 KiB block it shares with its neighbour
Write stamps are per 64 KiB block, so a write-back of one surface stamps the
whole block it shares with the surface packed right after it. A pending
image of that neighbour read the stamp as a store over its own bytes: its
write-back kept the guest bytes of the shared block in place of its results
and its next refresh re-uploaded them, stale. PPSA21564's half-resolution
fog texture (960x540 RGBA16F, linear, starting 0xb800 bytes before a block
end right after another 960x540 surface) lost its first 6 rows that way,
which the fog composite upsampled into an orange band across the top 12
rows of the scene in one of its cinematics.

The tracker now remembers the byte ranges of the driver's own stores
(MarkWritten) in the blocks they cover only in part, and StoredOver says
whether a store reached a given range since a generation (a CPU store still
counts for its whole block). The write-back keep rule and the refresh drop
rule ask it for the blocks a surface covers only in part.
2026-10-03 20:43:01 +13:00
Alexey b45716210c Merge pull request #326 from adriadam10/feat/scalar-relative-indexing
feat(shader): implement s_movrels/s_movreld (b32, b64) and s_movrelsd_2_b32
2026-10-03 10:35:26 +03:00
Alexey 67fd6385e7 Merge pull request #328 from arreina/pr/json-nesting-limit
fix(json2): reject documents nested deeper than 512 levels
2026-10-03 10:35:04 +03:00
Alexey 1043f90d8a Merge pull request #324 from adriadam10/feat/shader-memtime
feat(shader): implement s_memtime and s_memrealtime
2026-10-03 10:33:57 +03:00
Alexey 7813a9a1a5 Merge pull request #322 from oneandonlydean/fix/recompiler-readlane-wrap
fix(shader): wrap the v_readlane_b32 lane select at the wave size
2026-10-03 10:33:21 +03:00
Alexey ff96a3b159 Merge pull request #304 from oneandonlydean/perf/recompiler-two-lane-uniform-values
perf(recompiler): emit wave-uniform values once for both lanes of a two-lane invocation
2026-10-03 10:32:37 +03:00
Alexey d7543997f6 Merge pull request #318 from adriadam10/feat/f16-misc-legacy-mul
feat(shader): f16 ldexp/frexp/norm/class, v_sat_pk_u8_i16, v_mul/mac_legacy_f32
2026-10-03 10:31:55 +03:00
Adrià FranchandClaude c23ead6478 feat(shader): implement v_div_fixup_f16
Decode VOP3 opcode 0x35f and translate it on the raw half bits, matching
the RDNA2 hardware: NaN numerator or denominator is returned quieted,
0/0 and inf/inf give 0xfe00, a NaN quotient becomes a signed infinity,
and op_sel, abs and neg apply as for the other f16 ternary ops.

Co-Authored-By: Claude <[email protected]>
2026-10-03 09:19:46 +02:00
Dean Galvin d5aff03614 fix(recompiler): v_readfirstlane_b32 of an empty EXEC reads lane 0
With no lane active the hardware reads lane 0. The emitter shuffled from
the ballot's first lane: OpGroupNonUniformBallotFindLSB of an empty
ballot is undefined, and the two-lane wave64 path computed lane 31
(FindILsb of the empty high word plus 32). Lane 0 is now selected when
the ballot is empty.

Tests: agc_driver_read_first_lane_tests runs v_readfirstlane_b32 in a
wave32 and a wave64 compute shader with EXEC empty and with a later
first active lane.
2026-10-03 20:16:35 +13:00
Dean Galvin 9746b0a633 perf(agc): build check failure messages only when a check fails
Require takes its reason as a std::string, so a check whose message is
built with std::to_string and concatenation formatted that message on
every call, even when the check passed. The checks on per-draw and
per-descriptor paths (sampler and texture format decoding, descriptor
binding roles, storage formats, detiling, float registers) now build
their message only on the failing branch. Behaviour is unchanged.
2026-10-03 20:16:33 +13:00
Dean Galvin b85358c021 fix(agc): accept WRITE_DATA with ENGINE_SEL = PFP
WRITE_DATA's ENGINE_SEL (control bits 31:30) picks the CP engine that
performs the write: 0 the micro engine, 1 the prefetch parser, 2 the
constant engine. Validate refused every engine bit, so a submission
with a PFP WRITE_DATA failed as a whole. The prefetch parser handles
packets in queue order ahead of the micro engine, and the driver already
performs the write in queue order, so PFP is accepted like ME. The
constant engine stays refused.

Tests: agc_driver_pm4_tests runs a PFP WRITE_DATA and checks that a CE
one is still refused.
2026-10-03 20:16:31 +13:00
Dean Galvin a18cf0fc32 fix(agc): describe the pages after a gap in a Linux host page query
Without VirtualQuery, a range no cached page table covers is looked up
line by line in /proc/self/maps. A cursor in a gap between mappings never
matched a line, so the scan parsed the whole file and then reported the
rest of the range unmapped, including mapped pages after the gap. The
scan now stops at the first mapping above the cursor, reports the gap up
to it as inaccessible and continues from there, as the VirtualQuery path
does with a free region.

PPSA21564 queries near-null addresses (0x18, 0x30, 0x58) about 1500 times
a second during resource capture; each of those parsed the whole maps
file (about 5700 lines here) instead of stopping at the first mapping.

Tests: agc_driver_graphics_tests describes three host pages with the
middle one unmapped as two ranges, a query that starts in the gap as the
page after it, and a near-null address as inaccessible.
2026-10-03 20:16:30 +13:00
Dean Galvin e530fc0b14 feat(agc): take triangle fans as NGG geometry shader input
PPSA21564 draws small indexed triangle fans (VGT_PRIMITIVE_TYPE 5, six
indices, restart enabled) into a real ES + GS (VGT_SHADER_STAGES_EN
0x2030). DecodeShaderStages took only point, line, triangle list and strip
input, so these were skipped as "unsupported geometry input or output
assembly".

- A fan is accepted as geometry input with an input step of 1, like a
  strip: a subgroup of P triangles takes P + 2 vertices, in the decode,
  ShaderMeshInputInfo and the draw's group count.
- The mesh entry shades the draw's vertex 0 (the hub) in ES thread 0 of
  every subgroup and the subgroup's vertices from firstPrimitive + 1 in
  the others; GS thread p gets ES threads (p + 1, p + 2, 0). That is the
  order the hardware hands a GS with the first vertex provoking (as
  Vulkan orders fans), so a triangle keeps the winding and flat color of
  its rim vertex.
- The mesh path does not restart primitives: an indexed fan with restart
  enabled is refused when its indices hold the restart index (all ones).

Tests: agc_driver_graphics decodes PPSA21564's fan registers (30
triangles in a 32-vertex subgroup) and rejects short subgroups;
agc_shader_memory checks the fan subgroup sizes; agc_driver_mesh_tests
(GPU, run by hand) draws non-indexed and indexed fans over three
subgroups, checks each triangle takes its first rim vertex's flat color
and the fan is not closed, and refuses a restart index.
2026-10-03 20:16:27 +13:00
Dean Galvin 895c1c0eed fix(agc): record large memory-to-memory DMA_DATA copies on the GPU in queue order
A DMA_DATA too large to resolve as a store drained the device and then
copied on the submitting worker's thread. For a large range that copy takes
milliseconds, and meanwhile another queue's worker records, submits and runs
work that reads the destination in place. PPSA21564 copies each 12 MiB
frame of its intro video into one of two textures with a single DMA_DATA on
one queue and samples it on queue 0 without waiting for that queue; the
GPU's own DMA finishes in microseconds, so the title never needed to. Here
queue 0's upload of the texture ran while the CPU copy was still writing
it, and a frame showed the new frame's luma over the chroma of the frame
two before.

Such a copy (both addresses memory and incrementing, ranges disjoint and
non-empty) now goes through VulkanDevice::CopyBuffer like the copy kernel:
a transfer between the host imports, recorded in order, so everything
recorded after the packet reads the whole copy. The drain and CPU copy
remain the fallback when either range is not host-imported.
2026-10-03 20:16:25 +13:00
Alexey 926906e257 Merge pull request #320 from adriadam10/feat/lds-atomics
feat(shader): implement the missing 32-bit LDS atomics and fix ds_min/max_f32
2026-10-03 10:13:33 +03:00
Alexey 00193ec66f Merge pull request #311 from asimplestray/feat/shader-sop1-bitcount64
test(shader): cover 64-bit scalar bit-count ops
2026-10-03 10:01:10 +03:00
Alexey 9f1b6a79bf Merge pull request #306 from oneandonlydean/fix/agc-batch-stamps-under-draw-profile
fix(agc): stamp every batch under APS5_PROFILE_DRAW so the present report's GPU busy is real
2026-10-03 10:00:51 +03:00
Dean Galvin a791e7dd5d perf(recompiler): emit wave-uniform values once for both lanes of a two-lane invocation
A wave64 compute or mesh program on a 32-wide host runs two lanes per
invocation, and the emitter emitted every IR value once per lane, scalar ones
included: each SGPR value, scalar memory load and loop phi existed twice in
the module, raising register pressure for every such program.

WaveUniformValues (SpirvAnalysis) finds the values every lane of the wave
computes alike: user data, constants, resources, ballots, readlane and
readfirstlane results, scalar loads through a wave-uniform address, and what
follows from them alone. Lane ids, builtins other than the workgroup id, lane
exchanges and every other memory or image read differ by lane, as does
anything computed from them. For such a value without side effects, the
second lane reuses the first lane's definition. Both lanes are one
invocation, so they share control flow and the definition dominates every
use of the second lane.

agc_shader_memory checks the analysis and that a two-lane module computes a
scalar product as often as the one-lane module. The agc_driver_wave_uniform
execution test runs a wave64 program with a scalar loop, a ballot and a
readfirstlane and checks every lane's result. It skips on a subgroup
narrower than 32, such as lavapipe's.
2026-10-03 20:00:38 +13:00
Alexey 5dd3c6c338 Merge pull request #278 from oneandonlydean/perf/agc-resident-10bit-scanout
perf(agc): keep the 10-bit scanout resident and present it with the guest path's pixels
2026-10-03 10:00:01 +03:00
Alexey aff499474a Merge pull request #309 from asimplestray/feat/shader-vopc-const
test(shader): cover VOPC compare constants and ordered F16
2026-10-03 09:58:37 +03:00
Alexey de3344a9e7 Merge pull request #305 from oneandonlydean/fix/recompiler-pixel-helper-lanes
fix(recompiler): start pixel waves without their helper invocations in EXEC
2026-10-03 09:47:30 +03:00
Alexey f3ff6da034 Merge pull request #303 from oneandonlydean/fix/recompiler-computed-texel-offsets
fix(recompiler): sample with texel offsets the guest computes, through maintenance8's Offset
2026-10-03 09:46:58 +03:00
Alexey 29a8d01c83 Merge pull request #297 from oneandonlydean/fix/videoout-open-param-service-thread
fix(videoout): read the open param as the service thread's priority and affinity
2026-10-03 09:46:25 +03:00
Dean Galvin d9632d5523 fix(agc): complete a flip only once the frame's GPU work has finished
With APS5_FLIP_INFLIGHT (default 1) a presentation trailed on the GPU and
the flip completed as soon as its blit was queued behind the frame's
batches. The title reads that completion as "the GPU is done with the
frame" and rewrites the frame's memory, but the recorded GPU work still reads
guest memory in place when it runs. In PPSA21564 the per-draw constant
ring of the next frames landed under vertex programs that had not run
yet: a program read an integer sample count as float 1.0 from another
draw and stepped a loop by its reciprocal, about 1e9 iterations, and
other draws got wrong matrices.

The presenter now queues the present and then waits for the frame's own
fence, outside the GPU mutex, before reporting the flip, so the title
cannot reuse the frame's memory while the GPU still reads it.

Test: video_out_flip_tests aftergpu (needs a GPU and a display) submits a
busy compute dispatch, an end-of-pipe label without an interrupt (which
does not drain the device) and a flip, and checks that the flip
completes no earlier than the label lands.
2026-10-03 19:44:43 +13:00
Dean Galvin 0e2500786a fix(agc): stamp every batch under APS5_PROFILE_DRAW so the present report's GPU busy is real
The [present] line, printed under APS5_PROFILE_DRAW, takes its GPU busy and
idle gaps from the whole-batch timestamps in each batch's completion record.
Those stamps were only written under APS5_PROFILE_GPU, which also times every
command. Under APS5_PROFILE_DRAW alone every batch finished with zero stamps,
so the line read "GPU busy 0.0 ms, idle gaps 0.0 ms" with no missing records.

Under APS5_PROFILE_DRAW each batch now carries just its two batch stamps in a
two-query pool, reused across batches like the command buffers.
APS5_PROFILE_GPU is unchanged, and nothing is written with profiling off.

agc_driver_recorder_tests (GPU, by hand) checks that three consecutive
batches' completion records carry ordered stamps exactly when batch stamps
are on, and none with profiling off.
2026-10-03 19:44:01 +13:00
Alexey c394893eca Merge pull request #409 from oneandonlydean/perf/agc-defer-eop-interrupts
perf(agc): deliver end-of-pipe interrupts after their work without draining
2026-10-03 09:35:22 +03:00
Adrià FranchandClaude b066079628 fix(relinker): zero dst[127:64] in EXTRQ and INSERTQ lowerings
The APM leaves bits 127:64 of the destination undefined after EXTRQ and
INSERTQ, but hardware zeroes them, and the register-form INSERTQ stub
already does the same (#185). The other paths kept the old high qword, so
a following register-form INSERTQ that reads its length and index from
that qword computed the wrong low qword too.

Every stub path that left the high qword now ends with movq dst, dst.
The in-place PSRLQ, PMOVZX and PBLENDW forms leave it non-zero and have
no room for the movq, so those sites now take a stub. The two in-place
forms that emitted nothing now emit movq dst, dst.

Co-Authored-By: Claude <[email protected]>
2026-10-03 08:21:33 +02:00
Adrià FranchandClaude ee3b215f33 fix(relinker): report RIP-relative operands of VEX, EVEX and 0F38/0F3A instructions
DecodeInstruction returned before the ModRM byte for VEX and EVEX and
read the third opcode byte of 0F 38/0F 3A as ModRM, so their
RIP-relative operands were never reported. --to-intel then moved such an
instruction after a short EXTRQ/INSERTQ into the stub with its
displacement unchanged, and the strict unused-import filter missed its
references.

Co-Authored-By: Claude <[email protected]>
2026-10-03 08:10:29 +02:00
Adrià FranchandClaude 71ca3ff4b8 feat(relinker): lower SHA-1 instructions for --to-intel
SHA1RNDS4, SHA1NEXTE, SHA1MSG1 and SHA1MSG2 passed through --to-intel
unchanged, so a relinked title that executes them faults on Intel CPUs
without SHA-NI. Their register forms are now lowered out of line with
SSE2 only through the shared stub builder; short sites share stubs via
MatchSequence. Memory forms fail the relink with the file offset, as for
SHA-256.

Co-Authored-By: Claude <[email protected]>
2026-10-03 07:40:41 +02:00
RomainROCH 44c9c77a7c fix(rtc): reject invalid RFC 3339 timezone offsets 2026-10-03 04:08:27 +02:00