NetBSD Problem Report #56839
From www@netbsd.org Mon May 16 15:13:18 2022
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id CA1881A921F
for <gnats-bugs@gnats.NetBSD.org>; Mon, 16 May 2022 15:13:18 +0000 (UTC)
Message-Id: <20220516151317.5F00B1A923A@mollari.NetBSD.org>
Date: Mon, 16 May 2022 15:13:17 +0000 (UTC)
From: rokuyama.rk@gmail.com
Reply-To: rokuyama.rk@gmail.com
To: gnats-bugs@NetBSD.org
Subject: GCC emits wrong codes for compare_and_swap_1 bultins on armv5 (el & eb)
X-Send-Pr-Version: www-1.0
>Number: 56839
>Category: port-arm
>Synopsis: GCC emits wrong codes for compare_and_swap_1 bultins on armv5 (el & eb)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-arm-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon May 16 15:15:00 +0000 2022
>Last-Modified: Thu Mar 19 19:50:01 +0000 2026
>Originator: Rin Okuyama
>Release: 9.99.96
>Organization:
Department of Physics, Meiji University
>Environment:
NetBSD hdlg 9.99.96 NetBSD 9.99.96 (HDL_G) #5: Sun May 15 19:24:35 JST 2022 rin@latipes:/build/src/sys/arch/evbarm/compile/HDL_G evbarm
>Description:
Tests for __sync_{bool,val}_compare_and_swap_1() fail on armv5:
https://www.netbsd.org/~martin/evbarm-atf/402_atf.html#lib_libc_atomic_t___sync_compare_and_swap___sync_bool_compare_and_swap_1
These failures are observed both for little- and big-endian.
This is because GCC emits wrong codes for these built-in functions.
For some cases, GCC uses "mvn" insn to generate 2nd ("expected") and
3rd ("new") arguments for these builtins.
For example, it emits "mvn reg,#0x77" for 0x88, which results in
0xffffff88. This is wrong as these arguments are passed via registers;
inappropriate 0xff's in upper 3 bytes for "expected" argument make
comparison with uint8_t value of "*ptr" unconditionally fail.
This kind of wrong immediate generations are not observed for other
functions that take uint8_t arguments. Therefore, something is wrong
for treatments peculiar to these builtins.
Note that Linux version of __sync_bool_compare_and_swap_N() takes
signed integers as the 2nd and 3rd arguments on arm, whereas these are
unsigned for us. This may be related to this wrong "sign-extension".
The above-mentioned scenario is confirmed by a minimal stripped-down
version of the test for __sync_bool_compare_and_swap_1() (and
_atomic_cas_8(), which is used internally for this builtin):
https://gist.github.com/rokuyama/f469cbf96774db1f4658f0bb932c7a23
It fails for __sync_bool_compare_and_swap_1(), and succeeds for
_atomic_cas_8():
----
$ cc -g -O2 -c arm_builtin_compare_and_swap_1.c
$ cc arm_builtin_compare_and_swap_1.o
$ ./a.out
__sync_bool_compare_and_swap_1: val expects 0xf0 but 0x88
----
(Here, "-O2" is only for readability of objdump (see below).
The same failure occurs even with "-O0".)
objdump for this test case reads:
https://gist.github.com/rokuyama/eaf499d1e57767dbbe3e7bf30b2e0fce
Here, GCC generates 0x88 by "mvn" and "mov" for arguments for
__sync_bool_compare_and_swap_1() and _atomic_cas_8(), respectively.
>How-To-Repeat:
cd /usr/tests/lib/libc/atomic && atf-run t___sync_compare_and_swap
The stripped-down version of this test is provided above.
>Fix:
N/A
>Audit-Trail:
From: Nick Hudson <nick.hudson@gmx.co.uk>
To: gnats-bugs@netbsd.org, port-arm-maintainer@netbsd.org,
gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc:
Subject: Re: port-arm/56839: GCC emits wrong codes for compare_and_swap_1
bultins on armv5 (el & eb)
Date: Wed, 18 May 2022 12:48:54 +0100
I think this fixes things. It's a bit ugly...
https://www.netbsd.org/~skrll/pr56839.diff
Nick
From: Rin Okuyama <rokuyama.rk@gmail.com>
To: Nick Hudson <nick.hudson@gmx.co.uk>, gnats-bugs@netbsd.org,
port-arm-maintainer@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org
Cc:
Subject: Re: port-arm/56839: GCC emits wrong codes for compare_and_swap_1
bultins on armv5 (el & eb)
Date: Fri, 20 May 2022 10:32:32 +0900
Hi,
On 2022/05/18 20:48, Nick Hudson wrote:
> I think this fixes things. It's a bit ugly...
>
> https://www.netbsd.org/~skrll/pr56839.diff
This does not work:
(1) GCC expands __sync_bool_compare_and_swap_N() into
__sync_val_compare_and_swap_N() as optimization.
(2) The patch does not cover __sync_val_compare_and_swap_N()
( == _atomic_cas_8N() ).
On the other hand, this patch for _atomic_cas_8N() fixes the problem:
https://gist.github.com/rokuyama/3d791f2ceb2757dc389a95910162c9cb
However, IMO, this is not the real fix:
(a) I've found that MI part, not arm-dependent part, of GCC carries
out sign-extension; something is wrong in
expand_builtin_compare_and_swap() @ dist/gcc/gcc/builtins.c,
but I've never fully understand what goes wrong yet...
(Strangely enough, GCC itself recognizes that these builtins
takes unsigned integers...)
(b) Therefore, archs other than arm that do not have 1- and 2-byte
atomic cas builtins (== missing equivalent instructions) should
be affected.
(c) It should be better to fix GCC rather than adding workaround to
libc routines.
Thanks,
rin
From: Rin Okuyama <rokuyama.rk@gmail.com>
To: "gnats-bugs@NetBSD.org" <gnats-bugs@netbsd.org>, netbsd-bugs@netbsd.org
Cc:
Subject: Re: port-arm/56839 (GCC emits wrong codes for compare_and_swap_1
bultins on armv5 (el & eb))
Date: Tue, 15 Aug 2023 13:02:24 +0900
This still fails in the same manner even for GCC 12.3.0 and 10.5.0.
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: port-arm/56839: GCC emits wrong codes for compare_and_swap_1
builtins
Date: Wed, 5 Feb 2025 11:50:18 +0100
I am not convinced GCC is wrong here. The ABI says the caller needs to
0-extend or sign-extend the sub-word value and pass it as a 32bit register
value. So it all boils down to what the signature of the called function
is - and unfortunately that seems to be poorly or not documented anywhere.
But: gcc/dist/libgcc/config/arm/ implements the functions as taking
signed values - so that would match the gcc generated call sites.
#define SUBWORD_VAL_CAS(TYPE, WIDTH) \
TYPE HIDDEN \
__sync_val_compare_and_swap_##WIDTH (TYPE *ptr, TYPE oldval, \
TYPE newval) \
SUBWORD_VAL_CAS (short, 2)
SUBWORD_VAL_CAS (signed char, 1)
I think we need to make our functions match that (basically Nick's patch,
plus maybe extensions to a few other functions).
Martin
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/56839 CVS commit: src/tests/lib/libc/atomic
Date: Thu, 13 Mar 2025 14:00:51 +0000
Module Name: src
Committed By: riastradh
Date: Thu Mar 13 14:00:51 UTC 2025
Modified Files:
src/tests/lib/libc/atomic: t___sync_compare_and_swap.c
Log Message:
tests/lib/libc/atomic: Test subword compare-and-swap explicitly.
Make sure the sign doesn't bleed into an adjacent word.
We already had failing tests, but this should make the failures a
little more obvious and perhaps check for more adjacent problems.
PR port-arm/56839: GCC emits wrong codes for compare_and_swap_1
bultins on armv5 (el & eb)
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 \
src/tests/lib/libc/atomic/t___sync_compare_and_swap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Taylor R Campbell <riastradh@NetBSD.org>
To: Rin Okuyama <rokuyama.rk@gmail.com>,
Nick Hudson <nick.hudson@gmx.co.uk>,
Martin Husemann <martin@duskware.de>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@NetBSD.org
Subject: Re: port-arm/56839: GCC emits wrong codes for compare_and_swap_1 bultins on armv5 (el & eb)
Date: Thu, 13 Mar 2025 14:29:40 +0000
It looks like gcc is _inconsistent_ about the signedness of the
__sync_* builtins. Here, for example, in gcc-14.2.0, it appears to
use unsigned arguments in libgcc:
134 typedef unsigned int UQItype __attribute__((mode (QI)));
135 DEFINE (FN, 1, UQItype)
...
139 typedef unsigned int UHItype __attribute__((mode (HI)));
140 DEFINE (FN, 2, UHItype)
...
144 typedef unsigned int USItype __attribute__((mode (SI)));
145 DEFINE (FN, 4, USItype)
...
https://gcc.gnu.org/git/?p=3Dgcc.git;a=3Dblob;f=3Dlibgcc/sync.c;h=3D6ffe88a=
ac0f08d1adbc0b02f7f10d50d95d4c6eb;hb=3D04696df09633baf97cdbbdd6e9929b9d4721=
61d3#l125
And, for _FreeBSD_ on arm32, it also uses unsigned arguments:
220 EMIT_ALL_OPS_N (1, unsigned char, "ldrb", "strb", "streqb")
221 EMIT_ALL_OPS_N (2, unsigned short, "ldrh", "strh", "streqh")
222 EMIT_ALL_OPS_N (4, unsigned int, "ldr", "str", "streq")
https://gcc.gnu.org/git/?p=3Dgcc.git;a=3Dblob;f=3Dlibgcc/config/arm/freebsd=
-atomic.c;h=3D7cf00b1e75d4759b983401797f0224764a2ce82d;hb=3D04696df09633baf=
97cdbbdd6e9929b9d472161d3#l220
But elsewhere, e.g. for _Linux_ on arm32, it uses signed arguments:
249 SUBWORD_VAL_CAS (short, 2)
250 SUBWORD_VAL_CAS (signed char, 1)
https://gcc.gnu.org/git/?p=3Dgcc.git;a=3Dblob;f=3Dlibgcc/config/arm/linux-a=
tomic.c;h=3D6d6683194aff0404967b28030bc7677b0f2e5949;hb=3D04696df09633baf97=
cdbbdd6e9929b9d472161d3#l249
And I have no idea about the code generation parts of things.
We should file a bug upstream, perhaps.
But until we do, I think it should be sufficient to write all of our
__sync_* routines -- including both __sync_bool_* and __sync_val_*, of
course -- with signed arguments and pass them to the unsigned
_atomic_* functions, like Nick suggested.
This should paper over the gcc issue, by forcing gcc to generate code
that always zero-extends the subword when passing arguments in
registers so the comparison will succeed (at least, for ABIs where
that is relevant), without requiring changes to our _atomic_*
definitions which are perfectly good for their signatures.
I guess it is conceivable that there is an ABI where this will do the
wrong thing but I doubt it. Even on riscv64, where 8/16-bit units are
type-extended to 32 bit and then sign-extended to 64 bits (no matter
the signedness of the type), I think this will produce the correct
result. (Also I think these stubs won't be used on riscv anyway.)=20
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/56839 CVS commit: src/tests/lib/libc/atomic
Date: Fri, 25 Apr 2025 12:11:14 +0000
Module Name: src
Committed By: riastradh
Date: Fri Apr 25 12:11:14 UTC 2025
Modified Files:
src/tests/lib/libc/atomic: t___sync_compare_and_swap.c
Log Message:
t___sync_compare_and_swap: Mark tests xfail on armv5.
PR port-arm/56839: GCC emits wrong codes for compare_and_swap_1
bultins on armv5 (el & eb)
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 \
src/tests/lib/libc/atomic/t___sync_compare_and_swap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: rokuyama.rk@gmail.com
Subject: Re: PR/56839 CVS commit: src/tests/lib/libc/atomic
Date: Fri, 25 Apr 2025 14:21:38 +0200
Rin, I would like to resolve this along the lines of the fix suggested
by skrll (but extended to whatever other primitives that change did
not cover). Would you be OK with that?
If so, I'll prepare a patch with the other functions covered.
Martin
From: Rin Okuyama <rokuyama.rk@gmail.com>
To: Martin Husemann <martin@duskware.de>, gnats-bugs@netbsd.org
Cc:
Subject: Re: PR/56839 CVS commit: src/tests/lib/libc/atomic
Date: Mon, 28 Apr 2025 14:57:21 +0900
On 2025/04/25 21:21, Martin Husemann wrote:
> Rin, I would like to resolve this along the lines of the fix suggested
> by skrll (but extended to whatever other primitives that change did
> not cover). Would you be OK with that?
>
> If so, I'll prepare a patch with the other functions covered.
Thanks, please!!
// Belatedly, I catched up with this PR. The current GCC behavior is
// not optimal, but there should be ~ no practical benefits to ``fix''
// GCC in this case, IMO...
rin
>
> Martin
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: PR/56839: GCC emits wrong codes for compare_and_swap_1 bultins
on armv5 (el & eb)
Date: Thu, 19 Mar 2026 15:27:07 +0100
I tried what we last discussed (finaly) but new gcc is not happy
with it:
../common/lib/libc/atomic/atomic_init_testset.c:370:1: error: conflicting types for built-in function '__sync_val_compare_and_swap_2'; expected 'short unsigned int(volatile void *, short unsigned int, short unsigned int)' [-Werror=builtin-declaration-mismatch]
370 | __sync_val_compare_and_swap_2(volatile int16_t *addr, int16_t old, int16_t new)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Rin, did I misunderstand what you meant to do?
Or did something get fixed and the __sync_val_compare_and_swap_N optimization
is now gone?
Here is the full patch I tested:
Index: atomic_cas_16_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_16_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_16_cas.c
--- atomic_cas_16_cas.c 21 Feb 2014 16:06:48 -0000 1.3
+++ atomic_cas_16_cas.c 19 Mar 2026 14:25:45 -0000
@@ -36,12 +36,15 @@
#endif
#include <sys/atomic.h>
-bool bool_compare_and_swap_2(volatile uint16_t *, uint16_t, uint16_t, ...)
+bool bool_compare_and_swap_2(volatile int16_t *, int16_t, int16_t, ...)
asm("__sync_bool_compare_and_swap_2");
bool
-bool_compare_and_swap_2(volatile uint16_t *addr, uint16_t oldval,
- uint16_t newval, ...)
+bool_compare_and_swap_2(volatile int16_t *addr, int16_t oldval,
+ int16_t newval, ...)
{
- return atomic_cas_16(addr, oldval, newval) == oldval;
+ const uint16_t oldv = (uint16_t)oldval;
+ const uint16_t newv = (uint16_t)newval;
+
+ return atomic_cas_16((volatile uint16_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_32_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_32_cas.c,v
retrieving revision 1.2
diff -u -p -r1.2 atomic_cas_32_cas.c
--- atomic_cas_32_cas.c 8 Jan 2026 08:55:25 -0000 1.2
+++ atomic_cas_32_cas.c 19 Mar 2026 14:25:45 -0000
@@ -37,12 +37,15 @@
#include <sys/atomic.h>
-bool bool_compare_and_swap_4(volatile uint32_t *, uint32_t, uint32_t, ...)
+bool bool_compare_and_swap_4(volatile int32_t *, int32_t, int32_t, ...)
asm("__sync_bool_compare_and_swap_4");
bool
-bool_compare_and_swap_4(volatile uint32_t *addr, uint32_t oldval,
- uint32_t newval, ...)
+bool_compare_and_swap_4(volatile int32_t *addr, int32_t oldval,
+ int32_t newval, ...)
{
- return atomic_cas_32(addr, oldval, newval) == oldval;
+ const uint32_t oldv = (uint32_t)oldval;
+ const uint32_t newv = (uint32_t)newval;
+
+ return atomic_cas_32((volatile uint32_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_64_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_64_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_64_cas.c
--- atomic_cas_64_cas.c 8 Jan 2026 08:55:25 -0000 1.3
+++ atomic_cas_64_cas.c 19 Mar 2026 14:25:45 -0000
@@ -39,14 +39,17 @@
#ifdef __HAVE_ATOMIC64_OPS
-bool bool_compare_and_swap_8(volatile uint64_t *, uint64_t, uint64_t, ...)
+bool bool_compare_and_swap_8(volatile int64_t *, int64_t, int64_t, ...)
asm("__sync_bool_compare_and_swap_8");
bool
-bool_compare_and_swap_8(volatile uint64_t *addr, uint64_t oldval,
- uint64_t newval, ...)
+bool_compare_and_swap_8(volatile int64_t *addr, int64_t oldval,
+ int64_t newval, ...)
{
- return atomic_cas_64(addr, oldval, newval) == oldval;
+ const uin64_t oldv = (uint64_t)oldval;
+ const uin64_t newv = (uint64_t)newval;
+
+ return atomic_cas_64((volatile uint64 *)addr, oldv, newv) == oldv;
}
#endif
Index: atomic_cas_8_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_8_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_8_cas.c
--- atomic_cas_8_cas.c 21 Feb 2014 16:06:48 -0000 1.3
+++ atomic_cas_8_cas.c 19 Mar 2026 14:25:45 -0000
@@ -35,13 +35,17 @@
#include <stdbool.h>
#endif
#include <sys/atomic.h>
+#include <stdarg.h>
-bool bool_compare_and_swap_1(volatile uint8_t *, uint8_t, uint8_t, ...)
+bool bool_compare_and_swap_1(volatile int8_t *, int8_t, int8_t, ...)
asm("__sync_bool_compare_and_swap_1");
bool
-bool_compare_and_swap_1(volatile uint8_t *addr, uint8_t oldval,
- uint8_t newval, ...)
+bool_compare_and_swap_1(volatile int8_t *addr, int8_t oldval,
+ int8_t newval, ...)
{
- return atomic_cas_8(addr, oldval, newval) == oldval;
+ uint8_t oldv = (uint8_t)oldval;
+ uint8_t newv = (uint8_t)newval;
+
+ return atomic_cas_8((volatile uint8_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_by_cas32.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_by_cas32.c,v
retrieving revision 1.4
diff -u -p -r1.4 atomic_cas_by_cas32.c
--- atomic_cas_by_cas32.c 3 Sep 2014 19:30:47 -0000 1.4
+++ atomic_cas_by_cas32.c 19 Mar 2026 14:25:45 -0000
@@ -64,7 +64,14 @@ _atomic_cas_16(volatile uint16_t *addr,
return old;
}
-crt_alias(__sync_val_compare_and_swap_2,_atomic_cas_16)
+int16_t
+__sync_val_compare_and_swap_2(volatile int16_t *addr, int16_t old, int16_t new)
+{
+ const uint16_t oldv = (uint16_t)oldval;
+ const uint16_t newv = (uint16_t)newval;
+
+ return _atomic_cas_16((volatile uint16_t *)addr, oldv, newv);
+}
uint8_t
_atomic_cas_8(volatile uint8_t *addr, uint8_t old, uint8_t new)
@@ -88,4 +95,11 @@ _atomic_cas_8(volatile uint8_t *addr, ui
return old;
}
-crt_alias(__sync_val_compare_and_swap_1,_atomic_cas_8)
+int8_t
+__sync_val_compare_and_swap_1(volatile int8_t *addr, int8_t old, int8_t new)
+{
+ const uint8_t oldv = (uint8_t)oldval;
+ const uint8_t newv = (uint8_t)newval;
+
+ return _atomic_cas_8((volatile uint8_t *)addr, oldv, newv);
+}
Index: atomic_init_testset.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_init_testset.c,v
retrieving revision 1.21
diff -u -p -r1.21 atomic_init_testset.c
--- atomic_init_testset.c 9 Jan 2026 08:44:57 -0000 1.21
+++ atomic_init_testset.c 19 Mar 2026 14:25:45 -0000
@@ -345,8 +345,41 @@ __strong_alias(_atomic_cas_ptr_ni,_atomi
atomic_op_alias(atomic_cas_64,_atomic_cas_64)
atomic_op_alias(atomic_cas_64_ni,_atomic_cas_64)
__strong_alias(_atomic_cas_64_ni,_atomic_cas_64)
-crt_alias(__sync_val_compare_and_swap_8,_atomic_cas_64)
+
+int64_t
+__sync_val_compare_and_swap_8(volatile int64_t *addr, int64_t old, int64_t new)
+{
+ const uint64_t oldv = (uint64_t)old;
+ const uint64_t newv = (uint64_t)new;
+
+ return _atomic_cas_64((volatile uint64_t *)addr, oldv, newv);
+}
+
#endif
-crt_alias(__sync_val_compare_and_swap_4,_atomic_cas_32)
-crt_alias(__sync_val_compare_and_swap_2,_atomic_cas_16)
-crt_alias(__sync_val_compare_and_swap_1,_atomic_cas_8)
+
+int32_t
+__sync_val_compare_and_swap_4(volatile int32_t *addr, int32_t old, int32_t new)
+{
+ const uint32_t oldv = (uint32_t)old;
+ const uint32_t newv = (uint32_t)new;
+
+ return _atomic_cas_32((volatile uint32_t *)addr, oldv, newv);
+}
+
+int16_t
+__sync_val_compare_and_swap_2(volatile int16_t *addr, int16_t old, int16_t new)
+{
+ const uint16_t oldv = (uint16_t)old;
+ const uint16_t newv = (uint16_t)new;
+
+ return _atomic_cas_16((volatile uint16_t *)addr, oldv, newv);
+}
+
+int8_t
+__sync_val_compare_and_swap_1(volatile int8_t *addr, int8_t old, int8_t new)
+{
+ const uint8_t oldv = (uint8_t)old;
+ const uint8_t newv = (uint8_t)new;
+
+ return _atomic_cas_8((volatile uint8_t *)addr, oldv, newv);
+}
Martin
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: PR/56839: GCC emits wrong codes for compare_and_swap_1 bultins
on armv5 (el & eb)
Date: Thu, 19 Mar 2026 20:45:31 +0100
Here is a patch that seems to work (builds, and makes the xfail tests
work).
Did I miss anything else?
Martin
Index: atomic_cas_16_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_16_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_16_cas.c
--- atomic_cas_16_cas.c 21 Feb 2014 16:06:48 -0000 1.3
+++ atomic_cas_16_cas.c 19 Mar 2026 19:44:18 -0000
@@ -36,12 +36,15 @@
#endif
#include <sys/atomic.h>
-bool bool_compare_and_swap_2(volatile uint16_t *, uint16_t, uint16_t, ...)
+bool bool_compare_and_swap_2(volatile int16_t *, int16_t, int16_t, ...)
asm("__sync_bool_compare_and_swap_2");
bool
-bool_compare_and_swap_2(volatile uint16_t *addr, uint16_t oldval,
- uint16_t newval, ...)
+bool_compare_and_swap_2(volatile int16_t *addr, int16_t oldval,
+ int16_t newval, ...)
{
- return atomic_cas_16(addr, oldval, newval) == oldval;
+ const uint16_t oldv = (uint16_t)oldval;
+ const uint16_t newv = (uint16_t)newval;
+
+ return atomic_cas_16((volatile uint16_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_32_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_32_cas.c,v
retrieving revision 1.2
diff -u -p -r1.2 atomic_cas_32_cas.c
--- atomic_cas_32_cas.c 8 Jan 2026 08:55:25 -0000 1.2
+++ atomic_cas_32_cas.c 19 Mar 2026 19:44:18 -0000
@@ -37,12 +37,15 @@
#include <sys/atomic.h>
-bool bool_compare_and_swap_4(volatile uint32_t *, uint32_t, uint32_t, ...)
+bool bool_compare_and_swap_4(volatile int32_t *, int32_t, int32_t, ...)
asm("__sync_bool_compare_and_swap_4");
bool
-bool_compare_and_swap_4(volatile uint32_t *addr, uint32_t oldval,
- uint32_t newval, ...)
+bool_compare_and_swap_4(volatile int32_t *addr, int32_t oldval,
+ int32_t newval, ...)
{
- return atomic_cas_32(addr, oldval, newval) == oldval;
+ const uint32_t oldv = (uint32_t)oldval;
+ const uint32_t newv = (uint32_t)newval;
+
+ return atomic_cas_32((volatile uint32_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_64_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_64_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_64_cas.c
--- atomic_cas_64_cas.c 8 Jan 2026 08:55:25 -0000 1.3
+++ atomic_cas_64_cas.c 19 Mar 2026 19:44:18 -0000
@@ -39,14 +39,17 @@
#ifdef __HAVE_ATOMIC64_OPS
-bool bool_compare_and_swap_8(volatile uint64_t *, uint64_t, uint64_t, ...)
+bool bool_compare_and_swap_8(volatile int64_t *, int64_t, int64_t, ...)
asm("__sync_bool_compare_and_swap_8");
bool
-bool_compare_and_swap_8(volatile uint64_t *addr, uint64_t oldval,
- uint64_t newval, ...)
+bool_compare_and_swap_8(volatile int64_t *addr, int64_t oldval,
+ int64_t newval, ...)
{
- return atomic_cas_64(addr, oldval, newval) == oldval;
+ const uin64_t oldv = (uint64_t)oldval;
+ const uin64_t newv = (uint64_t)newval;
+
+ return atomic_cas_64((volatile uint64 *)addr, oldv, newv) == oldv;
}
#endif
Index: atomic_cas_8_cas.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_8_cas.c,v
retrieving revision 1.3
diff -u -p -r1.3 atomic_cas_8_cas.c
--- atomic_cas_8_cas.c 21 Feb 2014 16:06:48 -0000 1.3
+++ atomic_cas_8_cas.c 19 Mar 2026 19:44:18 -0000
@@ -35,13 +35,17 @@
#include <stdbool.h>
#endif
#include <sys/atomic.h>
+#include <stdarg.h>
-bool bool_compare_and_swap_1(volatile uint8_t *, uint8_t, uint8_t, ...)
+bool bool_compare_and_swap_1(volatile int8_t *, int8_t, int8_t, ...)
asm("__sync_bool_compare_and_swap_1");
bool
-bool_compare_and_swap_1(volatile uint8_t *addr, uint8_t oldval,
- uint8_t newval, ...)
+bool_compare_and_swap_1(volatile int8_t *addr, int8_t oldval,
+ int8_t newval, ...)
{
- return atomic_cas_8(addr, oldval, newval) == oldval;
+ uint8_t oldv = (uint8_t)oldval;
+ uint8_t newv = (uint8_t)newval;
+
+ return atomic_cas_8((volatile uint8_t *)addr, oldv, newv) == oldv;
}
Index: atomic_cas_by_cas32.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_cas_by_cas32.c,v
retrieving revision 1.4
diff -u -p -r1.4 atomic_cas_by_cas32.c
--- atomic_cas_by_cas32.c 3 Sep 2014 19:30:47 -0000 1.4
+++ atomic_cas_by_cas32.c 19 Mar 2026 19:44:18 -0000
@@ -64,8 +64,6 @@ _atomic_cas_16(volatile uint16_t *addr,
return old;
}
-crt_alias(__sync_val_compare_and_swap_2,_atomic_cas_16)
-
uint8_t
_atomic_cas_8(volatile uint8_t *addr, uint8_t old, uint8_t new)
{
@@ -87,5 +85,3 @@ _atomic_cas_8(volatile uint8_t *addr, ui
return old;
}
-
-crt_alias(__sync_val_compare_and_swap_1,_atomic_cas_8)
Index: atomic_init_testset.c
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_init_testset.c,v
retrieving revision 1.21
diff -u -p -r1.21 atomic_init_testset.c
--- atomic_init_testset.c 9 Jan 2026 08:44:57 -0000 1.21
+++ atomic_init_testset.c 19 Mar 2026 19:44:18 -0000
@@ -345,8 +345,43 @@ __strong_alias(_atomic_cas_ptr_ni,_atomi
atomic_op_alias(atomic_cas_64,_atomic_cas_64)
atomic_op_alias(atomic_cas_64_ni,_atomic_cas_64)
__strong_alias(_atomic_cas_64_ni,_atomic_cas_64)
-crt_alias(__sync_val_compare_and_swap_8,_atomic_cas_64)
+
+int64_t sync_val_compare_and_swap_8(volatile int64_t *addr, int64_t old, int64_t new)
+ asm("__sync_val_compare_and_swap_8");
+
+int64_t
+sync_val_compare_and_swap_8(volatile int64_t *addr, int64_t old, int64_t new)
+{
+ const uint64_t oldv = (uint64_t)old;
+ const uint64_t newv = (uint64_t)new;
+
+ return _atomic_cas_64((volatile uint64_t *)addr, oldv, newv);
+}
+
#endif
crt_alias(__sync_val_compare_and_swap_4,_atomic_cas_32)
-crt_alias(__sync_val_compare_and_swap_2,_atomic_cas_16)
-crt_alias(__sync_val_compare_and_swap_1,_atomic_cas_8)
+
+
+int16_t sync_val_compare_and_swap_2(volatile int16_t *addr, int16_t old, int16_t new)
+ asm("__sync_val_compare_and_swap_2");
+
+int16_t
+sync_val_compare_and_swap_2(volatile int16_t *addr, int16_t old, int16_t new)
+{
+ const uint16_t oldv = (uint16_t)old;
+ const uint16_t newv = (uint16_t)new;
+
+ return _atomic_cas_16((volatile uint16_t *)addr, oldv, newv);
+}
+
+int8_t sync_val_compare_and_swap_1(volatile int8_t *addr, int8_t old, int8_t new)
+ asm("__sync_val_compare_and_swap_1");
+
+int8_t
+sync_val_compare_and_swap_1(volatile int8_t *addr, int8_t old, int8_t new)
+{
+ const uint8_t oldv = (uint8_t)old;
+ const uint8_t newv = (uint8_t)new;
+
+ return _atomic_cas_8((volatile uint8_t *)addr, oldv, newv);
+}
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.