Diff for /gforth/doc/vmgen.texi between versions 1.8 and 1.24

version 1.8, 2002/08/08 19:20:26 version 1.24, 2003/03/02 13:12:33
Line 1 Line 1
   \input texinfo    @c -*-texinfo-*-
   @comment %**start of header
   @setfilename vmgen.info
 @include version.texi  @include version.texi
   @settitle Vmgen (Gforth @value{VERSION})
   @c @syncodeindex pg cp
   @comment %**end of header
   @copying
   This manual is for Vmgen
   (version @value{VERSION}, @value{UPDATED}),
   the virtual machine interpreter generator
   
   Copyright @copyright{} 2002, 03 Free Software Foundation, Inc.
   
   @quotation
   Permission is granted to copy, distribute and/or modify this document
   under the terms of the GNU Free Documentation License, Version 1.1 or
   any later version published by the Free Software Foundation; with no
   Invariant Sections, with the Front-Cover texts being ``A GNU Manual,''
   and with the Back-Cover Texts as in (a) below.  A copy of the
   license is included in the section entitled ``GNU Free Documentation
   License.''
   
   (a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
   this GNU Manual, like GNU software.  Copies published by the Free
   Software Foundation raise funds for GNU development.''
   @end quotation
   @end copying
   
   @dircategory Software development
   @direntry
   * Vmgen: (vmgen).               Virtual machine interpreter generator
   @end direntry
   
   @titlepage
   @title Vmgen
   @subtitle for Gforth version @value{VERSION}, @value{UPDATED}
   @author M. Anton Ertl (@email{anton@@mips.complang.tuwien.ac.at})
   @page
   @vskip 0pt plus 1filll
   @insertcopying
   @end titlepage
   
   @contents
   
   @ifnottex
   @node Top, Introduction, (dir), (dir)
   @top Vmgen
   
   @insertcopying
   @end ifnottex
   
   @menu
   * Introduction::                What can Vmgen do for you?
   * Why interpreters?::           Advantages and disadvantages
   * Concepts::                    VM interpreter background
   * Invoking Vmgen::              
   * Example::                     
   * Input File Format::           
   * Error messages::              reported by Vmgen
   * Using the generated code::    
   * Hints::                       VM archictecture, efficiency
   * The future::                  
   * Changes::                     from earlier versions
   * Contact::                     Bug reporting etc.
   * Copying This Manual::         Manual License
   * Index::                       
   
   @detailmenu
    --- The Detailed Node Listing ---
   
   Concepts
   
   * Front end and VM interpreter::  Modularizing an interpretive system
   * Data handling::               Stacks, registers, immediate arguments
   * Dispatch::                    From one VM instruction to the next
   
   Example
   
   * Example overview::            
   * Using profiling to create superinstructions::  
   
   Input File Format
   
   * Input File Grammar::          
   * Simple instructions::         
   * Superinstructions::           
   * Store Optimization::          
   * Register Machines::           How to define register VM instructions
   
   Input File Grammar
   
   * Eval escapes::                what follows \E
   
   Simple instructions
   
   * C Code Macros::               Macros recognized by Vmgen
   * C Code restrictions::         Vmgen makes assumptions about C code
   * Stack growth direction::      is configurable per stack
   
   Using the generated code
   
   * VM engine::                   Executing VM code
   * VM instruction table::        
   * VM code generation::          Creating VM code (in the front-end)
   * Peephole optimization::       Creating VM superinstructions
   * VM disassembler::             for debugging the front end
   * VM profiler::                 for finding worthwhile superinstructions
   
   Hints
   
   * Floating point::              and stacks
   
   Copying This Manual
   
   * GNU Free Documentation License::  License for copying this manual.
   
   @end detailmenu
   @end menu
   
 @c @ifnottex  @c @ifnottex
 This file documents vmgen (Gforth @value{VERSION}).  @c This file documents Vmgen (Gforth @value{VERSION}).
   
   @c ************************************************************
   @node Introduction, Why interpreters?, Top, Top
 @chapter Introduction  @chapter Introduction
   
 Vmgen is a tool for writing efficient interpreters.  It takes a simple  Vmgen is a tool for writing efficient interpreters.  It takes a simple
Line 12  it).  The run-time efficiency of the res Line 132  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 39  A @emph{virtual machine} (VM) represents Line 159  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  @cindex functionality features overview
   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 @strong
   
 @item VM instruction execution  @item VM instruction execution
   
Line 59  typically provide other means for debugg Line 180  typically provide other means for debugg
 source level.  source level.
   
 @item VM code profiling  @item VM code profiling
 Useful for optimizing the VM insterpreter with superinstructions  Useful for optimizing the VM interpreter with superinstructions
 (@pxref...).  (@pxref{VM profiler}).
   
 @end table  @end table
   
 VMgen supports efficient interpreters though various optimizations, in  To create parts of the interpretive system that do not deal with VM
   instructions, you have to use other tools (e.g., @command{bison}) and/or
   hand-code them.
   
   @cindex efficiency features overview
   @noindent
   Vmgen supports efficient interpreters though various optimizations, in
 particular  particular
   
 @itemize  @itemize @bullet
   
 @item Threaded code  @item Threaded code
   
Line 81  Replicating VM (super)instructions for b Line 208  Replicating VM (super)instructions for b
   
 @end itemize  @end itemize
   
 As a result, vmgen-based interpreters are only about an order of  @cindex speed for JVM
 magintude slower than native code from an optimizing C compiler on small  As a result, Vmgen-based interpreters are only about an order of
   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 91  and all other interpreters we looked at Line 219  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
 still benefit from most of the advantages offered by vmgen.  (@pxref{Register Machines}) and 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
 we will implement new features if someone asks for them; so the feature  we will consider new features if someone asks for them; so the feature
 list above is not exhaustive.  list above is not exhaustive.
   
 @c *********************************************************************  @c *********************************************************************
   @node Why interpreters?, Concepts, Introduction, Top
 @chapter Why interpreters?  @chapter Why interpreters?
   @cindex interpreters, advantages
   @cindex advantages of interpreters
   @cindex advantages of vmgen
   
 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 116  they combine all three of the following Line 249  they combine all three of the following
   
 @end itemize  @end itemize
   
   Vmgen makes it even easier to implement interpreters.
   
   @cindex speed of interpreters
 The main disadvantage of interpreters is their run-time speed.  However,  The main disadvantage of interpreters is their run-time speed.  However,
 there are huge differences between different interpreters in this area:  there are huge differences between different interpreters in this area:
 the slowdown over optimized C code on programs consisting of simple  the slowdown over optimized C code on programs consisting of simple
Line 125  slowdown for programs executing complex Line 261  slowdown for programs executing complex
 time spent in libraries for executing complex operations is the same in  time spent in libraries for executing complex operations is the same in
 all implementation strategies).  all implementation strategies).
   
 Vmgen makes it even easier to implement interpreters.  It also supports  Vmgen supports techniques for building efficient interpreters.
 techniques for building efficient interpreters.  
   
 @c ********************************************************************  @c ********************************************************************
   @node Concepts, Invoking Vmgen, Why interpreters?, Top
 @chapter Concepts  @chapter Concepts
   
   @menu
   * Front end and VM interpreter::  Modularizing an interpretive system
   * Data handling::               Stacks, registers, immediate arguments
   * Dispatch::                    From one VM instruction to the next
   @end menu
   
 @c --------------------------------------------------------------------  @c --------------------------------------------------------------------
 @section Front-end and virtual machine interpreter  @node Front end and VM interpreter, Data handling, Concepts, Concepts
   @section Front end and VM interpreter
   @cindex modularization of interpreters
   
 @cindex front-end  @cindex front-end
 Interpretive systems are typically divided into a @emph{front end} that  Interpretive systems are typically divided into a @emph{front end} that
Line 142  representation of the program. Line 286  representation of the program.
   
 @cindex virtual machine  @cindex virtual machine
 @cindex VM  @cindex VM
   @cindex VM instruction
 @cindex instruction, VM  @cindex instruction, VM
   @cindex VM branch instruction
   @cindex branch instruction, VM
   @cindex VM register
   @cindex register, VM
   @cindex opcode, VM instruction
   @cindex immediate argument, VM instruction
 For efficient interpreters the intermediate representation of choice is  For efficient interpreters the intermediate representation of choice is
 virtual machine code (rather than, e.g., an abstract syntax tree).  virtual machine code (rather than, e.g., an abstract syntax tree).
 @emph{Virtual machine} (VM) code consists of VM instructions arranged  @emph{Virtual machine} (VM) code consists of VM instructions arranged
 sequentially in memory; they are executed in sequence by the VM  sequentially in memory; they are executed in sequence by the VM
 interpreter, except for VM branch instructions, which implement control  interpreter, but VM branch instructions can change the control flow and
 structures.  The conceptual similarity to real machine code results in  are used for implementing control structures.  The conceptual similarity
 the name @emph{virtual machine}.  to real machine code results in the name @emph{virtual machine}.
   Various terms similar to terms for real machines are used; e.g., there
   are @emph{VM registers} (like the instruction pointer and stack
   pointer(s)), and the VM instruction consists of an @emph{opcode} and
   @emph{immediate arguments}.
   
 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 162  interpreter, but some systems also suppo Line 317  interpreter, but some systems also suppo
 as an image file, or in a full-blown linkable file format (e.g., JVM).  as an image file, or in a full-blown linkable file format (e.g., JVM).
 Vmgen currently has no special support for such features, but the  Vmgen currently has no special support for such features, but the
 information in the instruction descriptions can be helpful, and we are  information in the instruction descriptions can be helpful, and we are
 open for feature requests and suggestions.  open to feature requests and suggestions.
   
   @c --------------------------------------------------------------------
   @node Data handling, Dispatch, Front end and VM interpreter, Concepts
 @section Data handling  @section Data handling
   
 @cindex stack machine  @cindex stack machine
 @cindex register machine  @cindex register machine
 Most VMs use one or more stacks for passing temporary data between VM  Most VMs use one or more stacks for passing temporary data between VM
 instructions.  Another option is to use a register machine architecture  instructions.  Another option is to use a register machine architecture
 for the virtual machine; however, this option is either slower or  for the virtual machine; we believe that using a stack architecture is
   usually both simpler and faster.
   
   however, this option is slower or
 significantly more complex to implement than a stack machine architecture.  significantly more complex to implement than a stack machine architecture.
   
 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 191  the data on the stack. Line 351  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
 Vmgen has no built-in support for nor restrictions against @emph{garbage  Vmgen has no built-in support for, nor restrictions against
 collection}.  If you need garbage collection, you need to provide it in  @emph{garbage collection}.  If you need garbage collection, you need to
 your run-time libraries.  Using @emph{reference counting} is probably  provide it in your run-time libraries.  Using @emph{reference counting}
 harder, but might be possible (contact us if you are interested).  is probably harder, but might be possible (contact us if you are
   interested).
 @c reference counting might be possible by including counting code in   @c reference counting might be possible by including counting code in 
 @c the conversion macros.  @c the conversion macros.
   
   @c --------------------------------------------------------------------
   @node Dispatch,  , Data handling, Concepts
 @section Dispatch  @section Dispatch
   @cindex Dispatch of VM instructions
   @cindex main interpreter loop
   
 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 @strong
   
 @item switch dispatch  @item switch dispatch
   @cindex switch dispatch
 In this method the VM interpreter contains a giant @code{switch}  In this method the VM interpreter contains a giant @code{switch}
 statement, with one @code{case} for each VM instruction.  The VM  statement, with one @code{case} for each VM instruction.  The VM
 instructions are represented by integers (e.g., produced by an  instruction opcodes are represented by integers (e.g., produced by an
 @code{enum}) in the VM code, and dipatch occurs by loading the next  @code{enum}) in the VM code, and dispatch occurs by loading the next
 integer from the VM code, @code{switch}ing on it, and continuing at the  opcode, @code{switch}ing on it, and continuing at the appropriate
 appropriate @code{case}; after executing the VM instruction, jump back  @code{case}; after executing the VM instruction, the VM interpreter
 to the dispatch code.  jumps back to the dispatch code.
   
 @item threaded code  @item threaded code
 This method represents a VM instruction in the VM code by the address of  @cindex threaded code
 the start of the machine code fragment for executing the VM instruction.  This method represents a VM instruction opcode by the address of the
   start of the machine code fragment for executing the VM instruction.
 Dispatch consists of loading this address, jumping to it, and  Dispatch consists of loading this address, jumping to it, and
 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}).
   
   @c call threading
 @end table  @end table
   
   Threaded code can be twice as fast as switch dispatch, depending on the
   interpreter, the benchmark, and the machine.
   
 @c *************************************************************  @c *************************************************************
 @chapter Invoking vmgen  @node Invoking Vmgen, Example, Concepts, Top
   @chapter Invoking Vmgen
   @cindex 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{inputfile}
 @end example  @end example
   
 Here @var{infile} is the VM instruction description file, which usually  Here @var{inputfile} is the VM instruction description file, which
 ends in @file{.vmg}.  The output filenames are made by taking the  usually ends in @file{.vmg}.  The output filenames are made by taking
 basename of @file{infile} (i.e., the output files will be created in the  the basename of @file{inputfile} (i.e., the output files will be created
 current working directory) and replacing @file{.vmg} with @file{-vm.i},  in the current working directory) and replacing @file{.vmg} with
 @file{-disasm.i}, @file{-gen.i}, @file{-labels.i}, @file{-profile.i},  @file{-vm.i}, @file{-disasm.i}, @file{-gen.i}, @file{-labels.i},
 and @file{-peephole.i}.  E.g., @command{bison hack/foo.vmg} will create  @file{-profile.i}, and @file{-peephole.i}.  E.g., @command{vmgen
 @file{foo-vm.i} etc.  hack/foo.vmg} will create @file{foo-vm.i}, @file{foo-disasm.i},
   @file{foo-gen.i}, @file{foo-labels.i}, @file{foo-profile.i} and
   @file{foo-peephole.i}.
   
 The command-line options supported by vmgen are  The command-line options supported by Vmgen are
   
 @table @option  @table @option
   
Line 271  Print version and exit Line 446  Print version and exit
 @c env vars GFORTHDIR GFORTHDATADIR  @c env vars GFORTHDIR GFORTHDATADIR
   
 @c ****************************************************************  @c ****************************************************************
   @node Example, Input File Format, Invoking Vmgen, Top
 @chapter Example  @chapter Example
   @cindex example of a Vmgen-based interpreter
   
   @menu
   * Example overview::            
   * Using profiling to create superinstructions::  
   @end menu
   
   @c --------------------------------------------------------------------
   @node Example overview, Using profiling to create superinstructions, Example, Example
 @section Example overview  @section Example overview
   @cindex example overview
   @cindex @file{vmgen-ex}
   @cindex @file{vmgen-ex2}
   
 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
 tiny Modula-2-like language with a small JavaVM-like virtual machine.  tiny Modula-2-like language with a small JavaVM-like virtual machine.
   
 The difference between the examples is that @file{vmgen-ex} uses many  The difference between the examples is that @file{vmgen-ex} uses many
 casts, and @file{vmgen-ex2} tries to avoids most casts and uses unions  casts, and @file{vmgen-ex2} tries to avoids most casts and uses unions
 instead.  instead.  In the rest of this manual we usually mention just files in
   @file{vmgen-ex}; if you want to use unions, use the equivalent file in
   @file{vmgen-ex2}.
   @cindex unions example
   @cindex casts example
   
 The files provided with each example are:  The files provided with each example are:
   @cindex example files
   
 @example  @example
 Makefile  Makefile
Line 310  seq2rule.awk       script for creating s Line 503  seq2rule.awk       script for creating s
   
 For your own interpreter, you would typically copy the following files  For your own interpreter, you would typically copy the following files
 and change little, if anything:  and change little, if anything:
   @cindex wrapper files
   
 @example  @example
 disasm.c           wrapper file  disasm.c           wrapper file
Line 320  stat.awk           script for aggregatin Line 514  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 333  peephole-blacklist list of instructions Line 528  peephole-blacklist list of instructions
 @end example  @end example
   
 You can build the example by @code{cd}ing into the example's directory,  You can build the example by @code{cd}ing into the example's directory,
 and then typing @samp{make}; you can check that it works with @samp{make  and then typing @code{make}; you can check that it works with @code{make
 check}.  You can run run mini programs like this:  check}.  You can run run mini programs like this:
   
 @example  @example
 ./mini fib.mini  ./mini fib.mini
 @end example  @end example
   
 To learn about the options, type @samp{./mini -h}.  To learn about the options, type @code{./mini -h}.
   
   @c --------------------------------------------------------------------
   @node Using profiling to create superinstructions,  , Example overview, Example
 @section Using profiling to create superinstructions  @section Using profiling to create superinstructions
   @cindex profiling example
   @cindex superinstructions example
   
 I have not added rules for this in the @file{Makefile} (there are many  I have not added rules for this in the @file{Makefile} (there are many
 options for selecting superinstructions, and I did not want to hardcode  options for selecting superinstructions, and I did not want to hardcode
Line 380  execution count exceeding 10000, you wou Line 579  execution count exceeding 10000, you wou
 awk -f stat.awk fib.prof test.prof|  awk -f stat.awk fib.prof test.prof|
 awk '$3>=10000'|                #select sequences  awk '$3>=10000'|                #select sequences
 fgrep -v -f peephole-blacklist| #eliminate wrong instructions  fgrep -v -f peephole-blacklist| #eliminate wrong instructions
 awk -f seq2rule.awk|      #transform sequences into superinstruction rules  awk -f seq2rule.awk|  #transform sequences into superinstruction rules
 sort -k 3 >mini-super.vmg       #sort sequences  sort -k 3 >mini-super.vmg       #sort sequences
 @end example  @end example
   
 The file @file{peephole-blacklist} contains all instructions that  The file @file{peephole-blacklist} contains all instructions that
 directly access a stack or stack pointer (for mini: @code{call},  directly access a stack or stack pointer (for mini: @code{call},
 @code{return}); the sort step is necessary to ensure that prefixes  @code{return}); the sort step is necessary to ensure that prefixes
 preceed larger superinstructions.  precede larger superinstructions.
   
 Now you can create a version of mini with superinstructions by just  Now you can create a version of mini with superinstructions by just
 saying @samp{make}  saying @samp{make}
   
   
 @c ***************************************************************  @c ***************************************************************
   @node Input File Format, Error messages, Example, Top
 @chapter Input File Format  @chapter Input File Format
   @cindex input file format
   @cindex format, input file
   
 Vmgen takes as input a file containing specifications of virtual machine  Vmgen takes as input a file containing specifications of virtual machine
 instructions.  This file usually has a name ending in @file{.vmg}.  instructions.  This file usually has a name ending in @file{.vmg}.
   
 Most examples are taken from the example in @file{vmgen-ex}.  Most examples are taken from the example in @file{vmgen-ex}.
   
   @menu
   * Input File Grammar::          
   * Simple instructions::         
   * Superinstructions::           
   * Store Optimization::          
   * Register Machines::           How to define register VM instructions
   @end menu
   
   @c --------------------------------------------------------------------
   @node Input File Grammar, Simple instructions, Input File Format, Input File Format
 @section Input File Grammar  @section Input File Grammar
   @cindex grammar, input file
   @cindex input file grammar
   
 The grammar is in EBNF format, with @code{@var{a}|@var{b}} meaning  The grammar is in EBNF format, with @code{@var{a}|@var{b}} meaning
 ``@var{a} or @var{b}'', @code{@{@var{c}@}} meaning 0 or more repetitions  ``@var{a} or @var{b}'', @code{@{@var{c}@}} meaning 0 or more repetitions
 of @var{c} and @code{[@var{d}]} meaning 0 or 1 repetitions of @var{d}.  of @var{c} and @code{[@var{d}]} meaning 0 or 1 repetitions of @var{d}.
   
   @cindex free-format, not
   @cindex newlines, significance in syntax
 Vmgen input is not free-format, so you have to take care where you put  Vmgen input is not free-format, so you have to take care where you put
 spaces and especially newlines; it's not as bad as makefiles, though:  newlines (and, in a few cases, white 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|c-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  eval-escape:  '\E ' text newline
   
 eval-escape:  "\e " text newline  c-escape:     '\C ' text newline
 @end example  @end example
 @c \+ \- \g \f \c  @c \+ \- \g \f \c
   
 Note that the @code{\}s in this grammar are meant literally, not as  Note that the @code{\}s in this grammar are meant literally, not as
 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  There are two ways to delimit the C code in @code{simple-inst}:
 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.  @itemize @bullet
 @code{Ident} must conform to the usual conventions of C identifiers  
 (otherwise the C compiler would choke on the vmgen output).  @item
   If you start it with a @samp{@{} at the start of a line (i.e., not even
   white space before it), you have to end it with a @samp{@}} at the start
   of a line (followed by a newline).  In this case you may have empty
   lines within the C code (typically used between variable definitions and
   statements).
   
   @item
   You do not start it with @samp{@{}.  Then the C code ends at the first
   empty line, so you cannot have empty lines within this code.
   
   @end itemize
   
   The text in @code{comment}, @code{eval-escape} and @code{c-escape} must
   not contain a newline.  @code{Ident} must conform to the usual
   conventions of C identifiers (otherwise the C compiler would choke on
   the Vmgen output), except that idents in @code{stack-effect} may have a
   stack prefix (for stack prefix syntax, @pxref{Eval escapes}).
   
   @cindex C escape
   @cindex @code{\C}
   @cindex conditional compilation of Vmgen output
   The @code{c-escape} passes the text through to each output file (without
   the @samp{\C}).  This is useful mainly for conditional compilation
   (i.e., you write @samp{\C #if ...} etc.).
   
   @cindex sync lines
   @cindex @code{#line}
   In addition to the syntax given in the grammer, Vmgen also processes
   sync lines (lines starting with @samp{#line}), as produced by @samp{m4
   -s} (@pxref{Invoking m4, , Invoking m4, m4.info, GNU m4}) and similar
   tools.  This allows associating C compiler error messages with the
   original source of the C code.
   
 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
 description of the format used for Gforth in @file{prim}.  description of the format used for Gforth in @file{prim}.
   
 @subsection  @menu
   * Eval escapes::                what follows \E
   @end menu
   
   @node Eval escapes,  , Input File Grammar, Input File Grammar
   @subsection Eval escapes
   @cindex escape to Forth
   @cindex eval escape
   @cindex @code{\E}
   
 @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.  You will normally use this feature to define
 Forth, you can build the text according to the following grammar; these  stacks and types.
 rules are normally all Forth you need for using vmgen:  
   If you do not know (and do not want to learn) Forth, you can build the
   text according to the following grammar; these 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|set-flag
   
 stack-decl: "stack " ident ident ident  stack-decl: 'stack ' ident ident ident
 type-prefix-decl:   type-prefix-decl: 
     's" ' string '" ' ("single"|"double") ident "type-prefix" ident      's" ' string '" ' ('single'|'double') ident 'type-prefix' ident
 stack-prefix-decl:  ident "stack-prefix" string  stack-prefix-decl:  ident 'stack-prefix' string
   set-flag: ('store-optimization'|'include-skipped-insts') ('on'|'off')
 @end example  @end example
   
 Note that the syntax of this code is not checked thoroughly (there are  Note that the syntax of this code is not checked thoroughly (there are
 many other Forth program fragments that could be written there).  many other Forth program fragments that could be written in an
   eval-escape).
   
   A stack prefix can contain letters, digits, or @samp{:}, and may start
   with an @samp{#}; e.g., in Gforth the return stack has the stack prefix
   @samp{R:}.  This restriction is not checked during the stack prefix
   definition, but it is enforced by the parsing rules for stack items
   later.
   
 If you know Forth, the stack effects of the non-standard words involved  If you know Forth, the stack effects of the non-standard words involved
 are:  are:
   @findex stack
 @example  @findex type-prefix
 stack        ( "name" "pointer" "type" -- )  @findex single
              ( name execution: -- stack )  @findex double
 type-prefix  ( addr u xt1 xt2 n stack "prefix" -- )  @findex stack-prefix
 single       ( -- xt1 xt2 n )  @findex store-optimization
 double       ( -- xt1 xt2 n )  @example
 stack-prefix ( stack "prefix" -- )  stack                 ( "name" "pointer" "type" -- )
                         ( name execution: -- stack )
   type-prefix           ( addr u item-size stack "prefix" -- )
   single                ( -- item-size )
   double                ( -- item-size )
   stack-prefix          ( stack "prefix" -- )
   store-optimization    ( -- addr )
   include-skipped-insts ( -- addr )
 @end example  @end example
   
   An @var{item-size} takes three cells on the stack.
   
   @c --------------------------------------------------------------------
   @node Simple instructions, Superinstructions, Input File Grammar, Input File Format
 @section Simple instructions  @section Simple instructions
   @cindex simple VM instruction
   @cindex instruction, simple VM
   
 We will use the following simple VM instruction description as example:  We will use the following simple VM instruction description as example:
   
Line 486  its stack effect (@code{i1 i2 -- i}).  T Line 768  its stack effect (@code{i1 i2 -- i}).  T
 just plain C code.  just plain C code.
   
 @cindex stack effect  @cindex stack effect
   @cindex effect, stack
 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}
 the rightmost item (@code{i2}) taken from the top of stack) and later  (with the rightmost item (@code{i2}) taken from the top of stack;
 pushes one integer (@code{i)) on the data stack (the rightmost item is  intuition: if you push @code{i1}, then @code{i2} on the stack, the
 on the top afterwards).  resulting stack picture is @code{i1 i2}) and later pushes one integer
   (@code{i}) on the data stack (the rightmost item is on the top
   afterwards).
   
   @cindex prefix, type
   @cindex type prefix
   @cindex default stack of a type prefix
 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
 prefixes, similar to Fortran; in contrast to Fortran, you have to  prefixes, similar to Fortran; in contrast to Fortran, you have to
 define the prefix first:  define the prefix first:
Line 505  This defines the prefix @code{i} to refe Line 793  This defines the prefix @code{i} to refe
 @code{data-stack}.  It also specifies that this type takes one stack  @code{data-stack}.  It also specifies that this type takes one stack
 item (@code{single}).  The type prefix is part of the variable name.  item (@code{single}).  The type prefix is part of the variable name.
   
   @cindex stack definition
   @cindex defining a stack
 Before we can use @code{data-stack} in this way, we have to define it:  Before we can use @code{data-stack} in this way, we have to define it:
   
 @example  @example
Line 512  Before we can use @code{data-stack} in t Line 802  Before we can use @code{data-stack} in t
 @end example  @end example
 @c !! use something other than Cell  @c !! use something other than Cell
   
   @cindex stack basic type
   @cindex basic type of a stack
   @cindex type of a stack, basic
 This line defines the stack @code{data-stack}, which uses the stack  This line defines the stack @code{data-stack}, which uses the stack
 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 cast from and to
 to Cells on accessing the @code{data-stack) with conversion macros  Cells on accessing the @code{data-stack} with type cast macros
 (@pxref{Conversion macros}).  Stacks grow towards lower addresses in  (@pxref{VM engine}).  By default, stacks grow towards lower addresses in
 vmgen-erated interpreters.  Vmgen-erated interpreters (@pxref{Stack growth direction}).
   
   @cindex stack prefix
   @cindex prefix, stack
 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 541  This definition defines that the stack p Line 836  This definition defines that the stack p
 little differently than an ordinary stack, it is predefined, and you do  little differently than an ordinary stack, it is predefined, and you do
 not need to define it.  not need to define it.
   
   @cindex instruction stream
 The instruction stream contains instructions and their immediate  The instruction stream contains instructions and their immediate
 arguments, so specifying that an argument comes from the instruction  arguments, so specifying that an argument comes from the instruction
 stream indicates an immediate argument.  Of course, instruction stream  stream indicates an immediate argument.  Of course, instruction stream
Line 548  arguments can only appear to the left of Line 844  arguments can only appear to the left of
 If there are multiple instruction stream arguments, the leftmost is the  If there are multiple instruction stream arguments, the leftmost is the
 first one (just as the intuition suggests).  first one (just as the intuition suggests).
   
 @subsubsection C Code Macros  @menu
   * C Code Macros::               Macros recognized by Vmgen
   * C Code restrictions::         Vmgen makes assumptions about C code
   * Stack growth direction::      is configurable per stack
   @end menu
   
   @c --------------------------------------------------------------------
   @node C Code Macros, C Code restrictions, Simple instructions, Simple instructions
   @subsection C Code Macros
   @cindex macros recognized by Vmgen
   @cindex basic block, VM level
   
 Vmgen recognizes the following strings in the C code part of simple  Vmgen recognizes the following strings in the C code part of simple
 instructions:  instructions:
   
 @table @samp  @table @code
   
 @item SET_IP  @item SET_IP
 As far as vmgen is concerned, a VM instruction containing this ends a VM  @findex SET_IP
   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.
   
 @item SUPER_END  @item SUPER_END
 This ends a basic block (for profiling), without a SET_IP.  @findex SUPER_END
   This ends a basic block (for profiling), even if the instruction
 @item TAIL;  contains no @code{SET_IP}.
 Vmgen replaces @samp{TAIL;} with code for ending a VM instruction and  
 dispatching the next VM instruction.  This happens automatically when  @item INST_TAIL;
 control reaches the end of the C code.  If you want to have this in the  @findex INST_TAIL;
 middle of the C code, you need to use @samp{TAIL;}.  A typical example  Vmgen replaces @samp{INST_TAIL;} with code for ending a VM instruction and
 is a conditional VM branch:  dispatching the next VM instruction.  Even without a @samp{INST_TAIL;} this
   happens automatically when control reaches the end of the C code.  If
 @example  you want to have this in the middle of the C code, you need to use
 if (branch_condition) {  @samp{INST_TAIL;}.  A typical example is a conditional VM branch:
   SET_IP(target); TAIL;  
 }  @example
   if (branch_condition) @{
     SET_IP(target); INST_TAIL;
   @}
 /* implicit tail follows here */  /* implicit tail follows here */
 @end example  @end example
   
 In this example, @samp{TAIL;} is not strictly necessary, because there  In this example, @samp{INST_TAIL;} is not strictly necessary, because there
 is another one implicitly after the if-statement, but using it improves  is another one implicitly after the if-statement, but using it improves
 branch prediction accuracy slightly and allows other optimizations.  branch prediction accuracy slightly and allows other optimizations.
   
 @item SUPER_CONTINUE  @item SUPER_CONTINUE
   @findex SUPER_CONTINUE
 This indicates that the implicit tail at the end of the VM instruction  This indicates that the implicit tail at the end of the VM instruction
 dispatches the sequentially next VM instruction even if there is a  dispatches the sequentially next VM instruction even if there is a
 @code{SET_IP} in the VM instruction.  This enables an optimization that  @code{SET_IP} in the VM instruction.  This enables an optimization that
Line 589  is not yet implemented in the vmgen-ex c Line 900  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); INST_TAIL; /* now this INST_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{RESET_IP;} as @samp{SET_IP;}).  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.
   
   
 @subsubsection C Code restrictions  @c --------------------------------------------------------------------
   @node C Code restrictions, Stack growth direction, C Code Macros, Simple instructions
   @subsection C Code restrictions
   @cindex C code restrictions
   @cindex restrictions on C code
   @cindex assumptions about C code
   
   @cindex accessing stack (pointer)
   @cindex stack pointer, access
   @cindex instruction pointer, access
 Vmgen generates code and performs some optimizations under the  Vmgen generates code and performs some optimizations under the
 assumption that the user-supplied C code does not access the stack  assumption that the user-supplied C code does not access the stack
 pointers or stack items, and that accesses to the instruction pointer  pointers or stack items, and that accesses to the instruction pointer
Line 616  the following. Line 935  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: 
   @cindex stack caching, restriction on C code
   @cindex superinstructions, restrictions on components
   
 @itemize  @itemize @bullet
   
 @item  @item
 You may cache the top-of-stack item in a local variable (that is  Vmgen optionally supports caching the top-of-stack item in a local
 allocated to a register).  This is the most frequent source of trouble.  variable (that is allocated to a register).  This is the most frequent
 You can deal with it either by not using top-of-stack caching (slowdown  source of trouble.  You can deal with it either by not using
 factor 1-1.4, depending on machine), or by inserting flushing code  top-of-stack caching (slowdown factor 1-1.4, depending on machine), or
 (e.g., @samp{IF_spTOS(sp[...] = spTOS);}) at the start and reloading  by inserting flushing code (e.g., @samp{IF_spTOS(sp[...] = spTOS);}) at
 code (e.g., @samp{IF_spTOS(spTOS = sp[0])}) at the end of problematic C  the start and reloading code (e.g., @samp{IF_spTOS(spTOS = sp[0])}) at
 code.  Vmgen inserts a stack pointer update before the start of the  the end of problematic C code.  Vmgen inserts a stack pointer update
 user-supplied C code, so the flushing code has to use an index that  before the start of the user-supplied C code, so the flushing code has
 corrects for that.  In the future, this flushing may be done  to use an index that corrects for that.  In the future, this flushing
 automatically by mentioning a special string in the C code.  may be done automatically by mentioning a special string in the C code.
 @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
 will not affact the variables, and your write may be overwritten by the  will not affect the variables, and your write may be overwritten by the
 stores after the C code.  Similarly, a read from a stack using a stack  stores after the C code.  Similarly, a read from a stack using a stack
 pointer will not reflect computations of stack items in the same VM  pointer will not reflect computations of stack items in the same VM
 instruction.  instruction.
Line 645  instruction. Line 966  instruction.
 @item  @item
 Superinstructions keep stack items in variables across the whole  Superinstructions keep stack items in variables across the whole
 superinstruction.  So you should not include VM instructions, that  superinstruction.  So you should not include VM instructions, that
 access a stack or stack pointer, as components of superinstructions.  access a stack or stack pointer, as components of superinstructions
   (@pxref{VM profiler}).
   
 @end itemize  @end itemize
   
Line 655  macros can be implemented in several way Line 977  macros can be implemented in several way
 @samp{IP} points to the next instruction, and @samp{IPTOS} is its  @samp{IP} points to the next instruction, and @samp{IPTOS} is its
 contents.  contents.
   
   @c --------------------------------------------------------------------
   @node Stack growth direction,  , C Code restrictions, Simple instructions
   @subsection Stack growth direction
   @cindex stack growth direction
   
   @cindex @code{stack-access-transform}
   By default, the stacks grow towards lower addresses.  You can change
   this for a stack by setting the @code{stack-access-transform} field of
   the stack to an xt @code{( itemnum -- index )} that performs the
   appropriate index transformation.
   
   E.g., if you want to let @code{data-stack} grow towards higher
   addresses, with the stack pointer always pointing just beyond the
   top-of-stack, use this right after defining @code{data-stack}:
   
   @example
   \E : sp-access-transform ( itemnum -- index ) negate 1- ;
   \E ' sp-access-transform ' data-stack >body stack-access-transform !
   @end example
   
   This means that @code{sp-access-transform} will be used to generate
   indexes for accessing @code{data-stack}.  The definition of
   @code{sp-access-transform} above transforms n into -n-1, e.g, 1 into -2.
   This will access the 0th data-stack element (top-of-stack) at sp[-1],
   the 1st at sp[-2], etc., which is the typical way upward-growing
   stacks are used.  If you need a different transform and do not know
   enough Forth to program it, let me know.
   
   @c --------------------------------------------------------------------
   @node Superinstructions, Store Optimization, Simple instructions, Input File Format
 @section Superinstructions  @section Superinstructions
   @cindex superinstructions, defining
   @cindex defining 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 (preliminary results indicate only a factor
   1.1 speedup).
   
 Here is an example of a superinstruction definition:  Here is an example of a superinstruction definition:
   
Line 674  lit_sub = lit sub Line 1028  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}).
   
   @cindex prefixes of superinstructions
 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
   
 @example  @example
 sumof5 = add add add add  foo4 = load add sub mul
 @end example  @end example
   
 you first have to define  you first have to define @code{load}, @code{add}, @code{sub} and
   @code{mul}, plus
   
 @example  @example
 add ( n1 n2 -- n )  foo2 = load add
 n = n1+n2;  foo3 = load add sub
   
 sumof3 = add add  
 sumof4 = add add add  
 @end example  @end example
   
 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 where your C code changes the instruction pointer should
 last component; a VM instruction that accesses a stack pointer should  only be used as last component; a VM instruction where your C code
 not be used as component at all.  Vmgen does not check these  accesses a stack pointer should not be used as component at all.  Vmgen
 restrictions, they just result in bugs in your interpreter.  does not check these restrictions, they just result in bugs in your
   interpreter.
   
   @cindex include-skipped-insts
   The Vmgen flag @code{include-skipped-insts} influences superinstruction
   code generation.  Currently there is no support in the peephole
   optimizer for both variations, so leave this flag alone for now.
   
   @c -------------------------------------------------------------------
   @node  Store Optimization, Register Machines, Superinstructions, Input File Format
   @section Store Optimization
   @cindex store optimization
   @cindex optimization, stack stores
   @cindex stack stores, optimization
   @cindex eliminating stack stores
   
   This minor optimization (0.6\%--0.8\% reduction in executed instructions
   for Gforth) puts additional requirements on the instruction descriptions
   and is therefore disabled by default.
   
   What does it do?  Consider an instruction like
   
   @example
   dup ( n -- n n )
   @end example
   
   For simplicity, also assume that we are not caching the top-of-stack in
   a register.  Now, the C code for dup first loads @code{n} from the
   stack, and then stores it twice to the stack, one time to the address
   where it came from; that time is unnecessary, but gcc does not optimize
   it away, so vmgen can do it instead (if you turn on the store
   optimization).
   
   Vmgen uses the stack item's name to determine if the stack item contains
   the same value as it did at the start.  Therefore, if you use the store
   optimization, you have to ensure that stack items that have the same
   name on input and output also have the same value, and are not changed
   in the C code you supply.  I.e., the following code could fail if you
   turn on the store optimization:
   
   @example
   add1 ( n -- n )
   n++;
   @end example
   
   Instead, you have to use different names, i.e.:
   
   @example
   add1 ( n1 -- n1 )
   n2=n1+1;
   @end example
   
   Similarly, the store optimization assumes that the stack pointer is only
   changed by Vmgen-erated code.  If your C code changes the stack pointer,
   use different names in input and output stack items to avoid a (probably
   wrong) store optimization, or turn the store optimization off for this
   VM instruction.
   
   To turn on the store optimization, write
   
   @example
   \E store-optimization on
   @end example
   
   at the start of the file.  You can turn this optimization on or off
   between any two VM instruction descriptions.  For turning it off again,
   you can use
   
   @example
   \E store-optimization off
   @end example
   
   @c -------------------------------------------------------------------
   @node Register Machines,  , Store Optimization, Input File Format
   @section Register Machines
   @cindex Register VM
   @cindex Superinstructions for register VMs
   @cindex tracing of register VMs
   
   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
   
   A disadvantage of this method is that during tracing you only see the
   register numbers, but not the register contents.  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.
   
   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.  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 ********************************************************************
 @chapter Using the generated code  @node Error messages, Using the generated code, Input File Format, Top
   @chapter Error messages
   @cindex error messages
   
   These error messages are created by Vmgen:
   
   @table @code
   
   @cindex @code{# can only be on the input side} error
   @item # can only be on the input side
   You have used an instruction-stream prefix (usually @samp{#}) after the
   @samp{--} (the output side); you can only use it before (the input
   side).
   
   @cindex @code{prefix for this combination must be defined earlier} error
   @item the prefix for this superinstruction must be defined earlier
   You have defined a superinstruction (e.g. @code{abc = a b c}) without
   defining its direct prefix (e.g., @code{ab = a b}),
   @xref{Superinstructions}.
   
   @cindex @code{sync line syntax} error
   @item sync line syntax
   If you are using a preprocessor (e.g., @command{m4}) to generate Vmgen
   input code, you may want to create @code{#line} directives (aka sync
   lines).  This error indicates that such a line is not in th syntax
   expected by Vmgen (this should not happen; please report the offending
   line in a bug report).
   
   @cindex @code{syntax error, wrong char} error
   @item syntax error, wrong char
   A syntax error.  If you do not see right away where the error is, it may
   be helpful to check the following: Did you put an empty line in a VM
   instruction where the C code is not delimited by braces (then the empty
   line ends the VM instruction)?  If you used brace-delimited C code, did
   you put the delimiting braces (and only those) at the start of the line,
   without preceding white space?  Did you forget a delimiting brace?
   
   @cindex @code{too many stacks} error
   @item too many stacks
   Vmgen currently supports 3 stacks (plus the instruction stream); if you
   need more, let us know.
   
   @cindex @code{unknown prefix} error
   @item unknown prefix
   The stack item does not match any defined type prefix (after stripping
   away any stack prefix).  You should either declare the type prefix you
   want for that stack item, or use a different type prefix
   
   @cindex @code{unknown primitive} error
   @item unknown primitive
   You have used the name of a simple VM instruction in a superinstruction
   definition without defining the simple VM instruction first.
   
   @end table
   
   In addition, the C compiler can produce errors due to code produced by
   Vmgen; e.g., you need to define type cast functions.
   
 The easiest way to create a working VM interpreter with vmgen is  @c ********************************************************************
 probably to start with one of the examples, and modify it for your  @node Using the generated code, Hints, Error messages, Top
 purposes.  This chapter is just the reference manual for the macros  @chapter Using the generated code
 etc. used by the generated code, and the other context expected by the  @cindex generated code, usage
 generated code, and what you can do with the various generated files.  @cindex Using vmgen-erated code
   
   The easiest way to create a working VM interpreter with Vmgen is
   probably to start with @file{vmgen-ex}, and modify it for your purposes.
   This chapter explains what the various wrapper and generated files do.
   It also contains reference-manual style descriptions of the macros,
   variables etc. used by the generated code, and you can skip that on
   first reading.
   
   @menu
   * VM engine::                   Executing VM code
   * VM instruction table::        
   * VM code generation::          Creating VM code (in the front-end)
   * Peephole optimization::       Creating VM superinstructions
   * VM disassembler::             for debugging the front end
   * VM profiler::                 for finding worthwhile superinstructions
   @end menu
   
   @c --------------------------------------------------------------------
   @node VM engine, VM instruction table, Using the generated code, Using the generated code
 @section VM engine  @section VM engine
   @cindex VM instruction execution
   @cindex engine
   @cindex executing VM code
   @cindex @file{engine.c}
   @cindex @file{-vm.i} output file
   
 The VM engine is the VM interpreter that executes the VM code.  It is  The VM engine is the VM interpreter that executes the VM code.  It is
 essential for an interpretive system.  essential for an interpretive system.
Line 737  macros and variables used in the engine, Line 1293  macros and variables used in the engine,
 In our example the engine function also includes  In our example the engine function also includes
 @file{@var{name}-labels.i} (@pxref{VM instruction table}).  @file{@var{name}-labels.i} (@pxref{VM instruction table}).
   
   @cindex tracing VM code
   @cindex superinstructions and tracing
   In addition to executing the code, the VM engine can optionally also
   print out a trace of the executed instructions, their arguments and
   results.  For superinstructions it prints the trace as if only component
   instructions were executed; this allows to introduce new
   superinstructions while keeping the traces comparable to old ones
   (important for regression tests).
   
   It costs significant performance to check in each instruction whether to
   print tracing code, so we recommend producing two copies of the engine:
   one for fast execution, and one for tracing.  See the rules for
   @file{engine.o} and @file{engine-debug.o} in @file{vmgen-ex/Makefile}
   for an example.
   
 The following macros and variables are used in @file{@var{name}-vm.i}:  The following macros and variables are used in @file{@var{name}-vm.i}:
   
 @table @code  @table @code
   
   @findex LABEL
 @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{@var{label}:}.
 @var{label}}.  In either case @var{label} is usually the @var{inst_name}  In either case @var{label} is usually the @var{inst_name} with some
 with some prefix or suffix to avoid naming conflicts.  prefix or suffix to avoid naming conflicts.
   
   @findex LABEL2
   @item LABEL2(@var{inst_name})
   This will be used for dynamic superinstructions; at the moment, this
   should expand to nothing.
   
   @findex NAME
 @item NAME(@var{inst_name_string})  @item NAME(@var{inst_name_string})
 Called on entering a VM instruction with a string containing the name of  Called on entering a VM instruction with a string containing the name of
 the VM instruction as parameter.  In normal execution this should be a  the VM instruction as parameter.  In normal execution this should be
 noop, but for tracing this usually prints the name, and possibly other  expand to nothing, but for tracing this usually prints the name, and
 information (several VM registers in our example).  possibly other information (several VM registers in our example).
   
   @findex DEF_CA
 @item DEF_CA  @item DEF_CA
 Usually empty.  Called just inside a new scope at the start of a VM  Usually empty.  Called just inside a new scope at the start of a VM
 instruction.  Can be used to define variables that should be visible  instruction.  Can be used to define variables that should be visible
 during every VM instruction.  If you define this macro as non-empty, you  during every VM instruction.  If you define this macro as non-empty, you
 have to provide the finishing @samp{;} in the macro.  have to provide the finishing @samp{;} in the macro.
   
   @findex NEXT_P0
   @findex NEXT_P1
   @findex NEXT_P2
 @item NEXT_P0 NEXT_P1 NEXT_P2  @item NEXT_P0 NEXT_P1 NEXT_P2
 The three parts of instruction dispatch.  They can be defined in  The three parts of instruction dispatch.  They can be defined in
 different ways for best performance on various processors (see  different ways for best performance on various processors (see
 @file{engine.c} in the example or @file{engine/threaded.h} in Gforth).  @file{engine.c} in the example or @file{engine/threaded.h} in Gforth).
 @samp{NEXT_P0} is invoked right at the start of the VM isntruction (but  @samp{NEXT_P0} is invoked right at the start of the VM instruction (but
 after @samp{DEF_CA}), @samp{NEXT_P1} right after the user-supplied C  after @samp{DEF_CA}), @samp{NEXT_P1} right after the user-supplied C
 code, and @samp{NEXT_P2} at the end.  The actual jump has to be  code, and @samp{NEXT_P2} at the end.  The actual jump has to be
 performed by @samp{NEXT_P2}.  performed by @samp{NEXT_P2} (if you would do it earlier, important parts
   of the VM instruction would not be executed).
   
 The simplest variant is if @samp{NEXT_P2} does everything and the other  The simplest variant is if @samp{NEXT_P2} does everything and the other
 macros do nothing.  Then also related macros like @samp{IP},  macros do nothing.  Then also related macros like @samp{IP},
 @samp{SET_IP}, @samp{IP}, @samp{INC_IP} and @samp{IPTOS} are very  @samp{SET_IP}, @samp{IP}, @samp{INC_IP} and @samp{IPTOS} are very
 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
 @samp{NEXT_P0} usually requires changing the other macros (and, at least  @samp{NEXT_P0} usually requires changing the other macros (and, at least
 for Gforth on Alpha, it does not buy much, because the compiler often  for Gforth on Alpha, it does not buy much, because the compiler often
Line 786  manages to schedule the relevant stuff u Line 1369  manages to schedule the relevant stuff u
 extreme variant is to pull code up even further, into, e.g., NEXT_P1 of  extreme variant is to pull code up even further, into, e.g., NEXT_P1 of
 the previous VM instruction (prefetching, useful on PowerPCs).  the previous VM instruction (prefetching, useful on PowerPCs).
   
   @findex INC_IP
 @item INC_IP(@var{n})  @item INC_IP(@var{n})
 This increments @code{IP} by @var{n}.  This increments @code{IP} by @var{n}.
   
   @findex SET_IP
 @item SET_IP(@var{target})  @item SET_IP(@var{target})
 This sets @code{IP} to @var{target}.  This sets @code{IP} to @var{target}.
   
   @cindex type cast macro
   @findex vm_@var{A}2@var{B}
 @item vm_@var{A}2@var{B}(a,b)  @item vm_@var{A}2@var{B}(a,b)
 Type casting macro that assigns @samp{a} (of type @var{A}) to @samp{b}  Type casting macro that assigns @samp{a} (of type @var{A}) to @samp{b}
 (of type @var{B}).  This is mainly used for getting stack items into  (of type @var{B}).  This is mainly used for getting stack items into
Line 800  of stack basic type (@code{Cell} in our Line 1387  of stack basic type (@code{Cell} in our
 used with that stack (in both directions).  For the type-prefix type,  used with that stack (in both directions).  For the type-prefix type,
 you use the type-prefix (not the C type string) as type name (e.g.,  you use the type-prefix (not the C type string) as type name (e.g.,
 @samp{vm_Cell2i}, not @samp{vm_Cell2Cell}).  In addition, you have to  @samp{vm_Cell2i}, not @samp{vm_Cell2Cell}).  In addition, you have to
 define a vm_@var{X}2@var{X} macro for the stack basic type (used in  define a vm_@var{X}2@var{X} macro for the stack's basic type @var{X}
 superinstructions).  (used in superinstructions).
   
   @cindex instruction stream, basic type
 The stack basic type for the predefined @samp{inst-stream} is  The stack basic type for the predefined @samp{inst-stream} is
 @samp{Cell}.  If you want a stack with the same item size, making its  @samp{Cell}.  If you want a stack with the same item size, making its
 basic type @samp{Cell} usually reduces the number of macros you have to  basic type @samp{Cell} usually reduces the number of macros you have to
 define.  define.
   
   @cindex unions in type cast macros
   @cindex casts in type cast macros
   @cindex type casting between floats and integers
 Here our examples differ a lot: @file{vmgen-ex} uses casts in these  Here our examples differ a lot: @file{vmgen-ex} uses casts in these
 macros, whereas @file{vmgen-ex2} uses union-field selection (or  macros, whereas @file{vmgen-ex2} uses union-field selection (or
 assignment to union fields).  assignment to union fields).  Note that casting floats into integers and
   vice versa changes the bit pattern (and you do not want that).  In this
   case your options are to use a (temporary) union, or to take the address
   of the value, cast the pointer, and dereference that (not always
   possible, and sometimes expensive).
   
   @findex vm_two@var{A}2@var{B}
   @findex vm_@var{B}2two@var{A}
 @item vm_two@var{A}2@var{B}(a1,a2,b)  @item vm_two@var{A}2@var{B}(a1,a2,b)
 @item vm_@var{B}2two@var{A}(b,a1,a2)  @item vm_@var{B}2two@var{A}(b,a1,a2)
 Conversions between two stack items (@code{a1}, @code{a2}) and a  Type casting between two stack items (@code{a1}, @code{a2}) and a
 variable @code{b} of a type that takes two stack items.  This does not  variable @code{b} of a type that takes two stack items.  This does not
 occur in our small examples, but you can look at Gforth for examples.  occur in our small examples, but you can look at Gforth for examples
   (see @code{vm_twoCell2d} in @file{engine/forth.h}).
   
   @cindex stack pointer definition
   @cindex instruction pointer definition
 @item @var{stackpointer}  @item @var{stackpointer}
 For each stack used, the stackpointer name given in the stack  For each stack used, the stackpointer name given in the stack
 declaration is used.  For a regular stack this must be an l-expression;  declaration is used.  For a regular stack this must be an l-expression;
 typically it is a variable declared as a pointer to the stack's basic  typically it is a variable declared as a pointer to the stack's basic
 type.  For @samp{inst-stream}, the name is @samp{IP}, and it can be a  type.  For @samp{inst-stream}, the name is @samp{IP}, and it can be a
 plain r-value; typically it is a macro that abstracts away the  plain r-value; typically it is a macro that abstracts away the
 differences between the various implementations of NEXT_P*.  differences between the various implementations of @code{NEXT_P*}.
   
   @cindex IMM_ARG
   @findex IMM_ARG
   @item IMM_ARG(access,value)
   Define this to expland to ``(access)''.  This is just a placeholder for
   future extensions.
   
   @cindex top of stack caching
   @cindex stack caching
   @cindex TOS
   @findex IPTOS
 @item @var{stackpointer}TOS  @item @var{stackpointer}TOS
 The top-of-stack for the stack pointed to by @var{stackpointer}.  If you  The top-of-stack for the stack pointed to by @var{stackpointer}.  If you
 are using top-of-stack caching for that stack, this should be defined as  are using top-of-stack caching for that stack, this should be defined as
Line 834  should be a macro expanding to @samp{@va Line 1444  should be a macro expanding to @samp{@va
 pointer for the predefined @samp{inst-stream} is called @samp{IP}, so  pointer for the predefined @samp{inst-stream} is called @samp{IP}, so
 the top-of-stack is called @samp{IPTOS}.  the top-of-stack is called @samp{IPTOS}.
   
   @findex IF_@var{stackpointer}TOS
 @item IF_@var{stackpointer}TOS(@var{expr})  @item IF_@var{stackpointer}TOS(@var{expr})
 Macro for executing @var{expr}, if top-of-stack caching is used for the  Macro for executing @var{expr}, if top-of-stack caching is used for the
 @var{stackpointer} stack.  I.e., this should do @var{expr} if there is  @var{stackpointer} stack.  I.e., this should do @var{expr} if there is
 top-of-stack caching for @var{stackpointer}; otherwise it should do  top-of-stack caching for @var{stackpointer}; otherwise it should do
 nothing.  nothing.
   
   @findex SUPER_END
 @item SUPER_END  @item SUPER_END
 This is used by the VM profiler (@pxref{VM profiler}); it should not do  This is used by the VM profiler (@pxref{VM profiler}); it should not do
 anything in normal operation, and call @code{vm_count_block(IP)} for  anything in normal operation, and call @code{vm_count_block(IP)} for
 profiling.  profiling.
   
   @findex SUPER_CONTINUE
 @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.
   
   @findex VM_DEBUG
 @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
 interpretation, but better debugging).  Our example compiles two  interpretation, but better debugging).  Our example compiles two
 versions of the engine, a fast-running one that cannot trace, and one  versions of the engine, a fast-running one that cannot trace, and one
 with potential tracing and profiling.  with potential tracing and profiling.
   
   @findex vm_debug
 @item vm_debug  @item vm_debug
 Needed only if @samp{VM_DEBUG} is defined.  If this variable contains  Needed only if @samp{VM_DEBUG} is defined.  If this variable contains
 true, the VM instructions produce trace output.  It can be turned on or  true, the VM instructions produce trace output.  It can be turned on or
 off at any time.  off at any time.
   
   @findex vm_out
 @item vm_out  @item vm_out
 Needed only if @samp{VM_DEBUG} is defined.  Specifies the file on which  Needed only if @samp{VM_DEBUG} is defined.  Specifies the file on which
 to print the trace output (type @samp{FILE *}).  to print the trace output (type @samp{FILE *}).
   
   @findex printarg_@var{type}
 @item printarg_@var{type}(@var{value})  @item printarg_@var{type}(@var{value})
 Needed only if @samp{VM_DEBUG} is defined.  Macro or function for  Needed only if @samp{VM_DEBUG} is defined.  Macro or function for
 printing @var{value} in a way appropriate for the @var{type}.  This is  printing @var{value} in a way appropriate for the @var{type}.  This is
Line 874  basic type of the stack. Line 1491  basic type of the stack.
 @end table  @end table
   
   
 @section{VM instruction table}  @c --------------------------------------------------------------------
   @node VM instruction table, VM code generation, VM engine, Using the generated code
   @section VM instruction table
   @cindex instruction table
   @cindex opcode definition
   @cindex labels for threaded code
   @cindex @code{vm_prim}, definition
   @cindex @file{-labels.i} output file
   
 For threaded code we also need to produce a table containing the labels  For threaded code we also need to produce a table containing the labels
 of all VM instructions.  This is needed for VM code generation  of all VM instructions.  This is needed for VM code generation
Line 892  then the table is passed out, otherwise Line 1516  then the table is passed out, otherwise
 example, we pass the table out by assigning it to @samp{vm_prim} and  example, we pass the table out by assigning it to @samp{vm_prim} and
 returning from @samp{engine}.  returning from @samp{engine}.
   
 In our example, we also build such a table for switch dispatch; this is  In our example (@file{vmgen-ex/engine.c}), we also build such a table for
 mainly done for uniformity.  switch dispatch; this is mainly done for uniformity.
   
 For switch dispatch, we also need to define the VM instruction opcodes  For switch dispatch, we also need to define the VM instruction opcodes
 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 @code
   
   @findex INST_ADDR
 @item INST_ADDR(@var{inst_name})  @item INST_ADDR(@var{inst_name})
 For switch dispatch, this is just the name of the switch label (the same  For switch dispatch, this is just the name of the switch label (the same
 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
   
   
   @c --------------------------------------------------------------------
   @node VM code generation, Peephole optimization, VM instruction table, Using the generated code
 @section VM code generation  @section VM code generation
   @cindex VM code generation
   @cindex code generation, VM
   @cindex @file{-gen.i} output file
   
 Vmgen generates VM code generation functions in @file{@var{name}-gen.i}  Vmgen generates VM code generation functions in @file{@var{name}-gen.i}
 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  @findex gen_@var{inst}
   For a VM instruction @samp{x ( #a b #c -- d )}, Vmgen generates a
 function with the prototype  function with the prototype
   
 @example  @example
Line 932  The @code{ctp} argument points to a poin Line 1564  The @code{ctp} argument points to a poin
 allocate memory for the code to be generated beforehand, and start with  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  *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  memory, allocate a new area, and generate a VM-level jump to the new
 area (this is not implemented in our examples).  area (this overflow handling is not implemented in our examples).
   
   @cindex immediate arguments, VM code generation
 The other arguments correspond to the immediate arguments of the VM  The other arguments correspond to the immediate arguments of the VM
 instruction (with their appropriate types as defined in the  instruction (with their appropriate types as defined in the
 @code{type_prefix} declaration.  @code{type_prefix} declaration.
Line 941  instruction (with their appropriate type Line 1574  instruction (with their appropriate type
 The following types, variables, and functions are used in  The following types, variables, and functions are used in
 @file{@var{name}-gen.i}:  @file{@var{name}-gen.i}:
   
 @table @samp  @table @code
   
   @findex Inst
 @item Inst  @item Inst
 The type of the VM instruction; if you use threaded code, this is  The type of the VM instruction; if you use threaded code, this is
 @code{void *}; for switch dispatch this is an integer type.  @code{void *}; for switch dispatch this is an integer type.
   
   @cindex @code{vm_prim}, use
 @item vm_prim  @item vm_prim
 The VM instruction table (type: @code{Inst *}, @pxref{VM instruction table}).  The VM instruction table (type: @code{Inst *}, @pxref{VM instruction table}).
   
   @findex gen_inst
 @item gen_inst(Inst **ctp, Inst i)  @item gen_inst(Inst **ctp, Inst i)
 This function compiles the instruction @code{i}.  Take a look at it in  This function compiles the instruction @code{i}.  Take a look at it in
 @file{vmgen-ex/peephole.c}.  It is trivial when you don't want to use  @file{vmgen-ex/peephole.c}.  It is trivial when you don't want to use
Line 957  superinstructions (just the last two lin Line 1593  superinstructions (just the last two lin
 slightly more complicated in the example due to its ability to use  slightly more complicated in the example due to its ability to use
 superinstructions (@pxref{Peephole optimization}).  superinstructions (@pxref{Peephole optimization}).
   
   @findex genarg_@var{type_prefix}
 @item genarg_@var{type_prefix}(Inst **ctp, @var{type} @var{type_prefix})  @item genarg_@var{type_prefix}(Inst **ctp, @var{type} @var{type_prefix})
 This compiles an immediate argument of @var{type} (as defined in a  This compiles an immediate argument of @var{type} (as defined in a
 @code{type-prefix} definition).  These functions are trivial to define  @code{type-prefix} definition).  These functions are trivial to define
Line 965  every type that you use as immediate arg Line 1602  every type that you use as immediate arg
   
 @end table  @end table
   
   @findex BB_BOUNDARY
 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; but this support is also useful mainly for selecting
 If you use @code{BB_BOUNDARY}, you should also define it (take a look at  superinstructions).  If you use @code{BB_BOUNDARY}, you should also
 its definition in @file{vmgen-ex/mini.y}).  define it (take a look at its definition in @file{vmgen-ex/mini.y}).
   
 You do not need to call @code{BB_BOUNDARY} after branches, because you  You do not need to call @code{BB_BOUNDARY} after branches, because you
 will not define superinstructions that contain branches in the middle  will not define superinstructions that contain branches in the middle
Line 979  superinstruction at the branch), and bec Line 1617  superinstruction at the branch), and bec
 themselves to the profiler.  themselves to the profiler.
   
   
   @c --------------------------------------------------------------------
   @node Peephole optimization, VM disassembler, VM code generation, Using the generated code
 @section Peephole optimization  @section Peephole optimization
   @cindex peephole optimization
   @cindex superinstructions, generating
   @cindex @file{peephole.c}
   @cindex @file{-peephole.i} output file
   
 You need peephole optimization only if you want to use  You need peephole optimization only if you want to use
 superinstructions.  But having the code for it does not hurt much if you  superinstructions.  But having the code for it does not hurt much if you
Line 987  do not use superinstructions. Line 1631  do not use superinstructions.
   
 A simple greedy peephole optimization algorithm is used for  A simple greedy peephole optimization algorithm is used for
 superinstruction selection: every time @code{gen_inst} compiles a VM  superinstruction selection: every time @code{gen_inst} compiles a VM
 instruction, it looks if it can combine it with the last VM instruction  instruction, it checks if it can combine it with the last VM instruction
 (which may also be a superinstruction resulting from a previous peephole  (which may also be a superinstruction resulting from a previous peephole
 optimization); if so, it changes the last instruction to the combined  optimization); if so, it changes the last instruction to the combined
 instruction instead of laying down @code{i} at the current @samp{*ctp}.  instruction instead of laying down @code{i} at the current @samp{*ctp}.
Line 997  You can use this file almost verbatim. Line 1641  You can use this file almost verbatim.
 @file{@var{file}-peephole.i} which contains data for the peephoile  @file{@var{file}-peephole.i} which contains data for the peephoile
 optimizer.  optimizer.
   
   @findex init_peeptable
 You have to call @samp{init_peeptable()} after initializing  You have to call @samp{init_peeptable()} after initializing
 @samp{vm_prim}, and before compiling any VM code to initialize data  @samp{vm_prim}, and before compiling any VM code to initialize data
 structures for peephole optimization.  After that, compiling with the VM  structures for peephole optimization.  After that, compiling with the VM
Line 1007  instruction to branch to), you have to c Line 1652  instruction to branch to), you have to c
 (@pxref{VM code generation}) at branch targets.  (@pxref{VM code generation}) at branch targets.
   
   
   @c --------------------------------------------------------------------
   @node VM disassembler, VM profiler, Peephole optimization, Using the generated code
 @section VM disassembler  @section VM disassembler
   @cindex VM disassembler
   @cindex disassembler, VM code
   @cindex @file{disasm.c}
   @cindex @file{-disasm.i} output file
   
 A VM code disassembler is optional for an interpretive system, but  A VM code disassembler is optional for an interpretive system, but
 highly recommended during its development and maintenance, because it is  highly recommended during its development and maintenance, because it is
Line 1016  them from VM interpreter bugs). Line 1667  them from VM interpreter bugs).
   
 Vmgen supports VM code disassembling by generating  Vmgen supports VM code disassembling by generating
 @file{@var{file}-disasm.i}.  This code has to be wrapped into a  @file{@var{file}-disasm.i}.  This code has to be wrapped into a
 function, as is done in @file{vmgen-ex/disasm.i}.  You can use this file  function, as is done in @file{vmgen-ex/disasm.c}.  You can use this file
 almost verbatim.  In addition to @samp{vm_@var{A}2@var{B}(a,b)},  almost verbatim.  In addition to @samp{vm_@var{A}2@var{B}(a,b)},
 @samp{vm_out}, @samp{printarg_@var{type}(@var{value})}, which are  @samp{vm_out}, @samp{printarg_@var{type}(@var{value})}, which are
 explained above, the following macros and variables are used in  explained above, the following macros and variables are used in
 @file{@var{file}-disasm.i} (and you have to define them):  @file{@var{file}-disasm.i} (and you have to define them):
   
 @table @samp  @table @code
   
 @item ip  @item ip
 This variable points to the opcode of the current VM instruction.  This variable points to the opcode of the current VM instruction.
   
   @cindex @code{IP}, @code{IPTOS} in disassmbler
 @item IP IPTOS  @item IP IPTOS
 @samp{IPTOS} is the first argument of the current VM instruction, and  @samp{IPTOS} is the first argument of the current VM instruction, and
 @samp{IP} points to it; this is just as in the engine, but here  @samp{IP} points to it; this is just as in the engine, but here
 @samp{ip} points to the opcode of the VM instruction (in contrast to the  @samp{ip} points to the opcode of the VM instruction (in contrast to the
 engine, where @samp{ip} points to the next cell, or even one further).  engine, where @samp{ip} points to the next cell, or even one further).
   
   @findex VM_IS_INST
 @item VM_IS_INST(Inst i, int n)  @item VM_IS_INST(Inst i, int n)
 Tests if the opcode @samp{i} is the same as the @samp{n}th entry in the  Tests if the opcode @samp{i} is the same as the @samp{n}th entry in the
 VM instruction table.  VM instruction table.
Line 1040  VM instruction table. Line 1693  VM instruction table.
 @end table  @end table
   
   
   @c --------------------------------------------------------------------
   @node VM profiler,  , VM disassembler, Using the generated code
 @section VM profiler  @section VM profiler
   @cindex VM profiler
   @cindex profiling for selecting superinstructions
   @cindex superinstructions and profiling
   @cindex @file{profile.c}
   @cindex @file{-profile.i} output file
   
 The VM profiler is designed for getting execution and occurence counts  The VM profiler is designed for getting execution and occurence counts
 for VM instruction sequences, and these counts can then be used for  for VM instruction sequences, and these counts can then be used for
Line 1062  all its subsequences; e.g., Line 1722  all its subsequences; e.g.,
 I.e., a basic block consisting of @samp{lit storelocal branch} is  I.e., a basic block consisting of @samp{lit storelocal branch} is
 executed 9227465 times.  executed 9227465 times.
   
   @cindex @file{stat.awk}
   @cindex @file{seq2rule.awk}
 This output can be combined in various ways.  E.g.,  This output can be combined in various ways.  E.g.,
 @file{vmgen/stat.awk} adds up the occurences of a given sequence wrt  @file{vmgen-ex/stat.awk} adds up the occurences of a given sequence wrt
 dynamic execution, static occurence, and per-program occurence.  E.g.,  dynamic execution, static occurence, and per-program occurence.  E.g.,
   
 @example  @example
       2      16        36910041 loadlocal lit         2      16        36910041 loadlocal lit 
 @end example  @end example
   
   @noindent
 indicates that the sequence @samp{loadlocal lit} occurs in 2 programs,  indicates that the sequence @samp{loadlocal lit} occurs in 2 programs,
 in 16 places, and has been executed 36910041 times.  Now you can select  in 16 places, and has been executed 36910041 times.  Now you can select
 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 1090  sort -k 3 >mini-super.vmg       #sort se Line 1753  sort -k 3 >mini-super.vmg       #sort se
   
 Here the dynamic count is used for selecting sequences (preliminary  Here the dynamic count is used for selecting sequences (preliminary
 results indicate that the static count gives better results, though);  results indicate that the static count gives better results, though);
 the third line eliminats sequences containing instructions that must not  the third line eliminates sequences containing instructions that must not
 occur in a superinstruction, because they access a stack directly.  The  occur in a superinstruction, because they access a stack directly.  The
 dynamic count selection ensures that all subsequences (including  dynamic count selection ensures that all subsequences (including
 prefixes) of longer sequences occur (because subsequences have at least  prefixes) of longer sequences occur (because subsequences have at least
 the same count as the longer sequences); the sort in the last line  the same count as the longer sequences); the sort in the last line
 ensures that longer superinstructions occur after their prefixes.  ensures that longer superinstructions occur after their prefixes.
   
 But before using it, you have to have the profiler.  Vmgen supports its  But before using this, you have to have the profiler.  Vmgen supports its
 creation by generating @file{@var{file}-profile.i}; you also need the  creation by generating @file{@var{file}-profile.i}; you also need the
 wrapper file @file{vmgen-ex/profile.c} that you can use almost verbatim.  wrapper file @file{vmgen-ex/profile.c} that you can use almost verbatim.
   
   @cindex @code{SUPER_END} in profiling
   @cindex @code{BB_BOUNDARY} in profiling
 The profiler works by recording the targets of all VM control flow  The profiler works by recording the targets of all VM control flow
 changes (through @code{SUPER_END} during execution, and through  changes (through @code{SUPER_END} during execution, and through
 @code{BB_BOUNDARY} in the front end), and counting (through  @code{BB_BOUNDARY} in the front end), and counting (through
 @code{SUPER_END}) how often they were targeted.  After the program run,  @code{SUPER_END}) how often they were targeted.  After the program run,
 the numbers are corrected such that each VM basic block has the correct  the numbers are corrected such that each VM basic block has the correct
 count (originally entering a block without executing a branch does not  count (entering a block without executing a branch does not increase the
 increase the count), then the subsequences of all basic blocks are  count, and the correction fixes that), then the subsequences of all
 printed.  To get all this, you just have to define @code{SUPER_END} (and  basic blocks are printed.  To get all this, you just have to define
 @code{BB_BOUNDARY}) appropriately, and call @code{vm_print_profile(FILE  @code{SUPER_END} (and @code{BB_BOUNDARY}) appropriately, and call
 *file)} when you want to output the profile on @code{file}.  @code{vm_print_profile(FILE *file)} when you want to output the profile
   on @code{file}.
   
 The @file{@var{file}-profile.i} is simular to the disassembler file, and  @cindex @code{VM_IS_INST} in profiling
   The @file{@var{file}-profile.i} is similar to the disassembler file, and
 it uses variables and functions defined in @file{vmgen-ex/profile.c},  it uses variables and functions defined in @file{vmgen-ex/profile.c},
 plus @code{VM_IS_INST} already defined for the VM disassembler  plus @code{VM_IS_INST} already defined for the VM disassembler
 (@pxref{VM disassembler}).  (@pxref{VM disassembler}).
   
   @c **********************************************************
   @node Hints, The future, Using the generated code, Top
   @chapter Hints
   @cindex hints
   
   @menu
   * Floating point::              and stacks
   @end menu
   
   @c --------------------------------------------------------------------
   @node Floating point,  , Hints, Hints
   @section Floating point
   
   How should you deal with floating point values?  Should you use the same
   stack as for integers/pointers, or a different one?  This section
   discusses this issue with a view on execution speed.
   
   The simpler approach is to use a separate floating-point stack.  This
   allows you to choose FP value size without considering the size of the
   integers/pointers, and you avoid a number of performance problems.  The
   main downside is that this needs an FP stack pointer (and that may not
   fit in the register file on the 386 arhitecture, costing some
   performance, but comparatively little if you take the other option into
   account).  If you use a separate FP stack (with stack pointer @code{fp}),
   using an fpTOS is helpful on most machines, but some spill the fpTOS
   register into memory, and fpTOS should not be used there.
   
   The other approach is to share one stack (pointed to by, say, @code{sp})
   between integer/pointer and floating-point values.  This is ok if you do
   not use @code{spTOS}.  If you do use @code{spTOS}, the compiler has to
   decide whether to put that variable into an integer or a floating point
   register, and the other type of operation becomes quite expensive on
   most machines (because moving values between integer and FP registers is
   quite expensive).  If a value of one type has to be synthesized out of
   two values of the other type (@code{double} types), things are even more
   interesting.
   
   One way around this problem would be to not use the @code{spTOS}
   supported by Vmgen, but to use explicit top-of-stack variables (one for
   integers, one for FP values), and having a kind of accumulator+stack
   architecture (e.g., Ocaml bytecode uses this approach); however, this is
   a major change, and it's ramifications are not completely clear.
   
   @c **********************************************************
   @node The future, Changes, Hints, Top
   @chapter The future
   @cindex future ideas
   
   We have a number of ideas for future versions of Vmgen.  However, there
   are so many possible things to do that we would like some feedback from
   you.  What are you doing with Vmgen, what features are you missing, and
   why?
   
   One idea we are thinking about is to generate just one @file{.c} file
   instead of letting you copy and adapt all the wrapper files (you would
   still have to define stuff like the type-specific macros, and stack
   pointers etc. somewhere).  The advantage would be that, if we change the
   wrapper files between versions, you would not need to integrate your
   changes and our changes to them; Vmgen would also be easier to use for
   beginners.  The main disadvantage of that is that it would reduce the
   flexibility of Vmgen a little (well, those who like flexibility could
   still patch the resulting @file{.c} file, like they are now doing for
   the wrapper files).  In any case, if you are doing things to the wrapper
   files that would cause problems in a generated-@file{.c}-file approach,
   please let us know.
   
   @c **********************************************************
   @node Changes, Contact, The future, Top
 @chapter Changes  @chapter Changes
   @cindex Changes from old versions
   
   User-visible changes between 0.5.9-20020822 and 0.5.9-20020901:
   
 Users of the gforth-0.5.9-20010501 version of vmgen need to change  The store optimization is now disabled by default, but can be enabled by
   the user (@pxref{Store Optimization}).  Documentation for this
   optimization is also new.
   
   User-visible changes between 0.5.9-20010501 and 0.5.9-20020822:
   
   There is now a manual (in info, HTML, Postscript, or plain text format).
   
   There is the vmgen-ex2 variant of the vmgen-ex example; the new
   variant uses a union type instead of lots of casting.
   
   Both variants of the example can now be compiled with an ANSI C compiler
   (using switch dispatch and losing quite a bit of performance); tested
   with @command{lcc}.
   
   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
Line 1130  The required changes are: Line 1883  The required changes are:
   
 @table @code  @table @code
   
   @cindex @code{TAIL;}, changes
   @item TAIL;
   has been renamed into @code{INST_TAIL;} (less chance of an accidental
   match).
   
   @cindex @code{vm_@var{A}2@var{B}}, changes
 @item vm_@var{A}2@var{B}  @item vm_@var{A}2@var{B}
 now takes two arguments.  now takes two arguments.
   
   @cindex @code{vm_two@var{A}2@var{B}}, changes
 @item vm_two@var{A}2@var{B}(b,a1,a2);  @item vm_two@var{A}2@var{B}(b,a1,a2);
 changed to vm_two@var{A}2@var{B}(a1,a2,b) (note the absence of the @samp{;}).  changed to vm_two@var{A}2@var{B}(a1,a2,b) (note the absence of the @samp{;}).
   
Line 1142  Also some new macros have to be defined, Line 1902  Also some new macros have to be defined,
 @code{LABEL}; some macros have to be defined in new contexts, e.g.,  @code{LABEL}; some macros have to be defined in new contexts, e.g.,
 @code{VM_IS_INST} is now also needed in the disassembler.  @code{VM_IS_INST} is now also needed in the disassembler.
   
   @c *********************************************************
   @node Contact, Copying This Manual, Changes, Top
 @chapter Contact  @chapter Contact
   
   To report a bug, use
   @url{https://savannah.gnu.org/bugs/?func=addbug&group_id=2672}.
   
   For discussion on Vmgen (e.g., how to use it), use the mailing list
   @email{bug-vmgen@@mail.freesoftware.fsf.org} (use
   @url{http://mail.gnu.org/mailman/listinfo/help-vmgen} to subscribe).
   
   You can find vmgen information at
   @url{http://www.complang.tuwien.ac.at/anton/vmgen/}.
   
   @c ***********************************************************
   @node Copying This Manual, Index, Contact, Top
   @appendix Copying This Manual
   
   @menu
   * GNU Free Documentation License::  License for copying this manual.
   @end menu
   
   @include fdl.texi
   
   
   @node Index,  , Copying This Manual, Top
   @unnumbered Index
   
   @printindex cp
   
   @bye

Removed from v.1.8  
changed lines
  Added in v.1.24


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>