Excess arguments or returns are passed in memory in essentially the same way that a conventional ABI does. Ditto VARARGS and over-large args/results.
The memory-pass ABI on a Mill has to cope with the fact that a Mill call can cross protection boundaries. Consequently it is important that the argument pass happens without the caller being able to see the callee’s frame, nor the callee see the caller’s frame. Yet still get the data across. Yes, yet more magic 🙂
The full explanation requires pictures, but the short answer is that the caller piles the arguments contiguously up in his own space, and then the call automatically grants access to the pile to the callee, and the access is automatically revoked at the return. Addressing is via a pair of specRegs (unimaginatively called INP and OUTP) that can be used as base registers in load/store/LEA.
Pictures in one of the future talks at some point, don’t hold your breath 🙁