Some people believe that RISC-V is simple and elegant, other people believe that RISC-V is one of the worst and ugliest instruction-set architectures that have ever been conceived. Usually the first class of people consists of people with little experience in assembly programming and the second consists of those who had experience in using multiple ISAs for assembly programming.
Using RISC-V for executing programs written in high-level programming languages is fine. It should be noted that in the research papers that have coined the name RISC, where there was a list of properties defining what RISC means, one of them was that RISC ISAs were intended to be programmed exclusively in high-level languages and never in assembly language. From this point of view, RISC-V has certainly followed the original definition of the term RISC, by making the programming in assembly language difficult and error prone.
On the other hand, learning assembly programming with RISC-V is a great handicap because it does not expose the programmer to some of the most fundamental features of programming in an assembly language, because RISC-V does not have even many features that existed in Zilog Z80 or in vacuum-tube computers from 70 years ago, like integer overflow detection and indexed addressing.
Someone who has learned only RISC-V has an extremely incomplete image about how a normal instruction set architecture looks like. When faced with almost anyone of the several thousands of different ISAs that have been used during the last three quarters of a century a RISC-V assembly programmer will be puzzled.
6502 is also too quirky and unusual. I agree that among the old ISAs DEC PDP-11 or Motorola MC68000 are better ISAs for someone learning to program in an assembly language from scratch. Writing assembly programs for any of these 2 is much simpler than writing good assembly programs for RISC-V, where things as simple as doing a correct addition are quite difficult (by correct operation I mean an operation where any errors are handled appropriately).
This is the first time I’ve heard of this, but RISC-V not providing access to carry and overflow status seems insane. E.g. for BigNum implementations and constant-time (branchless) cryptography.
RISC-V does not have carry and overflow flags in the traditional sense. Which is actually great because it needs you don't have to specify the complicated details of how any single instruction might affect the flags. (And yes, it uses compare-and-branch instructions instead.) It does provide suggested insn sequences to check for overflow, which might be executed as a single instruction in a more full-featured implementation.
Those sequences of instructions transform the cheapest arithmetic operations into very expensive operations and they make unachievable the concurrent execution of up to 8 arithmetic instructions, which is possible in other modern CPU cores.
Using instruction fusion of a pair of instructions to achieve the effect of indexed addressing, but in a many times more complex and more inefficient way, is believable even if ugly.
Using instruction fusion to fuse the long sequence needed for checking overflow into a single operation is unbelievable.
Even if that were done, the immense discrepancy in complexity between detecting overflow with one extra XOR gate in a 64-bit adder that may have hundreds of gates, depending on its speed, and an instruction decoder capable of fetching ahead and decoding the corresponding long instruction sequence into one micro-operation is ridiculous.
I'm surprised RISC-V doesn't expose carry. Thanks for pointing this out. For embedded programming with AVR and ARM I often prefer ASM over C because I have access to the carry flag and I don't have to worry about C/C++ overflow undefined behavior.
I also agree the 6502 is not a simple ISA. However after learning 6502 machine code, MIPS, AVR, and ARMv6-M were all easy to learn.
Lol. I've been programming assembly language since 1980, on at least (that I can remember) 6502, 6800, 6809, 680x0, z80, 8086, PDP-11, VAX, Z8000, MIPS, SPARC, PA-RISC, PowerPC, Arm32, Arm64, AVR, PIC, MSP430, SuperH, and some proprietary ISAs on custom chips.
RISC-V is simply the best ISA I've ever used. It's got everything you need, without unnecessary complexity.
> RISC ISAs were intended to be programmed exclusively in high-level languages and never in assembly language.
That's a misunderstanding. RISC was designed to include only the instructions that high level language compilers found useful. There was never any intention to make assembly language programming difficult.
Some early RISC ISAs did make some of the housekeeping difficult for assembly language programmers by for example having branch delay slots, or no hardware interlocks between things such as loads or long-running instructions such as multiple or divide and the instructions that used their result. So if you counted wrong and tried to access the result register too soon you probably silently got the previous value.
That all went completely out the window as soon as there was a second implementation of the same ISA with a different number of pipeline stages, or more of less latency to cache, or a faster or slower divide instruction. And it was just completely untenable as soon as you got CPUs executing 2 or 3 instructions in each clock cycle instead of 1. The compiler could not calculate when it was safe to use a result because it didn't know what CPU version the code would be running on.
Modern RISC -- anything deigned since 1990 -- is completely fine to program in assembly language.
> RISC ISAs were intended to be programmed exclusively in high-level languages and never in assembly language.
> That's a misunderstanding. RISC was designed to include only the instructions that high level language compilers found useful. There was never any intention to make assembly language programming difficult.
That is no misunderstanding, but almost a quotation of the 4th point in the definition of the term "RISC", in “RISC I: A Reduced Instruction Set VLSI Computer”, David A. Patterson & Carlo H. Sequin (University of California, Berkeley), presented at ISCA '81.
Of course they did not try to make assembly language programming difficult as a goal, but the theory was that no ISA feature should be provided with the purpose of making the assembly programming easy, because it was expected that any inconvenience shall be handled by a compiler for a high-level language.
In practice, only the academic RISC ISAs from Berkeley and Stanford were less convenient to program in assembly language, while those from the industry, like IBM 801 and ARM and their successors did not have any disadvantage for programming in assembly language, on the contrary they were simpler to program than many less orthogonal older processors.
RISC-V has everything needed only in the same way as an UNIVAC from 1950 has everything needed.
As an ISA for didactic hardware implementation, RISC-V is very good. As a target for writing programs it is annoying whenever you are writing non-toy programs.
RISC-V has only one good feature in comparison with x86 or ARM, the combined compare-and-branch instructions, which saves a lot of instruction words in comparison with separate instructions, because branches are very frequent, e.g. one branch to every 6 to 8 instructions.
Except for that, there are too many important features that are missing without absolutely any justification and without any benefit.
Detecting integer overflow in hardware, like in almost all CPUs ever made, with the notable exceptions of Intel 8080, RISC-V and a few other that have never pretended to be suitable for general-purpose computing, is exceedingly simple and cheap. Detecting integer overflow in software is complicate and very expensive.
Implementing indexed addressing in hardware is extremely simple in comparison with implementing instruction fusion or with increasing the number of functional units and increasing the width of all structures to be able to execute more instructions concurrently, in order to reach the same performance for an ISA without indexed addressing.
While the loops of RISC-V usually save an instruction at the loop test, they waste at least one instruction at each memory access, so except for very simple loops RISC-V needs much more instructions for executing an interation than most other ISAs.
The RISC-V proponents have bogus excuses, i.e. the availability of the compressed mode and the possibility of using instruction fusion. These 2 are just workarounds for a bad instruction encoding that requires an excessive number of instructions for encoding any program. They can never be as good as a well designed instruction encoding.
All competing ISAs that are better encoded can also implement a compressed encoding (like ARM, MIPS and POWER also have) and they can implement instruction fusion. They seldom do this only because they seldom need this, unlike RISC-V.
I have programmed in about the same list as ISAs as enumerated by you, over about the same time interval. I agree that for most controller tasks RISC-V is acceptable, even if sub-optimal. When it is cheap enough (due to no royalties) that can overcome any other defects. On the other hand I have also written various programs dominated by complex computations, where the deficiencies in arithmetic and array addressing of RISC-V would have made it clearly unacceptable.
"4. Support high-level languages (HLL). An explanation of the degree of support follows. Our intention is always to use high-level languages with RISC I."
That doesn't say anything about making it difficult to use assembly language. It speaks only to making it UNNECESSARY, to the largest extent practical.
Maybe you weren't around at the time, but I remember very clearly the literature on the software crisis and the VAX being designed to make assembly language programming as productive as possible, EVEN at the expense of raw machine speed (the VAX 11/780 was slower than the PDP 11/70), because no one trusted the performance of high level languages.
The above aim of RISC was to make a machine fast enough and easy enough for compilers to use effectively that there would seldom be a reason to move out of the more productive high level language.
Great flamebait ;) what makes riscv suitable for teaching is that the ISA is trivial to map to hardware. This is because it is so regular. Students with zero experience can design simple riscv cpus in their first asm course. More experienced students can design cpus with pipelining, branch prediction, ooo execution, etc. Old ISAs from the 1980s are way more difficult.
RISC-V has been designed with the exact goal for being an ISA easy to implement in hardware, so that students will be able to do this.
For this purpose, RISC-V is excellent.
The RISC-V ISA has not been designed as an efficient method for encoding computer programs and even less for being easy to program in assembly language.
When programming in assembly language, a complex ISA is bad, because one cannot hold in mind all its peculiarities, but a too simple ISA is even worse, because every simple operation must be implemented by a complex sequence of instructions that is easy to forget and to get wrong.
I wonder if any of those who claim that the RISC-V ISA is simple can remember without searching the documentation how to implement the checks for integer overflow after each arithmetic operation.
The didactic examples of using RISC-V usually do not check for any errors, which is not acceptable in any critical application. I find funny that sometimes the same people who claim that the unsafe RISC-V ISA is good also claim that C and C++ are bad, because with default compilation options they are unsafe in comparison with e.g. Rust.
> I wonder if any of those who claim that the RISC-V ISA is simple can remember without searching the documentation how to implement the checks for integer overflow after each arithmetic operation.
I mean, I can't give you the Hacker's Delight magic numbers for expressing integer division by a constant via multiplication on AArch64 or x86-64 off the top of my head either, but that's what we have compilers for. The fact that you sometimes have to look up how to do simple things is just part of programming.
Using RISC-V for executing programs written in high-level programming languages is fine. It should be noted that in the research papers that have coined the name RISC, where there was a list of properties defining what RISC means, one of them was that RISC ISAs were intended to be programmed exclusively in high-level languages and never in assembly language. From this point of view, RISC-V has certainly followed the original definition of the term RISC, by making the programming in assembly language difficult and error prone.
On the other hand, learning assembly programming with RISC-V is a great handicap because it does not expose the programmer to some of the most fundamental features of programming in an assembly language, because RISC-V does not have even many features that existed in Zilog Z80 or in vacuum-tube computers from 70 years ago, like integer overflow detection and indexed addressing.
Someone who has learned only RISC-V has an extremely incomplete image about how a normal instruction set architecture looks like. When faced with almost anyone of the several thousands of different ISAs that have been used during the last three quarters of a century a RISC-V assembly programmer will be puzzled.
6502 is also too quirky and unusual. I agree that among the old ISAs DEC PDP-11 or Motorola MC68000 are better ISAs for someone learning to program in an assembly language from scratch. Writing assembly programs for any of these 2 is much simpler than writing good assembly programs for RISC-V, where things as simple as doing a correct addition are quite difficult (by correct operation I mean an operation where any errors are handled appropriately).