Since its initial release, Go has used a stack-based calling convention based on the Plan 9 ABI, in which arguments and result values are passed via memory on the stack. This has significant simplicity benefits: the rules of the calling convention are simple and build on existing struct layout rules; all platforms can use essentially the same conventions, leading to shared, portable compiler and runtime code; and call frames have an obvious first-class representation, which simplifies the implementation of the go and defer statements and reflection calls. Furthermore, the current Go ABI has no callee-save registers, meaning that no register contents live across a function call (any live state in a function must be flushed to the stack before a call). This simplifies stack tracing for garbage collection and stack growth and stack unwinding during panic recovery.
I didn't consider the effects of goroutines, but it's pretty common that JITs that have to emit precise stackmaps simply don't use callee-saved registers, so it doesn't seem any harder to make goroutine stacks first-class. But the detail is in the details, always.
This is basically argument from implementation simplicity. I am of the opinion that implementation simplicity is overrated, and should be essentially ignored, especially for projects as widely used as Go.
It's not. It's in a document proposing a more complex approach.
The point of that discussion, which is clear in the original text, is to identify the benefits of the existing approach and retain them if possible through the transition to a register based ABI.
https://go.googlesource.com/proposal/+/refs/changes/78/24817...