On Fri, 3 Jan 2025 at 01:22, Geert Uytterhoeven <geert@xxxxxxxxxxxxxx> wrote: > > Perhaps this is an issue with sparse? No, this is just m68k doing disgusting things that happen to work with gcc, because gcc considers casts to be lvalues (which in turn is comes from some horrid C++ thing, since in C++ casting is a whole magical extra complexity). IOW, this m68k pattern is horrendous, and sparse quite reasonably complains about it: #define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulu%.l %3,%1:%0" \ : "=d" ((USItype)(w0)), \ "=d" ((USItype)(w1)) \ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))) notice how it has two register outputs (the "=d"), and the destination of said output is not a proper lvalue, but a cast expression. I think you could just remove the cast. Afaik the w0/w1 arguments come from #define __umulsidi3(u, v) \ ({DIunion __w; \ umul_ppmm (__w.s.high, __w.s.low, u, v); \ __w.ll; }) and __w.s.high and __w.s.low are from struct DIstruct, which uses "SItype". So all the cast does is to change the signedness of the variable, but that has no *meaning* when you assign to it and the sizes match. Alternatively, you could just use the right types explicitly and write the umul_ppmm() macro something like #define umul_ppmm(w1, w0, u, v) do { \ USItype __w0, __w1; \ __asm__ ("mulu%.l %3,%1:%0" \ : "=d" (__w0) \ "=d" (__w1) \ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))); \ w0 = __w0; w1 = __w1; } while (0) NOTE! UNTESTED! Treat the above as a "something like this, perhaps". Linus