Set setMaxAtomicSizeInBitsSupported for Mips. Set the value as appropriate for 64-bit MIPS vs 32-bit and take MIPS-I into consideration.
I am not quite sure if I used the appropriate Subtarget checks.
brad on Jan 7 2023, 12:56 AM.Authored by
Makes sense to me.
For MIPS 1, we have essentially two choices: either we use setMaxAtomicSizeInBitsSupported(0), and generate __atomic_* calls, or we set setMaxAtomicSizeInBitsSupported(32), and generate native load/store with __sync_* calls for cmpxchg/atomicrmw. Either way, we can't actually provide implementations; the user has to make it work somehow. See D137980 for a similar discussion... but generating __sync_* calls seems to cause less trouble. (Not sure if anyone cares about MIPS 1 these days, though.)
Hi! Sorry to jump in randomly, but it just so happens that I was working on a very similar patch right now. Funnily enough I need to make everything work on MIPS I, because there are still people caring for that target, mainly in the homebrew scene as the CPU for the Playstation 1 and coprocessor of the Playstation 2 both are MIPS I targets.
Wouldn't it be more correct to set atomic widths to 0 and generate __atomic_* calls? As just emitting sync fences on CAS/RMW operations break with multithreading/preemption? I'm not so sure about the Playstation 1 but I'm pretty sure the Playstation 2 has multithreading support on the coprocessor. Also, as it has already been pointed out, MIPS I doesn't even support sync operations, so relying on some implementation of them, to me, seems more complicated to achieve.
You need some sort of operating-system level magic to make atomicrmw/cmpxchg work without ll/sc. Disabling interrupts, or a restartable sequence, or something along those lines. Most of the ways you'd implement that end up being compatible with lowering atomic load/store to plain load/store operations. Granted, other implementations are possible.
Yes exactly, what I'm saying is that if we just emit sync fences (in the form of libcalls) for CAS/RMW operations it might become impossible to target systems that have some sort of preemption. So I personally would prefer to set atomic width to 0 and generate libcalls for all atomic operations, so implementors for specific environments can do the right thing for the platform.
Baremetal Playstation 1 is likely the only MIPS1 target anyone will ever use with LLVM, so we should do whatever makes sense there. I don't think it makes sense to theorycraft configurations that don't exist. (If MIPS1 Linux were a thing, it would probably do something like https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt .)
Fair enough. Looking more in detail at Playstation 1 and 2, they both use cooperative multithreading so preemption is not an issue. So for these targets it doesn't really make a difference.
Just wanted to point out this recent github bug report..