More work on docs for the new opcodes.
[retro/experimental.git] / NEW-OPCODES
blobe9a3f38c18df584994a01521cb3ee4519289f532
1 Introduction 
2 ------------
4 This documentation describes additional features and functionality of Mat's extended Ngaro VM.
5 Other implementations may also incorporate some or all of these extensions in the future.
7 Work to support these extensions is being done in the 'compiler' module. Once this is worked
8 out an alternate Retro core using these extensions can be developed.
12 DTC Streams and Token Threading Code
13 -------------------------------------
15 There exist three categories of executable code in Ngaro: CPU dependant machine code, DTC streams
16 and bytecode sequences. The C code primitives, which form the basic instruction set, are implemented
17 as label sequences and are generated at compile time. A GCC extension allows label addresses to be
18 stored into variables. Thanks to this feature it is possible to execute the primitives though a
19 simple goto statement.
21 Example: 
23   labelA: C code ..
25   void **pointer_array[255];
26   void *inst;
28   pointer_array[0] = &&labelA;
29   ...
31   goto *inst++ = VM_code[pointer_array[vpc++]];
33 With this technique it is possible to implement direct (DTC), indirect (ITC), and token threading (TTC)
34 interpreters without use of assembler code. The Ngaro VM uses TTC because it is a straightforward
35 and fast way to decode the Ngaro bytecode. TTC has a disavantage of being slower then DTC because of
36 the bytecode to address translation for executing, but has the advantage of lower TLB cache misses in
37 the case of branch instructions.
39 The VM is able to compile linear bytecode sequences to DTC code (a stream). DTC streams can then be
40 executed like all other bytecodes (so the interpreter can extend its instruction set at runtime). It
41 is also possible to compile and execute a stream without extending the instruction set permanently
42 (that's analog to the generation of super instructions in other forth systems like gforth). The
43 combination of TTC and DTC combines a good branch performance with a faster dispatch method which can
44 result in a huge performane gain over traditional threading techniques. However to profit from this
45 capability the Retro compiler must support the generation of super instructions at minimum.
49 Compiling a DTC Stream 
50 ----------------------
52 To compile a new stream there exist a special instruction: 
54   SINST number of instructions: N instruction 1,instruction 2 .. instruction N
56 Because of the incompatible way of threading beetween DTC and STC it is not possible to branch from
57 a stream to bytecode directly and vis versa. Instead subroutines must be compiled seperatly to new
58 instructions and can then be included as extended instruction with a XOP prefix (similar to a microcode
59 technique very good known by Intel and Zilog to support more than 255 opcodes, by the way). Another
60 possibility would be to use two special instructions (TCALL and TRETURN) for this task but these are
61 not yet tested.
63 The SINST bytecode push the start offset of the generated stream onto the data stack so the bytecode
64 of the new instruction is identical with its stream offset. To implement a temporary super instruction
65 the bytecode can be executed with the EXE instruction before the internal offset pointer to the stream
66 memory is decreased to its old position by the TRESET instruction with the result to free the allocated
67 memory of the instruction:
69 Example: 
71   SINST 6
72   LI_IAC 0
73   LIT 1
74   ADD
75   DUP
76   LIT 1000000
77   LT_JUMP 2
78   EXE
79   TRESET
81 These example shows two details of the SINST bytecode. The number of instructions without parameters is
82 counted form one up in contrast to the immediate destination of conditional branches where parameters
83 are counted too. Here, six bytecodes are compiled to a stream and the LI_JUMP instruction branches to
84 the LIT bytecode.
88 Avoiding Stack Addressing 
89 -------------------------
91 Register based VM designs offer the chance of a better VM performance because the primitives don't need
92 to address the stack for arithmetic and logic operations. Ngaro compensates for this though static
93 2r-stack caching with the possibility to address the two cache registers for the first and second stack
94 element directly:
97   LI_IAC  value
98   LI_IOP  value
100 These two instruction load the TOS and NOS cache registers (IAC and IOP) directly with its immediate
101 parameters.
104   RADD
105   RSUB
106   RMUL
107   RAND value
108   ROR  value
109   RXOR value
111 Arithmetic and logic operations, IOP or immediate parameter = operand, result stored in IAC.