TL;DR: It's the pipeline.
The 80486 contains parallel operating stages for decoding, operand fetch, execution and write back. So while an ADD reg,reg
does take 3 clocks to perform, as it did in the original 8086, its execution overlaps with the previous/next operation, so the CPU can crank out one ADD reg,reg
per clock.
The Long Read
(Caveat, there's a whole lot more going on in these stages, so I might not remember all details)
Two clocks was the minimum execution time for any instruction since the 8088. ADD
(or similar) as register/register did take 3 cycles. With the 286 they were sped up to two cycle operation due to optimized microcode and routing (*1). While the 386 did speed up execution even more due to better address generation, the basic execution scheme stayed the same with a 3 stage instruction prefetch.
The 486 did straighten address generation even further, but more importantly, it redid the instruction fetch architecture, introducing a 5-stage pipeline.
- Fetch - Get 16 bytes from Cache (or memory)
- Decode 1 - Primary instruction decode - here only the first 1..3 bytes were examined
- Decode 2 - Address decode/Operand prefetch
- Execution - Do the Operation
- Write back - Store data in register file (or memory buffer)
Operation of these stages is conditional, but they will always be taken (passed thru) to keep a constant clock rate.
- Fetch always gets a cache (memory) line of 16 byte at a time into one of its two buffers. Thus on average it only needs to do so every 4-5 instructions. This time is available to prefill the second buffer. Thus the 486 can keep up fast execution even without cache as long as the code is linear.
- Decode 1 looks at opcode and addressing field to determine the action to be taken, feed back the real instruction length to the fetch stage (so it can advance), and set up the operation that D2 performs. Of note here, each prefix byte is handled as an instruction of its own, taking another clock cycle (*2,3). Similarly for the first byte (e.g.
0Fh
) of a two byte opcode.
- Decode 2 decodes operand access, fetches offsets or immediate values from the fetch stage's buffer. It also performs address calculations. Simple ones within a single cycle, complex ones need two.
- Execution. If all data is present as either immediate, or in cache, or from the register file, the execution performs in a single cycle.
- Write Back stores either the read value (memory, cache or Fetch buffer) or the latched results from Execution into the registers and or memory write buffers.
So a single ADD reg,reg
still needs 3 cycles but due to pipelining the CPU can finish one every clock.
But wait, what happens if there are two ADD reg,reg
, the second needing the result of the previous? Like ADD AX,BX; ADD CX,AX
. Wouldn't that mean the second has to wait in execution until write back of the first is finished?
Well, yes, except the engineers added a shortcut/feedback between Write Back and Execution. The WB input, the result of the previous Execute, is not only written to the register set, but as well offered back to Execution as alternative input (tagged with what the target was). So if one instruction needs to read a register that was the result of the prior instruction it's available even before it gets written into the 'real' register.
Cool, isn't it? But it gets even more tricky. The flags of any operation done in Execute are also provided back from Write Back to be used in the next instruction. This is done to enable a one cycle not-taken jump after flag modifying operations like compare or subtract.
Despite that optimization, status register manipulating instructions do not benefit from this shortcut to avoid implications. Direct status register manipulations don't go through WB but are two step microinstructions handling the Status Register directly. This is important as status register settings not only change over all operation behaviour but also can generate various exceptions.
It's beneficial to remember that the 80486 is not a RISC CPU and does not translate internally to RISC(-like) instructions, but continues to operate like their predecessors. Just with a very cleverly designed pipeline with feedback between various stages (*4) and parallel operation of address calculation units. While The Pentium (P5) introduced superscalar operation (through parallel pipelines), it wasn't until the P6 (Pentium Pro) that a code translation to a (somewhat) RISC like core happened - but even then lots of un-RISCy side channels were used.
Following designs really expanded on that, with the pipeline growing to 10 stages in Pentium III, 20 for the first Pentium 4 and IIRC 40 (!) stages for the last Netburst CPU, before going back to a simpler but massively parallel design like the one P6 already had... But that's another story altogether.
*1 - The main gain of the 80286 in speed was a dedicated address calculation unit, but that's a different story.
*2 - That's why a LOCK
takes zero cycles on a 286/386 but one cycle on a 486.
*3 - Somewhere I read a nice study made by Intel (IIRC) about prefixes and the pipeline. One really remarkable part was that Unix programs on average use only half as many prefixes as DOS programs. Proves my point how stupid it is to do address calculation with segment values.
*4 - Which substantially violates the simplicity criterion of RISC designs.
clc
andstc
leave the other flags in EFLAGS unmodified, whileadd
overwrites all the condition flags. Modern OoO exec x86 CPUs typically rename CF separately from the SPAZO group of flags.