NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-arm/56839: GCC emits wrong codes for compare_and_swap_1 bultins on armv5 (el & eb)
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=gcc.git;a=blob;f=libgcc/sync.c;h=6ffe88aac0f08d1adbc0b02f7f10d50d95d4c6eb;hb=04696df09633baf97cdbbdd6e9929b9d472161d3#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=gcc.git;a=blob;f=libgcc/config/arm/freebsd-atomic.c;h=7cf00b1e75d4759b983401797f0224764a2ce82d;hb=04696df09633baf97cdbbdd6e9929b9d472161d3#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=gcc.git;a=blob;f=libgcc/config/arm/linux-atomic.c;h=6d6683194aff0404967b28030bc7677b0f2e5949;hb=04696df09633baf97cdbbdd6e9929b9d472161d3#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.)
Home |
Main Index |
Thread Index |
Old Index