Most computers contain only a couple thousand instructions, but the bit width(usually 64-bit) technically allows computers to have access to millions or even billions of instructions. Some could be extremely useful, like DIVIDE, EXPONENT or conditional operations. Plus, clock speeds are grinding to a halt, and quantum computing is a long way away. Why haven't they added extra instructions to microprocessors yet?
Because every instruction needs some circuitry to implement it. The more instructions you add, the bigger the processor gets. Since most of these operations will never be used, it's just wasted complexity.
All the complexity can even slow the processor down. RISC processors, such as the ARM, were based on the idea of throwing away a large number of operations, and making the resulting smaller processor core as fast as possible.
Even modern X86 processors, with a huge instruction set, have ended up having a faster processor hiding inside, emulating a huge complicated one.
To complement Simon B's answer, GPUs, on the other hand, do a lot of complex calculations. But they can be boiled down to multiply-add instructions, A = B*C + D. So they at least try to have complex multiply-add instructions because they are common instructions.
To recap. If you add more instructions the CPU will become:
- more complex, i.e. bigger CPU and harder to use efficiently
- slower. The speed you can run it depends on the slowest unit
- more expensive. Is this what your customer wants?
Also, read about "risc vs cisc architectures"
Most computers contain only a couple thousand instructions, but the bit width(usually 64-bit) technically allows computers to have access to millions or even billions of instructions.
First, let's be clear that being 64 bit doesn't mean anything for instructions. Most 64 bit systems use 32 bit long instructions, with the exception of x86 where instructions can be anywhere from less than 32 bits to several hundred bits.
As for why the number of instructions is limited, for a system using 32 bit instructions (which is a very efficient number to use), the number of possible instructions that can be encoded is somewhat limited since you ideally want to have at least 3 registers for at least some opcodes. However even x86 where instructions can have arbitrary length has on the order of a few thousand unique instructions (not all of which are necessarily still used) because there aren't that many useful things an instruction can do. Encoding lots of useless instructions (as x86 does) doesn't necessarily hurt you, but it doesn't help either.
Why haven't they added extra instructions to microprocessors yet?
Intel and ARM regularly add new instructions. Focusing on intel, there has been Haswell New Instructions, Broadwell New Instructions, Skylake New Instructions, Palm Cove (Cannonlake) New Instructions and last year's Sunny Cove (Icelake) New instructions.
Most of the useful instructions were added long ago so these typically have a marginal effect on average, but there are specific applications where these can make a large difference.
Most computers contain only a couple thousand instructions,
That depends on how you count them. Should all instructions with a similar function be grouped together, or different variations counted separately? Or should they be grouped according to what operations the CPU has to perform to implement them (and how different must those operations be to make the instructions 'different')?
The answer? Anywhere from 981 to 3683 depending on which criteria you use.
But why so few (or so many) when there could could be even more? Fundamentally the limit is not technical, but economic. Nobody wants those extra instructions badly enough to justify adding them.
Some could be extremely useful, like DIVIDE, EXPONENT or conditional operations.
That accounts for a dozen of so, most of which current CPUs already have. Millions or billions of instructions? Nobody wants them.
Just because you think an instruction could be 'useful' doesn't mean it's worthwhile implementing. Since almost all modern coding is done in high level languages, so long as there are sufficient instructions to satisfy compiler writers everybody is happy. Any other 'useful' operations that are desired can be implemented in higher level code.
There are exceptions to this of course, which is why modern CPUs tend to have more instructions in them. But there have also been cases where instructions were removed because they weren't used enough to justify keeping them. This may be done to save silicon, reduce complexity, increase speed, or simply to avoid having to support features that nobody wants.
I am having trouble finding the document that explicitly shows the opcode format for ARM, but many opcodes have a large part of their bitfield reserved for immediate data or branch offsets. so not all of the 64 bits or 32 bits are there to encode different instructions, but are there to encode data that is built into the instruction.
I would say that, arguably, they do support millions of instructions. But it really depends on how you define an "instruction".
In general, instructions are divided up into several fields - one part indicates what the operation is (add, subtract, divide, branch, jump, read, write, etc.) and then other parts can provide arguments - immediate values or register indicies. So, if you group all of the possible immediate values and all possible register indicies together, then you only have a relatively small number of operations. As each operation must be evaluated on dedicated hardware (well, more or less...things like add and subtract can be done on the same hardware with some configuration/preprocessing) the number of distinct operations must be limited by the area and complexity of the chip.
However, different arguments result in different machine code. For example, take the RISC-V add instruction,
ADD rd, rs1, rs2 which takes two register values,
rs2, adds them together, and places the result in a third register,
rd. RISC-V has 32 registers, so that means there are 32*32*32 = 32,768 different "instructions" that all map on to ADD, but with different arguments. Similarly,
ADDI rd, rs1, imm takes a 12 bit immediate value, adds it to
rs1, and writes the result to
rd. So, this results in 32*32*4096 = 4,194,304 distinct encodings just for
Dividing up the "instruction space" is a very important part of the design of an ISA. Which bits you use for register arguments, which bits you use for immediate values, which bits you use to determine the operation, which bits you use to determine the instruction format, which bits you use to determine the instruction size, etc. all have some bearing on the flexibility and expressiveness of the instruction set and complexity of the decode hardware required in the CPU. Increasing the number of available operations generally comes at the expense of flexibility - immediate size, number of arguments, number of addressable registers, etc.