Next: Peephole optimization, Previous: VM instruction table, Up: Using the generated code [Contents][Index]
Vmgen generates VM code generation functions in name-gen.i 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)
The 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
type_prefix
declaration.
The following types, variables, and functions are used in name-gen.i:
Inst
The type of the VM instruction; if you use threaded code, this is void
*
; for switch dispatch this is an integer type.
vm_prim
The VM instruction table (type: Inst *
, see VM instruction table).
gen_inst(Inst **ctp, Inst i)
This function compiles the instruction 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)
This compiles an immediate argument of type (as defined in a
type-prefix
definition). 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 vmgen-ex/mini.y).
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.
Next: Peephole optimization, Previous: VM instruction table, Up: Using the generated code [Contents][Index]