Skip to content

fix: ARM64 JIT crashes, visual corruption, and 64-bit pointer safety (#1766)#1824

Merged
midwan merged 2 commits intomasterfrom
fix/arm64-jit-crashes-and-corruption
Mar 8, 2026
Merged

fix: ARM64 JIT crashes, visual corruption, and 64-bit pointer safety (#1766)#1824
midwan merged 2 commits intomasterfrom
fix/arm64-jit-crashes-and-corruption

Conversation

@midwan
Copy link
Collaborator

@midwan midwan commented Mar 8, 2026

Summary

Fixes 12 root-cause bugs in the ARM64 JIT compiler that caused crashes, visual corruption, and stalls across various Amiga configurations. All fixes are root-cause — no guards or bandaids.

  • Crashes/stalls: Inter-block dont_care_flags() stale flag bug, FBcc 64-bit branch target truncation, BSR.L/Bcc.L sign extension for backward branches, bus error recovery via setjmp/longjmp
  • Visual corruption: ADDX byte/word register initialization (MOVN_xi dual-purpose bug), ADDX/SUBX Z-flag M68K "only clears" semantics
  • 64-bit safety: arm_ADD_l/arm_ADD_l_ri sign extension, set_const 32-bit masking, 64-bit pc_p store/load paths, MOVE16 pointer arithmetic
  • Memory: size_t for natmem sizes, 4GB ARM64 reservation, commit_natmem_gaps() read-only gap pages
  • Performance: Two-pass liveflags, R_REGSTRUCT range optimization, ADDX/SUBX Z-flag skip, guard removal, setjmp outside inner loop

Test Results

Config Result
Lightwave-NoRAM.uae (no Z3 RAM, A1200+68040+JIT) ✅ Boots to Workbench
Lightwave.uae (256MB Z3, LightWave 3D app) ✅ App runs stable
A4000.uae (68060/AGA, red gradient wallpaper) ✅ Clean — no corruption
SysInfo.uae (MIPS benchmark) ✅ ~7391 MIPS

Files Changed (16 source + 3 skill docs)

JIT Core (6 files)

  • compemu_support_arm.cpp — Inter-block fix, two-pass liveflags, cleanup
  • codegen_arm64.cpp — R_REGSTRUCT range optimization, 64-bit pc_p paths
  • compemu_midfunc_arm64.cpp — Sign-extension fixes, set_const masking
  • compemu_midfunc_arm64_2.cpp — ADDX/SUBX Z-flag + MOVN_xi fix, MOVE16
  • compemu_fpp_arm.cpp — FBcc branch target truncation fix
  • compemu.hjit_in_compiled_code extern

Runtime (4 files)

  • newcpu.cpp — setjmp/bus error recovery, dispatch loop
  • sigsegv_handler.cpp — SIGBUS/longjmp handler
  • m68k.h — FLAGBIT_X=0, SET_XFLG/GET_XFLG bit 0

Memory (6 files)

  • amiberry_mem.cppcommit_natmem_gaps(), 4GB ARM64, size_t
  • memory.cpp/memory.h — Gap commit call, size_t declarations
  • vm.h/vm.cpp — size_t function signatures throughout
  • main.cpp, ram.cpp, expansion.cpp — size_t, cleanup

Closes #1766

…1766)

Fix 12 root-cause bugs in the ARM64 JIT compiler that caused crashes,
visual corruption, and stalls across various Amiga configurations.

Crashes & stalls:
- Inter-block dont_care_flags: flush_flags() before dont_care_flags()
  to prevent stale NZCV on interpreter fallback path
- FBcc branch target truncation: avoid set_const() for 64-bit host
  pointers on non-PC_P registers in FPU conditional branches
- BSR.L/Bcc.L sign extension: cast comp_get_ilong() to (uae_s32)
  for 32-bit displacements in 32 branch handlers + generator
- Bus error recovery: setjmp/longjmp in m68k_run_jit() with SIGBUS
  handler integration for JIT code accessing unmapped memory

Visual corruption (A4000 AGA wallpaper):
- ADDX_b/w MOVN_xi initialization: move register init outside the
  FLAG_Z guard since it serves dual purpose (Z-flag base AND
  byte-packing padding for ADCS carry chain)
- ADDX/SUBX Z-flag semantics: implement M68K "only clears" behavior
  with proper sticky-Z via UBFX/CMP/SET_xxZflag/CSEL/AND

64-bit pointer safety:
- arm_ADD_l/arm_ADD_l_ri: sign-extend 32-bit M68K displacements when
  destination is PC_P (the only 64-bit virtual register)
- set_const: mask non-PC_P registers to 32 bits
- All pc_p store/load paths use 64-bit operations
- MOVE16: use ADD_xxx (64-bit) for natmem pointer arithmetic

Memory subsystem:
- natmem_reserved_size upgraded to size_t (was uae_u32, overflowed)
- ARM64 gets 4GB natmem reservation
- commit_natmem_gaps() fills unmapped regions with read-only pages

Performance optimizations:
- Two-pass liveflags: use successor block needed_flags for better
  flag elimination (+2.3% with R_REGSTRUCT range optimization)
- R_REGSTRUCT range-based offset: regflags uses fast 1-instruction
  STR_wXi instead of 4-5 instruction LOAD_U64 path
- ADDX/SUBX Z-flag skip: wrap Z handling in needed_flags check
- Guard infrastructure fully removed (was diagnostic-only)
- setjmp placed outside inner dispatch loop (~2% cost)

Tested: Lightwave-NoRAM.uae (boots), Lightwave.uae (app stable),
A4000.uae (clean AGA wallpaper), SysInfo.uae (~7391 MIPS).
@midwan midwan self-assigned this Mar 8, 2026
@midwan midwan added the bug label Mar 8, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0499f03b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…rm zero-fill skip

- sigsegv_handler.cpp: longjmp value 3 (address error) → 2 (bus error)
  for unmapped memory faults from unrecognized JIT instructions
- amiberry_mem.cpp: remove #ifndef _WIN32 guard around zero-fill skip
  since Windows VirtualAlloc(MEM_COMMIT) also zero-fills pages
@midwan midwan merged commit 489ddb9 into master Mar 8, 2026
24 checks passed
@midwan midwan deleted the fix/arm64-jit-crashes-and-corruption branch March 8, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make JIT for ARM64 work

1 participant