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