No comment on the ARM64 vs RISCV ports, but my rule of thumb for ports back in the Plan 9 days was that if something ran on both Linux and Windows, then I could get it working on Plan 9 in reasonable time. Not because Linux and Windows are anything like Plan 9, but because they were different enough from each other that it meant that the developers had given proper thought to separating out OS-specific code. The second port is always the hard one. After that the only difficulties are system-specific.
When I started on Go, we had only amd64. I added 386 about six months later, with help from Ken to get the register optimizer hooked up. Given that we had already planned for separating architecture-specific code, it was relatively straightforward, but even so there was still quite a bit of refactoring, mainly to reduce copies of code that could be moved inside the portable boundary. We did arm a few months later, again not a big deal. Those were the ones Go shipped in the open source release. At that point I think things were very solid from a portability standpoint.
The most difficult port was probably power64, both because it has a very unusual calling convention and because it is big-endian. There turned out to be code in the runtime that accessed the garbage collection bitmaps as both an array of uint32 and as an array of uint8. That's fine on little-endian but not on big-endian. At this point I think it would be reasonable to just drop big-endian systems entirely. The endian wars are over, little endian won, and it allows that kind of punning.
Best,
Russ