Advise needed on implementing atomic operations for M68k

Hello!

One missing part in the M68k backend is currently support for atomic operations
such as atomic load and store and compare and swap which results in a backend
error [1] when trying to build code which uses atomic operations.

I have already looked into the other backends such as X86, Sparc and PowerPC trying
to understand how the implementation works but I haven't fully understood everything
yet.

From my current understanding, we would have to define atomic_load_8/16/32 and atomic_

store_8/16/32 in the TableGen code as well as atomic_cmp_and_swap_8/16/32. For load and
store, it should be sufficient to use normal move instructions [2] and for compare_
and_swap, there are actually two instructions, CAS [3] and CAS2 [4] available
on m68k, the latter could even be used to implement a 64-bit compare_and_swap
if I'm not mistaken [5].

For compare_and_swap, it seems the necessary pattern would resemble the one used
on Sparc V9, for example:

let Predicates = [HasV9], Constraints = "$swap = $rd", asi = 0b10000000 in
  def CASrr: F3_1_asi<3, 0b111100,
                (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
                                     IntRegs:$swap),
                 "cas [$rs1], $rs2, $rd",
                 [(set i32:$rd,
                     (atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>;

but I don't fully understand every line in this snippet of TableGen code so I was
wondering whether someone could point me at some documentation that helps making
sense of that all.

And I assume we also need a lowering function in M68kISelLowering.cpp, don't we?

Thanks,
Adrian