OK, fair enough that one doesn’t necessarily imply the other, but if you were designing a CPU/ISA today, would you start with a CISC design? If so, why?
I do wonder if CISC might make a comeback. One is cache efficiency.
If you are doing many-core (NOT multi-core) than RISC make obvious sense.
If you are doing in-order pipelined execution, than RISC makes-sense.
But if you are doing superscalar out-of-order where you have multiple execution units and you crack instructions anyway, why not have CISC so that the you have more micro-ops to reorder and optimise? It seems like it would give the schedulers more flexibility to keep the pipelines fed.
With most infrastructure now open-source I think the penalty for introducing a new ISA is a lot less burdensome. If you port LLVM, GCC, and the JVM and most businesses could use it in production immediately without needing emulation that helped doom the Itanium.
I agree that cache efficiency is important. You can never have enough L1. It seems to me that compressed instructions ala ARM Thumb and RISC-V Compressed give you most of what you really want. One of the problems in the CISC era was that the compilers actually didn’t generate many of the fancy instructions, so it’s unclear whether you’d get back much from decoding massive amounts of micro-ops and letting the superscaler scheduler work it out if the compiler is mostly generating the simple instructions anyway. That said, the compilers of that era were also less sophisticated, so maybe we’d do better now.
In the end, though, I don’t see CISC making any significant come back, other than perhaps in embedded where code size is definitely important and speeds are generally lower and multi-cycle execution is ok. But it feels like we already have all the ISAs we need to cover that space pretty well already.
I'd do the same thing others are doing, which is a hybrid of classic RISC and CISC elements:
* From the RISC side, adhere to a load-store architecture with lots of registers
* From the CISC side, have compressed variable length encoding and fused instructions for common complex operations (e.g. multiply-add, compare-and-branch)
That’s the right answer, IMO. To me, that sounds a lot like a RISC with some complex instructions, which is really where all RISCs have landed in any case. That said, I would use fixed length compressed instructions ala Thumb and RISC-V Compressed. And there’s nothing wrong with that patch of design space. That works.
Thumb was originally fixed length yes, but Thumb-2 introduced 32-bit encoded instructions to complete the set, so it's now variable length encoded.
Likewise, RISC-V Compressed only provides compressed encodings of a subset of RISC-V instructions, so binaries that make use of RISC-V Compressed will be variable-length encoded, mixing 16-bit and 32-bit encoded instructions.
Historically, having two instruction lengths was common or even the norm for RISC and RISC-like (before the name was made up) register-rich load/store machines including CDC6600, Cray 1, IBM 801 (original 24 bit version), Berkeley RISC-II.
It was only RISC ISAs introduced between 1985 (Arm, MIPS, SPARC) and 1992 (DEC Alpha) that had fixed-length 4 byte instructions -- a mere eight years out of the 60 year history of RISC designs.
Fair point on the RISC-II having non-fixed instruction sizes.
In any case, I think it's weird that we've experienced semantic drift to the point that architectures with instruction sets that are too large and complex to be considered reduced get referred to as RISC simply because they're load-store architectures with lots of registers.
I don't think newer things labelled as "RISC" have significantly (if at all) exceeded original 1985 ARM for complexity of an individual instruction, or 1990 IBM RS/6000 for sheer number of instructions, so unless you have a newer example this "semantic drift" happened 35-40 years ago in the first 5-10 years after publication of the first RISC papers.
Arm64 of course hits both axes.
While I think having a small number of instructions (at least optionally) is desirable for a number of reasons I don't see that as defining RISC. RISC is, I think, about instructions being uniform enough to not complicate the execution pipeline. If you keep the instructions to reading two registers and writing a result to one register, preferably after 1 clock cycle, then I don't think there is any number of different operations available on those 2 operands that would make something be not RISC any more.
Some people think it's ok to read 3 input registers -- again, Arm since 1985. And everyone in floating point, since `±A*B±C` is the fundamental and most common operation in floating point algorithms and IEEE 754-2008 mandates that the operation be done without intermediate rounding.
There are some manufacturers who have apparently thought "RISC" is a good marketing thing and put the label on things that I don't consider to be RISC. For example Microchip claims 8 bit PIC is RISC. It certainly isn't -- it's a classic accumulator architecture (as are Intel 8051 and 8080 and MOS 6602) with Acc-Mem and Mem-Acc instructions. Calling memory "registers" doesn't change that On the other hand Atmel AVR is clearly RISC.
Also TI market the MSP430 as RISC. It's a lovely little minimalist 16 bit ISA very similar to PDP-11 and, like PDP-11, all the 2-operand arithmetic operations can be done memory-to-memory which is a definite RISC no-no. Original M68000 - also PDP-11 like -- has a better claim to being RISC as (like 8086) it at least kept everything except MOV{B,W,L} down to reg-mem.
But, no, PIC and MSP430 are not RISC despite their manufacturers saying they are.