Skip to content

feat(libc): implement the compiler-rt integer builtins - #6322

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
hypermoist:feat/libc-integer-builtins
Oct 18, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
hypermoist:feat/libc-integer-builtins

Conversation

@hypermoist

@hypermoist hypermoist commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

Implements the 59 compiler-rt integer builtins that the system libc.prx exports and AnyPS5 did not have:

  • shifts __ashldi3, __ashrdi3, __lshrdi3, __ashlti3, __ashrti3, __lshrti3
  • bit counts __clz{si,di,ti}2, __ctz{si,di,ti}2, __ffs{di,ti}2, __parity{si,di,ti}2, __popcount{si,di,ti}2
  • comparisons __cmp{di,ti}2, __ucmp{di,ti}2; negation __neg{di,ti}2; multiplication __muldi3, __multi3
  • division __div{si,di}3, __mod{si,di}3, __udiv{si,di}3, __umod{si,di}3, __divmod{si,di}4, __udivmod{si,di,ti}4
  • overflow reporting __mulo{si,di,ti}4 and overflow checking __addv, __subv, __mulv (si3, di3, ti3), __negv, __absv (si2, di2, ti2)

They live in a new src/IntegerBuiltins.cpp. The 128-bit paths use the existing SonyCrt.hpp long division and a hand-written 128-bit multiply, so no compiler-rt is needed on Windows.

Behaviour follows the libc.prx bundled with PPSA08427 (disassembly) where it differs from upstream compiler-rt:

  • __addv* and __subv* are plain wrapping additions/subtractions on the console (the check was optimized away), so they wrap here too.
  • __udivsi3 is a software loop there, so __udivsi3, __umodsi3 and __udivmodsi4 give quotient 0 and the dividend as remainder for a zero divisor.
  • __clzdi2/__ctzdi2 of 0 return 32 and __clzti2/__ctzti2 of 0 return 64.
  • __divsi3, __modsi3 and the 64/128-bit divisions trap on a zero divisor (div), and __negv*, __absv*, __mulv* call an abort helper then ud2 on overflow; these throw std::runtime_error, like the existing __udivti3/__umodti3. Recorded in docs/dev/debt/libc.md.

Tested

Differential test against the console: the libc.prx of PPSA08427 was mapped into a Linux process (PT_LOAD segments, RELATIVE relocations applied, the stack-protector GOT slot pointed at a dummy guard) and every builtin here was called side by side with this implementation on 200,000 random and edge-case inputs each (inputs on which this implementation throws are skipped, since the console traps there). All 59 functions agree bit for bit. The harness is not part of this PR because it needs the console binary.

Linux (CachyOS, GCC Release build, plus a clang -Wall -Wextra syntax check): new guest_integer_builtins test (shifts, bit counts, comparisons, 128-bit multiply, division/remainder edge cases including INT_MIN / -1 and zero divisors, __mulo* overflow flags at the boundaries, wrapping and throwing v variants) passes; guest_crt and guest_math pass. tools/check_conventions.py passes; tools/pr_overlap.py --branch reports no overlap.

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
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

🤖 Generated with Claude Code

https://claude.ai/code/session_01Q8tinbP1MUpUaDsbNWnGnu

Shifts, bit counts, comparisons, negation, multiplication, division and
remainder, __udivmodti4, the overflow-reporting __mulo* and the overflow
checking __addv*/__subv*/__mulv*/__negv*/__absv* families. Where the libc.prx
bundled with PPSA08427 differs from compiler-rt it is followed: __addv* and
__subv* wrap, and the 32-bit unsigned division returns 0 for a zero divisor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8tinbP1MUpUaDsbNWnGnu
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Progress report (fdea36b → 667e8ad)

📈 System libraries: 88.89% (+0.18%, +59 implemented functions)

✅ 59 implemented
Library Name
libc __absvdi2_nid_postfix
libc __absvsi2_nid_postfix
libc __absvti2_nid_postfix
libc __addvdi3_nid_postfix
libc __addvsi3_nid_postfix
libc __addvti3_nid_postfix
libc __ashldi3_nid_postfix
libc __ashlti3_nid_postfix
libc __ashrdi3_nid_postfix
libc __ashrti3_nid_postfix
libc __clzdi2_nid_postfix
libc __clzsi2_nid_postfix
libc __clzti2_nid_postfix
libc __cmpdi2_nid_postfix
libc __cmpti2_nid_postfix
libc __ctzdi2_nid_postfix
libc __ctzsi2_nid_postfix
libc __ctzti2_nid_postfix
libc __divdi3_nid_postfix
libc __divmoddi4_nid_postfix
libc __divmodsi4_nid_postfix
libc __divsi3_nid_postfix
libc __ffsdi2_nid_postfix
libc __ffsti2_nid_postfix
libc __lshrdi3_nid_postfix
libc __lshrti3_nid_postfix
libc __moddi3_nid_postfix
libc __modsi3_nid_postfix
libc __muldi3_nid_postfix
libc __mulodi4_nid_postfix
libc __mulosi4_nid_postfix
libc __muloti4_nid_postfix
libc __multi3_nid_postfix
libc __mulvdi3_nid_postfix
libc __mulvsi3_nid_postfix
libc __mulvti3_nid_postfix
libc __negdi2_nid_postfix
libc __negti2_nid_postfix
libc __negvdi2_nid_postfix
libc __negvsi2_nid_postfix
libc __negvti2_nid_postfix
libc __paritydi2_nid_postfix
libc __paritysi2_nid_postfix
libc __parityti2_nid_postfix
libc __popcountdi2_nid_postfix
libc __popcountsi2_nid_postfix
libc __popcountti2_nid_postfix
libc __subvdi3_nid_postfix
libc __subvsi3_nid_postfix
libc __subvti3_nid_postfix
libc __ucmpdi2_nid_postfix
libc __ucmpti2_nid_postfix
libc __udivdi3_nid_postfix
libc __udivmoddi4_nid_postfix
libc __udivmodsi4_nid_postfix
libc __udivmodti4_nid_postfix
libc __udivsi3_nid_postfix
libc __umoddi3_nid_postfix
libc __umodsi3_nid_postfix

… builtins

The libc.prx bundled with PPSA08427 returns 32 from __clzdi2 and __ctzdi2 and
64 from __clzti2 and __ctzti2 for a zero argument; found by comparing every
builtin against it on random inputs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8tinbP1MUpUaDsbNWnGnu
This was referenced Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 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 7557 __multi3_nid_postfix

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 3987 docs/dev/debt/libc.md
PR 5021 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6044 core/libs/prx/libc/CMakeLists.txt
PR 6226 docs/dev/debt/libc.md
PR 6565 docs/dev/debt/libc.md
PR 7039 docs/dev/debt/libc.md
PR 7081 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7084 core/libs/prx/libc/CMakeLists.txt
PR 7201 core/libs/prx/libc/CMakeLists.txt
PR 7332 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants