Ah yeah. Cool.

I did something similar in a recent Z80 based project, shouldn't be too difficult to do that on m68k.

Only trouble I can see arising from this is enabling and disabling interrupts is privileged, and from the 68010 onwards you can't even see the status register to know if interrupts are on/off outside of supervisor mode, so you wouldn't be able to execute this code from any application running in user mode.

I suppose that is why it's better trapped as an invalid instruction and emulated lower down?


On Fri, Apr 24, 2020, 11:20 Rich Felker <dalias@libc.org> wrote:
On Fri, Apr 24, 2020 at 11:14:38AM +1000, Tom Storey wrote:
> Sorry to ask what sounds like a dumb question, but is
>
> cli;nonatomic_cas;sti
>
> basically "disable interrupts, do something equivalent to cas, re-enable
> interrupts"?

Yeah. Basically:

static inline int a_cas(volatile int *p, int t, int s)
{
        __asm__ __volatile__("cli" : : : "memory");
        if (*p==t) *p=s; else t=*p;
        __asm__ __volatile__("sti" : : : "memory");
        return t;
}

where cli and sti are replaced with the m68k instructions for those
operations. Of course if you might have code that already has
interrupts disabled somewhere calling libc stuff, you may need to make
it save the old interrupt state and restore it rather than just sti.
See the sh2 version (runtime selected so it's in __sh_cas_imask in
src/thread/sh/atomics.s and atomic_arch.h just calls the
runtime-selected function) for an example of code doing this

Rich