Why doesn't the opcode of an instruction uniquely identify the operation?

This probably isn't related to Snap, but I have no idea where else to ask this and I think this is at least somewhat related to CS.
I've looked in some instruction formats for multiple architectures, and I noticed that many of them seem to use the same opcodes for different instructions. For example, in MIPS, the opcode for add is the same as the opcode for and.

So are opcodes supposed to be for identifying part(s) of the instruction format, or something else?
I also found this page for MIPS says that

For instructions that share an opcode, the funct parameter contains the necessary control codes to differentiate the different instructions. 6 bits long (0 to 5). Example: Opcode 0x00 accesses the ALU, and the funct selects which ALU function to use.

Is the pattern of MIPS using opcodes to select which "part" of the CPU to use standard?
Also, it seems like the addi instruction actually uses 0x08 as the opcode, which doesn't make sense since logically addi would also use the ALU? Is 0x08 also an opcode for the ALU, but for a different format?

Example of what I'm talking about from the RISC-V specification:

In a RISC architecture, all instructions are the same width (e.g., 32 bits). This very much simplifies, and therefore speeds up, instruction fetching, compared to using exactly as many bytes as necessary for each instruction.

But instructions vary a lot in how much information each kind of instruction has to include. Specifically, some instructions refer to memory locations for data, so those instructions have to include at 16-bit address, with a few extra bits for index register and indirect addressing flags. Let's say a total of 23 bits for a memory reference. A typical instruction of this kind would be Load Word, which transfers a word from memory to a processor register (another five bits or so). So we're up to 28 bits, leaving just four bits to specify the opcode.

So there can be only a handful of instructions that refer to memory, basically just load, store, and jump. All other instructions have all their operands in processor registers. This means there are more bits available to specify which instruction you want. There's just one opcode that means "register to register instruction" and there are lots of bits available to say which specific operation you want.

In other words, some of the bits that would otherwise hold a memory address are available as an extension to the opcode.

The real defining characteristic of a RISC design isn't that it has fewer instructions, but rather that most instructions use only data in registers.

Immediate instructions have one of the operands in the instruction itself. Instead of a 16-bit memory address (plus five-bit index register and one-bit indirect addresing flag), you have a 16-bit immediate value, which doesn't need index or indirection bits. So that frees up six extra bits for an extended opcode. In three-register instructions, each register number is five bits, so three of them fit in the 16 bits for addressing, again with six extra bits for an extended opcide.

Does that help?

yes, way more than I expected to get as an answer (from people in general, not from you specifically)

I used to teach this course at Berkeley. :~)

What was it called?

Whoa!How smart you are!

I thought that you taught haskell

"Machine Structures."


What, I'm smart because I know two programming languages? I know more than that. But knowing a lot doesn't mean I'm smart; it just means I'm >70 years old. It would be embarrassing if I didn't know more than you!

No, I've never even programmed in it. The main course I taught, "Structure and Interpretation of Computer Programs," used Scheme. (But don't say "Brian taught Scheme"; it's a course about big ideas, that just uses Scheme as its programming language because it has to use something. (Well, that overstates the case a little. SICP and Scheme have the same big ideas built into them.) The course is named after the best computer science book ever written.)

You are smart because you often put long and advanced stuff like this in the forum

oh right i was wanting to mean that language,but i didnt program in haskell or scheme so both were the same to me lol

Oh ok

So basically RISC architectures use less opcodes so that you have more room for the other data in the instruction?

random off-topic question, is that course still at berkeley?

Well, thank you. But that just means I'm a teacher! I don't feel especially smart. (I don't mean that I'm especially stupid, either; it's just that when you hang out with the likes of Marvin Minsky and John McCarthy it's hard to feel really smart.)