I believe this is incorrect? I believe RV{32,64}-with-C is simply a superset of RV{32,64}-without-C. Now I have only implemented RV32I, so I'm not that familiar with the C extension or other extensions for that matter, but in my digging through the various RV specs, I haven't found anything which suggests that implementing C requires breaking code compiled without the use of C.
Do you have any details?
Wish I could use strike-outs here, but oh well.
i̵t̵ ̵t̵u̵r̵n̵s̵ ̵o̵u̵t̵ ̶t̶h̶e̶r̶e̶ ̶a̶r̶e̶ ̶d̶i̶f̶f̶e̶r̶e̶n̶t̶ ̴s̴t̴r̴i̴c̴t̴ ̴t̴h̴r̴o̴u̴g̴h̴ ̴s̴t̴y̴l̴e̴s̴
and the font HN uses doesn't handle any of them well
> The C extension is compatible with all other standard instruction extensions. The C extension allows 16-bit instructions to be freely intermixed with 32-bit instructions, with the latter now able to start on any 16-bit boundary [...]
Consider also a 16-bit aligned 32-bit instruction crossing a page boundary, potentially with different access permissions. This type of bug allowed userspace applications to hang early Cortex-A8 based phones(ARM errata 657417).
(This mostly applies to the high end, but designers on low-end devices may be more SRAM-constrained)
Anyway, all that aside, I personally wouldn't be sad to see the C extensions go away. I'm actively designing a RISC-V core for a small game console, and probably won't implement them, and will spend the time on more DV instead. I don't expect them to have any meaningful benefits for my case and mostly increase frontend complexity.
I know there's the big discussion about macro-op fusion. But in hindsight, I think a big motivator for C -- implicit or not -- was the fact that on the very low-end microcontroller or in the softcore (FPGA) world, you typically have disproportionately low amounts of SRAM available versus compute fabric. Those were the initial deployment targets (and initial successful deployments!) for RISC-V, since you need tons of extra features for "Application Class" designs. These cores often have a short pipeline and are completely in-order, so their cost and verification effort are much lower. These are (very likely) not going to implement macro fusion, at least on the medium-low end. So, increasing the effective size of the I-cache through smaller opcodes is often a straight win to increase IPC. On the other hand, Application Class designs today are typically OoO, so they achieve high IPC while still hiding miss latencies pretty effectively; smaller instructions are still good but the benefits they provide aren't as prominent. And it does use a ridiculous amount of opcode space, yes.
Another big issue for Application Class systems IIRC -- unrelated to all this -- is that I don't think hardware implementing C can actually run binaries compiled without it. This means Linux distros cannot compile for the lowest common denominator of "no C extension" and ship it to all users. It is effectively a fundamental ABI break, so they must ship packages for users with C, and a whole different set of packages for users without. That is... really not ideal. In practice having to maintain a whole different ABI for things like this means few people do it, it bitrots, and the quality is overall lower everywhere.
I wonder if they would have just been better off copying one of ARM's design principles from the very start: actual design families akin to the -M, -R, and -A series of ARM processors, created for different actual design spaces. These could actually be allowed to have (potentially large!) incompatibilities between them while still sharing a lot of the base instruction set and privileged e.g. PMP extensions could probably exist among all of them. I'd be happy to have an "Application Class" "-A series" RISC-V processor that could run Linux but didn't have compressed instructions or whatever; it probably has enough cache and OoO capacity to handle it.