Merge pull request #6331 from hypermoist/feat/libc-generic-atomics

feat(libc): implement the 16-byte __sync builtins and __atomic_is_lock_free
This commit is contained in:
Adrià authored and GitHub committed 2026-10-19 01:37:09 +02:00
commit 0f121739ce
4 files changed
+192

No files matched your search

+1
View File
@@ -24,6 +24,7 @@
- [acosl](../../../core/libs/prx/libc/src/Math.cpp) (libc) - computed by the host's math library, like the other libc math functions here, not by the console's (FreeBSD msun ld80 code in Sony's `libc.prx`): results can differ from the console's in the last bit, and on Linux glibc sets `errno` to `EDOM` for `acosl` outside [-1, 1] where msun only raises the floating-point exception. `long double` is the x87 80-bit format, as Sony's `frexpl` uses it (`fldt 0x8(%rsp)`, result in `st(0)`)
- [atanl, sinl, cosl, tanl, sinhl, coshl, tanhl, expl, exp2l, logl, log10l and powl](../../../core/libs/prx/libc/src/Math.cpp) (libc) - computed by the host's math library, as `acosl` is, not by the console's FreeBSD msun ld80 code: results can differ from the console's in the last bit (glibc's `log10l(1000)` is not exactly 3), and on Linux glibc sets `errno` to `EDOM` or `ERANGE` where msun only raises the floating-point exception. `ldexpl` and `truncl` are exact operations and give the console's result; `logb` and `remainder` give the console's value too, but on Linux glibc sets `errno` (`ERANGE` for `logb(0)`, `EDOM` for `remainder` by zero or of an infinity) where msun only raises the floating-point exception
- [std_execute_once](../../../core/libs/prx/libc/Export.cpp) (libc) - assumed to be the plain-named twin of `std::_Execute_once` (`_ZSt13_Execute_onceRSt9once_flagPFiPvS1_PS1_ES1_`, the callee of Dinkumware `call_once`): it delegates there and gets the [thread.once.callonce] semantics already verified for that symbol (one invocation per flag, concurrent callers block until it completes, and a failing or throwing invocation leaves the flag unready so the next caller runs it). The name equivalence is not confirmed on a title, and the callback convention (called with (null, arg, null), non-zero return meaning success) is the twin's, unverified for this symbol
- [__atomic_load, __atomic_store, __atomic_exchange and __atomic_compare_exchange](../../../core/libs/prx/libc/src/AtomicBuiltins.cpp) (libc) - the generic, size-parameterised libatomic entry points are a single `ud2` in the `libc.prx` bundled with PPSA08427 (disassembly), so the console traps on any call; these throw instead
- [Dinkumware mutexes and conditions](../../../core/libs/prx/libc/src/Threads.cpp) (libc) use pointer-to-handle arguments, matching the console aerolib signatures reported in [#3079](https://github.com/boykopovar/AnyPS5/pull/3079). The title's `_Mtx_lock` maps `0` to `_Thrd_success` (0), `0x8002000b` to `_Thrd_busy` (3), and other failures to `_Thrd_error` (4); its internal mutex init recognizes recursive flag `0x100`, while every other type uses default attributes. The observed relock failure for a plain mutex suggests those defaults are error-checking, but that has not been confirmed on hardware. The title's `_Mtx_unlock` and `_Cnd_wait` return success regardless of their internal result. The host implementation treats invalid ownership preconditions as no-ops, and throws for invalid handles, host wait errors and destroying a locked mutex as debug guards; those cases are not confirmed against the console.
- [Floating-point compiler-rt builtins](../../../core/libs/prx/libc/src/FloatBuiltins.cpp) (libc) follow the `libc.prx` bundled with PPSA08427 (disassembly, and that binary run side by side on random inputs) where it differs from current compiler-rt: the soft-float `__add`, `__sub`, `__mul` and `__div` (`sf3`, `df3`) round to nearest, raise no exception flags and ignore MXCSR, here done with SSE under a default MXCSR that is restored afterwards; division flushes a quotient below the smallest normal to a signed zero; `__extendsfdf2` and `__truncdfsf2` copy NaN payloads unshifted; float-to-integer conversions do not saturate but shift the significand by a count masked to the shift width. `__mulsc3`, `__muldc3`, `__divsc3` and `__divdc3` fuse the same products as the console with `fma` and scale through the x87 like its `scalbn`, so their values match, but NaN payloads and exception flags can differ, as the host `fma` and `logb` are not the console's VEX FMA code and libm
- [random, srandom, initstate, setstate](../../../core/libs/prx/libc/src/Random.cpp) (libc) follow FreeBSD 11 [random.c](https://github.com/freebsd/freebsd-src/blob/4ab2e064d7950be84256d671a7ae93f87cc6aa36/lib/libc/stdlib/random.c): the additive feedback generator on a default 128-byte `TYPE_3` table, `good_rand` seeding, state sizes rounded down to 8, 32, 64, 128 or 256 bytes, and `setstate` returning the previous state or null for a rear position past the degree. `initstate` below 8 bytes returns null without setting errno, as that file and its manual do (glibc sets `EINVAL`). FreeBSD does not lock the generator; here every call is serialised by one lock, so concurrent callers draw the serial sequence between them. A null state throws, where FreeBSD faults. That the console's `libSceLibcInternal` uses this FreeBSD code and not another generator is unverified