Part IIInstruction Set Architectures

RISC vs CISC and Other Classifications

August 3, 2026·31 min read·intermediate

The previous chapter described the anatomy of an instruction set without passing judgment on which design choices are superior. This chapter adds history and classification. It traces the arc from the earliest…

The previous chapter described the anatomy of an instruction set without passing judgment on which design choices are superior. This chapter adds history and classification. It traces the arc from the earliest accumulator machines of the 1940s through the stack experiments of the 1960s, the general-purpose register revolution of the 1960s and 1970s, the RISC insurgency of the 1980s, and the CISC counterattack that followed. The conclusion is that the boundary between RISC and CISC has blurred almost to the point of irrelevance, and that a richer taxonomy is needed to describe modern instruction sets.

01.Operand Models: Where Do the Inputs Live?

Before asking how complex an instruction set should be, it helps to ask a more primitive question: where does an arithmetic instruction find its operands? Three answers have been tried in the history of computer design, and each one defines a class of machine.

The accumulator model

The earliest electronic computers had limited storage and even more limited wiring. The simplest way to build an arithmetic unit was to give it a single implicit register, the accumulator, and route every computation through that register. An “add memory” instruction fetches a value from a memory address and adds it to whatever is already in the accumulator. The result stays in the accumulator. A “store” instruction copies the accumulator to a memory address. The pattern for computing C=A+BC = A + B is:

Accumulator-style code for C=A+BC = A + B.

Plain Text
LOAD A ; accumulator <- mem[A]
ADD B ; accumulator <- accumulator + mem[B]
STORE C ; mem[C] <- accumulator

The EDSAC (1949), the IAS machine at Princeton (1952), and the early IBM 701 (1952) were all accumulator machines. The model is simple to implement because the ALU always reads one operand from the accumulator and one from memory, and always writes the result to the accumulator. The cost is traffic: every intermediate result that does not fit in the single accumulator must be stored to memory and loaded back later.

The stack model

The stack machine replaces the single accumulator with an implicit operand stack. A “push” instruction loads a value from memory and pushes it onto the stack. An “add” instruction pops the top two entries, adds them, and pushes the result. A “pop” instruction stores the top of the stack to memory. The same C=A+BC = A + B computation becomes:

Stack-machine code for C=A+BC = A + B.

Plain Text
PUSH A ; push mem[A] onto stack
PUSH B ; push mem[B] onto stack
ADD ; pop two, push sum
POP C ; pop result to mem[C]

The Burroughs B5000 (1961) was the most celebrated stack machine. Its designers argued that the stack model maps naturally to the evaluation of arithmetic expressions, which compilers already convert to postfix (reverse Polish) notation internally. Java bytecode and the WebAssembly virtual machine both use a stack model at the specification level, though the hardware underneath is always a register machine. The JVM’s just-in-time compiler translates the stack-based bytecode into register-based machine code as part of its compilation pass, effectively undoing the stack representation before execution.

The appeal of the stack model is simplicity of encoding. Arithmetic instructions name no registers at all: the operands are implicit. This makes instructions short. The cost is that the stack’s strict last-in, first-out discipline makes it hard to keep frequently accessed values near the top. A computation that needs a value buried three entries deep must swap or duplicate stack entries, generating extra instructions. Compilers targeting stack machines tend to produce more instructions than compilers targeting register machines for the same computation.

The general-purpose register model

The general-purpose register (GPR) model gives the processor a file of kk named registers and lets arithmetic instructions specify their source and destination registers explicitly. The IBM System/360 (1964) was the landmark GPR design [1]. It provided 16 general-purpose 32-bit registers and a rich set of instructions that could name any register as source or destination. The CDC 6600 (1964), designed by Seymour Cray, had 24 operating registers organized into three specialized banks (8 address, 8 data, 8 index) and introduced many of the ideas that later became central to superscalar and out-of-order execution.

The GPR model won. Every commercially significant ISA since the mid-1970s has been a GPR machine. RISC-V has 32 registers. ARM A64 has 31. x86-64 has 16 (recently extended to 32 with APX). The reason is that a register file with kk entries can hold kk frequently used values simultaneously, reducing the number of loads and stores the program must execute. As Chapter 2 noted, memory access is far more expensive than a register read, and the gap has widened with every hardware generation.

The number of registers in the file is itself a design trade-off. More registers mean fewer spills to memory, but each additional register requires extra bits in every instruction to encode the register specifier. With 32 registers, each specifier is 5 bits. An R-type instruction that names three registers spends 15 of its 32 bits just on register specifiers. The IBM System/360 chose 16 registers (4-bit specifiers) in 1964, when every bit of encoding space was precious. The RISC designers of the 1980s chose 32, judging that the spill reduction justified the wider specifiers in a 32-bit instruction word. The trade-off has held stable since: no mainstream general-purpose ISA has gone above 32 architectural integer registers (though the x86-64 APX extension finally doubles from 16 to 32, decades after the RISC world settled on that count). The compiler-scheduled IA-64, covered later in this chapter, is the notable exception, defining 128 integer registers precisely because it moved instruction scheduling into software.

02.Memory Access Models: Load-Store versus Register-Memory

A second axis of classification asks which instructions can touch memory. Two answers dominate.

Load-store (RISC style)

In a load-store architecture, only dedicated load and store instructions access memory. Arithmetic instructions operate exclusively on registers. If a program wants to add a value from memory to a register, it must first load the value into a register, then add the two registers. RISC-V, ARM A64, and every other RISC ISA follow this model.

The load-store discipline makes the pipeline easier to design. The memory-access stage of the pipeline activates only for load and store instructions. Arithmetic instructions skip it entirely. This regularity simplifies hazard detection and forwarding logic, and it means that every arithmetic instruction has the same latency profile through the pipeline.

Register-memory (CISC style)

In a register-memory architecture, arithmetic instructions can have one operand in memory. x86-64 is the canonical example. The instruction ADD EAX, [RBX] reads a 32-bit value from the address in RBX, adds it to EAX, and writes the result to EAX. A single x86 instruction does what two RISC instructions (a load followed by an add) would do.

The register-memory model improves code density because fewer instructions are needed. The cost is pipeline irregularity. An instruction that accesses memory has a longer latency than one that does not. The decoder must determine whether the instruction touches memory before it can schedule it. In a modern out-of-order x86-64 processor, the decoder solves this problem by cracking the register-memory instruction into two micro-ops: one that performs the load and one that performs the add. The rest of the pipeline sees only uniform micro-ops, restoring the regularity that the ISA-level encoding obscured.

A subtler cost of register-memory instructions is that they complicate precise exception handling. If the memory access faults (because the address is unmapped), the processor must report the exception at the original instruction, not at the micro-op that performed the load. The retirement logic must track the correspondence between micro-ops and the ISA-level instructions they came from, adding bookkeeping that a load-store ISA avoids because each memory access is already its own instruction.

03.Encoding Width: Fixed versus Variable

Chapter 13 introduced the distinction between fixed-width and variable-width encoding. The classification is worth revisiting here because it aligns closely with the RISC/CISC divide. Every RISC ISA that has achieved commercial success uses fixed-width 32-bit instructions (with optional 16-bit compressed forms). Every major CISC ISA uses variable-width encoding. The alignment is not coincidental.

A load-store ISA with a large register file needs three register specifiers (two sources and one destination) in most arithmetic instructions. Three 5-bit specifiers consume 15 of the 32 available bits. A 7-bit opcode, a 3-bit function selector, and a 7-bit function-extension field fill the rest. An instruction that needs a 12-bit immediate instead drops to two register specifiers, so 10 bits of specifiers, a 7-bit opcode, a 3-bit function selector, and the immediate again total 32. The 32-bit budget is tight but workable.

A register-memory ISA with complex addressing modes needs room for a base register, an index register, a scale factor, a displacement, and an immediate, in addition to the opcode and the destination register. Fitting all of these into a fixed 32-bit word is not practical. Variable-width encoding lets simple instructions be short and complex instructions be long, matching the encoding budget to the instruction’s actual needs.

The consequence for decoder design is substantial. A fixed-width decoder reads one aligned word and extracts fields at known bit positions. A variable-width decoder must scan the byte stream, identify prefix bytes, determine the opcode length, locate the operand specifiers, and compute the total instruction length before it can dispatch the instruction. Modern x86-64 processors invest a significant fraction of the front-end’s power budget in this pre-decode and length-detection logic.

The pre-decode problem is harder than it first appears. Consider a fetch window of 16 bytes. A fixed-width ISA with 4-byte instructions always contains exactly 4 instructions in that window, each starting at a 4-byte-aligned offset. A variable- width ISA does not know how many instructions the window contains until every instruction boundary has been found. The first instruction might be 2 bytes, the second might be 7 bytes, the third might be 4 bytes. Finding these boundaries requires sequential scanning from a known starting point. Modern x86-64 front ends use a pre-decode pipeline stage that marks instruction boundaries in the byte stream and caches the boundary information so that subsequent fetches of the same code region do not repeat the scan.

04.The Historical Arc

The ISA design space was explored in roughly chronological order. Accumulator machines came first because hardware was expensive and a single register was all the designers could afford. Stack machines came next as an attempt to match the hardware model to the compiler’s internal representation. GPR machines followed as register files became cheap enough to build at scale. The RISC philosophy then challenged the assumption that more complex instructions were always better. The history is worth knowing because the trade-offs that shaped each era still echo in modern design.

The accumulator era, 1940s–1950s

EDSAC (Cambridge, 1949), the IAS machine (Princeton, 1952), and the IBM 701 (1952) all organized computation around a single accumulator. The IBM 704 (1956) added three index registers for array addressing, a concession to the frequency with which scientific programs step through arrays. But the accumulator remained the central bottleneck. Every intermediate result had to pass through it, and programs spent a large fraction of their instructions moving data between the accumulator and memory.

A concrete measure of the cost: computing D=(A+B)×CD = (A + B) \times C on an accumulator machine requires at least one store-and-reload cycle to park the intermediate sum A+BA + B before the multiply. On a GPR machine with three or more registers, the intermediate stays in a register and the store-and-reload is eliminated. For a computation with kk live intermediate values, an accumulator machine may need k1k - 1 extra stores and loads. In floating-point-heavy scientific code of the 1950s, these extra memory accesses dominated execution time.

The stack interlude, 1960s

The Burroughs B5000 (1961) and its successors (B5500, B6700, B7700) were designed around a hardware-managed stack. The designers, led by Robert Barton, argued that the stack model was the natural match for Algol 60, the dominant high-level language of the era. Hewlett-Packard’s HP 3000 (1972) was another production stack machine. The approach produced elegant compilers but hit a performance ceiling as programs grew more complex and the strict stack discipline created too many redundant push-pop sequences.

The stack model’s fundamental limitation is that it turns every reuse of a buried value into extra instructions. If a computation needs the value three positions below the top of the stack, it must either duplicate or rotate stack entries to bring the value to the top. A register machine accesses any register in a single cycle regardless of when the value was written. For computations with many live temporaries (common in numerical code and in modern compiler intermediate representations), the register file’s random-access property is a decisive advantage.

The GPR revolution, 1960s–1970s

The IBM System/360 (1964) established the GPR model as the industry standard [1]. Its 16 general-purpose registers and its clean separation of integer and floating-point operations became the template for a generation of mainframes and minicomputers. The CDC 6600 (1964) pushed further, with multiple functional units that could execute different instructions simultaneously, anticipating superscalar design by two decades. The DEC PDP-11 (1970) brought the GPR model to minicomputers with 8 general-purpose 16-bit registers and a rich set of orthogonal addressing modes.

The CISC accumulation, 1970s

By the late 1970s, ISA designers had adopted the philosophy that complex instructions were desirable. The reasoning was straightforward: memory was slow and expensive, so packing more work into each instruction reduced the number of instruction fetches and improved code density. The DEC VAX (1977) was the culmination of this philosophy. It offered dozens of addressing modes, variable-length instructions from 1 to 54 bytes, and complex operations such as polynomial evaluation and packed- decimal arithmetic as single instructions. Intel’s 8086 (1978) was less extreme but still offered a variable-length encoding, segment-based addressing, and string-manipulation instructions that could move, compare, or scan entire arrays.

The RISC insurgency, 1980s

The RISC movement began with two academic projects in the early 1980s. At Berkeley, David Patterson and Carlo Séquin designed the RISC-I processor (1982), which had 32 registers, a fixed 32-bit instruction format, and only 31 instruction types. At Stanford, John Hennessy designed the MIPS processor (1984), with similar principles [2]. Both projects were motivated by an empirical observation: most of the complex instructions in CISC ISAs were rarely used by compilers, yet their presence in the ISA complicated every stage of the pipeline.

The key insight was that a simpler ISA could be clocked faster. If the hardware spent less time decoding complex instructions, it could spend more time executing simple ones at a higher rate. A RISC processor that executed one simple instruction per cycle could outperform a CISC processor that took three or four cycles to execute a complex instruction, even though the RISC program was longer. Patterson and Hennessy captured this argument in the processor performance equation:

The CISC approach reduced instruction count. The RISC approach reduced CPI (cycles per instruction) and clock cycle time. Whether the product was smaller for RISC or CISC depended on the magnitudes of each factor. The RISC proponents argued, correctly for the technology of the 1980s, that the CPI and cycle-time improvements more than compensated for the instruction-count increase.

The commercial fruits of the RISC movement were the MIPS R2000 (1985), the SPARC (1987, from Sun Microsystems), the IBM POWER (1990), the ARM (originally Acorn RISC Machine, 1985), the DEC Alpha (1992), and the HP PA-RISC (1986). Each followed the same core principles: fixed-width encoding, load-store memory model, large register file, and simple instructions designed to execute in a single pipeline stage.

The ARM story is worth a brief aside. Acorn Computers, a British company known for the BBC Micro, designed the original ARM processor in 1985 with a team of fewer than a dozen engineers. Sophie Wilson wrote much of the instruction set specification. Steve Furber led the hardware design. The first ARM chip had roughly 25,000 transistors, small enough that the entire design was done without any automated layout tools. The low transistor count and simple pipeline gave the ARM chip unusually low power consumption, a property that became the ARM franchise’s defining commercial advantage when mobile computing arrived a decade later. The original ARM was, in every sense, a product of the RISC philosophy: a simple, orthogonal instruction set designed for a small, fast pipeline.

The CISC counterattack, late 1980s–1990s

Intel’s response to the RISC challenge was not to abandon x86 but to build a RISC engine underneath it. The Intel 486 (1989) introduced a short pipeline and started executing simple x86 instructions in a single cycle. The Pentium Pro (1995) went further, translating each x86 instruction into one or more fixed-width micro-operations (micro-ops) at the front end and executing those micro-ops in an out-of-order, superscalar back end that was, internally, a RISC machine. AMD adopted the same strategy with the K5 (1996) and refined it through the Athlon and Zen families.

This approach worked. x86 processors matched and often exceeded the performance of RISC processors on general-purpose workloads by the late 1990s. The micro-op translation layer added area and power, but the x86 ecosystem’s enormous installed base of software justified the cost. The RISC ISAs lost their performance lead, and the market consolidated around x86 for desktops and servers and ARM for mobile devices.

05.Why the Distinction Blurred

By 2000, the sharpest claims of the RISC movement had been absorbed into mainstream practice. Every high-performance processor, regardless of its ISA classification, used deep pipelines, out-of-order execution, register renaming, and speculative branch prediction. The remaining differences between RISC and CISC ISAs were in the front-end cost of decoding and in code density, not in the execution engine’s architecture.

Several developments contributed to the blurring.

First, transistor budgets grew exponentially. The decoder complexity that made CISC impractical in 1985 became a small fraction of the total chip area by 2005. Modern x86-64 decoders consume a few percent of the core’s area.

Second, compilers improved. The RISC movement’s original argument partly rested on the claim that compilers rarely used complex CISC instructions. As compilers became more sophisticated, they began to exploit more of the ISA. At the same time, RISC ISAs added instructions that would have been considered “complex” by 1985 standards. ARM A64 has a fused multiply-add. RISC-V’s M extension has multiply and divide. The line between a “simple” and a “complex” instruction shifted.

Third, memory latency became the dominant bottleneck. Once the processor could execute instructions faster than memory could supply them, the execution model (RISC or CISC) mattered less than the cache hierarchy, the prefetcher, and the memory controller. Performance optimization shifted from instruction- level concerns to memory-level concerns.

Fourth, the market applied pressure toward convergence. Compilers, operating systems, and application binaries represent the ecosystem’s investment in an ISA. A RISC ISA that wanted to compete with x86 in the desktop market had to run x86 software somehow (through emulation, binary translation, or dual-boot), and an x86 processor that wanted to compete with RISC on performance had to adopt RISC microarchitectural techniques internally. The two sides met in the middle: RISC ISAs grew more complex (ARM added SIMD and crypto instructions), and CISC ISAs grew more RISC-like internally (micro-op translation, register renaming, deep out-of-order pipelines).

06.A Modern Taxonomy beyond RISC and CISC

If RISC versus CISC no longer captures the important distinctions, what does? Several orthogonal axes describe the design space more usefully.

Operand model

Accumulator, stack, or GPR, as discussed earlier in this chapter. The GPR model is universal in modern hardware, though the stack model persists in virtual machines (JVM, WebAssembly, Ethereum bytecode).

Memory access model

Load-store versus register-memory. ARM A64 and RISC-V are load-store. x86-64 is register-memory. The distinction matters for decoder and pipeline regularity.

Encoding strategy

Fixed-width, variable-width, or hybrid (fixed base with optional compressed forms, as in RISC-V with the C extension). The distinction matters for front-end power and decode bandwidth.

Execution model

In-order versus out-of-order. Scalar versus superscalar. The execution model is a microarchitectural choice, not an ISA choice, but some ISAs (notably VLIW and EPIC, discussed below) expose the execution model to software.

Parallelism model

SISD (single instruction, single data), SIMD (single instruction, multiple data), MIMD (multiple instruction, multiple data), and SIMT (single instruction, multiple threads, the GPU model). Flynn’s taxonomy from 1966 still provides a useful first-level classification. Modern processors combine several models: a single core is SISD for scalar code and SIMD when executing vector instructions, while the chip as a whole is MIMD with multiple independent cores.

VLIW and EPIC: the compiler-exposed approach

A very long instruction word (VLIW) processor bundles multiple operations into a single wide instruction word, and the compiler is responsible for filling each slot with an operation that can execute in parallel with the others. The Multiflow Trace and the Cydrome Cydra-5 of the late 1980s were early commercial VLIW machines. Intel’s Itanium (IA-64) was the most ambitious attempt. It used a variant called EPIC (Explicitly Parallel Instruction Computing) in which 128-bit “bundles” of three instructions carried a template field that told the hardware which operations could execute simultaneously.

The VLIW approach shifts scheduling complexity from the hardware to the compiler. The advantage is a simpler pipeline with no need for dynamic scheduling or register renaming. The disadvantage is that the compiler must know the pipeline latencies at compile time, which ties the binary to a specific microarchitecture. A VLIW binary compiled for a 4-wide machine runs poorly on a 6-wide machine because the compiler packed only 4 operations per bundle. This lack of binary portability across generations, combined with the difficulty of building a compiler that fills the wide bundles effectively, contributed to Itanium’s commercial failure.

VLIW survives in niche domains where the compiler can be tightly coupled to the hardware: digital signal processors (TI C6000 family), GPU shader compilers that target a known microarchitecture, and some network-processing engines. It has not succeeded as a general-purpose ISA strategy.

Data-flow and transport-triggered architectures

Two other models deserve brief mention. A data-flow architecture fires an instruction as soon as all of its input operands are available, with no program counter and no sequential instruction stream. The MIT Tagged Token Dataflow Machine (1980s) and the Manchester Dataflow Machine were research prototypes. Data-flow eliminates the need for explicit scheduling, but the overhead of tracking token availability made it impractical at scale. The concept survives in the data-flow graphs inside modern out-of-order engines, where the scheduler fires micro-ops based on operand readiness.

A transport-triggered architecture (TTA) programs the processor by specifying data movements between functional-unit ports rather than specifying operations. The operation is a side effect of writing data to a functional unit’s trigger port. TTA is an extreme form of compiler-exposed scheduling and shares VLIW’s binary-portability problems. It remains a research curiosity, though the TTA-based Processor Generator project at Tampere University has produced working FPGA implementations for DSP workloads.

Table 1. Summary of ISA classification axes with examples.

AxisOptionsExamples
Operand modelAccumulator / Stack / GPREDSAC / B5000 / System/360
Memory modelLoad-store / Reg-memory / Mem-memRISC-V / x86-64 / VAX
EncodingFixed / Variable / HybridARM A64 / x86-64 / RISC-V+C
ParallelismSISD / SIMD / MIMD / SIMTScalar / NEON / Multicore / GPU
SchedulingHardware (OoO) / Software (VLIW)Zen 4 / Itanium

07.Lessons for Modern ISA Design

The RISC-versus-CISC era left several enduring lessons that shaped every ISA designed after it.

Simplicity at the ISA level pays for itself in the microarchitecture. A regular instruction encoding makes the decoder smaller, faster, and lower power. The decoder runs on every instruction, so its cost multiplies by the instruction rate. A few percent of area saved in the decoder compounds across billions of instructions per second.

Backward compatibility outlasts performance arguments. Intel’s x86 survived the RISC challenge not because its encoding was better but because the installed software base was worth more than the decoder’s cost. ARM survived the transition from 32-bit A32 to 64-bit A64 because the A64 encoding was a clean redesign that kept the ecosystem continuity at the toolchain level even though the ISA encoding changed. RISC-V benefits from starting with no legacy at all.

The ISA is the specification, not the implementation. x86-64 is classified as CISC, but the execution engine inside a modern Intel or AMD core is as thoroughly pipelined, renamed, and out-of-order as any RISC core. ARM A64 is classified as RISC, but Cortex-X4 has a decode width of 10 and an issue width of 16, wider than most x86-64 cores. Classification labels describe the ISA’s encoding philosophy, not the chip’s actual architecture.

The performance equation is the arbiter. Whether an ISA design is good or bad depends on the product of instruction count, CPI, and clock cycle time, as the equation above states. No single factor dominates across all workloads and all technology nodes. The ISA designer’s job is to find the encoding that minimizes the product for the target workload and the target technology.

Energy efficiency has become the new performance. The RISC-versus-CISC debate of the 1980s centered on execution speed. Since the end of Dennard scaling around 2006, the conversation has shifted to energy per operation. A simpler decoder consumes less energy per instruction decoded. A fixed-width fetch consumes less energy than a variable-length pre-decode scan. ARM’s dominance in mobile and RISC-V’s growth in embedded are driven as much by energy arguments as by performance arguments. The decoder’s contribution to total core power is typically 5 to 15 percent in modern high-performance designs, and that fraction is higher in smaller, energy-constrained cores where the decoder is a larger share of the total area.

The number of ISAs is consolidating, not expanding. In the mid-1990s, at least eight commercially significant ISAs competed: x86, MIPS, SPARC, PA-RISC, Alpha, PowerPC, ARM, and 68k. By 2026, three dominate: x86-64, ARM A64, and the rising RISC-V. The consolidation is driven by ecosystem economics. Maintaining a compiler toolchain, an operating system port, a library ecosystem, and a developer community for an ISA costs billions of dollars over its lifetime. Only ISAs with a large enough installed base or a strong enough structural advantage (open licensing, in RISC-V’s case) can sustain that investment.

08.Worked Examples

09.Exercises

References

  1. [1]Amdahl, Gene M. and Blaauw, Gerrit A. and Brooks, Frederick P. (1964). “Architecture of the IBM.” IBM Journal of Research and Development, 8(2), pp. 87--101. doi:10.1147/rd.82.0087
  2. [2]Hennessy, John L. and Patterson, David A. (2019). “Computer Architecture: A Quantitative Approach.” Morgan Kaufmann.
Book mode
computer-architectureinstruction-set-architectures
Was this helpful?