version 1.10, 2002/08/13 19:33:38
|
version 1.11, 2002/08/14 09:00:22
|
Line 29 Software Foundation raise funds for GNU
|
Line 29 Software Foundation raise funds for GNU
|
|
|
@dircategory GNU programming tools |
@dircategory GNU programming tools |
@direntry |
@direntry |
* vmgen: (vmgen). Interpreter generator |
* Vmgen: (vmgen). Interpreter generator |
@end direntry |
@end direntry |
|
|
@titlepage |
@titlepage |
@title Vmgen |
@title Vmgen |
@subtitle for Gforth version @value{VERSION}, @value{UPDATED} |
@subtitle for Gforth version @value{VERSION}, @value{UPDATED} |
@author M. Anton Ertl (@email{anton@mips.complang.tuwien.ac.at}) |
@author M. Anton Ertl (@email{anton@@mips.complang.tuwien.ac.at}) |
@page |
@page |
@vskip 0pt plus 1filll |
@vskip 0pt plus 1filll |
@insertcopying |
@insertcopying |
Line 54 Software Foundation raise funds for GNU
|
Line 54 Software Foundation raise funds for GNU
|
* Introduction:: What can Vmgen do for you? |
* Introduction:: What can Vmgen do for you? |
* Why interpreters?:: Advantages and disadvantages |
* Why interpreters?:: Advantages and disadvantages |
* Concepts:: VM interpreter background |
* Concepts:: VM interpreter background |
* Invoking vmgen:: |
* Invoking Vmgen:: |
* Example:: |
* Example:: |
* Input File Format:: |
* Input File Format:: |
* Using the generated code:: |
* Using the generated code:: |
Line 82 Input File Format
|
Line 82 Input File Format
|
* Input File Grammar:: |
* Input File Grammar:: |
* Simple instructions:: |
* Simple instructions:: |
* Superinstructions:: |
* Superinstructions:: |
|
* Register Machines:: How to define register VM instructions |
|
|
Simple instructions |
Simple instructions |
|
|
Line 105 Copying This Manual
|
Line 106 Copying This Manual
|
@end menu |
@end menu |
|
|
@c @ifnottex |
@c @ifnottex |
This file documents Vmgen (Gforth @value{VERSION}). |
@c This file documents Vmgen (Gforth @value{VERSION}). |
|
|
@c ************************************************************ |
@c ************************************************************ |
@node Introduction, Why interpreters?, Top, Top |
@node Introduction, Why interpreters?, Top, Top |
Line 118 it). The run-time efficiency of the res
|
Line 119 it). The run-time efficiency of the res
|
within a factor of 10 of machine code produced by an optimizing |
within a factor of 10 of machine code produced by an optimizing |
compiler. |
compiler. |
|
|
The interpreter design strategy supported by vmgen is to divide the |
The interpreter design strategy supported by Vmgen is to divide the |
interpreter into two parts: |
interpreter into two parts: |
|
|
@itemize @bullet |
@itemize @bullet |
Line 145 A @emph{virtual machine} (VM) represents
|
Line 146 A @emph{virtual machine} (VM) represents
|
machine code. Control flow occurs through VM branch instructions, like |
machine code. Control flow occurs through VM branch instructions, like |
in a real machine. |
in a real machine. |
|
|
In this setup, vmgen can generate most of the code dealing with virtual |
In this setup, Vmgen can generate most of the code dealing with virtual |
machine instructions from a simple description of the virtual machine |
machine instructions from a simple description of the virtual machine |
instructions (@pxref...), in particular: |
instructions (@pxref{Input File Format}), in particular: |
|
|
@table @emph |
@table @asis |
|
|
@item VM instruction execution |
@item VM instruction execution |
|
|
Line 166 source level.
|
Line 167 source level.
|
|
|
@item VM code profiling |
@item VM code profiling |
Useful for optimizing the VM insterpreter with superinstructions |
Useful for optimizing the VM insterpreter with superinstructions |
(@pxref...). |
(@pxref{VM profiler}). |
|
|
@end table |
@end table |
|
|
VMgen supports efficient interpreters though various optimizations, in |
@noindent |
|
Vmgen supports efficient interpreters though various optimizations, in |
particular |
particular |
|
|
@itemize |
@itemize @bullet |
|
|
@item Threaded code |
@item Threaded code |
|
|
Line 187 Replicating VM (super)instructions for b
|
Line 189 Replicating VM (super)instructions for b
|
|
|
@end itemize |
@end itemize |
|
|
As a result, vmgen-based interpreters are only about an order of |
As a result, Vmgen-based interpreters are only about an order of |
magintude slower than native code from an optimizing C compiler on small |
magnitude slower than native code from an optimizing C compiler on small |
benchmarks; on large benchmarks, which spend more time in the run-time |
benchmarks; on large benchmarks, which spend more time in the run-time |
system, the slowdown is often less (e.g., the slowdown of a |
system, the slowdown is often less (e.g., the slowdown of a |
Vmgen-generated JVM interpreter over the best JVM JIT compiler we |
Vmgen-generated JVM interpreter over the best JVM JIT compiler we |
Line 197 and all other interpreters we looked at
|
Line 199 and all other interpreters we looked at
|
interpreter). |
interpreter). |
|
|
VMs are usually designed as stack machines (passing data between VM |
VMs are usually designed as stack machines (passing data between VM |
instructions on a stack), and vmgen supports such designs especially |
instructions on a stack), and Vmgen supports such designs especially |
well; however, you can also use vmgen for implementing a register VM and |
well; however, you can also use Vmgen for implementing a register VM and |
still benefit from most of the advantages offered by vmgen. |
still benefit from most of the advantages offered by Vmgen. |
|
|
There are many potential uses of the instruction descriptions that are |
There are many potential uses of the instruction descriptions that are |
not implemented at the moment, but we are open for feature requests, and |
not implemented at the moment, but we are open for feature requests, and |
Line 213 list above is not exhaustive.
|
Line 215 list above is not exhaustive.
|
Interpreters are a popular language implementation technique because |
Interpreters are a popular language implementation technique because |
they combine all three of the following advantages: |
they combine all three of the following advantages: |
|
|
@itemize |
@itemize @bullet |
|
|
@item Ease of implementation |
@item Ease of implementation |
|
|
Line 236 Vmgen makes it even easier to implement
|
Line 238 Vmgen makes it even easier to implement
|
techniques for building efficient interpreters. |
techniques for building efficient interpreters. |
|
|
@c ******************************************************************** |
@c ******************************************************************** |
@node Concepts, Invoking vmgen, Why interpreters?, Top |
@node Concepts, Invoking Vmgen, Why interpreters?, Top |
@chapter Concepts |
@chapter Concepts |
|
|
@menu |
@menu |
Line 266 interpreter, except for VM branch instru
|
Line 268 interpreter, except for VM branch instru
|
structures. The conceptual similarity to real machine code results in |
structures. The conceptual similarity to real machine code results in |
the name @emph{virtual machine}. |
the name @emph{virtual machine}. |
|
|
In this framework, vmgen supports building the VM interpreter and any |
In this framework, Vmgen supports building the VM interpreter and any |
other component dealing with VM instructions. It does not have any |
other component dealing with VM instructions. It does not have any |
support for the front end, apart from VM code generation support. The |
support for the front end, apart from VM code generation support. The |
front end can be implemented with classical compiler front-end |
front end can be implemented with classical compiler front-end |
Line 293 significantly more complex to implement
|
Line 295 significantly more complex to implement
|
Vmgen has special support and optimizations for stack VMs, making their |
Vmgen has special support and optimizations for stack VMs, making their |
implementation easy and efficient. |
implementation easy and efficient. |
|
|
You can also implement a register VM with vmgen (@pxref{Register |
You can also implement a register VM with Vmgen (@pxref{Register |
Machines}), and you will still profit from most vmgen features. |
Machines}), and you will still profit from most Vmgen features. |
|
|
@cindex stack item size |
@cindex stack item size |
@cindex size, stack items |
@cindex size, stack items |
Line 308 the data on the stack.
|
Line 310 the data on the stack.
|
@cindex immediate arguments |
@cindex immediate arguments |
Another source of data is immediate arguments VM instructions (in the VM |
Another source of data is immediate arguments VM instructions (in the VM |
instruction stream). The VM instruction stream is handled similar to a |
instruction stream). The VM instruction stream is handled similar to a |
stack in vmgen. |
stack in Vmgen. |
|
|
@cindex garbage collection |
@cindex garbage collection |
@cindex reference counting |
@cindex reference counting |
Line 323 harder, but might be possible (contact u
|
Line 325 harder, but might be possible (contact u
|
@node Dispatch, , Data handling, Concepts |
@node Dispatch, , Data handling, Concepts |
@section Dispatch |
@section Dispatch |
|
|
Understanding this section is probably not necessary for using vmgen, |
Understanding this section is probably not necessary for using Vmgen, |
but it may help. You may want to skip it now, and read it if you find statements about dispatch methods confusing. |
but it may help. You may want to skip it now, and read it if you find statements about dispatch methods confusing. |
|
|
After executing one VM instruction, the VM interpreter has to dispatch |
After executing one VM instruction, the VM interpreter has to dispatch |
the next VM instruction (vmgen calls the dispatch routine @samp{NEXT}). |
the next VM instruction (Vmgen calls the dispatch routine @samp{NEXT}). |
Vmgen supports two methods of dispatch: |
Vmgen supports two methods of dispatch: |
|
|
@table |
@table @asis |
|
|
@item switch dispatch |
@item switch dispatch |
In this method the VM interpreter contains a giant @code{switch} |
In this method the VM interpreter contains a giant @code{switch} |
Line 348 Dispatch consists of loading this addres
|
Line 350 Dispatch consists of loading this addres
|
incrementing the VM instruction pointer. Typically the threaded-code |
incrementing the VM instruction pointer. Typically the threaded-code |
dispatch code is appended directly to the code for executing the VM |
dispatch code is appended directly to the code for executing the VM |
instruction. Threaded code cannot be implemented in ANSI C, but it can |
instruction. Threaded code cannot be implemented in ANSI C, but it can |
be implemented using GNU C's labels-as-values extension (@pxref{labels |
be implemented using GNU C's labels-as-values extension (@pxref{Labels |
as values}). |
as Values, , Labels as Values, gcc.info, GNU C Manual}). |
|
|
@end table |
@end table |
|
|
@c ************************************************************* |
@c ************************************************************* |
@node Invoking vmgen, Example, Concepts, Top |
@node Invoking Vmgen, Example, Concepts, Top |
@chapter Invoking vmgen |
@chapter Invoking Vmgen |
|
|
The usual way to invoke vmgen is as follows: |
The usual way to invoke Vmgen is as follows: |
|
|
@example |
@example |
vmgen @var{infile} |
vmgen @var{infile} |
Line 371 current working directory) and replacing
|
Line 373 current working directory) and replacing
|
and @file{-peephole.i}. E.g., @command{bison hack/foo.vmg} will create |
and @file{-peephole.i}. E.g., @command{bison hack/foo.vmg} will create |
@file{foo-vm.i} etc. |
@file{foo-vm.i} etc. |
|
|
The command-line options supported by vmgen are |
The command-line options supported by Vmgen are |
|
|
@table @option |
@table @option |
|
|
Line 391 Print version and exit
|
Line 393 Print version and exit
|
@c env vars GFORTHDIR GFORTHDATADIR |
@c env vars GFORTHDIR GFORTHDATADIR |
|
|
@c **************************************************************** |
@c **************************************************************** |
@node Example, Input File Format, Invoking vmgen, Top |
@node Example, Input File Format, Invoking Vmgen, Top |
@chapter Example |
@chapter Example |
|
|
@menu |
@menu |
Line 403 Print version and exit
|
Line 405 Print version and exit
|
@node Example overview, Using profiling to create superinstructions, Example, Example |
@node Example overview, Using profiling to create superinstructions, Example, Example |
@section Example overview |
@section Example overview |
|
|
There are two versions of the same example for using vmgen: |
There are two versions of the same example for using Vmgen: |
@file{vmgen-ex} and @file{vmgen-ex2} (you can also see Gforth as |
@file{vmgen-ex} and @file{vmgen-ex2} (you can also see Gforth as |
example, but it uses additional (undocumented) features, and also |
example, but it uses additional (undocumented) features, and also |
differs in some other respects). The example implements @emph{mini}, a |
differs in some other respects). The example implements @emph{mini}, a |
Line 448 stat.awk script for aggregatin
|
Line 450 stat.awk script for aggregatin
|
seq2rule.awk script for creating superinstructions |
seq2rule.awk script for creating superinstructions |
@end example |
@end example |
|
|
|
@noindent |
You would typically change much in or replace the following files: |
You would typically change much in or replace the following files: |
|
|
@example |
@example |
Line 536 Most examples are taken from the example
|
Line 539 Most examples are taken from the example
|
* Input File Grammar:: |
* Input File Grammar:: |
* Simple instructions:: |
* Simple instructions:: |
* Superinstructions:: |
* Superinstructions:: |
|
* Register Machines:: How to define register VM instructions |
@end menu |
@end menu |
|
|
@c -------------------------------------------------------------------- |
@c -------------------------------------------------------------------- |
Line 551 spaces and especially newlines; it's not
|
Line 555 spaces and especially newlines; it's not
|
any sequence of spaces and tabs is equivalent to a single space. |
any sequence of spaces and tabs is equivalent to a single space. |
|
|
@example |
@example |
description: {instruction|comment|eval-escape} |
description: @{instruction|comment|eval-escape@} |
|
|
instruction: simple-inst|superinst |
instruction: simple-inst|superinst |
|
|
simple-inst: ident " (" stack-effect " )" newline c-code newline newline |
simple-inst: ident " (" stack-effect " )" newline c-code newline newline |
|
|
stack-effect: {ident} " --" {ident} |
stack-effect: @{ident@} " --" @{ident@} |
|
|
super-inst: ident " =" ident {ident} |
super-inst: ident " =" ident @{ident@} |
|
|
comment: "\ " text newline |
comment: "\ " text newline |
|
|
Line 571 Note that the @code{\}s in this grammar
|
Line 575 Note that the @code{\}s in this grammar
|
C-style encodings for non-printable characters. |
C-style encodings for non-printable characters. |
|
|
The C code in @code{simple-inst} must not contain empty lines (because |
The C code in @code{simple-inst} must not contain empty lines (because |
vmgen would mistake that as the end of the simple-inst. The text in |
Vmgen would mistake that as the end of the simple-inst. The text in |
@code{comment} and @code{eval-escape} must not contain a newline. |
@code{comment} and @code{eval-escape} must not contain a newline. |
@code{Ident} must conform to the usual conventions of C identifiers |
@code{Ident} must conform to the usual conventions of C identifiers |
(otherwise the C compiler would choke on the vmgen output). |
(otherwise the C compiler would choke on the Vmgen output). |
|
|
Vmgen understands a few extensions beyond the grammar given here, but |
Vmgen understands a few extensions beyond the grammar given here, but |
these extensions are only useful for building Gforth. You can find a |
these extensions are only useful for building Gforth. You can find a |
Line 583 description of the format used for Gfort
|
Line 587 description of the format used for Gfort
|
@subsection Eval escapes |
@subsection Eval escapes |
@c woanders? |
@c woanders? |
The text in @code{eval-escape} is Forth code that is evaluated when |
The text in @code{eval-escape} is Forth code that is evaluated when |
vmgen reads the line. If you do not know (and do not want to learn) |
Vmgen reads the line. If you do not know (and do not want to learn) |
Forth, you can build the text according to the following grammar; these |
Forth, you can build the text according to the following grammar; these |
rules are normally all Forth you need for using vmgen: |
rules are normally all Forth you need for using Vmgen: |
|
|
@example |
@example |
text: stack-decl|type-prefix-decl|stack-prefix-decl |
text: stack-decl|type-prefix-decl|stack-prefix-decl |
Line 631 just plain C code.
|
Line 635 just plain C code.
|
The stack effect specifies that @code{sub} pulls two integers from the |
The stack effect specifies that @code{sub} pulls two integers from the |
data stack and puts them in the C variables @code{i1} and @code{i2} (with |
data stack and puts them in the C variables @code{i1} and @code{i2} (with |
the rightmost item (@code{i2}) taken from the top of stack) and later |
the rightmost item (@code{i2}) taken from the top of stack) and later |
pushes one integer (@code{i)) on the data stack (the rightmost item is |
pushes one integer (@code{i}) on the data stack (the rightmost item is |
on the top afterwards). |
on the top afterwards). |
|
|
How do we know the type and stack of the stack items? Vmgen uses |
How do we know the type and stack of the stack items? Vmgen uses |
Line 658 This line defines the stack @code{data-s
|
Line 662 This line defines the stack @code{data-s
|
pointer @code{sp}, and each item has the basic type @code{Cell}; other |
pointer @code{sp}, and each item has the basic type @code{Cell}; other |
types have to fit into one or two @code{Cell}s (depending on whether the |
types have to fit into one or two @code{Cell}s (depending on whether the |
type is @code{single} or @code{double} wide), and are converted from and |
type is @code{single} or @code{double} wide), and are converted from and |
to Cells on accessing the @code{data-stack) with conversion macros |
to Cells on accessing the @code{data-stack} with conversion macros |
(@pxref{Conversion macros}). Stacks grow towards lower addresses in |
(@pxref{VM engine}). Stacks grow towards lower addresses in |
vmgen-erated interpreters. |
Vmgen-erated interpreters. |
|
|
We can override the default stack of a stack item by using a stack |
We can override the default stack of a stack item by using a stack |
prefix. E.g., consider the following instruction: |
prefix. E.g., consider the following instruction: |
Line 705 instructions:
|
Line 709 instructions:
|
@table @samp |
@table @samp |
|
|
@item SET_IP |
@item SET_IP |
As far as vmgen is concerned, a VM instruction containing this ends a VM |
As far as Vmgen is concerned, a VM instruction containing this ends a VM |
basic block (used in profiling to delimit profiled sequences). On the C |
basic block (used in profiling to delimit profiled sequences). On the C |
level, this also sets the instruction pointer. |
level, this also sets the instruction pointer. |
|
|
Line 720 middle of the C code, you need to use @s
|
Line 724 middle of the C code, you need to use @s
|
is a conditional VM branch: |
is a conditional VM branch: |
|
|
@example |
@example |
if (branch_condition) { |
if (branch_condition) @{ |
SET_IP(target); TAIL; |
SET_IP(target); TAIL; |
} |
@} |
/* implicit tail follows here */ |
/* implicit tail follows here */ |
@end example |
@end example |
|
|
Line 738 is not yet implemented in the vmgen-ex c
|
Line 742 is not yet implemented in the vmgen-ex c
|
typical application is in conditional VM branches: |
typical application is in conditional VM branches: |
|
|
@example |
@example |
if (branch_condition) { |
if (branch_condition) @{ |
SET_IP(target); TAIL; /* now this TAIL is necessary */ |
SET_IP(target); TAIL; /* now this TAIL is necessary */ |
} |
@} |
SUPER_CONTINUE; |
SUPER_CONTINUE; |
@end example |
@end example |
|
|
@end table |
@end table |
|
|
Note that vmgen is not smart about C-level tokenization, comments, |
Note that Vmgen is not smart about C-level tokenization, comments, |
strings, or conditional compilation, so it will interpret even a |
strings, or conditional compilation, so it will interpret even a |
commented-out SUPER_END as ending a basic block (or, e.g., |
commented-out SUPER_END as ending a basic block (or, e.g., |
@samp{RETAIL;} as @samp{TAIL;}). Conversely, vmgen requires the literal |
@samp{RETAIL;} as @samp{TAIL;}). Conversely, Vmgen requires the literal |
presence of these strings; vmgen will not see them if they are hiding in |
presence of these strings; Vmgen will not see them if they are hiding in |
a C preprocessor macro. |
a C preprocessor macro. |
|
|
|
|
Line 768 the following.
|
Line 772 the following.
|
Accessing a stack or stack pointer directly can be a problem for several |
Accessing a stack or stack pointer directly can be a problem for several |
reasons: |
reasons: |
|
|
@itemize |
@itemize @bullet |
|
|
@item |
@item |
You may cache the top-of-stack item in a local variable (that is |
You may cache the top-of-stack item in a local variable (that is |
Line 784 automatically by mentioning a special st
|
Line 788 automatically by mentioning a special st
|
@c sometimes flushing and/or reloading unnecessary |
@c sometimes flushing and/or reloading unnecessary |
|
|
@item |
@item |
The vmgen-erated code loads the stack items from stack-pointer-indexed |
The Vmgen-erated code loads the stack items from stack-pointer-indexed |
memory into variables before the user-supplied C code, and stores them |
memory into variables before the user-supplied C code, and stores them |
from variables to stack-pointer-indexed memory afterwards. If you do |
from variables to stack-pointer-indexed memory afterwards. If you do |
any writes to the stack through its stack pointer in your C code, it |
any writes to the stack through its stack pointer in your C code, it |
Line 808 contents.
|
Line 812 contents.
|
|
|
|
|
@c -------------------------------------------------------------------- |
@c -------------------------------------------------------------------- |
@node Superinstructions, , Simple instructions, Input File Format |
@node Superinstructions, Register Machines, Simple instructions, Input File Format |
@section Superinstructions |
@section Superinstructions |
|
|
Note: don't invest too much work in (static) superinstructions; a future |
Note: don't invest too much work in (static) superinstructions; a future |
version of vmgen will support dynamic superinstructions (see Ian |
version of Vmgen will support dynamic superinstructions (see Ian |
Piumarta and Fabio Riccardi, @cite{Optimizing Direct Threaded Code by |
Piumarta and Fabio Riccardi, @cite{Optimizing Direct Threaded Code by |
Selective Inlining}, PLDI'98), and static superinstructions have much |
Selective Inlining}, PLDI'98), and static superinstructions have much |
less benefit in that context. |
less benefit in that context. |
Line 827 lit_sub = lit sub
|
Line 831 lit_sub = lit sub
|
@code{sub} are its components. This superinstruction performs the same |
@code{sub} are its components. This superinstruction performs the same |
action as the sequence @code{lit} and @code{sub}. It is generated |
action as the sequence @code{lit} and @code{sub}. It is generated |
automatically by the VM code generation functions whenever that sequence |
automatically by the VM code generation functions whenever that sequence |
occurs, so you only need to add this definition if you want to use this |
occurs, so if you want to use this superinstruction, you just need to |
superinstruction (and even that can be partially automatized, |
add this definition (and even that can be partially automatized, |
@pxref{...}). |
@pxref{VM profiler}). |
|
|
Vmgen requires that the component instructions are simple instructions |
Vmgen requires that the component instructions are simple instructions |
defined before superinstructions using the components. Currently, vmgen |
defined before superinstructions using the components. Currently, Vmgen |
also requires that all the subsequences at the start of a |
also requires that all the subsequences at the start of a |
superinstruction (prefixes) must be defined as superinstruction before |
superinstruction (prefixes) must be defined as superinstruction before |
the superinstruction. I.e., if you want to define a superinstruction |
the superinstruction. I.e., if you want to define a superinstruction |
Line 854 sumof4 = add add add
|
Line 858 sumof4 = add add add
|
Here, @code{sumof4} is the longest prefix of @code{sumof5}, and @code{sumof3} |
Here, @code{sumof4} is the longest prefix of @code{sumof5}, and @code{sumof3} |
is the longest prefix of @code{sumof4}. |
is the longest prefix of @code{sumof4}. |
|
|
Note that vmgen assumes that only the code it generates accesses stack |
Note that Vmgen assumes that only the code it generates accesses stack |
pointers, the instruction pointer, and various stack items, and it |
pointers, the instruction pointer, and various stack items, and it |
performs optimizations based on this assumption. Therefore, VM |
performs optimizations based on this assumption. Therefore, VM |
instructions that change the instruction pointer should only be used as |
instructions that change the instruction pointer should only be used as |
Line 862 last component; a VM instruction that ac
|
Line 866 last component; a VM instruction that ac
|
not be used as component at all. Vmgen does not check these |
not be used as component at all. Vmgen does not check these |
restrictions, they just result in bugs in your interpreter. |
restrictions, they just result in bugs in your interpreter. |
|
|
|
@node Register Machines, , Superinstructions, Input File Format |
|
@section Register Machines |
|
|
|
If you want to implement a register VM rather than a stack VM with |
|
Vmgen, there are two ways to do it: Directly and through |
|
superinstructions. |
|
|
|
If you use the direct way, you define instructions that take the |
|
register numbers as immediate arguments, like this: |
|
|
|
@example |
|
add3 ( #src1 #src2 #dest -- ) |
|
reg[dest] = reg[src1]+reg[src2]; |
|
@end example |
|
|
|
If you use superinstructions to define a register VM, you define simple |
|
instructions that use a stack, and then define superinstructions that |
|
have no overall stack effect, like this: |
|
|
|
@example |
|
loadreg ( #src -- n ) |
|
n = reg[src]; |
|
|
|
storereg ( n #dest -- ) |
|
reg[dest] = n; |
|
|
|
adds ( n1 n2 -- n ) |
|
n = n1+n2; |
|
|
|
add3 = loadreg loadreg adds storereg |
|
@end example |
|
|
|
An advantage of this method is that you see the values and not just the |
|
register numbers in tracing (actually, with an appropriate definition of |
|
@code{printarg_src} (@pxref{VM engine}), you can print the values of the |
|
source registers on entry, but you cannot print the value of the |
|
destination register on exit. A disadvantage of this method is that |
|
currently you cannot generate superinstructions directly, but only |
|
through generating a sequence of simple instructions (we might change |
|
this in the future if there is demand). |
|
|
|
Could the register VM support be improved, apart from the issues |
|
mentioned above? It is hard to see how to do it in a general way, |
|
because there are a number of different designs that different people |
|
mean when they use the term @emph{register machine} in connection with |
|
VM interpreters. However, if you have ideas or requests in that |
|
direction, please let me know (@pxref{Contact}). |
|
|
@c ******************************************************************** |
@c ******************************************************************** |
@node Using the generated code, Changes, Input File Format, Top |
@node Using the generated code, Changes, Input File Format, Top |
@chapter Using the generated code |
@chapter Using the generated code |
|
|
The easiest way to create a working VM interpreter with vmgen is |
The easiest way to create a working VM interpreter with Vmgen is |
probably to start with one of the examples, and modify it for your |
probably to start with one of the examples, and modify it for your |
purposes. This chapter is just the reference manual for the macros |
purposes. This chapter is just the reference manual for the macros |
etc. used by the generated code, the other context expected by the |
etc. used by the generated code, the other context expected by the |
Line 907 The following macros and variables are u
|
Line 959 The following macros and variables are u
|
|
|
@item LABEL(@var{inst_name}) |
@item LABEL(@var{inst_name}) |
This is used just before each VM instruction to provide a jump or |
This is used just before each VM instruction to provide a jump or |
@code{switch} label (the @samp{:} is provided by vmgen). For switch |
@code{switch} label (the @samp{:} is provided by Vmgen). For switch |
dispatch this should expand to @samp{case @var{label}}; for |
dispatch this should expand to @samp{case @var{label}}; for |
threaded-code dispatch this should just expand to @samp{case |
threaded-code dispatch this should just expand to @samp{case |
@var{label}}. In either case @var{label} is usually the @var{inst_name} |
@var{label}}. In either case @var{label} is usually the @var{inst_name} |
Line 944 macros do nothing. Then also related ma
|
Line 996 macros do nothing. Then also related ma
|
straightforward to define. For switch dispatch this code consists just |
straightforward to define. For switch dispatch this code consists just |
of a jump to the dispatch code (@samp{goto next_inst;} in our example; |
of a jump to the dispatch code (@samp{goto next_inst;} in our example; |
for direct threaded code it consists of something like |
for direct threaded code it consists of something like |
@samp{({cfa=*ip++; goto *cfa;})}. |
@samp{(@{cfa=*ip++; goto *cfa;@})}. |
|
|
Pulling code (usually the @samp{cfa=*ip;}) up into @samp{NEXT_P1} |
Pulling code (usually the @samp{cfa=*ip;}) up into @samp{NEXT_P1} |
usually does not cause problems, but pulling things up into |
usually does not cause problems, but pulling things up into |
Line 1014 anything in normal operation, and call @
|
Line 1066 anything in normal operation, and call @
|
profiling. |
profiling. |
|
|
@item SUPER_CONTINUE |
@item SUPER_CONTINUE |
This is just a hint to vmgen and does nothing at the C level. |
This is just a hint to Vmgen and does nothing at the C level. |
|
|
@item VM_DEBUG |
@item VM_DEBUG |
If this is defined, the tracing code will be compiled in (slower |
If this is defined, the tracing code will be compiled in (slower |
Line 1069 For switch dispatch, we also need to def
|
Line 1121 For switch dispatch, we also need to def
|
used as case labels in an @code{enum}. |
used as case labels in an @code{enum}. |
|
|
For both purposes (VM instruction table, and enum), the file |
For both purposes (VM instruction table, and enum), the file |
@file{@var{name}-labels.i} is generated by vmgen. You have to define |
@file{@var{name}-labels.i} is generated by Vmgen. You have to define |
the following macro used in this file: |
the following macro used in this file: |
|
|
@table @samp |
@table @samp |
Line 1079 For switch dispatch, this is just the na
|
Line 1131 For switch dispatch, this is just the na
|
name as used in @samp{LABEL(@var{inst_name})}), for both uses of |
name as used in @samp{LABEL(@var{inst_name})}), for both uses of |
@file{@var{name}-labels.i}. For threaded-code dispatch, this is the |
@file{@var{name}-labels.i}. For threaded-code dispatch, this is the |
address of the label defined in @samp{LABEL(@var{inst_name})}); the |
address of the label defined in @samp{LABEL(@var{inst_name})}); the |
address is taken with @samp{&&} (@pxref{labels-as-values}). |
address is taken with @samp{&&} (@pxref{Labels as Values, , Labels as |
|
Values, gcc.info, GNU C Manual}). |
|
|
@end table |
@end table |
|
|
Line 1092 Vmgen generates VM code generation funct
|
Line 1145 Vmgen generates VM code generation funct
|
that the front end can call to generate VM code. This is essential for |
that the front end can call to generate VM code. This is essential for |
an interpretive system. |
an interpretive system. |
|
|
For a VM instruction @samp{x ( #a b #c -- d )}, vmgen generates a |
For a VM instruction @samp{x ( #a b #c -- d )}, Vmgen generates a |
function with the prototype |
function with the prototype |
|
|
@example |
@example |
Line 1140 every type that you use as immediate arg
|
Line 1193 every type that you use as immediate arg
|
In addition to using these functions to generate code, you should call |
In addition to using these functions to generate code, you should call |
@code{BB_BOUNDARY} at every basic block entry point if you ever want to |
@code{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 |
use superinstructions (or if you want to use the profiling supported by |
vmgen; however, this is mainly useful for selecting superinstructions). |
Vmgen; however, this is mainly useful for selecting superinstructions). |
If you use @code{BB_BOUNDARY}, you should also define it (take a look at |
If you use @code{BB_BOUNDARY}, you should also define it (take a look at |
its definition in @file{vmgen-ex/mini.y}). |
its definition in @file{vmgen-ex/mini.y}). |
|
|
Line 1253 in 16 places, and has been executed 3691
|
Line 1306 in 16 places, and has been executed 3691
|
superinstructions in any way you like (note that compile time and space |
superinstructions in any way you like (note that compile time and space |
typically limit the number of superinstructions to 100--1000). After |
typically limit the number of superinstructions to 100--1000). After |
you have done that, @file{vmgen/seq2rule.awk} turns lines of the form |
you have done that, @file{vmgen/seq2rule.awk} turns lines of the form |
above into rules for inclusion in a vmgen input file. Note that this |
above into rules for inclusion in a Vmgen input file. Note that this |
script does not ensure that all prefixes are defined, so you have to do |
script does not ensure that all prefixes are defined, so you have to do |
that in other ways. So, an overall script for turning profiles into |
that in other ways. So, an overall script for turning profiles into |
superinstructions can look like this: |
superinstructions can look like this: |
Line 1300 plus @code{VM_IS_INST} already defined f
|
Line 1353 plus @code{VM_IS_INST} already defined f
|
@node Changes, Contact, Using the generated code, Top |
@node Changes, Contact, Using the generated code, Top |
@chapter Changes |
@chapter Changes |
|
|
Users of the gforth-0.5.9-20010501 version of vmgen need to change |
Users of the gforth-0.5.9-20010501 version of Vmgen need to change |
several things in their source code to use the current version. I |
several things in their source code to use the current version. I |
recommend keeping the gforth-0.5.9-20010501 version until you have |
recommend keeping the gforth-0.5.9-20010501 version until you have |
completed the change (note that you can have several versions of Gforth |
completed the change (note that you can have several versions of Gforth |