Hi,
As Noha said, it's not that difficult to hook native code in. But to have something maintainable
and bug less will be a challenge. To mitigate this having all code in scheme could be wise.
Anyway I can now compile simple functions to native sequences of machine code but with some
tools around it so let me explain the setup.
The idea is that To have a set of registers that is not touched, the registers are
vm - points to a table with vm specific datastructures like free variables etc.
jmp - a pointer to a jump table
rbx - neeeded to be maintained because of C conventions.
The sellected registers will not be changed during a C call and is therefore not needed to be stored when calling out
to C (for x86-64, for x86 you do not have this possibility)
The vm contains at the moment,
vm-rbx
vm-r12 |
vm-r14 | Stored registers according to the C convention
vm-clo | free variable table
vm-obj | object table
vm-c | C - function table
ret | A return adress
The generated instruction could feature
1. Pure machine instructions for fastpaths.
2. The option to jump to a vm instruction like a named goto. Then ret needs to contain a return adress
3. The option to call a C function using the function table
So the idea here is to keep some of the vm:ness of the setup in order to keep code complexity low.
Also rsp ands tbp are used to match sp and fp in the guile-2.0 VM.
The general impression after looking at about 142 instructions are that the bytevectors will be typical 10x
larger then the VM bytevectors e.g. there is a good compression ratio by using the VM ops. On the other hand
we do save space by not inlining everything.
Anyway this is indeed a fun exercise and I see it as a testbed for implementation strategies and as a fun testbed
for assemblers in guile. The examples that can be run does not include looping (yet) so it's really not that useful but
in a matter of a week I would expect that some loop benchmarks can be done.
An example currently look like,
(use-modules (native vm init))
(use-modules (native vm jit))
(define (f) (vector 1 2 3 4 5 6))
(jit f)
(f)
execute native
execute native/finish
$2 = #(1 2 3 4 5 6)
/stefan