@Waccoon
I thought this criticism was worthy of an additional note:
The encoding of MC64K is actually a lot like x86 (!), as it just tacks on numerous extra extension bytes as modifiers, which is lazy. Like x86, you need to parse almost the whole instruction to determine how long it is, which is just silly.
What you describe as lazy is probably true for a hardware implementation. However, for a bytecode interpreter, it's pretty sensible because parsing is part of execution regardless. Let's consider what is just about the longest example I can think of:
fbgt.d #4.669201609, $ABADCAFE(a0, d0.l * 4), .target
The bytecode layout of this instruction would be (from lowest address to highest)
{ fbgt.d : 1 byte } { dst ea mode : 1 byte } { dst ea mode reg pair : 1 byte } { dst ea mode offset : 4 bytes } { src ea mode : 1 byte } { src ea literal : 8 bytes } { branch displacement : 4 bytes }
That's 20 bytes in total, which is pretty long. However, consider that this is executed serially by the interpreter:
1. Get the opcode => jump to handler for fbgt.d
2. Get the destination EA mode => jump to handler for scaled index with displacement
2.1 Get the register number pair for the scaled indexing, calculate base effective address
2.2 Get the displacement from the opcode stream and add to the base effective address.
2.3 Fetch the double at the address
3. Get the source EA mode => jump to handler for immediate 8 byte
3.1 Get the double in the opcode stream
4. Compare the operands
4.1 If the comparison is true, get the branch displacement in the opcode stream and add to the PC ready to branch.
4.2 if the comparison is false, step over the branch displacement to the next instruction.
At each step, the data that is needed is next in the instruction stream. All of these operations deal with bytes apart from the one packed register pair, which allows for very simplistic C code (read the kind the compiler can optimise most readily) to be used. As there is no performance penalty for misaligned access to a cached value on x64, the 4 and 8 byte entities are read as such. Each step of the decode and execution advances the PC. Thus the PC is always aligned at an instruction boundary on completion.
Note that it's not easy to create even longer instructions, since immediate values are illegal destination address modes. Any other operation that can be statically evaluated by the assembler, for example comparing an EA mode to itself (as long as the EA mode has no increment/decrement semantics) is evaluated by the assembler and folded to a fixed branch (for true) or nothing (for false).
Regarding the need to determine the instruction size, the only part of the current workflow that needs to care about that is the assembler itself. It's a simple two pass design that during pass 1 resolves any references to things it's already seen immediately, and references to things it hasn't seen yet in during pass 2.
Finally while you contend that using extension bytes is a bad idea for extending the instruction set, I'd say yes and no. First of all, I'm not especially interested in adding extra instructions, I'm interested in writing code that feels familiar. Secondly, there is an instruction that can call the host, the basic mechanism for which costs about the same as 2 of the fastest class of register to register operations. This allows the host to provide all sorts of native code solutions for things, including classically vectorisable stuff. We use this for the basic IO, graphics, etc. but there's also a vector algebra set for 2D/3D calculation, bulk memory operations and so on.
Adding an extension instruction set to the interpreter is totally possible and would just reserve a prefix byte to jump to the corresponding handler. However, for stuff like SIMD this is not ideal since the cost of the scaffolding around the instruction would limit the gain made by using it. However, if JIT is ever introduced, then the multibyte instruction encoding becomes somewhat moot and at that point introduction of SIMD operations as an instruction set extension would definitely have some merit.