|
Keep in mind that the numbers presented in the article are large because the majority of them come from a nearly cartesian product; if you consider the ALU-ish operations alone, there's the operation (add, sub, adc, sbb, and, or, cmp, xor, etc.), addressing mode (reg, mem[imm], mem[reg], mem[reg+reg * scale], mem[reg+imm], mem[reg * scale+imm], mem[reg+reg * scale+imm]), width and type (int8, int16, int32, int64, float32, float64, float80, plus vector variants: int8x8, int16x4, int32x2, int64x1, float32x4, ... ). Approximately from the list above there are already 8x8x16 = 1024 "instructions", which within an order of magnitude correlates nicely with the estimates given in the article. The rest (probably dozens at most) are mainly for OS-oriented system management, and special operations done in hardware like AES (without which the equivalent software implementation would be orders of magnitude slower). The main "simplification" which RISCs have done is restricted the operand types, so that e.g. most if not all the ALU ops must use register addressing modes, and all the other addressing modes (of which there are not many) are restricted to memory-register move instructions. That turns parts of the cartesian product into a sum, reducing the instruction count by the above measures, but IMHO is the wrong thing to do since now it means all software has to contain more instructions to do what the hardware would otherwise be able to figure out (and possibly optimise execution of) in a CISC. For example, x86 can express mem[reg + reg * scale + imm] = reg + mem[reg + reg * scale + imm] in a single instruction (decoded into multiple uops, which can be scheduled into whatever hardware resources are available) while a RISC would require several. |