guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 178/437: Update texinfo documentation to match current i


From: Andy Wingo
Subject: [Guile-commits] 178/437: Update texinfo documentation to match current implementation.
Date: Mon, 2 Jul 2018 05:14:12 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit 16d18f11d389ec96cf5934cea1badfd8f4b6127b
Author: pcpa <address@hidden>
Date:   Thu Jan 24 19:41:35 2013 -0200

    Update texinfo documentation to match current implementation.
    
        * check/Makefile.am: "make debug" target should pass only
        the main test tool program as argument for running gdb
    
        * configure.ac: Add the --enable-assertions options.
    
        * doc/Makefile.am, doc/body.texi, doc/lightning.texi:
        Major rewrite of the documentation to match the current
        implementation.
    
        * doc/version.texi: Automatic date update.
    
        * doc/ifib.c, doc/incr.c, doc/printf.c, doc/rfib.c, doc/rpn.c:
        Implementation of the documentation examples, that are also
        compiled during a normal build.
    
        * doc/p-lightning.texi, doc/porting.texi, doc/toc.texi,
        doc/u-lightning.texi, doc/using.texi: These files were
        renamed in the documentation rewrite, as the documentation
        was significantly trimmed due to full removal of the porting
        chapters. Better porting documentation should be added but
        for the moment it was just removed the documentation not
        matching the implementation.
---
 .gitignore           |    1 +
 ChangeLog            |   27 +-
 check/Makefile.am    |    4 +-
 configure.ac         |   11 +
 doc/Makefile.am      |   41 +-
 doc/body.texi        | 1281 +++++++++++++++++++++++++++++++++-------
 doc/ifib.c           |   44 ++
 doc/incr.c           |   29 +
 doc/lightning.texi   |   28 +-
 doc/p-lightning.texi |  100 ----
 doc/porting.texi     | 1600 --------------------------------------------------
 doc/printf.c         |   38 ++
 doc/rfib.c           |   49 ++
 doc/rpn.c            |   94 +++
 doc/toc.texi         |   76 ---
 doc/u-lightning.texi |  100 ----
 doc/using.texi       | 1273 ---------------------------------------
 doc/version.texi     |    8 +-
 18 files changed, 1423 insertions(+), 3381 deletions(-)

diff --git a/.gitignore b/.gitignore
index a89a8e1..ddfc424 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ missing
 stamp-h1
 test-driver
 check/.deps
+doc/.deps
 lib/.deps
 m4/libtool.m4
 m4/lt~obsolete.m4
diff --git a/ChangeLog b/ChangeLog
index 84d3c43..1322aac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,31 @@
+2013-01-24 Paulo Andrade <address@hidden>
+
+       * check/Makefile.am: "make debug" target should pass only
+       the main test tool program as argument for running gdb
+
+       * configure.ac: Add the --enable-assertions options.
+
+       * doc/Makefile.am, doc/body.texi, doc/lightning.texi:
+       Major rewrite of the documentation to match the current
+       implementation.
+
+       * doc/version.texi: Automatic date update.
+
+       * doc/ifib.c, doc/incr.c, doc/printf.c, doc/rfib.c, doc/rpn.c:
+       Implementation of the documentation examples, that are also
+       compiled during a normal build.
+
+       * doc/p-lightning.texi, doc/porting.texi, doc/toc.texi,
+       doc/u-lightning.texi, doc/using.texi: These files were
+       renamed in the documentation rewrite, as the documentation
+       was significantly trimmed due to full removal of the porting
+       chapters. Better porting documentation should be added but
+       for the moment it was just removed the documentation not
+       matching the implementation.
+
 2013-01-18 Paulo Andrade <address@hidden>
 
-       lib/jit_note.c: Correct bounds check and wrong code keeping
+       * lib/jit_note.c: Correct bounds check and wrong code keeping
        a pointer that could be changed after a realloc call.
 
 2013-01-18 Paulo Andrade <address@hidden>
diff --git a/check/Makefile.am b/check/Makefile.am
index ce78c49..33ce213 100644
--- a/check/Makefile.am
+++ b/check/Makefile.am
@@ -172,6 +172,6 @@ CLEANFILES = $(TESTS)
 
 #TESTS_ENVIRONMENT=$(srcdir)/run-test;
 
-debug:         $(check_PROGRAMS)
-       $(LIBTOOL) --mode=execute gdb $(check_PROGRAMS)
+debug:         lightning
+       $(LIBTOOL) --mode=execute gdb lightning
 
diff --git a/configure.ac b/configure.ac
index 9d5e433..83a7805 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,17 @@ if test "x$DISASSEMBLER" != "xno"; then
     LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1"
 fi
 
+AC_ARG_ENABLE(assertions,
+             AS_HELP_STRING([--enable-assertions],
+                            [Enable runtime code generation assertions]),
+             [DEBUG=$enableval], [DEBUG=auto])
+if test "x$DEBUG" = xyes; then
+    LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDEBUG=1"
+else
+    LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DNDEBUG"
+    DEBUG=no
+fi
+
 cpu=
 case "$target_cpu" in
     i?86|x86_64)       cpu=x86         ;;
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 3baca2d..3f4ff64 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,7 +1,40 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+
+AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
+
 info_TEXINFOS = lightning.texi 
-EXTRA_TEXINFOS = u-lightning.texi p-lightning.texi
 MOSTLYCLEANFILES = lightning.tmp
 
-lightning_TEXINFOS = body.texi toc.texi using.texi porting.texi version.texi
-u_lightning_TEXINFOS = body.texi toc.texi using.texi version.texi
-p_lightning_TEXINFOS = body.texi toc.texi porting.texi version.texi
+lightning_TEXINFOS = body.texi version.texi
+
+noinst_PROGRAMS = incr printf rpn rfib ifib
+
+$(top_builddir)/lib/liblightning.la:
+       cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la
+
+incr_LDADD = $(top_builddir)/lib/liblightning.la -lm -ldl
+incr_SOURCES = incr.c
+
+printf_LDADD = $(top_builddir)/lib/liblightning.la -lm -ldl
+printf_SOURCES = printf.c
+
+rpn_LDADD = $(top_builddir)/lib/liblightning.la -lm -ldl
+rpn_SOURCES = rpn.c
+
+rfib_LDADD = $(top_builddir)/lib/liblightning.la -lm -ldl
+rfib_SOURCES = rfib.c
+
+ifib_LDADD = $(top_builddir)/lib/liblightning.la -lm -ldl
+ifib_SOURCES = ifib.c
diff --git a/doc/body.texi b/doc/body.texi
index 7c20d51..af924e8 100644
--- a/doc/body.texi
+++ b/doc/body.texi
@@ -1,66 +1,32 @@
address@hidden
address@hidden @lightning{}, a library for dynamic code generation
address@hidden
-     * @value{TITLE}: (lightning).
address@hidden direntry
-
-This file documents GNU lightning, Version @value{VERSION}.
-It was last updated on @value{UPDATED}.
-
-Copyright @copyright{} 2000 Free Software Foundation, Inc.
-Authored by Paolo Bonzini.
-
-This document is released under the terms of the GNU Free Documentation
-License as published by the Free Software Foundation; either version 1.1, or
-(at your option) any later version.
-
-You should have received a copy of the GNU Free Documentation License along
-with GNU lightning; see the file @file{COPYING.DOC}.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 
USA.  
-
-There are no Secondary Sections, no Cover Texts and no Invariant Sections
-(as defined in the license); this text, along with its equivalent in the
-printed manual, constitutes the Title Page.
address@hidden ifinfo
-
address@hidden odd
-
address@hidden
address@hidden @value{TITLE}
address@hidden Version @value{VERSION}
address@hidden @value{UPDATE-MONTH}
-
address@hidden by Paolo Bonzini
-
address@hidden  The following two commands start the copyright page.
address@hidden
address@hidden 0pt plus 1filll
-Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
-
-This document is released under the terms of the @sc{gnu} Free Documentation
-License as published by the Free Software Foundation; either version 1.1, or
-(at your option) any later version.
-
-You should have received a copy of the @sc{gnu} Free Documentation License
-along with @sc{gnu} @i{lightning}; see the file @file{COPYING.DOC}.  If not,
-write to the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-MA 02110-1301, USA.  
-
-There are no Secondary Sections, no Cover Texts and no Invariant Sections
-(as defined in the license); this text, along with its equivalent in the
-Info documentation, constitutes the Title Page.
address@hidden titlepage
-
 @ifnottex
 @node Top
 @top @lightning{}
 
address@hidden
address@hidden comma
address@hidden|,|}
address@hidden macro
address@hidden iftex
+
address@hidden
address@hidden comma
address@hidden|,|}
address@hidden macro
address@hidden ifnottex
+
 This document describes @value{TOPIC} the @lightning{} library for
 dynamic code generation.  Unlike other dynamic code generation systems,
 which are usually either inefficient or non-portable, @lightning{} is
 both retargetable and very fast.
 
address@hidden toc.texi
address@hidden
+* Overview::                What GNU lightning is
+* Installation::            Configuring and installing GNU lightning
+* The instruction set::     The RISC instruction set used i GNU lightning
+* GNU lightning examples::  GNU lightning's examples
+* Reentrancy::              Re-entrant usage of GNU lightning
+* Acknowledgements::        Acknowledgements for GNU lightning
address@hidden menu
 @end ifnottex
 
 @node Overview
@@ -73,14 +39,6 @@ which are usually either inefficient or non-portable, 
@lightning{} is
 both retargetable and very fast.
 @end iftex
 
address@hidden USING
-This manual assumes that you are pretty comfortable with the usage of
address@hidden for dynamic code generation, as described in
address@hidden instruction set, @lightning{}'s instruction set}, and
-instead focuses on the retargeting process.  What follows is nothing
-more then a brief overview of the system.
address@hidden ifclear
-
 Dynamic code generation is the generation of machine code 
 at runtime. It is typically used to strip a layer of interpretation 
 by allowing compilation to occur at runtime.  One of the most
@@ -105,28 +63,8 @@ are generated, so programs using dynamic code generation 
must be
 retargeted for each machine; in addition, coding a run-time code
 generator is a tedious and error-prone task more than a difficult one.
 
address@hidden USING
-This manual describes the @lightning{} dynamic code generation library.
address@hidden provides a portable, fast and easily retargetable dynamic
-code generation system. 
address@hidden ifset
address@hidden USING
 @lightning{} provides a portable, fast and easily retargetable dynamic
 code generation system. 
address@hidden ifclear
-
-To be fast, @lightning{} emits machine code without first creating
-intermediate data structures such as RTL representations traditionally
-used by optimizing compilers (@pxref{RTL representation, , , gcc, Using
-and porting GNU CC}).  @lightning{} translates code directly from a
-machine independent interface to that of the underlying architecture.
-This makes code generation more efficient, since no intermediate data
-structures have to be constructed and consumed.  A collateral benefit
-it that @lightning{} consumes little space: other than the memory
-needed to store generated instructions and data structures such as
-parse trees, the only data structure that client will usually need
-is an array of pointers to labels and unresolved jumps, which you
-can often allocate directly on the system stack.
 
 To be portable, @lightning{} abstracts over current architectures'
 quirks and unorthogonalities.  The interface that it exposes to is that
@@ -143,141 +81,1098 @@ real architectures closely enough that, most of the 
time, the
 compiler's constant folding pass ends up generating code which
 assembles machine instructions without further tests.
 
address@hidden Drawbacks
-
address@hidden has been useful in practice; however, it does have
-at least four drawbacks: it has limited registers, no peephole
-optimizer, no instruction scheduler and no symbolic debugger. Of
-these, the last is the most critical even though it does not
-affect the quality of generated code: the only way to debug code
-generated at run-time  is to step through it at the level of
-host specific machine code.  A decent knowledge of the underlying
-instruction set is thus needed to make sense of the debugger's
-output.
-
-The low number of available registers (six) is also an important
-limitation.  However, let's take the primary application of dynamic
-code generation, that is, bytecode translators.  The underlying
-virtual machines tend to have very few general purpose registers
-(usually 0 to 2) and the translators seldom rely on sophisticated
-graph-coloring algorithms to allocate registers to temporary
-variables.  Rather, these translators usually obtain performance
-increases because: a) they remove indirect jumps, which are usually
-poorly predicted, and thus often form a bottleneck, b) they
-parameterize the generated code and go through the process of decoding
-the bytecodes just once.  So, their usage of registers is rather
-sparse---in fact, in practice, six registers were found to be
-enough for most purposes.
-
-The lack of a peephole optimizer is most important on machines where a 
-single instruction can map to multiple native instructions.  For
-instance, Intel chips' division instruction hard-codes the dividend
-to be in EAX and the quotient and remainder to be output, respectively,
-in EAX and EDX: on such chips, @lightning{} does lots of pushing and
-popping of EAX and EDX to save those registers that are not used.  
-Unnecessary stack operations could be removed by looking at whether
-preserved registers are destroyed soon.  Unfortunately, the current 
-implementation of @lightning{} is so fast because it only knows about
-the single instruction that is being generated; performing these
-optimizations would require a flow analysis pass that would probably
-hinder @lightning{}'s speed.
-
-The lack of an instruction scheduler is not very important---pretty
-good instruction scheduling can actually be obtained by separating
-register writes from register reads.  The only architectures on which
-a scheduler would be useful are those on which arithmetic instructions
-have two operands; an example is, again, the x86, on which the single
-instruction
address@hidden Installation
address@hidden Configuring and installing @lightning{}
+
+The first thing to do to use @lightning{} is to configure the
+program, picking the set of macros to be used on the host
+architecture; this configuration is automatically performed by
+the @file{configure} shell script; to run it, merely type:
 @example
-    subr_i  R0, R1, R2       @rem{!Compute R0 = R1 - R2}
+     ./configure
 @end example
address@hidden
-is translated to two instruction, of which the second depends on the
-result of the first:
+
address@hidden supports the @code{--enable-disassembler} option, that
+enables linking to GNU binutils and optionally print human readable
+disassembly of the jit code. This option can be disabled by the
address@hidden option.
+
+Another option that @file{configure} accepts is
address@hidden, which enables several consistency checks in
+the run-time assemblers.  These are not usually needed, so you can
+decide to simply forget about it; also remember that these consistency
+checks tend to slow down your code generator.
+
+After you've configured @lightning{}, run @file{make} as usual.
+
address@hidden has an extensive set of tests to validate it is working
+correctly in the build host. To test it run:
 @example
-    movl    %ebx, %eax       @rem{! Move R1 into R0}
-    subl    %edx, %eax       @rem{! Subtract R2 from R0}
+    make check
 @end example
 
address@hidden BOTH
address@hidden Using GNU lightning
address@hidden Using @lightning{}
+The next important step is:
address@hidden
+    make install
address@hidden example
 
-This chapter describes installing and using @lightning{}.
+This ends the process of installing @lightning{}.
 
address@hidden
address@hidden
address@hidden menu
address@hidden The instruction set
address@hidden @lightning{}'s instruction set
 
address@hidden
address@hidden ifset
address@hidden's instruction set was designed by deriving instructions
+that closely match those of most existing RISC architectures, or
+that can be easily syntesized if absent.  Each instruction is composed
+of:
address@hidden @bullet
address@hidden
+an operation, like @code{sub} or @code{mul}
 
address@hidden USING
address@hidden using.texi
address@hidden ifset
address@hidden
+most times, a register/immediate flag (@code{r} or @code{i})
 
address@hidden BOTH
address@hidden
address@hidden
+an unsigned modifier (@code{u}), a type identifier or two, when applicable.
address@hidden itemize
 
address@hidden Porting GNU lightning
address@hidden Porting @lightning{}
+Examples of legal mnemonics are @code{addr} (integer add, with three
+register operands) and @code{muli} (integer multiply, with two
+register operands and an immediate operand).  Each instruction takes
+two or three operands; in most cases, one of them can be an immediate
+value instead of a register.
 
-This chapter describes the process of porting @lightning{}.
-It assumes that you are pretty comfortable with the usage of
address@hidden for dynamic code generation, as described in
address@hidden GNU lightning}.
+Most @lightning{} integer operations are signed wordsize operations,
+with the exception of operations that convert types, or load or store
+values to/from memory. When applicable, the types and C types are as
+follow:
 
address@hidden
address@hidden
address@hidden menu
address@hidden
+     _c         @r{signed char}
+     _uc        @r{unsigned char}
+     _s         @r{short}
+     _us        @r{unsigned short}
+     _i         @r{int}
+     _ui        @r{unsigned int}
+     _l         @r{long}
+     _f         @r{float}
+     _d         @r{double}
address@hidden example
+
+Most integer operations do not need a type modifier, and when loading or
+storing values to memory there is an alias to the proper operation
+using wordsize operands, that is, if ommited, the type is @r{int} on
+32-bit architectures and @r{long} on 64-bit architectures.  Note
+that lightning also expects @code{sizeof(void*)} to match the wordsize.
+
+When an unsigned operation result differs from the equivalent signed
+operation, there is a the @code{_u} modifier.
+
+There are at least seven integer registers, of which six are
+general-purpose, while the last is used to contain the frame pointer
+(@code{FP}).  The frame pointer can be used to allocate and access local
+variables on the stack, using the @code{allocai} instruction.
+
+Of the general-purpose registers, at least three are guaranteed to be
+preserved across function calls (@code{V0}, @code{V1} and
address@hidden) and at least three are not (@code{R0}, @code{R1} and
address@hidden).  Six registers are not very much, but this
+restriction was forced by the need to target CISC architectures
+which, like the x86, are poor of registers; anyway, backends can
+specify the actual number of available registers with the calls
address@hidden (for caller-save registers) and @code{JIT_V_NUM}
+(for callee-save registers).
+
+There are at least six floating-point registers, named @code{F0} to
address@hidden  These are usually caller-save and are separate from the integer
+registers on the supported architectures; on Intel architectures,
+in 32 bit mode if SSE2 is not available or use of X87 is forced,
+the register stack is mapped to a flat register file.  As for the
+integer registers, the macro @code{JIT_F_NUM} yields the number of
+floating-point registers.
+
+The complete instruction set follows; as you can see, most non-memory
+operations only take integers (either signed or unsigned) as operands;
+this was done in order to reduce the instruction set, and because most
+architectures only provide word and long word operations on registers.
+There are instructions that allow operands to be extended to fit a larger
+data type, both in a signed and in an unsigned way.
 
address@hidden
address@hidden ifset
address@hidden @b
address@hidden Binary ALU operations
+These accept three operands; the last one can be an immediate.
address@hidden operations must directly follow @code{addc}, and
address@hidden must follow @code{subc}; otherwise, results are undefined.
+Most, if not all, architectures do not support @r{float} or @r{double}
+immediate operands; lightning emulates those operations by moving the
+immediate to a temporary register and emiting the call with only
+register operands.
address@hidden
+addr         _f  _d  O1 = O2 + O3
+addi         _f  _d  O1 = O2 + O3
+addxr                O1 = O2 + (O3 + carry)
+addxi                O1 = O2 + (O3 + carry)
+addcr                O1 = O2 + O3, set carry
+addci                O1 = O2 + O3, set carry
+subr         _f  _d  O1 = O2 - O3
+subi         _f  _d  O1 = O2 - O3
+subxr                O1 = O2 - (O3 + carry)
+subxi                O1 = O2 - (O3 + carry)
+subcr                O1 = O2 - O3, set carry
+subci                O1 = O2 - O3, set carry
+mulr         _f  _d  O1 = O2 * O3
+muli         _f  _d  O1 = O2 * O3
+divr     _u  _f  _d  O1 = O2 / O3
+divi     _u  _f  _d  O1 = O2 / O3
+remr     _u          O1 = O2 % O3
+remi     _u          O1 = O2 % O3
+andr                 O1 = O2 & O3
+andi                 O1 = O2 & O3
+orr                  O1 = O2 | O3
+ori                  O1 = O2 | O3
+xorr                 O1 = O2 ^ O3
+xori                 O1 = O2 ^ O3
+lshr                 O1 = O2 << O3
+lshi                 O1 = O2 << O3
+rshr     _u          O1 = O2 >> address@hidden sign bit is propagated unless 
using the @code{_u} modifier.}
+rshi     _u          O1 = O2 >> address@hidden sign bit is propagated unless 
using the @code{_u} modifier.}
address@hidden example
+
address@hidden Unary ALU operations
+These accept two operands, both of which must be registers.
address@hidden
+negr         _f  _d  O1 = -O2
+comr                 O1 = ~O2
address@hidden example
+
+There unary ALU operations are only defined for float operands.
address@hidden
+absr         _f  _d  O1 = fabs(O2)
+sqrtr                O1 = sqrt(O2)
address@hidden example
 
address@hidden PORTING
address@hidden porting.texi
address@hidden ifset
+Besides requiring the @code{r} modifier, there are no unary operations
+with an immediate operand.
 
address@hidden BOTH
address@hidden
address@hidden ifset
address@hidden Compare instructions
+These accept three operands; again, the last can be an immediate.
+The last two operands are compared, and the first operand, that must be
+an integer register, is set to either 0 or 1, according to whether the
+given condition was met or not.
 
address@hidden Future
address@hidden The future of @lightning{}
+The conditions given below are for the standard behavior of C,
+where the ``unordered'' comparison result is mapped to false.
+
address@hidden
+ltr       _u  _f  _d  O1 =  (O2 <  O3)
+lti       _u  _f  _d  O1 =  (O2 <  O3)
+ler       _u  _f  _d  O1 =  (O2 <= O3)
+lei       _u  _f  _d  O1 =  (O2 <= O3)
+gtr       _u  _f  _d  O1 =  (O2 >  O3)
+gti       _u  _f  _d  O1 =  (O2 >  O3)
+ger       _u  _f  _d  O1 =  (O2 >= O3)
+gei       _u  _f  _d  O1 =  (O2 >= O3)
+eqr           _f  _d  O1 =  (O2 == O3)
+eqi           _f  _d  O1 =  (O2 == O3)
+ner           _f  _d  O1 =  (O2 != O3)
+nei           _f  _d  O1 =  (O2 != O3)
+unltr         _f  _d  O1 = !(O2 >= O3)
+unler         _f  _d  O1 = !(O2 >  O3)
+ungtr         _f  _d  O1 = !(O2 <= O3)
+unger         _f  _d  O1 = !(O2 <  O3)
+uneqr         _f  _d  O1 = !(O2 <  O3) && !(O2 >  O3)
+ltgtr         _f  _d  O1 = !(O2 >= O3) || !(O2 <= O3)
+ordr          _f  _d  O1 =  (O2 == O2) &&  (O3 == O3)
+unordr        _f  _d  O1 =  (O2 != O2) ||  (O3 != O3)
address@hidden example
+
address@hidden Transfer operations
+These accept two operands; for @code{ext} both of them must be
+registers, while @code{mov} accepts an immediate value as the second
+operand.
+
+Unlike @code{movr} and @code{movi}, the other instructions are used
+to truncate a wordsize operand to a smaller integer data type or to
+convert float data types. You can also use @code{extr} to convert an
+integer to a floating point value: the usual options are @code{extr_f}
+and @code{extr_d}.
+
address@hidden
+movr                                 _f  _d  O1 = O2
+movi                                 _f  _d  O1 = O2
+extr      _c  _uc  _s  _us  _i  _ui  _f  _d  O1 = O2
+truncr                               _f  _d  O1 = trunc(O2)
address@hidden example
 
-Presented below is the set of tasks that I feel need to be performed
-to make @lightning{} a more fully functional, viable system.  They are
-presented in no particular order.  I would @emph{very much} welcome any
-volunteers who would like to help with the implementation of one or
-more of these tasks.  Please write to me, Paolo Bonzini, at
address@hidden@@gnu.org} if you are interested in adding your efforts
-to the @lightning{} project.
+In 64-bit architectures it may be required to use @code{truncr_f_i},
address@hidden, @code{truncr_d_i} and @code{truncr_d_l} to match
+the equivalent C code.  Only the @code{_i} modifier is available in
+32-bit architectures.
 
-Tasks:
address@hidden
+truncr_f_i    = <int> O1 = <float> O2
+truncr_f_l    = <long>O1 = <float> O2
+truncr_d_i    = <int> O1 = <double>O2
+truncr_d_l    = <long>O1 = <double>O2
address@hidden example
+
+The float conversion operations are @emph{destination first,
+source second}, but the order of the types is reversed.  This happens
+for historical reasons.
+
address@hidden
+extr_f_d    = <double>O1 = <float> O2
+extr_d_f    = <float> O1 = <double>O2
address@hidden example
+
address@hidden Network extensions
+These accept two operands, both of which must be registers; these
+two instructions actually perform the same task, yet they are
+assigned to two mnemonics for the sake of convenience and
+completeness.  As usual, the first operand is the destination and
+the second is the source.
address@hidden
+htonr    @r{Host-to-network (big endian) order}
+ntohr    @r{Network-to-host order }
address@hidden example
+
address@hidden Load operations
address@hidden accepts two operands while @code{ldx} accepts three;
+in both cases, the last can be either a register or an immediate
+value. Values are extended (with or without sign, according to
+the data type specification) to fit a whole register.
+The @code{_ui} and @code{_l} types are only available in 64-bit
+architectures.  For convenience, there is a version without a
+type modifier for integer or pointer operands that uses the
+appropriate wordsize call.
address@hidden
+ldr     _c  _uc  _s  _us  _i  _ui  _l  _f  _d  O1 = *O2
+ldi     _c  _uc  _s  _us  _i  _ui  _l  _f  _d  O1 = *O2
+ldxr    _c  _uc  _s  _us  _i  _ui  _l  _f  _d  O1 = *(O2+O3)
+ldxi    _c  _uc  _s  _us  _i  _ui  _l  _f  _d  O1 = *(O2+O3)
address@hidden example
+
address@hidden Store operations
address@hidden accepts two operands while @code{stx} accepts three; in
+both cases, the first can be either a register or an immediate
+value. Values are sign-extended to fit a whole register.
address@hidden
+str     _c  _uc  _s  _us  _i  _ui  _l  _f  _d  *O1 = O2
+sti     _c  _uc  _s  _us  _i  _ui  _l  _f  _d  *O1 = O2
+stxr    _c  _uc  _s  _us  _i  _ui  _l  _f  _d  *(O1+O2) = O3
+stxi    _c  _uc  _s  _us  _i  _ui  _l  _f  _d  *(O1+O2) = O3
address@hidden example
+As for the load operations, the @code{_ui} and @code{_l} types are
+only available in 64-bit architectures, and for convenience, there
+is a version without a type modifier for integer or pointer operands
+that uses the appropriate wordsize call.
+
address@hidden Argument management
+These are:
address@hidden
+prepare     (not specified)
+pushargr    _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+pushargi    _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+arg         _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+getarg      _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+ret         (not specified)
+retr        _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+reti        _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+retval      _c  _uc  _s  _us  _i  _ui  _l  _f  _d
+epilog      (not specified)
address@hidden example
+As with other operations that use a type modifier, the @code{_ui} and
address@hidden types are only available in 64-bit architectures, but there
+are operations without a type modifier that alias to the appropriate
+integer operation with wordsize operands.
+
address@hidden, @code{pusharg}, and @code{retval} are used by the caller,
+while @code{arg}, @code{getarg} and @code{ret} are used by the callee.
+A code snippet that wants to call another procedure and has to pass
+arguments must, in order: use the @code{prepare} instruction and use
+the @code{pushargr} or @code{pushargi} to push the arguments @strong{in
+left to right order}; and use @code{finish} or @code{call} (explained below)
+to perform the actual call.
+
address@hidden and @code{getarg} are used by the callee.
address@hidden is different from other instruction in that it does not
+actually generate any code: instead, it is a function which returns
+a value to be passed to @address@hidden a
+value'' means that @lightning{} code that compile these
+instructions return a value when expanded.} You should call
address@hidden as soon as possible, before any function call or, more
+easily, right after the @code{prolog} instructions
+(which is treated later).
+
address@hidden accepts a register argument and a value returned by
address@hidden, and will move that argument to the register, extending
+it (with or without sign, according to the data type specification)
+to fit a whole register.  These instructions are more intimately
+related to the usage of the @lightning{} instruction set in code
+that generates other code, so they will be treated more
+specifically in @ref{GNU lightning examples, , Generating code at
+run-time}.
+
+Finally, the @code{retval} instruction fetches the return value of a
+called function in a register.  The @code{retval} instruction takes a
+register argument and copies the return value of the previously called
+function in that register.  A function with a return value should use
address@hidden or @code{reti} to put the return value in the return register
+before returning.  @xref{Fibonacci, the Fibonacci numbers}, for an example.
+
address@hidden is an optional call, that marks the end of a function
+body. It is automatically generated by lightning if starting a new
+function (what should be done after a @code{ret} call) or finishing
+generating jit.
+
+You should observe a few rules when using these macros.  First of
+all, if calling a varargs function, you should use the @code{ellipsis}
+call to mark the position of the ellipsis in the C prototype.
+
+You should not nest calls to @code{prepare} inside a
address@hidden/finish} block.  Doing this will result in undefined
+behavior. Note that for functions with zero arguments you can use
+just @code{call}.
+
address@hidden Branch instructions
+Like @code{arg}, these also return a value which, in this case,
+is to be used to compile forward branches as explained in
address@hidden, , Fibonacci numbers}.  They accept two operands to be
+compared; of these, the last can be either a register or an immediate.
+They are:
address@hidden
+bltr      _u  _f  _d  @r{if }(O2 <  O3)@r{ goto }O1
+blti      _u  _f  _d  @r{if }(O2 <  O3)@r{ goto }O1
+bler      _u  _f  _d  @r{if }(O2 <= O3)@r{ goto }O1
+blei      _u  _f  _d  @r{if }(O2 <= O3)@r{ goto }O1
+bgtr      _u  _f  _d  @r{if }(O2 >  O3)@r{ goto }O1
+bgti      _u  _f  _d  @r{if }(O2 >  O3)@r{ goto }O1
+bger      _u  _f  _d  @r{if }(O2 >= O3)@r{ goto }O1
+bgei      _u  _f  _d  @r{if }(O2 >= O3)@r{ goto }O1
+beqr          _f  _d  @r{if }(O2 == O3)@r{ goto }O1
+beqi          _f  _d  @r{if }(O2 == O3)@r{ goto }O1
+bner          _f  _d  @r{if }(O2 != O3)@r{ goto }O1
+bnei          _f  _d  @r{if }(O2 != O3)@r{ goto }O1
+
+bunltr        _f  _d  @r{if }!(O2 >= O3)@r{ goto }O1
+bunler        _f  _d  @r{if }!(O2 >  O3)@r{ goto }O1
+bungtr        _f  _d  @r{if }!(O2 <= O3)@r{ goto }O1
+bunger        _f  _d  @r{if }!(O2 <  O3)@r{ goto }O1
+buneqr        _f  _d  @r{if }!(O2 <  O3) && !(O2 >  O3)@r{ goto }O1
+bltgtr        _f  _d  @r{if }!(O2 >= O3) || !(O2 <= O3)@r{ goto }O1
+bordr         _f  _d  @r{if } (O2 == O2) &&  (O3 == O3)@r{ goto }O1
+bunordr       _f  _d  @r{if }!(O2 != O2) ||  (O3 != O3)@r{ goto }O1
+
+bmsr                  @r{if }O2 &  address@hidden goto }O1
+bmsi                  @r{if }O2 &  address@hidden goto }O1
+bmcr                  @r{if }!(O2 & O3)@r{ goto }O1
+bmci                  @r{if }!(O2 & O3)@r{ goto address@hidden mnemonics mean, 
respectively, @dfn{branch if mask set} and @dfn{branch if mask cleared}.}
+boaddr    _u          O2 += address@hidden, goto address@hidden if overflow}
+boaddi    _u          O2 += address@hidden, goto address@hidden if overflow}
+bxaddr    _u          O2 += address@hidden, goto address@hidden if no overflow}
+bxaddi    _u          O2 += address@hidden, goto address@hidden if no overflow}
+bosubr    _u          O2 -= address@hidden, goto address@hidden if overflow}
+bosubi    _u          O2 -= address@hidden, goto address@hidden if overflow}
+bxsubr    _u          O2 -= address@hidden, goto address@hidden if no overflow}
+bxsubi    _u          O2 -= address@hidden, goto address@hidden if no overflow}
address@hidden example
+
address@hidden Jump and return operations
+These accept one argument except @code{ret} which has none; the
+difference between @code{finishi} and @code{calli} is that the
+latter does not clean the stack from pushed parameters (if any)
+and the former must @strong{always} follow a @code{prepare}
+instruction.
address@hidden
+callr     (not specified)                @r{function call to a register}
+calli     (not specified)                @r{function call to O1}
+finishr   (not specified)                @r{function call to a register}
+finishi   (not specified)                @r{function call to O1}
+jmpi/jmpr (not specified)                @r{unconditional jump to O1}
+ret       (not specified)                @r{return from subroutine}
+retr      _c _uc _s _us _i _ui _l _f _d
+reti      _c _uc _s _us _i _ui _l _f _d
+retval    _c _uc _s _us _i _ui _l _f _d  @r{move return value}
+                                         @r{to register}
address@hidden example
+
+Like branch instruction, @code{jmpi} also returns a value which is to
+be used to compile forward branches. @xref{Fibonacci, , Fibonacci
+numbers}.
+
address@hidden Function prolog
+
+These macros are used to set up a function prolog.  The @code{allocai}
+call accept a single integer argument and returns an offset value
+for stack storage access.
+
address@hidden
+prolog    (not specified)                @r{function prolog}
+allocai   (not specified)                @r{reserve space on the stack}
address@hidden example
+
address@hidden receives the number of bytes to allocate and returns
+the offset from the frame pointer register @code{FP} to the base of
+the area.
address@hidden table
+
+As a small appetizer, here is a small function that adds 1 to the input
+parameter (an @code{int}).  I'm using an assembly-like syntax here which
+is a bit different from the one used when writing real subroutines with
address@hidden; the real syntax will be introduced in @xref{GNU lightning
+examples, , Generating code at run-time}.
+
address@hidden
+incr:
+     prolog
+in = arg                     @rem{! We have an integer argument}
+     getarg    R0, in        @rem{! Move it to R0}
+     addi      R0, R0, 1     @rem{! Add 1}
+     retr      R0            @rem{! And return the result}
address@hidden example
+
+And here is another function which uses the @code{printf} function from
+the standard C library to write a number in hexadecimal notation:
+
address@hidden
+printhex:
+     prolog
+in = arg                     @rem{! Same as above}
+     getarg    R0, in
+     prepare                 @rem{! Begin call sequence for printf}
+     pushargi  "%x"          @rem{! Push format string}
+     ellipsis                @rem{! Varargs start here}
+     pushargr  R0            @rem{! Push second argument}
+     finishi   printf        @rem{! Call printf}
+     ret                     @rem{! Return to caller}
address@hidden example
+
address@hidden GNU lightning examples
address@hidden Generating code at run-time
+
+To use @lightning{}, you should include the @file{lightning.h} file that
+is put in your include directory by the @samp{make install} command.
+
+Each of the instructions above translates to a macro or function call.
+All you have to do is prepend @code{jit_} (lowercase) to opcode names
+and @code{JIT_} (uppercase) to register names.  Of course, parameters
+are to be put between parentheses.
+
+This small tutorial presents three examples:
+
address@hidden
 @itemize @bullet
 @item
-The most important task to make @lightning{} more widely usable
-is to retarget it.  Although currently supported architectures
-(x86, SPARC, PowerPC) are certainly some of the most widely used,
address@hidden could be ported to others---namely, the Alpha and
-MIPS architectures.
+The @code{incr} function found in @ref{The instruction set, ,
address@hidden's instruction set}:
+
address@hidden
+A simple function call to @code{printf}
 
 @item
-Another interesting task is to allow the instruction stream to grow
-dynamically.  This is a problem because not all architectures allow
-to write position independent address@hidden x86's absolute
-jumps, for example, are actually slow indirect jumps, and need a
-register.}
+An RPN calculator.
 
 @item
-Optimize leaf procedures on the SPARC.  This involves using the
-output registers (@address@hidden) instead of the local registers
-(@address@hidden) when writing leaf procedures;  the problem is,
-leaf procedures also receive parameters in the output registers,
-so they would be overwritten by write accesses to general-purpose
-registers.
+Fibonacci numbers
 @end itemize
address@hidden iftex
address@hidden
address@hidden
+* incr::             A function which increments a number by one
+* printf::           A simple function call to printf
+* RPN calculator::   A more complex example, an RPN calculator
+* Fibonacci::        Calculating Fibonacci numbers
address@hidden menu
address@hidden ifnottex
+
address@hidden incr
address@hidden A function which increments a number by one
+
+Let's see how to create and use the sample @code{incr} function created
+in @ref{The instruction set, , @lightning{}'s instruction set}:
+
address@hidden
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);    @rem{/* Pointer to Int Function of Int */}
+
+int main(int argc, char *argv[])
address@hidden
+  jit_node_t  *in;
+  pifi         incr;
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  jit_prolog();                    @rem{/* @t{     prolog             } */}
+  in = jit_arg();                  @rem{/* @t{     in = arg           } */}
+  jit_getarg(JIT_R0, in);          @rem{/* @t{     getarg R0          } */}
+  jit_addi(JIT_R0, JIT_R0, 1);     @rem{/* @t{     addi   address@hidden 
address@hidden 1   } */}
+  jit_retr(JIT_R0);                @rem{/* @t{     retr   R0          } */}
+
+  incr = jit_emit();
+
+  @rem{/* call the generated address@hidden passing 5 as an argument */}
+  printf("%d + 1 = %d\n", 5, incr(5));
+
+  finish_jit();
+  return 0;
address@hidden
address@hidden example
+
+Let's examine the code line by line (well, address@hidden):
+
address@hidden @t
address@hidden #include <lightning.h>
+You already know about this.  It defines all of @lightning{}'s macros.
+
address@hidden static jit_state_t *_jit;
+You might wonder about what is @code{jit_state_t}.  It is a structure
+that stores jit code generation information.  The name @code{_jit} is
+special, because since multiple jit generators can run at the same
+time, you must either @r{#define _jit my_jit_state} or name it
address@hidden
+
address@hidden typedef int (*pifi)(int);
+Just a handy typedef for a pointer to a function that takes an
address@hidden and returns another.
+
address@hidden jit_node_t  *in;
+Declares a variable to hold an identifier for a function argument. It
+is an opaque pointer, that will hold the return of a call to @code{arg}
+and be used as argument to @code{getarg}.
+
address@hidden pifi         incr;
+Declares a function pointer variable to a function that receives an
address@hidden and returns an @code{int}.
+
address@hidden init_jit(argv[0]);
+You must call this function before creating a @code{jit_state_t}
+object. This function does global state initialization, and may need
+to detect CPU or Operating System features.  It receives a string
+argument that is later used to read symbols from a shared object using
+GNU binutils if disassembly was enabled at configure time. If no
+disassembly will be performed a NULL pointer can be used as argument.
+
address@hidden _jit = jit_new_state();
+This call initializes a @lightning{} jit state.
+
address@hidden jit_prolog();
+Ok, so we start generating code for our beloved address@hidden
+
address@hidden in = jit_arg();
address@hidden jit_getarg(JIT_R0, in);
+We retrieve the first (and only) argument, an integer, and store it
+into the general-purpose register @code{R0}.
+
address@hidden jit_addi(JIT_R0, JIT_R0, 1);
+We add one to the content of the register.
+
address@hidden jit_retr(JIT_R0);
+This instruction generates a standard function epilog that returns
+the contents of the @code{R0} register.
+
address@hidden incr = jit_emit();
+This instruction is very important.  It actually translates the
address@hidden macros used before to machine code, flushes the generated
+code area out of the processor's instruction cache and return a
+pointer to the start of the code.
+
address@hidden printf("%d + 1 = %d", 5, incr(5));
+Calling our function is this simple---it is not distinguishable from
+a normal C function call, the only difference being that @code{incr}
+is a variable.
+
address@hidden finish_jit();
+This call cleanups any global state hold by @lightning{}, and is
+advisable to call it once jit code will no longer be generated.
address@hidden table
+
address@hidden abstracts two phases of dynamic code generation: selecting
+instructions that map the standard representation, and emitting binary
+code for these instructions.  The client program has the responsibility
+of describing the code to be generated using the standard @lightning{}
+instruction set.
+
+Let's examine the code generated for @code{incr} on the x86_64
+architecture (on the right is the code that an assembly-language
+programmer would write):
+
address@hidden @b
address@hidden x86_64
address@hidden
+    sub   $0x30,%rsp
+    mov   %rbp,(%rsp)
+    mov   %rsp,%rbp
+    sub   $0x18,%rsp
+    mov   %rdi,%rax            mov %rdi, %rax
+    add   $0x1,%rax            inc %rax
+    mov   %rbp,%rsp
+    mov   (%rsp),%rbp
+    add   $0x30,%rsp
+    retq                       retq
address@hidden example
+In this case, the main overhead is due to the function's prolog and
+epilog, and stack alignment after reserving stack space for word
+to/from float conversions or moving data from/to x87 to/from SSE.
+Note that besides allocating space to save callee saved registers,
+no registers are saved/restored because @lightning{} notices those
+registers are not modified. There is currently no logic to detect
+if it needs to allocate stack space for type conversions neither
+proper leaf function detection, but these are subject to change
+(FIXME).
address@hidden table
+
address@hidden printf
address@hidden A simple function call to @code{printf}
+
+Again, here is the code for the example:
+
address@hidden
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef void (*pvfi)(int);      @rem{/* Pointer to Void Function of Int */}
+
+int main(int argc, char *argv[])
address@hidden
+  pvfi          myFunction;             @rem{/* ptr to generated code */}
+  jit_node_t    *start, *end;           @rem{/* a couple of labels */}
+  jit_node_t    *in;                    @rem{/* to get the argument */}
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  start = jit_note(__FILE__, __LINE__);
+  jit_prolog();
+  in = jit_arg();
+  jit_getarg(JIT_R1, in);
+  jit_pushargi((jit_word_t)"generated %d bytes\n");
+  jit_ellipsis();
+  jit_pushargr(JIT_R1);
+  jit_finishi(printf);
+  jit_ret();
+  jit_epilog();
+  end = jit_note(__FILE__, __LINE__);
+
+  myFunction = jit_emit();
+
+  @rem{/* call the generated address@hidden passing its size as argument */}
+  myFunction((char*)jit_address(end) - (char*)jit_address(start));
+
+  jit_disassemble();
+
+  finish_jit();
+  return 0;
address@hidden
address@hidden example
+
+The function shows how many bytes were generated.  Most of the code
+is not very interesting, as it resembles very closely the program
+presented in @ref{incr, , A function which increments a number by one}.
+
+For this reason, we're going to concentrate on just a few statements.
+
address@hidden @t
address@hidden start = jit_note(__FILE__, __LINE__);
address@hidden @address@hidden
address@hidden end = jit_note(__FILE__, __LINE__);
+These two instruction call the @code{jit_note} macro, which creates
+a note in the jit code; arguments to @code{jit_note} usually are a
+filename string and line number integer, but using NULL for the
+string argument is perfectly valid if only need to create a simple
+marker in the code.
+
address@hidden jit_ellipsis();
address@hidden usually is only required if calling varargs functions
+with double arguments, but it is a good practice to properly describe
+the @address@hidden in the call sequence.
+
address@hidden jit_pushargi((jit_word_t)"generated %d bytes\n");
+Note the use of the @code{(jit_word_t)} cast, that is used only
+to avoid a compiler warning, due to using a pointer where a
+wordsize integer type was expected.
+
address@hidden jit_prepare();
address@hidden @address@hidden
address@hidden jit_finishi(printf);
+Once the arguments to @code{printf} have been pushed, what means
+moving them to stack or register arguments, the @code{printf}
+function is called and the stack cleaned.  Note how @lightning{}
+abstracts the differences between different architectures and
+ABI's -- the client program does not know how parameter passing
+works on the host architecture.
+
address@hidden jit_epilog();
+Usually it is not required to call @code{epilog}, but because it
+is implicitly called when noticing the end of a function, if the
address@hidden variable was set with a @code{note} call after the
address@hidden, it would not consider the function epilog.
+
address@hidden myFunction((char*)jit_address(end) - (char*)jit_address(start));
+This calls the generate jit function passing as argument the offset
+difference from the @code{start} and @code{end} notes. The @code{address}
+call must be done after the @code{emit} call or either a fatal error
+will happen (if @lightning{} is built with assertions enable) or an
+undefined value will be returned.
+
address@hidden jit_disassemble();
address@hidden will dump the generated code to standard output,
+unless @lightning{} was built with the disassembler disabled, in which
+case no output will be shown.
address@hidden table
+
address@hidden RPN calculator
address@hidden A more complex example, an RPN calculator
+
+We create a small stack-based RPN calculator which applies a series
+of operators to a given parameter and to other numeric operands.
+Unlike previous examples, the code generator is fully parameterized
+and is able to compile different formulas to different functions.
+Here is the code for the expression compiler; a sample usage will
+follow.
+
+Since @lightning{} does not provide push/pop instruction, this
+example uses a stack-allocated area to store the data.  Such an
+area can be allocated using the macro @code{allocai}, which
+receives the number of bytes to allocate and returns the offset
+from the frame pointer register @code{FP} to the base of the
+area.
+
+Usually, you will use the @code{ldxi} and @code{stxi} instruction
+to access stack-allocated variables.  However, it is possible to
+use operations such as @code{add} to compute the address of the
+variables, and pass the address around.
+
address@hidden
+#include <stdio.h>
+#include <lightning.h>
+
+typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
+
+static jit_state_t *_jit;
+
+void stack_push(int reg, int *sp)
address@hidden
+  jit_stxi_i (*sp, JIT_FP, reg);
+  *sp += sizeof (int);
address@hidden
+
+void stack_pop(int reg, int *sp)
address@hidden
+  *sp -= sizeof (int);
+  jit_ldxi_i (reg, JIT_FP, *sp);
address@hidden
+
+jit_node_t *compile_rpn(char *expr)
address@hidden
+  jit_node_t *in, *fn;
+  int stack_base, stack_ptr;
+
+  fn = jit_note(NULL, 0);
+  jit_prolog();
+  in = jit_arg();
+  stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
 
+  jit_getarg_i(JIT_R2, in);
+
+  while (*expr) @{
+    char buf[32];
+    int n;
+    if (sscanf(expr, "%[0-9]%n", buf, &n)) @{
+      expr += n - 1;
+      stack_push(JIT_R0, &stack_ptr);
+      jit_movi(JIT_R0, atoi(buf));
+    @} else if (*expr == 'x') @{
+      stack_push(JIT_R0, &stack_ptr);
+      jit_movr(JIT_R0, JIT_R2);
+    @} else if (*expr == '+') @{
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_addr(JIT_R0, JIT_R1, JIT_R0);
+    @} else if (*expr == '-') @{
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_subr(JIT_R0, JIT_R1, JIT_R0);
+    @} else if (*expr == '*') @{
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_mulr(JIT_R0, JIT_R1, JIT_R0);
+    @} else if (*expr == '/') @{
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_divr(JIT_R0, JIT_R1, JIT_R0);
+    @} else @{
+      fprintf(stderr, "cannot compile: %s\n", expr);
+      abort();
+    @}
+    ++expr;
+  @}
+  jit_retr(JIT_R0);
+  jit_epilog();
+  return fn;
address@hidden
address@hidden example
+
+The principle on which the calculator is based is easy: the stack top
+is held in R0, while the remaining items of the stack are held in the
+memory area that we allocate with @code{allocai}.  Compiling a numeric
+operand or the argument @code{x} pushes the old stack top onto the
+stack and moves the operand into R0; compiling an operator pops the
+second operand off the stack into R1, and compiles the operation so
+that the result goes into R0, thus becoming the new stack top.
+
+This example allocates a fixed area for 32 @code{int}s.  This is not
+a problem when the function is a leaf like in this case; in a full-blown
+compiler you will want to analyze the input and determine the number
+of needed stack slots---a very simple example of register allocation.
+The area is then managed like a stack using @code{stack_push} and
address@hidden
+
+Source code for the client (which lies in the same source file) follows:
+
address@hidden
+int main(int argc, char *argv[])
address@hidden
+  jit_note_t *nc, *nf;
+  pifi c2f, f2c;
+  int i;
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  nc = compile_rpn("32x9*5/+");
+  nf = compile_rpn("x32-5*9/");
+  (void)jit_emit();
+  c2f = (pifi)jit_address(nc);
+  f2c = (pifi)jit_address(nf);
+
+  printf("\nC:");
+  for (i = 0; i <= 100; i += 10) printf("%3d ", i);
+  printf("\nF:");
+  for (i = 0; i <= 100; i += 10) printf("%3d ", c2f(i));
+  printf("\n");
+
+  printf("\nF:");
+  for (i = 32; i <= 212; i += 18) printf("%3d ", i);
+  printf("\nC:");
+  for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i));
+  printf("\n");
+
+  finish_jit();
+  return 0;
address@hidden
address@hidden example
+
+The client displays a conversion table between Celsius and Fahrenheit
+degrees (both Celsius-to-Fahrenheit and Fahrenheit-to-Celsius). The
+formulas are, @math{F(c) = c*9/5+32} and @math{C(f) = (f-32)*5/9},
+respectively.
+
+Providing the formula as an argument to @code{compile_rpn} effectively
+parameterizes code generation, making it possible to use the same code
+to compile different functions; this is what makes dynamic code
+generation so powerful.
+
address@hidden Fibonacci
address@hidden Fibonacci numbers
+
+The code in this section calculates a variant of the Fibonacci sequence.
+While the traditional Fibonacci sequence is modeled by the recurrence
+relation:
address@hidden
+     f(0) = f(1) = 1
+     f(n) = f(n-1) + f(n-2)
address@hidden display
+
address@hidden
+the functions in this section calculates the following sequence, which
+is more interesting as a address@hidden's because, as is
+easily seen, the sequence represents the number of activations of the
address@hidden procedure that are needed to compute its value through
+recursion.}:
address@hidden
+     fib(0) = fib(1) = 1
+     fib(n) = fib(n-1) + fib(n-2) + 1
address@hidden display
+
+The purpose of this example is to introduce branches.  There are two
+kind of branches: backward branches and forward branches.  We'll
+present the calculation in a recursive and iterative form; the
+former only uses forward branches, while the latter uses both.
+
address@hidden
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
+
+int main(int argc, char *argv[])
address@hidden
+  pifi       fib;
+  jit_node_t *label;
+  jit_node_t *call;
+  jit_node_t *in;                 @rem{/* offset of the argument */}
+  jit_node_t *ref;                @rem{/* to patch the forward reference */}
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  label = jit_label();
+        jit_prolog   ();
+  in =  jit_arg      ();
+        jit_getarg   (JIT_V0, in);              @rem{/* V0 = n */}
+  ref = jit_blti     (JIT_V0, 2);
+        jit_subi     (JIT_V1, JIT_V0, 1);       @rem{/* V1 = n-1 */}
+        jit_subi     (JIT_V2, JIT_V0, 2);       @rem{/* V2 = n-2 */}
+        jit_prepare();
+          jit_pushargr(JIT_V1);
+        call = jit_finishi(NULL);
+        jit_patch_at(call, label);
+        jit_retval(JIT_V1);                     @rem{/* V1 = fib(n-1) */}
+        jit_prepare();
+          jit_pushargr(JIT_V2);
+        call = jit_finishi(NULL);
+        jit_patch_at(call, label);
+        jit_retval(JIT_V2);                     @rem{/* V2 = fib(n-2) */}
+        jit_addi(JIT_V1,  JIT_V1,  1);
+        jit_addr(JIT_R0, JIT_V1, JIT_V2);       @rem{/* R0 = V1 + V2 + 1 */}
+        jit_retr(JIT_R0);
+
+  jit_patch(ref);                               @rem{/* patch jump */}
+        jit_movi(JIT_R0, 1);                    @rem{/* R0 = 1 */}
+        jit_retr(JIT_R0);
+
+  @rem{/* call the generated address@hidden passing 32 as an argument */}
+  fib = jit_emit();
+  printf("fib(%d) = %d\n", 32, fib(32));
+  finish_jit();
+  return 0;
address@hidden
address@hidden example
+
+As said above, this is the first example of dynamically compiling
+branches.  Branch instructions have two operands containing the
+values to be compared, and return a @code{jit_note_t *} object
+to be patched.
+
+Because labels final address are only known after calling @code{emit},
+it is required to call @code{patch} or @code{patch_at}, what does
+tell @lightning{} that the target to patch is actually a pointer to
+a @code{jit_node_t *} object, otherwise, it would assume that is
+a pointer to a C function. Note that conditional branches do not
+receive a label argument, so they must be patched.
+
+You need to call @code{patch_at} on the return of value @code{calli},
address@hidden, @code{jmpi} and @code{calli} if it is actually
+referencing a label in the jit code. All other branch instructions
+do not receive a label argument. Note that @code{movi} is an special
+case, and patching it is usually done to get the final address of
+a label, usually to later call @code{jmpr}.
+
+Now, here is the iterative version:
+
address@hidden
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
+
+int main(int argc, char *argv[])
address@hidden
+  pifi       fib;
+  jit_node_t *in;               @rem{/* offset of the argument */}
+  jit_node_t *ref;              @rem{/* to patch the forward reference */}
+  jit_node_t *jump;             @rem{/* jump to start of loop */}
+  jit_node_t *loop;             @rem{/* start of the loop */}
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+        jit_prolog   ();
+  in =  jit_arg      ();
+        jit_getarg   (JIT_R2, in);              @rem{/* R2 = n */}
+        jit_movi     (JIT_R1, 1);
+  ref = jit_blti     (JIT_R2, 2);
+        jit_subi     (JIT_R2, JIT_R2, 1);
+        jit_movi     (JIT_R0, 1);
+
+  loop= jit_label();
+        jit_subi     (JIT_R2, JIT_R2, 1);       @rem{/* decr. counter */}
+        jit_addr     (JIT_V0, JIT_R0, JIT_R1);  @rem{/* V0 = R0 + R1 */}
+        jit_movr     (JIT_R0, JIT_R1);          @rem{/* R0 = R1 */}
+        jit_addi     (JIT_R1, JIT_V0, 1);       @rem{/* R1 = V0 + 1 */}
+  jump= jit_bnei     (JIT_R2, 0);               @rem{/* if (R2) goto loop; */}
+  jit_patch_at(jump, label);
+
+  jit_patch(ref);                               @rem{/* patch forward jump */}
+        jit_movr     (JIT_R0, JIT_R1);          @rem{/* R0 = R1 */}
+        jit_retr     (JIT_R0);
+
+  @rem{/* call the generated address@hidden passing 36 as an argument */}
+  fib = jit_emit();
+  printf("fib(%d) = %d\n", 36, fib(36));
+  finish_jit();
+  return 0;
address@hidden
address@hidden example
+
+This code calculates the recurrence relation using iteration (a
address@hidden loop in high-level languages).  There are no function
+calls anymore: instead, there is a backward jump (the @code{bnei} at
+the end of the loop).
+
+Note that the program must remember the address for backward jumps;
+for forward jumps it is only required to remember the jump code,
+and call @code{patch} for the implicit label.
+
address@hidden Reentrancy
address@hidden Re-entrant usage of @lightning{}
+
address@hidden uses the special @code{_jit} identifier. To be able
+to be able to use multiple jit generation states at the same
+time, it is required to used code similar to:
+
address@hidden
+    struct jit_state lightning;
+    #define _jit lightning
address@hidden example
+
+This will cause the symbol defined to @code{_jit} to be passed as
+the first argument to the underlying @lightning{} implementation,
+that is usually a function with an @code{_} (underscode) prefix
+and with an argument named @code{_jit}, in the pattern:
+
address@hidden
+       static void _jit_mnemonic(jit_state_t *, jit_gpr_t, jit_gpr_t);
+       #define jit_mnemonic(u, v) _jit_mnemonic(_jit, u, v);
address@hidden example
+
+The reason for this is to use the same syntax as the initial lightning
+implementation and to avoid needing the user to keep adding an extra
+argument to every call, as multiple jit states generating code in
+paralell should be very uncommon.
+
address@hidden Registers
address@hidden Accessing the whole register file
+
+As mentioned earlier in this chapter, all @lightning{} back-ends are
+guaranteed to have at least six general-purpose integer registers and
+six floating-point registers, but many back-ends will have more.
+
+To access the entire register files, you can use the
address@hidden, @code{JIT_V} and @code{JIT_F} macros.  They
+accept a parameter that identifies the register number, which
+must be strictly less than @code{JIT_R_NUM}, @code{JIT_V_NUM}
+and @code{JIT_F_NUM} respectively; the number need not be
+constant.  Of course, expressions like @code{JIT_R0} and
address@hidden(0)} denote the same register, and likewise for
+integer callee-saved, or floating-point, registers.
 
 @node Acknowledgements
 @chapter Acknowledgements
@@ -298,9 +1193,3 @@ yet very interesting.
 I also thank Steve Byrne for writing GNU Smalltalk, since @lightning{}
 was first developed as a tool to be used in GNU Smalltalk's dynamic
 translator from bytecodes to native code.
-
address@hidden
address@hidden
address@hidden iftex
-
address@hidden
diff --git a/doc/ifib.c b/doc/ifib.c
new file mode 100644
index 0000000..7e098cb
--- /dev/null
+++ b/doc/ifib.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);       /* Pointer to Int Function of Int */
+
+int main(int argc, char *argv[])
+{
+  pifi       fib;
+  jit_node_t *in;               /* offset of the argument */
+  jit_node_t *ref;              /* to patch the forward reference */
+  jit_node_t *jump;             /* jump to start of loop */
+  jit_node_t *loop;             /* start of the loop */
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+        jit_prolog   ();
+  in =  jit_arg      ();
+        jit_getarg   (JIT_R2, in);              /* R2 = n */
+        jit_movi     (JIT_R1, 1);
+  ref = jit_blti     (JIT_R2, 2);
+        jit_subi     (JIT_R2, JIT_R2, 1);
+        jit_movi     (JIT_R0, 1);
+
+  loop= jit_label();
+        jit_subi     (JIT_R2, JIT_R2, 1);       /* decr. counter */
+        jit_addr     (JIT_V0, JIT_R0, JIT_R1);  /* V0 = R0 + R1 */
+        jit_movr     (JIT_R0, JIT_R1);          /* R0 = R1 */
+        jit_addi     (JIT_R1, JIT_V0, 1);       /* R1 = V0 + 1 */
+  jump= jit_bnei     (JIT_R2, 0);               /* if (R2) goto loop; */
+  jit_patch_at(jump, loop);
+
+  jit_patch(ref);                               /* patch forward jump */
+        jit_movr     (JIT_R0, JIT_R1);          /* R0 = R1 */
+        jit_retr     (JIT_R0);
+
+  /* call the generated code, passing 36 as an argument */
+  fib = jit_emit();
+  printf("fib(%d) = %d\n", 36, fib(36));
+  finish_jit();
+  return 0;
+}
diff --git a/doc/incr.c b/doc/incr.c
new file mode 100644
index 0000000..5d5e438
--- /dev/null
+++ b/doc/incr.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);    /* Pointer to Int Function of Int */
+
+int main(int argc, char *argv[])
+{
+  jit_node_t  *in;
+  pifi         incr;
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  jit_prolog();                    /* @t{     prolog             } */
+  in = jit_arg();                  /* @t{     in = arg           } */
+  jit_getarg(JIT_R0, in);          /* @t{     getarg R0          } */
+  jit_addi(JIT_R0, JIT_R0, 1);     /* @t{     addi   R0\, R0\, 1 } */
+  jit_retr(JIT_R0);                /* @t{     retr   R0          } */
+
+  incr = jit_emit();
+
+  /* call the generated code\, passing 5 as an argument */
+  printf("%d + 1 = %d\n", 5, incr(5));
+
+  finish_jit();
+  return 0;
+}
diff --git a/doc/lightning.texi b/doc/lightning.texi
index a336a3d..c7d8f98 100644
--- a/doc/lightning.texi
+++ b/doc/lightning.texi
@@ -3,11 +3,8 @@
 
 @setfilename lightning.info
 
address@hidden TITLE       Using and porting @sc{gnu} @i{lightning}
address@hidden TOPIC       installing, using and porting
address@hidden BOTH
address@hidden USING
address@hidden PORTING
address@hidden TITLE       Using @sc{gnu} @i{lightning}
address@hidden TOPIC       installing and using
 
 @settitle @value{TITLE}
 
@@ -63,29 +60,9 @@
 @c References to the other half of the manual
 @c ---------------------------------------------------------------------
 
address@hidden USING
 @macro usingref{node, name}
 @ref{\node\, , \name\}
 @end macro
address@hidden ifset
-
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\, u-lightning, Using @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\, p-lightning, Porting @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
 
 @c ---------------------------------------------------------------------
 @c End of macro section
@@ -98,3 +75,4 @@
 
 @c ***********************************************************************
 
address@hidden
diff --git a/doc/p-lightning.texi b/doc/p-lightning.texi
deleted file mode 100644
index 98a9b63..0000000
--- a/doc/p-lightning.texi
+++ /dev/null
@@ -1,100 +0,0 @@
-\input texinfo.tex  @c -*- texinfo -*-
address@hidden %**start of header (This is for running Texinfo on a region.)
-
address@hidden lightning.info
-
address@hidden TITLE       Using @sc{gnu} @i{lightning}
address@hidden TOPIC       installing and using
address@hidden BOTH
address@hidden USING
address@hidden PORTING
-
address@hidden @value{TITLE}
-
address@hidden 
---------------------------------------------------------------------
address@hidden Common macros
address@hidden 
---------------------------------------------------------------------
-
address@hidden bulletize{a}
address@hidden
-\a\
address@hidden macro
-
address@hidden rem{a}
address@hidden@i{\a\}}
address@hidden macro
-
address@hidden gnu{}
address@hidden
address@hidden macro
-
address@hidden lightning{}
address@hidden @i{lightning}
address@hidden macro
-
address@hidden 
---------------------------------------------------------------------
address@hidden Macros for Texinfo 3.1/4.0 compatibility
address@hidden 
---------------------------------------------------------------------
-
address@hidden @hlink (macro), @url and @email are used instead of @uref for 
Texinfo 3.1
address@hidden compatibility
address@hidden hlink{url, link}
-\link\ (\url\)
address@hidden macro
-
address@hidden ifhtml can only be true in Texinfo 4.0, which has uref
address@hidden
address@hidden hlink
-
address@hidden hlink{url, link}
address@hidden, \link\}
address@hidden macro
-
address@hidden email{mail}
address@hidden:\mail\, , \mail\}
address@hidden macro
-
address@hidden url{url}
address@hidden
address@hidden macro
address@hidden ifhtml
-
address@hidden 
---------------------------------------------------------------------
address@hidden References to the other half of the manual
address@hidden 
---------------------------------------------------------------------
-
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
-
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\, u-lightning, Using @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\, p-lightning, Porting @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
-
address@hidden 
---------------------------------------------------------------------
address@hidden End of macro section
address@hidden 
---------------------------------------------------------------------
-
address@hidden version.texi
address@hidden body.texi
-
address@hidden %**end of header (This is for running Texinfo on a region.)
-
address@hidden 
***********************************************************************
-
diff --git a/doc/porting.texi b/doc/porting.texi
deleted file mode 100644
index 66cd151..0000000
--- a/doc/porting.texi
+++ /dev/null
@@ -1,1600 +0,0 @@
address@hidden Structure of a port
address@hidden An overview of the porting process
-
-A particular port of @lightning{} is composed of four files. These
-have a common suffix which identifies the port (for example,
address@hidden or @code{ppc}), and a prefix that identifies their
-function; they are:
-
address@hidden @bullet
address@hidden
address@hidden@var{suffix}.h}, which contains the description of the
-target machine's instruction format.  The creation of this file
-is discussed in @ref{Run-time assemblers, , Creating the run-time
-assembler}.
-
address@hidden
address@hidden@var{suffix}.h}, which contains the mappings from
address@hidden's instruction set to the target machine's assembly
-language format.  The creation of this file is discussed in
address@hidden macros, , Creating the platform-independent layer}.
-
address@hidden
address@hidden@var{suffix}.h}, for now, only contains the definition
-of @code{jit_flush_code}. The creation of this file is briefly
-discussed in @ref{Standard functions, , More complex tasks in
-the platform-independent layer}.
-
address@hidden
address@hidden@var{suffix}.h}, which contains the description of the
-target machine's instruction format and the internal macros for doing
-floating point computation. The creation of this file is discussed
-in @ref{Floating-point macros, , Implementing macros for floating
-point}.
address@hidden itemize
-
-Before doing anything, you have to add the ability to recognize the
-new port during the configuration process.  This is explained in
address@hidden configure, , Automatically recognizing the new platform}.
-
address@hidden Adjusting configure
address@hidden Automatically recognizing the new platform
-
-Before starting your port, you have to add the ability to recognize the
-new port during the configure process.  You only have to run
address@hidden, which you'll find in the main distribution
-directory, and note down the first part of the output (up to the first
-dash).
-
-Then, in the two files @file{configure.in} and @file{lightning.m4},
-lookup the line
address@hidden
-    case "$host_cpu" in
address@hidden example
-
address@hidden
-and, right after it, add the line:
address@hidden
-    @var{cpu-name})  address@hidden           ;;
address@hidden example
-
address@hidden
-where @var{cpu-name} is the cpu as output by @file{config.guess}, and
address@hidden is the suffix that you are going to use for your files
-(@pxref{Structure of a port, , An overview of the porting process}).
-
-Now create empty files for your new port:
address@hidden
-    touch lightning/asm-xxx.h
-    touch lightning/fp-xxx.h
-    touch lightning/core-xxx.h
-    touch lightning/funcs-xxx.h
address@hidden example
-
address@hidden
-and run @file{configure}, which should create the symlinks that are
-needed by @code{lightning.h}.  This is important because it will allow
-you to use @lightning{} (albeit in a limited way) for testing even
-before the port is completed.
-
address@hidden Run-time assemblers
address@hidden Creating the run-time assembler
-
-The run-time assembler is a set of macros whose purpose is to assemble
-instructions for the target machine's assembly language, translating
-mnemonics to machine language together with their operands.  While a
-run-time assembler is not, strictly speaking, part of @lightning{}
-(it is a private layer to be used while implementing the standard
-macros that are ultimately used by clients), designing a run-time
-assembler first allows you to think in terms of assembly language
-rather than binary code (address@hidden), making it considerably easier
-to write the standard macros.
-
-Creating a run-time assembler is a tedious process rather than a
-difficult one, because most of the time will be spent collecting and
-copying information from the architecture's manual.
-
-Macros defined by a run-time assembler are conventionally named after
-the mnemonic and the type of its operands.  Examples took from the
-SPARC's run-time assembler are @code{ADDrrr}, a macro that assembles
-an @code{ADD} instruction with three register operands, and
address@hidden, which assembles a @code{SUBCC} instruction whose second
-operand is an immediate and the remaining two are registers.
-
-The first step in creating the assembler is to pick a convention for
-operand specifiers (@code{r} and @code{i} in the example above) and for
-register names.  On the SPARC, this convention is as follows
-
address@hidden @code
address@hidden @b{r}
-A register name.  For every @code{r} in the macro name, a numeric
-parameter @code{RR} is passed to the macro, and the operand is assembled
-as @address@hidden
-
address@hidden @b{i}
-An immediate, usually a 13-bit signed integer (with exception for
-instructions such as @code{SETHI} and branches).  The macros check
-the size of the passed parameter if @lightning{} is configured with
address@hidden
-
address@hidden @b{x}
-A combination of two @code{r} parameters, which are summed to determine
-the effective address in a memory load/store operation.
-
address@hidden @b{m}
-A combination of an @code{r} and @code{i} parameter, which are summed to
-determine the effective address in a memory load/store operation.
address@hidden table
-
-Additional macros can be defined that provide easier access to register
-names.  For example, on the SPARC, @code{_Ro(3)} and @code{_Rg(5)} map
-respectively to @code{%o3} and @code{%g5}; on the x86, instead, symbolic
-representations of the register names are provided (for example,
address@hidden and @code{_EBX}).
-
-CISC architectures sometimes have registers of different sizes--this is
-the case on the x86 where @code{%ax} is a 16-bit register while
address@hidden is a 32-bit one.  In this case, it can be useful to embed
-information on the size in the definition of register names.  The x86
-machine language, for example, represents all three of @code{%bh},
address@hidden and @code{%edi} as 7; but the x86 run-time assemblers defines
-them with different numbers, putting the register's size in the upper
-nybble (for example, @samp{17h} for @code{%bh} and @samp{27h} for
address@hidden) so that consistency checks can be made on the operands'
-sizes when @code{--enable-assertions} is used.
-
-The next important part defines the native architecture's instruction
-formats.  These can be as few as ten on RISC architectures, and as many
-as fifty on CISC architectures.  In the latter case it can be useful
-to define more macros for sub-formats (such as macros for different
-addressing modes) or even for sub-fields in an instruction.  Let's see
-an example of these macros.
-
address@hidden
-#define _2i( OP, RD, OP2, IMM)
-        _I((_u2 (OP )<<30)  |  (_u5(RD)<<25)  |  (_u3(OP2)<<22)  |
-            _u22(IMM)                                            )
address@hidden example
-
-The name of the macro, @code{_2i}, indicates a two-operand instruction
-comprising an immediate operand.  The instruction format is:
-
address@hidden
- .------.---------.------.-------------------------------------------.
- |  OP  |   RD    | OP2  |               IMM                         |
- |------+---------+------+-------------------------------------------|
- |2 bits|  5 bits |3 bits|             22 bits                       |
- |31-30 |  29-25  | 22-24|              0-21                         |
- '------'---------'------'-------------------------------------------'
address@hidden example
-
address@hidden provides macros named @code{_sXX(OP)} and @code{_uXX(OP)},
-where XX is a number between 1 and 31, which address@hidden when
address@hidden is used.} whether @code{OP} can be
-represented as (respectively) a signed or unsigned integer of the
-given size.  What the macro above does, then, is to shift and @sc{or}
-together the different fields, ensuring that each of them fits the field.
-
-Here is another definition, this time for the PowerPC architecture.
-
address@hidden
-#define _X(OP,RD,RA,RB,XO,RC)
-        _I((_u6 (OP)<<26)  |  (_u5(RD)<<21)  |  (_u5(RA)<<16)  |
-           ( _u5(RB)<<11)  |  (_u10(XO)<<1)  |   _u1(RC)       )
address@hidden example
-
-Here is the bit layout corresponding to this instruction format:
-
address@hidden
- .--------.--------.--------.--------.---------------------.-------.
- |    OP  |   RD   |   RA   |   RB   |           X0        |   RC  |
- |--------+--------+--------+--------+-----------------------------|
- | 6 bits | 5 bits | 5 bits | 5 bits |         10 bits     | 1 bit |
- | 31-26  | 25-21  | 16-20  | 11-15  |         1-10        |   0   |
- '--------'---------'-------'--------'-----------------------------'
address@hidden example
-
-How do these macros actually generate code? The secret lies in the
address@hidden macro, which is one of four predefined macros which actually
-store machine language instructions in memory.  They are @code{_B},
address@hidden, @code{_I} and @code{_L}, respectively for 8-bit, 16-bit,
-32-bit, and @code{long} (either 32-bit or 64-bit, depending on the
-architecture) values.
-
-Next comes another set of macros (usually the biggest) which represents
-the actual mnemonics---macros such as @code{ADDrrr} and @code{SUBCCrir},
-which were cited earlier in this chapter, belong to this set.  Most of
-the times, all these macros will do is to use the ``instruction format''
-macros, specifying the values of the fields in the different instruction
-formats.  Let's see a few of these definitions, again taken from the
-SPARC assembler:
-
address@hidden
-#define BAi(DISP)                       _2   (0, 0,  8, 2, DISP)
-#define BA_Ai(DISP)                     _2   (0, 1,  8, 2, DISP)
-
-#define SETHIir(IMM, RD)                _2i  (0, RD, 4, IMM)
-
-#define ADDrrr(RS1, RS2, RD)            _3   (2, RD,  0, RS1, 0, 0, RS2)
-#define ADDrir(RS1, IMM, RD)            _3i  (2, RD,  0, RS1, 1,    IMM)
-#define ADDCCrrr(RS1, RS2, RD)          _3   (2, RD, 16, RS1, 0, 0, RS2)
-#define ADDCCrir(RS1, IMM, RD)          _3i  (2, RD, 16, RS1, 1,    IMM)
-#define ANDrrr(RS1, RS2, RD)            _3   (2, RD,  1, RS1, 0, 0, RS2)
-#define ANDrir(RS1, IMM, RD)            _3i  (2, RD,  1, RS1, 1,    IMM)
-#define ANDCCrrr(RS1, RS2, RD)          _3   (2, RD, 17, RS1, 0, 0, RS2)
-#define ANDCCrir(RS1, IMM, RD)          _3i  (2, RD, 17, RS1, 1,    IMM)
address@hidden example
-
-A few things have to be noted.  For example:
address@hidden @bullet
address@hidden
-The SPARC assembly language sometimes uses a comma inside a mnemonic
-(for example, @code{ba,a}).  This symbol is not allowed inside a
address@hidden macro name, so it is replaced with an underscore; the same
-is done with the dots found in the PowerPC assembly language (for
-example, @code{andi.} is defined as @code{ANDI_rri}).
-
address@hidden
-It can be useful to group together instructions with the same
-instruction format, as doing this tends to make the source code
-more readable (numbers are put in the same columns).
-
address@hidden
-Using an editor without automatic wrap at end of line can be useful,
-since run-time assemblers tend to have very long lines.
address@hidden itemize
-
-A final touch is to define the synthetic instructions, which are
-usually found on RISC machines.  For example, on the SPARC, the
address@hidden instruction has two synonyms (@code{LDUW} and @code{LDSW})
-which are defined thus:
-
address@hidden
-#define LDUWxr(RS1, RS2, RD)            LDxr(RS1, RS2, RD)
-#define LDUWmr(RS1, IMM, RD)            LDmr(RS1, IMM, RD)
-#define LDSWxr(RS1, RS2, RD)            LDxr(RS1, RS2, RD)
-#define LDSWmr(RS1, IMM, RD)            LDmr(RS1, IMM, RD)
address@hidden example
-
-Other common case are instructions which take advantage of registers
-whose value is hard-wired to zero, and short-cut instructions which
-hard-code some or all of the operands:
-
address@hidden
address@hidden/* Destination is %g0\, which the processor never overwrites. */}
-#define CMPrr(R1, R2)   SUBCCrrr(R1, R2, 0) @rem{/* subcc %r1\, %r2\, %g0 */}
-
address@hidden/* One of the source registers is hard-coded to be %g0. */}
-#define NEGrr(R,S)      SUBrrr(0, R, S)     @rem{/* sub %g0\, %rR\, %rS */}
-
address@hidden/* All of the operands are hard-coded. */}
-#define RET()           JMPLmr(31,8 ,0)     @rem{/* jmpl [%r31+8]\, %g0  */}
-
address@hidden/* One of the operands acts as both source and destination */}
-#define BSETrr(R,S)     ORrrr(R, S, S)      @rem{/* or %rR\, %rS\, %rS */}
address@hidden example
-
-Specific to RISC computers, finally, is the instruction to load an
-arbitrarily sized immediate into a register.  This instruction is
-usually implemented as one or two basic instructions:
-
address@hidden
address@hidden
-If the number is small enough, an instruction is sufficient
-(@code{LI} or @code{ORI} on the PowerPC, @code{MOV} on the SPARC).
-
address@hidden
-If the lowest bits are all zeroed, an instruction is sufficient
-(@code{LIS} on the PowerPC, @code{SETHI} on the SPARC).
-
address@hidden
-Otherwise, the high bits are set first (with @code{LIS} or
address@hidden), and the result is then @sc{or}ed with the low
-bits
address@hidden enumerate
-
-Here is the definition of such an instruction for the PowerPC:
-
address@hidden
-#define MOVEIri(R,I)      (_siP(16,I) ? LIri(R,I) :     \ @rem{/* case 1    */}
-                          (_uiP(16,I) ? ORIrri(R,0,I) : \ @rem{/* case 1    */}
-                          _MOVEIri(R, _HI(I), _LO(I)) ))  @rem{/* case 2/3  */}
-
-#define _MOVEIri(H,L,R)  (LISri(R,H), (L ? ORIrri(R,R,L) : 0))
address@hidden example
-
address@hidden
-and for the SPARC:
-
address@hidden
-#define SETir(I,R)      (_siP(13,I) ? MOVir(I,R) : \
-                        _SETir(_HI(I), _LO(I), R))
-
-#define _SETir(H,L,R)   (SETHIir(H,R), (L ? ORrir(R,L,R) : 0))
address@hidden example
-
-In both cases, @code{_HI} and @code{_LO} are macros for internal use
-that extract different parts of the immediate operand.
-
-You should take a look at the run-time assemblers distributed with
address@hidden before trying to craft your own.  In particular, make
-sure you understand the RISC run-time assemblers (the SPARC's is
-the simplest) before trying to decypher the x86 run-time assembler,
-which is significantly more complex.
-
-
address@hidden Standard macros
address@hidden Creating the platform-independent layer
-
-The platform-independent layer is the one that is ultimately used
-by @lightning{} clients.  Creating this layer is a matter of creating
-a hundred or so macros that comprise part of the interface used by
-the clients, as described in
address@hidden instruction set, @lightning{}'s instruction set}.
-
-Fortunately, a number of these definitions are common to the different
-platforms and are defined just once in one of the header files that
-make up @lightning{}, that is, @file{core-common.h}.
-
-Most of the macros are relatively straight-forward to implement (with
-a few caveats for architectures whose assembly language only offers
-two-operand arithmetic instructions).  This section will cover the
-tricky points, before presenting the complete listing of the macros
-that make up the platform-independent interface provided by
address@hidden
-
address@hidden
address@hidden
address@hidden menu
-
address@hidden Forward references
address@hidden Implementing forward references
-
-Implementation of forward references takes place in:
-
address@hidden @bullet
address@hidden
-The branch macros
-
address@hidden
-The @code{jit_patch_at} macros
address@hidden itemize
-
-Roughly speaking, the branch macros, as seen in @usingref{GNU lightning
-macros, Generating code at run-time}, return a value that later calls
-to @code{jit_patch} or @code{jit_patch_at} use to complete the assembly
-of the forward reference.  This value is usually the contents of the
-program counter after the branch instruction is compiled (which is
-accessible in the @code{_jit.pc} variable).  Let's see an example from
-the x86 back-end:
-
address@hidden
-#define jit_bmsr_i(label, s1, s2)                            \
-   (TESTLrr((s1), (s2)), JNZm(label,0,0,0), _jit.pc)
address@hidden example
-
-The @code{bms} (@dfn{branch if mask set}) instruction is assembled as
-the combination of a @code{TEST} instruction (bit-wise @sc{and} between
-the two operands) and a @code{JNZ} instruction (jump if non-zero).  The
-macro then returns the final value of the program counter.
-
address@hidden is one of the few macros that need to possess a
-knowledge of the machine's instruction formats.  Its purpose is to
-patch a branch instruction (identified by the value returned at the
-moment the branch was compiled) to jump to the current position (that
-is, to the address identified by @code{_jit.pc}).
-
-On the x86, the displacement between the jump and the landing point is
-expressed as a 32-bit signed integer lying in the last four bytes of the
-jump instruction.  The definition of @code{_jit_patch_at} is:
-
address@hidden
-#define jit_patch(jump_pc, pv)    (*_PSL((jump_pc) - 4) = \
-                                  (pv) - (jump_pc))
address@hidden example
-
-The @code{_PSL} macro is nothing more than a cast to @code{long *},
-and is used here to shorten the definition and avoid cluttering it with
-excessive parentheses.  These type-cast macros are:
-
address@hidden @bullet
address@hidden
address@hidden(X)} to cast to a @code{unsigned char *}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned short *}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned int *}.
-
address@hidden
address@hidden(X)} to cast to a @code{long *}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned long *}.
address@hidden itemize
-
-On other platforms, notably RISC ones, the displacement is embedded into
-the instruction itself.  In this case, @code{jit_patch_at} must first zero
-out the field, and then @sc{or} in the correct displacement.  The SPARC,
-for example, encodes the displacement in the bottom 22 bits; in addition
-the right-most two bits are suppressed, which are always zero because
-instruction have to be word-aligned.
-
address@hidden
-#define jit_patch_at(delay_pc, pv)   jit_patch_ (((delay_pc) - 1), (pv))
-
address@hidden/* branch instructions return the address of the @emph{delay}
- * instruction---this is just a helper macro that makes the code more
- * readable.
- */}
-#define jit_patch_(jump_pc, pv)   (*jump_pc =              \
-        (*jump_pc & ~_MASK(22)) |                          \
-         ((_UL(pv) - _UL(jump_pc)) >> 2) & _MASK(22))
address@hidden example
-
-This introduces more predefined shortcut macros:
address@hidden @bullet
address@hidden
address@hidden(X)} to cast to a @code{unsigned char}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned short}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned int}.
-
address@hidden
address@hidden(X)} to cast to a @code{long}.
-
address@hidden
address@hidden(X)} to cast to a @code{unsigned long}.
-
address@hidden
address@hidden(N)} gives a binary number made of N ones.
address@hidden itemize
-
-Dual to branches and @code{jit_patch_at} are @code{jit_movi_p}
-and @code{jit_patch_movi}, since they can also be used to implement
-forward references.  @code{jit_movi_p} should be carefully implemented
-to use an encoding that is as long as possible, and it should return
-an address which is then passed to @code{jit_patch_movi}.  The
-implementation of @code{jit_patch_movi} is similar to
address@hidden
-
address@hidden Common features
address@hidden Common features supported by @file{core-common.h}
-
-The @file{core-common.h} file contains hundreds of macro definitions
-which will spare you defining a lot of things in the files the are
-specific to your port.  Here is a list of the features that 
address@hidden provides.
-
address@hidden @b
address@hidden Support for common synthetic instructions
-These are instructions that can be represented as a simple operation,
-for example a bit-wise @sc{and} or a subtraction.  @file{core-common.h}
-recognizes when the port-specific header file defines these macros and
-avoids compiler warnings about redefined macros, but there should be
-no need to define them.  They are:
address@hidden
-#define jit_extr_c_ui(d, rs)
-#define jit_extr_s_ui(d, rs)
-#define jit_extr_c_ul(d, rs)
-#define jit_extr_s_ul(d, rs)
-#define jit_extr_i_ul(d, rs)
-#define jit_negr_i(d, rs)
-#define jit_negr_l(d, rs)
address@hidden example
-
address@hidden Support for the @sc{abi}
-All of @code{jit_prolog}, @code{jit_leaf} and @code{jit_finish} are not
-mandatory.  If not defined, they will be defined respectively as an
-empty macro, as a synonym for @code{jit_prolog}, and as a synonym for
address@hidden  Whether to define them or not in the port-specific
-header file, it depends on the underlying architecture's @sc{abi}---in
-general, however, you'll need to define at least @code{jit_prolog}.
-
address@hidden Support for uncommon instructions
-These are instructions that many widespread architectures lack.
address@hidden is able to provide default definitions, but they
-are usually inefficient if the hardware provides a way to do these
-operations with a single instruction.  They are extension with sign
-and ``reverse subtraction'' (that is, address@hidden@math{-}REG1):
address@hidden
-#define jit_extr_c_i(d, rs)
-#define jit_extr_s_i(d, rs)
-#define jit_extr_c_l(d, rs)
-#define jit_extr_s_l(d, rs)
-#define jit_extr_i_l(d, rs)
-#define jit_rsbi_i(d, rs, is)
-#define jit_rsbi_l(d, rs, is)
-#define jit_rsbi_p(d, rs, is)
address@hidden example
-
address@hidden Conversion between network and host byte ordering
-These macros are no-ops on big endian systems.  Don't define them on
-such systems; on the other hand, they are mandatory on little endian
-systems.  They are:
address@hidden
-#define jit_ntoh_ui(d, rs)
-#define jit_ntoh_us(d, rs)
address@hidden example
-
address@hidden Support for a ``zero'' register
-Many RISC architectures provide a read-only register whose value is
-hard-coded to be zero; this register is then used implicitly when
-referring to a memory location using a single register.  For example,
-on the SPARC, an operand like @code{[%l6]} is actually assembled as
address@hidden  If this is the case, you should define
address@hidden to be the number of this register; @file{core-common.h}
-will use it to implement all variations of the @code{ld} and @code{st}
-instructions.  For example:
address@hidden
-#define jit_ldi_c(d, is)         jit_ldxi_c(d, JIT_RZERO, is)
-#define jit_ldr_i(d, rs)         jit_ldxr_c(d, JIT_RZERO, rs)
address@hidden example
-
-If available, JIT_RZERO is also used to provide more efficient
-definitions of the @code{neg} instruction (see ``Support for common
-synthetic instructions'', above).
-
address@hidden Synonyms
address@hidden provides a lot of trivial definitions which make
-the instruction set as orthogonal as possible.  For example, adding two
-unsigned integers is exactly the same as adding two signed integers
-(assuming a two's complement representation of negative numbers); yet,
address@hidden provides both @code{jit_addr_i} and @code{jit_addr_ui}
-macros.  Similarly, pointers and unsigned long integers behave in the
-same way, but @lightning{} has separate instruction for the two data
-types---those that operate on pointers usually include a typecast
-that makes programs clearer.
-
address@hidden Shortcuts
-These define ``synthetic'' instructions whose definition is not as
-trivial as in the case of synonyms, but is anyway standard.  This
-is the case for bitwise @sc{not} (which is implemented by XORing a
-string of ones), ``reverse subtraction'' between registers (which is
-converted to a normal subtraction with the two source operands
-inverted), and subtraction of an immediate from a register (which is
-converted to an addition).  Unlike @code{neg} and @code{ext} (see
-``Support for common synthetic instructions'', above), which are
-simply non-mandatory, you must not define these functions.
-
address@hidden Support for @code{long}s
-On most systems, @code{long}s and @code{unsigned long}s are the same
-as, respectively, @code{int}s and @code{unsigned int}s.  In this case,
address@hidden defines operations on these types to be synonyms.
-
address@hidden @code{jit_state}
-Last but not least, @file{core-common.h} defines the @code{jit_state}
-type.  Part of this @code{struct} is machine-dependent and includes
-all kinds of state needed by the back-end; this part is always
-accessible in a re-entrant way as @code{_jitl}.  @code{_jitl} will be
-of type @code{struct jit_local_state}; this struct must be defined
-even if no state is required.
-
address@hidden table
-
address@hidden Delay slots
address@hidden Supporting scheduling of delay slots
-
-Delay slot scheduling is obtained by clients through the
address@hidden macro.  However this macro is not to be defined
-in the platform-independent layer, because @lightning{} provides
-a common definition in @file{core-common.h}.
-
-Instead, the platform-independent layer must define another macro,
-called @code{jit_fill_delay_after}, which has to exchange the
-instruction to be scheduled in the delay slot with the branch
-instruction.  The only parameter accepted by the macro is a call
-to a branch macro, which must be expanded @strong{exactly once} by
address@hidden  The client must be able to pass the
-return value of @code{jit_fill_delay_after} to @code{jit_patch_at}.
-
-There are two possible approaches that can be used in
address@hidden  They are summarized in the following
-pictures:
-
address@hidden @bullet
address@hidden
-The branch instructions assemble a @sc{nop} instruction which is
-then removed by @code{jit_fill_delay_after}.
-
address@hidden
-     before                         |   after
-   ---------------------------------+-----------------------------
-     ...                            |
-     <would-be delay instruction>   |    <branch instruction>
-     <branch instruction>           |    <delay instruction>
-     NOP                            |           <--- _jit.pc
-              <--- _jit.pc          |
address@hidden example
-
address@hidden
-The branch instruction assembles the branch so that the delay
-slot is annulled, @code{jit_fill_delay_after} toggles the bit:
-
address@hidden
-     before                         |   after
-   ---------------------------------+-----------------------------
-     ...                            |
-     <would-be delay instruction>   |    <branch instruction>
-     <branch with annulled delay>   |    <delay instruction>
-              <--- _jit.pc          |           <--- _jit.pc
address@hidden example
address@hidden itemize
-
-Don't forget that you can take advantage of delay slots in the
-implementation of boolean instructions such as @code{le} or @code{gt}.
-
address@hidden Immediate values
address@hidden Supporting arbitrarily sized immediate values
-
-This is a problem that is endemic to RISC machines.  The basic idea
-is to reserve one or two register to represent large immediate values.
-Let's see an example from the SPARC:
-
address@hidden
-   addi_i R0, V2, 45         |  addi_i R0, V2, 10000
-  ---------------------------+---------------------------
-   add    %l5, 45, %l0       |  set    10000, %l6
-                             |  add    %l5, %l6, %l0
address@hidden example
-
-In this case, @code{%l6} is reserved to be used for large immediates.
-An elegant solution is to use an internal macro which automatically
-decides which version is to be compiled.
-
-Beware of register conflicts on machines with delay slots.  This is
-the case for the SPARC, where @code{%l7} is used instead for large
-immediates in compare-and-branch instructions.  So the sequence
-
address@hidden
-   jit_delay(
-      jit_addi_i(JIT_R0, JIT_V2, 10000),
-      jit_blei_i(label, JIT_R1, 20000)
-   );
address@hidden example
-
address@hidden
-is assembled this way:
-
address@hidden
-   set 10000, %l6       @rem{! prepare immediate for add}
-   set 20000, %l7       @rem{! prepare immediate for cmp}
-   cmp %l1, %l7
-   ble label
-   add %l5, %l6, %l0    @rem{! delay slot}
-       @end example
-
-Note that using @code{%l6} in the branch instruction would have given
-an incorrect address@hidden would have been filled with the value of
address@hidden@i{20000}} rather than @address@hidden
-
address@hidden Implementing the ABI
address@hidden Implementing the ABI
-
-Implementing the underlying architecture's @sc{abi} is done in the
-macros that handle function prologs and epilogs and argument passing.
-
-Let's look at the prologs and epilogs first.  These are usually pretty
-simple and, what's more important, with constant content---that is,
-they always generate exactly the same instruction sequence.  Here is
-an example:
-
address@hidden
-          SPARC                        x86
-          save %sp, -96, %sp           push %ebp
-                                       push %ebx
-                                       push %esi
-                                       push %edi
-                                       movl %esp, %ebp
-          ...                          ...
-          ret                          popl %edi
-          restore                      popl %esi
-                                       popl %ebx
-                                       popl %ebp
-                                       ret
address@hidden example
-
-The registers that are saved (@code{%ebx}, @code{%esi}, @code{%edi}) are
-mapped to the @code{V0} through @code{V2} registers in the @lightning{}
-instruction set.
-
-Argument passing is more tricky.  There are basically three
address@hidden speed and ease of implementation, @lightning{} does not
-currently support passing some of the parameters on the stack and some
-in registers.}:
address@hidden @b
address@hidden Register windows
-Output registers are different from input registers---the prolog takes
-care of moving the caller's output registers to the callee's input
-registers.  This is the case with the SPARC.
-
address@hidden Passing parameters via registers
-In this case, output registers are the same as input registers.  The
-program must take care of saving input parameters somewhere (on the
-stack, or in non-argument registers).  This is the case with the
-PowerPC.
-
address@hidden All the parameters are passed on the stack
-This case is by far the simplest and is the most common in CISC
-architectures, like the x86 and Motorola 68000.
address@hidden table
-
-In all cases, the port-specific header file will define two variable
-for private use---one to be used by the caller during the
address@hidden/@code{pusharg}/@code{finish} sequence, one to be used
-by the callee, specifically in the @code{jit_prolog} and @code{jit_arg}
-macros.
-
-Let's look again, this time with more detail, at each of the cases.
-
address@hidden @b
address@hidden Register windows
address@hidden is the same as @code{jit_calli}, and is defined
-in @file{core-common.h} (@pxref{Common features, , Common features
-supported by @file{core-common.h}}).
-
address@hidden
-#define jit_prepare_i(numargs)  (_jitl.pusharg = _Ro(numargs))
-#define jit_pusharg_i(rs)       (--_jitl.pusharg,         \
-                                 MOVrr((rs), _jitl.pusharg))
address@hidden example
-
-Remember that arguments pushing takes place in reverse order, thus
-giving a pre-decrement (rather than post-increment) in
address@hidden
-
-Here is what happens on the callee's side:
-
address@hidden
-#define jit_arg_c()           (_jitl.getarg++)
-#define jit_getarg_c(rd, ofs) jit_extr_c_i  ((rd), (ofs))
-#define jit_prolog(numargs)   (SAVErir(JIT_SP, -96, JIT_SP), \
-                               _jitl.getarg = _Ri(0))
address@hidden example
-
-The @code{jit_arg} macros return nothing more than a register index,
-which is then used by the @code{jit_getarg} macros.  @code{jit_prolog}
-resets the counter used by @code{jit_arg} to zero; the @code{numargs}
-parameter is not used. It is sufficient for @code{jit_leaf} to be a
-synonym for @code{jit_prolog}.
-
address@hidden Passing parameter via registers
-The code is almost the same as that for the register windows case, but
-with an additional address@hidden will transfer the
-argument from the input register to a non-argument register so that
-function calls will not clobber it.  The prolog and epilog code can then
-become unbearably long, up to 20 instructions on the PPC; a common
-solution in this case is that of @dfn{trampolines}.
-
-The prolog does nothing more than put the function's actual address in a
-caller-preserved register and then call the trampoline:
address@hidden
-       mflr    r0                 @rem{! grab return address}
-       movei   r10, trampo_2args  @rem{! jump to trampoline}
-       mtlr    r10
-       blrl
-here:  mflr    r31                @rem{! r31 = address of epilog}
-       @rem{...actual code...}
-       mtlr    r31                @rem{! return to the trampoline}
-       blr
address@hidden example
-
-In this case, @code{jit_prolog} does use its argument containing the
-number of parameters to pick the appropriate trampoline. Here,
address@hidden is the address of a trampoline designed for
-2-argument functions.
-
-The trampoline executes the prolog code, jumps to the contents of
address@hidden, and upon return from the subroutine it executes the
-epilog code.
-
address@hidden All the parameters are passed on the stack
address@hidden uses a hardware push operation, which is commonly
-available on CISC machines (where this approach is most likely
-followed).  Since the stack has to be cleaned up after the call,
address@hidden remembers how many parameters have been put there,
-and @code{jit_finish} adjusts the stack pointer after the call.
-
address@hidden
-#define jit_prepare_i(numargs) (_jitl.args += (numargs))
-#define jit_pusharg_i(rs)      PUSHLr(rs)
-#define jit_finish(sub)        (jit_calli((sub)),              \
-                               ADDLir(4 * _jitl.args, JIT_SP), \
-                               _jitl.numargs = 0)
address@hidden example
-
-Note the usage of @code{+=} in @code{jit_prepare_i}.  This is done
-so that one can defer the popping of the arguments that were saved
-on the stack (@dfn{stack pollution}).  To do so, it is sufficient to
-use @code{jit_calli} instead of @code{jit_finish} in all but the
-last call.
-
-On the caller's side, @code{arg} returns an offset relative to the
-frame pointer, and @code{getarg} loads the argument from the stack:
-
address@hidden
-#define jit_getarg_c(rd, ofs) jit_ldxi_c((rd), _EBP, (ofs));
-#define jit_arg_c()           ((_jitl.frame += sizeof(int) \
-                                            -  sizeof(int))
address@hidden example
-
-The @code{_jitl.frame} variable is initialized by @code{jit_prolog}
-with the displacement between the value of the frame pointer
-(@code{%ebp}) and the address of the first parameter.
address@hidden table
-
-These schemes are the most used, so @file{core-common.h} provides a way
-to employ them automatically.  If you do not define the
address@hidden macro and its companions, @file{core-common.h} will
-presume that you intend to pass parameters through either the registers
-or the stack.
-
-If you define @code{JIT_AP}, stack-based parameter passing will be
-employed and the @code{jit_getarg} macros will be defined like this:
-
address@hidden
-#define jit_getarg_c(reg, ofs)  jit_ldxi_c((reg), JIT_AP, (ofs));
address@hidden example
-
-In other words, the @code{jit_arg} macros (which are still to be defined
-by the platform-specific back-end) shall return an offset into the stack
-frame.  On the other hand, if you don't define @code{JIT_AP},
-register-based parameter passing will be employed and the @code{jit_arg}
-macros shall return a register number; in this case, @code{jit_getarg}
-will be implemented in terms of @code{jit_extr} and @code{jit_movr}
-operations:
-
address@hidden
-#define jit_getarg_c(reg, ofs)         jit_extr_c_i  ((reg), (ofs))
-#define jit_getarg_i(reg, ofs)         jit_movr_i    ((reg), (ofs))
address@hidden example
-
-
address@hidden Macro list
address@hidden Macros composing the platform-independent layer
-
address@hidden @b
address@hidden Register names (all mandatory but the last three)
address@hidden
-#define JIT_R
-#define JIT_R_NUM
-#define JIT_V
-#define JIT_V_NUM
-#define JIT_FPR
-#define JIT_FPR_NUM
-#define JIT_FP
-#define JIT_SP
-#define JIT_AP
-#define JIT_RZERO
address@hidden example
-
address@hidden Helper macros (non-mandatory):
address@hidden
-#define jit_fill_delay_after(branch)
address@hidden example
-
address@hidden Mandatory:
address@hidden
-#define jit_allocai()
-#define jit_arg_c()
-#define jit_arg_i()
-#define jit_arg_l()
-#define jit_arg_p()
-#define jit_arg_s()
-#define jit_arg_uc()
-#define jit_arg_ui()
-#define jit_arg_ul()
-#define jit_arg_us()
-#define jit_abs_d(rd,rs)
-#define jit_addi_i(d, rs, is)
-#define jit_addr_d(rd,s1,s2)
-#define jit_addr_i(d, s1, s2)
-#define jit_addxi_i(d, rs, is)
-#define jit_addxr_i(d, s1, s2)
-#define jit_andi_i(d, rs, is)
-#define jit_andr_i(d, s1, s2)
-#define jit_beqi_i(label, rs, is)
-#define jit_beqr_d(label, s1, s2)
-#define jit_beqr_i(label, s1, s2)
-#define jit_bgei_i(label, rs, is)
-#define jit_bgei_ui(label, rs, is)
-#define jit_bger_d(label, s1, s2)
-#define jit_bger_i(label, s1, s2)
-#define jit_bger_ui(label, s1, s2)
-#define jit_bgti_i(label, rs, is)
-#define jit_bgti_ui(label, rs, is)
-#define jit_bgtr_d(label, s1, s2)
-#define jit_bgtr_i(label, s1, s2)
-#define jit_bgtr_ui(label, s1, s2)
-#define jit_blei_i(label, rs, is)
-#define jit_blei_ui(label, rs, is)
-#define jit_bler_d(label, s1, s2)
-#define jit_bler_i(label, s1, s2)
-#define jit_bler_ui(label, s1, s2)
-#define jit_bltgtr_d(label, s1, s2)
-#define jit_blti_i(label, rs, is)
-#define jit_blti_ui(label, rs, is)
-#define jit_bltr_d(label, s1, s2)
-#define jit_bltr_i(label, s1, s2)
-#define jit_bltr_ui(label, s1, s2)
-#define jit_bmci_i(label, rs, is)
-#define jit_bmcr_i(label, s1, s2)
-#define jit_bmsi_i(label, rs, is)
-#define jit_bmsr_i(label, s1, s2)
-#define jit_bnei_i(label, rs, is)
-#define jit_bner_d(label, s1, s2)
-#define jit_bner_i(label, s1, s2)
-#define jit_boaddi_i(label, rs, is)
-#define jit_boaddi_ui(label, rs, is)
-#define jit_boaddr_i(label, s1, s2)
-#define jit_boaddr_ui(label, s1, s2)
-#define jit_bordr_d(label, s1, s2)
-#define jit_bosubi_i(label, rs, is)
-#define jit_bosubi_ui(label, rs, is)
-#define jit_bosubr_i(label, s1, s2)
-#define jit_bosubr_ui(label, s1, s2)
-#define jit_buneqr_d(label, s1, s2)
-#define jit_bunger_d(label, s1, s2)
-#define jit_bungtr_d(label, s1, s2)
-#define jit_bunler_d(label, s1, s2)
-#define jit_bunltr_d(label, s1, s2)
-#define jit_bunordr_d(label, s1, s2)
-#define jit_calli(label)
-#define jit_callr(label)
-#define jit_ceilr_d_i(rd, rs)
-#define jit_divi_i(d, rs, is)
-#define jit_divi_ui(d, rs, is)
-#define jit_divr_d(rd,s1,s2)
-#define jit_divr_i(d, s1, s2)
-#define jit_divr_ui(d, s1, s2)
-#define jit_eqi_i(d, rs, is)
-#define jit_eqr_d(d, s1, s2)
-#define jit_eqr_i(d, s1, s2)
-#define jit_extr_i_d(rd, rs)
-#define jit_floorr_d_i(rd, rs)
-#define jit_gei_i(d, rs, is)
-#define jit_gei_ui(d, s1, s2)
-#define jit_ger_d(d, s1, s2)
-#define jit_ger_i(d, s1, s2)
-#define jit_ger_ui(d, s1, s2)
-#define jit_gti_i(d, rs, is)
-#define jit_gti_ui(d, s1, s2)
-#define jit_gtr_d(d, s1, s2)
-#define jit_gtr_i(d, s1, s2)
-#define jit_gtr_ui(d, s1, s2)
-#define jit_hmuli_i(d, rs, is)
-#define jit_hmuli_ui(d, rs, is)
-#define jit_hmulr_i(d, s1, s2)
-#define jit_hmulr_ui(d, s1, s2)
-#define jit_jmpi(label)
-#define jit_jmpr(reg)
-#define jit_ldxi_f(rd, rs, is)
-#define jit_ldxr_f(rd, s1, s2)
-#define jit_ldxi_c(d, rs, is)
-#define jit_ldxi_d(rd, rs, is)
-#define jit_ldxi_i(d, rs, is)
-#define jit_ldxi_s(d, rs, is)
-#define jit_ldxi_uc(d, rs, is)
-#define jit_ldxi_us(d, rs, is)
-#define jit_ldxr_c(d, s1, s2)
-#define jit_ldxr_d(rd, s1, s2)
-#define jit_ldxr_i(d, s1, s2)
-#define jit_ldxr_s(d, s1, s2)
-#define jit_ldxr_uc(d, s1, s2)
-#define jit_ldxr_us(d, s1, s2)
-#define jit_lei_i(d, rs, is)
-#define jit_lei_ui(d, s1, s2)
-#define jit_ler_d(d, s1, s2)
-#define jit_ler_i(d, s1, s2)
-#define jit_ler_ui(d, s1, s2)
-#define jit_lshi_i(d, rs, is)
-#define jit_lshr_i(d, r1, r2)
-#define jit_ltgtr_d(d, s1, s2)
-#define jit_lti_i(d, rs, is)
-#define jit_lti_ui(d, s1, s2)
-#define jit_ltr_d(d, s1, s2)
-#define jit_ltr_i(d, s1, s2)
-#define jit_ltr_ui(d, s1, s2)
-#define jit_modi_i(d, rs, is)
-#define jit_modi_ui(d, rs, is)
-#define jit_modr_i(d, s1, s2)
-#define jit_modr_ui(d, s1, s2)
-#define jit_movi_d(rd,immd)
-#define jit_movi_f(rd,immf)
-#define jit_movi_i(d, is)
-#define jit_movi_p(d, is)
-#define jit_movr_d(rd,rs)
-#define jit_movr_i(d, rs)
-#define jit_muli_i(d, rs, is)
-#define jit_muli_ui(d, rs, is)
-#define jit_mulr_d(rd,s1,s2)
-#define jit_mulr_i(d, s1, s2)
-#define jit_mulr_ui(d, s1, s2)
-#define jit_negr_d(rd,rs)
-#define jit_nei_i(d, rs, is)
-#define jit_ner_d(d, s1, s2)
-#define jit_ner_i(d, s1, s2)
-#define jit_nop()
-#define jit_ordr_d(d, s1, s2)
-#define jit_ori_i(d, rs, is)
-#define jit_orr_i(d, s1, s2)
-#define jit_patch_at(jump_pc, value)
-#define jit_patch_movi(jump_pc, value)
-#define jit_prepare_d(numargs)
-#define jit_prepare_f(numargs)
-#define jit_prepare_i(numargs)
-#define jit_pusharg_i(rs)
-#define jit_ret()
-#define jit_retval_i(rd)
-#define jit_roundr_d_i(rd, rs)
-#define jit_rshi_i(d, rs, is)
-#define jit_rshi_ui(d, rs, is)
-#define jit_rshr_i(d, r1, r2)
-#define jit_rshr_ui(d, r1, r2)
-#define jit_sqrt_d(rd,rs)
-#define jit_stxi_c(id, rd, rs)
-#define jit_stxi_d(id, rd, rs)
-#define jit_stxi_f(id, rd, rs)
-#define jit_stxi_i(id, rd, rs)
-#define jit_stxi_s(id, rd, rs)
-#define jit_stxr_c(d1, d2, rs)
-#define jit_stxr_d(d1, d2, rs)
-#define jit_stxr_f(d1, d2, rs)
-#define jit_stxr_i(d1, d2, rs)
-#define jit_stxr_s(d1, d2, rs)
-#define jit_subr_d(rd,s1,s2)
-#define jit_subr_i(d, s1, s2)
-#define jit_subxi_i(d, rs, is)
-#define jit_subxr_i(d, s1, s2)
-#define jit_truncr_d_i(rd, rs)
-#define jit_uneqr_d(d, s1, s2)
-#define jit_unger_d(d, s1, s2)
-#define jit_ungtr_d(d, s1, s2)
-#define jit_unler_d(d, s1, s2)
-#define jit_unltr_d(d, s1, s2)
-#define jit_unordr_d(d, s1, s2)
-#define jit_xori_i(d, rs, is)
-#define jit_xorr_i(d, s1, s2)
address@hidden example
-
address@hidden Non mandatory---there should be no need to define them:
address@hidden
-#define jit_extr_c_ui(d, rs)
-#define jit_extr_s_ui(d, rs)
-#define jit_extr_c_ul(d, rs)
-#define jit_extr_s_ul(d, rs)
-#define jit_extr_i_ul(d, rs)
-#define jit_negr_i(d, rs)
-#define jit_negr_l(d, rs)
address@hidden example
-
address@hidden Non mandatory---whether to define them depends on the @sc{abi}:
address@hidden
-#define jit_prolog(n)
-#define jit_finish(sub)
-#define jit_finishr(reg)
-#define jit_leaf(n)
-#define jit_getarg_c(reg, ofs)
-#define jit_getarg_i(reg, ofs)
-#define jit_getarg_l(reg, ofs)
-#define jit_getarg_p(reg, ofs)
-#define jit_getarg_s(reg, ofs)
-#define jit_getarg_uc(reg, ofs)
-#define jit_getarg_ui(reg, ofs)
-#define jit_getarg_ul(reg, ofs)
-#define jit_getarg_us(reg, ofs)
-#define jit_getarg_f(reg, ofs)
-#define jit_getarg_d(reg, ofs)
address@hidden example
-
address@hidden Non mandatory---define them if instructions that do this exist:
address@hidden
-#define jit_extr_c_i(d, rs)
-#define jit_extr_s_i(d, rs)
-#define jit_extr_c_l(d, rs)
-#define jit_extr_s_l(d, rs)
-#define jit_extr_i_l(d, rs)
-#define jit_rsbi_i(d, rs, is)
-#define jit_rsbi_l(d, rs, is)
address@hidden example
-
address@hidden Non mandatory if condition code are always set by add/sub, 
needed on other systems:
address@hidden
-#define jit_addci_i(d, rs, is)
-#define jit_addci_l(d, rs, is)
-#define jit_subci_i(d, rs, is)
-#define jit_subci_l(d, rs, is)
address@hidden example
-
address@hidden Mandatory on little endian systems---don't define them on other 
systems:
address@hidden
-#define jit_ntoh_ui(d, rs)
-#define jit_ntoh_us(d, rs)
address@hidden example
-
address@hidden Mandatory if JIT_RZERO not defined---don't define them if it is 
defined:
address@hidden
-#define jit_ldi_c(d, is)
-#define jit_ldi_i(d, is)
-#define jit_ldi_s(d, is)
-#define jit_ldr_c(d, rs)
-#define jit_ldr_i(d, rs)
-#define jit_ldr_s(d, rs)
-#define jit_ldi_uc(d, is)
-#define jit_ldi_ui(d, is)
-#define jit_ldi_us(d, is)
-#define jit_ldr_uc(d, rs)
-#define jit_ldr_ui(d, rs)
-#define jit_ldr_us(d, rs)
-#define jit_sti_c(id, rs)
-#define jit_sti_i(id, rs)
-#define jit_sti_s(id, rs)
-#define jit_str_c(rd, rs)
-#define jit_str_i(rd, rs)
-#define jit_str_s(rd, rs)
-#define jit_ldi_f(rd, is)
-#define jit_sti_f(id, rs)
-#define jit_ldi_d(rd, is)
-#define jit_sti_d(id, rs)
-#define jit_ldr_f(rd, rs)
-#define jit_str_f(rd, rs)
-#define jit_ldr_d(rd, rs)
-#define jit_str_d(rd, rs)
address@hidden example
-
address@hidden Synonyms---don't define them:
address@hidden
-#define jit_addi_p(d, rs, is)
-#define jit_addi_ui(d, rs, is)
-#define jit_addi_ul(d, rs, is)
-#define jit_addr_p(d, s1, s2)
-#define jit_addr_ui(d, s1, s2)
-#define jit_addr_ul(d, s1, s2)
-#define jit_andi_ui(d, rs, is)
-#define jit_andi_ul(d, rs, is)
-#define jit_andr_ui(d, s1, s2)
-#define jit_andr_ul(d, s1, s2)
-#define jit_beqi_p(label, rs, is)
-#define jit_beqi_ui(label, rs, is)
-#define jit_beqi_ul(label, rs, is)
-#define jit_beqr_p(label, s1, s2)
-#define jit_beqr_ui(label, s1, s2)
-#define jit_beqr_ul(label, s1, s2)
-#define jit_bmci_ui(label, rs, is)
-#define jit_bmci_ul(label, rs, is)
-#define jit_bmcr_ui(label, s1, s2)
-#define jit_bmcr_ul(label, s1, s2)
-#define jit_bmsi_ui(label, rs, is)
-#define jit_bmsi_ul(label, rs, is)
-#define jit_bmsr_ui(label, s1, s2)
-#define jit_bmsr_ul(label, s1, s2)
-#define jit_bgei_p(label, rs, is)
-#define jit_bger_p(label, s1, s2)
-#define jit_bgti_p(label, rs, is)
-#define jit_bgtr_p(label, s1, s2)
-#define jit_blei_p(label, rs, is)
-#define jit_bler_p(label, s1, s2)
-#define jit_blti_p(label, rs, is)
-#define jit_bltr_p(label, s1, s2)
-#define jit_bnei_p(label, rs, is)
-#define jit_bnei_ui(label, rs, is)
-#define jit_bnei_ul(label, rs, is)
-#define jit_bner_p(label, s1, s2)
-#define jit_bner_ui(label, s1, s2)
-#define jit_bner_ul(label, s1, s2)
-#define jit_eqi_p(d, rs, is)
-#define jit_eqi_ui(d, rs, is)
-#define jit_eqi_ul(d, rs, is)
-#define jit_eqr_p(d, s1, s2)
-#define jit_eqr_ui(d, s1, s2)
-#define jit_eqr_ul(d, s1, s2)
-#define jit_extr_c_s(d, rs)
-#define jit_extr_c_us(d, rs)
-#define jit_extr_uc_s(d, rs)
-#define jit_extr_uc_us(d, rs)
-#define jit_extr_uc_i(d, rs)
-#define jit_extr_uc_ui(d, rs)
-#define jit_extr_us_i(d, rs)
-#define jit_extr_us_ui(d, rs)
-#define jit_extr_uc_l(d, rs)
-#define jit_extr_uc_ul(d, rs)
-#define jit_extr_us_l(d, rs)
-#define jit_extr_us_ul(d, rs)
-#define jit_extr_ui_l(d, rs)
-#define jit_extr_ui_ul(d, rs)
-#define jit_gei_p(d, rs, is)
-#define jit_ger_p(d, s1, s2)
-#define jit_gti_p(d, rs, is)
-#define jit_gtr_p(d, s1, s2)
-#define jit_ldr_p(d, rs)
-#define jit_ldr_ul(d, rs)
-#define jit_ldi_p(d, is)
-#define jit_ldi_ul(d, is)
-#define jit_ldxi_p(d, rs, is)
-#define jit_ldxi_ul(d, rs, is)
-#define jit_ldxr_p(d, s1, s2)
-#define jit_ldxr_ul(d, s1, s2)
-#define jit_lei_p(d, rs, is)
-#define jit_ler_p(d, s1, s2)
-#define jit_lshi_ui(d, rs, is)
-#define jit_lshi_ul(d, rs, is)
-#define jit_lshr_ui(d, s1, s2)
-#define jit_lshr_ul(d, s1, s2)
-#define jit_lti_p(d, rs, is)
-#define jit_ltr_p(d, s1, s2)
-#define jit_movi_p(d, is)
-#define jit_movi_ui(d, rs)
-#define jit_movi_ul(d, rs)
-#define jit_movr_p(d, rs)
-#define jit_movr_ui(d, rs)
-#define jit_movr_ul(d, rs)
-#define jit_nei_p(d, rs, is)
-#define jit_nei_ui(d, rs, is)
-#define jit_nei_ul(d, rs, is)
-#define jit_ner_p(d, s1, s2)
-#define jit_ner_ui(d, s1, s2)
-#define jit_ner_ul(d, s1, s2)
-#define jit_hton_ui(d, rs)
-#define jit_hton_us(d, rs)
-#define jit_ori_ui(d, rs, is)
-#define jit_ori_ul(d, rs, is)
-#define jit_orr_ui(d, s1, s2)
-#define jit_orr_ul(d, s1, s2)
-#define jit_pusharg_c(rs)
-#define jit_pusharg_p(rs)
-#define jit_pusharg_s(rs)
-#define jit_pusharg_uc(rs)
-#define jit_pusharg_ui(rs)
-#define jit_pusharg_ul(rs)
-#define jit_pusharg_us(rs)
-#define jit_retval_c(rd)
-#define jit_retval_p(rd)
-#define jit_retval_s(rd)
-#define jit_retval_uc(rd)
-#define jit_retval_ui(rd)
-#define jit_retval_ul(rd)
-#define jit_retval_us(rd)
-#define jit_rsbi_p(d, rs, is)
-#define jit_rsbi_ui(d, rs, is)
-#define jit_rsbi_ul(d, rs, is)
-#define jit_rsbr_p(d, rs, is)
-#define jit_rsbr_ui(d, s1, s2)
-#define jit_rsbr_ul(d, s1, s2)
-#define jit_sti_p(d, is)
-#define jit_sti_uc(d, is)
-#define jit_sti_ui(d, is)
-#define jit_sti_ul(d, is)
-#define jit_sti_us(d, is)
-#define jit_str_p(d, rs)
-#define jit_str_uc(d, rs)
-#define jit_str_ui(d, rs)
-#define jit_str_ul(d, rs)
-#define jit_str_us(d, rs)
-#define jit_stxi_p(d, rs, is)
-#define jit_stxi_uc(d, rs, is)
-#define jit_stxi_ui(d, rs, is)
-#define jit_stxi_ul(d, rs, is)
-#define jit_stxi_us(d, rs, is)
-#define jit_stxr_p(d, s1, s2)
-#define jit_stxr_uc(d, s1, s2)
-#define jit_stxr_ui(d, s1, s2)
-#define jit_stxr_ul(d, s1, s2)
-#define jit_stxr_us(d, s1, s2)
-#define jit_subi_p(d, rs, is)
-#define jit_subi_ui(d, rs, is)
-#define jit_subi_ul(d, rs, is)
-#define jit_subr_p(d, s1, s2)
-#define jit_subr_ui(d, s1, s2)
-#define jit_subr_ul(d, s1, s2)
-#define jit_subxi_p(d, rs, is)
-#define jit_subxi_ui(d, rs, is)
-#define jit_subxi_ul(d, rs, is)
-#define jit_subxr_p(d, s1, s2)
-#define jit_subxr_ui(d, s1, s2)
-#define jit_subxr_ul(d, s1, s2)
-#define jit_xori_ui(d, rs, is)
-#define jit_xori_ul(d, rs, is)
-#define jit_xorr_ui(d, s1, s2)
-#define jit_xorr_ul(d, s1, s2)
address@hidden example
-
address@hidden Shortcuts---don't define them:
address@hidden
-#define JIT_R0
-#define JIT_R1
-#define JIT_R2
-#define JIT_V0
-#define JIT_V1
-#define JIT_V2
-#define JIT_FPR0
-#define JIT_FPR1
-#define JIT_FPR2
-#define JIT_FPR3
-#define JIT_FPR4
-#define JIT_FPR5
-#define jit_patch(jump_pc)
-#define jit_notr_c(d, rs)
-#define jit_notr_i(d, rs)
-#define jit_notr_l(d, rs)
-#define jit_notr_s(d, rs)
-#define jit_notr_uc(d, rs)
-#define jit_notr_ui(d, rs)
-#define jit_notr_ul(d, rs)
-#define jit_notr_us(d, rs)
-#define jit_rsbr_d(d, s1, s2)
-#define jit_rsbr_i(d, s1, s2)
-#define jit_rsbr_l(d, s1, s2)
-#define jit_subi_i(d, rs, is)
-#define jit_subi_l(d, rs, is)
address@hidden example
-
address@hidden Mandatory unless target arithmetic is always done in the same 
precision:
address@hidden
-#define jit_abs_f(rd,rs)
-#define jit_addr_f(rd,s1,s2)
-#define jit_beqr_f(label, s1, s2)
-#define jit_bger_f(label, s1, s2)
-#define jit_bgtr_f(label, s1, s2)
-#define jit_bler_f(label, s1, s2)
-#define jit_bltgtr_f(label, s1, s2)
-#define jit_bltr_f(label, s1, s2)
-#define jit_bner_f(label, s1, s2)
-#define jit_bordr_f(label, s1, s2)
-#define jit_buneqr_f(label, s1, s2)
-#define jit_bunger_f(label, s1, s2)
-#define jit_bungtr_f(label, s1, s2)
-#define jit_bunler_f(label, s1, s2)
-#define jit_bunltr_f(label, s1, s2)
-#define jit_bunordr_f(label, s1, s2)
-#define jit_ceilr_f_i(rd, rs)
-#define jit_divr_f(rd,s1,s2)
-#define jit_eqr_f(d, s1, s2)
-#define jit_extr_d_f(rs, rd)
-#define jit_extr_f_d(rs, rd)
-#define jit_extr_i_f(rd, rs)
-#define jit_floorr_f_i(rd, rs)
-#define jit_ger_f(d, s1, s2)
-#define jit_gtr_f(d, s1, s2)
-#define jit_ler_f(d, s1, s2)
-#define jit_ltgtr_f(d, s1, s2)
-#define jit_ltr_f(d, s1, s2)
-#define jit_movr_f(rd,rs)
-#define jit_mulr_f(rd,s1,s2)
-#define jit_negr_f(rd,rs)
-#define jit_ner_f(d, s1, s2)
-#define jit_ordr_f(d, s1, s2)
-#define jit_roundr_f_i(rd, rs)
-#define jit_rsbr_f(d, s1, s2)
-#define jit_sqrt_f(rd,rs)
-#define jit_subr_f(rd,s1,s2)
-#define jit_truncr_f_i(rd, rs)
-#define jit_uneqr_f(d, s1, s2)
-#define jit_unger_f(d, s1, s2)
-#define jit_ungtr_f(d, s1, s2)
-#define jit_unler_f(d, s1, s2)
-#define jit_unltr_f(d, s1, s2)
-#define jit_unordr_f(d, s1, s2)
address@hidden example
-
address@hidden Mandatory if sizeof(long) != sizeof(int)---don't define them on 
other systems:
address@hidden
-#define jit_addi_l(d, rs, is)
-#define jit_addr_l(d, s1, s2)
-#define jit_andi_l(d, rs, is)
-#define jit_andr_l(d, s1, s2)
-#define jit_beqi_l(label, rs, is)
-#define jit_beqr_l(label, s1, s2)
-#define jit_bgei_l(label, rs, is)
-#define jit_bgei_ul(label, rs, is)
-#define jit_bger_l(label, s1, s2)
-#define jit_bger_ul(label, s1, s2)
-#define jit_bgti_l(label, rs, is)
-#define jit_bgti_ul(label, rs, is)
-#define jit_bgtr_l(label, s1, s2)
-#define jit_bgtr_ul(label, s1, s2)
-#define jit_blei_l(label, rs, is)
-#define jit_blei_ul(label, rs, is)
-#define jit_bler_l(label, s1, s2)
-#define jit_bler_ul(label, s1, s2)
-#define jit_blti_l(label, rs, is)
-#define jit_blti_ul(label, rs, is)
-#define jit_bltr_l(label, s1, s2)
-#define jit_bltr_ul(label, s1, s2)
-#define jit_bosubi_l(label, rs, is)
-#define jit_bosubi_ul(label, rs, is)
-#define jit_bosubr_l(label, s1, s2)
-#define jit_bosubr_ul(label, s1, s2)
-#define jit_boaddi_l(label, rs, is)
-#define jit_boaddi_ul(label, rs, is)
-#define jit_boaddr_l(label, s1, s2)
-#define jit_boaddr_ul(label, s1, s2)
-#define jit_bmci_l(label, rs, is)
-#define jit_bmcr_l(label, s1, s2)
-#define jit_bmsi_l(label, rs, is)
-#define jit_bmsr_l(label, s1, s2)
-#define jit_bnei_l(label, rs, is)
-#define jit_bner_l(label, s1, s2)
-#define jit_divi_l(d, rs, is)
-#define jit_divi_ul(d, rs, is)
-#define jit_divr_l(d, s1, s2)
-#define jit_divr_ul(d, s1, s2)
-#define jit_eqi_l(d, rs, is)
-#define jit_eqr_l(d, s1, s2)
-#define jit_extr_c_l(d, rs)
-#define jit_extr_c_ul(d, rs)
-#define jit_extr_s_l(d, rs)
-#define jit_extr_s_ul(d, rs)
-#define jit_extr_i_l(d, rs)
-#define jit_extr_i_ul(d, rs)
-#define jit_gei_l(d, rs, is)
-#define jit_gei_ul(d, rs, is)
-#define jit_ger_l(d, s1, s2)
-#define jit_ger_ul(d, s1, s2)
-#define jit_gti_l(d, rs, is)
-#define jit_gti_ul(d, rs, is)
-#define jit_gtr_l(d, s1, s2)
-#define jit_gtr_ul(d, s1, s2)
-#define jit_hmuli_l(d, rs, is)
-#define jit_hmuli_ul(d, rs, is)
-#define jit_hmulr_l(d, s1, s2)
-#define jit_hmulr_ul(d, s1, s2)
-#define jit_ldi_l(d, is)
-#define jit_ldi_ui(d, is)
-#define jit_ldr_l(d, rs)
-#define jit_ldr_ui(d, rs)
-#define jit_ldxi_l(d, rs, is)
-#define jit_ldxi_ui(d, rs, is)
-#define jit_ldxr_l(d, s1, s2)
-#define jit_ldxr_ui(d, s1, s2)
-#define jit_lei_l(d, rs, is)
-#define jit_lei_ul(d, rs, is)
-#define jit_ler_l(d, s1, s2)
-#define jit_ler_ul(d, s1, s2)
-#define jit_lshi_l(d, rs, is)
-#define jit_lshr_l(d, s1, s2)
-#define jit_lti_l(d, rs, is)
-#define jit_lti_ul(d, rs, is)
-#define jit_ltr_l(d, s1, s2)
-#define jit_ltr_ul(d, s1, s2)
-#define jit_modi_l(d, rs, is)
-#define jit_modi_ul(d, rs, is)
-#define jit_modr_l(d, s1, s2)
-#define jit_modr_ul(d, s1, s2)
-#define jit_movi_l(d, rs)
-#define jit_movr_l(d, rs)
-#define jit_muli_l(d, rs, is)
-#define jit_muli_ul(d, rs, is)
-#define jit_mulr_l(d, s1, s2)
-#define jit_mulr_ul(d, s1, s2)
-#define jit_nei_l(d, rs, is)
-#define jit_ner_l(d, s1, s2)
-#define jit_ori_l(d, rs, is)
-#define jit_orr_l(d, s1, s2)
-#define jit_pusharg_l(rs)
-#define jit_retval_l(rd)
-#define jit_rshi_l(d, rs, is)
-#define jit_rshi_ul(d, rs, is)
-#define jit_rshr_l(d, s1, s2)
-#define jit_rshr_ul(d, s1, s2)
-#define jit_sti_l(d, is)
-#define jit_str_l(d, rs)
-#define jit_stxi_l(d, rs, is)
-#define jit_stxr_l(d, s1, s2)
-#define jit_subr_l(d, s1, s2)
-#define jit_xori_l(d, rs, is)
-#define jit_xorr_l(d, s1, s2)
address@hidden example
address@hidden table
-
address@hidden Standard functions
address@hidden More complex tasks in the platform-independent layer
-
-There is actually a single function that you @strong{must} define
-in the @address@hidden file, that is, @code{jit_flush_code}.
-
-As explained in @usingref{GNU lightning macros, Generating code at
-run-time}, its purpose is to flush part of the processor's
-instruction cache (usually the part of memory that contains the
-generated code), avoiding the processor executing bogus data
-that it happens to find in the cache.  The @code{jit_flush_code}
-function takes the first and the last address to flush.
-
-On many processors (for example, the x86 and the all the processors
-in the 68k family up to the 68030), it is not even necessary to flush
-the cache.  In this case, the contents of the file will simply be
-
address@hidden
-#ifndef __lightning_funcs_h
-#define __lightning_funcs_h
-
-#define jit_flush_code(dest, end)
-
-#endif @rem{/* __lightning_core_h */}
address@hidden example
-
-On other processors, flushing the cache is necessary for
-proper behavior of the program; in this case, the file will contain
-a proper definition of the function.  However, we must make yet
-another distinction.
-
-On some processors, flushing the cache is obtained through a call
-to the operating system or to the C run-time library.  In this case,
-the definition of @code{jit_flush_code} will be very simple: two
-examples are the Alpha and the 68040. For the Alpha the code will
-be:
address@hidden
-#define jit_flush_code(dest, end) \
-        __asm__ __volatile__("call_pal 0x86");
address@hidden example
-
address@hidden
-and, for the Motorola
address@hidden
-#define jit_flush_code(start, end) \
-        __clear_cache((start), (end))
address@hidden example
-
-As you can see, the Alpha does not even need to pass the start and
-end address to the function.  It is good practice to protect usage of
-the @acronym{GNU CC}-specific @code{__asm__} directive by relying
-on the preprocessor.  For example:
-
address@hidden
-#if !defined(__GNUC__) && !defined(__GNUG__)
-#error Go get GNU C, I do not know how to flush the cache
-#error with this compiler.
-#else
-#define jit_flush_code(dest, end) \
-        __asm__ __volatile__("call_pal 0x86");
-#endif
address@hidden example
-
address@hidden's configuration process tries to compile a dummy file that
-includes @code{lightning.h}, and gives a warning if there are problem
-with the compiler that is installed on the system.
-
-In more complex cases, you'll need to write a full-fledged function.
-Don't forget to make it @code{static}, otherwise you'll have problems
-linking programs that include @code{lightning.h} multiple times. An
-example, taken from the @file{funcs-ppc.h} file, is:
-
address@hidden
-#ifndef __lightning_funcs_h
-#define __lightning_funcs_h
-
-#if !defined(__GNUC__) && !defined(__GNUG__)
-#error Go get GNU C, I do not know how to flush the cache
-#error with this compiler.
-#else
-static void
-jit_flush_code(start, end)
-     void       *start;
-     void       *end;
address@hidden
-  register char *dest = start;
-
-  for (; dest <= end; dest += SIZEOF_CHAR_P)
-    __asm__ __volatile__ 
-      ("dcbst 0,%0; sync; icbi 0,%0; isync"::"r"(dest));
address@hidden
-#endif
-
-#endif /* __lightning_funcs_h */
address@hidden example
-
-The @address@hidden file is also the right place to put
-helper functions that do complex tasks for the
address@hidden@var{suffix}.h} file.  For example, the PowerPC assembler
-defines @code{jit_prolog} as a function and puts it in that file (for more
-information, @pxref{Implementing the ABI}).  Take special care when
-defining such a function, as explained in @usingref{Reentrancy,
-Reentrant usage of @lightning{}}.
-
-
address@hidden Floating-point macros
address@hidden Implementing macros for floating point
-
diff --git a/doc/printf.c b/doc/printf.c
new file mode 100644
index 0000000..52bd2aa
--- /dev/null
+++ b/doc/printf.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef void (*pvfi)(int);    /* Pointer to Void Function of Int */
+
+int main(int argc, char *argv[])
+{
+  pvfi          myFunction;             /* ptr to generated code */
+  jit_node_t    *start, *end;           /* a couple of labels */
+  jit_node_t    *in;                    /* to get the argument */
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  start = jit_note(__FILE__, __LINE__);
+  jit_prolog();
+  in = jit_arg();
+  jit_getarg(JIT_R1, in);
+  jit_pushargi((jit_word_t)"generated %d bytes\n");
+  jit_ellipsis();
+  jit_pushargr(JIT_R1);
+  jit_finishi(printf);
+  jit_ret();
+  jit_epilog();
+  end = jit_note(__FILE__, __LINE__);
+
+  myFunction = jit_emit();
+
+  /* call the generated code, passing its size as argument */
+  myFunction((char*)jit_address(end) - (char*)jit_address(start));
+
+  jit_disassemble();
+
+  finish_jit();
+  return 0;
+}
diff --git a/doc/rfib.c b/doc/rfib.c
new file mode 100644
index 0000000..1ce02d5
--- /dev/null
+++ b/doc/rfib.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <lightning.h>
+
+static jit_state_t *_jit;
+
+typedef int (*pifi)(int);       /* Pointer to Int Function of Int */
+
+int main(int argc, char *argv[])
+{
+  pifi       fib;
+  jit_node_t *label;
+  jit_node_t *call;
+  jit_node_t *in;                 /* offset of the argument */
+  jit_node_t *ref;                /* to patch the forward reference */
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  label = jit_label();
+        jit_prolog   ();
+  in =  jit_arg      ();
+        jit_getarg   (JIT_V0, in);              /* V0 = n */
+  ref = jit_blti     (JIT_V0, 2);
+        jit_subi     (JIT_V1, JIT_V0, 1);       /* V1 = n-1 */
+        jit_subi     (JIT_V2, JIT_V0, 2);       /* V2 = n-2 */
+        jit_prepare();
+          jit_pushargr(JIT_V1);
+        call = jit_finishi(NULL);
+        jit_patch_at(call, label);
+        jit_retval(JIT_V1);                     /* V1 = fib(n-1) */
+        jit_prepare();
+          jit_pushargr(JIT_V2);
+        call = jit_finishi(NULL);
+        jit_patch_at(call, label);
+        jit_retval(JIT_V2);                     /* V2 = fib(n-2) */
+        jit_addi(JIT_V1,  JIT_V1,  1);
+        jit_addr(JIT_R0, JIT_V1, JIT_V2);       /* R0 = V1 + V2 + 1 */
+        jit_retr(JIT_R0);
+
+  jit_patch(ref);                               /* patch jump */
+        jit_movi(JIT_R0, 1);                    /* R0 = 1 */
+        jit_retr(JIT_R0);
+
+  /* call the generated code, passing 32 as an argument */
+  fib = jit_emit();
+  printf("fib(%d) = %d\n", 32, fib(32));
+  finish_jit();
+  return 0;
+}
diff --git a/doc/rpn.c b/doc/rpn.c
new file mode 100644
index 0000000..f02cef3
--- /dev/null
+++ b/doc/rpn.c
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <lightning.h>
+
+typedef int (*pifi)(int);       /* Pointer to Int Function of Int */
+
+static jit_state_t *_jit;
+
+void stack_push(int reg, int *sp)
+{
+  jit_stxi_i (*sp, JIT_FP, reg);
+  *sp += sizeof (int);
+}
+
+void stack_pop(int reg, int *sp)
+{
+  *sp -= sizeof (int);
+  jit_ldxi_i (reg, JIT_FP, *sp);
+}
+
+jit_node_t *compile_rpn(char *expr)
+{
+  jit_node_t *in, *fn;
+  int stack_base, stack_ptr;
+
+  fn = jit_note(NULL, 0);
+  jit_prolog();
+  in = jit_arg();
+  stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
+
+  jit_getarg_i(JIT_R2, in);
+
+  while (*expr) {
+    char buf[32];
+    int n;
+    if (sscanf(expr, "%[0-9]%n", buf, &n)) {
+      expr += n - 1;
+      stack_push(JIT_R0, &stack_ptr);
+      jit_movi(JIT_R0, atoi(buf));
+    } else if (*expr == 'x') {
+      stack_push(JIT_R0, &stack_ptr);
+      jit_movr(JIT_R0, JIT_R2);
+    } else if (*expr == '+') {
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_addr(JIT_R0, JIT_R1, JIT_R0);
+    } else if (*expr == '-') {
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_subr(JIT_R0, JIT_R1, JIT_R0);
+    } else if (*expr == '*') {
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_mulr(JIT_R0, JIT_R1, JIT_R0);
+    } else if (*expr == '/') {
+      stack_pop(JIT_R1, &stack_ptr);
+      jit_divr(JIT_R0, JIT_R1, JIT_R0);
+    } else {
+      fprintf(stderr, "cannot compile: %s\n", expr);
+      abort();
+    }
+    ++expr;
+  }
+  jit_retr(JIT_R0);
+  jit_epilog();
+  return fn;
+}
+
+int main(int argc, char *argv[])
+{
+  jit_node_t *nc, *nf;
+  pifi c2f, f2c;
+  int i;
+
+  init_jit(argv[0]);
+  _jit = jit_new_state();
+
+  nc = compile_rpn("32x9*5/+");
+  nf = compile_rpn("x32-5*9/");
+  (void)jit_emit();
+  c2f = (pifi)jit_address(nc);
+  f2c = (pifi)jit_address(nf);
+
+  printf("\nC:");
+  for (i = 0; i <= 100; i += 10) printf("%3d ", i);
+  printf("\nF:");
+  for (i = 0; i <= 100; i += 10) printf("%3d ", c2f(i));
+  printf("\n");
+
+  printf("\nF:");
+  for (i = 32; i <= 212; i += 18) printf("%3d ", i);
+  printf("\nC:");
+  for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i));
+  printf("\n");
+
+  finish_jit();
+  return 0;
+}
diff --git a/doc/toc.texi b/doc/toc.texi
deleted file mode 100644
index 193d4f2..0000000
--- a/doc/toc.texi
+++ /dev/null
@@ -1,76 +0,0 @@
address@hidden These macros are used because these items could go both in the
address@hidden short listing (for partial books) and in the detailed listing
address@hidden (for full books - i.e. using & porting)
-
address@hidden usingmenu{}
address@hidden USING
-* Installation::            Configuring and installing GNU lightning
-* The instruction set::     The RISC instruction set used i GNU lightning
-* GNU lightning macros::    GNU lightning's macros
-* Reentrancy::              Re-entrant usage of GNU lightning
-* Bundling GNU lightning::  Using GNU lightning in your programs
address@hidden ifset
address@hidden macro
-
address@hidden portingmenu{}
address@hidden PORTING
-* Structure of a port::   An overview of the porting process
-* Adjusting configure::   Automatically recognizing the new platform
-* Run-time assemblers::   An internal layer to simplify porting
-* Standard macros::       The platform-independent layer used by clients.
-* Standard functions::    Doing more complex tasks.
-* Floating-point macros:: Implementing macros for floating point.
address@hidden ifset
address@hidden macro
-
address@hidden standardmacrosmenu{}
address@hidden This comment is needed because of makeinfo's vagaries...
-* Forward references::    Implementing forward references
-* Common features::       Common features supported by @file{core-common.h}
-* Delay slots::           Supporting scheduling of delay slots
-* Immediate values::      Supporting arbitrarily sized immediate values
-* Implementing the ABI::  Function prologs and epilogs, and argument passing
-* Macro list::            Macros composing the platform-independent layer
address@hidden macro
-
address@hidden
address@hidden BOTH
-* Overview::              What GNU lightning is
address@hidden
address@hidden
-* Future::                Tasks for GNU lightning's subsequent releases
-* Acknowledgements::      Acknowledgements for GNU lightning
-
address@hidden PORTING
address@hidden
---- The detailed node listing ---
-
-Standard macros:
address@hidden
address@hidden detailmenu
address@hidden ifset
address@hidden ifclear
-
address@hidden BOTH
-* Overview::              What GNU lightning is.
-* Using GNU lightning::   Using GNU lightning in your programs
-* Porting GNU lightning:: Retargeting GNU lightning to a new system
-* Future::                Tasks for GNU lightning's subsequent releases
-* Acknowledgements::      Acknowledgements for GNU lightning
-
address@hidden
---- The detailed node listing ---
-
-Using @lightning{}:
address@hidden
-
-Porting @lightning{}:
address@hidden
-
-Standard macros:
address@hidden
address@hidden detailmenu
-
address@hidden ifset
-
address@hidden menu
diff --git a/doc/u-lightning.texi b/doc/u-lightning.texi
deleted file mode 100644
index 0c2481b..0000000
--- a/doc/u-lightning.texi
+++ /dev/null
@@ -1,100 +0,0 @@
-\input texinfo.tex  @c -*- texinfo -*-
address@hidden %**start of header (This is for running Texinfo on a region.)
-
address@hidden lightning.info
-
address@hidden TITLE       Porting @sc{gnu} @i{lightning}
address@hidden TOPIC       Porting
address@hidden BOTH
address@hidden USING
address@hidden PORTING
-
address@hidden @value{TITLE}
-
address@hidden 
---------------------------------------------------------------------
address@hidden Common macros
address@hidden 
---------------------------------------------------------------------
-
address@hidden bulletize{a}
address@hidden
-\a\
address@hidden macro
-
address@hidden rem{a}
address@hidden@i{\a\}}
address@hidden macro
-
address@hidden gnu{}
address@hidden
address@hidden macro
-
address@hidden lightning{}
address@hidden @i{lightning}
address@hidden macro
-
address@hidden 
---------------------------------------------------------------------
address@hidden Macros for Texinfo 3.1/4.0 compatibility
address@hidden 
---------------------------------------------------------------------
-
address@hidden @hlink (macro), @url and @email are used instead of @uref for 
Texinfo 3.1
address@hidden compatibility
address@hidden hlink{url, link}
-\link\ (\url\)
address@hidden macro
-
address@hidden ifhtml can only be true in Texinfo 4.0, which has uref
address@hidden
address@hidden hlink
-
address@hidden hlink{url, link}
address@hidden, \link\}
address@hidden macro
-
address@hidden email{mail}
address@hidden:\mail\, , \mail\}
address@hidden macro
-
address@hidden url{url}
address@hidden
address@hidden macro
address@hidden ifhtml
-
address@hidden 
---------------------------------------------------------------------
address@hidden References to the other half of the manual
address@hidden 
---------------------------------------------------------------------
-
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
-
address@hidden USING
address@hidden usingref{node, name}
address@hidden, , \name\, u-lightning, Using @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\}
address@hidden macro
address@hidden ifset
-
address@hidden PORTING
address@hidden portingref{node, name}
address@hidden, , \name\, p-lightning, Porting @sc{gnu} @i{lightning}}
address@hidden macro
address@hidden ifclear
-
address@hidden 
---------------------------------------------------------------------
address@hidden End of macro section
address@hidden 
---------------------------------------------------------------------
-
address@hidden version.texi
address@hidden body.texi
-
address@hidden %**end of header (This is for running Texinfo on a region.)
-
address@hidden 
***********************************************************************
-
diff --git a/doc/using.texi b/doc/using.texi
deleted file mode 100644
index 332383e..0000000
--- a/doc/using.texi
+++ /dev/null
@@ -1,1273 +0,0 @@
address@hidden Installation
address@hidden Configuring and installing @lightning{}
-
-The first thing to do to use @lightning{} is to configure the
-program, picking the set of macros to be used on the host
-architecture; this configuration is automatically performed by
-the @file{configure} shell script; to run it, merely type:
address@hidden
-     ./configure
address@hidden example
-
address@hidden supports cross-compiling in that you can choose a
-different set of macros from the one needed on the computer that
-you are compiling @lightning{} on.  For example,
address@hidden
-     ./configure --host=sparc-sun-linux
address@hidden example
-
address@hidden will select the SPARC set of runtime assemblers.  You can use
-configure's ability to make reasonable assumptions about the vendor
-and operating system and simply type
address@hidden
-     ./configure --host=i386
-     ./configure --host=ppc
-     ./configure --host=sparc
address@hidden example
-
-Another option that @file{configure} accepts is
address@hidden, which enables several consistency checks in
-the run-time assemblers.  These are not usually needed, so you can
-decide to simply forget about it; also remember that these consistency
-checks tend to slow down your code generator.
-
-After you've configured @lightning{}, you don't have to compile it
-because it is nothing more than a set of include files.  If you want to
-compile the examples, run @file{make} as usual.  The next important
-step is:
address@hidden
-    make install
address@hidden example
-
-This ends the process of installing @lightning{}.
-
address@hidden The instruction set
address@hidden @lightning{}'s instruction set
-
address@hidden's instruction set was designed by deriving instructions
-that closely match those of most existing RISC architectures, or
-that can be easily syntesized if absent.  Each instruction is composed
-of:
address@hidden @bullet
address@hidden
-an operation, like @code{sub} or @code{mul}
-
address@hidden
-sometimes, an register/immediate flag (@code{r} or @code{i})
-
address@hidden
-a type identifier or, occasionally, two
address@hidden itemize
-
-The second and third field are separated by an underscore; thus,
-examples of legal mnemonics are @code{addr_i} (integer add, with three
-register operands) and @code{muli_l} (long integer multiply, with two
-register operands and an immediate operand).  Each instruction takes
-two or three operands; in most cases, one of them can be an immediate
-value instead of a register.
-
address@hidden supports a full range of integer types: operands can be 1,
-2 or 4 bytes long (64-bit architectures might support 8 bytes long
-operands), either signed or unsigned.  The types are listed in the
-following table together with the C types they represent:
-
address@hidden
-     c          @r{signed char}
-     uc         @r{unsigned char}
-     s          @r{short}
-     us         @r{unsigned short}
-     i          @r{int}
-     ui         @r{unsigned int}
-     l          @r{long}
-     ul         @r{unsigned long}
-     f          @r{float}
-     d          @r{double}
-     p          @r{void *}
address@hidden example
-
-Some of these types may not be distinct: for example, (e.g., @code{l}
-is equivalent to @code{i} on 32-bit machines, and @code{p} is
-substantially equivalent to @code{ul}).
-
-There are at least seven integer registers, of which six are
-general-purpose, while the last is used to contain the frame pointer
-(@code{FP}).  The frame pointer can be used to allocate and access local
-variables on the stack, using the @code{allocai} instruction.
-
-Of the general-purpose registers, at least three are guaranteed to be
-preserved across function calls (@code{V0}, @code{V1} and
address@hidden) and at least three are not (@code{R0}, @code{R1} and
address@hidden).  Six registers are not very much, but this
-restriction was forced by the need to target CISC architectures
-which, like the x86, are poor of registers; anyway, backends can
-specify the actual number of available registers with the macros
address@hidden (for caller-save registers) and @code{JIT_V_NUM}
-(for callee-save registers).
-
-In addition, there is a special @code{RET} register which contains
-the return value of the current function (@emph{not} the return value
-of callees---use the @code{retval} instruction for this).  You should
-always remember, however, that writing this register could overwrite
-either a general-purpose register or an incoming parameter, depending
-on the architecture.
-
-There are at least six floating-point registers, named @code{FPR0} to
address@hidden  These are caller-save and are separate from the integer
-registers on all the supported architectures; on Intel architectures,
-the register stack is mapped to a flat register file.  As for the
-integer registers, the macro @code{JIT_FPR_NUM} yields the number of
-floating-point registers, and the special @code{FPRET} register contains
-the return value of the current function.
-
-The complete instruction set follows; as you can see, most non-memory
-operations only take integers, long integers (either signed or
-unsigned) and pointers as operands; this was done in order to reduce
-the instruction set, and because most architectures only provide word
-and long word operations on registers.  There are instructions that
-allow operands to be extended to fit a larger data type, both in a
-signed and in an unsigned way.
-
address@hidden @b
address@hidden Binary ALU operations
-These accept three operands; the last one can be an immediate
-value for integer operands, or a register for all operand types.
address@hidden operations must directly follow @code{addc}, and
address@hidden must follow @code{subc}; otherwise, results are undefined.
address@hidden
-addr     i  ui  l  ul  p  f  d  O1 = O2 + O3
-addi     i  ui  l  ul  p        O1 = O2 + O3
-addxr    i  ui  l  ul           O1 = O2 + (O3 + carry)
-addxi    i  ui  l  ul           O1 = O2 + (O3 + carry)
-addcr    i  ui  l  ul           O1 = O2 + O3, set carry
-addci    i  ui  l  ul           O1 = O2 + O3, set carry
-subr     i  ui  l  ul  p  f  d  O1 = O2 - O3
-subi     i  ui  l  ul  p        O1 = O2 - O3
-subxr    i  ui  l  ul           O1 = O2 - (O3 + carry)
-subxi    i  ui  l  ul           O1 = O2 - (O3 + carry)
-subcr    i  ui  l  ul           O1 = O2 - O3, set carry
-subci    i  ui  l  ul           O1 = O2 - O3, set carry
-rsbr     i  ui  l  ul  p  f  d  O1 = O3 - O2
-rsbi     i  ui  l  ul  p        O1 = O3 - O2
-mulr     i  ui  l  ul     f  d  O1 = O2 * O3
-muli     i  ui  l  ul           O1 = O2 * O3
-hmulr    i  ui  l  ul           O1 = @r{high bits of} O2 * O3
-hmuli    i  ui  l  ul           O1 = @r{high bits of} O2 * O3
-divr     i  ui  l  ul     f  d  O1 = O2 / O3
-divi     i  ui  l  ul           O1 = O2 / O3
-modr     i  ui  l  ul           O1 = O2 % O3
-modi     i  ui  l  ul           O1 = O2 % O3
-andr     i  ui  l  ul           O1 = O2 & O3
-andi     i  ui  l  ul           O1 = O2 & O3
-orr      i  ui  l  ul           O1 = O2 | O3
-ori      i  ui  l  ul           O1 = O2 | O3
-xorr     i  ui  l  ul           O1 = O2 ^ O3
-xori     i  ui  l  ul           O1 = O2 ^ O3
-lshr     i  ui  l  ul           O1 = O2 << O3
-lshi     i  ui  l  ul           O1 = O2 << O3
-rshr     i  ui  l  ul           O1 = O2 >> address@hidden sign bit is 
propagated for signed types.}
-rshi     i  ui  l  ul           O1 = O2 >> address@hidden sign bit is 
propagated for signed types.}
address@hidden example
-
address@hidden Unary ALU operations
-These accept two operands, both of which must be registers.
address@hidden
-negr     i     l         f  d  O1 = -O2
-notr     i  ui l  ul           O1 = ~O2
address@hidden example
-
address@hidden Compare instructions
-These accept three operands; again, the last can be an immediate
-value for integer data types.  The last two operands are compared,
-and the first operand is set to either 0 or 1, according to
-whether the given condition was met or not.
-
-The conditions given below are for the standard behavior of C,
-where the ``unordered'' comparison result is mapped to false.
-
address@hidden
-ltr      i  ui  l  ul  p  f  d  O1 = (O2 <  O3)
-lti      i  ui  l  ul  p        O1 = (O2 <  O3)
-ler      i  ui  l  ul  p  f  d  O1 = (O2 <= O3)
-lei      i  ui  l  ul  p        O1 = (O2 <= O3)
-gtr      i  ui  l  ul  p  f  d  O1 = (O2 >  O3)
-gti      i  ui  l  ul  p        O1 = (O2 >  O3)
-ger      i  ui  l  ul  p  f  d  O1 = (O2 >= O3)
-gei      i  ui  l  ul  p        O1 = (O2 >= O3)
-eqr      i  ui  l  ul  p  f  d  O1 = (O2 == O3)
-eqi      i  ui  l  ul  p        O1 = (O2 == O3)
-ner      i  ui  l  ul  p  f  d  O1 = (O2 != O3)
-nei      i  ui  l  ul  p        O1 = (O2 != O3)
-unltr                     f  d  O1 = !(O2 >= O3)
-unler                     f  d  O1 = !(O2 >  O3)
-ungtr                     f  d  O1 = !(O2 <= O3)
-unger                     f  d  O1 = !(O2 <  O3)
-uneqr                     f  d  O1 = !(O2 <  O3) && !(O2 >  O3)
-ltgtr                     f  d  O1 = !(O2 >= O3) || !(O2 <= O3)
-ordr                      f  d  O1 =  (O2 == O2) &&  (O3 == O3)
-unordr                    f  d  O1 =  (O2 != O2) ||  (O3 != O3)
address@hidden example
-
address@hidden Transfer operations
-These accept two operands; for @code{ext} both of them must be
-registers, while @code{mov} accepts an immediate value as the second
-operand.
-
-Unlike @code{movr} and @code{movi}, the other instructions are applied
-between operands of different data types, and they need @strong{two}
-data type specifications.  You can use @code{extr} to convert between
-integer data types, in which case the first must be smaller in size
-than the second; for example @code{extr_c_ui} is correct while
address@hidden is not.  You can also use @code{extr} to convert
-an integer to a floating point value: the only available possibilities
-are @code{extr_i_f} and @code{extr_i_d}.  The other instructions
-convert a floating point value to an integer, so the possible
-suffixes are @code{_f_i} and @code{_d_i}.
-
address@hidden
-movr                      i  ui  l  ul  p  f  d  O1 = O2
-movi                      i  ui  l  ul  p  f  d  O1 = O2
-extr        c  uc  s  us  i  ui  l  ul     f  d  O1 = O2
-roundr                    i                f  d  O1 = round(O2)
-truncr                    i                f  d  O1 = trunc(O2)
-floorr                    i                f  d  O1 = floor(O2)
-ceilr                     i                f  d  O1 = ceil(O2)
address@hidden example
-
-Note that the order of the arguments is @emph{destination first,
-source second} as for all other @lightning{} instructions, but
-the order of the types is always reversed with respect to that
-of the arguments: @address@hidden,
address@hidden  This happens for historical
-reasons.
-
address@hidden Network extensions
-These accept two operands, both of which must be registers; these
-two instructions actually perform the same task, yet they are
-assigned to two mnemonics for the sake of convenience and
-completeness.  As usual, the first operand is the destination and
-the second is the source.
address@hidden
-hton       us ui          @r{Host-to-network (big endian) order}
-ntoh       us ui          @r{Network-to-host order }
address@hidden example
-
address@hidden Load operations
address@hidden accepts two operands while @code{ldx} accepts three;
-in both cases, the last can be either a register or an immediate
-value. Values are extended (with or without sign, according to
-the data type specification) to fit a whole register.
address@hidden
-ldr     c  uc  s  us  i  ui  l  ul  p  f  d  O1 = *O2
-ldi     c  uc  s  us  i  ui  l  ul  p  f  d  O1 = *O2
-ldxr    c  uc  s  us  i  ui  l  ul  p  f  d  O1 = *(O2+O3)
-ldxi    c  uc  s  us  i  ui  l  ul  p  f  d  O1 = *(O2+O3)
address@hidden example
-
address@hidden Store operations
address@hidden accepts two operands while @code{stx} accepts three; in
-both cases, the first can be either a register or an immediate
-value. Values are sign-extended to fit a whole register.
address@hidden
-str     c  uc  s  us  i  ui  l  ul  p  f  d  *O1 = O2
-sti     c  uc  s  us  i  ui  l  ul  p  f  d  *O1 = O2
-stxr    c  uc  s  us  i  ui  l  ul  p  f  d  *(O1+O2) = O3
-stxi    c  uc  s  us  i  ui  l  ul  p  f  d  *(O1+O2) = O3
address@hidden example
-
address@hidden Argument management
-These are:
address@hidden
-prepare                   i                f  d
-pusharg     c  uc  s  us  i  ui  l  ul  p  f  d
-getarg      c  uc  s  us  i  ui  l  ul  p  f  d
-arg         c  uc  s  us  i  ui  l  ul  p  f  d
-retval      c  uc  s  us  i  ui  l  ul  p
address@hidden example
-
-Of these, the first two are used by the caller, while the last two
-are used by the callee.  A code snippet that wants to call another
-procedure and has to pass registers must, in order: use the
address@hidden instruction, giving the number of arguments to
-be passed to the procedure (once for each data type); use
address@hidden to push the arguments @strong{in reverse order};
-and use @code{calli} or @code{finish} (explained below) to
-perform the actual call.
-
address@hidden and @code{getarg} are used by the callee.
address@hidden is different from other instruction in that it does not
-actually generate any code: instead, it is a function which returns
-a value to be passed to @address@hidden a
-value'' means that @lightning{} macros that compile these
-instructions return a value when expanded.} You should call
address@hidden as soon as possible, before any function call or, more
-easily, right after the @code{prolog} or @code{leaf} instructions
-(which are treated later).
-
address@hidden accepts a register argument and a value returned by
address@hidden, and will move that argument to the register, extending
-it (with or without sign, according to the data type specification)
-to fit a whole register.  These instructions are more intimately
-related to the usage of the @lightning{} instruction set in code
-that generates other code, so they will be treated more
-specifically in @ref{GNU lightning macros, , Generating code at
-run-time}.
-
-Finally, the @code{retval} instruction fetches the return value of a
-called function in a register.  The @code{retval} instruction takes a
-register argument and copies the return value of the previously called
-function in that register.  A function should put its own return value
-in the @code{RET} register before returning.  @xref{Fibonacci, the
-Fibonacci numbers}, for an example.
-
-You should observe a few rules when using these macros.  First of
-all, it is not allowed to call functions with more than six arguments;
-this was done to simplify and speed up the implementation on
-architectures that use registers for parameter passing.
-
-You should not nest calls to @code{prepare}, nor call zero-argument
-functions (which do not need a call to @code{prepare}) inside a
address@hidden/calli} or @code{prepare/finish} block.  Doing this
-might corrupt already pushed arguments.
-
-You @strong{cannot} pass parameters between subroutines using
-the six general-purpose registers.  This might work only when
-targeting particular architectures.
-
-On the other hand, it is possible to assume that callee-saved registers
-(@code{R0} through @code{R2}) are not clobbered by another dynamically
-generated function which does not use them as operands in its code and
-which does not return a value.
-
address@hidden Branch instructions
-Like @code{arg}, these also return a value which, in this case,
-is to be used to compile forward branches as explained in
address@hidden, , Fibonacci numbers}.  They accept a pointer to the
-destination of the branch and two operands to be compared; of these,
-the last can be either a register or an immediate.  They are:
address@hidden
-bltr      i  ui  l  ul  p  f  d  @r{if }(O2 <  O3)@r{ goto }O1
-blti      i  ui  l  ul  p        @r{if }(O2 <  O3)@r{ goto }O1
-bler      i  ui  l  ul  p  f  d  @r{if }(O2 <= O3)@r{ goto }O1
-blei      i  ui  l  ul  p        @r{if }(O2 <= O3)@r{ goto }O1
-bgtr      i  ui  l  ul  p  f  d  @r{if }(O2 >  O3)@r{ goto }O1
-bgti      i  ui  l  ul  p        @r{if }(O2 >  O3)@r{ goto }O1
-bger      i  ui  l  ul  p  f  d  @r{if }(O2 >= O3)@r{ goto }O1
-bgei      i  ui  l  ul  p        @r{if }(O2 >= O3)@r{ goto }O1
-beqr      i  ui  l  ul  p  f  d  @r{if }(O2 == O3)@r{ goto }O1
-beqi      i  ui  l  ul  p        @r{if }(O2 == O3)@r{ goto }O1
-bner      i  ui  l  ul  p  f  d  @r{if }(O2 != O3)@r{ goto }O1
-bnei      i  ui  l  ul  p        @r{if }(O2 != O3)@r{ goto }O1
-
-bunltr                     f  d  @r{if }!(O2 >= O3)@r{ goto }O1
-bunler                     f  d  @r{if }!(O2 >  O3)@r{ goto }O1
-bungtr                     f  d  @r{if }!(O2 <= O3)@r{ goto }O1
-bunger                     f  d  @r{if }!(O2 <  O3)@r{ goto }O1
-buneqr                     f  d  @r{if }!(O2 <  O3) && !(O2 >  O3)@r{ goto }O1
-bltgtr                     f  d  @r{if }!(O2 >= O3) || !(O2 <= O3)@r{ goto }O1
-bordr                      f  d  @r{if } (O2 == O2) &&  (O3 == O3)@r{ goto }O1
-bunordr                    f  d  @r{if }!(O2 != O2) ||  (O3 != O3)@r{ goto }O1
-
-bmsr      i ui l  ul             @r{if }O2 &  address@hidden goto }O1
-bmsi      i ui l  ul             @r{if }O2 &  address@hidden goto }O1
-bmcr      i ui l  ul             @r{if }!(O2 & O3)@r{ goto }O1
-bmci      i ui l  ul             @r{if }!(O2 & O3)@r{ goto address@hidden 
mnemonics mean, respectively, @dfn{branch if mask set} and @dfn{branch if mask 
cleared}.}
-boaddr    i ui l  ul             O2 += address@hidden, goto address@hidden on 
overflow}
-boaddi    i ui l  ul             O2 += address@hidden, goto address@hidden on 
overflow}
-bosubr    i ui l  ul             O2 -= address@hidden, goto address@hidden on 
overflow}
-bosubi    i ui l  ul             O2 -= address@hidden, goto address@hidden on 
overflow}
address@hidden example
-
address@hidden Jump and return operations
-These accept one argument except @code{ret} which has none; the
-difference between @code{finish} and @code{calli} is that the
-latter does not clean the stack from pushed parameters (if any)
-and the former must @strong{always} follow a @code{prepare}
-instruction.
address@hidden
-calli     (not specified)                  @r{function call to O1}
-callr     (not specified)                  @r{function call to a register}
-finish    (not specified)                  @r{function call to O1}
-finishr   (not specified)                  @r{function call to a register}
-jmpi/jmpr (not specified)                  @r{unconditional jump to O1}
-ret       (not specified)                  @r{return from subroutine}
-retval    c  uc s  us i  ui l  ul p  f  d  @r{move return value}
-                                           @r{to register}
address@hidden example
-
-Like branch instruction, @code{jmpi} also returns a value which is to
-be used to compile forward branches. @xref{Fibonacci, , Fibonacci
-numbers}.
-
address@hidden Function prolog
-
-These macros are used to set up the function prolog, in particular to
-declare the number of arguments accepted by a function, and to reserve
-space on the stack to be used for variables.  They accept a single
-numeric argument.
-
address@hidden
-prolog    (not specified)                  @r{function prolog for O1 args}
-leaf      (not specified)                  @r{the same for leaf functions}
-allocai   (not specified)                  @r{reserve space on the stack}
address@hidden example
-
-Results are undefined when using function calls in a leaf function.
-
address@hidden receives the number of bytes to allocate and returns
-the offset from the frame pointer register @code{FP} to the base of
-the area.  The area is aligned to an @code{int}; future versions of
address@hidden may provide more fine-grained control on the alignment of
-stack-allocated variables.
address@hidden table
-
-As a small appetizer, here is a small function that adds 1 to the input
-parameter (an @code{int}).  I'm using an assembly-like syntax here which
-is a bit different from the one used when writing real subroutines with
address@hidden; the real syntax will be introduced in @xref{GNU lightning
-macros, , Generating code at run-time}.
-
address@hidden
-incr:
-     leaf      1
-in = arg_i                   @rem{! We have an integer argument}
-     getarg_i  R0, in        @rem{! Move it to R0}
-     addi_i    RET, R0, 1    @rem{! Add 1\, put result in return value}
-     ret                     @rem{! And return the result}
address@hidden example
-
-And here is another function which uses the @code{printf} function from
-the standard C library to write a number in hexadecimal notation:
-
address@hidden
-printhex:
-     prolog    1
-in = arg_i                    @rem{! Same as above}
-     getarg_i  R0, in
-     prepare   2              @rem{! Begin call sequence for printf}
-     pusharg_i R0             @rem{! Push second argument}
-     pusharg_p "%x"           @rem{! Push format string}
-     finish    printf         @rem{! Call printf}
-     ret                      @rem{! Return to caller}
address@hidden example
-
address@hidden GNU lightning macros
address@hidden Generating code at run-time
-
-To use @lightning{}, you should include the @file{lightning.h} file that
-is put in your include directory by the @samp{make install} command.
-That include files defines about four hundred public macros (plus
-others that are private to @lightning{}), one for each opcode listed
-above.
-
-Each of the instructions above translates to a macro.  All you have to
-do is prepend @code{jit_} (lowercase) to opcode names and @code{JIT_}
-(uppercase) to register names.  Of course, parameters are to be put
-between parentheses, just like with every other @sc{cpp} macro.
-
-This small tutorial presents three examples:
-
address@hidden
address@hidden @bullet
address@hidden
-The @code{incr} function found in @ref{The instruction set, ,
address@hidden's instruction set}:
-
address@hidden
-A simple function call to @code{printf}
-
address@hidden
-An RPN calculator.
-
address@hidden
-Fibonacci numbers
address@hidden itemize
address@hidden iftex
address@hidden
address@hidden
-* incr::             A function which increments a number by one
-* printf::           A simple function call to printf
-* RPN calculator::   A more complex example, an RPN calculator
-* Fibonacci::        Calculating Fibonacci numbers
address@hidden menu
address@hidden ifnottex
-
address@hidden incr
address@hidden A function which increments a number by one
-
-Let's see how to create and use the sample @code{incr} function created
-in @ref{The instruction set, , @lightning{}'s instruction set}:
-
address@hidden
-#include <stdio.h>
-#include "lightning.h"
-
-static jit_insn codeBuffer[1024];
-
-typedef int (*pifi)(int);    @rem{/* Pointer to Int Function of Int */}
-
-int main()
address@hidden
-  pifi  incr = (pifi) (jit_set_ip(codeBuffer).iptr);
-  int   in;
-
-  jit_leaf(1);                     @rem{/* @t{     leaf  1            } */}
-  in = jit_arg_i();                @rem{/* @t{in = arg_i              } */}
-  jit_getarg_i(JIT_R0, in);        @rem{/* @t{     getarg_i R0        } */}
-  jit_addi_i(JIT_RET, JIT_R0, 1);  @rem{/* @t{     addi_i   RET\, R0\, 1} */}
-  jit_ret();                       @rem{/* @t{     ret                } */}
-
-  jit_flush_code(codeBuffer, jit_get_ip().ptr);
-
-  @rem{/* call the generated code\, passing 5 as an argument */}
-  printf("%d + 1 = %d\n", 5, incr(5));
-  return 0;
address@hidden
address@hidden example
-
-Let's examine the code line by line (well, address@hidden):
-
address@hidden @t
address@hidden #include "lightning.h"
-You already know about this.  It defines all of @lightning{}'s macros.
-
address@hidden static jit_insn codeBuffer[1024];
-You might wonder about what is @code{jit_insn}.  It is just a type that
-is defined by @lightning{}.  Its exact definition depends on the
-architecture; in general, defining an array of 1024 @code{jit_insn}s
-allows one to write 100 to 400 @lightning{} instructions (depending on
-the architecture and exact instructions).
-
address@hidden typedef int (*pifi)(int);
-Just a handy typedef for a pointer to a function that takes an
address@hidden and returns another.
-
address@hidden pifi incr = (pifi) (jit_set_ip(codeBuffer).iptr);
-This is the first @lightning{} macro we encounter that does not map to
-an instruction.  It is @code{jit_set_ip}, which takes a pointer to an
-area of memory where compiled code will be put and returns the same
-value, cast to a @code{union} type whose members are pointers to
-functions returning different C types.  This union is called
address@hidden and is defined as follows:
-
address@hidden
-    typedef union jit_code @{
-      char               *ptr;
-      void               (*vptr)();
-      char               (*cptr)();
-      unsigned char      (*ucptr)();
-      short              (*sptr)();
-      unsigned short     (*usptr)();
-      int                (*iptr)();
-      unsigned int       (*uiptr)();
-      long               (*lptr)();
-      unsigned long      (*ulptr)();
-      void *             (*pptr)();
-      float              (*fptr)();
-      double             (*dptr)();
-    @} jit_code;
address@hidden example
-
-Any of the members could have been used, since the result is soon casted
-to type @code{pifi} but, for the sake of clarity, the program uses
address@hidden, a pointer to a function with no prototype and returning an
address@hidden
-
-Analogous to @code{jit_set_ip} is @code{jit_get_ip}, which does not
-modify the instruction pointer---it is nothing more than a cast of the
-current @sc{ip} to @code{jit_code}.
-
address@hidden int       in;
-A footnote in @ref{The instruction set, , @lightning{}'s instruction
-set}, under the description of @code{arg}, says that macros implementing
address@hidden return a value---we'll be using this variable to store the
-result of @code{arg}.
-
address@hidden jit_leaf(1);
-Ok, so we start generating code for our beloved address@hidden it will
-accept one argument and won't call any other function.
-
address@hidden in = jit_arg_i();
address@hidden jit_getarg_i(JIT_R0, in);
-We retrieve the first (and only) argument, an integer, and store it
-into the general-purpose register @code{R0}.
-
address@hidden jit_addi_i(JIT_RET, JIT_R0, 1);
-We add one to the content of the register and store the result in the
-return value.
-
address@hidden jit_ret();
-This instruction generates a standard function epilog that returns
-the contents of the @code{RET} register.
-
address@hidden jit_flush_code(codeBuffer, jit_get_ip().ptr);
-This instruction is very important.  It flushes the generated code
-area out of the processor's instruction cache, avoiding the processor
-executes bogus data that it happens to find there.  The
address@hidden function accepts the first and the last address
-to flush; we use @code{jit_get_ip} to find out the latter.
-
address@hidden printf("%d + 1 = %d", 5, incr(5));
-Calling our function is this simple---it is not distinguishable from
-a normal C function call, the only difference being that @code{incr}
-is a variable.
address@hidden table
-
address@hidden abstracts two phases of dynamic code generation: selecting
-instructions that map the standard representation, and emitting binary
-code for these instructions.  The client program has the responsibility
-of describing the code to be generated using the standard @lightning{}
-instruction set.
-
-Let's examine the code generated for @code{incr} on the SPARC and x86
-architectures (on the right is the code that an assembly-language
-programmer would write):
-
address@hidden @b
address@hidden SPARC
address@hidden
-    save %sp, -96, %sp
-    mov  %i0, %l0                   retl
-    add  %l0, 1,  %i0               add %o0, 1, %o0
-    ret
-    restore
address@hidden example
-In this case, @lightning{} introduces overhead to create a register
-window (not knowing that the procedure is a leaf procedure) and to
-move the argument to the general purpose register @code{R0} (which
-maps to @code{%l0} on the SPARC).  The former overhead could be
-avoided by teaching @lightning{} about leaf procedures (@pxref{Future});
-the latter could instead be avoided by rewriting the getarg instruction
-as @code{jit_getarg_i(JIT_RET, in)}, which was not done in this
-example.
-
address@hidden x86
address@hidden
-    pushl %ebp
-    movl  %esp, %ebp
-    pushl %ebx
-    pushl %esi
-    pushl %edi
-    movl  8(%ebp), %eax        movl 4(%esp), %eax
-    addl  $1, %eax             incl %eax
-    popl  %edi
-    popl  %esi
-    popl  %ebx
-    popl  %ebp
-    ret                        ret
address@hidden example
-In this case, the main overhead is due to the function's prolog and
-epilog, which is nine instructions long on the x86; a hand-written
-routine would not save unused callee-preserved registers on the stack.
-It is to be said, however, that this is not a problem in more
-complicated uses, because more complex procedure would probably use
-the @code{V0} through @code{V2} registers (@code{%ebx}, @code{%esi},
address@hidden); in this case, a hand-written routine would have included
-the prolog too.  Also, a ten byte prolog would probably be a small
-overhead in a more complex function.
address@hidden table
-
-In such a simple case, the macros that make up the back-end compile
-reasonably efficient code, with the notable exception of prolog/epilog
-code.
-
address@hidden printf
address@hidden A simple function call to @code{printf}
-
-Again, here is the code for the example:
-
address@hidden
-#include <stdio.h>
-#include "lightning.h"
-
-static jit_insn codeBuffer[1024];
-
-typedef void (*pvfi)(int);      @rem{/* Pointer to Void Function of Int */}
-
-int main()
address@hidden
-  pvfi          myFunction;             @rem{/* ptr to generated code */}
-  char          *start, *end;           @rem{/* a couple of labels */}
-  int           in;                     @rem{/* to get the argument */}
-
-  myFunction = (pvfi) (jit_set_ip(codeBuffer).vptr);
-  start = jit_get_ip().ptr;
-  jit_prolog(1);
-  in = jit_arg_i();
-  jit_movi_p(JIT_R0, "generated %d bytes\n");
-  jit_getarg_i(JIT_R1, in);
-  jit_prepare(2);
-    jit_pusharg_i(JIT_R1);              @rem{/* push in reverse order */}
-    jit_pusharg_p(JIT_R0);
-  jit_finish(printf);
-  jit_ret();
-  end = jit_get_ip().ptr;
-
-  @rem{/* call the generated code\, passing its size as argument */}
-  jit_flush_code(start, end);
-  myFunction(end - start);
address@hidden
address@hidden example
-
-The function shows how many bytes were generated.  Most of the code
-is not very interesting, as it resembles very closely the program
-presented in @ref{incr, , A function which increments a number by one}.
-
-For this reason, we're going to concentrate on just a few statements.
-
address@hidden @t
address@hidden start = jit_get_ip().ptr;
address@hidden @address@hidden
address@hidden end = jit_get_ip().ptr;
-These two instruction call the @code{jit_get_ip} macro which was
-mentioned in @ref{incr, , A function which increments a number by one}
-too.  In this case we use the only field of @code{jit_code} that is
-not a function pointer: @code{ptr}, which is a simple @code{char *}.
-
address@hidden jit_movi_p(JIT_R0, "generated %d bytes\n");
-Note the use of the @samp{p} type specifier, which automatically
-casts the second parameter to an @code{unsigned long} to make the
-code more clear and less cluttered by typecasts.
-
address@hidden jit_prepare(2);
address@hidden jit_pusharg_i(JIT_R1);
address@hidden jit_pusharg_p(JIT_R0);
address@hidden jit_finish(printf);
-Once the arguments to @code{printf} have been put in general-purpose
-registers, we can start a prepare/pusharg/finish sequence that
-moves the argument to either the stack or registers, then calls
address@hidden, then cleans up the stack.  Note how @lightning{}
-abstracts the differences between different architectures and
-ABI's -- the client program does not know how parameter passing
-works on the host architecture.
address@hidden table
-
address@hidden RPN calculator
address@hidden A more complex example, an RPN calculator
-
-We create a small stack-based RPN calculator which applies a series
-of operators to a given parameter and to other numeric operands.
-Unlike previous examples, the code generator is fully parameterized
-and is able to compile different formulas to different functions.
-Here is the code for the expression compiler; a sample usage will
-follow.
-
-Since @lightning{} does not provide push/pop instruction, this
-example uses a stack-allocated area to store the data.  Such an
-area can be allocated using the macro @code{jit_allocai}, which
-receives the number of bytes to allocate and returns the offset
-from the frame pointer register @code{JIT_FP} to the base of the
-area.  The area is aligned to an @code{int}; future versions
-of @lightning{} may provide more fine-grained control on the
-alignment of stack-allocated variables.
-
-Usually, you will use the @code{ldxi} and @code{stxi} instruction
-to access stack-allocated variables.  However, it is possible to
-use operations such as @code{add} to compute the address of the
-variables, and pass the address around.
-
address@hidden
-#include <stdio.h>
-#include "lightning.h"
-
-typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
-
-void stack_push(int reg, int *sp)
address@hidden
-  jit_stxi_i (*sp, JIT_FP, reg);
-  *sp += sizeof (int);
address@hidden
-
-void stack_pop(int reg, int *sp)
address@hidden
-  *sp -= sizeof (int);
-  jit_ldxi_i (reg, JIT_FP, *sp);
address@hidden
-
-pifi compile_rpn(char *expr)
address@hidden
-  pifi fn;
-  int stack_base, stack_ptr;
-  int in;
-
-  fn = (pifi) (jit_get_ip().iptr);
-  jit_leaf(1);
-  in = jit_arg_i();
-  stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
-
-  jit_getarg_i(JIT_R2, in);
-
-  while (*expr) @{
-    char buf[32];
-    int n;
-    if (sscanf(expr, "%[0-9]%n", buf, &n)) @{
-      expr += n - 1;
-      stack_push(JIT_R0, &stack_ptr);
-      jit_movi_i(JIT_R0, atoi(buf));
-    @} else if (*expr == 'x') @{
-      stack_push(JIT_R0, &stack_ptr);
-      jit_movi_i(JIT_R0, JIT_R2);
-    @} else if (*expr == '+') @{
-      stack_pop(JIT_R1, &stack_ptr);
-      jit_addr_i(JIT_R0, JIT_R1, JIT_R0);
-    @} else if (*expr == '-') @{
-      stack_pop(JIT_R1, &stack_ptr);
-      jit_subr_i(JIT_R0, JIT_R1, JIT_R0);
-    @} else if (*expr == '*') @{
-      stack_pop(JIT_R1, &stack_ptr);
-      jit_mulr_i(JIT_R0, JIT_R1, JIT_R0);
-    @} else if (*expr == '/') @{
-      stack_pop(JIT_R1, &stack_ptr);
-      jit_divr_i(JIT_R0, JIT_R1, JIT_R0);
-    @} else @{
-      fprintf(stderr, "cannot compile: %s\n", expr);
-      abort();
-    @}
-    ++expr;
-  @}
-  jit_movr_i(JIT_RET, JIT_R0);
-  jit_ret();
-  return fn;
address@hidden
address@hidden example
-
-The principle on which the calculator is based is easy: the stack top
-is held in R0, while the remaining items of the stack are held in the
-memory area that we allocate with @code{allocai}.  Compiling a numeric
-operand or the argument @code{x} pushes the old stack top onto the
-stack and moves the operand into R0; compiling an operator pops the
-second operand off the stack into R1, and compiles the operation so
-that the result goes into R0, thus becoming the new stack top.
-
-This example allocates a fixed area for 32 @code{int}s.  This is not
-a problem when the function is a leaf like in this case; in a full-blown
-compiler you will want to analyze the input and determine the number
-of needed stack slots---a very simple example of register allocation.
-The area is then managed like a stack using @code{stack_push} and
address@hidden
-
-Try to locate a call to @code{jit_set_ip} in the source code.  You
-will not find one; this means that the client has to manually set
-the instruction pointer.  This technique has one advantage and one
-drawback.  The advantage is that the client can simply set the
-instruction pointer once and then generate code for multiple functions,
-one after another, without caring about passing a different instruction
-pointer each time; see @ref{Reentrancy, , Re-entrant usage of
address@hidden for the disadvantage.
-
-Source code for the client (which lies in the same source file) follows:
-
address@hidden
-static jit_insn codeBuffer[1024];
-
-int main()
address@hidden
-  pifi c2f, f2c;
-  int i;
-
-  jit_set_ip(codeBuffer);
-  c2f = compile_rpn("32x9*5/+");
-  f2c = compile_rpn("x32-5*9/");
-  jit_flush_code(codeBuffer, jit_get_ip().ptr);
-
-  printf("\nC:");
-  for (i = 0; i <= 100; i += 10) printf("%3d ", i);
-  printf("\nF:");
-  for (i = 0; i <= 100; i += 10) printf("%3d ", c2f(i));
-  printf("\n");
-
-  printf("\nF:");
-  for (i = 32; i <= 212; i += 10) printf("%3d ", i);
-  printf("\nC:");
-  for (i = 32; i <= 212; i += 10) printf("%3d ", f2c(i));
-  printf("\n");
-  return 0;
address@hidden
address@hidden example
-
-The client displays a conversion table between Celsius and Fahrenheit
-degrees (both Celsius-to-Fahrenheit and Fahrenheit-to-Celsius). The
-formulas are, @math{F(c) = c*9/5+32} and @math{C(f) = (f-32)*5/9},
-respectively.
-
-Providing the formula as an argument to @code{compile_rpn} effectively
-parameterizes code generation, making it possible to use the same code
-to compile different functions; this is what makes dynamic code
-generation so powerful.
-
-The @file{rpn.c} file in the @lightning{} distribution includes a more
-complete (and more complex) implementation of @code{compile_rpn},
-which does constant folding and is able to assemble instructions with
-an immediate parameter.  Still, it is based on the same principle and
-also uses @code{allocai} to allocate space for the stack.
-
address@hidden Fibonacci
address@hidden Fibonacci numbers
-
-The code in this section calculates a variant of the Fibonacci sequence.
-While the traditional Fibonacci sequence is modeled by the recurrence
-relation:
address@hidden
-     f(0) = f(1) = 1
-     f(n) = f(n-1) + f(n-2)
address@hidden display
-
address@hidden
-the functions in this section calculates the following sequence, which
-is more interesting as a address@hidden's because, as is
-easily seen, the sequence represents the number of activations of the
address@hidden procedure that are needed to compute its value through
-recursion.}:
address@hidden
-     nfibs(0) = nfibs(1) = 1
-     nfibs(n) = nfibs(n-1) + nfibs(n-2) + 1
address@hidden display
-
-The purpose of this example is to introduce branches.  There are two
-kind of branches: backward branches and forward branches.  We'll
-present the calculation in a recursive and iterative form; the
-former only uses forward branches, while the latter uses both.
-
address@hidden
-#include <stdio.h>
-#include "lightning.h"
-
-static jit_insn codeBuffer[1024];
-
-typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
-
-int main()
address@hidden
-  pifi      nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
-  int       in;                 @rem{/* offset of the argument */}
-  jit_insn  *ref;               @rem{/* to patch the forward reference */}
-
-        jit_prolog   (1);
-  in =  jit_arg_ui   ();
-        jit_getarg_ui(JIT_V0, in);              @rem{/* V0 = n */}
-  ref = jit_blti_ui  (jit_forward(), JIT_V0, 2);
-        jit_subi_ui  (JIT_V1, JIT_V0, 1);       @rem{/* V1 = n-1 */}
-        jit_subi_ui  (JIT_V2, JIT_V0, 2);       @rem{/* V2 = n-2 */}
-        jit_prepare(1);
-          jit_pusharg_ui(JIT_V1);
-        jit_finish(nfibs);
-        jit_retval(JIT_V1);                     @rem{/* V1 = nfibs(n-1) */}
-        jit_prepare(1);
-          jit_pusharg_ui(JIT_V2);
-        jit_finish(nfibs);
-        jit_retval(JIT_V2);                     @rem{/* V2 = nfibs(n-2) */}
-        jit_addi_ui(JIT_V1,  JIT_V1,  1);
-        jit_addr_ui(JIT_RET, JIT_V1, JIT_V2);   @rem{/* RET = V1 + V2 + 1 */}
-        jit_ret();
-
-  jit_patch(ref);                               @rem{/* patch jump */}
-        jit_movi_i(JIT_RET, 1);                 @rem{/* RET = 1 */}
-        jit_ret();
-
-  @rem{/* call the generated code\, passing 32 as an argument */}
-  jit_flush_code(codeBuffer, jit_get_ip().ptr);
-  printf("nfibs(%d) = %d", 32, nfibs(32));
-  return 0;
address@hidden
address@hidden example
-
-As said above, this is the first example of dynamically compiling
-branches.  Branch instructions have three operands: two contains the
-values to be compared, while the first is a @dfn{label}; @lightning{}
-label's are represented as @code{jit_insn *} values.  Unlike other
-instructions (apart from @code{arg}, which is actually a directive
-rather than an instruction), branch instructions also return a value
-which, as we see in the example above, can be used to compile
-forward references.
-
-Compiling a forward reference is a two-step operation.  First, a
-branch is compiled with a dummy label, since the actual destination
-of the jump is not yet known; the dummy label is returned by the
address@hidden()} macro.  The value returned by the branch
-instruction is saved to be used later.
-
-Then, when the destination of the jump is reached, another macro
-is used, @code{jit_patch()}. This macro must be called once for
address@hidden point in which the code had a forward branch to the
-instruction following @code{jit_patch} (in this case a @code{movi_i}
-instruction).
-
-Now, here is the iterative version:
-
address@hidden
-#include <stdio.h>
-#include "lightning.h"
-
-static jit_insn codeBuffer[1024];
-
-typedef int (*pifi)(int);       @rem{/* Pointer to Int Function of Int */}
-
-int main()
address@hidden
-  pifi     nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
-  int      in;                  @rem{/* offset of the argument */}
-  jit_insn *ref;                @rem{/* to patch the forward reference */}
-  jit_insn *loop;               @rem{/* start of the loop */}
-
-        jit_leaf     (1);
-  in =  jit_arg_ui   ();
-        jit_getarg_ui(JIT_R2, in);              @rem{/* R2 = n */}
-        jit_movi_ui  (JIT_R1, 1);
-  ref = jit_blti_ui  (jit_forward(), JIT_R2, 2);
-        jit_subi_ui  (JIT_R2, JIT_R2, 1);
-        jit_movi_ui  (JIT_R0, 1);
-
-  loop= jit_get_label();
-        jit_subi_ui  (JIT_R2, JIT_R2, 1);       @rem{/* decr. counter */}
-        jit_addr_ui  (JIT_V0, JIT_R0, JIT_R1);  @rem{/* V0 = R0 + R1 */}
-        jit_movr_ui  (JIT_R0, JIT_R1);          @rem{/* R0 = R1 */}
-        jit_addi_ui  (JIT_R1, JIT_V0, 1);       @rem{/* R1 = V0 + 1 */}
-        jit_bnei_ui  (loop, JIT_R2, 0);         @rem{/* if (R2) goto loop; */}
-
-  jit_patch(ref);                               @rem{/* patch forward jump */}
-        jit_movr_ui  (JIT_RET, JIT_R1);         @rem{/* RET = R1 */}
-        jit_ret      ();
-
-  @rem{/* call the generated code\, passing 36 as an argument */}
-  jit_flush_code(codeBuffer, jit_get_ip().ptr);
-  printf("nfibs(%d) = %d", 36, nfibs(36));
-  return 0;
address@hidden
address@hidden example
-
-This code calculates the recurrence relation using iteration (a
address@hidden loop in high-level languages).  There is still a forward
-reference (indicated by the @code{jit_forward}/@code{jit_patch} pair);
-there are no function calls anymore: instead, there is a backward
-jump (the @code{bnei} at the end of the loop).
-
-In this case, the destination address should be known, because the
-jumps lands on an instruction that has already been compiled.
-However the program must make a provision and remember the address
-where the jump will land.  This is achieved with @code{jit_get_label},
-yet another macro that is much similar to @code{jit_get_ip} but,
-instead of a @code{jit_code} union, it answers an @code{jit_insn *}
-that the branch macros accept.
-
-Now, let's make one more change: let's rewrite the loop like this:
-
address@hidden
-  @address@hidden
-
-  jit_delay(
-        jit_movi_ui  (JIT_R1, 1),
-  ref = jit_blti_ui  (jit_forward(), JIT_R2, 2));
-        jit_subi_ui  (JIT_R2, JIT_R2, 1);
-
-  loop= jit_get_label();
-        jit_subi_ui  (JIT_R2, JIT_R2, 1);       @rem{/* decr. counter */}
-        jit_addr_ui  (JIT_V0, JIT_R0, JIT_R1);  @rem{/* V0 = R0 + R1 */}
-        jit_movr_ui  (JIT_R0, JIT_R1);          @rem{/* R0 = R1 */}
-  jit_delay(
-        jit_addi_ui  (JIT_R1, JIT_V0, 1),       @rem{/* R1 = V0 + 1 */}
-        jit_bnei_ui  (loop, JIT_R2, 0));        @rem{/* if (R2) goto loop; */}
-
-  @address@hidden
address@hidden example
-
-The @code{jit_delay} macro is used to schedule delay slots in jumps and
-branches.  This is optional, but might lead to performance improvements
-in tight inner loops (of course not in a loop that is executed 35
-times, but this is just an example).
-
address@hidden takes two @lightning{} instructions, a @dfn{delay
-instruction} and a @dfn{branch instruction}.  Note that the two
-instructions must be written in execution order (first the delay
-instruction, then the branch instruction), @strong{not} with the branch
-first.  If the current machine has a delay slot, the delay instruction
-(or part of it) is placed in the delay slot after the branch
-instruction; otherwise, it emits the delay instruction before the branch
-instruction.  The delay instruction must not depend on being executed
-before or after the branch.
-
-Instead of @code{jit_patch}, you can use @code{jit_patch_at}, which
-takes two arguments: the first is the same as for @code{jit_patch}, and
-the second is the valued to be patched in.  In other words, these two
-invocations have the same effect:
-
address@hidden
-  jit_patch (jump_pc);
-  jit_patch_at (jump_pc, jit_get_ip ());
address@hidden example
-
-Dual to branches and @code{jit_patch_at} are @code{jit_movi_p}
-and @code{jit_patch_movi}, which can also be used to implement
-forward references.  @code{jit_movi_p} is carefully implemented
-to use an encoding that is as long as possible, so that it can
-always be patched; in addition, like branches, it will return
-an address which is then passed to @code{jit_patch_movi}.  The
-usage of @code{jit_patch_movi} is similar to @code{jit_patch_at}.
-
address@hidden Reentrancy
address@hidden Re-entrant usage of @lightning{}
-
-By default, @lightning{} is able to compile different functions at the
-same time as long as it happens in different object files, and on the
-other hand constrains code generation tasks to reside in a single
-object file.
-
-The reason for this is not apparent, but is easily explained:
-the @file{lightning.h} header file defines its state as a
address@hidden variable, so calls to @code{jit_set_ip} and
address@hidden residing in different files access different
-instruction pointers.  This was not done without reason: it makes
-the usage of @lightning{} much simpler, as it limits the initialization
-tasks to the bare minimum and removes the need to link the program
-with a separate library.
-
-On the other hand, multi-threaded or otherwise concurrent programs
-require reentrancy in the code generator, so this approach cannot be
-the only one.  In fact, it is possible to define your own copy of
address@hidden's instruction state by defining a variable of type
address@hidden and @code{#define}-ing @code{_jit} to it:
-
address@hidden
-    struct jit_state lightning;
-    #define _jit lightning
address@hidden example
-
-You are free to define the @code{jit_state} variable as you like:
address@hidden, @code{static} to a function, @code{auto}, or global.
-
-This feature takes advantage of an aspect of macros (@dfn{cascaded
-macros}), which is documented thus in @acronym{CPP}'s reference manual:
-
address@hidden
-A cascade of macros is when one macro's body contains a reference to
-another macro.  This is very common practice.  For example,
address@hidden
-#define BUFSIZE 1020
-#define TABLESIZE BUFSIZE
address@hidden example
-This is not at all the same as defining @code{TABLESIZE} to be
address@hidden  The @code{#define} for @code{TABLESIZE} uses exactly the
-body you specify---in this case, @code{BUFSIZE}---and does not check to
-see whether it too is the name of a macro; it's only when you use
address@hidden that the result of its expansion is checked for more
-macro names. 
-
-This makes a difference if you change the definition of @code{BUFSIZE}
-at some point in the source file. @code{TABLESIZE}, defined as shown,
-will always expand using the definition of @code{BUFSIZE} that is
-currently in effect: 
-#define BUFSIZE 1020
-#define TABLESIZE BUFSIZE
-#undef BUFSIZE
-#define BUFSIZE 37
-
-Now @code{TABLESIZE} expands (in two stages) to `37'. (The @code{#undef}
-is to prevent any warning about the nontrivial redefinition of
address@hidden)
address@hidden quotation
-
address@hidden
-In the same way, @code{jit_get_label} will adopt whatever definition of
address@hidden is in effect:
address@hidden
-#define        jit_get_label()                 (_jit.pc)
address@hidden example
-
-Special care must be taken when functions residing in separate files
-must access the same state.  This could be the case, for example, if a
-special library contained function for strength reduction of
-multiplications to adds & shifts, or maybe of divisions to
-multiplications and shifts.  The function would be compiled using a
-single definition of @code{_jit} and that definition would be used
-whenever the function would be called.
-
-Since @lightning{} uses a feature of the preprocessor to obtain
-re-entrancy, it makes sense to rely on the preprocessor in this case
-too.
-
-The idea is to pass the current @code{struct jit_state} to the
-function:
-
address@hidden
-static void
-_opt_muli_i(jit, dest, source, n)
-     register struct jit_state *jit;
-     register int              dest, source, n;
address@hidden
-#define _jit          jit
address@hidden
-#undef _jit
address@hidden
address@hidden example
-
address@hidden
-doing this unbeknownst to the client, using a macro in the header file:
-
address@hidden
-extern void _opt_muli_i(struct jit_state *, int, int, int);
-
-#define opt_muli_i(rd, rs, n)  _opt_muli_i(&_jit, (rd), (rs), (n))
address@hidden example
-
-
address@hidden Registers
address@hidden Accessing the whole register file
-
-As mentioned earlier in this chapter, all @lightning{} back-ends are
-guaranteed to have at least six general-purpose integer registers and
-six floating-point registers, but many back-ends will have more.
-
-To access the entire register files, you can use the
address@hidden, @code{JIT_V} and @code{JIT_FPR} macros.  They
-accept a parameter that identifies the register number, which
-must be strictly less than @code{JIT_R_NUM}, @code{JIT_V_NUM}
-and @code{JIT_FPR_NUM} respectively; the number need not be
-constant.  Of course, expressions like @code{JIT_R0} and
address@hidden(0)} denote the same register, and likewise for
-integer callee-saved, or floating-point, registers.
-
address@hidden Bundling GNU lightning
address@hidden Using @lightning{} in your programs
-
-It is very easy to include @lightning{}'s source code (without the
-documentation and examples) into your program's distribution 
-so that people don't need to have it installed in order to use it.
-
-Here is a step by step explanation of what to do:
-
address@hidden
address@hidden Run @command{lightningize} from your package's main
-distribution directory.
address@hidden
-     lightningize
address@hidden example
-
address@hidden
-This will copy the source code for the @lightning{} back ends
-into the @file{lightning} directory of your package.
-
address@hidden If you're using Automake, you might be pleased to know that
address@hidden files will be already there.
-
-If you're not using Automake and @code{aclocal}, instead,
-you should delete the @file{Makefile.am} files (they are of no use
-to you) and copy the contents of the @file{lightning.m4} file, found in
address@hidden's macro repository (usually @file{/usr/share/aclocal},
-to your @file{configure.in} or @file{acinclude.m4} or @file{aclocal.m4} file.
-
address@hidden Include a call to the @code{LIGHTNING_CONFIGURE_IF_NOT_FOUND}
-macro in your @file{configure.in} file.
address@hidden enumerate
-
address@hidden will first look for a
-pre-installed copy of @lightning{} and, if it can be found, it will
-use it; otherwise, it will test if there is a back-end for the host
-system.  If @lightning{} is already installed, or if the system is
-supported by lightning, it will define the @code{HAVE_LIGHTNING}
-symbol.
-
-In addition, an Automake conditional named @code{HAVE_INSTALLED_LIGHTNING}
-will be set if @lightning{} is already installed, which can be used to
-set up include paths appropriately.
-
-Finally, @code{LIGHTNING_CONFIGURE_IF_NOT_FOUND} accepts two
-optional parameters: respectively, an action to be taken if @lightning{}
-is available, and an action to be taken if it is not.
diff --git a/doc/version.texi b/doc/version.texi
index c9347b9..b7b6751 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
address@hidden UPDATED 3 June 2009
address@hidden UPDATED-MONTH June 2009
address@hidden EDITION 1.2c
address@hidden VERSION 1.2c
address@hidden UPDATED 24 January 2013
address@hidden UPDATED-MONTH January 2013
address@hidden EDITION 2.0
address@hidden VERSION 2.0



reply via email to

[Prev in Thread] Current Thread [Next in Thread]