Node:VM code generation, Next:Peephole optimization, Previous:VM instruction table, Up:Using the generated code
Vmgen generates VM code generation functions in
that the front end can call to generate VM code. This is essential for
an interpretive system.
For a VM instruction
x ( #a b #c -- d ), Vmgen generates a
function with the prototype
void gen_x(Inst **ctp, a_type a, c_type c)
ctp argument points to a pointer to the next instruction.
*ctp is increased by the generation functions; i.e., you should
allocate memory for the code to be generated beforehand, and start with
*ctp set at the start of this memory area. Before running out of
memory, allocate a new area, and generate a VM-level jump to the new
area (this overflow handling is not implemented in our examples).
The other arguments correspond to the immediate arguments of the VM
instruction (with their appropriate types as defined in the
The following types, variables, and functions are used in
void *; for switch dispatch this is an integer type.
Inst *, see VM instruction table).
gen_inst(Inst **ctp, Inst i)
i. Take a look at it in
vmgen-ex/peephole.c. It is trivial when you don't want to use superinstructions (just the last two lines of the example function), and slightly more complicated in the example due to its ability to use superinstructions (see Peephole optimization).
genarg_type_prefix(Inst **ctp, type type_prefix)
type-prefixdefinition). These functions are trivial to define (see
vmgen-ex/support.c). You need one of these functions for every type that you use as immediate argument.
In addition to using these functions to generate code, you should call
BB_BOUNDARY at every basic block entry point if you ever want to
use superinstructions (or if you want to use the profiling supported by
Vmgen; but this support is also useful mainly for selecting
superinstructions). If you use
BB_BOUNDARY, you should also
define it (take a look at its definition in
You do not need to call
BB_BOUNDARY after branches, because you
will not define superinstructions that contain branches in the middle
(and if you did, and it would work, there would be no reason to end the
superinstruction at the branch), and because the branches announce
themselves to the profiler.