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