Skip to content

feat(libc): export the std::__sce_v2 binary scaling helpers - #15099

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
Danigamer05:feat/libc-sce-v2-binary-scaling-20261102
Nov 3, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
Danigamer05:feat/libc-sce-v2-binary-scaling-20261102

Conversation

@Danigamer05

Copy link
Copy Markdown
Contributor

What

Export six std::__sce_v2 Dinkumware binary scaling helpers from libc:

Export NID Original RVA
_ZNSt8__sce_v27_DscaleEPdl gRj52WoTf5Q 0xCB330
_ZNSt8__sce_v28_FDscaleEPfl wYwj23xDzPQ 0xCF0F0
_ZNSt8__sce_v28_LDscaleEPel +AqTGiV4vBA 0x10D2D0
_ZNSt8__sce_v29_DunscaleEPsPd 1Vlo0OcN+sk 0xCA210
_ZNSt8__sce_v210_FDunscaleEPsPf r8xEVOsN728 0xCA0C0
_ZNSt8__sce_v210_LDunscaleEPsPe iAKatJKy6QY 0xCA200

The behavior comes from the libc.prx bundled with PPSA03671 v01.001.005 (J03848509, SHA-256 483961e086b8a1fffa8138b3c0badf798987fb5f35ec908d828946408be2d8a6).

That module computes these helpers on the exponent and fraction bits:

  • NaN and infinity return their codes unchanged.
  • Subnormal inputs are normalized first.
  • _Dscale rounds a result that becomes subnormal to nearest even, returns an infinity on overflow and a signed zero on underflow.
  • _Dunscale returns the significand in [1/2, 1) and its exponent.
  • None of them sets errno or a floating-point exception flag.

The new ScaleFieldBits and UnscaleFieldBits in MathExact.cpp do the same with integer operations. The unversioned _Dscale and _Dunscale already here give the same values and codes for these inputs. They use host ldexp and frexp, which raise the denormal, underflow, overflow, inexact or invalid flags that the original never raises, so the versioned exports do not forward to them. As in the original, whose _LDscale and _LDunscale call the double forms, the __sce_v2 long double forms take an 8-byte double.

Tested

Windows x86-64, WinLibs GCC 15.2.0, Release, BUILD_TESTING=ON, main 5e85609d0b0152d14ae34d708d3237005ed311ca. Exact tested commit: 1c5093f845ed7ec88cd5533cb14c86fdc8cf182f.

The change was first tested on main 52e9ae6d57f37200c6b27234efb226b45d754528 at ef367efd7b803f96dfa7e8be523480663de73e0b, including the negative control below, then rebased onto the main above without conflicts; the diff of the change is the same apart from context lines. All four selected CTests and all 35,144,604 side-by-side vectors were run again at the tested commit and pass.

Not tested: Linux, macOS, another SDK, a game, GPU or console. No game compatibility claim. No original module, extracted bytes, oracle or log is committed or uploaded.

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

🤖 Generated with Claude Code

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

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Progress report (1d91f29 → 1c5093f)

📈 System libraries: 26.64% (+0.01%, +6 implemented functions)

✅ 6 implemented
Library Name
libc _ZNSt8__sce_v210_FDunscaleEPsPf_nid_postfix
libc _ZNSt8__sce_v210_LDunscaleEPsPe_nid_postfix
libc _ZNSt8__sce_v27_DscaleEPdl_nid_postfix
libc _ZNSt8__sce_v28_FDscaleEPfl_nid_postfix
libc _ZNSt8__sce_v28_LDscaleEPel_nid_postfix
libc _ZNSt8__sce_v29_DunscaleEPsPd_nid_postfix

Changed libraries (implemented exports)

Library Before After Change
libc 1533/1548 (99.03%) 1539/1554 (99.03%) +0.0037%

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

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 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6819 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7081 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7386 docs/dev/debt/libc.md
PR 7447 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7715 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 8150 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 8965 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 9340 docs/dev/debt/libc.md
PR 9371 docs/dev/debt/libc.md
PR 9447 docs/dev/debt/libc.md
PR 9526 docs/dev/debt/libc.md
PR 9929 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 10113 docs/dev/debt/libc.md
PR 10226 docs/dev/debt/libc.md
PR 10245 docs/dev/debt/libc.md
PR 10250 docs/dev/debt/libc.md
PR 10253 docs/dev/debt/libc.md
PR 10265 docs/dev/debt/libc.md
PR 10274 docs/dev/debt/libc.md
PR 10325 docs/dev/debt/libc.md
PR 10328 docs/dev/debt/libc.md
PR 10345 docs/dev/debt/libc.md
PR 10349 docs/dev/debt/libc.md
PR 10405 docs/dev/debt/libc.md
PR 10506 docs/dev/debt/libc.md
PR 10510 docs/dev/debt/libc.md
PR 10512 docs/dev/debt/libc.md
PR 10565 docs/dev/debt/libc.md
PR 10987 docs/dev/debt/libc.md
PR 11260 docs/dev/debt/libc.md
PR 11262 docs/dev/debt/libc.md
PR 11266 docs/dev/debt/libc.md
PR 11332 docs/dev/debt/libc.md
PR 11632 docs/dev/debt/libc.md
PR 11634 docs/dev/debt/libc.md
PR 11724 docs/dev/debt/libc.md
PR 11726 docs/dev/debt/libc.md
PR 11831 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 11907 docs/dev/debt/libc.md
PR 12122 docs/dev/debt/libc.md
PR 12397 docs/dev/debt/libc.md
PR 12514 docs/dev/debt/libc.md
PR 12560 docs/dev/debt/libc.md
PR 12574 docs/dev/debt/libc.md
PR 12593 docs/dev/debt/libc.md
PR 12622 docs/dev/debt/libc.md
PR 12627 docs/dev/debt/libc.md
PR 12682 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 12688 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 12700 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 12965 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 13119 docs/dev/debt/libc.md
PR 13390 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 13804 docs/dev/debt/libc.md
PR 14212 docs/dev/debt/libc.md
PR 14585 core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md
PR 14610 core/libs/prx/libc/include/Api.hpp
docs/dev/debt/libc.md

@BunnyFl BunnyFl 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.

Cross-checked against firmware 13.42's system libSceLibcInternal.sprx (sha256 a01795ab49df639dd40abd6194956ada062244826824ce486c9acab227bf5285) as well as the title's bundled libc.prx. Read from disassembly only, not measured on a console:

  • All six NIDs are exported there.
  • _LDscale (0x11e100) is call 0xdc480, the versioned _Dscale.
  • _LDunscale (0xdb350) is call 0xdb360, the versioned _Dunscale.

So the 8-byte long double forwarding matches the system module too. I didn't re-run the flag and errno comparison against the system module.

Build and test on Windows (WinLibs GCC, BUILD_TESTING=ON), PR merged into current main: guest_sce_v2_binary_scaling and guest_math_exact pass. On main the exports don't exist, and the test doesn't link.

@oneandonlydean oneandonlydean self-assigned this Nov 3, 2026
@oneandonlydean
oneandonlydean merged commit 67ea76b into boykopovar:main Nov 3, 2026
21 checks passed
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.

3 participants