Skip to content

docs(relinker): record Rosetta instruction support on an M2 with macOS 14.8.9 - #7953

Open
kiaramaldonado wants to merge 1 commit into
boykopovar:mainfrom
kiaramaldonado:docs/rosetta-m2-macos14
Open

kiaramaldonado wants to merge 1 commit into
boykopovar:mainfrom
kiaramaldonado:docs/rosetta-m2-macos14

Conversation

@kiaramaldonado

Copy link
Copy Markdown

What

Adds an entry to docs/dev/debt/relinker.md recording Rosetta instruction support on an M2 with macOS 14.8.9. Under macOS 14's Rosetta, most of what the M1 (macOS 26.6.2) and M5 (macOS 26.4) surveys record as executing raises SIGILL: AVX, AVX2, FMA, F16C, RDRAND, and every BMI1/BMI2 instruction except TZCNT and LZCNT. ANDN is lowered by --to-rosetta, but the rest are not, so a converted module that reaches them faults on this host. RDTSCP reports the same constant TSC_AUX (ECX = 0xAAAAAAAB).

This is a separate entry rather than another sentence in the existing --to-rosetta entry. That entry is already 1,791 characters, and the debt-length check added in #6757 warns about entries over 1,000. The new entry is 610 characters.

M2, macOS 14.8.9
TZCNT, LZCNT, POPCNT, MOVBE, CLFLUSHOPT, PREFETCHW, RDTSCP execute
ANDN, BEXTR, BLSI, BLSMSK, BLSR, BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX SIGILL
AVX, AVX2, FMA, F16C SIGILL
RDRAND, RDSEED, RDPID, CLWB, ADCX, ADOX SIGILL

Method: same as #7185. Each instruction runs in its own forked x86-64 process built with clang -arch x86_64 (Apple clang 15.0.0). A process that exits normally executed the instruction; one killed by a signal did not. Each executing instruction's result was also compared with the expected value, and all matched. TZCNT(0) and LZCNT(0) both return 64, so they are not running as BSF/BSR. CPUID leaves 1, 7 and 0x80000001 were read directly under Rosetta. The encodings were checked with objdump.

Raw probe output
cpuid max leaf 0x7
leaf1 ecx=0298220f edx=0f8b8b15  MOVBE=0 POPCNT=1 AVX=0 F16C=0 FMA=0 RDRAND=0 OSXSAVE=0
leaf7 ebx=00000000 ecx=00000000  BMI1=0 AVX2=0 BMI2=0 RDSEED=0 ADX=0 CLFLUSHOPT=0 CLWB=0 RDPID=0
leaf80000001 ecx=00000001 edx=28100800  LZCNT=0 PREFETCHW=0 RDTSCP=1
ANDN        Illegal instruction: 4
BEXTR       Illegal instruction: 4
BLSI        Illegal instruction: 4
BLSMSK      Illegal instruction: 4
BLSR        Illegal instruction: 4
TZCNT       executes  got=0x3 want=0x3
LZCNT       executes  got=0x3f want=0x3f
POPCNT      executes  got=0x8 want=0x8
BZHI        Illegal instruction: 4
MULX        Illegal instruction: 4
PDEP        Illegal instruction: 4
PEXT        Illegal instruction: 4
RORX        Illegal instruction: 4
SARX        Illegal instruction: 4
SHLX        Illegal instruction: 4
SHRX        Illegal instruction: 4
MOVBE       executes  got=0x44332211 want=0x44332211
FMA         Illegal instruction: 4
AVX         Illegal instruction: 4
AVX2        Illegal instruction: 4
F16C        Illegal instruction: 4
RDRAND      Illegal instruction: 4
RDSEED      Illegal instruction: 4
RDPID       Illegal instruction: 4
RDTSCP      executes  got=0xaaaaaaab want=0x0
CLWB        Illegal instruction: 4
CLFLUSHOPT  executes  got=0x0 want=0x0
PREFETCHW   executes  got=0x0 want=0x0
ADCX        Illegal instruction: 4
ADOX        Illegal instruction: 4

(For RDTSCP, got is ECX; want is unused.)

The overlap check could not compare #5021, #6977, #7173, #7332 and #7417, which also change docs/dev/debt/relinker.md. I checked them by hand: none of them edits the --to-rosetta entry (#7173 adds a separate ADCX/ADOX entry). If one merges first and conflicts, I'll rebase.

Tested

Documentation only. The measurements are from an Apple M2 with macOS 14.8.9, as described above. python3 tools/check_conventions.py --base origin/main passes.

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 under Silent stubs in their library's technical debt file
  • 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
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 19, 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
PR 7173 docs/dev/debt/relinker.md L31

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 docs/dev/debt/relinker.md
PR 7822 docs/dev/debt/relinker.md
PR 7918 docs/dev/debt/relinker.md
PR 8076 docs/dev/debt/relinker.md
PR 9408 docs/dev/debt/relinker.md

@github-actions github-actions Bot added the docs label Oct 19, 2026

@jotitadev jotitadev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Data point from the same chip generation on a newer macOS. It suggests the M2 difference follows the macOS version, as the existing entry already says for the M1.

Apple M2 Max, macOS 27.2 (26B5112a). Same method as #7185 and this PR: one forked x86-64 process per instruction, built with clang -arch x86_64 (Apple clang 21.0.0), sysctl.proc_translated = 1, and results compared with expected values. Three runs gave identical results.

cpuid leaf1 ecx=0298220f edx=0f8b8b15
leaf7 ebx=00000000 ecx=00000000
leaf80000001 ecx=00000001 edx=28100800
ANDN BEXTR BLSI BLSMSK BLSR BZHI MULX PDEP PEXT RORX SARX SHLX SHRX   execute, results match
TZCNT LZCNT POPCNT MOVBE (TZCNT(0) = 64)                              execute, results match
AVX AVX2 FMA F16C RDRAND                                              execute, results match
CLFLUSHOPT PREFETCHW                                                  execute
RDTSCP                                                                executes, ECX = 0xaaaaaaab
RDSEED RDPID CLWB ADCX ADOX                                           SIGILL
  • The CPUID leaves are bit-for-bit the ones in your M2 / macOS 14.8.9 output. CPUID doesn't tell the two hosts apart, but execution does. On macOS 27.2, everything your table lists as SIGILL apart from RDSEED, RDPID, CLWB, ADCX and ADOX executes with correct results.
  • This matches the M1 pattern already in the entry (ANDN/RDRAND fault on macOS 15.3.1 and execute on 26.6.2). The new entry might say that on the M2 the faults were seen on macOS 14.8.9 and are absent on macOS 27.2, so readers don't take it as a chip limit.

Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.

This branch has not been deployed

No deployments
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.

2 participants