L1VM - update

As you may have already noticed there was a lot going on in the past weeks. After doing some benchmarks now I know that my VM is one of the fastest VMs out there. My simple design of my RISC CPU with 61 opcodes makes this possible. Now with the new compiler flags: (no-var-pull-on) and (no-var-pull-off) the generated code don’t uses the “load” and “pull” opcodes inside this code block.

To use this we for example need the variables: “x”, “y” and “count” in the registers:

// double-test-optimized-jit.l1com
//
// (no-var-pull-on) (no-var-pull-off) optimization demo
#include <intr.l1h>
(main func)
    (set int64 1 zero 0)
    (set double 1 zerod 0.0)
    (set double 1 x 23.0)
    (set double 1 y 42.0)
    (set int64 1 max 10000000Q)
    (set int64 1 loop 0)
    (set int64 1 one 1)
    (set double 1 count 1.0)
    (set int64 1 f 0)
    (set int64 1 jit_start 0)
    (set int64 1 jit_end 0)
    (optimize-if)
    (:jit_start jit_start loadl)
    (:jit_end jit_end loadl)
    run_jit_comp (jit_start, jit_end)
    //
    // put the following variables into registers:
    // adding 0.0 to them as a workaround
    //
    {x = (x + zerod)}
    {y = (y + zerod)}
    {count = (count + zerod)}
    (:loop)
    run_jit_code (zero)
    (:next jmp)
    (:jit_start)
    (no-var-pull-on)

    {count = (count + x)}

The following lines do the calculations:

{count = (count + x)}
{count = (count + x)}

// snip....

This code snippet is compiled into:

addd 5, 3, 1
addd 1, 3, 5

So every line in the Brackets program is compiled into one “addd” opcode. And “addd 5, 3, 1” simply adds the two registers “5” (count) and “3” (x) and stores the result of the addition in the target register “1”. Then in: “add 1, 3, 5” to the “1” register holding the result of the previous calculation in the register, “3” (x) is added. Then storing the result into register “5”. This steps are repeated until the “add” opcodes end!

We loaded the needed variables “x”, “y” and “count” into registers already before. So no “loadd” opcodes are needed. And the generated opcodes are all in the JIT-compilers instruction set. So there is no more need to write the code in inline assembly! This was an important step! Now it is more easy to write fast programs in Brackets.

Only the expressions in the curly brackets: { } can be used to write JIT-compilable code! Note: the “addd” opcodes end with:

addd 5, 4, 1
:jit_end
addd 1, 4, 5

Here register “4” is the variable “y”! And the last line is: “addd 1, 4, 5”. So the target register is “5”! And the loop will continue with the first line as shown above with register “5”! In this register now is the result of the adding loop. This is important if we use loops!