Originally created by: rrthomas
Simple version of Mit's encoding (thanks, @apt1002 for reminding me of this option): reserve the bottom two bits of the opcode to indicate a rest-of-word instruction; otherwise, decode only one byte.
This can be used in a simple-minded way by only choosing one of two options: either use the whole word, or only use byte instructions. Actually requiring this seems attractive, because then byte opcodes in other than the first byte could use the full 8 bits, but this complicates the decoder.
To be able to get away with "only" 64 instructions, will first need traps à la Mit.
Originally posted by: apt1002
I think what you mean is that you don't want to waste 2 bits between every instruction, just because you use 2 bits before the first instruction. I agree, obviously.
However, using a 6-bit encoding for the first instruction and an 8-bit encoding for the remainder sounds like a lot of work for Bee and for compilers targeting Bee, and will make it difficult to realise any benefits.
Surely the easy way to get a benefit is to abandon the idea that the boundaries between the instructions are byte-aligned? For example, you could divide the 32-bit word into 2+6+6+6+6+6, or 2+10+10+10, depending on how many opcodes you want to define.
Of course this extends our earlier conversation about concatenating code, and whether you need random access to individual instructions. To recap, I claim that you don't, and that "append" is a sufficient primitive (in addition to random access to words for patching forward references). I don't think there is any need for individual instructions to have addresses. You counter that byte access is a reality and you might as well use it.
Ticket changed by: rrthomas
Originally posted by: rrthomas
Closing this. Bee's 1-instruction-per-word is a very nice simplification, which makes assembly, disassembly and single-stepping much easier than for Mit.
Ticket changed by: rrthomas
Originally posted by: rrthomas
Reopening, for two reasons:
NOPs.Originally posted by: apt1002
I have been giving this a bit more thought, and I'd like to propose a design. I think it is necessary to distinguish three kinds of instruction:
CALLI,JUMPI,JUMPZI,PUSHRELIare PC-relative, in the sense that they contain an immediate constant whose value depends on the location at which the instruction is assembled.NOP(which will presumably becomeNEXT),PUSHI,TRAP,JUMP,CALL,RET,CATCH,THROW,BREAKare terminal, in the sense that they are always the last instruction in an opcode word.PC-relative instructions need to occupy an entire opcode word, as they do now. Partly this is to allow them to be patched. Partly it is because it is necessary to know the value of PC in order to assemble these instructions, and attempting to pack them with other instructions adds significant complexity. The bottom bits of the word are the opcode, and the remainder of the bits are the immediate constant. An opcode
BEE_OP_INSNis reserved to mean "not PC-relative".In contrast, terminal and non-terminal instructions can be packed. In general, a packed opcode word can contain (after
BEE_OP_INSN) zero or more non-terminal instructions, followed by exactly one terminal instruction, maybe followed by an immediate constant.Packed encoding
Various options exist for packing the instructions:
Supplementary instructions
It will perhaps be desirable to add some non-terminal instructions such as
PUSH0andPUSH1to avoid using the terminalPUSHIinstruction for common small immediate constants.RETI(returning a constant) might also be useful, to avoid following the terminalPUSHIinstruction by a word containing onlyRET.NEXTZIt is slightly annoying that the number of PC-relative instructions is five (including
BEE_OP_INSN) as this is slightly too many for a 2-bit opcode. To fix this, I suggest deletingJUMPZI(and alsoJUMPZ), and addingNEXTZ. The newNEXTZinstruction pops the top item of the data stack, and behaves likeNEXTif it is zero, otherwise it incrementsPC.JUMPZIandJUMPZbecome pseudo-instructions:JUMPZIcan be implemented asNEXTZif the following word containsJUMPI.JUMPZcan be implemented asNEXTZ POPif the following word containsJUMP.Note that
JUMPZandJUMPZIpsuedo-instructions are non-terminal. Instructions following them on the not-taken path can be packed into the same word. This might often include the first few instructions of loop bodies and "then" blocks.NEXTZcan be used to form other pseudo-instructions too:JUMPNZcan be implemented asNEXTZ JUMPif the following word begins withPOP.RETZcan be implemented asNEXTZif the following word containsRET.RETZIcan be implemented asNEXTZif the following word containsRETI.NOTZcan be implemented asNEXTZ NEXTif the following word containsNOT.NEGATEZcan be implemented asNEXTZ NEXTif the following word containsNEGATE.nSWAPZcan be implemented asNEXTZ NEXTif the following word containsPUSHn SWAP.INCZcan be implemented asNEXTZ NEXTif the following word containsNOT NEGATE.