I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
The important point is that there is no reason why a 16-bit/32-bit encoding shouldn't have smashed Aarch64's 32-bit only code density.
My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
> I agree that 16-bit/32-bit variable length would struggle to beat x86. But I suspect it could have gotten close, simply because x86 wastes a huge amount of its advantage on legacy cruft.
I'm saying the opposite. Maybe some theoretical CISC-V would leave RISC-V behind, but x86(and -64) makes wild choices for instruction density, and RV64GC already clearly beats x86-64 in .text density.
> My secondary point, is that why should RISC-V limit itself to just 16-bit/32-bit? It has the encoding space set aside for 6 bytes, 8 bytes, 10 bytes and all the way up to 24 bytes (which is overkill). If it's already paying the variable length tax, it should be making better use of it. IMO, a 2, 4, 6, 8, 10... byte scheme should be able to massively improve on x86's code density.
There's nonlinear issues as you add more options. A 16-32 decoder is pretty simple, a 16-32-48 isn't the worse thing in the world (and a 32bit immediate might make it worth it), but you start to hit weird explosions in gate count once you go much past that. Hence x86's splitting into essentially multiple front end banks in modern designs, and even then typically only has one decoder per bank that can decode everything, and even that takes multiple cycles for some instruction sequences, even just to discover the length.
The larger lengths in the RISC-V spec are more targeted towards bespoke stuff like GPGPU that's maxing out issuing a single instruction per instruction stream anyway. When you look at shader machine code, it's clear density was essentially an afterthought, but they love them some 64bit wide instructions. Which unsurprisingly is pretty much the same width of vertical microcode in archs that still do such a thing.