1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-21 03:00:19 +02:00

big merge

git-archimport-id: bonzini@gnu.org--2004b/lightning--stable--1.2--patch-1
git-archimport-id: bonzini@gnu.org--2004b/lightning--stable--1.2--patch-2
This commit is contained in:
Paolo Bonzini 2004-10-14 16:10:07 +00:00
parent a72bbf2f6a
commit ba5044a668
49 changed files with 2022 additions and 1059 deletions

1
.cvsignore Normal file
View file

@ -0,0 +1 @@
autom4te.cache

View file

@ -1,2 +1,3 @@
Paolo Bonzini <bonzini@gnu.org> Paolo Bonzini <bonzini@gnu.org>
i386 and PPC assemblers by Ian Piumarta <piumarta@inria.fr> i386 and PPC assemblers by Ian Piumarta <piumarta@inria.fr>
Major PPC contributions by Laurent Michel <ldm@thorgal.homelinux.org>

214
ChangeLog
View file

@ -1,3 +1,217 @@
2004-10-12 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/fp.h: Fix bugs in conditional branches.
2004-10-10 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/funcs.h: Fix pasto in jit_flush_code.
2004-10-08 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/fp.h: Optimized conditional branches.
2004-09-20 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/asm.h: Fix more typos.
2004-09-20 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/asm.h: Fix typos, replace `26' with JIT_AUX.
2004-09-20 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/fp.h: Added conditional branches.
2004-09-18 Laurent Michel <ldm@thorgal.homelinux.org>
* lightning/ppc/fp.h (jit_unler_d, jit_unltr_d, jit_unger_d,
jit_ungtr_d, jit_ltgt_d, jit_uneq_d): Implemented missing tests
to fully support testfp.
(jit_floorr_d_i, jit_ceilr_d_i, jit_roundr_d_i, jit_truncr_d_i):
New macros.
* lightning/ppc/asm.h: Added missing opcodes FCTIWZ and MTFSFI.
* lightning/ppc/funcs.h (_jit_prolog): Fixed minor mistake in
the initialization of _jitl.nextarg_geti, relying on the
JIT_AUX macro as well to get the register offset.
2004-09-07 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/funcs.h: Fix typo.
2004-09-06 Paolo Bonzini <bonzini@gnu.org>
* tests/funcfp.c: Use %g. Remove C99 variable declarations.
* tests/testfp.c: Don't use __builtin_nan.
* lightning/ppc/core.h: Add three V registers.
* lightning/ppc/funcs.h: Adjust.
* lightning/sparc/core.h: Some fixes related to FP argument passing.
Move R0 to %g2, use %o7 for JIT_BIG2.
* lightning/sparc/fp.h: Some fixes related to FP argument passing.
2004-09-02 Paolo Bonzini <bonzini@gnu.org>
* lightning/sparc/core.h: Add another V register,
move R0 to %o7.
2004-07-15 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/funcs.h: Implement jit_flush_code,
in order to support Fedora's exec-shield.
2004-07-14 Paolo Bonzini <bonzini@gnu.org>
* lightning/core-common.h: Add more jit_extr_*_* macros.
* lightning/doc/using.texi: Be clearer about the order
of arguments in jit_extr_*_*.
* lightning/doc/porting.texi: Add more jit_extr_*_* macros.
* lightning/i386/fp.h: Fix typo in jit_extr_i_d.
2004-07-14 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/funcs.h: Adjust offset of LR into
stack frame if running under the Darwin ABI.
2004-07-13 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/fp.h: Rename jit_exti_d to jit_extr_i_d.
2004-07-13 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/core.h: Fix thinko.
* lightning/i386/core.h: Fix jit_lti_ui.
* lightning/core-common.h: Add missing macros.
* lightning/ppc/fp.h: Rename jit_neg_* to jit_negr_*.
* lightning/i386/fp.h: Rename jit_neg_* to jit_negr_*.
* lightning/sparc/fp.h: Rename jit_neg_* to jit_negr_*.
* lightning/fp-common.h: Rename jit_neg_* to jit_negr_*.
* doc/porting.texi: Add undocumented macros.
2004-07-12 Paolo Bonzini <bonzini@gnu.org>
* doc/porting.texi: Add missing macros.
2004-07-12 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/funcs.h: Don't generate trampolines.
Separate prolog and epilog generation.
* lightning/ppc/core.h: Generate epilog explicitly.
Don't reserve r31 anymore.
* lightning/core-common.h: Remove call to jit_setup_code.
2004-07-09 Paolo Bonzini <bonzini@gnu.org>
* lightning/lightning.h.in: Avoid preprocessor warnings.
* lightning/lightning-inst.h: Likewise.
* lightning/i386/core.h: Define JIT_R, JIT_R_NUM, JIT_V,
JIT_V_NUM.
* lightning/ppc/core.h: Likewise.
* lightning/sparc/core.h: Likewise.
* lightning/i386/fp.h: Define JIT_FPR, JIT_FPR_NUM.
* lightning/ppc/fp.h: Likewise.
* lightning/sparc/fp.h: Likewise.
* lightning/core-common.h: Define fixed register names.
* lightning/fp-common.h: Likewise for FP regs.
2004-07-09 Paolo Bonzini <bonzini@gnu.org>
* lightning/ppc/funcs.h: Fix location where return address
is stored.
* lightning/i386/asm.h: Add a trailing _ to opcodes without
any parameter.
* lightning/i386/core.h: Adjust for the above.
2004-04-15 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/fp.h: Change "and" to "_and"
to satisfy C++ compilers.
2004-04-14 Paolo Bonzini <bonzini@gnu.org>
* lightning/sparc/fp.h: Use memcpy to implement jit_movi.
* lightning/ppc/fp.h: Use memcpy to implement jit_movi.
Move floating-point opcodes...
* lightning/ppc/asm.h: ... here.
2004-04-14 Paolo Bonzini <bonzini@gnu.org>
* lightning/core-common.h: Add jit_finishr.
* lightning/ppc/core.h: Add jit_callr and jit_finishr.
* lightning/i386/core.h: Add jit_callr.
* lightning/sparc/core.h: Add jit_callr. Fix typo.
2004-04-14 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/core.h: Fix pasto in jit_b*_ui.
2004-03-30 Laurent Michel
* lightning/ppc: Implement PowerPC floating point
(ChangeLog entry missing).
2004-03-12 Paolo Bonzini <bonzini@gnu.org>
* lightning/fp-common.h: Load/store macros are not the
same for floats and doubles anywhere, but jit_retval may be.
* lightning/i386/asm.h: Fix = mistaken for == in ESCrri.
* lightning/i386/core.h: Fix typo in jit_prepare_[fd].
* lightning/i386/fp.h: Rewritten.
* tests/testfp.c: Add tests for unordered comparisons.
* tests/testfp.ok: Add results.
2004-03-15 Paolo Bonzini <bonzini@gnu.org>
Merge changes from Laurent Michel.
* lightning/asm-common.h: Add _jit_I_noinc.
* lightning/core-common.h: Support jit_init,
jit_setup_code, jit_patch_at. Return patchable IP from
jit_movi_p.
* lightning/funcs-common.h: Provide defaults
for jit_setup_code, jit_start_pfx, jit_end_pfx
* lightning/i386/core.h: Add jit_patch_at, jit_patch_movi.
* lightning/ppc/core.h: Likewise.
* lightning/sparc/core.h: Likewise.
* lightning/ppc/asm.h: Fix generation of branch destination
displacements in _FB and _BB
* lightning/ppc/core.h: Generate trampolines in the user
area.
* lightning/ppc/funcs.h: Add a few casts.
* tests/bc.c: New testcase.
* lightning/i386/asm.h: Wrap into #ifndef LIGHTNING_DEBUG.
* lightning/ppc/asm.h: Wrap into #ifndef LIGHTNING_DEBUG.
* lightning/sparc/asm.h: Wrap into #ifndef LIGHTNING_DEBUG.
2004-03-09 Paolo Bonzini <bonzini@gnu.org>
* lightning/sparc/fp.h: Rewrite. Move macros for
FP code generation...
* lightning/sparc/asm.h: ... here.
* lightning/sparc/core.h: Rename jit_prepare to
jit_prepare_i, jit_retval to jit_retval_i.
* lightning/ppc/core.h: Rename jit_prepare to
jit_prepare_i, jit_retval to jit_retval_i.
* lightning/i386/core.h: Rename jit_prepare to
jit_prepare_i, jit_retval to jit_retval_i.
* lightning/core-common.h: Provide backwards
compatible synonyms for the above.
* lightning/fp-common.h: Rewrite.
* lightning-inst.h: Include fp unconditionally.
* lightning.h.in: Include fp unconditionally.
* tests/Makefile.am: Enable fp tests.
* tests/fib.c: Use jit_retval_i.
* tests/fibit.c: Cast codeBuffer to char *.
* tests/funcfp.c: Use new fp macros.
* tests/printf.c: Use jit_retval_i.
* tests/rpnfp.c: Use new fp macros.
* tests/testfp.c: Use new fp macros.
2004-03-02 Paolo Bonzini <bonzini@gnu.org> 2004-03-02 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/core.h: generate correct code when * lightning/i386/core.h: generate correct code when

11
NEWS
View file

@ -1,10 +1,17 @@
NEWS FROM VERSION 1.1.2 TO 1.2 NEWS FROM VERSION 1.1.2 TO 1.2
o Floating-point interface rewritten, uses a common register o Floating-point interface rewritten, uses a register file
file architecture rather than a stack. architecture rather than a stack.
o Many bug fixes. o Many bug fixes.
o jit_prepare and jit_retval are now jit_prepare_i and
jit_retval_i.
o Support for Fedora Core 1's exec-shield feature.
o PPC supports both SysV and Darwin ABIs.
o More (and more complete) examples provided. o More (and more complete) examples provided.
--- ---

8
THANKS Normal file
View file

@ -0,0 +1,8 @@
Thanks to all the following people for their help in
improving GNU lightning:
Tom Tromey <tromey@redhat.com>
Laurent Michel <ldm@thorgal.homelinux.org>
Eli Barzilay <eli@barzilay.org>
Jens Troeger <savage@light-speed.de>
Basile Starynkevitch <basile@starynkevitch.net>

1
config/config.guess vendored Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/config.guess

1
config/config.sub vendored Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/config.sub

1
config/depcomp Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/depcomp

1
config/mdate-sh Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/mdate-sh

1
config/missing Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/missing

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources. # texi2dvi --- produce DVI (or PDF) files from Texinfo (or LaTeX) sources.
# $Id: texi2dvi,v 1.14 2003/02/05 00:42:33 karl Exp $ # $Id: texi2dvi,v 1.1.1.1 2004/03/03 12:51:44 bonzini Exp $
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001,
# 2002, 2003 Free Software Foundation, Inc. # 2002, 2003 Free Software Foundation, Inc.
@ -27,7 +27,7 @@
# the `--debug' option when making a bug report. # the `--debug' option when making a bug report.
# This string is expanded by rcs automatically when this file is checked out. # This string is expanded by rcs automatically when this file is checked out.
rcs_revision='$Revision: 1.14 $' rcs_revision='$Revision: 1.1.1.1 $'
rcs_version=`set - $rcs_revision; echo $2` rcs_version=`set - $rcs_revision; echo $2`
program=`echo $0 | sed -e 's!.*/!!'` program=`echo $0 | sed -e 's!.*/!!'`
version="texi2dvi (GNU Texinfo 4.5) $rcs_version version="texi2dvi (GNU Texinfo 4.5) $rcs_version

1
config/texinfo.tex Symbolic link
View file

@ -0,0 +1 @@
/sw/share/automake-1.9/texinfo.tex

3
doc/.cvsignore Normal file
View file

@ -0,0 +1,3 @@
*.info*
stamp-*
version.texi

View file

@ -1,5 +1,3 @@
EXTRA_DIST=lightning.info lightning.info-1 lightning.info-2 lightning.info-3
TEXI2DVI=$(top_srcdir)/config/texi2dvi TEXI2DVI=$(top_srcdir)/config/texi2dvi
HELP2MAN = $(top_srcdir)/config/help2man HELP2MAN = $(top_srcdir)/config/help2man

View file

@ -51,7 +51,7 @@ There are no Secondary Sections, no Cover Texts and no Invariant Sections
Info documentation, constitutes the Title Page. Info documentation, constitutes the Title Page.
@end titlepage @end titlepage
@ifclear ISTEX @ifnottex
@node Top @node Top
@top @lightning{} @top @lightning{}
@ -61,17 +61,17 @@ which are usually either inefficient or non-portable, @lightning{} is
both retargetable and very fast. both retargetable and very fast.
@include toc.texi @include toc.texi
@end ifclear @end ifnottex
@node Overview @node Overview
@chapter Introduction to @lightning{} @chapter Introduction to @lightning{}
@ifset ISTEX @iftex
This document describes @value{TOPIC} the @lightning{} library for This document describes @value{TOPIC} the @lightning{} library for
dynamic code generation. Unlike other dynamic code generation systems, dynamic code generation. Unlike other dynamic code generation systems,
which are usually either inefficient or non-portable, @lightning{} is which are usually either inefficient or non-portable, @lightning{} is
both retargetable and very fast. both retargetable and very fast.
@end ifset @end iftex
@ifclear USING @ifclear USING
This manual assumes that you are pretty comfortable with the usage of This manual assumes that you are pretty comfortable with the usage of

View file

@ -36,11 +36,6 @@
@c Macros for Texinfo 3.1/4.0 compatibility @c Macros for Texinfo 3.1/4.0 compatibility
@c --------------------------------------------------------------------- @c ---------------------------------------------------------------------
@c Emulate the `@ifnottex' command which is found in Texinfo 4.0
@iftex
@set ISTEX
@end iftex
@c @hlink (macro), @url and @email are used instead of @uref for Texinfo 3.1 @c @hlink (macro), @url and @email are used instead of @uref for Texinfo 3.1
@c compatibility @c compatibility
@macro hlink{url, link} @macro hlink{url, link}

View file

@ -353,16 +353,20 @@ that make up the platform-independent interface provided by
Implementation of forward references takes place in: Implementation of forward references takes place in:
@itemize @bullet @itemize @bullet
@bulletize The branch macros @item
@bulletize The @code{jit_patch} macros The branch macros
@item
The @code{jit_patch_at} macros
@end itemize @end itemize
Roughly speaking, the branch macros, as seen in @usingref{GNU lightning Roughly speaking, the branch macros, as seen in @usingref{GNU lightning
macros, Generating code at run-time}, return a value that later calls macros, Generating code at run-time}, return a value that later calls
to @code{jit_patch} use to complete the assembly of the forward to @code{jit_patch} or @code{jit_patch_at} use to complete the assembly
reference. This value is usually the contents of the program counter of the forward reference. This value is usually the contents of the
after the branch instruction is compiled (which is accessible in the program counter after the branch instruction is compiled (which is
@code{_jit.pc} variable). Let's see an example from the x86 back-end: accessible in the @code{_jit.pc} variable). Let's see an example from
the x86 back-end:
@example @example
#define jit_bmsr_i(label, s1, s2) \ #define jit_bmsr_i(label, s1, s2) \
@ -374,7 +378,7 @@ 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 the two operands) and a @code{JNZ} instruction (jump if non-zero). The
macro then returns the final value of the program counter. macro then returns the final value of the program counter.
@code{jit_patch} is one of the few macros that need to possess a @code{jit_patch_at} is one of the few macros that need to possess a
knowledge of the machine's instruction formats. Its purpose is to knowledge of the machine's instruction formats. Its purpose is to
patch a branch instruction (identified by the value returned at the patch a branch instruction (identified by the value returned at the
moment the branch was compiled) to jump to the current position (that moment the branch was compiled) to jump to the current position (that
@ -382,11 +386,11 @@ is, to the address identified by @code{_jit.pc}).
On the x86, the displacement between the jump and the landing point is 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 expressed as a 32-bit signed integer lying in the last four bytes of the
jump instruction. The definition of @code{_jit_patch} is: jump instruction. The definition of @code{_jit_patch_at} is:
@example @example
#define jit_patch(jump_pc) (*_PSL((jump_pc) - 4) = \ #define jit_patch(jump_pc, pv) (*_PSL((jump_pc) - 4) = \
_jit.pc - (jump_pc)) (pv) - (jump_pc))
@end example @end example
The @code{_PSL} macro is nothing more than a cast to @code{long *}, The @code{_PSL} macro is nothing more than a cast to @code{long *},
@ -394,42 +398,69 @@ and is used here to shorten the definition and avoid cluttering it with
excessive parentheses. These type-cast macros are: excessive parentheses. These type-cast macros are:
@itemize @bullet @itemize @bullet
@bulletize @code{_PUC(X)} to cast to a @code{unsigned char *}. @item
@bulletize @code{_PUS(X)} to cast to a @code{unsigned short *}. @code{_PUC(X)} to cast to a @code{unsigned char *}.
@bulletize @code{_PUI(X)} to cast to a @code{unsigned int *}.
@bulletize @code{_PSL(X)} to cast to a @code{long *}. @item
@bulletize @code{_PUL(X)} to cast to a @code{unsigned long *}. @code{_PUS(X)} to cast to a @code{unsigned short *}.
@item
@code{_PUI(X)} to cast to a @code{unsigned int *}.
@item
@code{_PSL(X)} to cast to a @code{long *}.
@item
@code{_PUL(X)} to cast to a @code{unsigned long *}.
@end itemize @end itemize
On other platforms, notably RISC ones, the displacement is embedded into On other platforms, notably RISC ones, the displacement is embedded into
the instruction itself. In this case, @code{jit_patch} must first zero 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, 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 for example, encodes the displacement in the bottom 22 bits; in addition
the right-most two bits are suppressed, which are always zero because the right-most two bits are suppressed, which are always zero because
instruction have to be word-aligned. instruction have to be word-aligned.
@example @example
#define jit_patch(delay_pc) jit_patch_ ( ((delay_pc) - 1) ) #define jit_patch_at(delay_pc, pv) jit_patch_ (((delay_pc) - 1), (pv))
@rem{/* branch instructions return the address of the @emph{delay} @rem{/* branch instructions return the address of the @emph{delay}
* instruction---this is just a helper macro that makes the code more * instruction---this is just a helper macro that makes the code more
* readable. * readable.
*/} */}
#define jit_patch_(jump_pc) (*jump_pc = \ #define jit_patch_(jump_pc, pv) (*jump_pc = \
(*jump_pc & ~_MASK(22)) | \ (*jump_pc & ~_MASK(22)) | \
((_UL(_jit.pc) - _UL(jump_pc)) >> 2) & _MASK(22)) ((_UL(pv) - _UL(jump_pc)) >> 2) & _MASK(22))
@end example @end example
This introduces more predefined shortcut macros: This introduces more predefined shortcut macros:
@itemize @bullet @itemize @bullet
@bulletize @code{_UC(X)} to cast to a @code{unsigned char}. @item
@bulletize @code{_US(X)} to cast to a @code{unsigned short}. @code{_UC(X)} to cast to a @code{unsigned char}.
@bulletize @code{_UI(X)} to cast to a @code{unsigned int}.
@bulletize @code{_SL(X)} to cast to a @code{long}. @item
@bulletize @code{_UL(X)} to cast to a @code{unsigned long}. @code{_US(X)} to cast to a @code{unsigned short}.
@bulletize @code{_MASK(N)} gives a binary number made of N ones.
@item
@code{_UI(X)} to cast to a @code{unsigned int}.
@item
@code{_SL(X)} to cast to a @code{long}.
@item
@code{_UL(X)} to cast to a @code{unsigned long}.
@item
@code{_MASK(N)} gives a binary number made of N ones.
@end itemize @end 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
@code{jit_patch_at}.
@node Common features @node Common features
@section Common features supported by @file{core-common.h} @section Common features supported by @file{core-common.h}
@ -448,14 +479,16 @@ avoids compiler warnings about redefined macros, but there should be
no need to define them. They are: no need to define them. They are:
@example @example
#define jit_extr_c_ui(d, rs) #define jit_extr_c_ui(d, rs)
#define jit_extr_i_ul(d, rs)
#define jit_extr_s_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_i(d, rs)
#define jit_negr_l(d, rs) #define jit_negr_l(d, rs)
@end example @end example
@item Support for the @sc{abi} @item Support for the @sc{abi}
Both @code{jit_prolog}, @code{jit_leaf} and @code{jit_finish} are not 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 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 empty macro, as a synonym for @code{jit_prolog}, and as a synonym for
@code{jit_calli}. Whether to define them or not in the port-specific @code{jit_calli}. Whether to define them or not in the port-specific
@ -471,8 +504,12 @@ and ``reverse subtraction'' (that is, REG2@math{=}IMM@math{-}REG1):
@example @example
#define jit_extr_c_i(d, rs) #define jit_extr_c_i(d, rs)
#define jit_extr_s_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_i(d, rs, is)
#define jit_rsbi_l(d, rs, is) #define jit_rsbi_l(d, rs, is)
#define jit_rsbi_p(d, rs, is)
@end example @end example
@item Conversion between network and host byte ordering @item Conversion between network and host byte ordering
@ -510,7 +547,7 @@ unsigned integers is exactly the same as adding two signed integers
@lightning{} provides both @code{jit_addr_i} and @code{jit_addr_ui} @lightning{} provides both @code{jit_addr_i} and @code{jit_addr_ui}
macros. Similarly, pointers and unsigned long integers behave in the macros. Similarly, pointers and unsigned long integers behave in the
same way, but @lightning{} has separate instruction for the two data same way, but @lightning{} has separate instruction for the two data
types---those that operate on pointers usually comprise a typecast types---those that operate on pointers usually include a typecast
that makes programs clearer. that makes programs clearer.
@item Shortcuts @item Shortcuts
@ -553,7 +590,7 @@ instruction to be scheduled in the delay slot with the branch
instruction. The only parameter accepted by the macro is a call instruction. The only parameter accepted by the macro is a call
to a branch macro, which must be expanded @strong{exactly once} by to a branch macro, which must be expanded @strong{exactly once} by
@code{jit_fill_delay_after}. The client must be able to pass the @code{jit_fill_delay_after}. The client must be able to pass the
return value of @code{jit_fill_delay_after} to @code{jit_patch}. return value of @code{jit_fill_delay_after} to @code{jit_patch_at}.
There are two possible approaches that can be used in There are two possible approaches that can be used in
@code{jit_fill_delay_after}. They are summarized in the following @code{jit_fill_delay_after}. They are summarized in the following
@ -701,7 +738,7 @@ in @file{core-common.h} (@pxref{Common features, , Common features
supported by @file{core-common.h}}). supported by @file{core-common.h}}).
@example @example
#define jit_prepare(numargs) (_jitl.pusharg = _Ro(numargs)) #define jit_prepare_i(numargs) (_jitl.pusharg = _Ro(numargs))
#define jit_pusharg_i(rs) (--_jitl.pusharg, \ #define jit_pusharg_i(rs) (--_jitl.pusharg, \
MOVrr((rs), _jitl.pusharg)) MOVrr((rs), _jitl.pusharg))
@end example @end example
@ -759,18 +796,18 @@ epilog code.
@code{jit_pusharg} uses a hardware push operation, which is commonly @code{jit_pusharg} uses a hardware push operation, which is commonly
available on CISC machines (where this approach is most likely available on CISC machines (where this approach is most likely
followed). Since the stack has to be cleaned up after the call, followed). Since the stack has to be cleaned up after the call,
@code{jit_prepare} remembers how many parameters have been put there, @code{jit_prepare_i} remembers how many parameters have been put there,
and @code{jit_finish} adjusts the stack pointer after the call. and @code{jit_finish} adjusts the stack pointer after the call.
@example @example
#define jit_prepare(numargs) (_jitl.args += (numargs)) #define jit_prepare_i(numargs) (_jitl.args += (numargs))
#define jit_pusharg_i(rs) PUSHLr(rs) #define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (jit_calli((sub)), \ #define jit_finish(sub) (jit_calli((sub)), \
ADDLir(4 * _jitl.args, JIT_SP), \ ADDLir(4 * _jitl.args, JIT_SP), \
_jitl.numargs = 0) _jitl.numargs = 0)
@end example @end example
Note the usage of @code{+=} in @code{jit_prepare}. This is done 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 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 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 use @code{jit_calli} instead of @code{jit_finish} in all but the
@ -823,12 +860,12 @@ operations:
@table @b @table @b
@item Register names (all mandatory but the last two) @item Register names (all mandatory but the last two)
@example @example
#define JIT_R0 #define JIT_R
#define JIT_R1 #define JIT_R_NUM
#define JIT_R2 #define JIT_V
#define JIT_V0 #define JIT_V_NUM
#define JIT_V1 #define JIT_FPR
#define JIT_V2 #define JIT_FPR_NUM
#define JIT_SP #define JIT_SP
#define JIT_FP #define JIT_FP
#define JIT_RZERO #define JIT_RZERO
@ -850,57 +887,81 @@ operations:
#define jit_arg_ui() #define jit_arg_ui()
#define jit_arg_ul() #define jit_arg_ul()
#define jit_arg_us() #define jit_arg_us()
#define jit_abs_d(rd,rs)
#define jit_addi_i(d, rs, is) #define jit_addi_i(d, rs, is)
#define jit_addr_d(rd,s1,s2)
#define jit_addr_i(d, s1, s2) #define jit_addr_i(d, s1, s2)
#define jit_addxi_i(d, rs, is) #define jit_addxi_i(d, rs, is)
#define jit_addxr_i(d, s1, s2) #define jit_addxr_i(d, s1, s2)
#define jit_andi_i(d, rs, is) #define jit_andi_i(d, rs, is)
#define jit_andr_i(d, s1, s2) #define jit_andr_i(d, s1, s2)
#define jit_beqi_i(label, rs, is) #define jit_beqi_i(label, rs, is)
#define jit_beqr_d(label, s1, s2)
#define jit_beqr_i(label, s1, s2) #define jit_beqr_i(label, s1, s2)
#define jit_bgei_i(label, rs, is) #define jit_bgei_i(label, rs, is)
#define jit_bgei_ui(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_i(label, s1, s2)
#define jit_bger_ui(label, s1, s2) #define jit_bger_ui(label, s1, s2)
#define jit_bgti_i(label, rs, is) #define jit_bgti_i(label, rs, is)
#define jit_bgti_ui(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_i(label, s1, s2)
#define jit_bgtr_ui(label, s1, s2) #define jit_bgtr_ui(label, s1, s2)
#define jit_blei_i(label, rs, is) #define jit_blei_i(label, rs, is)
#define jit_blei_ui(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_i(label, s1, s2)
#define jit_bler_ui(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_i(label, rs, is)
#define jit_blti_ui(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_i(label, s1, s2)
#define jit_bltr_ui(label, s1, s2) #define jit_bltr_ui(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_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_bmci_i(label, rs, is) #define jit_bmci_i(label, rs, is)
#define jit_bmcr_i(label, s1, s2) #define jit_bmcr_i(label, s1, s2)
#define jit_bmsi_i(label, rs, is) #define jit_bmsi_i(label, rs, is)
#define jit_bmsr_i(label, s1, s2) #define jit_bmsr_i(label, s1, s2)
#define jit_bnei_i(label, rs, is) #define jit_bnei_i(label, rs, is)
#define jit_bner_d(label, s1, s2)
#define jit_bner_i(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_calli(label)
#define jit_callr(label)
#define jit_ceilr_d_i(rd, rs)
#define jit_divi_i(d, rs, is) #define jit_divi_i(d, rs, is)
#define jit_divi_ui(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_i(d, s1, s2)
#define jit_divr_ui(d, s1, s2) #define jit_divr_ui(d, s1, s2)
#define jit_eqi_i(d, rs, is) #define jit_eqi_i(d, rs, is)
#define jit_eqr_d(d, s1, s2)
#define jit_eqr_i(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_i(d, rs, is)
#define jit_gei_ui(d, s1, s2) #define jit_gei_ui(d, s1, s2)
#define jit_ger_d(d, s1, s2)
#define jit_ger_i(d, s1, s2) #define jit_ger_i(d, s1, s2)
#define jit_ger_ui(d, s1, s2) #define jit_ger_ui(d, s1, s2)
#define jit_gti_i(d, rs, is) #define jit_gti_i(d, rs, is)
#define jit_gti_ui(d, s1, s2) #define jit_gti_ui(d, s1, s2)
#define jit_gtr_d(d, s1, s2)
#define jit_gtr_i(d, s1, s2) #define jit_gtr_i(d, s1, s2)
#define jit_gtr_ui(d, s1, s2) #define jit_gtr_ui(d, s1, s2)
#define jit_hmuli_i(d, rs, is) #define jit_hmuli_i(d, rs, is)
@ -909,61 +970,93 @@ operations:
#define jit_hmulr_ui(d, s1, s2) #define jit_hmulr_ui(d, s1, s2)
#define jit_jmpi(label) #define jit_jmpi(label)
#define jit_jmpr(reg) #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_c(d, rs, is)
#define jit_ldxi_d(rd, rs, is)
#define jit_ldxi_i(d, rs, is) #define jit_ldxi_i(d, rs, is)
#define jit_ldxi_s(d, rs, is) #define jit_ldxi_s(d, rs, is)
#define jit_ldxi_uc(d, rs, is) #define jit_ldxi_uc(d, rs, is)
#define jit_ldxi_us(d, rs, is) #define jit_ldxi_us(d, rs, is)
#define jit_ldxr_c(d, s1, s2) #define jit_ldxr_c(d, s1, s2)
#define jit_ldxr_d(rd, s1, s2)
#define jit_ldxr_i(d, s1, s2) #define jit_ldxr_i(d, s1, s2)
#define jit_ldxr_s(d, s1, s2) #define jit_ldxr_s(d, s1, s2)
#define jit_ldxr_uc(d, s1, s2) #define jit_ldxr_uc(d, s1, s2)
#define jit_ldxr_us(d, s1, s2) #define jit_ldxr_us(d, s1, s2)
#define jit_lei_i(d, rs, is) #define jit_lei_i(d, rs, is)
#define jit_lei_ui(d, s1, s2) #define jit_lei_ui(d, s1, s2)
#define jit_ler_d(d, s1, s2)
#define jit_ler_i(d, s1, s2) #define jit_ler_i(d, s1, s2)
#define jit_ler_ui(d, s1, s2) #define jit_ler_ui(d, s1, s2)
#define jit_lshi_i(d, rs, is) #define jit_lshi_i(d, rs, is)
#define jit_lshr_i(d, r1, r2) #define jit_lshr_i(d, r1, r2)
#define jit_ltgtr_d(d, s1, s2)
#define jit_lti_i(d, rs, is) #define jit_lti_i(d, rs, is)
#define jit_lti_ui(d, s1, s2) #define jit_lti_ui(d, s1, s2)
#define jit_ltr_d(d, s1, s2)
#define jit_ltr_i(d, s1, s2) #define jit_ltr_i(d, s1, s2)
#define jit_ltr_ui(d, s1, s2) #define jit_ltr_ui(d, s1, s2)
#define jit_modi_i(d, rs, is) #define jit_modi_i(d, rs, is)
#define jit_modi_ui(d, rs, is) #define jit_modi_ui(d, rs, is)
#define jit_modr_i(d, s1, s2) #define jit_modr_i(d, s1, s2)
#define jit_modr_ui(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_i(d, is)
#define jit_movi_p(d, is)
#define jit_movr_d(rd,rs)
#define jit_movr_i(d, rs) #define jit_movr_i(d, rs)
#define jit_muli_i(d, rs, is) #define jit_muli_i(d, rs, is)
#define jit_muli_ui(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_i(d, s1, s2)
#define jit_mulr_ui(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_nei_i(d, rs, is)
#define jit_ner_d(d, s1, s2)
#define jit_ner_i(d, s1, s2) #define jit_ner_i(d, s1, s2)
#define jit_nop() #define jit_nop()
#define jit_ordr_d(d, s1, s2)
#define jit_ori_i(d, rs, is) #define jit_ori_i(d, rs, is)
#define jit_orr_i(d, s1, s2) #define jit_orr_i(d, s1, s2)
#define jit_patch(jump_pc) #define jit_patch_at(jump_pc, value)
#define jit_patch_movi(jump_pc, value)
#define jit_pop_i(rs) #define jit_pop_i(rs)
#define jit_prepare(numargs) #define jit_prepare_d(numargs)
#define jit_prepare_f(numargs)
#define jit_prepare_i(numargs)
#define jit_push_i(rs) #define jit_push_i(rs)
#define jit_pusharg_i(rs) #define jit_pusharg_i(rs)
#define jit_ret() #define jit_ret()
#define jit_retval_i(rd) #define jit_retval_i(rd)
#define jit_roundr_d_i(rd, rs)
#define jit_rshi_i(d, rs, is) #define jit_rshi_i(d, rs, is)
#define jit_rshi_ui(d, rs, is) #define jit_rshi_ui(d, rs, is)
#define jit_rshr_i(d, r1, r2) #define jit_rshr_i(d, r1, r2)
#define jit_rshr_ui(d, r1, r2) #define jit_rshr_ui(d, r1, r2)
#define jit_sqrt_d(rd,rs)
#define jit_stxi_c(rd, id, rs) #define jit_stxi_c(rd, id, rs)
#define jit_stxi_d(id, rd, rs)
#define jit_stxi_f(id, rd, rs)
#define jit_stxi_i(rd, id, rs) #define jit_stxi_i(rd, id, rs)
#define jit_stxi_s(rd, id, rs) #define jit_stxi_s(rd, id, rs)
#define jit_stxr_c(d1, d2, 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_i(d1, d2, rs)
#define jit_stxr_s(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_subr_i(d, s1, s2)
#define jit_subxi_i(d, rs, is) #define jit_subxi_i(d, rs, is)
#define jit_subxr_i(d, s1, s2) #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_xori_i(d, rs, is)
#define jit_xorr_i(d, s1, s2) #define jit_xorr_i(d, s1, s2)
@end example @end example
@ -971,17 +1064,20 @@ operations:
@item Non mandatory---there should be no need to define them: @item Non mandatory---there should be no need to define them:
@example @example
#define jit_extr_c_ui(d, rs) #define jit_extr_c_ui(d, rs)
#define jit_extr_i_ul(d, rs)
#define jit_extr_s_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_i(d, rs)
#define jit_negr_l(d, rs) #define jit_negr_l(d, rs)
@end example @end example
@item Non mandatory---whether to define them depends on the @sc{abi}: @item Non mandatory---whether to define them depends on the @sc{abi}:
@example @example
#define jit_prolog() #define jit_prolog(n)
#define jit_finish() #define jit_finish(sub)
#define jit_leaf() #define jit_finishr(reg)
#define jit_leaf(n)
#define jit_getarg_c(reg, ofs) #define jit_getarg_c(reg, ofs)
#define jit_getarg_i(reg, ofs) #define jit_getarg_i(reg, ofs)
#define jit_getarg_l(reg, ofs) #define jit_getarg_l(reg, ofs)
@ -991,12 +1087,17 @@ operations:
#define jit_getarg_ui(reg, ofs) #define jit_getarg_ui(reg, ofs)
#define jit_getarg_ul(reg, ofs) #define jit_getarg_ul(reg, ofs)
#define jit_getarg_us(reg, ofs) #define jit_getarg_us(reg, ofs)
#define jit_getarg_f(reg, ofs)
#define jit_getarg_d(reg, ofs)
@end example @end example
@item Non mandatory---define them if instructions that do this exist: @item Non mandatory---define them if instructions that do this exist:
@example @example
#define jit_extr_c_i(d, rs) #define jit_extr_c_i(d, rs)
#define jit_extr_s_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_i(d, rs, is)
#define jit_rsbi_l(d, rs, is) #define jit_rsbi_l(d, rs, is)
@end example @end example
@ -1037,6 +1138,14 @@ operations:
#define jit_str_c(rd, rs) #define jit_str_c(rd, rs)
#define jit_str_i(rd, rs) #define jit_str_i(rd, rs)
#define jit_str_s(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)
@end example @end example
@item Synonyms---don't define them: @item Synonyms---don't define them:
@ -1085,14 +1194,20 @@ operations:
#define jit_eqr_p(d, s1, s2) #define jit_eqr_p(d, s1, s2)
#define jit_eqr_ui(d, s1, s2) #define jit_eqr_ui(d, s1, s2)
#define jit_eqr_ul(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_i(d, rs)
#define jit_extr_uc_ui(d, rs) #define jit_extr_uc_ui(d, rs)
#define jit_extr_ui_l(d, rs)
#define jit_extr_ui_l(d, rs)
#define jit_extr_ui_ul(d, rs)
#define jit_extr_ui_ul(d, rs)
#define jit_extr_us_i(d, rs) #define jit_extr_us_i(d, rs)
#define jit_extr_us_ui(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_gei_p(d, rs, is)
#define jit_ger_p(d, s1, s2) #define jit_ger_p(d, s1, s2)
#define jit_gti_p(d, rs, is) #define jit_gti_p(d, rs, is)
@ -1145,8 +1260,10 @@ operations:
#define jit_retval_ui(rd) #define jit_retval_ui(rd)
#define jit_retval_ul(rd) #define jit_retval_ul(rd)
#define jit_retval_us(rd) #define jit_retval_us(rd)
#define jit_rsbi_p(d, rs, is)
#define jit_rsbi_ui(d, rs, is) #define jit_rsbi_ui(d, rs, is)
#define jit_rsbi_ul(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_ui(d, s1, s2)
#define jit_rsbr_ul(d, s1, s2) #define jit_rsbr_ul(d, s1, s2)
#define jit_sti_p(d, is) #define jit_sti_p(d, is)
@ -1175,6 +1292,12 @@ operations:
#define jit_subr_p(d, s1, s2) #define jit_subr_p(d, s1, s2)
#define jit_subr_ui(d, s1, s2) #define jit_subr_ui(d, s1, s2)
#define jit_subr_ul(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_ui(d, rs, is)
#define jit_xori_ul(d, rs, is) #define jit_xori_ul(d, rs, is)
#define jit_xorr_ui(d, s1, s2) #define jit_xorr_ui(d, s1, s2)
@ -1183,6 +1306,19 @@ operations:
@item Shortcuts---don't define them: @item Shortcuts---don't define them:
@example @example
#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_c(d, rs)
#define jit_notr_i(d, rs) #define jit_notr_i(d, rs)
#define jit_notr_l(d, rs) #define jit_notr_l(d, rs)
@ -1191,12 +1327,61 @@ operations:
#define jit_notr_ui(d, rs) #define jit_notr_ui(d, rs)
#define jit_notr_ul(d, rs) #define jit_notr_ul(d, rs)
#define jit_notr_us(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_i(d, s1, s2)
#define jit_rsbr_l(d, s1, s2) #define jit_rsbr_l(d, s1, s2)
#define jit_subi_i(d, rs, is) #define jit_subi_i(d, rs, is)
#define jit_subi_l(d, rs, is) #define jit_subi_l(d, rs, is)
@end example @end example
@item Mandatory unless target arithmetic is always done in the same precision:
@example
#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)
@end example
@item Mandatory if sizeof(long) != sizeof(int)---don't define them on other systems: @item Mandatory if sizeof(long) != sizeof(int)---don't define them on other systems:
@example @example
#define jit_addi_l(d, rs, is) #define jit_addi_l(d, rs, is)
@ -1241,6 +1426,12 @@ operations:
#define jit_divr_ul(d, s1, s2) #define jit_divr_ul(d, s1, s2)
#define jit_eqi_l(d, rs, is) #define jit_eqi_l(d, rs, is)
#define jit_eqr_l(d, s1, s2) #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_l(d, rs, is)
#define jit_gei_ul(d, rs, is) #define jit_gei_ul(d, rs, is)
#define jit_ger_l(d, s1, s2) #define jit_ger_l(d, s1, s2)

View file

@ -7,7 +7,6 @@
* Installation:: Configuring and installing GNU lightning * Installation:: Configuring and installing GNU lightning
* The instruction set:: The RISC instruction set used i GNU lightning * The instruction set:: The RISC instruction set used i GNU lightning
* GNU lightning macros:: GNU lightning's macros * GNU lightning macros:: GNU lightning's macros
* Floating-point:: Doing floating point computations.
* Reentrancy:: Re-entrant usage of GNU lightning * Reentrancy:: Re-entrant usage of GNU lightning
* Autoconf support:: Using @code{autoconf} with GNU lightning * Autoconf support:: Using @code{autoconf} with GNU lightning
@end ifset @end ifset

View file

@ -49,9 +49,14 @@ that closely match those of most existing RISC architectures, or
that can be easily syntesized if absent. Each instruction is composed that can be easily syntesized if absent. Each instruction is composed
of: of:
@itemize @bullet @itemize @bullet
@bulletize an operation (like @code{sub} or @code{mul}) @item
@bulletize sometimes, an register/immediate flag (@code{r} or @code{i}) an operation, like @code{sub} or @code{mul}
@bulletize a type identifier (occasionally, two)
@item
sometimes, an register/immediate flag (@code{r} or @code{i})
@item
a type identifier or, occasionally, two
@end itemize @end itemize
The second and third field are separated by an underscore; thus, The second and third field are separated by an underscore; thus,
@ -75,6 +80,8 @@ following table together with the C types they represent:
ui @r{unsigned int} ui @r{unsigned int}
l @r{long} l @r{long}
ul @r{unsigned long} ul @r{unsigned long}
f @r{float}
d @r{double}
p @r{void *} p @r{void *}
@end example @end example
@ -82,27 +89,31 @@ 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 is equivalent to @code{i} on 32-bit machines, and @code{p} is
substantially equivalent to @code{ul}). substantially equivalent to @code{ul}).
There are seven registers, of which six are general-purpose, while There are at least seven integer registers, of which six are
the last is used to contain the stack pointer (@code{SP}). The general-purpose, while the last is used to contain the stack pointer
stack pointer can be used to allocate and access local variables (@code{SP}). The stack pointer can be used to allocate and access local
on the stack (which is supposed to grow downwards in memory on all variables on the stack (which is supposed to grow downwards in memory
architectures). on all architectures).
Of the six general-purpose registers, three are guaranteed to be Of the general-purpose registers, at least three are guaranteed to be
preserved across function calls (@code{V0}, @code{V1} and preserved across function calls (@code{V0}, @code{V1} and
@code{V2}) and three are not (@code{R0}, @code{R1} and @code{V2}) and at least three are not (@code{R0}, @code{R1} and
@code{R2}).@footnote{Six registers are not very much, but this @code{R2}). Six registers are not very much, but this
restriction was forced by the need to target CISC architectures restriction was forced by the need to target CISC architectures
which, like the x86, are poor of registers. Anyway, consider which, like the x86, are poor of registers; anyway, backends can
that even on a RISC architecture you don't have many more registers specify the actual number of available caller- and callee-save
which are not devoted to function calls: on the SPARC, you have nine registers.
(@code{%g1} and the eight registers @code{%l0} through @code{%l7}).}
In addition, there is a special @code{RET} register which contains In addition, there is a special @code{RET} register which contains
the return value. You should always remember, however, that writing the return value. You should always remember, however, that writing
this register could overwrite either a general-purpose register or this register could overwrite either a general-purpose register or
an incoming parameter, depending on the architecture. an incoming parameter, depending on the architecture.
There are at least six floating-point registers, named @code{FPR0} to
@code{FPR5}. These are separate from the integer registers on
all the supported architectures; on Intel architectures, the
register stack is mapped to a flat register file.
The complete instruction set follows; as you can see, most non-memory The complete instruction set follows; as you can see, most non-memory
operations only take integers, long integers (either signed or operations only take integers, long integers (either signed or
unsigned) and pointers as operands; this was done in order to reduce unsigned) and pointers as operands; this was done in order to reduce
@ -113,61 +124,117 @@ signed and in an unsigned way.
@table @b @table @b
@item Binary ALU operations @item Binary ALU operations
These accept three operands, of which the last can be an immediate These accept three operands; the last one can be an immediate
value. @code{addx} operations must directly follow @code{addc}, and value for integer operands, or a register for all operand types.
@code{addx} operations must directly follow @code{addc}, and
@code{subx} must follow @code{subc}; otherwise, results are undefined. @code{subx} must follow @code{subc}; otherwise, results are undefined.
@example @example
addr/addi i ui l ul p O1 = O2 + O3 addr i ui l ul p f d O1 = O2 + O3
addxr/addxi i ui l ul O1 = O2 + (O3 + carry) addi i ui l ul p O1 = O2 + O3
addcr/addci i ui l ul O1 = O2 + O3, set carry addxr i ui l ul O1 = O2 + (O3 + carry)
subr/subi i ui l ul p O1 = O2 - O3 addxi i ui l ul O1 = O2 + (O3 + carry)
subxr/subxi i ui l ul O1 = O2 - (O3 + carry) addcr i ui l ul O1 = O2 + O3, set carry
subcr/subci i ui l ul O1 = O2 - O3, set carry addci i ui l ul O1 = O2 + O3, set carry
rsbr/rsbi i ui l ul p O1 = O3 - O2 subr i ui l ul p f d O1 = O2 - O3
mulr/muli i ui l ul O1 = O2 * O3 subi i ui l ul p O1 = O2 - O3
hmulr/hmuli i ui l ul O1 = @r{high bits of} O2 * O3 subxr i ui l ul O1 = O2 - (O3 + carry)
divr/divi i ui l ul O1 = O2 / O3 subxi i ui l ul O1 = O2 - (O3 + carry)
modr/modi i ui l ul O1 = O2 % O3 subcr i ui l ul O1 = O2 - O3, set carry
andr/andi i ui l ul O1 = O2 & O3 subci i ui l ul O1 = O2 - O3, set carry
orr/ori i ui l ul O1 = O2 | O3 rsbr i ui l ul p f d O1 = O3 - O2
xorr/xori i ui l ul O1 = O2 ^ O3 rsbi i ui l ul p O1 = O3 - O2
lshr/lshi i ui l ul O1 = O2 << O3 mulr i ui l ul f d O1 = O2 * O3
rshr/rshi i ui l ul O1 = O2 >> O3@footnote{The sign bit is propagated for signed types.} 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 >> O3@footnote{The sign bit is propagated for signed types.}
rshi i ui l ul O1 = O2 >> O3@footnote{The sign bit is propagated for signed types.}
@end example @end example
@item Unary ALU operations @item Unary ALU operations
These accept two operands, both of which must be registers. These accept two operands, both of which must be registers.
@example @example
negr i l O1 = -O2 negr i l f d O1 = -O2
notr i ui l ul O1 = ~O2 notr i ui l ul O1 = ~O2
@end example @end example
@item Compare instructions @item Compare instructions
These accept three operands, of which the last can be an immediate These accept three operands; again, the last can be an immediate
value. The last two operands are compared, and the first operand is value for integer data types. The last two operands are compared,
set to either 0 or 1, according to whether the given condition was and the first operand is set to either 0 or 1, according to
met or not. 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.
@example @example
ltr/lti i ui l ul p O1 = (O2 < O3) ltr i ui l ul p f d O1 = (O2 < O3)
ler/lei i ui l ul p O1 = (O2 <= O3) lti i ui l ul p O1 = (O2 < O3)
gtr/gti i ui l ul p O1 = (O2 > O3) ler i ui l ul p f d O1 = (O2 <= O3)
ger/gei i ui l ul p O1 = (O2 >= O3) lei i ui l ul p O1 = (O2 <= O3)
eqr/eqi i ui l ul p O1 = (O2 == O3) gtr i ui l ul p f d O1 = (O2 > O3)
ner/nei i ui l ul p 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)
@end example @end example
@item Transfer operations @item Transfer operations
These accept two operands; for @code{ext} both of them must be These accept two operands; for @code{ext} both of them must be
registers, while @code{mov} accepts an immediate value as the second registers, while @code{mov} accepts an immediate value as the second
operand. @code{ext} needs @strong{two} data type specifications, of operand.
which the first must be smaller in size than the second; for example
@code{extr_c_ui} is correct while @code{extr_ul_us} is not. 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
@code{extr_ul_us} 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}.
@example @example
movr/movi i ui l ul p O1 = O2 movr i ui l ul p f d O1 = O2
extr c uc s us i ui l ul O1 = O2@footnote{Unlike @code{movr} and @code{movi}, @code{extr} is applied between operands of different sizes.} 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)
@end example @end 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: @emph{shorter}---source---@emph{first,
longer}---destination---@emph{second}. This happens for historical
reasons.
@item Network extensions @item Network extensions
These accept two operands, both of which must be registers; these These accept two operands, both of which must be registers; these
two instructions actually perform the same task, yet they are two instructions actually perform the same task, yet they are
@ -185,8 +252,10 @@ in both cases, the last can be either a register or an immediate
value. Values are extended (with or without sign, according to value. Values are extended (with or without sign, according to
the data type specification) to fit a whole register. the data type specification) to fit a whole register.
@example @example
ldr/ldi c uc s us i ui l ul p O1 = *O2 ldr c uc s us i ui l ul p f d O1 = *O2
ldxr/ldxi c uc s us i ui l ul p O1 = *(O2+O3) 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)
@end example @end example
@item Store operations @item Store operations
@ -194,8 +263,10 @@ ldxr/ldxi c uc s us i ui l ul p O1 = *(O2+O3)
both cases, the first can be either a register or an immediate both cases, the first can be either a register or an immediate
value. Values are sign-extended to fit a whole register. value. Values are sign-extended to fit a whole register.
@example @example
str/sti c uc s us i ui l ul p *O1 = O2 str c uc s us i ui l ul p f d *O1 = O2
stxr/stxi c uc s us i ui l ul p *(O1+O2) = O3 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
@end example @end example
@item Stack management @item Stack management
@ -210,19 +281,20 @@ popr i ui l ul p @r{pop }O1@r{ off the stack}
@item Argument management @item Argument management
These are: These are:
@example @example
prepare (not specified) prepare i f d
pusharg c uc s us i ui l ul p pusharg c uc s us i ui l ul p f d
getarg c uc s us i ui l ul p getarg c uc s us i ui l ul p f d
arg c uc s us i ui l ul p arg c uc s us i ui l ul p f d
@end example @end example
Of these, the first two are used by the caller, while the last two 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 are used by the callee. A code snippet that wants to call another
procedure and has to pass registers must, in order: use the procedure and has to pass registers must, in order: use the
@code{prepare} instruction, giving the number of arguments to @code{prepare} instruction, giving the number of arguments to
be passed to the procedure; use @code{pusharg} to push the arguments be passed to the procedure (once for each data type); use
@strong{in reverse order}; and use @code{calli} or @code{finish} @code{pusharg} to push the arguments @strong{in reverse order};
(explained below) to perform the actual call. and use @code{calli} or @code{finish} (explained below) to
perform the actual call.
@code{arg} and @code{getarg} are used by the callee. @code{arg} and @code{getarg} are used by the callee.
@code{arg} is different from other instruction in that it does not @code{arg} is different from other instruction in that it does not
@ -269,18 +341,36 @@ is to be used to compile forward branches as explained in
destination of the branch and two operands to be compared; of these, destination of the branch and two operands to be compared; of these,
the last can be either a register or an immediate. They are: the last can be either a register or an immediate. They are:
@example @example
bltr/blti i ui l ul p @r{if }O2 < O3@r{ goto }O1 bltr i ui l ul p f d @r{if }(O2 < O3)@r{ goto }O1
bler/blei i ui l ul p @r{if }O2 <= O3@r{ goto }O1 blti i ui l ul p @r{if }(O2 < O3)@r{ goto }O1
bgtr/bgti 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
bger/bgei i ui l ul p @r{if }O2 >= O3@r{ goto }O1 blei i ui l ul p @r{if }(O2 <= O3)@r{ goto }O1
beqr/beqi 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
bner/bnei i ui l ul p @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
bmsr/bmsi i ui l ul @r{if }O2 & O3@r{ goto }O1 bunltr f d @r{if }!(O2 >= O3)@r{ goto }O1
bmcr/bmci i ui l ul @r{if }!(O2 & O3)@r{ goto }O1@footnote{These two mnemonics mean, respectively, @dfn{branch if mask set} and @dfn{branch if mask cleared}.} 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
boaddr/boaddi i ui l ul O2 += O3@r{, goto }O1@r{ on overflow} bmsr i ui l ul @r{if }O2 & O3@r{ goto }O1
bosubr/bosubi i ui l ul O2 -= O3@r{, goto }O1@r{ on overflow} bmsi i ui l ul @r{if }O2 & O3@r{ 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 }O1@footnote{These mnemonics mean, respectively, @dfn{branch if mask set} and @dfn{branch if mask cleared}.}
boaddr i ui l ul O2 += O3@r{, goto }O1@r{ on overflow}
boaddi i ui l ul O2 += O3@r{, goto }O1@r{ on overflow}
bosubr i ui l ul O2 -= O3@r{, goto }O1@r{ on overflow}
bosubi i ui l ul O2 -= O3@r{, goto }O1@r{ on overflow}
@end example @end example
@item Jump and return operations @item Jump and return operations
@ -292,12 +382,14 @@ instruction. Results are undefined when using function calls
in a leaf function. in a leaf function.
@example @example
calli (not specified) @r{function call to O1} 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} 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} jmpi/jmpr (not specified) @r{unconditional jump to O1}
prolog (not specified) @r{function prolog for O1 args} prolog (not specified) @r{function prolog for O1 args}
leaf (not specified) @r{the same for leaf functions} leaf (not specified) @r{the same for leaf functions}
ret (not specified) @r{return from subroutine} ret (not specified) @r{return from subroutine}
retval c uc s us i ui l ul p @r{move return value} retval c uc s us i ui l ul p f d @r{move return value}
@r{to register} @r{to register}
@end example @end example
@ -353,7 +445,7 @@ between parentheses, just like with every other @sc{cpp} macro.
This small tutorial presents three examples: This small tutorial presents three examples:
@ifset ISTEX @iftex
@itemize @bullet @itemize @bullet
@item @item
The @code{incr} function found in @ref{The instruction set, , The @code{incr} function found in @ref{The instruction set, ,
@ -368,15 +460,15 @@ An RPN calculator.
@item @item
Fibonacci numbers Fibonacci numbers
@end itemize @end itemize
@end ifset @end iftex
@ifclear ISTEX @ifnottex
@menu @menu
* incr:: A function which increments a number by one * incr:: A function which increments a number by one
* printf:: A simple function call to printf * printf:: A simple function call to printf
* RPN calculator:: A more complex example, an RPN calculator * RPN calculator:: A more complex example, an RPN calculator
* Fibonacci:: Calculating Fibonacci numbers * Fibonacci:: Calculating Fibonacci numbers
@end menu @end menu
@end ifclear @end ifnottex
@node incr @node incr
@section A function which increments a number by one @section A function which increments a number by one
@ -931,8 +1023,23 @@ instruction; otherwise, it emits the delay instruction before the branch
instruction. The delay instruction must not depend on being executed instruction. The delay instruction must not depend on being executed
before or after the branch. before or after the branch.
@node Floating-point Instead of @code{jit_patch}, you can use @code{jit_patch_at}, which
@chapter Doing floating point computations 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:
@example
jit_patch (jump_pc);
jit_patch_at (jump_pc, jit_get_ip ());
@end 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}.
@node Reentrancy @node Reentrancy
@chapter Re-entrant usage of @lightning{} @chapter Re-entrant usage of @lightning{}
@ -1040,6 +1147,22 @@ extern void _opt_muli_i(struct jit_state *, int, int, int);
@end example @end example
@section Registers
@chapter Accessing the whole register file
As mentioned earlier in this chapter, all @lightning{} back-ends
are guaranteed to have at least six integer registers and six
floating-point registers, but many back-ends will have more.
To access the entire register files, you can use the
@code{JIT_R}, @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
@code{JIT_R(0)} denote the same register, and likewise for
integer callee-saved, or floating-point, registers.
@node Autoconf support @node Autoconf support
@chapter Using @code{autoconf} with @lightning{} @chapter Using @code{autoconf} with @lightning{}

View file

@ -39,7 +39,6 @@ extern "C" {
#endif #endif
#include <lightning/asm-common.h> #include <lightning/asm-common.h>
#include <lightning/funcs-common.h>
#ifndef LIGHTNING_DEBUG #ifndef LIGHTNING_DEBUG
#include <lightning/asm.h> #include <lightning/asm.h>
@ -48,11 +47,9 @@ extern "C" {
#include <lightning/core.h> #include <lightning/core.h>
#include <lightning/core-common.h> #include <lightning/core-common.h>
#include <lightning/funcs.h> #include <lightning/funcs.h>
#include <lightning/funcs-common.h>
#include <lightning/fp.h> #include <lightning/fp.h>
#ifdef jit_cmp
#include <lightning/fp-common.h> #include <lightning/fp-common.h>
#endif
#ifndef JIT_R0 #ifndef JIT_R0
#error GNU lightning does not support the current target #error GNU lightning does not support the current target

View file

@ -62,7 +62,6 @@ extern "C" {
#endif #endif
#include <lightning/asm-common.h> #include <lightning/asm-common.h>
#include <lightning/funcs-common.h>
#ifndef LIGHTNING_DEBUG #ifndef LIGHTNING_DEBUG
#include <lightning/asm.h> #include <lightning/asm.h>
@ -71,11 +70,9 @@ extern "C" {
#include <lightning/core.h> #include <lightning/core.h>
#include <lightning/core-common.h> #include <lightning/core-common.h>
#include <lightning/funcs.h> #include <lightning/funcs.h>
#include <lightning/funcs-common.h>
#include <lightning/fp.h> #include <lightning/fp.h>
#ifdef jit_cmp
#include <lightning/fp-common.h> #include <lightning/fp-common.h>
#endif
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
extern void disassemble(FILE *stream, char *from, char *to); extern void disassemble(FILE *stream, char *from, char *to);

View file

@ -12,5 +12,5 @@ dist_pkgdata_DATA = Makefile.am
nobase_dist_lightning_HEADERS = $(LIGHTNING_FILES) nobase_dist_lightning_HEADERS = $(LIGHTNING_FILES)
nodist_lightning_HEADERS = asm.h core.h funcs.h fp.h nodist_lightning_HEADERS = asm.h core.h funcs.h fp.h
else else
dist_noinst_HEADERS = $(LIGHTNING_FILES) lightning.h dist_noinst_HEADERS = $(LIGHTNING_FILES)
endif endif

View file

@ -93,7 +93,6 @@ typedef unsigned long _ul;
#define _jit_UI(X) ((_ui )(X)) #define _jit_UI(X) ((_ui )(X))
#define _jit_SL(X) ((_sl )(X)) #define _jit_SL(X) ((_sl )(X))
#define _jit_UL(X) ((_ul )(X)) #define _jit_UL(X) ((_ul )(X))
# define _PUC(X) ((_uc *)(X)) # define _PUC(X) ((_uc *)(X))
# define _PUS(X) ((_us *)(X)) # define _PUS(X) ((_us *)(X))
# define _PUI(X) ((_ui *)(X)) # define _PUI(X) ((_ui *)(X))
@ -104,6 +103,7 @@ typedef unsigned long _ul;
#define _jit_W(W) _jit_UL(((*_jit.x.us_pc++)= _jit_US((W)&0xffff))) #define _jit_W(W) _jit_UL(((*_jit.x.us_pc++)= _jit_US((W)&0xffff)))
#define _jit_I(I) _jit_UL(((*_jit.x.ui_pc++)= _jit_UI((I) ))) #define _jit_I(I) _jit_UL(((*_jit.x.ui_pc++)= _jit_UI((I) )))
#define _jit_L(L) _jit_UL(((*_jit.x.ul_pc++)= _jit_UL((L) ))) #define _jit_L(L) _jit_UL(((*_jit.x.ul_pc++)= _jit_UL((L) )))
#define _jit_I_noinc(I) _jit_UL(((*_jit.x.ui_pc)= _jit_UI((I) )))
#define _MASK(N) ((unsigned)((1<<(N)))-1) #define _MASK(N) ((unsigned)((1<<(N)))-1)
#define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N))) #define _siP(N,I) (!((((unsigned)(I))^(((unsigned)(I))<<1))&~_MASK(N)))

View file

@ -45,14 +45,24 @@ typedef struct {
struct jit_local_state jitl; struct jit_local_state jitl;
} jit_state; } jit_state;
#ifdef jit_init
static jit_state _jit = jit_init ();
#else
static jit_state _jit; static jit_state _jit;
#endif
#define JIT_NOREG (-1) #define JIT_NOREG (-1)
#define JIT_R0 JIT_R(0)
#define JIT_R1 JIT_R(1)
#define JIT_R2 JIT_R(2)
#define JIT_V0 JIT_V(0)
#define JIT_V1 JIT_V(1)
#define JIT_V2 JIT_V(2)
#define _jitl _jit.jitl #define _jitl _jit.jitl
#define jit_get_ip() (*(jit_code *) &_jit.x.pc) #define jit_get_ip() (*(jit_code *) &_jit.x.pc)
#define jit_set_ip(ptr) (_jit.x.pc = (jit_insn *) ptr, jit_get_ip()) #define jit_set_ip(ptr) (_jit.x.pc = (ptr), jit_get_ip ())
#define jit_get_label() (_jit.x.pc) #define jit_get_label() (_jit.x.pc)
#define jit_forward() (_jit.x.pc) #define jit_forward() (_jit.x.pc)
@ -138,16 +148,24 @@ typedef union jit_code {
#define jit_subci_ul(d, rs, is) jit_subci_l((d), (rs), (is)) #define jit_subci_ul(d, rs, is) jit_subci_l((d), (rs), (is))
#define jit_subcr_ul(d, s1, s2) jit_subcr_l((d), (s1), (s2)) #define jit_subcr_ul(d, s1, s2) jit_subcr_l((d), (s1), (s2))
#define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is)) #define jit_subxi_ui(d, rs, is) jit_subxi_i((d), (rs), (is))
#define jit_subxi_ul(d, rs, is) jit_subxi_l((d), (rs), (is))
#define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2)) #define jit_subxr_ui(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_subxr_ul(d, s1, s2) jit_subxr_i((d), (s1), (s2))
#define jit_xori_ul(d, rs, is) jit_xori_l((d), (rs), (is)) #define jit_xori_ul(d, rs, is) jit_xori_l((d), (rs), (is))
#define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2)) #define jit_xorr_ul(d, s1, s2) jit_xorr_l((d), (s1), (s2))
#define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2)) #define jit_addr_p(d, s1, s2) jit_addr_ul((d), (s1), (s2))
#define jit_addi_p(d, rs, is) jit_addi_ul((d), (rs), (long) (is)) #define jit_addi_p(d, rs, is) jit_addi_ul((d), (rs), (long) (is))
#define jit_movr_p(d, rs) jit_movr_ul((d), (rs)) #define jit_movr_p(d, rs) jit_movr_ul((d), (rs))
#define jit_movi_p(d, is) jit_movi_ul((d), (long) (is))
#define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2)) #define jit_subr_p(d, s1, s2) jit_subr_ul((d), (s1), (s2))
#define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is)) #define jit_subi_p(d, rs, is) jit_subi_ul((d), (rs), (long) (is))
#define jit_rsbi_p(d, rs, is) jit_rsbi_ul((d), (rs), (long) (is))
#ifndef jit_movi_p
#define jit_movi_p(d, is) (jit_movi_ul((d), (long) (is)), _jit.x.pc)
#endif
#define jit_patch(pv) jit_patch_at ((pv), (_jit.x.pc))
#ifndef jit_addci_i #ifndef jit_addci_i
#define jit_addci_i(d, rs, is) jit_addi_i((d), (rs), (is)) #define jit_addci_i(d, rs, is) jit_addi_i((d), (rs), (is))
@ -190,8 +208,11 @@ typedef union jit_code {
#define jit_subi_l(d, rs, is) jit_addi_l((d), (rs), -(is)) #define jit_subi_l(d, rs, is) jit_addi_l((d), (rs), -(is))
#define jit_subci_i(d, rs, is) jit_addci_i((d), (rs), -(is)) #define jit_subci_i(d, rs, is) jit_addci_i((d), (rs), -(is))
#define jit_subci_l(d, rs, is) jit_addci_l((d), (rs), -(is)) #define jit_subci_l(d, rs, is) jit_addci_l((d), (rs), -(is))
#define jit_rsbr_f(d, s1, s2) jit_subr_f((d), (s2), (s1))
#define jit_rsbr_d(d, s1, s2) jit_subr_d((d), (s2), (s1))
#define jit_rsbr_i(d, s1, s2) jit_subr_i((d), (s2), (s1)) #define jit_rsbr_i(d, s1, s2) jit_subr_i((d), (s2), (s1))
#define jit_rsbr_l(d, s1, s2) jit_subr_l((d), (s2), (s1)) #define jit_rsbr_l(d, s1, s2) jit_subr_l((d), (s2), (s1))
#define jit_rsbr_p(d, s1, s2) jit_subr_p((d), (s2), (s1))
/* Unary */ /* Unary */
#define jit_notr_c(d, rs) jit_xori_c((d), (rs), 255) #define jit_notr_c(d, rs) jit_xori_c((d), (rs), 255)
@ -216,23 +237,43 @@ typedef union jit_code {
#define jit_extr_s_i(d, rs) (jit_lshi_i((d), (rs), 16), jit_rshi_i((d), (d), 16)) #define jit_extr_s_i(d, rs) (jit_lshi_i((d), (rs), 16), jit_rshi_i((d), (d), 16))
#endif #endif
#ifdef jit_addi_l /* sizeof(long) != sizeof(int) */
#ifndef jit_extr_c_l
#define jit_extr_c_l(d, rs) (jit_lshi_l((d), (rs), 56), jit_rshi_l((d), (d), 56))
#endif
#ifndef jit_extr_s_l
#define jit_extr_s_l(d, rs) (jit_lshi_l((d), (rs), 48), jit_rshi_l((d), (d), 48))
#endif
#ifndef jit_extr_i_l
#define jit_extr_i_l(d, rs) (jit_lshi_l((d), (rs), 32), jit_rshi_l((d), (d), 32))
#endif
#ifndef jit_extr_c_ul
#define jit_extr_c_ul(d, rs) jit_andi_l((d), (rs), 0xFF)
#endif
#ifndef jit_extr_s_ul
#define jit_extr_s_ul(d, rs) jit_andi_l((d), (rs), 0xFFFF)
#endif
#ifndef jit_extr_i_ul
#define jit_extr_i_ul(d, rs) jit_andi_l((d), (rs), 0xFFFFFFFFUL)
#endif
#endif
#define jit_extr_c_s(d, rs) jit_extr_c_i((d), (rs))
#define jit_extr_c_us(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_uc_s(d, rs) jit_extr_uc_i((d), (rs))
#define jit_extr_uc_us(d, rs) jit_extr_uc_ui((d), (rs))
#define jit_extr_uc_i(d, rs) jit_extr_c_ui((d), (rs)) #define jit_extr_uc_i(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_uc_ui(d, rs) jit_extr_c_ui((d), (rs)) #define jit_extr_uc_ui(d, rs) jit_extr_c_ui((d), (rs))
#define jit_extr_us_i(d, rs) jit_extr_s_ui((d), (rs)) #define jit_extr_us_i(d, rs) jit_extr_s_ui((d), (rs))
#define jit_extr_us_ui(d, rs) jit_extr_s_ui((d), (rs)) #define jit_extr_us_ui(d, rs) jit_extr_s_ui((d), (rs))
#define jit_extr_uc_l(d, rs) jit_extr_c_ul((d), (rs))
#ifndef jit_extr_i_ul #define jit_extr_uc_ul(d, rs) jit_extr_c_ul((d), (rs))
#ifdef jit_addi_l /* sizeof(long) != sizeof(int) */ #define jit_extr_us_l(d, rs) jit_extr_s_ul((d), (rs))
#define jit_extr_i_ul(d, rs) jit_andi_ui((d), (rs), 0xFF) #define jit_extr_us_ul(d, rs) jit_extr_s_ul((d), (rs))
#else /* sizeof(long) == sizeof(int) */
#define jit_extr_i_ul(d, rs) jit_movr_i(d, rs)
#endif /* sizeof(long) == sizeof(int) */
#endif
#define jit_extr_ui_l(d, rs) jit_extr_i_ul((d), (rs)) #define jit_extr_ui_l(d, rs) jit_extr_i_ul((d), (rs))
#define jit_extr_ui_ul(d, rs) jit_extr_i_ul((d), (rs)) #define jit_extr_ui_ul(d, rs) jit_extr_i_ul((d), (rs))
/* NTOH/HTON is not mandatory for big endian architectures */ /* NTOH/HTON is not mandatory for big endian architectures */
#ifndef jit_ntoh_ui /* big endian */ #ifndef jit_ntoh_ui /* big endian */
#define jit_ntoh_ui(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs))) #define jit_ntoh_ui(d, rs) ((d) == (rs) ? (void)0 : jit_movr_i((d), (rs)))
@ -251,7 +292,7 @@ typedef union jit_code {
#define jit_pushr_p(rs) jit_pushr_ul(rs) #define jit_pushr_p(rs) jit_pushr_ul(rs)
#define jit_popr_p(rs) jit_popr_ul(rs) #define jit_popr_p(rs) jit_popr_ul(rs)
#define jit_prepare(nint) jitfp_prepare((nint), 0, 0) #define jit_prepare(nint) jit_prepare_i((nint))
#define jit_pusharg_c(rs) jit_pusharg_i(rs) #define jit_pusharg_c(rs) jit_pusharg_i(rs)
#define jit_pusharg_s(rs) jit_pusharg_i(rs) #define jit_pusharg_s(rs) jit_pusharg_i(rs)
#define jit_pusharg_uc(rs) jit_pusharg_i(rs) #define jit_pusharg_uc(rs) jit_pusharg_i(rs)
@ -388,10 +429,17 @@ typedef union jit_code {
#define jit_retval_c(rd) jit_retval_i((rd)) #define jit_retval_c(rd) jit_retval_i((rd))
#define jit_retval_s(rd) jit_retval_i((rd)) #define jit_retval_s(rd) jit_retval_i((rd))
/* This was a bug, but we keep it. */
#define jit_retval(rd) jit_retval_i ((rd))
#ifndef jit_finish #ifndef jit_finish
#define jit_finish(sub) jit_calli(sub) #define jit_finish(sub) jit_calli(sub)
#endif #endif
#ifndef jit_finishr
#define jit_finishr(reg) jit_callr(reg)
#endif
#ifndef jit_prolog #ifndef jit_prolog
#define jit_prolog(numargs) #define jit_prolog(numargs)
#endif #endif
@ -474,6 +522,14 @@ typedef union jit_code {
#define jit_rshi_ul(d, rs, is) jit_rshi_ui((d), (rs), (is)) #define jit_rshi_ul(d, rs, is) jit_rshi_ui((d), (rs), (is))
#define jit_rshr_ul(d, s1, s2) jit_rshr_ui((d), (s1), (s2)) #define jit_rshr_ul(d, s1, s2) jit_rshr_ui((d), (s1), (s2))
/* Sign/Zero extension */
#define jit_extr_c_l(d, rs) jit_extr_c_i(d, rs)
#define jit_extr_c_ul(d, rs) jit_extr_c_ui(d, rs)
#define jit_extr_s_l(d, rs) jit_extr_s_i(d, rs)
#define jit_extr_s_ul(d, rs) jit_extr_s_ui(d, rs)
#define jit_extr_i_l(d, rs) jit_movr_i(d, rs)
#define jit_extr_i_ul(d, rs) jit_movr_i(d, rs)
/* Unary */ /* Unary */
#define jit_movi_l(d, rs) jit_movi_i((d), (rs)) #define jit_movi_l(d, rs) jit_movi_i((d), (rs))
#define jit_movr_l(d, rs) jit_movr_i((d), (rs)) #define jit_movr_l(d, rs) jit_movr_i((d), (rs))

View file

@ -29,232 +29,58 @@
* *
***********************************************************************/ ***********************************************************************/
struct jit_fp { #define JIT_FPR0 JIT_FPR(0)
char kind; #define JIT_FPR1 JIT_FPR(1)
char subkind; #define JIT_FPR2 JIT_FPR(2)
union { #define JIT_FPR3 JIT_FPR(3)
struct { #define JIT_FPR4 JIT_FPR(4)
int displ; #define JIT_FPR5 JIT_FPR(5)
char reg1;
char reg2;
} addr;
union {
double number;
long split[sizeof(double) / sizeof(long)];
} imm;
struct {
struct jit_fp *lhs, *rhs;
} ops;
} d;
};
#ifdef jit_trunc
enum { JIT_NULL, /* unused */
JIT_CMP, JIT_FLOOR, JIT_CEIL, JIT_ROUND, JIT_TRUNC, /* integer */
JIT_XI, JIT_ADD, JIT_XR, JIT_SUB, /* subkinds */
JIT_I, JIT_MUL, JIT_R, JIT_DIV,
JIT_INT,
JIT_ABS, JIT_SIN, JIT_COS, JIT_TAN, JIT_ATN, /* functions */
JIT_EXP, JIT_LOG, JIT_NEG, JIT_SQRT,
JIT_OP, JIT_FN, JIT_LD, JIT_IMM }; /* kinds */
/* Declarations */
static void _jit_emit(jit_state *, struct jit_fp *,
int, int, int, int) JIT_UNUSED;
static struct jit_fp *_jit_op(struct jit_fp *, int,
struct jit_fp *, struct jit_fp *) JIT_UNUSED;
static struct jit_fp *_jit_ld(struct jit_fp *, int,
int, int) JIT_UNUSED;
static struct jit_fp *_jit_fn(struct jit_fp *, int,
struct jit_fp *) JIT_UNUSED;
static struct jit_fp *_jit_imm(struct jit_fp *, double) JIT_UNUSED;
/* Internal function to walk the tree */
void
_jit_emit(jit_state *jit, struct jit_fp *head,
int store_kind, int store1, int store2, int reg0)
{
#define _jit (*jit)
switch (head->kind) {
case JIT_OP:
_jit_emit(jit, head->d.ops.lhs, JIT_NULL, 0, 0, reg0);
_jit_emit(jit, head->d.ops.rhs, JIT_NULL, 0, 0, reg0 + 1);
switch (head->subkind) {
case JIT_ADD: jit_add_two(reg0); break;
case JIT_SUB: jit_sub_two(reg0); break;
case JIT_MUL: jit_mul_two(reg0); break;
case JIT_DIV: jit_div_two(reg0); break;
}
break;
case JIT_IMM:
#ifdef JIT_LONG_IS_INT
jit_fpimm(reg0, head->d.imm.split[0], head->d.imm.split[1]);
#else
jit_fpimm(reg0, head->d.imm.split[0]);
#endif
break;
case JIT_FN:
_jit_emit(jit, head->d.ops.lhs, JIT_NULL, 0, 0, reg0);
switch (head->subkind) {
case JIT_ABS: jit_abs(reg0); break;
case JIT_NEG: jit_neg(reg0); break;
#ifdef JIT_TRANSCENDENTAL
case JIT_SIN: jit_sin(reg0); break;
case JIT_SQRT: jit_sqrt(reg0); break;
case JIT_COS: jit_cos(reg0); break;
case JIT_TAN: jit_tan(reg0); break;
case JIT_ATN: jit_atn(reg0); break;
case JIT_EXP: jit_exp(reg0); break;
case JIT_LOG: jit_log(reg0); break;
#endif
}
break;
case JIT_LD:
switch (head->subkind) {
case JIT_INT: jit_exti_d(reg0, head->d.addr.reg1); break;
case JIT_XI: jit_ldxi_f(reg0, head->d.addr.reg1, head->d.addr.displ); break;
case JIT_XR: jit_ldxr_f(reg0, head->d.addr.reg1, head->d.addr.reg2); break;
case JIT_XI | 1: jit_ldxi_d(reg0, head->d.addr.reg1, head->d.addr.displ); break;
case JIT_XR | 1: jit_ldxr_d(reg0, head->d.addr.reg1, head->d.addr.reg2); break;
#ifndef JIT_RZERO
case JIT_I: jit_ldi_f(reg0, head->d.addr.displ); break;
case JIT_R: jit_ldr_f(reg0, head->d.addr.reg1); break;
case JIT_I | 1: jit_ldi_d(reg0, head->d.addr.displ); break;
case JIT_R | 1: jit_ldr_d(reg0, head->d.addr.reg1); break;
#endif
}
break;
}
switch (store_kind) {
case JIT_FLOOR: jit_floor(store1, reg0); break;
case JIT_CEIL: jit_ceil(store1, reg0); break;
case JIT_TRUNC: jit_trunc(store1, reg0); break;
case JIT_ROUND: jit_round(store1, reg0); break;
case JIT_CMP: jit_cmp(store1, store2, reg0); break;
case JIT_XI: jit_stxi_f(store2, store1, reg0); break;
case JIT_XR: jit_stxr_f(store2, store1, reg0); break;
case JIT_XI | 1: jit_stxi_d(store2, store1, reg0); break;
case JIT_XR | 1: jit_stxr_d(store2, store1, reg0); break;
#ifndef JIT_RZERO
case JIT_I: jit_sti_f(store2, reg0); break;
case JIT_R: jit_str_f(store2, reg0); break;
case JIT_I | 1: jit_sti_d(store2, reg0); break;
case JIT_R | 1: jit_str_d(store2, reg0); break;
#endif
case JIT_NULL: break;
}
#undef _jit
}
/* Internal functions to build the tree */
struct jit_fp *
_jit_op(struct jit_fp *where, int which,
struct jit_fp *op1, struct jit_fp *op2)
{
where->kind = JIT_OP;
where->subkind = which;
where->d.ops.lhs = op1;
where->d.ops.rhs = op2;
return (where);
}
struct jit_fp *
_jit_ld(struct jit_fp *where, int which, int op1, int op2)
{
where->kind = JIT_LD;
where->subkind = which;
switch (which & ~1) {
case JIT_XI: where->d.addr.reg1 = op1;
case JIT_I: where->d.addr.displ = op2; break;
case JIT_XR: where->d.addr.reg2 = op2;
case JIT_INT:
case JIT_R: where->d.addr.reg1 = op1; break;
}
return (where);
}
struct jit_fp *
_jit_fn(struct jit_fp *where, int which, struct jit_fp *op1)
{
where->kind = JIT_FN;
where->subkind = which;
where->d.ops.lhs = op1;
return (where);
}
struct jit_fp *
_jit_imm(struct jit_fp *where, double number)
{
where->kind = JIT_IMM;
where->d.imm.number = number;
return (where);
}
#define jitfp_begin(buf) (_jit.fp = (buf), --_jit.fp)
#define jitfp_add(op1, op2) _jit_op(++_jit.fp, JIT_ADD, (op1), (op2))
#define jitfp_sub(op1, op2) _jit_op(++_jit.fp, JIT_SUB, (op1), (op2))
#define jitfp_mul(op1, op2) _jit_op(++_jit.fp, JIT_MUL, (op1), (op2))
#define jitfp_div(op1, op2) _jit_op(++_jit.fp, JIT_DIV, (op1), (op2))
#define jitfp_imm(imm) _jit_imm(++_jit.fp, (imm))
#define jitfp_exti_d(reg1) _jit_ld(++_jit.fp, JIT_INT, (reg1), 0)
#define jitfp_ldxi_f(reg1, imm) _jit_ld(++_jit.fp, JIT_XI, (reg1), (long)(imm))
#define jitfp_ldxr_f(reg1, reg2) _jit_ld(++_jit.fp, JIT_XR, (reg1), (reg2))
#define jitfp_ldxi_d(reg1, imm) _jit_ld(++_jit.fp, JIT_XI | 1, (reg1), (long)(imm))
#define jitfp_ldxr_d(reg1, reg2) _jit_ld(++_jit.fp, JIT_XR | 1, (reg1), (reg2))
#define jitfp_abs(op1) _jit_fn(++_jit.fp, JIT_ABS, (op1))
#define jitfp_sqrt(op1) _jit_fn(++_jit.fp, JIT_SQRT, (op1))
#define jitfp_neg(op1) _jit_fn(++_jit.fp, JIT_NEG, (op1))
#define jitfp_stxi_f(imm, reg1, op1) _jit_emit(&_jit, (op1), JIT_XI, (reg1), (long)(imm), 0)
#define jitfp_stxr_f(reg1, reg2, op1) _jit_emit(&_jit, (op1), JIT_XR, (reg1), (reg2), 0)
#define jitfp_stxi_d(imm, reg1, op1) _jit_emit(&_jit, (op1), JIT_XI | 1, (reg1), (long)(imm), 0)
#define jitfp_stxr_d(reg1, reg2, op1) _jit_emit(&_jit, (op1), JIT_XR | 1, (reg1), (reg2), 0)
#define jitfp_cmp(regle, regge, op1) _jit_emit(&_jit, (op1), JIT_CMP, regle, regge, 0)
#define jitfp_floor(reg1, op1) _jit_emit(&_jit, (op1), JIT_FLOOR, reg1, 0, 0)
#define jitfp_ceil(reg1, op1) _jit_emit(&_jit, (op1), JIT_CEIL, reg1, 0, 0)
#define jitfp_trunc(reg1, op1) _jit_emit(&_jit, (op1), JIT_TRUNC, reg1, 0, 0)
#define jitfp_round(reg1, op1) _jit_emit(&_jit, (op1), JIT_ROUND, reg1, 0, 0)
#ifdef JIT_TRANSCENDENTAL
#define jitfp_sin(op1) _jit_fn(++_jit.fp, JIT_SIN, (op1))
#define jitfp_cos(op1) _jit_fn(++_jit.fp, JIT_COS, (op1))
#define jitfp_tan(op1) _jit_fn(++_jit.fp, JIT_TAN, (op1))
#define jitfp_atn(op1) _jit_fn(++_jit.fp, JIT_ATN, (op1))
#define jitfp_exp(op1) _jit_fn(++_jit.fp, JIT_EXP, (op1))
#define jitfp_log(op1) _jit_fn(++_jit.fp, JIT_LOG, (op1))
#endif
#ifdef JIT_RZERO #ifdef JIT_RZERO
#define jitfp_ldi_f(imm) _jit_ld(++_jit.fp, JIT_XI, JIT_RZERO, (long)(imm)) #ifndef jit_ldi_f
#define jitfp_ldr_f(reg1) _jit_ld(++_jit.fp, JIT_XR, JIT_RZERO, (reg1)) #define jit_ldi_f(rd, is) jit_ldxi_f((rd), JIT_RZERO, (is))
#define jitfp_ldi_d(imm) _jit_ld(++_jit.fp, JIT_XI | 1, JIT_RZERO, (long)(imm)) #define jit_sti_f(id, rs) jit_stxi_f((id), JIT_RZERO, (rs))
#define jitfp_ldr_d(reg1) _jit_ld(++_jit.fp, JIT_XR | 1, JIT_RZERO, (reg1)) #define jit_ldi_d(rd, is) jit_ldxi_d((rd), JIT_RZERO, (is))
#define jitfp_sti_f(imm, op1) _jit_emit(&_jit, (op1), JIT_XI, JIT_RZERO, (long)(imm), 0) #define jit_sti_d(id, rs) jit_stxi_d((id), JIT_RZERO, (rs))
#define jitfp_str_f(reg1, op1) _jit_emit(&_jit, (op1), JIT_XR, JIT_RZERO, (reg1), 0)
#define jitfp_sti_d(imm, op1) _jit_emit(&_jit, (op1), JIT_XI | 1, JIT_RZERO, (long)(imm), 0)
#define jitfp_str_d(reg1, op1) _jit_emit(&_jit, (op1), JIT_XR | 1, JIT_RZERO, (reg1), 0)
#else
#define jitfp_ldi_f(imm) _jit_ld(++_jit.fp, JIT_I, 0, (long)(imm))
#define jitfp_ldr_f(reg1) _jit_ld(++_jit.fp, JIT_R, (reg1), 0)
#define jitfp_ldi_d(imm) _jit_ld(++_jit.fp, JIT_I | 1, 0, (long)(imm))
#define jitfp_ldr_d(reg1) _jit_ld(++_jit.fp, JIT_R | 1, (reg1), 0)
#define jitfp_sti_f(imm, op1) _jit_emit(&_jit, (op1), JIT_I, 0, (long)(imm), 0)
#define jitfp_str_f(reg1, op1) _jit_emit(&_jit, (op1), JIT_R, 0, (reg1), 0)
#define jitfp_sti_d(imm, op1) _jit_emit(&_jit, (op1), JIT_I | 1, 0, (long)(imm), 0)
#define jitfp_str_d(reg1, op1) _jit_emit(&_jit, (op1), JIT_R | 1, 0, (reg1), 0)
#endif #endif
#ifndef jit_ldr_f
#define jit_ldr_f(rd, rs) jit_ldxr_f((rd), JIT_RZERO, (rs))
#define jit_str_f(rd, rs) jit_stxr_f((rd), JIT_RZERO, (rs))
#define jit_ldr_d(rd, rs) jit_ldxr_d((rd), JIT_RZERO, (rs))
#define jit_str_d(rd, rs) jit_stxr_d((rd), JIT_RZERO, (rs))
#endif
#endif
#ifndef jit_addr_f
#define jit_addr_f(rd,s1,s2) jit_addr_d(rd,s1,s2)
#define jit_subr_f(rd,s1,s2) jit_subr_d(rd,s1,s2)
#define jit_mulr_f(rd,s1,s2) jit_mulr_d(rd,s1,s2)
#define jit_divr_f(rd,s1,s2) jit_divr_d(rd,s1,s2)
#define jit_movr_f(rd,rs) jit_movr_d(rd,rs)
#define jit_abs_f(rd,rs) jit_abs_d(rd,rs)
#define jit_negr_f(rd,rs) jit_negr_d(rd,rs)
#define jit_sqrt_f(rd,rs) jit_sqrt_d(rd,rs)
#define jit_extr_f_d(rs, rd)
#define jit_extr_d_f(rs, rd)
#define jit_extr_i_f(rd, rs) jit_extr_i_d(rd, rs)
#define jit_roundr_f_i(rd, rs) jit_roundr_d_i(rd, rs)
#define jit_floorr_f_i(rd, rs) jit_floorr_d_i(rd, rs)
#define jit_ceilr_f_i(rd, rs) jit_ceilr_d_i(rd, rs)
#define jit_truncr_f_i(rd, rs) jit_truncr_d_i(rd, rs)
#define jit_ltr_f(d, s1, s2) jit_ltr_d(d, s1, s2)
#define jit_ler_f(d, s1, s2) jit_ler_d(d, s1, s2)
#define jit_eqr_f(d, s1, s2) jit_eqr_d(d, s1, s2)
#define jit_ner_f(d, s1, s2) jit_ner_d(d, s1, s2)
#define jit_ger_f(d, s1, s2) jit_ger_d(d, s1, s2)
#define jit_gtr_f(d, s1, s2) jit_gtr_d(d, s1, s2)
#define jit_unltr_f(d, s1, s2) jit_unltr_d(d, s1, s2)
#define jit_unler_f(d, s1, s2) jit_unler_d(d, s1, s2)
#define jit_uneqr_f(d, s1, s2) jit_uneqr_d(d, s1, s2)
#define jit_ltgtr_f(d, s1, s2) jit_ltgtr_d(d, s1, s2)
#define jit_unger_f(d, s1, s2) jit_unger_d(d, s1, s2)
#define jit_ungtr_f(d, s1, s2) jit_ungtr_d(d, s1, s2)
#define jit_ordr_f(d, s1, s2) jit_ordr_d(d, s1, s2)
#define jit_unordr_f(d, s1, s2) jit_unordr_d(d, s1, s2)
#define jit_retval_f(rs) jit_retval_d(rs)
#endif #endif

View file

@ -45,4 +45,10 @@ jit_fail(const char *msg, const char *file, int line, const char *function)
abort(); abort();
} }
#ifndef jit_start_pfx
#define jit_start_pfx() ( (jit_insn*)0x4)
#define jit_end_pfx() ( (jit_insn*)0x0)
#endif
#endif /* __lightning_funcs_common_h */ #endif /* __lightning_funcs_common_h */

View file

@ -43,6 +43,7 @@
typedef _uc jit_insn; typedef _uc jit_insn;
#ifndef LIGHTNING_DEBUG
#define _b00 0 #define _b00 0
#define _b01 1 #define _b01 1
#define _b10 2 #define _b10 2
@ -340,10 +341,10 @@ typedef _uc jit_insn;
#define CALLsm(D,B,I,S) _O_r_X (0xff ,_b010 ,(int)(D),B,I,S ) #define CALLsm(D,B,I,S) _O_r_X (0xff ,_b010 ,(int)(D),B,I,S )
#define CBW() _O (0x98 ) #define CBW_() _O (0x98 )
#define CLC() _O (0xf8 ) #define CLC_() _O (0xf8 )
#define CLTD() _O (0x99 ) #define CLTD_() _O (0x99 )
#define CMC() _O (0xf5 ) #define CMC_() _O (0xf5 )
#define CMPBrr(RS, RD) _O_Mrm (0x38 ,_b11,_r1(RS),_r1(RD) ) #define CMPBrr(RS, RD) _O_Mrm (0x38 ,_b11,_r1(RS),_r1(RD) )
@ -365,7 +366,7 @@ typedef _uc jit_insn;
#define CMPLim(IM, MD, MB, MI, MS) _O_r_X_L (0x81 ,_b111 ,MD,MB,MI,MS ,IM ) #define CMPLim(IM, MD, MB, MI, MS) _O_r_X_L (0x81 ,_b111 ,MD,MB,MI,MS ,IM )
#define CWD() _O (0x99 ) #define CWD_() _O (0x99 )
#define CMPXCHGBrr(RS,RD) _OO_Mrm (0x0fb0 ,_b11,_r1(RS),_r1(RD) ) #define CMPXCHGBrr(RS,RD) _OO_Mrm (0x0fb0 ,_b11,_r1(RS),_r1(RD) )
@ -399,7 +400,7 @@ typedef _uc jit_insn;
#define ENTERii(W, B) _O_W_B (0xc8 ,_su16(W),_su8(B)) #define ENTERii(W, B) _O_W_B (0xc8 ,_su16(W),_su8(B))
#define HLT() _O (0xf4 ) #define HLT_() _O (0xf4 )
#define IDIVBr(RS) _O_Mrm (0xf6 ,_b11,_b111 ,_r1(RS) ) #define IDIVBr(RS) _O_Mrm (0xf6 ,_b11,_b111 ,_r1(RS) )
@ -443,7 +444,7 @@ typedef _uc jit_insn;
#define INCLm(MD,MB,MI,MS) _O_r_X (0xff ,_b000 ,MD,MB,MI,MS ) #define INCLm(MD,MB,MI,MS) _O_r_X (0xff ,_b000 ,MD,MB,MI,MS )
#define INVD() _OO (0x0f08 ) #define INVD_() _OO (0x0f08 )
#define INVLPGm(MD, MB, MI, MS) _OO_r_X (0x0f01 ,_b111 ,MD,MB,MI,MS ) #define INVLPGm(MD, MB, MI, MS) _OO_r_X (0x0f01 ,_b111 ,MD,MB,MI,MS )
@ -523,9 +524,9 @@ typedef _uc jit_insn;
#define JMPsm(D,B,I,S) _O_r_X (0xff ,_b100 ,(int)(D),B,I,S ) #define JMPsm(D,B,I,S) _O_r_X (0xff ,_b100 ,(int)(D),B,I,S )
#define LAHF() _O (0x9f ) #define LAHF_() _O (0x9f )
#define LEALmr(MD, MB, MI, MS, RD) _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS ) #define LEALmr(MD, MB, MI, MS, RD) _O_r_X (0x8d ,_r4(RD) ,MD,MB,MI,MS )
#define LEAVE() _O (0xc9 ) #define LEAVE_() _O (0xc9 )
#define LMSWr(RS) _OO_Mrm (0x0f01 ,_b11,_b110,_r4(RS) ) #define LMSWr(RS) _OO_Mrm (0x0f01 ,_b11,_b110,_r4(RS) )
@ -600,7 +601,7 @@ typedef _uc jit_insn;
#define NEGLm(MD,MB,MI,MS) _O_r_X (0xf7 ,_b011 ,MD,MB,MI,MS ) #define NEGLm(MD,MB,MI,MS) _O_r_X (0xf7 ,_b011 ,MD,MB,MI,MS )
#define NOP() _O (0x90 ) #define NOP_() _O (0x90 )
#define NOTBr(RD) _O_Mrm (0xf6 ,_b11,_b010 ,_r1(RD) ) #define NOTBr(RD) _O_Mrm (0xf6 ,_b11,_b010 ,_r1(RD) )
@ -639,11 +640,11 @@ typedef _uc jit_insn;
#define POPLm(MD,MB,MI,MS) _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS ) #define POPLm(MD,MB,MI,MS) _O_r_X (0x8f ,_b000 ,MD,MB,MI,MS )
#define POPA() _wO (0x61 ) #define POPA_() _wO (0x61 )
#define POPAD() _O (0x61 ) #define POPAD_() _O (0x61 )
#define POPF() _wO (0x9d ) #define POPF_() _wO (0x9d )
#define POPFD() _O (0x9d ) #define POPFD_() _O (0x9d )
#define PUSHWr(R) _wOr (0x50,_r2(R) ) #define PUSHWr(R) _wOr (0x50,_r2(R) )
@ -655,13 +656,13 @@ typedef _uc jit_insn;
#define PUSHLi(IM) _Os_sL (0x68 ,IM ) #define PUSHLi(IM) _Os_sL (0x68 ,IM )
#define PUSHA() _wO (0x60 ) #define PUSHA_() _wO (0x60 )
#define PUSHAD() _O (0x60 ) #define PUSHAD_() _O (0x60 )
#define PUSHF() _O (0x9c ) #define PUSHF_() _O (0x9c )
#define PUSHFD() _wO (0x9c ) #define PUSHFD_() _wO (0x9c )
#define RET() _O (0xc3 ) #define RET_() _O (0xc3 )
#define RETi(IM) _O_W (0xc2 ,_su16(IM)) #define RETi(IM) _O_W (0xc2 ,_su16(IM))
@ -721,7 +722,7 @@ typedef _uc jit_insn;
JITFAIL ("source register must be CL" ) ) JITFAIL ("source register must be CL" ) )
#define SAHF() _O (0x9e ) #define SAHF_() _O (0x9e )
#define SALBir SHLBir #define SALBir SHLBir
@ -904,7 +905,7 @@ typedef _uc jit_insn;
JITFAIL ("source register must be CL" ) ) JITFAIL ("source register must be CL" ) )
#define STC() _O (0xf9 ) #define STC_() _O (0xf9 )
#define SUBBrr(RS, RD) _O_Mrm (0x28 ,_b11,_r1(RS),_r1(RD) ) #define SUBBrr(RS, RD) _O_Mrm (0x28 ,_b11,_r1(RS),_r1(RD) )
@ -985,8 +986,8 @@ typedef _uc jit_insn;
#define ESCmi(D,B,I,S,OP) _O_r_X(0xd8|(OP >> 3), (OP & 7), D,B,I,S) #define ESCmi(D,B,I,S,OP) _O_r_X(0xd8|(OP >> 3), (OP & 7), D,B,I,S)
#define ESCri(RD,OP) _O_Mrm(0xd8|(OP >> 3), _b11, (OP & 7), RD) #define ESCri(RD,OP) _O_Mrm(0xd8|(OP >> 3), _b11, (OP & 7), RD)
#define ESCrri(RS,RD,OP) ((RS) = _ST0 ? ESCri(RD,(OP|040)) \ #define ESCrri(RS,RD,OP) ((RS) == _ST0 ? ESCri(RD,(OP|040)) \
: (RD) = _ST0 ? ESCri(RS,OP) \ : (RD) == _ST0 ? ESCri(RS,OP) \
: JITFAIL ("coprocessor instruction without st0")) : JITFAIL ("coprocessor instruction without st0"))
#define FLDSm(D,B,I,S) ESCmi(D,B,I,S,010) /* fld m32real */ #define FLDSm(D,B,I,S) ESCmi(D,B,I,S,010) /* fld m32real */
@ -1036,7 +1037,7 @@ typedef _uc jit_insn;
#define FNSTSWr(RD) ((RD == _AX || RD == _EAX) ? _OO (0xdfe0) \ #define FNSTSWr(RD) ((RD == _AX || RD == _EAX) ? _OO (0xdfe0) \
: JITFAIL ("AX or EAX expected")) : JITFAIL ("AX or EAX expected"))
/* N byte NOPs */ /* N byte NOPs */
#define _NOPi(N) ((( (N) >= 8) ? (_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00),_jit_B(0x90)) : (void) 0), \ #define NOPi(N) ((( (N) >= 8) ? (_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00),_jit_B(0x90)) : (void) 0), \
(( ((N)&7) == 7) ? (_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00)) : \ (( ((N)&7) == 7) ? (_jit_B(0x8d),_jit_B(0xb4),_jit_B(0x26),_jit_L(0x00)) : \
( ((N)&7) == 6) ? (_jit_B(0x8d),_jit_B(0xb6),_jit_L(0x00)) : \ ( ((N)&7) == 6) ? (_jit_B(0x8d),_jit_B(0xb6),_jit_L(0x00)) : \
( ((N)&7) == 5) ? (_jit_B(0x90),_jit_B(0x8d),_jit_B(0x74),_jit_B(0x26),_jit_B(0x00)) : \ ( ((N)&7) == 5) ? (_jit_B(0x90),_jit_B(0x8d),_jit_B(0x74),_jit_B(0x26),_jit_B(0x00)) : \
@ -1056,5 +1057,6 @@ typedef _uc jit_insn;
/* [2] "Intel Architecture Software Developer's Manual Volume 2: Instruction Set Reference", */ /* [2] "Intel Architecture Software Developer's Manual Volume 2: Instruction Set Reference", */
/* Intel Corporation 1997. */ /* Intel Corporation 1997. */
#endif
#endif /* __lightning_asm_h */ #endif /* __lightning_asm_h */

View file

@ -34,16 +34,15 @@
#ifndef __lightning_core_h #ifndef __lightning_core_h
#define __lightning_core_h #define __lightning_core_h
#define JIT_R0 _EAX
#define JIT_R1 _ECX
#define JIT_R2 _EDX
#define JIT_V0 _EBX
#define JIT_V1 _ESI
#define JIT_V2 _EDI
#define JIT_FP _EBP #define JIT_FP _EBP
#define JIT_SP _ESP #define JIT_SP _ESP
#define JIT_RET _EAX #define JIT_RET _EAX
#define JIT_R_NUM 3
#define JIT_V_NUM 3
#define JIT_R(i) (_EAX + (i))
#define JIT_V(i) ((i) == 0 ? _EBX : _ESI + (i) - 1)
struct jit_local_state { struct jit_local_state {
int framesize; int framesize;
int argssize; int argssize;
@ -265,10 +264,13 @@ struct jit_local_state {
/* The += allows for stack pollution */ /* The += allows for stack pollution */
#define jitfp_prepare(ni,nf,nd) ((void) (_jitl.argssize += (ni) + (nf) + 2*(nd))) #define jit_prepare_i(ni) (_jitl.argssize += (ni))
#define jit_prepare_f(nf) (_jitl.argssize += (nf))
#define jit_prepare_d(nd) (_jitl.argssize += 2 * (nd))
#define jit_pusharg_i(rs) PUSHLr(rs) #define jit_pusharg_i(rs) PUSHLr(rs)
#define jit_finish(sub) (jit_calli((sub)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0) #define jit_finish(sub) (jit_calli((sub)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_retval(rd) jit_movr_i ((rd), _EAX) #define jit_finishr(reg) (jit_callr((reg)), ADDLir(4 * _jitl.argssize, JIT_SP), _jitl.argssize = 0)
#define jit_retval_i(rd) jit_movr_i ((rd), _EAX)
#define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int)) #define jit_arg_c() ((_jitl.framesize += sizeof(int)) - sizeof(int))
#define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int)) #define jit_arg_uc() ((_jitl.framesize += sizeof(int)) - sizeof(int))
@ -289,6 +291,8 @@ struct jit_local_state {
#define jit_movr_i(d, rs) ((rs) == (d) ? 0 : MOVLrr((rs), (d))) #define jit_movr_i(d, rs) ((rs) == (d) ? 0 : MOVLrr((rs), (d)))
#define jit_movi_i(d, is) ((is) ? MOVLir((is), (d)) : XORLrr ((d), (d)) ) #define jit_movi_i(d, is) ((is) ? MOVLir((is), (d)) : XORLrr ((d), (d)) )
#define jit_movi_p(d, is) (MOVLir((is), (d)), _jit.x.pc)
#define jit_patch_movi(pa,pv) (*_PSL((pa) - 4) = _jit_SL((pv)))
#define jit_ntoh_ui(d, rs) jit_op_((d), (rs), BSWAPLr(d)) #define jit_ntoh_ui(d, rs) jit_op_((d), (rs), BSWAPLr(d))
#define jit_ntoh_us(d, rs) jit_op_((d), (rs), RORWir(8, d)) #define jit_ntoh_us(d, rs) jit_op_((d), (rs), RORWir(8, d))
@ -311,7 +315,7 @@ struct jit_local_state {
#define jit_gei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETGEr, SETNSr ) #define jit_gei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETGEr, SETNSr )
#define jit_eqi_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETEr, SETEr ) #define jit_eqi_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETEr, SETEr )
#define jit_nei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETNEr, SETNEr ) #define jit_nei_i(d, rs, is) jit_bool_i0((d), (rs), (is), SETNEr, SETNEr )
#define jit_lti_ui(d, rs, is) jit_bool_i ((d), (rs), (is), SETB ) #define jit_lti_ui(d, rs, is) jit_bool_i ((d), (rs), (is), SETBr )
#define jit_lei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETBEr, SETEr ) #define jit_lei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETBEr, SETEr )
#define jit_gti_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAr, SETNEr ) #define jit_gti_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAr, SETNEr )
#define jit_gei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAEr, INCLr ) #define jit_gei_ui(d, rs, is) jit_bool_i0((d), (rs), (is), SETAEr, INCLr )
@ -340,10 +344,10 @@ struct jit_local_state {
#define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label,0,0,0), JNSm(label,0,0,0) ) #define jit_bgei_i(label, rs, is) jit_bra_i0((rs), (is), JGEm(label,0,0,0), JNSm(label,0,0,0) )
#define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label, 0,0,0), JEm(label, 0,0,0) ) #define jit_beqi_i(label, rs, is) jit_bra_i0((rs), (is), JEm(label, 0,0,0), JEm(label, 0,0,0) )
#define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label,0,0,0), JNEm(label,0,0,0) ) #define jit_bnei_i(label, rs, is) jit_bra_i0((rs), (is), JNEm(label,0,0,0), JNEm(label,0,0,0) )
#define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JLm(label, 0,0,0) ) #define jit_blti_ui(label, rs, is) jit_bra_i ((rs), (is), JBm(label, 0,0,0) )
#define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JLEm(label,0,0,0), JEm(label, 0,0,0) ) #define jit_blei_ui(label, rs, is) jit_bra_i0((rs), (is), JBEm(label,0,0,0), JEm(label, 0,0,0) )
#define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JGm(label, 0,0,0), JNEm(label,0,0,0) ) #define jit_bgti_ui(label, rs, is) jit_bra_i0((rs), (is), JAm(label, 0,0,0), JNEm(label,0,0,0) )
#define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JGEm(label,0,0,0) ) #define jit_bgei_ui(label, rs, is) jit_bra_i ((rs), (is), JAEm(label,0,0,0) )
#define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc) #define jit_boaddi_i(label, rs, is) (ADDLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
#define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc) #define jit_bosubi_i(label, rs, is) (SUBLir((is), (rs)), JOm(label,0,0,0), _jit.x.pc)
#define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc) #define jit_boaddi_ui(label, rs, is) (ADDLir((is), (rs)), JCm(label,0,0,0), _jit.x.pc)
@ -354,9 +358,10 @@ struct jit_local_state {
#define jit_jmpi(label) (JMPm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc) #define jit_jmpi(label) (JMPm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
#define jit_calli(label) (CALLm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc) #define jit_calli(label) (CALLm( ((unsigned long) (label)), 0, 0, 0), _jit.x.pc)
#define jit_callr(reg) (CALLsr(reg))
#define jit_jmpr(reg) JMPsr(reg) #define jit_jmpr(reg) JMPsr(reg)
#define jit_patch(jump_pc) (*_PSL((jump_pc) - 4) = _jit_SL(_jit.x.pc - (jump_pc))) #define jit_patch_at(jump_pc,v) (*_PSL((jump_pc) - 4) = _jit_SL((v) - (jump_pc)))
#define jit_ret() (POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), POPLr(_EBP), RET()) #define jit_ret() (POPLr(_EDI), POPLr(_ESI), POPLr(_EBX), POPLr(_EBP), RET_())
/* Memory */ /* Memory */
#define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d)) #define jit_ldi_c(d, is) MOVSBLmr((is), 0, 0, 0, (d))
@ -400,9 +405,9 @@ struct jit_local_state {
#define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0) #define jit_stxi_i(id, rd, rs) MOVLrm((rs), (id), (rd), 0, 0)
/* Extra */ /* Extra */
#define jit_nop() NOP() #define jit_nop() NOP_()
#define _jit_alignment(pc, n) (((pc ^ _MASK(4)) + 1) & _MASK(n)) #define _jit_alignment(pc, n) (((pc ^ _MASK(4)) + 1) & _MASK(n))
#define jit_align(n) _NOPi(_jit_alignment(_jit_UL(_jit.x.pc), (n))) #define jit_align(n) NOPi(_jit_alignment(_jit_UL(_jit.x.pc), (n)))
#endif /* __lightning_core_h */ #endif /* __lightning_core_h */

View file

@ -33,49 +33,48 @@
#ifndef __lightning_asm_fp_h #ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h #define __lightning_asm_fp_h
/* Actually, we should redesign the jitfp interface. As a first step, I have /* We really must map the x87 stack onto a flat register file. In practice,
defined the macros for many x87 instructions, and I am using them here. we can provide something sensible and make it work on the x86 using the
stack like a file of eight registers.
In practice, we can provide something sensible and make it work on the x86 We use six or seven registers so as to have some freedom
using the stack like a file of eight registers. Then this awful stuff goes for floor, ceil, round, (and log, tan, atn and exp).
away, and everything is "beautiful" as the rest of GNU lightning---and we'll
document it, promised.
Well, let's use six or seven registers so as to have some freedom
for floor, ceil, round, log, tan, atn and exp.
Not hard at all, basically play with FXCH. FXCH is mostly free, Not hard at all, basically play with FXCH. FXCH is mostly free,
so the generated code is not bad. Of course we special case when one so the generated code is not bad. Of course we special case when one
of the operands turns out to be ST0. of the operands turns out to be ST0.
- binary ops: Here are the macros that actually do the trick. */
add FRR3 to FPR0 #define JIT_FPR_NUM 6
FADD ST0,ST3 #define JIT_FPR(i) (i)
add FPR0 to FPR3 #define jit_fxch(rs, op) (((rs) != 0 ? FXCHr(rs) : 0), \
FADD ST3,ST0 op, ((rs) != 0 ? FXCHr(rs) : 0))
add FPR3 to FPR7 (I'm using nasm syntax here) #define jit_fp_unary(rd, s1, op) \
FXCH ST3 ((rd) == (s1) ? jit_fxch ((rd), op) \
FADD ST7,ST0 : (rd) == 0 ? (FSTPr (0), FLDr ((s1)-1), op) \
FXCH ST3 : (FLDr ((s1)), op, FSTPr ((rd))))
- stores: #define jit_fp_binary(rd, s1, s2, op, opr) \
((rd) == (s1) ? \
((s2) == 0 ? opr(0, (rd)) \
: (s2) == (s1) ? jit_fxch((rd), op(0, 0)) \
: jit_fxch((rd), op((s2), 0))) \
: (rd) == (s2) ? jit_fxch((s1), opr(0, (rd) == 0 ? (s1) : (rd))) \
: (FLDr (s1), op(0, (s2)+1), FSTPr((rd)+1)))
store FPR3 #define jit_addr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FADDrr,FADDrr)
#define jit_subr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FSUBrr,FSUBRrr)
#define jit_mulr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FMULrr,FMULrr)
#define jit_divr_d(rd,s1,s2) jit_fp_binary((rd),(s1),(s2),FDIVrr,FDIVRrr)
FXCH ST3 #define jit_abs_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e1))
FST [FUBAR] #define jit_negr_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9e0))
FXCH ST3 #define jit_sqrt_d(rd,rs) jit_fp_unary ((rd), (rs), _OO (0xd9fa))
store FPR0 /* - moves:
FST [FUBAR]
(and similarly for other unary ops like FCHS or FABS)
- moves:
move FPR0 to FPR3 move FPR0 to FPR3
FST ST3 FST ST3
@ -85,11 +84,16 @@
FST ST3 FST ST3
move FPR3 to FPR1 move FPR3 to FPR1
FSTP ST1 Save old st0 into destination register FLD ST1
FLD ST2 Stack is rotated, so FPRn becomes STn-1 FST ST4 Stack is rotated, so FPRn becomes STn+1 */
FXCH ST1 Get back old st0
- loads: #define jit_movr_d(rd,s1) \
((s1) == (rd) ? 0 \
: (s1) == 0 ? FSTr ((rd)) \
: (rd) == 0 ? (FXCHr ((s1)), FSTr ((s1))) \
: (FLDr ((s1)), FSTr ((rd)+1)))
/* - loads:
load into FPR0 load into FPR0
FSTP ST0 FSTP ST0
@ -102,53 +106,82 @@
(and similarly for immediates, using the stack) */ (and similarly for immediates, using the stack) */
#define jit_add_two(reg0) FADDPr(1) #define jit_movi_f(rd,immf) \
#define jit_sub_two(reg0) FSUBRPr(1) (_O (0x68), \
#define jit_mul_two(reg0) FMULPr(1) *((float *) _jit.x.pc) = (float) immf, \
#define jit_div_two(reg0) FDIVRPr(1) _jit.x.uc_pc += sizeof (float), \
jit_ldr_f((rd), _ESP), \
ADDLir(4, _ESP))
#define jit_abs(reg0) _OO(0xd9e1) /* fabs */ union jit_double_imm {
#define jit_sqr(reg0) FMULrr(0,0) double d;
#define jit_sqrt(reg0) _OO(0xd9fa) /* fsqrt */ int i[2];
};
#define jit_exti_d(reg0, rs) (PUSHLr((rs)), FILDLm(0, _ESP, 0, 0), POPLr((rs))) #define jit_movi_d(rd,immd) \
(_O (0x68), \
#define jit_neg(reg0) _OO(0xd9e0) /* fchs */ _jit.x.uc_pc[4] = 0x68, \
((union jit_double_imm *) (_jit.x.uc_pc + 5))->d = (double) immd, \
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1) *((int *) _jit.x.uc_pc) = ((union jit_double_imm *) (_jit.x.uc_pc + 5))->i[1], \
#define jit_ldxi_f(reg0, rs, is) FLDSm((is), (rs), 0, 0) _jit.x.uc_pc += 9, \
#define jit_ldxr_f(reg0, s1, s2) FLDSm(0, (s1), (s2), 1) jit_ldr_d((rd), _ESP), \
#define jit_ldxi_d(reg0, rs, is) FLDLm((is), (rs), 0, 0)
#define jit_ldxr_d(reg0, s1, s2) FLDLm(0, (s1), (s2), 1)
#define jit_ldi_f(reg0, is) FLDSm((is), 0, 0, 0)
#define jit_ldr_f(reg0, rs) FLDSm(0, (rs), 0, 0)
#define jit_ldi_d(reg0, is) FLDLm((is), 0, 0, 0)
#define jit_ldr_d(reg0, rs) FLDLm(0, (rs), 0, 0)
#define jit_stxi_f(id, rd, reg0) FSTPSm((id), (rd), 0, 0)
#define jit_stxr_f(d1, d2, reg0) FSTPSm(0, (d1), (d2), 1)
#define jit_stxi_d(id, rd, reg0) FSTPLm((id), (rd), 0, 0)
#define jit_stxr_d(d1, d2, reg0) FSTPLm(0, (d1), (d2), 1)
#define jit_sti_f(id, reg0) FSTPSm((id), 0, 0, 0)
#define jit_str_f(rd, reg0) FSTPSm(0, (rd), 0, 0)
#define jit_sti_d(id, reg0) FSTPLm((id), 0, 0, 0)
#define jit_str_d(rd, reg0) FSTPLm(0, (rd), 0, 0)
#define jit_fpimm(reg0, first, second) \
(PUSHLi(second), \
PUSHLi(first), \
FLDLm(0, _ESP, 0, 0), \
ADDLir(8, _ESP)) ADDLir(8, _ESP))
#define jit_ldi_f(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), 0, 0, 0)) \
: (FLDSm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldi_d(rd, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), 0, 0, 0)) \
: (FLDLm((is), 0, 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_f(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (rs), 0, 0)) \
: (FLDSm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldr_d(rd, rs) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (rs), 0, 0)) \
: (FLDLm(0, (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_f(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDSm((is), (rs), 0, 0)) \
: (FLDSm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxi_d(rd, rs, is) \
((rd) == 0 ? (FSTPr (0), FLDLm((is), (rs), 0, 0)) \
: (FLDLm((is), (rs), 0, 0), FSTPr ((rd) + 1)))
#define jit_ldxr_f(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDSm(0, (s1), (s2), 1)) \
: (FLDSm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_ldxr_d(rd, s1, s2) \
((rd) == 0 ? (FSTPr (0), FLDLm(0, (s1), (s2), 1)) \
: (FLDLm(0, (s1), (s2), 1), FSTPr ((rd) + 1)))
#define jit_extr_i_d(rd, rs) (PUSHLr((rs)), \
((rd) == 0 ? (FSTPr (0), FILDLm(0, _ESP, 0, 0)) \
: (FILDLm(0, _ESP, 0, 0), FSTPr ((rd) + 1))), \
POPLr((rs)))
#define jit_stxi_f(id, rd, rs) jit_fxch ((rs), FSTSm((id), (rd), 0, 0))
#define jit_stxr_f(d1, d2, rs) jit_fxch ((rs), FSTSm(0, (d1), (d2), 1))
#define jit_stxi_d(id, rd, rs) jit_fxch ((rs), FSTLm((id), (rd), 0, 0))
#define jit_stxr_d(d1, d2, rs) jit_fxch ((rs), FSTLm(0, (d1), (d2), 1))
#define jit_sti_f(id, rs) jit_fxch ((rs), FSTSm((id), 0, 0, 0))
#define jit_str_f(rd, rs) jit_fxch ((rs), FSTSm(0, (rd), 0, 0))
#define jit_sti_d(id, rs) jit_fxch ((rs), FSTLm((id), 0, 0, 0))
#define jit_str_d(rd, rs) jit_fxch ((rs), FSTLm(0, (rd), 0, 0))
/* Assume round to near mode */ /* Assume round to near mode */
#define jit_floor(rd, reg0) \ #define jit_floorr_d_i(rd, rs) \
jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)) (FLDr (rs), jit_floor2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_ceil(rd, reg0) \ #define jit_ceilr_d_i(rd, rs) \
jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)) (FLDr (rs), jit_ceil2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_trunc(rd, reg0) \ #define jit_truncr_d_i(rd, rs) \
jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)) (FLDr (rs), jit_trunc2((rd), ((rd) == _EDX ? _EAX : _EDX)))
#define jit_calc_diff(ofs) \ #define jit_calc_diff(ofs) \
FISTLm(ofs, _ESP, 0, 0), \ FISTLm(ofs, _ESP, 0, 0), \
@ -200,41 +233,102 @@
POPLr(aux)) POPLr(aux))
/* the easy one */ /* the easy one */
#define jit_round(rd, reg0) \ #define jit_roundr_d_i(rd, rs) \
(PUSHLr(_EAX), \ (PUSHLr(_EAX), \
FISTPLm(0, _ESP, 0, 0), \ jit_fxch ((rs), FISTPLm(0, _ESP, 0, 0)), \
POPLr((rd))) POPLr((rd)))
#define jit_cmp(le, ge, reg0) ( \ #define jit_fp_test(d, s1, s2, n, _and, res) \
((le) == _EAX || (ge) == _EAX ? 0 : PUSHLr(_EAX)), \ (((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
FCOMr(0), \ ((d) != _EAX ? MOVLrr(_EAX, (d)) : 0), \
FNSTSWr(_AX), \ FNSTSWr(_EAX), \
TESTBir(0x40, _AH), \ SHRLir(n, _EAX), \
MOVLir(0, (le)), \ ((_and) ? ANDLir((_and), _EAX) : MOVLir(0, _EAX)), \
MOVLrr((le), (ge)), \ res, \
JZSm(_jit.x.pc + 11, 0, 0, 0), \ ((d) != _EAX ? _O (0x90 + ((d) & 7)) : 0)) /* xchg */
_OO(0xd9e4), /* ftst */ /* 2 */ \
FNSTSWr(_AX), /* 2 */ \
SAHF(), /* 1 */ \
SETLEr( ((le) & 15) | 0x10), /* 3 */ \
SETGEr( ((ge) & 15) | 0x10), /* 3 */ \
((le) == _EAX || (ge) == _EAX ? ANDLir (1, _EAX) : POPLr(_EAX)) )
#define jitfp_getarg_f(ofs) jitfp_ldxi_f(JIT_FP,(ofs)) #define jit_fp_btest(d, s1, s2, n, _and, cmp, res) \
#define jitfp_getarg_d(ofs) jitfp_ldxi_d(JIT_FP,(ofs)) (((s1) == 0 ? FUCOMr((s2)) : (FLDr((s1)), FUCOMPr((s2) + 1))), \
#define jitfp_pusharg_d(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jitfp_str_d(JIT_SP,(op1))) PUSHLr(_EAX), \
#define jitfp_pusharg_f(op1) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jitfp_str_f(JIT_SP,(op1))) FNSTSWr(_EAX), \
#define jitfp_retval(op1) _jit_emit(&_jit, (op1), JIT_NULL, 0, 0, 0) SHRLir(n, _EAX), \
((_and) ? ANDLir ((_and), _EAX) : 0), \
((cmp) ? CMPLir ((cmp), _AL) : 0), \
POPLr(_EAX), \
res ((d), 0, 0, 0))
#define JIT_TRANSCENDENTAL #define jit_nothing_needed(x)
#define jit_sin(reg0) _OO(0xd9fe) /* fsin */ /* After FNSTSW we have 1 if <, 40 if =, 0 if >, 45 if unordered. Here
#define jit_cos(reg0) _OO(0xd9ff) /* fcos */ is how to map the values of the status word's high byte to the
#define jit_tan(reg0) (_OO(0xd9f2), /* fptan */ \ conditions.
< = > unord valid values condition
gt no no yes no 0 STSW & 45 == 0
lt yes no no no 1 STSW & 45 == 1
eq no yes no no 40 STSW & 45 == 40
unord no no no yes 45 bit 2 == 1
ge no yes no no 0, 40 bit 0 == 0
unlt yes no no yes 1, 45 bit 0 == 1
ltgt yes no yes no 0, 1 bit 6 == 0
uneq no yes no yes 40, 45 bit 6 == 1
le yes yes no no 1, 40 odd parity for STSW & 41
ungt no no yes yes 0, 45 even parity for STSW & 41
unle yes yes no yes 1, 40, 45 STSW & 45 != 0
unge no yes yes yes 0, 40, 45 STSW & 45 != 1
ne yes no yes yes 0, 1, 45 STSW & 45 != 40
ord yes yes yes no 0, 1, 40 bit 2 == 0
lt, le, ungt, unge are actually computed as gt, ge, unlt, unle with
the operands swapped; it is more efficient this way. */
#define jit_gtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETZr (_AL))
#define jit_ger_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, SBBBir (-1, _AL))
#define jit_unler_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, SETNZr (_AL))
#define jit_unltr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 9, 0, ADCBir (0, _AL))
#define jit_ltr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETZr (_AL))
#define jit_ler_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, SBBBir (-1, _AL))
#define jit_unger_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 8, 0x45, SETNZr (_AL))
#define jit_ungtr_d(d, s1, s2) jit_fp_test((d), (s2), (s1), 9, 0, ADCBir (0, _AL))
#define jit_eqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETEr (_AL)))
#define jit_ner_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 8, 0x45, (CMPBir (0x40, _AL), SETNEr (_AL)))
#define jit_ltgtr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, SBBBir (-1, _AL))
#define jit_uneqr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 15, 0, ADCBir (0, _AL))
#define jit_ordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, SBBBir (-1, _AL))
#define jit_unordr_d(d, s1, s2) jit_fp_test((d), (s1), (s2), 11, 0, ADCBir (0, _AL))
#define jit_bgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JZm)
#define jit_bger_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JNCm)
#define jit_bunler_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0, JNZm)
#define jit_bunltr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 9, 0, 0, JCm)
#define jit_bltr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JZm)
#define jit_bler_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JNCm)
#define jit_bunger_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 8, 0x45, 0, JNZm)
#define jit_bungtr_d(d, s1, s2) jit_fp_btest((d), (s2), (s1), 9, 0, 0, JCm)
#define jit_beqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JZm)
#define jit_bner_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 8, 0x45, 0x40, JNZm)
#define jit_bltgtr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JNCm)
#define jit_buneqr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 15, 0, 0, JCm)
#define jit_bordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JNCm)
#define jit_bunordr_d(d, s1, s2) jit_fp_btest((d), (s1), (s2), 11, 0, 0, JCm)
#define jit_getarg_f(rd, ofs) jit_ldxi_f((rd), JIT_FP,(ofs))
#define jit_getarg_d(rd, ofs) jit_ldxi_d((rd), JIT_FP,(ofs))
#define jit_pusharg_d(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(double)), jit_str_d(JIT_SP,(rs)))
#define jit_pusharg_f(rs) (jit_subi_i(JIT_SP,JIT_SP,sizeof(float)), jit_str_f(JIT_SP,(rs)))
#define jit_retval_d(op1) jit_movr_d(0, (op1))
#if 0
#define jit_sin() _OO(0xd9fe) /* fsin */
#define jit_cos() _OO(0xd9ff) /* fcos */
#define jit_tan() (_OO(0xd9f2), /* fptan */ \
FSTPr(0)) /* fstp st */ FSTPr(0)) /* fstp st */
#define jit_atn(reg0) (_OO(0xd9e8), /* fld1 */ \ #define jit_atn() (_OO(0xd9e8), /* fld1 */ \
_OO(0xd9f3)) /* fpatan */ _OO(0xd9f3)) /* fpatan */
#define jit_exp(reg0) (_OO(0xd9ea), /* fldl2e */ \ #define jit_exp() (_OO(0xd9ea), /* fldl2e */ \
FMULPr(1), /* fmulp */ \ FMULPr(1), /* fmulp */ \
_OO(0xd9c0), /* fld st */ \ _OO(0xd9c0), /* fld st */ \
_OO(0xd9fc), /* frndint */ \ _OO(0xd9fc), /* frndint */ \
@ -245,8 +339,9 @@
_OO(0xdec1), /* faddp */ \ _OO(0xdec1), /* faddp */ \
_OO(0xd9fd), /* fscale */ \ _OO(0xd9fd), /* fscale */ \
FSTPr(1)) /* fstp st(1) */ FSTPr(1)) /* fstp st(1) */
#define jit_log(reg0) (_OO(0xd9ed), /* fldln2 */ \ #define jit_log() (_OO(0xd9ed), /* fldln2 */ \
FXCHr(1), /* fxch st(1) */ \ FXCHr(1), /* fxch st(1) */ \
_OO(0xd9f1)) /* fyl2x */ _OO(0xd9f1)) /* fyl2x */
#endif
#endif /* __lightning_asm_h */ #endif /* __lightning_asm_h */

View file

@ -34,6 +34,57 @@
#ifndef __lightning_funcs_h #ifndef __lightning_funcs_h
#define __lightning_funcs_h #define __lightning_funcs_h
#define jit_flush_code(dest, end) #ifdef __linux__
#include <unistd.h>
#endif
static void
jit_flush_code(void *dest, void *end)
{
/* On the x86, the PROT_EXEC bits are not handled by the MMU.
However, the kernel can emulate this by setting the code
segment's limit to the end address of the highest page
whose PROT_EXEC bit is set.
Linux kernels that do so and that disable by default the
execution of the data and stack segment are becoming more
and more common (Fedora, for example), so we implement our
jit_flush_code as an mprotect. */
#ifdef __linux__
static unsigned long prev_page = 0, prev_length = 0;
int page, length;
#ifdef PAGESIZE
const int page_size = PAGESIZE;
#else
static int page_size = -1;
if (page_size == -1)
page_size = sysconf (_SC_PAGESIZE);
#endif
page = (long) dest & ~(page_size - 1);
length = ((char *) end - (char *) page + page_size - 1) & ~(page_size - 1);
/* Simple-minded attempt at optimizing the common case where a single
chunk of memory is used to compile multiple functions. */
if (page >= prev_page && page + length <= prev_page + prev_length)
return;
mprotect ((void *) page, length, PROT_READ | PROT_WRITE | PROT_EXEC);
/* See if we can extend the previously mprotect'ed memory area towards
higher addresses: the starting address remains the same as before. */
if (page >= prev_page && page <= prev_page + prev_length)
prev_length = page + length - prev_page;
/* See if we can extend the previously mprotect'ed memory area towards
lower addresses: the highest address remains the same as before. */
else if (page < prev_page && page + length <= prev_page + prev_length)
prev_length += prev_page - page, prev_page = page;
/* Nothing to do, replace the area. */
else
prev_page = page, prev_length = length;
#endif
}
#endif /* __lightning_funcs_h */ #endif /* __lightning_funcs_h */

View file

@ -61,6 +61,7 @@
typedef unsigned int jit_insn; typedef unsigned int jit_insn;
#ifndef LIGHTNING_DEBUG
#define _cr0 0 #define _cr0 0
#define _cr1 1 #define _cr1 1
#define _cr2 2 #define _cr2 2
@ -81,9 +82,9 @@ typedef unsigned int jit_insn;
/* primitive instruction forms [1, Section A.4] */ /* primitive instruction forms [1, Section A.4] */
#define _FB( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| _d26(BD)| (_u1(AA)<<1)|_u1(LK)) #define _FB( OP, BD,AA,LK ) (_jit_I_noinc((_u6(OP)<<26)| _d26(BD)| (_u1(AA)<<1)|_u1(LK)), _jit.x.pc++, 0)
#define _FBA( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| (_u26(BD)&~3)| (_u1(AA)<<1)|_u1(LK)) #define _FBA( OP, BD,AA,LK ) _jit_I((_u6(OP)<<26)| (_u26(BD)&~3)| (_u1(AA)<<1)|_u1(LK))
#define _BB( OP,BO,BI, BD,AA,LK ) _jit_I((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)| _d16(BD)| (_u1(AA)<<1)|_u1(LK)) #define _BB( OP,BO,BI, BD,AA,LK ) (_jit_I_noinc((_u6(OP)<<26)|(_u5(BO)<<21)|(_u5(BI)<<16)| _d16(BD)| (_u1(AA)<<1)|_u1(LK)), _jit.x.pc++, 0)
#define _D( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _s16(DD) ) #define _D( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _s16(DD) )
#define _Du( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _u16(DD) ) #define _Du( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _u16(DD) )
#define _Ds( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _su16(DD) ) #define _Ds( OP,RD,RA, DD ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)| _su16(DD) )
@ -93,6 +94,7 @@ typedef unsigned int jit_insn;
#define _XO( OP,RD,RA,RB,OE,XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|(_u1(OE)<<10)|( _u9(XO)<<1)|_u1(RC)) #define _XO( OP,RD,RA,RB,OE,XO,RC ) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|(_u1(OE)<<10)|( _u9(XO)<<1)|_u1(RC))
#define _M( OP,RS,RA,SH,MB,ME,RC ) _jit_I((_u6(OP)<<26)|(_u5(RS)<<21)|(_u5(RA)<<16)|( _u5(SH)<<11)|(_u5(MB)<< 6)|( _u5(ME)<<1)|_u1(RC)) #define _M( OP,RS,RA,SH,MB,ME,RC ) _jit_I((_u6(OP)<<26)|(_u5(RS)<<21)|(_u5(RA)<<16)|( _u5(SH)<<11)|(_u5(MB)<< 6)|( _u5(ME)<<1)|_u1(RC))
/* special purpose registers (form XFX) [1, Section 8.2, page 8-138] */ /* special purpose registers (form XFX) [1, Section 8.2, page 8-138] */
#define SPR_LR ((8<<5)|(0)) #define SPR_LR ((8<<5)|(0))
@ -313,10 +315,10 @@ typedef unsigned int jit_insn;
#define MOVEIri(R,I) (_siP(16,I) ? LIri(R,I) : \ #define MOVEIri(R,I) (_siP(16,I) ? LIri(R,I) : \
MOVEIri2(R, _HI(I), _LO(I)) ) MOVEIri2(R, _HI(I), _LO(I)) )
#define SUBIrri(RD,RA,IM) ADDIrri(RD,RA,-_jit_L((IM))) /* [1, Section F.2.1] */ #define SUBIrri(RD,RA,IM) ADDIrri(RD,RA,-_LO((IM))) /* [1, Section F.2.1] */
#define SUBISrri(RD,RA,IM) ADDISrri(RD,RA,-_jit_L((IM))) #define SUBISrri(RD,RA,IM) ADDISrri(RD,RA,-_LO((IM)))
#define SUBICrri(RD,RA,IM) ADDICrri(RD,RA,-_jit_L((IM))) #define SUBICrri(RD,RA,IM) ADDICrri(RD,RA,-_LO((IM)))
#define SUBIC_rri(RD,RA,IM) ADDIC_rri(RD,RA,-_jit_L((IM))) #define SUBIC_rri(RD,RA,IM) ADDIC_rri(RD,RA,-_LO((IM)))
#define SUBrrr(RD,RA,RB) SUBFrrr(RD,RB,RA) /* [1, Section F.2.2] */ #define SUBrrr(RD,RA,RB) SUBFrrr(RD,RB,RA) /* [1, Section F.2.2] */
#define SUBOrrr(RD,RA,RB) SUBFOrrr(RD,RB,RA) #define SUBOrrr(RD,RA,RB) SUBFOrrr(RD,RB,RA)
@ -350,17 +352,21 @@ typedef unsigned int jit_insn;
#define CLRRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, 0, 31-(N)) #define CLRRWIrri(RA,RS,N) RLWINMrriii(RA, RS, 0, 0, 31-(N))
#define CLRLSLWIrrii(RA,RS,B,N) RLWINMrriii(RA, RS, N, (B)-(N), 31-(N)) #define CLRLSLWIrrii(RA,RS,B,N) RLWINMrriii(RA, RS, N, (B)-(N), 31-(N))
/* 9 below inverts the branch condition and the branch prediction. /* 9 below inverts the branch condition and the branch prediction.
* This has an incestuous knowledge of the fact that register 26 * This has an incestuous knowledge of JIT_AUX */
* is used as auxiliary!!! */
#define BC_EXT(A, C, D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \ #define BC_EXT(A, C, D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
? BCiii((A), (C), (D)) \ ? BCiii((A), (C), (D)) \
: (BCiii((A)^9, (C), _jit.x.pc+5), LISri(26,_HI(D)), ORIrri(26,26,_LO(D)), \ : (BCiii((A)^9, (C), _jit.x.pc+5), \
MTLRr(26), BLR() )) LISri(JIT_AUX,_HI(D)), \
ORIrri(JIT_AUX,JIT_AUX,_LO(D)), \
MTLRr(JIT_AUX), BLR() ))
#define B_EXT(D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \ #define B_EXT(D) (_siP(16, _jit_UL(D)-_jit_UL(_jit.x.pc)) \
? Bi((D)) \ ? Bi((D)) \
: (LISri(26,_HI(D)), ORIrri(26,26,_LO(D)), MTLRr(26), BLR()) ) : (LISri(JIT_AUX,_HI(D)), \
ORIrri(JIT_AUX,JIT_AUX,_LO(D)), \
MTLRr(JIT_AUX), BLR()) )
#define BTii(C,D) BC_EXT(12, C, D) /* [1, Table F-5] */ #define BTii(C,D) BC_EXT(12, C, D) /* [1, Table F-5] */
#define BFii(C,D) BC_EXT( 4, C, D) #define BFii(C,D) BC_EXT( 4, C, D)
@ -379,7 +385,7 @@ typedef unsigned int jit_insn;
#define BLTLRi(CR) BCLRii(12, ((CR)<<2)+0) /* [1, Table F-10] */ #define BLTLRi(CR) BCLRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLELRi(CR) BCLRii( 4 ((CR)<<2)+1) #define BLELRi(CR) BCLRii( 4, ((CR)<<2)+1)
#define BEQLRi(CR) BCLRii(12, ((CR)<<2)+2) #define BEQLRi(CR) BCLRii(12, ((CR)<<2)+2)
#define BGELRi(CR) BCLRii( 4, ((CR)<<2)+0) #define BGELRi(CR) BCLRii( 4, ((CR)<<2)+0)
#define BGTLRi(CR) BCLRii(12, ((CR)<<2)+1) #define BGTLRi(CR) BCLRii(12, ((CR)<<2)+1)
@ -405,7 +411,7 @@ typedef unsigned int jit_insn;
#define BNULRLi(CR) BCLRLii( 4, ((CR)<<2)+3) #define BNULRLi(CR) BCLRLii( 4, ((CR)<<2)+3)
#define BLTCTRi(CR) BCCTRii(12, ((CR)<<2)+0) /* [1, Table F-10] */ #define BLTCTRi(CR) BCCTRii(12, ((CR)<<2)+0) /* [1, Table F-10] */
#define BLECTRi(CR) BCCTRii( 4 ((CR)<<2)+1) #define BLECTRi(CR) BCCTRii( 4, ((CR)<<2)+1)
#define BEQCTRi(CR) BCCTRii(12, ((CR)<<2)+2) #define BEQCTRi(CR) BCCTRii(12, ((CR)<<2)+2)
#define BGECTRi(CR) BCCTRii( 4, ((CR)<<2)+0) #define BGECTRi(CR) BCCTRii( 4, ((CR)<<2)+0)
#define BGTCTRi(CR) BCCTRii(12, ((CR)<<2)+1) #define BGTCTRi(CR) BCCTRii(12, ((CR)<<2)+1)
@ -511,7 +517,7 @@ typedef unsigned int jit_insn;
#define BNUi(D) BNUii(0,D) #define BNUi(D) BNUii(0,D)
#define BLTLii(C,D) BCLiii(12, ((C)<<2)+0, D) /* [1, Table F-??] */ #define BLTLii(C,D) BCLiii(12, ((C)<<2)+0, D) /* [1, Table F-??] */
#define BLELii(C,D) BCLiii( 4 ((C)<<2)+1, D) #define BLELii(C,D) BCLiii( 4, ((C)<<2)+1, D)
#define BEQLii(C,D) BCLiii(12, ((C)<<2)+2, D) #define BEQLii(C,D) BCLiii(12, ((C)<<2)+2, D)
#define BGELii(C,D) BCLiii( 4, ((C)<<2)+0, D) #define BGELii(C,D) BCLiii( 4, ((C)<<2)+0, D)
#define BGTLii(C,D) BCLiii(12, ((C)<<2)+1, D) #define BGTLii(C,D) BCLiii(12, ((C)<<2)+1, D)
@ -586,7 +592,50 @@ typedef unsigned int jit_insn;
#define _LO(I) (_jit_UL(I) & _MASK(16)) #define _LO(I) (_jit_UL(I) & _MASK(16))
#define _HI(I) (_jit_UL(I) >> (16)) #define _HI(I) (_jit_UL(I) >> (16))
#define _A(OP,RD,RA,RB,RC,XO,RCx) _jit_I((_u6(OP)<<26)|(_u5(RD)<<21)|(_u5(RA)<<16)|( _u5(RB)<<11)|_u5(RC)<<6|(_u5(XO)<<1)|_u1(RCx))
#define LFDrri(RD,RA,imm) _D(50,RD,RA,imm)
#define LFDUrri(RD,RA,imm) _D(51,RD,RA,imm)
#define LFDUxrrr(RD,RA,RB) _X(31,RD,RA,RB,631,0)
#define LFDxrrr(RD,RA,RB) _X(31,RD,RA,RB,599,0)
#define LFSrri(RD,RA,imm) _D(48,RD,RA,imm)
#define LFSUrri(RD,RA,imm) _D(49,RD,RA,imm)
#define LFSUxrrr(RD,RA,RB) _X(31,RD,RA,RB,567,0)
#define LFSxrrr(RD,RA,RB) _X(31,RD,RA,RB,535,0)
#define STFDrri(RS,RA,imm) _D(54,RS,RA,imm)
#define STFDUrri(RS,RA,imm) _D(55,RS,RA,imm)
#define STFDUxrrr(RS,RA,RB) _X(31,RS,RA,RB,759,0)
#define STFDxrrr(RS,RA,RB) _X(31,RS,RA,RB,727,0)
#define STFSrri(RS,RA,imm) _D(52,RS,RA,imm)
#define STFSUrri(RS,RA,imm) _D(53,RS,RA,imm)
#define STFSUxrrr(RS,RA,RB) _X(31,RS,RA,RB,695,0)
#define STFSxrrr(RS,RA,RB) _X(31,RS,RA,RB,663,0)
#define STFIWXrrr(RS,RA,RB) _X(31,RS,RA,RB,983,0)
#define FADDDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,21,0)
#define FADDSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,21,0)
#define FSUBDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,20,0)
#define FSUBSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,20,0)
#define FMULDrrr(RD,RA,RC) _A(63,RD,RA,0,RC,25,0)
#define FMULSrrr(RD,RA,RC) _A(59,RD,RA,0,RC,25,0)
#define FDIVDrrr(RD,RA,RB) _A(63,RD,RA,RB,0,18,0)
#define FDIVSrrr(RD,RA,RB) _A(59,RD,RA,RB,0,25,0)
#define FSQRTDrr(RD,RB) _A(63,RD,0,RB,0,22,0)
#define FSQRTSrr(RD,RB) _A(59,RD,0,RB,0,22,0)
#define FSELrrrr(RD,RA,RB,RC) _A(63,RD,RA,RB,RC,23,0)
#define FCTIWrr(RD,RB) _X(63,RD,0,RB,14,0)
#define FCTIWZrr(RD,RB) _X(63,RD,0,RB,15,0)
#define FRSPrr(RD,RB) _X(63,RD,0,RB,12,0)
#define FABSrr(RD,RB) _X(63,RD,0,RB,264,0)
#define FNABSrr(RD,RB) _X(63,RD,0,RB,136,0)
#define FNEGrr(RD,RB) _X(63,RD,0,RB,40,0)
#define FMOVErr(RD,RB) _X(63,RD,0,RB,72,0)
#define FCMPOrrr(CR,RA,RB) _X(63,_u3((CR)<<2),RA,RB,32,0)
#define FCMPUrrr(CR,RA,RB) _X(63,_u3((CR)<<2),RA,RB,0,0)
#define MTFSFIri(CR,IMM) _X(63,_u5((CR)<<2),0,_u5((IMM)<<1),134,0)
/*** References: /*** References:
* *
@ -594,4 +643,5 @@ typedef unsigned int jit_insn;
*/ */
#endif
#endif /* __ccg_asm_ppc_h */ #endif /* __ccg_asm_ppc_h */

View file

@ -36,20 +36,24 @@
#define __lightning_core_h #define __lightning_core_h
struct jit_local_state { struct jit_local_state {
int nextarg_put; /* Next r3-r8 reg. to be written */ int nextarg_puti; /* number of integer args */
int nextarg_putfp; /* Next r3-r8 reg. to be written */ int nextarg_putf; /* number of float args */
int nextarg_get; /* Next r20-r25 reg. to be read */ int nextarg_putd; /* number of double args */
int nextarg_geti; /* Next r20-r25 reg. to be read */
int nextarg_getd; /* The FP args are picked up from FPR1 -> FPR10 */
int nbArgs; /* Number of arguments for the prolog */
}; };
#define JIT_SP 1 #define JIT_SP 1
#define JIT_RET 3 #define JIT_RET 3
#define JIT_R0 9 #define JIT_R_NUM 3
#define JIT_R1 10 #define JIT_V_NUM 7
#define JIT_R2 30 /* using r8 would limit argument passing */ #define JIT_R(i) (9+(i))
#define JIT_V0 29 #define JIT_V(i) (31-(i))
#define JIT_V1 28 #define JIT_AUX JIT_V(JIT_V_NUM) /* for 32-bit operands & shift counts */
#define JIT_V2 27
#define JIT_AUX 26 /* for 32-bit operands & shift counts */ #define jit_pfx_start() (_jit.jitl.trampolines)
#define jit_pfx_end() (_jit.jitl.free)
/* If possible, use the `small' instruction (rd, rs, imm) /* If possible, use the `small' instruction (rd, rs, imm)
* else load imm into r26 and use the `big' instruction (rd, rs, r26) * else load imm into r26 and use the `big' instruction (rd, rs, r26)
@ -58,6 +62,9 @@ struct jit_local_state {
#define jit_chk_imu(imm, small, big) (_uiP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) ) #define jit_chk_imu(imm, small, big) (_uiP(16,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
#define jit_chk_imu15(imm, small, big) (_uiP(15,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) ) #define jit_chk_imu15(imm, small, big) (_uiP(15,(imm)) ? (small) : (MOVEIri(JIT_AUX, imm), (big)) )
#define jit_big_ims(imm, big) (MOVEIri(JIT_AUX, imm), (big))
#define jit_big_imu(imm, big) (MOVEIri(JIT_AUX, imm), (big))
/* Helper macros for branches */ /* Helper macros for branches */
#define jit_s_brai(rs, is, jmp) (jit_chk_ims (is, CMPWIri(rs, is), CMPWrr(rs, JIT_AUX)), jmp, _jit.x.pc) #define jit_s_brai(rs, is, jmp) (jit_chk_ims (is, CMPWIri(rs, is), CMPWrr(rs, JIT_AUX)), jmp, _jit.x.pc)
#define jit_s_brar(s1, s2, jmp) ( CMPWrr(s1, s2), jmp, _jit.x.pc) #define jit_s_brar(s1, s2, jmp) ( CMPWrr(s1, s2), jmp, _jit.x.pc)
@ -87,38 +94,48 @@ struct jit_local_state {
MULLWrrr(31, 31, JIT_AUX), SUBrrr((rs), (rs), JIT_AUX), \ MULLWrrr(31, 31, JIT_AUX), SUBrrr((rs), (rs), JIT_AUX), \
MFLRr(31)) MFLRr(31))
/* Emit a 2-instruction MOVEI, even if a 1-instruction one is possible
* (it is a rare case for branches, and a fixed sequence of instructions
* is easier to patch). */
#define jit_movei(reg, imm) (LISri(reg,_HI(imm)), ORIrri((reg),(reg),_LO(imm)))
/* Patch a movei instruction made of a LIS at lis_pc and an ORI at ori_pc. */ /* Patch a movei instruction made of a LIS at lis_pc and an ORI at ori_pc. */
#define jit_patch_movei(lis_pc, ori_pc) \ #define jit_patch_movei(lis_pc, ori_pc, dest) \
(*(lis_pc) &= ~_MASK(16), *lis_pc |= _HI(_jit.x.pc), \ (*(lis_pc) &= ~_MASK(16), *(lis_pc) |= _HI(dest), \
*(ori_pc) &= ~_MASK(16), *ori_pc |= _LO(_jit.x.pc)) \ *(ori_pc) &= ~_MASK(16), *(ori_pc) |= _LO(dest)) \
/* Patch a branch instruction */ /* Patch a branch instruction */
#define jit_patch_branch(jump_pc) \ #define jit_patch_branch(jump_pc,pv) \
(*(jump_pc) &= ~_MASK(16) | 3, \ (*(jump_pc) &= ~_MASK(16) | 3, \
*(jump_pc) |= (_jit_UL(_jit.x.pc) - _jit_UL(jump_pc)) & _MASK(16)) *(jump_pc) |= (_jit_UL(pv) - _jit_UL(jump_pc)) & _MASK(16))
#define jit_patch_ucbranch(jump_pc,pv) \
(*(jump_pc) &= ~_MASK(26) | 3, \
(*(jump_pc) |= (_jit_UL((pv)) - _jit_UL(jump_pc)) & _MASK(26)))
#define _jit_b_encoding (18 << 26)
#define _jit_blr_encoding ((19 << 26) | (20 << 21) | (00 << 16) | (00 << 11) | (16 << 1)) #define _jit_blr_encoding ((19 << 26) | (20 << 21) | (00 << 16) | (00 << 11) | (16 << 1))
#define _jit_is_ucbranch(a) (((*(a) & (63<<26)) == _jit_b_encoding))
#define jit_patch(jump_pc) ( \ #define jit_patch_at(jump_pc, value) ( \
((*(jump_pc - 1) & ~1) == _jit_blr_encoding) \ ((*(jump_pc - 1) & ~1) == _jit_blr_encoding) \
? jit_patch_movei(((jump_pc) - 4), ((jump_pc) - 3)) \ ? jit_patch_movei(((jump_pc) - 4), ((jump_pc) - 3), (value)) \
: jit_patch_branch((jump_pc) - 1)) : ( _jit_is_ucbranch((jump_pc) - 1) \
? jit_patch_ucbranch((jump_pc) - 1, (value)) \
: jit_patch_branch((jump_pc) - 1, (value))))
#define jit_patch_movi(movi_pc, val) \
jit_patch_movei((movi_pc) - 2, (movi_pc) - 1, (val))
#define jit_arg_c() (_jitl.nextarg_geti--)
#define jit_arg_i() (_jitl.nextarg_geti--)
#define jit_arg_l() (_jitl.nextarg_geti--)
#define jit_arg_p() (_jitl.nextarg_geti--)
#define jit_arg_s() (_jitl.nextarg_geti--)
#define jit_arg_uc() (_jitl.nextarg_geti--)
#define jit_arg_ui() (_jitl.nextarg_geti--)
#define jit_arg_ul() (_jitl.nextarg_geti--)
#define jit_arg_us() (_jitl.nextarg_geti--)
/* Check Mach-O-Runtime documentation: Must skip GPR(s) whenever "corresponding" FPR is used */
#define jit_arg_f() (_jitl.nextarg_geti-- ,_jitl.nextarg_getd++)
#define jit_arg_d() (_jitl.nextarg_geti-=2,_jitl.nextarg_getd++)
#define jit_arg_c() (_jitl.nextarg_get--)
#define jit_arg_i() (_jitl.nextarg_get--)
#define jit_arg_l() (_jitl.nextarg_get--)
#define jit_arg_p() (_jitl.nextarg_get--)
#define jit_arg_s() (_jitl.nextarg_get--)
#define jit_arg_uc() (_jitl.nextarg_get--)
#define jit_arg_ui() (_jitl.nextarg_get--)
#define jit_arg_ul() (_jitl.nextarg_get--)
#define jit_arg_us() (_jitl.nextarg_get--)
#define jit_addi_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDrrr((d), (rs), JIT_AUX)) #define jit_addi_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDrrr((d), (rs), JIT_AUX))
#define jit_addr_i(d, s1, s2) ADDrrr((d), (s1), (s2)) #define jit_addr_i(d, s1, s2) ADDrrr((d), (s1), (s2))
#define jit_addci_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDCrrr((d), (rs), JIT_AUX)) #define jit_addci_i(d, rs, is) jit_chk_ims((is), ADDICrri((d), (rs), (is)), ADDCrrr((d), (rs), JIT_AUX))
@ -159,9 +176,10 @@ struct jit_local_state {
#define jit_bosubi_ui(label, rs, is) (jit_chk_ims ((is), SUBICri((rs), (rs), is), SUBCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc) #define jit_bosubi_ui(label, rs, is) (jit_chk_ims ((is), SUBICri((rs), (rs), is), SUBCrr((rs), JIT_AUX)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_boaddr_ui(label, s1, s2) ( ADDCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc) #define jit_boaddr_ui(label, s1, s2) ( ADDCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_bosubr_ui(label, s1, s2) ( SUBCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc) #define jit_bosubr_ui(label, s1, s2) ( SUBCrr((s1), (s1), (s2)), MCRXRi(0), BEQi((label)), _jit.x.pc)
#define jit_calli(label) (jit_movei(JIT_AUX, (label)), MTLRr(JIT_AUX), BLRL(), _jit.x.pc) #define jit_calli(label) (jit_movi_p(JIT_AUX, (label)), MTCTRr(JIT_AUX), BCTRL(), _jitl.nextarg_puti = _jitl.nextarg_putf = _jitl.nextarg_putd = 0, _jit.x.pc)
#define jit_divi_i(d, rs, is) jit_chk_ims(1111111, 0, DIVWrrr ((d), (rs), JIT_AUX)) #define jit_callr(reg) (MTCTRr(reg), BCTRL())
#define jit_divi_ui(d, rs, is) jit_chk_imu(1111111, 0, DIVWUrrr((d), (rs), JIT_AUX)) #define jit_divi_i(d, rs, is) jit_big_ims((is), DIVWrrr ((d), (rs), JIT_AUX))
#define jit_divi_ui(d, rs, is) jit_big_imu((is), DIVWUrrr((d), (rs), JIT_AUX))
#define jit_divr_i(d, s1, s2) DIVWrrr ((d), (s1), (s2)) #define jit_divr_i(d, s1, s2) DIVWrrr ((d), (s1), (s2))
#define jit_divr_ui(d, s1, s2) DIVWUrrr((d), (s1), (s2)) #define jit_divr_ui(d, s1, s2) DIVWUrrr((d), (s1), (s2))
#define jit_eqi_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX)) #define jit_eqi_i(d, rs, is) (jit_chk_ims((is), SUBIrri(JIT_AUX, (rs), (is)), SUBrrr(JIT_AUX, (rs), JIT_AUX)), SUBFICrri((d), JIT_AUX, 0), ADDErrr((d), (d), JIT_AUX))
@ -176,8 +194,8 @@ struct jit_local_state {
#define jit_gti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _gt) #define jit_gti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _gt)
#define jit_gtr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _gt) #define jit_gtr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _gt)
#define jit_gtr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _gt) #define jit_gtr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _gt)
#define jit_hmuli_i(d, rs, is) jit_chk_ims(1111111, 0, MULHWrrr ((d), (rs), JIT_AUX)) #define jit_hmuli_i(d, rs, is) jit_big_ims((is), MULHWrrr ((d), (rs), JIT_AUX))
#define jit_hmuli_ui(d, rs, is) jit_chk_imu(1111111, 0, MULHWUrrr((d), (rs), JIT_AUX)) #define jit_hmuli_ui(d, rs, is) jit_big_imu((is), MULHWUrrr((d), (rs), JIT_AUX))
#define jit_hmulr_i(d, s1, s2) MULHWrrr ((d), (s1), (s2)) #define jit_hmulr_i(d, s1, s2) MULHWrrr ((d), (s1), (s2))
#define jit_hmulr_ui(d, s1, s2) MULHWUrrr((d), (s1), (s2)) #define jit_hmulr_ui(d, s1, s2) MULHWUrrr((d), (s1), (s2))
#define jit_jmpi(label) (B_EXT((label)), _jit.x.pc) #define jit_jmpi(label) (B_EXT((label)), _jit.x.pc)
@ -197,16 +215,18 @@ struct jit_local_state {
#define jit_ler_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _gt ) #define jit_ler_i(d, s1, s2) jit_sboolr2((d), (s1), (s2), _gt )
#define jit_ler_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _gt ) #define jit_ler_ui(d, s1, s2) jit_uboolr2((d), (s1), (s2), _gt )
#define jit_lshi_i(d, rs, is) SLWIrri((d), (rs), (is)) #define jit_lshi_i(d, rs, is) SLWIrri((d), (rs), (is))
#define jit_lshr_i(d, s1, s2) (ANDIrri(JIT_AUX, (s2), 31), SLWrrr ((d), (s1), JIT_AUX)) #define jit_lshr_i(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SLWrrr ((d), (s1), JIT_AUX))
#define jit_lti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _lt ) #define jit_lti_i(d, rs, is) jit_sbooli ((d), (rs), (is), _lt )
#define jit_lti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _lt ) #define jit_lti_ui(d, rs, is) jit_ubooli ((d), (rs), (is), _lt )
#define jit_ltr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _lt ) #define jit_ltr_i(d, s1, s2) jit_sboolr ((d), (s1), (s2), _lt )
#define jit_ltr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _lt ) #define jit_ltr_ui(d, s1, s2) jit_uboolr ((d), (s1), (s2), _lt )
#define jit_modi_i(d, rs, is) _jit_mod(jit_divi_i (31, (rs), JIT_AUX), (is)) #define jit_modi_i(d, rs, is) _jit_mod(jit_divi_i (31, (rs), JIT_AUX), (rs), (is))
#define jit_modi_ui(d, rs, is) _jit_mod(jit_divi_ui(31, (rs), JIT_AUX), (irs)) #define jit_modi_ui(d, rs, is) _jit_mod(jit_divi_ui(31, (rs), JIT_AUX), (rs), (is))
#define jit_modr_i(d, s1, s2) (DIVWrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX)) #define jit_modr_i(d, s1, s2) (DIVWrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
#define jit_modr_ui(d, s1, s2) (DIVWUrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX)) #define jit_modr_ui(d, s1, s2) (DIVWUrrr(JIT_AUX, (s1), (s2)), MULLWrrr(JIT_AUX, JIT_AUX, (s2)), SUBrrr((d), (s1), JIT_AUX))
#define jit_movi_i(d, is) MOVEIri((d), (is)) #define jit_movi_i(d, is) MOVEIri((d), (is))
#define jit_movi_p(d, is) (LISri((d), _HI((is))),ORIrri((d),(d),_LO((is))),_jit.x.pc)
#define jit_movr_i(d, rs) MRrr((d), (rs)) #define jit_movr_i(d, rs) MRrr((d), (rs))
#define jit_muli_i(d, rs, is) jit_chk_ims ((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX)) #define jit_muli_i(d, rs, is) jit_chk_ims ((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
#define jit_muli_ui(d, rs, is) jit_chk_imu15((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX)) #define jit_muli_ui(d, rs, is) jit_chk_imu15((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
@ -218,17 +238,19 @@ struct jit_local_state {
#define jit_ori_i(d, rs, is) jit_chk_imu((is), ORIrri((d), (rs), (is)), ORrrr((d), (rs), JIT_AUX)) #define jit_ori_i(d, rs, is) jit_chk_imu((is), ORIrri((d), (rs), (is)), ORrrr((d), (rs), JIT_AUX))
#define jit_orr_i(d, s1, s2) ORrrr((d), (s1), (s2)) #define jit_orr_i(d, s1, s2) ORrrr((d), (s1), (s2))
#define jit_popr_i(rs) (LWZrm((rs), 0, 1), ADDIrri(1, 1, 4)) #define jit_popr_i(rs) (LWZrm((rs), 0, 1), ADDIrri(1, 1, 4))
#define jitfp_prepare(numi, numf, numd) (_jitl.nextarg_put = 3 + (numi) + (numf) + 2*(numd)) #define jit_prepare_i(numi) (_jitl.nextarg_puti = numi)
#define jit_prepare_f(numf) (_jitl.nextarg_putf = numf)
#define jit_prepare_d(numd) (_jitl.nextarg_putd = numd)
#define jit_prolog(n) _jit_prolog(&_jit, (n)) #define jit_prolog(n) _jit_prolog(&_jit, (n))
#define jit_pushr_i(rs) STWUrm((rs), -4, 1) #define jit_pushr_i(rs) STWUrm((rs), -4, 1)
#define jit_pusharg_i(rs) (--_jitl.nextarg_put, MRrr(_jitl.nextarg_put, (rs))) #define jit_pusharg_i(rs) (--_jitl.nextarg_puti, MRrr((3 + _jitl.nextarg_putd * 2 + _jitl.nextarg_putf + _jitl.nextarg_puti), (rs)))
#define jit_ret() jit_jmpr(31) #define jit_ret() _jit_epilog(&_jit)
#define jit_retval(rd) MRrr((rd), 3) #define jit_retval_i(rd) MRrr((rd), 3)
#define jit_rsbi_i(d, rs, is) jit_chk_ims((is), SUBFICrri((d), (rs), (is)), SUBFCrrr((d), (rs), JIT_AUX)) #define jit_rsbi_i(d, rs, is) jit_chk_ims((is), SUBFICrri((d), (rs), (is)), SUBFCrrr((d), (rs), JIT_AUX))
#define jit_rshi_i(d, rs, is) SRAWIrri((d), (rs), (is)) #define jit_rshi_i(d, rs, is) SRAWIrri((d), (rs), (is))
#define jit_rshi_ui(d, rs, is) SRWIrri ((d), (rs), (is)) #define jit_rshi_ui(d, rs, is) SRWIrri ((d), (rs), (is))
#define jit_rshr_i(d, s1, s2) (ANDIrrr(JIT_AUX, (s2), 31), SRAWrrr ((d), (s1), JIT_AUX)) #define jit_rshr_i(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SRAWrrr ((d), (s1), JIT_AUX))
#define jit_rshr_ui(d, s1, s2) (ANDIrrr(JIT_AUX, (s2), 31), SRWrrr ((d), (s1), JIT_AUX)) #define jit_rshr_ui(d, s1, s2) (ANDI_rri(JIT_AUX, (s2), 31), SRWrrr ((d), (s1), JIT_AUX))
#define jit_stxi_c(id, rd, rs) jit_chk_ims((id), STBrm((rs), (id), (rd)), STBrx((rs), (rd), JIT_AUX)) #define jit_stxi_c(id, rd, rs) jit_chk_ims((id), STBrm((rs), (id), (rd)), STBrx((rs), (rd), JIT_AUX))
#define jit_stxi_i(id, rd, rs) jit_chk_ims((id), STWrm((rs), (id), (rd)), STWrx((rs), (rd), JIT_AUX)) #define jit_stxi_i(id, rd, rs) jit_chk_ims((id), STWrm((rs), (id), (rd)), STWrx((rs), (rd), JIT_AUX))
#define jit_stxi_s(id, rd, rs) jit_chk_ims((id), STHrm((rs), (id), (rd)), STHrx((rs), (rd), JIT_AUX)) #define jit_stxi_s(id, rd, rs) jit_chk_ims((id), STHrm((rs), (id), (rd)), STHrx((rs), (rd), JIT_AUX))
@ -237,7 +259,7 @@ struct jit_local_state {
#define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2)) #define jit_stxr_s(d1, d2, rs) STHrx((rs), (d1), (d2))
#define jit_subr_i(d, s1, s2) SUBrrr((d), (s1), (s2)) #define jit_subr_i(d, s1, s2) SUBrrr((d), (s1), (s2))
#define jit_subcr_i(d, s1, s2) SUBCrrr((d), (s1), (s2)) #define jit_subcr_i(d, s1, s2) SUBCrrr((d), (s1), (s2))
#define jit_subxi_i(d, rs, is) jit_chk_ims(111111111, 0, SUBErrr((d), (rs), JIT_AUX)) #define jit_subxi_i(d, rs, is) jit_big_ims((is), SUBErrr((d), (rs), JIT_AUX))
#define jit_subxr_i(d, s1, s2) SUBErrr((d), (s1), (s2)) #define jit_subxr_i(d, s1, s2) SUBErrr((d), (s1), (s2))
#define jit_xori_i(d, rs, is) jit_chk_imu((is), XORIrri((d), (rs), (is)), XORrrr((d), (rs), JIT_AUX)) #define jit_xori_i(d, rs, is) jit_chk_imu((is), XORIrri((d), (rs), (is)), XORrrr((d), (rs), JIT_AUX))
#define jit_xorr_i(d, s1, s2) XORrrr((d), (s1), (s2)) #define jit_xorr_i(d, s1, s2) XORrrr((d), (s1), (s2))

View file

@ -35,70 +35,177 @@
#ifndef __lightning_asm_fp_h #ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h #define __lightning_asm_fp_h
#if 0
/* dummy for now */ #define JIT_FPR_NUM 6
#define JIT_FPR(i) (8+(i))
#define jit_add_two(reg0) FADDrrr(13 - (reg0), 13 - (reg0), 12 - (reg0)) #define JIT_FPFR 0
#define jit_sub_two(reg0) FSUBrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
#define jit_mul_two(reg0) FMULrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
#define jit_div_two(reg0) FDIVrrr(13 - (reg0), 13 - (reg0), 12 - (reg0))
#define jit_abs(reg0) FABSr(13 - (reg0))
#define jit_sqrt(reg0) FSQRTr(13 - (reg0))
#define jit_neg(reg0) FNEGr(13 - (reg0))
#define jit_ldxi_f(reg0, rs, is) 0
#define jit_ldxr_f(reg0, s1, s2) 0
#define jit_ldxi_d(reg0, rs, is) 0
#define jit_ldxr_d(reg0, s1, s2) 0
#define jit_ldi_f(reg0, is) 0
#define jit_ldr_f(reg0, rs) 0
#define jit_ldi_d(reg0, is) 0
#define jit_ldr_d(reg0, rs) 0
#define jit_stxi_f(id, rd, reg0) 0
#define jit_stxr_f(d1, d2, reg0) 0
#define jit_stxi_d(id, rd, reg0) 0
#define jit_stxr_d(d1, d2, reg0) 0
#define jit_sti_f(id, reg0) 0
#define jit_str_f(rd, reg0) 0
#define jit_sti_d(id, reg0) 0
#define jit_str_d(rd, reg0) 0
/* Make space for 1 or 2 words, store address in REG */ /* Make space for 1 or 2 words, store address in REG */
#define jit_data(REG, D1) (_FBA (18, 8, 0, 1), _jit_L(D1), MFLRr(REG)) #define jit_data(REG, D1) (_FBA (18, 8, 0, 1), _jit_L(D1), MFLRr(REG))
#define jit_data2(REG, D1, D2) (_FBA (18, 12, 0, 1), _jit_L(D1), _jit_L(D2), MFLRr(REG))
#define jit_fpimm(reg0, first, second) \ #define jit_addr_d(rd,s1,s2) FADDDrrr((rd),(s1),(s2))
(jit_data2(JIT_AUX, (first), (second)), \ #define jit_subr_d(rd,s1,s2) FSUBDrrr((rd),(s1),(s2))
jit_ldxi_d((reg0), JIT_AUX, 0)) #define jit_mulr_d(rd,s1,s2) FMULDrrr((rd),(s1),(s2))
#define jit_divr_d(rd,s1,s2) FDIVDrrr((rd),(s1),(s2))
#define jit_floor(rd, reg0) jit_call_fp((rd), (reg0), floor) #define jit_addr_f(rd,s1,s2) FADDSrrr((rd),(s1),(s2))
#define jit_ceil(rd, reg0) jit_call_fp((rd), (reg0), ceil) #define jit_subr_f(rd,s1,s2) FSUBSrrr((rd),(s1),(s2))
#define jit_mulr_f(rd,s1,s2) FMULSrrr((rd),(s1),(s2))
#define jit_divr_f(rd,s1,s2) FDIVSrrr((rd),(s1),(s2))
#define jit_call_fp(rd, reg0, fn) \ #define jit_movr_d(rd,rs) ( (rd) == (rs) ? 0 : FMOVErr((rd),(rs)))
jit_fail(#fn " not supported", __FILE__, __LINE__, __FUNCTION__) #define jit_movi_d(reg0,d) do { \
/* pass reg0 as first parameter of rd double _v = (d); \
bl fn _FBA (18, 12, 0, 1); \
mr r3, rd */ memcpy(_jit.x.uc_pc, &_v, sizeof (double)); \
_jit.x.uc_pc += sizeof (double); \
MFLRr (JIT_AUX); \
jit_ldxi_d((reg0), JIT_AUX, 0); \
} while(0)
#define jit_trunc(rd, reg0) (jit_data((rd), 0), \
FCTIWZrr(13 - (reg0), 13 - (reg0)), \
STFIWXrrr(13 - (reg0), 0, (rd)), \
LWZrm((rd), 0, (rd)))
#define jit_round(rd, reg0) (jit_data((rd), 0), \ #define jit_movr_f(rd,rs) ( (rd) == (rs) ? 0 : FMOVErr((rd),(rs)))
FCTIWrr(13 - (reg0), 13 - (reg0)), \ #define jit_movi_f(reg0,f) do { \
STFIWXrrr(13 - (reg0), 0, (rd)), \ float _v = (f); \
LWZrm((rd), 0, (rd))) _FBA (18, 8, 0, 1); \
memcpy(_jit.x.uc_pc, &_v, sizeof (float)); \
_jit.x.uc_pc += sizeof (float); \
MFLRr (JIT_AUX); \
jit_ldxi_f((reg0), JIT_AUX, 0); \
} while(0)
#define jit_cmp(le, ge, reg0) (FCMPOirr(7, 13 - (reg0), 0), \
CRORiii(28 + _gt, 28 + _gt, 28 + _eq), \
CRORiii(28 + _lt, 28 + _lt, 28 + _eq), \
MFCRr((ge)), \
EXTRWIrrii((le), (ge), 1, 28 + _lt), \
EXTRWIrrii((ge), (ge), 1, 28 + _gt))
#endif #define jit_abs_d(rd,rs) FABSrr((rd),(rs))
#define jit_negr_d(rd,rs) FNEGrr((rd),(rs))
#define jit_sqrt_d(rd,rs) FSQRTDrr((rd),(rs))
#define jit_ldxi_f(reg0, rs, is) (_siP(16,(is)) ? LFSrri((reg0),(rs),(is)) : (MOVEIri(JIT_AUX,(is)),LFSxrrr((reg0),(rs),JIT_AUX)))
#define jit_ldxi_d(reg0, rs, is) (_siP(16,(is)) ? LFDrri((reg0),(rs),(is)) : (MOVEIri(JIT_AUX,(is)),LFDxrrr((reg0),(rs),JIT_AUX)))
#define jit_ldxr_f(reg0, s1, s2) LFSxrrr((reg0),(s1),(s2))
#define jit_ldxr_d(reg0, s1, s2) LFDxrrr((reg0),(s1),(s2))
#define jit_ldi_f(reg0, is) (_siP(16,(is)) ? LFSrri((reg0),0,(is)) : (MOVEIri(JIT_AUX,(is)),LFSrri((reg0),JIT_AUX,0)))
#define jit_ldi_d(reg0, is) (_siP(16,(is)) ? LFDrri((reg0),0,(is)) : (MOVEIri(JIT_AUX,(is)),LFDrri((reg0),JIT_AUX,0)))
#define jit_ldr_f(reg0, rs) LFSrri((reg0),(rs),0)
#define jit_ldr_d(reg0, rs) LFDrri((reg0),(rs),0)
#define jit_stxi_f(id, rd, reg0) (_siP(16,(id)) ? STFSrri((reg0),(rd),(id)) : (MOVEIri(JIT_AUX,(id)),STFSrri((reg0),(rd),JIT_AUX)))
#define jit_stxi_d(id, rd, reg0) (_siP(16,(id)) ? STFDrri((reg0),(rd),(id)) : (MOVEIri(JIT_AUX,(id)),STFDrri((reg0),(rd),JIT_AUX)))
#define jit_stxr_f(d1, d2, reg0) STFSxrrr((reg0),(d1),(d2))
#define jit_stxr_d(d1, d2, reg0) STFDxrrr((reg0),(d1),(d2))
#define jit_sti_f(id, reg0) (_siP(16,(id)) ? STFSrri((reg0),0,(id)) : (MOVEIri(JIT_AUX,(id)),STFSrri((reg0),JIT_AUX,0)))
#define jit_sti_d(id, reg0) (_siP(16,(id)) ? STFDrri((reg0),0,(id)) : (MOVEIri(JIT_AUX,(id)),STFDrri((reg0),JIT_AUX,0)))
#define jit_str_f(rd, reg0) STFSrri((reg0),(rd),0)
#define jit_str_d(rd, reg0) STFDrri((reg0),(rd),0)
#define jit_fpboolr(d, s1, s2, rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)))
#define jit_fpboolr_neg(d, s1, s2,rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)), \
XORIrri((d), (d), 1))
#define jit_fpboolur(d, s1, s2, rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)))
#define jit_fpboolur_neg(d, s1, s2,rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (rcbit)), \
XORIrri((d), (d), 1))
#define jit_fpboolur_or(d, s1, s2, bit1, bit2) (\
FCMPUrrr(_cr0,(s1),(s2)), \
CRORiii((bit1), (bit1), (bit2)), \
MFCRr((d)), \
EXTRWIrrii((d), (d), 1, (bit1)))
#define jit_gtr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_gt)
#define jit_ger_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_lt)
#define jit_ltr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_lt)
#define jit_ler_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_gt)
#define jit_eqr_d(d, s1, s2) jit_fpboolr ((d),(s1),(s2),_eq)
#define jit_ner_d(d, s1, s2) jit_fpboolr_neg((d),(s1),(s2),_eq)
#define jit_unordr_d(d, s1, s2) jit_fpboolur ((d),(s1),(s2),_un)
#define jit_ordr_d(d, s1, s2) jit_fpboolur_neg((d),(s1),(s2),_un)
#define jit_unler_d(d, s1, s2) jit_fpboolur_neg ((d), (s1), (s2), _gt)
#define jit_unltr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _lt)
#define jit_unger_d(d, s1, s2) jit_fpboolur_neg ((d), (s1), (s2), _lt)
#define jit_ungtr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _gt)
#define jit_ltgtr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _gt, _lt)
#define jit_uneqr_d(d, s1, s2) jit_fpboolur_or ((d), (s1), (s2), _un, _eq)
#define jit_fpbr(d, s1, s2, rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
BTii ((rcbit), (d)))
#define jit_fpbr_neg(d, s1, s2,rcbit) ( \
FCMPOrrr(_cr0,(s1),(s2)), \
BFii ((rcbit), (d)))
#define jit_fpbur(d, s1, s2, rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
BTii ((rcbit), (d)))
#define jit_fpbur_neg(d, s1, s2,rcbit) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
BFii ((rcbit), (d)))
#define jit_fpbur_or(d, s1, s2, bit1, bit2) ( \
FCMPUrrr(_cr0,(s1),(s2)), \
CRORiii((bit1), (bit1), (bit2)), \
BTii ((bit1), (d)))
#define jit_bgtr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_gt)
#define jit_bger_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_lt)
#define jit_bltr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_lt)
#define jit_bler_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_gt)
#define jit_beqr_d(d, s1, s2) jit_fpbr ((d),(s1),(s2),_eq)
#define jit_bner_d(d, s1, s2) jit_fpbr_neg((d),(s1),(s2),_eq)
#define jit_bunordr_d(d, s1, s2) jit_fpbur ((d),(s1),(s2),_un)
#define jit_bordr_d(d, s1, s2) jit_fpbur_neg((d),(s1),(s2),_un)
#define jit_bunler_d(d, s1, s2) jit_fpbur_neg ((d), (s1), (s2), _gt)
#define jit_bunltr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _lt)
#define jit_bunger_d(d, s1, s2) jit_fpbur_neg ((d), (s1), (s2), _lt)
#define jit_bungtr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _gt)
#define jit_bltgtr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _gt, _lt)
#define jit_buneqr_d(d, s1, s2) jit_fpbur_or ((d), (s1), (s2), _un, _eq)
#define jit_getarg_f(rd, ofs) jit_movr_f((rd),(ofs))
#define jit_getarg_d(rd, ofs) jit_movr_d((rd),(ofs))
#define jit_pusharg_d(rs) (_jitl.nextarg_putd--,jit_movr_d((_jitl.nextarg_putf+_jitl.nextarg_putd+1), (rs)))
#define jit_pusharg_f(rs) (_jitl.nextarg_putf--,jit_movr_f((_jitl.nextarg_putf+_jitl.nextarg_putd+1), (rs)))
#define jit_retval_d(op1) jit_movr_d(1, (op1))
#define jit_retval_f(op1) jit_movr_f(1, (op1))
#define jit_floorr_d_i(rd,rs) (MTFSFIri(7,3), \
FCTIWrr(31,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(31,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_ceilr_d_i(rd,rs) (MTFSFIri(7,2), \
FCTIWrr(31,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(31,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_roundr_d_i(rd,rs) (MTFSFIri(7,0), \
FCTIWrr(31,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(31,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#define jit_truncr_d_i(rd,rs) (FCTIWZrr(31,(rs)), \
MOVEIri(JIT_AUX,-4), \
STFIWXrrr(31,JIT_SP,JIT_AUX), \
LWZrm((rd),-4,JIT_SP))
#endif /* __lightning_asm_h */ #endif /* __lightning_asm_h */

View file

@ -7,7 +7,7 @@
/*********************************************************************** /***********************************************************************
* *
* Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. * Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini. * Written by Paolo Bonzini.
* *
* This file is part of GNU lightning. * This file is part of GNU lightning.
@ -69,13 +69,13 @@ jit_flush_code(void *start, void *end)
end -= ((long) end) & (cache_line_size - 1); end -= ((long) end) & (cache_line_size - 1);
/* Force data cache write-backs */ /* Force data cache write-backs */
for (ddest = start; ddest <= (char *) end; ddest += cache_line_size) { for (ddest = (char *) start; ddest <= (char *) end; ddest += cache_line_size) {
__asm__ __volatile__ ("dcbst 0,%0" : : "r"(ddest)); __asm__ __volatile__ ("dcbst 0,%0" : : "r"(ddest));
} }
__asm__ __volatile__ ("sync" : : ); __asm__ __volatile__ ("sync" : : );
/* Now invalidate the instruction cache */ /* Now invalidate the instruction cache */
for (idest = start; idest <= (char *) end; idest += cache_line_size) { for (idest = (char *) start; idest <= (char *) end; idest += cache_line_size) {
__asm__ __volatile__ ("icbi 0,%0" : : "r"(idest)); __asm__ __volatile__ ("icbi 0,%0" : : "r"(idest));
} }
__asm__ __volatile__ ("isync" : : ); __asm__ __volatile__ ("isync" : : );
@ -85,75 +85,78 @@ jit_flush_code(void *start, void *end)
#define _jit (*jit) #define _jit (*jit)
/* Emit a trampoline for a function. static void
* Upon entrance to the trampoline: _jit_epilog(jit_state *jit)
* - R0 = return address for the function
* - LR = address where the real code for the function lies
* - R3-R8 = parameters
* After jumping to the address pointed to by R10:
* - LR = address where the epilog lies (the function must return there)
* - R25-R20 = parameters (order is reversed, 1st argument is R25)
*/
static jit_insn *
_jit_trampoline(jit, n)
register jit_state *jit;
register int n;
{ {
static jit_insn trampolines[200]; int n = _jitl.nbArgs;
static jit_insn *p_trampolines[6], *free = trampolines; int frame_size, i, ofs;
jit_insn *trampo; int first_saved_reg = JIT_AUX - n;
int i, ofs, frame_size; int num_saved_regs = 32 - first_saved_reg;
if (!p_trampolines[n]) { frame_size = 24 + 32 + num_saved_regs * 4; /* r24..r31 + args */
_jit.x.pc = trampo = p_trampolines[n] = free;
frame_size = 24 + (6 + n) * 4; /* r26..r31 + args */
frame_size += 15; /* the stack must be quad-word */ frame_size += 15; /* the stack must be quad-word */
frame_size &= ~15; /* aligned */ frame_size &= ~15; /* aligned */
STWUrm(1, -frame_size, 1); /* stwu r1, -x(r1) */ #ifdef _CALL_DARWIN
LWZrm(0, frame_size + 8, 1); /* lwz r0, x+8(r1) (ret.addr.) */
for (ofs = frame_size - (6 + n) * 4, i = 26 - n; i <= 31; ofs += 4, i++) { #else
STWrm(i, ofs, 1); /* stw rI, ofs(r1) */ LWZrm(0, frame_size + 4, 1); /* lwz r0, x+4(r1) (ret.addr.) */
} #endif
STWrm(0, ofs+4, 1); /* stw r0, x(r1) */
for (i = 0; i < n; i++) {
MRrr(25-i, 3+i); /* save parameters in r25..r20 */
}
BLRL(); /* blrl */
LWZrm(0, ofs+4, 1); /* lwz r0, x(r1) (ret.addr.) */
MTLRr(0); /* mtspr LR, r0 */ MTLRr(0); /* mtspr LR, r0 */
for (ofs = frame_size - (6 + n) * 4, i = 26 - n; i <= 31; ofs += 4, i++) { ofs = frame_size - num_saved_regs * 4;
LWZrm(i, ofs, 1); /* lwz rI, ofs(r1) */ LMWrm(first_saved_reg, ofs, 1); /* lmw rI, ofs(r1) */
}
ADDIrri(1, 1, frame_size); /* addi r1, r1, x */ ADDIrri(1, 1, frame_size); /* addi r1, r1, x */
BLR(); /* blr */ BLR(); /* blr */
jit_flush_code(trampo, _jit.x.pc);
free = _jit.x.pc;
}
return p_trampolines[n];
} }
/* Emit a prolog for a function.
Upon entrance to the trampoline:
- LR = address where the real code for the function lies
- R3-R8 = parameters
Upon finishing the trampoline:
- R0 = return address for the function
- R25-R20 = parameters (order is reversed, 1st argument is R25)
The +32 in frame_size computation is to accound for the parameter area of
a function frame.
On PPC the frame must have space to host the arguments of any callee.
However, as it currently stands, the argument to jit_trampoline (n) is
the number of arguments of the caller we generate. Therefore, the
callee can overwrite a part of the stack (saved register area when it
flushes its own parameter on the stack. The addition of a constant
offset = 32 is enough to hold eight 4 bytes arguments. This is less
than perfect but is a reasonable work around for now.
Better solution must be investigated. */
static void static void
_jit_prolog(jit, n) _jit_prolog(jit_state *jit, int n)
register jit_state *jit;
register int n;
{ {
register jit_insn *save_pc, *trampo; int frame_size;
int ofs, i;
int first_saved_reg = JIT_AUX - n;
int num_saved_regs = 32 - first_saved_reg;
save_pc = _jit.x.pc; _jitl.nextarg_geti = JIT_AUX - 1;
trampo = _jit_trampoline(jit, n); _jitl.nextarg_getd = 1;
_jit.x.pc = save_pc; _jitl.nbArgs = n;
frame_size = 24 + 32 + num_saved_regs * 4; /* r27..r31 + args */
frame_size += 15; /* the stack must be quad-word */
frame_size &= ~15; /* aligned */
_jitl.nextarg_get = 25;
MFLRr(0); MFLRr(0);
MOVEIri(10, trampo); STWUrm(1, -frame_size, 1); /* stwu r1, -x(r1) */
MTLRr(10);
BLRL(); /* blrl */ ofs = frame_size - num_saved_regs * 4;
MFLRr(31); /* mflr r31 */ STMWrm(first_saved_reg, ofs, 1); /* stmw rI, ofs(r1) */
#ifdef _CALL_DARWIN
STWrm(0, frame_size + 8, 1); /* stw r0, x+8(r1) */
#else
STWrm(0, frame_size + 4, 1); /* stw r0, x+4(r1) */
#endif
for (i = 0; i < n; i++)
MRrr(JIT_AUX-1-i, 3+i); /* save parameters below r24 */
} }
#undef _jit #undef _jit

View file

@ -49,6 +49,7 @@
typedef unsigned int jit_insn; typedef unsigned int jit_insn;
#ifndef LIGHTNING_DEBUG
#define _d30(BD) ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2) #define _d30(BD) ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2)
#define _d22(BD) _ck_d(22, _d30(BD)) #define _d22(BD) _ck_d(22, _d30(BD))
@ -82,6 +83,9 @@ typedef unsigned int jit_insn;
#define _3( RD, OP3, RS1, I, ASI, RS2) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2)) #define _3( RD, OP3, RS1, I, ASI, RS2) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)|(_u8(ASI)<<5)|_u5 (RS2))
#define _3i(RD, OP3, RS1, I, IMM) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM)) #define _3i(RD, OP3, RS1, I, IMM) _jit_I((3<<30)| (_u5(RD)<<25)|(_u6(OP3)<<19)|(_u5(RS1)<<14)|(_u1(I)<<13)| _s13(IMM))
#define _FP1(RD, RS1, OPF, RS2) _2f((RD), 52, (RS1), (OPF), (RS2))
#define _FP2(RD, RS1, OPF, RS2) _2f((RD), 53, (RS1), (OPF), (RS2))
/* basic instructions [Section B, page 87] */ /* basic instructions [Section B, page 87] */
#define ADDrrr(RS1, RS2, RD) _2 ((RD), 0, (RS1), 0, 0, (RS2)) #define ADDrrr(RS1, RS2, RD) _2 ((RD), 0, (RS1), 0, 0, (RS2))
@ -300,4 +304,80 @@ typedef unsigned int jit_insn;
#define WRii(IMM, RD) WRrii(0, (IMM), (RD)) #define WRii(IMM, RD) WRrii(0, (IMM), (RD))
#define WRri(RS2, RD) WRrri(0, (RS2), (RD)) #define WRri(RS2, RD) WRrri(0, (RS2), (RD))
#define LDFSRx(RS1, RS2) _3 (0, 33, (RS1), 0, 0, (RS2))
#define LDFSRm(RS1, IMM) _3i (0, 33, (RS1), 1, (IMM))
#define STFSRx(RD1, RD2) _3 (0, 37, (RD1), 0, 0, (RD2))
#define STFSRm(RD, IMM) _3i (0, 37, (RD), 1, (IMM))
#define FITODrr(FRS, FRD) _FP1((FRD), 0, 200, (FRS))
#define FITOSrr(FRS, FRD) _FP1((FRD), 0, 196, (FRS))
#define FDTOIrr(FRS, FRD) _FP1((FRD), 0, 210, (FRS))
#define FSTOIrr(FRS, FRD) _FP1((FRD), 0, 209, (FRS))
#define FSTODrr(FRS, FRD) _FP1((FRD), 0, 201, (FRS))
#define FDTOSrr(FRS, FRD) _FP1((FRD), 0, 198, (FRS))
#define FMOVSrr(FRS, FRD) _FP1((FRD), 0, 1, (FRS))
#define FNEGSrr(FRS, FRD) _FP1((FRD), 0, 5, (FRS))
#define FABSSrr(FRS, FRD) _FP1((FRD), 0, 9, (FRS))
#define FMOVDrr(FRS, FRD) _FP1((FRD), 0, 2, (FRS))
#define FNEGDrr(FRS, FRD) _FP1((FRD), 0, 6, (FRS))
#define FABSDrr(FRS, FRD) _FP1((FRD), 0, 10, (FRS))
#define FSQRTDrr(FRS, FRD) _FP1((FRD), 0, 42, (FRS))
#define FSQRTSrr(FRS, FRD) _FP1((FRD), 0, 41, (FRS))
#define FADDSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 65, (FRS2))
#define FSUBSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 69, (FRS2))
#define FMULSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 73, (FRS2))
#define FDIVSrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 77, (FRS2))
#define FADDDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 66, (FRS2))
#define FSUBDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 70, (FRS2))
#define FMULDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 74, (FRS2))
#define FDIVDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 78, (FRS2))
#define FCMPSrr(FRS1, FRS2) _FP2(0, (FRS1), 81, (FRS2))
#define FCMPDrr(FRS1, FRS2) _FP2(0, (FRS1), 82, (FRS2))
#define LDFxr(RS1, RS2, RD) _3 ((RD), 32, (RS1), 0, 0, (RS2))
#define LDFmr(RS1, IMM, RD) _3i ((RD), 32, (RS1), 1, (IMM))
#define LDDFxr(RS1, RS2, RD) _3 ((RD), 35, (RS1), 0, 0, (RS2))
#define LDDFmr(RS1, IMM, RD) _3i ((RD), 35, (RS1), 1, (IMM))
#define STFrx(RS, RD1, RD2) _3 ((RS), 36, (RD1), 0, 0, (RD2))
#define STFrm(RS, RD1, IMM) _3i ((RS), 36, (RD1), 1, (IMM))
#define STDFrx(RS, RD1, RD2) _3 ((RS), 39, (RD1), 0, 0, (RD2))
#define STDFrm(RS, RD1, IMM) _3i ((RS), 39, (RD1), 1, (IMM))
#define FBNi(DISP) _0 (0, 0, 6, (DISP))
#define FBN_Ai(DISP) _0 (1, 0, 6, (DISP))
#define FBNEi(DISP) _0 (0, 1, 6, (DISP))
#define FBNE_Ai(DISP) _0 (1, 1, 6, (DISP))
#define FBLGi(DISP) _0 (0, 2, 6, (DISP))
#define FBLG_Ai(DISP) _0 (1, 2, 6, (DISP))
#define FBULi(DISP) _0 (0, 3, 6, (DISP))
#define FBUL_Ai(DISP) _0 (1, 3, 6, (DISP))
#define FBLi(DISP) _0 (0, 4, 6, (DISP))
#define FBL_Ai(DISP) _0 (1, 4, 6, (DISP))
#define FBUGi(DISP) _0 (0, 5, 6, (DISP))
#define FBUG_Ai(DISP) _0 (1, 5, 6, (DISP))
#define FBGi(DISP) _0 (0, 6, 6, (DISP))
#define FBG_Ai(DISP) _0 (1, 6, 6, (DISP))
#define FBUi(DISP) _0 (0, 7, 6, (DISP))
#define FBU_Ai(DISP) _0 (1, 7, 6, (DISP))
#define FBAi(DISP) _0 (0, 8, 6, (DISP))
#define FBA_Ai(DISP) _0 (1, 8, 6, (DISP))
#define FBEi(DISP) _0 (0, 9, 6, (DISP))
#define FBE_Ai(DISP) _0 (1, 9, 6, (DISP))
#define FBUEi(DISP) _0 (0, 10, 6, (DISP))
#define FBUE_Ai(DISP) _0 (1, 10, 6, (DISP))
#define FBGEi(DISP) _0 (0, 11, 6, (DISP))
#define FBGE_Ai(DISP) _0 (1, 11, 6, (DISP))
#define FBUGEi(DISP) _0 (0, 12, 6, (DISP))
#define FBUGE_Ai(DISP) _0 (1, 12, 6, (DISP))
#define FBLEi(DISP) _0 (0, 13, 6, (DISP))
#define FBLE_Ai(DISP) _0 (1, 13, 6, (DISP))
#define FBULEi(DISP) _0 (0, 14, 6, (DISP))
#define FBULE_Ai(DISP) _0 (1, 14, 6, (DISP))
#define FBOi(DISP) _0 (0, 15, 6, (DISP))
#define FBO_Ai(DISP) _0 (1, 15, 6, (DISP))
#endif
#endif /* __ccg_asm_sparc_h */ #endif /* __ccg_asm_sparc_h */

View file

@ -33,14 +33,13 @@
#ifndef __lightning_core_h #ifndef __lightning_core_h
#define __lightning_core_h #define __lightning_core_h
#define JIT_R0 _Rl(0) #define JIT_R_NUM 3
#define JIT_R1 _Rl(1) #define JIT_V_NUM 6
#define JIT_R2 _Rl(2) #define JIT_R(i) ((i) ? _Rl((i) - 1) : _Rg(2))
#define JIT_V0 _Rl(3) #define JIT_V(i) _Rl((i)+2)
#define JIT_V1 _Rl(4)
#define JIT_V2 _Rl(5)
#define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */ #define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */
#define JIT_BIG2 _Rg(2) /* %g2 used to make 32-bit compare operands */ #define JIT_BIG2 _Ro(7) /* %o7 used to make 32-bit compare operands */
#define JIT_SP _Ro(6) #define JIT_SP _Ro(6)
#define JIT_RZERO _Rg(0) #define JIT_RZERO _Rg(0)
#define JIT_RET _Ri(0) #define JIT_RET _Ri(0)
@ -94,10 +93,18 @@ struct jit_local_state {
#define jit_prepare_y(rs, is) (SRArir(rs, 31, JIT_BIG), WRri(JIT_BIG, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is)) #define jit_prepare_y(rs, is) (SRArir(rs, 31, JIT_BIG), WRri(JIT_BIG, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
#define jit_clr_y(rs, is) ( WRri(0, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is)) #define jit_clr_y(rs, is) ( WRri(0, _y), NOP(), NOP(), NOP(), _jit.x.pc -= jit_immsize(is))
#define jit_mod(div, mul, d, s1, s2) ( \ #define jit_modr(jit_div, jit_mul, d, s1, s2) \
div (JIT_BIG2, s1, s2), \ (jit_div (JIT_BIG, s1, s2), \
mul (JIT_BIG2, JIT_BIG2, s2), \ jit_mul (JIT_BIG, JIT_BIG, s2), \
jit_subr_i (d, s1, JIT_BIG2)) jit_subr_i (d, s1, JIT_BIG))
#define jit_modi(jit_divi, jit_muli, jit_divr, jit_mulr, d, rs, is) \
(_siP(13,(imm)) \
? (jit_divi (JIT_BIG, rs, is), \
jit_muli (JIT_BIG, JIT_BIG, is), \
jit_subr_i (d, rs, JIT_BIG)) \
: (SETir ((is), JIT_BIG2), \
jit_modr (jit_divr, jit_mulr, d, rs, JIT_BIG2)))
/* How many instruction are needed to put imm in a register. */ /* How many instruction are needed to put imm in a register. */
#define jit_immsize(imm) (!(imm) ? 0 : \ #define jit_immsize(imm) (!(imm) ? 0 : \
@ -107,10 +114,16 @@ struct jit_local_state {
/* branch instructions return the address of the *delay* instruction -- this /* branch instructions return the address of the *delay* instruction -- this
* is just a helper macro that makes jit_patch more readable. * is just a helper macro that makes jit_patch more readable.
*/ */
#define jit_patch_(jump_pc) \ #define jit_patch_(jump_pc,pv) \
(*jump_pc &= ~_MASK(22), \ (*jump_pc &= ~_MASK(22), \
*jump_pc |= ((_jit_UL(_jit.x.pc) - _jit_UL(jump_pc)) >> 2) & _MASK(22)) *jump_pc |= ((_jit_UL((pv)) - _jit_UL(jump_pc)) >> 2) & _MASK(22))
#define jit_patch_set(sethi_pc, or_pc, dest) \
(*(sethi_pc) &= ~_MASK(22), *(sethi_pc) |= _HI(dest), \
*(or_pc) &= ~_MASK(13), *(or_pc) |= _LO(dest)) \
#define jit_patch_movi(movi_pc, val) \
jit_patch_set((movi_pc) - 2, (movi_pc) - 1, (val))
#define jit_arg_c() (_jitl.nextarg_get++) #define jit_arg_c() (_jitl.nextarg_get++)
#define jit_arg_i() (_jitl.nextarg_get++) #define jit_arg_i() (_jitl.nextarg_get++)
@ -162,8 +175,10 @@ struct jit_local_state {
#define jit_boaddr_ui(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1) #define jit_boaddr_ui(label, s1, s2) ( ADDCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_bosubr_ui(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1) #define jit_bosubr_ui(label, s1, s2) ( SUBCCrrr((s1), (s2), (s1)), BCSi((label)), NOP(), _jit.x.pc - 1)
#define jit_calli(label) (CALLi(label), NOP(), _jit.x.pc - 1) #define jit_calli(label) (CALLi(label), NOP(), _jit.x.pc - 1)
#define jit_callr(reg) (CALLx((reg), 0), NOP())
#define jit_divi_i(d, rs, is) (jit_prepare_y((rs), 0x12345678), SETir((is), JIT_BIG), SDIVrrr((rs), JIT_BIG, (d)) ) #define jit_divi_i(d, rs, is) (jit_prepare_y((rs), 0x12345678), SETir((is), JIT_BIG), SDIVrrr((rs), JIT_BIG, (d)) )
#define jit_divi_ui(d, rs, is) (jit_clr_y((rs)), 0x12345678), SETir((is), JIT_BIG), UDIVrrr((rs), JIT_BIG, (d)) ) #define jit_divi_ui(d, rs, is) (jit_clr_y((rs), 0x12345678), SETir((is), JIT_BIG), UDIVrrr((rs), JIT_BIG, (d)) )
#define jit_divr_i(d, s1, s2) (jit_prepare_y((s1), 0), SDIVrrr((s1), (s2), (d))) #define jit_divr_i(d, s1, s2) (jit_prepare_y((s1), 0), SDIVrrr((s1), (s2), (d)))
#define jit_divr_ui(d, s1, s2) (jit_clr_y((s1), 0), UDIVrrr((s1), (s2), (d))) #define jit_divr_ui(d, s1, s2) (jit_clr_y((s1), 0), UDIVrrr((s1), (s2), (d)))
#define jit_eqi_i(d, rs, is) jit_chk_imm((is), \ #define jit_eqi_i(d, rs, is) jit_chk_imm((is), \
@ -208,11 +223,12 @@ struct jit_local_state {
#define jit_lti_ui(d, rs, is) jit_booli ((d), (rs), (is), BLUi(_jit.x.pc + 3) ) #define jit_lti_ui(d, rs, is) jit_booli ((d), (rs), (is), BLUi(_jit.x.pc + 3) )
#define jit_ltr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLi(_jit.x.pc + 3) ) #define jit_ltr_i(d, s1, s2) jit_boolr ((d), (s1), (s2), BLi(_jit.x.pc + 3) )
#define jit_ltr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLUi(_jit.x.pc + 3) ) #define jit_ltr_ui(d, s1, s2) jit_boolr ((d), (s1), (s2), BLUi(_jit.x.pc + 3) )
#define jit_modi_i(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, (d), (rs), (is)) #define jit_modi_i(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, jit_divr_i, jit_mulr_i, (d), (rs), (is))
#define jit_modi_ui(d, rs, is) jit_modi(jit_divi_i, jit_muli_i, (d), (rs), (is)) #define jit_modi_ui(d, rs, is) jit_modi(jit_divi_ui, jit_muli_ui, jit_divr_ui, jit_mulr_ui, (d), (rs), (is))
#define jit_modr_i(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2)) #define jit_modr_i(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2))
#define jit_modr_ui(d, s1, s2) jit_modr(jit_divr_i, jit_mulr_i, (d), (s1), (s2)) #define jit_modr_ui(d, s1, s2) jit_modr(jit_divr_ui, jit_mulr_ui, (d), (s1), (s2))
#define jit_movi_i(d, is) SETir((is), (d)) #define jit_movi_i(d, is) SETir((is), (d))
#define jit_movi_p(d, is) (SETir2(_HI((is)), _LO((is)), (d)), _jit.x.pc)
#define jit_movr_i(d, rs) MOVrr((rs), (d)) #define jit_movr_i(d, rs) MOVrr((rs), (d))
#define jit_muli_i(d, rs, is) jit_chk_imm((is), SMULrir((rs), (is), (d)), SMULrrr((rs), JIT_BIG, (d))) #define jit_muli_i(d, rs, is) jit_chk_imm((is), SMULrir((rs), (is), (d)), SMULrrr((rs), JIT_BIG, (d)))
#define jit_muli_ui(d, rs, is) jit_chk_imm((is), UMULrir((rs), (is), (d)), UMULrrr((rs), JIT_BIG, (d))) #define jit_muli_ui(d, rs, is) jit_chk_imm((is), UMULrir((rs), (is), (d)), UMULrrr((rs), JIT_BIG, (d)))
@ -221,14 +237,14 @@ struct jit_local_state {
#define jit_nop() NOP() #define jit_nop() NOP()
#define jit_ori_i(d, rs, is) jit_chk_imm((is), ORrir((rs), (is), (d)), ORrrr((rs), JIT_BIG, (d))) #define jit_ori_i(d, rs, is) jit_chk_imm((is), ORrir((rs), (is), (d)), ORrrr((rs), JIT_BIG, (d)))
#define jit_orr_i(d, s1, s2) ORrrr((s1), (s2), (d)) #define jit_orr_i(d, s1, s2) ORrrr((s1), (s2), (d))
#define jit_patch(delay_pc) jit_patch_ ( ((delay_pc) - 1) ) #define jit_patch_at(delay_pc, pv) jit_patch_ (((delay_pc) - 1) , (pv))
#define jit_popr_i(rs) (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 8, JIT_SP)) #define jit_popr_i(rs) (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 8, JIT_SP))
#define jitfp_prepare(numargs, nf, nd) (_jitl.nextarg_put = (numargs)) #define jit_prepare_i(num) (_jitl.nextarg_put += (num))
#define jit_prolog(numargs) (SAVErir(JIT_SP, -96, JIT_SP), _jitl.nextarg_get = _Ri(0)) #define jit_prolog(numargs) (SAVErir(JIT_SP, -120, JIT_SP), _jitl.nextarg_get = _Ri(0))
#define jit_pushr_i(rs) (STrm((rs), JIT_SP, -8), SUBrir(JIT_SP, 8, JIT_SP)) #define jit_pushr_i(rs) (STrm((rs), JIT_SP, -8), SUBrir(JIT_SP, 8, JIT_SP))
#define jit_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put))) #define jit_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put)))
#define jit_ret() (RET(), RESTORE()) #define jit_ret() (RET(), RESTORE())
#define jit_retval(rd) MOVrr(_Ro(0), (rd)) #define jit_retval_i(rd) MOVrr(_Ro(0), (rd))
#define jit_rshi_i(d, rs, is) SRArir((rs), (is), (d)) #define jit_rshi_i(d, rs, is) SRArir((rs), (is), (d))
#define jit_rshi_ui(d, rs, is) SRLrir((rs), (is), (d)) #define jit_rshi_ui(d, rs, is) SRLrir((rs), (is), (d))
#define jit_rshr_i(d, r1, r2) SRArrr((r1), (r2), (d)) #define jit_rshr_i(d, r1, r2) SRArrr((r1), (r2), (d))

View file

@ -7,7 +7,7 @@
/*********************************************************************** /***********************************************************************
* *
* Copyright 2000, 2001, 2002 Free Software Foundation, Inc. * Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini. * Written by Paolo Bonzini.
* *
* This file is part of GNU lightning. * This file is part of GNU lightning.
@ -35,99 +35,61 @@
#ifndef __lightning_asm_fp_h #ifndef __lightning_asm_fp_h
#define __lightning_asm_fp_h #define __lightning_asm_fp_h
#if 0 #define JIT_FPR_NUM 6
#define JIT_FPR(i) (30-(i)*2)
#define JIT_FPTMP 18
/* dummy for now */ #define jit_addr_f(rd,s1,s2) FADDSrrr((s1), (s2), (rd))
#define jit_subr_f(rd,s1,s2) FSUBSrrr((s1), (s2), (rd))
#define jit_mulr_f(rd,s1,s2) FMULSrrr((s1), (s2), (rd))
#define jit_divr_f(rd,s1,s2) FDIVSrrr((s1), (s2), (rd))
#define _FP1(RD, RS1, OPF, RS2) _2f((RD), 52, (RS1), (OPF), (RS2)) #define jit_addr_d(rd,s1,s2) FADDDrrr((s1), (s2), (rd))
#define _FP2(RD, RS1, OPF, RS2) _2f((RD), 53, (RS1), (OPF), (RS2)) #define jit_subr_d(rd,s1,s2) FSUBDrrr((s1), (s2), (rd))
#define jit_mulr_d(rd,s1,s2) FMULDrrr((s1), (s2), (rd))
#define jit_divr_d(rd,s1,s2) FDIVDrrr((s1), (s2), (rd))
#define FITODrr(FRS, FRD) _FP1((FRD), 0, 200, (FRS)) #define jit_movr_f(rd,rs) FMOVSrr((rs), (rd))
#define FDTOIrr(FRS, FRD) _FP1((FRD), 0, 210, (FRS)) #define jit_abs_d(rd,rs) FABSSrr((rs), (rd))
#define FSTODrr(FRS, FRD) _FP1((FRD), 0, 201, (FRS)) #define jit_negr_d(rd,rs) FNEGSrr((rs), (rd))
#define FDTOSrr(FRS, FRD) _FP1((FRD), 0, 198, (FRS)) #define jit_sqrt_d(rd,rs) FSQRTSrr((rs), (rd))
#define FMOVSrr(FRS, FRD) _FP1((FRD), 0, 1, (FRS)) #define jit_movr_d(rd,rs) FMOVDrr((rs), (rd))
#define FNEGSrr(FRS, FRD) _FP1((FRD), 0, 5, (FRS)) #define jit_abs_f(rd,rs) FABSDrr((rs), (rd))
#define FABSSrr(FRS, FRD) _FP1((FRD), 0, 9, (FRS)) #define jit_negr_f(rd,rs) FNEGDrr((rs), (rd))
#define FSQRTDrr(FRS, FRD) _FP1((FRD), 0, 74, (FRS)) #define jit_sqrt_f(rd,rs) FSQRTDrr((rs), (rd))
#define jit_extr_f_d(rs, rd) FSTODrr((rs), (rd))
#define jit_extr_d_f(rs, rd) FDTOSrr((rs), (rd))
#define FADDDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 66, (FRS2)) #define jit_movi_f(rd,immf) \
#define FSUBDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 70, (FRS2)) do { \
#define FMULDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 82, (FRS2)) float _v = (immf); \
#define FDIVDrrr(FRS1, FRS2, FRD) _FP1((FRD), (FRS1), 86, (FRS2)) _1(_jit.x.pc + 3), LDFmr(_Ro(7), 8, (rd)); \
memcpy(_jit.x.uc_pc, &_v, sizeof (float)); \
_jit.x.uc_pc += sizeof (float); \
} while(0)
#define FCMPDrr(FRS1, FRS2) _FP2(0, (FRS1), 82, (FRS2)) #define jit_movi_d(rd,immd) \
do { \
#define LDFxr(RS1, RS2, RD) _3 ((RD), 32, (RS1), 0, 0, (RS2)) double _v = (immd); \
#define LDFmr(RS1, IMM, RD) _3i ((RD), 32, (RS1), 1, (IMM)) if ((long)_jit.x.pc & 4) NOP(); \
#define LDDFxr(RS1, RS2, RD) _3 ((RD), 35, (RS1), 0, 0, (RS2)) _1(_jit.x.pc + 4); \
#define LDDFmr(RS1, IMM, RD) _3i ((RD), 35, (RS1), 1, (IMM)) LDDFmr(_Ro(7), 8, (rd)); \
#define STFrx(RS, RD1, RD2) _3 ((RS), 36, (RD1), 0, 0, (RD2)) memcpy(_jit.x.uc_pc, &_v, sizeof (double)); \
#define STFrm(RS, RD1, IMM) _3i ((RS), 36, (RD1), 1, (IMM)) _jit.x.uc_pc += sizeof (double); \
#define STDFrx(RS, RD1, RD2) _3 ((RS), 39, (RD1), 0, 0, (RD2)) } while(0)
#define STDFrm(RS, RD1, IMM) _3i ((RS), 39, (RD1), 1, (IMM))
#define FBNi(DISP) _0 (0, 0, 6, (DISP))
#define FBN_Ai(DISP) _0 (1, 0, 6, (DISP))
#define FBNEi(DISP) _0 (0, 1, 6, (DISP))
#define FBNE_Ai(DISP) _0 (1, 1, 6, (DISP))
#define FBLGi(DISP) _0 (0, 2, 6, (DISP))
#define FBLG_Ai(DISP) _0 (1, 2, 6, (DISP))
#define FBULi(DISP) _0 (0, 3, 6, (DISP))
#define FBUL_Ai(DISP) _0 (1, 3, 6, (DISP))
#define FBLi(DISP) _0 (0, 4, 6, (DISP))
#define FBL_Ai(DISP) _0 (1, 4, 6, (DISP))
#define FBUGi(DISP) _0 (0, 5, 6, (DISP))
#define FBUG_Ai(DISP) _0 (1, 5, 6, (DISP))
#define FBGi(DISP) _0 (0, 6, 6, (DISP))
#define FBG_Ai(DISP) _0 (1, 6, 6, (DISP))
#define FBUi(DISP) _0 (0, 7, 6, (DISP))
#define FBU_Ai(DISP) _0 (1, 7, 6, (DISP))
#define FBAi(DISP) _0 (0, 8, 6, (DISP))
#define FBA_Ai(DISP) _0 (1, 8, 6, (DISP))
#define FBEi(DISP) _0 (0, 9, 6, (DISP))
#define FBE_Ai(DISP) _0 (1, 9, 6, (DISP))
#define FBUEi(DISP) _0 (0, 10, 6, (DISP))
#define FBUE_Ai(DISP) _0 (1, 10, 6, (DISP))
#define FBGEi(DISP) _0 (0, 11, 6, (DISP))
#define FBGE_Ai(DISP) _0 (1, 11, 6, (DISP))
#define FBUGEi(DISP) _0 (0, 12, 6, (DISP))
#define FBUGE_Ai(DISP) _0 (1, 12, 6, (DISP))
#define FBLEi(DISP) _0 (0, 13, 6, (DISP))
#define FBLE_Ai(DISP) _0 (1, 13, 6, (DISP))
#define FBULEi(DISP) _0 (0, 14, 6, (DISP))
#define FBULE_Ai(DISP) _0 (1, 14, 6, (DISP))
#define FBOi(DISP) _0 (0, 15, 6, (DISP))
#define FBO_Ai(DISP) _0 (1, 15, 6, (DISP))
#define FSKIPUG() _0d (1, 13, 6, 2) /* fble,a .+8 */
#define FSKIPUL() _0d (1, 11, 6, 2) /* fbge,a .+8 */
#define jit_add_two(reg0) FADDDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_sub_two(reg0) FSUBDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_mul_two(reg0) FMULDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_div_two(reg0) FDIVDrrr(30 - (reg0) * 2, 28 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_abs(reg0) FABSSrr(30 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_neg(reg0) FNEGSrr(30 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_sqrt(reg0) FSQRTDrr(30 - (reg0) * 2, 30 - (reg0) * 2)
#define jit_fpimm(reg0, first, second) \
(_1(4), NOP(), _jit_L(first), _jit_L(second), \
jit_ldxi_d((reg0), _Ro(7), 8))
#define jit_ldxi_f(reg0, rs, is) (jit_chk_imm((is), LDFmr((rs), (is), 30 - (reg0) * 2), LDFxr((rs), JIT_BIG, 30 - (reg0) * 2)), FSTODrr(30 - (reg0) * 2, 30 - (reg0) * 2))
#define jit_ldxi_d(reg0, rs, is) jit_chk_imm((is), LDDFmr((rs), (is), 30 - (reg0) * 2), LDDFxr((rs), JIT_BIG, 30 - (reg0) * 2))
#define jit_ldxr_f(reg0, s1, s2) (LDFxr((s1), (s2), 30 - (reg0) * 2), FSTODrr(30 - (reg0) * 2, 30 - (reg0) * 2))
#define jit_ldxr_d(reg0, s1, s2) LDDFxr((s1), (s2), 30 - (reg0) * 2)
#define jit_stxi_f(id, rd, reg0) (FDTOSrr(30 - (reg0) * 2, 30 - (reg0) * 2), jit_chk_imm((id), STFrm(30 - (reg0) * 2, (rd), (id)), STFrx(30 - (reg0) * 2, (rd), JIT_BIG)))
#define jit_stxi_d(id, rd, reg0) jit_chk_imm((id), STDFrm(30 - (reg0) * 2, (rd), (id)), STDFrx(30 - (reg0) * 2, (rd), JIT_BIG))
#define jit_stxr_f(d1, d2, reg0) (FDTOSrr(30 - (reg0) * 2, 30 - (reg0) * 2), STFrx (30 - (reg0) * 2, (d1), (d2)))
#define jit_stxr_d(d1, d2, reg0) STDFrx(30 - (reg0) * 2, (d1), (d2))
#define jit_do_round(mode, rd, freg) ( \ #define jit_ldxi_f(rd, rs, is) jit_chk_imm((is), LDFmr((rs), (is), (rd)), LDFxr((rs), JIT_BIG, (rd)))
_1(3), \ #define jit_ldxi_d(rd, rs, is) jit_chk_imm((is), LDDFmr((rs), (is), (rd)), LDDFxr((rs), JIT_BIG, (rd)))
#define jit_ldxr_f(rd, s1, s2) LDFxr((s1), (s2), (rd))
#define jit_ldxr_d(rd, s1, s2) LDDFxr((s1), (s2), (rd))
#define jit_stxi_f(id, rd, rs) jit_chk_imm((id), STFrm((rs), (rd), (id)), STFrx((rs), (rd), JIT_BIG))
#define jit_stxi_d(id, rd, rs) jit_chk_imm((id), STDFrm((rs), (rd), (id)), STDFrx((rs), (rd), JIT_BIG))
#define jit_stxr_f(d1, d2, rs) STFrx((rs), (d1), (d2))
#define jit_stxr_d(d1, d2, rs) STDFrx((rs), (d1), (d2))
#define jit_do_round(mode, rd, freg, macro) ( \
_1(_jit.x.pc + 3), \
SETHIir(_HI(mode << 29), JIT_BIG), \ SETHIir(_HI(mode << 29), JIT_BIG), \
NOP(), \ NOP(), \
STFSRm(_Ro(7), 8), /* store fsr */ \ STFSRm(_Ro(7), 8), /* store fsr */ \
@ -135,29 +97,71 @@
XORrrr(rd, JIT_BIG, JIT_BIG), /* adjust mode */ \ XORrrr(rd, JIT_BIG, JIT_BIG), /* adjust mode */ \
STrm(JIT_BIG, _Ro(7), 8), \ STrm(JIT_BIG, _Ro(7), 8), \
LDFSRm(_Ro(7), 8), /* load fsr */ \ LDFSRm(_Ro(7), 8), /* load fsr */ \
FDTOIrr(freg, freg), /* truncate */ \ macro, /* truncate */ \
STrm(rd, _Ro(7), 8), /* load old fsr */ \ STrm(rd, _Ro(7), 8), /* load old fsr */ \
LDFSRm(_Ro(7), 8), \ LDFSRm(_Ro(7), 8), \
STFrm(freg, _Ro(7), 8), /* store truncated value */ \ STFrm(JIT_FPTMP, _Ro(7), 8), /* store truncated value */ \
LDmr(_Ro(7), 8, rd)) /* load it into rd */ LDmr(_Ro(7), 8, rd)) /* load it into rd */
#define jit_do_round_no_fsr(macro1, macro2) ( \
_1(_jit.x.pc + 3), \
macro1, \
NOP(), \
macro2)
/* call delay slot data ,--- call lands here */ #define jit_extr_i_d(rd, rs) jit_do_round_no_fsr (NOP(), (STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, (rd)), FITODrr((rd), (rd))))
#define jit_exti_d(reg0, rs) (_1(3), NOP(), NOP(), STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, 30 - (reg0) * 2), FITODrr(30 - (reg0) * 2, 30 - (reg0) * 2)) #define jit_extr_i_f(rd, rs) jit_do_round_no_fsr (NOP(), (STrm((rs), _Ro(7), 8), LDFmr(_Ro(7), 8, (rd)), FITOSrr((rd), (rd))))
#define jit_round(rd, reg0) (_1(3), FDTOIrr(30 - (reg0) * 2, 30 - (reg0) * 2), NOP(), STFrm(30 - (reg0) * 2, _Ro(7), 8), LDmr(_Ro(7), 8, (rd))) #define jit_roundr_d_i(rd, rs) jit_do_round_no_fsr (FDTOIrr((rs), JIT_FPTMP), (STFrm(JIT_FPTMP, _Ro(7), 8), LDmr(_Ro(7), 8, (rd))))
#define jit_floor(rd, reg0) jit_do_round(3, (rd), (30 - (reg0) * 2)) #define jit_roundr_f_i(rd, rs) jit_do_round_no_fsr (FSTOIrr((rs), JIT_FPTMP), (STFrm(JIT_FPTMP, _Ro(7), 8), LDmr(_Ro(7), 8, (rd))))
#define jit_ceil(rd, reg0) jit_do_round(2, (rd), (30 - (reg0) * 2)) #define jit_floorr_d_i(rd, rs) jit_do_round(3, (rd), (rs), FDTOIrr((rs), JIT_FPTMP))
#define jit_trunc(rd, reg0) jit_do_round(1, (rd), (30 - (reg0) * 2)) #define jit_ceilr_d_i(rd, rs) jit_do_round(2, (rd), (rs), FDTOIrr((rs), JIT_FPTMP))
#define jit_truncr_d_i(rd, rs) jit_do_round(1, (rd), (rs), FDTOIrr((rs), JIT_FPTMP))
#define jit_floorr_f_i(rd, rs) jit_do_round(3, (rd), (rs), FSTOIrr((rs), JIT_FPTMP))
#define jit_ceilr_f_i(rd, rs) jit_do_round(2, (rd), (rs), FSTOIrr((rs), JIT_FPTMP))
#define jit_truncr_f_i(rd, rs) jit_do_round(1, (rd), (rs), FSTOIrr((rs), JIT_FPTMP))
static double jit_zero = 0.0; #define jit_ltr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ler_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ler_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_eqr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_eqr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ner_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBNEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ner_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBNEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ger_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ger_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_gtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_gtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unltr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBULi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unltr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBULi(_jit.x.pc + 3), MOVir (1, (d), MOVir (0, (d)))
#define jit_unler_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBULEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unler_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBULEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_uneqr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_uneqr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltgtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBLGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ltgtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBLGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unger_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unger_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUGEi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ungtr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ungtr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUGi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ordr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBOi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_ordr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBOi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unordr_d(d, s1, s2) (FCMPDrr ((s1), (s2)), FBUi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_unordr_f(d, s1, s2) (FCMPSrr ((s1), (s2)), FBUi(_jit.x.pc + 3), MOVir (1, (d)), MOVir (0, (d)))
#define jit_cmp(le, ge, reg0) (SETHIir(_HI(_jit_UL(&jit_zero)), (le)), \ #define jit_prepare_f(num) (_jitl.nextarg_put += (num))
LDDFmr((le), _LO(_jit_UL(&jit_zero)), 28 - (reg0) * 2), \ #define jit_prepare_d(num) (_jitl.nextarg_put += 2 * (num))
FCMPDrr(30 - (reg0) * 2, 28 - (reg0) * 2), \
MOVir(0, (le)), MOVir(0, (ge)), \
FSKIPUL(), MOVir(1, (ge)), \
FSKIPUG(), MOVir(1, (le)))
#endif #define jit_arg_f() (_jitl.nextarg_get++)
#define jit_arg_d() (_jitl.nextarg_get += _jitl.nextarg_get & 1, _jitl.nextarg_get += 2, _jitl.nextarg_get - 2)
#define jit_getarg_f(rd, ofs) (STrm(ofs, _Ri(6), -24), LDFmr (_Ri(6), -24, (rd)))
#define jit_getarg_d(rd, ofs) (STDrm(ofs, _Ri(6), -24), LDDFmr (_Ri(6), -24, (rd)))
#define jit_pusharg_f(rs) (STFrm((rs), _Ri(6), -24), --_jitl.nextarg_put, LDmr (_Ri(6), -24, _Ro(_jitl.nextarg_put)))
#define jit_pusharg_d(rs) (STDFrm((rs), _Ri(6), -24), _jitl.nextarg_put -= 2, LDmr (_Ri(6), -24, _Ro(_jitl.nextarg_put)))
#define jit_retval_f(rs) jit_movr_f(0, rs)
#define jit_retval_d(rs) jit_movr_d(0, rs)
#endif /* __lightning_asm_fp_h */ #endif /* __lightning_asm_fp_h */

View file

@ -1,6 +1,8 @@
EXTRA_LIBRARIES = libdisass.a EXTRA_LIBRARIES = libdisass.a
noinst_LIBRARIES = @LIBDISASS@ noinst_LIBRARIES = @LIBDISASS@
AM_CPPFLAGS = -I$(top_srcdir)
libdisass_a_SOURCES = dis-buf.c i386-dis.c ppc-dis.c ppc-opc.c sparc-dis.c \ libdisass_a_SOURCES = dis-buf.c i386-dis.c ppc-dis.c ppc-opc.c sparc-dis.c \
sparc-opc.c disass.c sparc-opc.c disass.c

View file

@ -1,8 +1,7 @@
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
EXTRA_PROGRAMS = testfp funcfp rpnfp noinst_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay add bp testfp funcfp rpnfp
noinst_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay add noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok bp.ok
noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok
EXTRA_DIST = $(noinst_DATA) run-test EXTRA_DIST = $(noinst_DATA) run-test
if DISASS if DISASS
@ -10,7 +9,6 @@ LDADD = $(top_builddir)/opcode/libdisass.a
endif endif
if REGRESSION_TESTING if REGRESSION_TESTING
TESTS = fib fibit fibdelay incr printf printf2 rpn add \ TESTS = fib fibit fibdelay incr printf printf2 rpn add bp testfp funcfp rpnfp
#testfp funcfp rpnfp
TESTS_ENVIRONMENT=$(srcdir)/run-test TESTS_ENVIRONMENT=$(srcdir)/run-test
endif endif

89
tests/bp.c Normal file
View file

@ -0,0 +1,89 @@
/******************************** -*- C -*- ****************************
*
* Simple example of recursion and forward references
*
***********************************************************************/
/***********************************************************************
*
* Copyright 2000, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini and Laurent Michel.
*
* This file is part of GNU lightning.
*
* GNU lightning is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1, or (at your option)
* any later version.
*
* GNU lightning 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with GNU lightning; see the file COPYING.LESSER; if not, write to the
* Free Software Foundation, 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
***********************************************************************/
#include <stdio.h>
#include "lightning.h"
static jit_insn codeBuffer[1024];
typedef int (*pifi)(int); /* Pointer to Int Function of Int */
int main()
{
pifi nfibs = (pifi) (jit_set_ip(codeBuffer).iptr);
int in; /* offset of the argument */
jit_insn *ref; /* to patch the forward reference */
jit_insn *mref; /* ref of move to backpatch */
jit_insn *tp; /* location to patch */
jit_prolog (1);
in = jit_arg_ui ();
jit_getarg_ui(JIT_V0, in); /* V0 = n */
mref= jit_movi_p(JIT_V2,jit_forward ()); /* Generate a dumb movi */
jit_jmpr(JIT_V2);
/* generate some dump filler that will never be executed!*/
jit_addi_ui(JIT_V0,JIT_V0,1);
jit_addi_ui(JIT_V0,JIT_V0,1);
jit_addi_ui(JIT_V0,JIT_V0,1);
jit_addi_ui(JIT_V0,JIT_V0,1);
tp = jit_get_label ();
ref = jit_blti_ui (jit_forward(), JIT_V0, 2);
jit_subi_ui (JIT_V1, JIT_V0, 1); /* V1 = n-1 */
jit_subi_ui (JIT_V2, JIT_V0, 2); /* V2 = n-2 */
jit_prepare (1);
jit_pusharg_ui(JIT_V1);
jit_finish(nfibs);
jit_retval(JIT_V1); /* V1 = nfibs(n-1) */
jit_prepare(1);
jit_pusharg_ui(JIT_V2);
jit_finish(nfibs);
jit_retval(JIT_V2); /* V2 = nfibs(n-2) */
jit_addi_ui(JIT_V1, JIT_V1, 1);
jit_addr_ui(JIT_RET, JIT_V1, JIT_V2); /* RET = V1 + V2 + 1 */
jit_ret();
jit_patch(ref); /* patch jump */
jit_movi_i(JIT_RET, 1); /* RET = 1 */
jit_ret();
jit_patch_movi(mref,tp); /* Ok. Do the back-patching */
/* call the generated code, passing 32 as an argument */
jit_flush_code(codeBuffer, jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif
#ifndef LIGHTNING_CROSS
printf("nfibs(%d) = %d\n", 32, nfibs(32));
#endif
return 0;
}

1
tests/bp.ok Normal file
View file

@ -0,0 +1 @@
nfibs(32) = 7049155

View file

@ -48,14 +48,14 @@ int main()
ref = jit_blti_ui (jit_forward(), JIT_V0, 2); ref = jit_blti_ui (jit_forward(), JIT_V0, 2);
jit_subi_ui (JIT_V1, JIT_V0, 1); /* V1 = n-1 */ jit_subi_ui (JIT_V1, JIT_V0, 1); /* V1 = n-1 */
jit_subi_ui (JIT_V2, JIT_V0, 2); /* V2 = n-2 */ jit_subi_ui (JIT_V2, JIT_V0, 2); /* V2 = n-2 */
jit_prepare (1); jit_prepare_i(1);
jit_pusharg_ui(JIT_V1); jit_pusharg_ui(JIT_V1);
jit_finish(nfibs); jit_finish(nfibs);
jit_retval(JIT_V1); /* V1 = nfibs(n-1) */ jit_retval_i (JIT_V1); /* V1 = nfibs(n-1) */
jit_prepare(1); jit_prepare_i(1);
jit_pusharg_ui(JIT_V2); jit_pusharg_ui(JIT_V2);
jit_finish(nfibs); jit_finish(nfibs);
jit_retval(JIT_V2); /* V2 = nfibs(n-2) */ jit_retval_i (JIT_V2); /* V2 = nfibs(n-2) */
jit_addi_ui(JIT_V1, JIT_V1, 1); jit_addi_ui(JIT_V1, JIT_V1, 1);
jit_addr_ui(JIT_RET, JIT_V1, JIT_V2); /* RET = V1 + V2 + 1 */ jit_addr_ui(JIT_RET, JIT_V1, JIT_V2); /* RET = V1 + V2 + 1 */
jit_ret(); jit_ret();

View file

@ -65,7 +65,7 @@ int main()
jit_flush_code(codeBuffer, jit_get_ip().ptr); jit_flush_code(codeBuffer, jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *) codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
/* call the generated code, passing 36 as an argument */ /* call the generated code, passing 36 as an argument */

View file

@ -7,7 +7,7 @@
/*********************************************************************** /***********************************************************************
* *
* Copyright 2000 Free Software Foundation, Inc. * Copyright 2000, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini. * Written by Paolo Bonzini.
* *
* This file is part of GNU lightning. * This file is part of GNU lightning.
@ -34,139 +34,139 @@
#include "lightning.h" #include "lightning.h"
static jit_insn codeBuffer[300]; static jit_insn codeBuffer[300];
static struct jit_fp buffer[300];
typedef int (*intFunc) (int, int);
typedef double (*dblFunc) (double, double);
typedef float (*floatFunc) (float, float);
typedef int (*intFunc)(int,int); /* Generate a function that computes and returns the sum of
typedef double (*dblFunc)(double,double);
typedef float (*floatFunc)(float,float);
dblFunc makeDblFunc()
/* Generate a function that computes and returns the sum of
its two double arguments (return an int) its two double arguments (return an int)
i.e., double foo(double x,double y) { return x + y;} i.e., double foo(double x,double y) { return x + y;} */
*/ dblFunc
makeDblFunc ()
{ {
dblFunc retVal; dblFunc retVal;
int dbl1,dbl2; int dbl1, dbl2;
jit_set_ip(codeBuffer); retVal = (dblFunc) jit_get_ip ().iptr;
retVal = (dblFunc)jit_get_ip().iptr; jit_prolog (2);
jit_prolog(2); dbl1 = jit_arg_d ();
jitfp_begin(buffer); dbl2 = jit_arg_d ();
dbl1 = jit_arg_d(); jit_getarg_d (JIT_FPR0, dbl1);
dbl2 = jit_arg_d(); jit_getarg_d (JIT_FPR1, dbl2);
jit_addr_d (JIT_FPR0, JIT_FPR0, JIT_FPR1);
jit_retval_d (JIT_FPR0);
jitfp_retval(jitfp_add(jitfp_getarg_d(dbl1), jit_ret ();
jitfp_getarg_d(dbl2))); jit_flush_code ((char *) retVal, jit_get_ip ().ptr);
jit_ret();
jit_flush_code((char*)retVal,jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, retVal, jit_get_ip().ptr); disassemble (stderr, (char *) retVal, jit_get_ip ().ptr);
#endif #endif
return retVal; return retVal;
} }
floatFunc makeFloatFunc() /* Generate a function that computes and returns the sum of
/* Generate a function that computes and returns the sum of
its two double arguments (return an int) its two double arguments (return an int)
i.e., double foo(double x,double y) { return x + y;} i.e., double foo(double x,double y) { return x + y;} */
*/ floatFunc
makeFloatFunc ()
{ {
floatFunc retVal; floatFunc retVal;
int dbl1,dbl2; int dbl1, dbl2;
//jit_set_ip(codeBuffer); retVal = (floatFunc) jit_get_ip ().iptr;
retVal = (floatFunc)jit_get_ip().iptr; jit_prolog (2);
jit_prolog(2); dbl1 = jit_arg_f ();
jitfp_begin(buffer); dbl2 = jit_arg_f ();
dbl1 = jit_arg_f(); jit_getarg_f (JIT_FPR0, dbl1);
dbl2 = jit_arg_f(); jit_getarg_f (JIT_FPR1, dbl2);
jit_addr_f (JIT_FPR0, JIT_FPR0, JIT_FPR1);
jit_retval_f (JIT_FPR0);
jitfp_retval(jitfp_add(jitfp_getarg_f(dbl1), jit_ret ();
jitfp_getarg_f(dbl2))); jit_flush_code ((char *) retVal, jit_get_ip ().ptr);
jit_ret();
jit_flush_code((char*)retVal,jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, retVal, jit_get_ip().ptr); disassemble (stderr, (char *) retVal, jit_get_ip ().ptr);
#endif #endif
return retVal; return retVal;
} }
dblFunc makeCallFunc(dblFunc theFunc) dblFunc
makeCallFunc (dblFunc theFunc)
{ {
dblFunc retVal; dblFunc retVal;
int dbl1,dbl2; int dbl1, dbl2;
//jit_set_ip(codeBuffer); retVal = (dblFunc) jit_get_ip ().iptr;
retVal = (dblFunc)jit_get_ip().iptr; jit_prolog (2);
jit_prolog(2); dbl1 = jit_arg_d ();
jitfp_begin(buffer); dbl2 = jit_arg_d ();
dbl1 = jit_arg_d();
dbl2 = jit_arg_d();
jitfp_prepare(0,0,2); jit_prepare_d (2);
jitfp_pusharg_d(jitfp_mul(jitfp_getarg_d(dbl1), jit_getarg_d (JIT_FPR0, dbl1);
jitfp_getarg_d(dbl2))); jit_getarg_d (JIT_FPR1, dbl2);
jitfp_pusharg_d(jitfp_getarg_d(dbl1)); jit_mulr_d (JIT_FPR1, JIT_FPR1, JIT_FPR0);
jit_finish((void*)theFunc); jit_pusharg_d (JIT_FPR1);
jit_ret(); jit_pusharg_d (JIT_FPR0);
jit_flush_code((char*)retVal,jit_get_ip().ptr); jit_finish ((void *) theFunc);
jit_ret ();
jit_flush_code ((char *) retVal, jit_get_ip ().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, retVal, jit_get_ip().ptr); disassemble (stderr, (char *) retVal, jit_get_ip ().ptr);
#endif #endif
return retVal; return retVal;
} }
floatFunc makeCallFloatFunc(floatFunc theFunc) floatFunc
makeCallFloatFunc (floatFunc theFunc)
{ {
floatFunc retVal; floatFunc retVal;
int dbl1,dbl2; int dbl1, dbl2;
//jit_set_ip(codeBuffer); retVal = (floatFunc) jit_get_ip ().iptr;
retVal = (floatFunc)jit_get_ip().iptr; jit_prolog (2);
jit_prolog(2); dbl1 = jit_arg_f ();
jitfp_begin(buffer); dbl2 = jit_arg_f ();
dbl1 = jit_arg_f();
dbl2 = jit_arg_f();
jitfp_prepare(0,2,0); jit_prepare_f (2);
jitfp_pusharg_f(jitfp_mul(jitfp_getarg_f(dbl1), jit_getarg_f (JIT_FPR0, dbl1);
jitfp_getarg_f(dbl2))); jit_getarg_f (JIT_FPR1, dbl2);
jitfp_pusharg_f(jitfp_getarg_f(dbl1)); jit_mulr_f (JIT_FPR1, JIT_FPR1, JIT_FPR0);
jit_finish((void*)theFunc); jit_pusharg_f (JIT_FPR1);
jit_ret(); jit_pusharg_f (JIT_FPR0);
jit_flush_code((char*)retVal,jit_get_ip().ptr); jit_finish ((void *) theFunc);
jit_ret ();
jit_flush_code ((char *) retVal, jit_get_ip ().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, retVal, jit_get_ip().ptr); disassemble (stderr, (char *) retVal, jit_get_ip ().ptr);
#endif #endif
return retVal; return retVal;
} }
int main(int argc,char* argv[]) int
main (int argc, char *argv[])
{ {
dblFunc myFunc2 = makeDblFunc(); dblFunc myFunc2, callIt1;
floatFunc myFunc3 = makeFloatFunc(); floatFunc myFunc3, callIt2;
dblFunc callIt1 = makeCallFunc(myFunc2); double y;
floatFunc callIt2 = makeCallFloatFunc(myFunc3); float a, b, z;
jit_set_ip (codeBuffer);
myFunc2 = makeDblFunc ();
myFunc3 = makeFloatFunc ();
callIt1 = makeCallFunc (myFunc2);
callIt2 = makeCallFloatFunc (myFunc3);
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
double y = callIt1(10.5,15.3); y = callIt1 (10.5, 15.3);
float a = 1.5; a = 1.5;
float b = 10.5; b = 10.5;
float z = callIt2(a,b); z = callIt2 (a, b);
printf("result is %f\t %f\n",y,z); printf ("result is %.5g\t %.5g\n", y, z);
#endif #endif
return 0; return 0;

View file

@ -1 +1 @@
result is 171.150000 17.250000 result is 171.15 17.25

View file

@ -48,7 +48,7 @@ int main()
ofs = jit_arg_i(); ofs = jit_arg_i();
jit_movi_p(JIT_R0, "looks like %d bytes sufficed\n"); jit_movi_p(JIT_R0, "looks like %d bytes sufficed\n");
jit_getarg_i(JIT_R1, ofs); jit_getarg_i(JIT_R1, ofs);
jit_prepare(2); jit_prepare_i(2);
jit_pusharg_i(JIT_R1); /* push in reverse order */ jit_pusharg_i(JIT_R1); /* push in reverse order */
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
jit_finish(printf); jit_finish(printf);

View file

@ -38,19 +38,18 @@ static jit_insn codeBuffer[1024];
typedef double (*pdfd) (double); /* Pointer to Double Function of Double */ typedef double (*pdfd) (double); /* Pointer to Double Function of Double */
static int regs[6] = { JIT_FPR0, JIT_FPR1, JIT_FPR2, JIT_FPR3, JIT_FPR4, JIT_FPR5 };
pdfd pdfd
compile_rpn (char *expr) compile_rpn (char *expr)
{ {
pdfd fn; pdfd fn;
int ofs, sp = 1; int ofs, sp = 1;
struct jit_fp buffer[300], *stack[10];
jitfp_begin (buffer);
fn = (pdfd) (jit_get_ip ().dptr); fn = (pdfd) (jit_get_ip ().dptr);
jit_leaf (1); jit_leaf (1);
ofs = jit_arg_d (); ofs = jit_arg_d ();
stack[0] = jitfp_getarg_d (ofs); jit_getarg_d (regs[0], ofs);
while (*expr) while (*expr)
{ {
@ -62,26 +61,27 @@ compile_rpn (char *expr)
{ {
double d = strtod (buf, NULL); double d = strtod (buf, NULL);
expr += n - 1; expr += n - 1;
stack[sp++] = jitfp_imm (d); jit_movi_d (regs[sp], d);
sp++;
} }
else if (*expr == '+') else if (*expr == '+')
{ {
stack[sp - 2] = jitfp_add (stack[sp - 2], stack[sp - 1]); jit_addr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]);
sp--; sp--;
} }
else if (*expr == '-') else if (*expr == '-')
{ {
stack[sp - 2] = jitfp_sub (stack[sp - 2], stack[sp - 1]); jit_subr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]);
sp--; sp--;
} }
else if (*expr == '*') else if (*expr == '*')
{ {
stack[sp - 2] = jitfp_mul (stack[sp - 2], stack[sp - 1]); jit_mulr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]);
sp--; sp--;
} }
else if (*expr == '/') else if (*expr == '/')
{ {
stack[sp - 2] = jitfp_div (stack[sp - 2], stack[sp - 1]); jit_divr_d (regs[sp - 2], regs[sp - 2], regs[sp - 1]);
sp--; sp--;
} }
else else
@ -91,7 +91,7 @@ compile_rpn (char *expr)
} }
++expr; ++expr;
} }
jitfp_retval (stack[0]); jit_retval_d (regs[0]);
jit_ret (); jit_ret ();
jit_flush_code ((char *) fn, jit_get_ip ().ptr); jit_flush_code ((char *) fn, jit_get_ip ().ptr);

View file

@ -7,7 +7,7 @@
/*********************************************************************** /***********************************************************************
* *
* Copyright 2000, 2002 Free Software Foundation, Inc. * Copyright 2000, 2002, 2004 Free Software Foundation, Inc.
* Written by Paolo Bonzini. * Written by Paolo Bonzini.
* *
* This file is part of GNU lightning. * This file is part of GNU lightning.
@ -34,104 +34,115 @@
#include "lightning.h" #include "lightning.h"
static jit_insn codeBuffer[300]; static jit_insn codeBuffer[300];
static struct jit_fp buffer[300];
static double a; static double a;
void void
int_test(what, code) int_test(char *what, jit_code code, double b, double c, double d, double e, double f)
char *what;
jit_code code;
{ {
a = -2.6; printf("%s\t\t%d ", what, code.iptr()); a = b; printf("%s\t\t%d ", what, code.iptr());
a = -2.4; printf("%d ", code.iptr()); a = c; printf("%d ", code.iptr());
a = 0.0; printf("%d ", code.iptr()); a = d; printf("%d ", code.iptr());
a = 2.4; printf("%d ", code.iptr()); a = e; printf("%d ", code.iptr());
a = 2.6; printf("%d\n", code.iptr()); a = f; printf("%d\n", code.iptr());
} }
int int
main() main()
{ {
jit_code code; jit_code code;
volatile double x = 0.0;
code.ptr = (char *) codeBuffer; code.ptr = (char *) codeBuffer;
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer); jit_ldi_d(JIT_FPR0, &a);
jitfp_cmp(JIT_R1, JIT_R0, jit_movi_d(JIT_FPR1, 0.0);
jitfp_ldi_d(&a) jit_gtr_d(JIT_R0, JIT_FPR0, JIT_FPR1);
); jit_ltr_d(JIT_R1, JIT_FPR0, JIT_FPR1);
jit_subr_i(JIT_RET, JIT_R0, JIT_R1); /* [greater] - [less] = -1/0/1 */ jit_subr_i(JIT_RET, JIT_R0, JIT_R1); /* [greater] - [less] = -1/0/1 */
jit_ret(); jit_ret();
jit_flush_code(codeBuffer, jit_get_ip().ptr); jit_flush_code(codeBuffer, jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
int_test("compare", code); int_test("compare", code, -2.6, -2.4, 0, 2.4, 2.6);
#endif
#ifdef __GNUC__
jit_set_ip(codeBuffer);
jit_leaf(0);
jit_ldi_d(JIT_FPR0, &a);
jit_movi_d(JIT_FPR1, 0.0);
jit_eqr_d(JIT_R0, JIT_FPR0, JIT_FPR1);
jit_ltgtr_d(JIT_R1, JIT_FPR0, JIT_FPR1);
jit_lshi_i(JIT_R1, JIT_R1, 1);
jit_orr_i(JIT_RET, JIT_R0, JIT_R1);
jit_ret();
jit_flush_code(codeBuffer, jit_get_ip().ptr);
#ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif
#ifndef LIGHTNING_CROSS
int_test("nans", code, x / x, 1 / (a - a), -1 / (a - a), 0.0, -2.0);
#endif
#else
printf ("nans\t\t1 3 3 0 3\n");
#endif #endif
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer); jit_ldi_d(JIT_FPR0, &a);
jitfp_trunc(JIT_RET, jit_truncr_d_i(JIT_RET, JIT_FPR0);
jitfp_ldi_d(&a)
);
jit_ret(); jit_ret();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
int_test("trunc", code); int_test("trunc", code, -2.6, -2.4, 0, 2.4, 2.6);
#endif #endif
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer); jit_ldi_d(JIT_FPR0, &a);
jitfp_ceil(JIT_RET, jit_ceilr_d_i(JIT_RET, JIT_FPR0);
jitfp_ldi_d(&a)
);
jit_ret(); jit_ret();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
int_test("ceil", code); int_test("ceil", code, -2.6, -2.4, 0, 2.4, 2.6);
#endif #endif
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer); jit_ldi_d(JIT_FPR0, &a);
jitfp_floor(JIT_RET, jit_floorr_d_i(JIT_RET, JIT_FPR0);
jitfp_ldi_d(&a)
);
jit_ret(); jit_ret();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
int_test("floor", code); int_test("floor", code, -2.6, -2.4, 0, 2.4, 2.6);
#endif #endif
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer); jit_ldi_d(JIT_FPR0, &a);
jitfp_round(JIT_RET, jit_roundr_d_i(JIT_RET, JIT_FPR0);
jitfp_ldi_d(&a)
);
jit_ret(); jit_ret();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
int_test("round", code); int_test("round", code, -2.6, -2.4, 0, 2.4, 2.6);
#endif #endif
#if 0 && defined JIT_TRANSCENDENTAL #if 0 && defined JIT_TRANSCENDENTAL
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer);
jitfp_sti_d(&a, jitfp_sti_d(&a,
jitfp_log( jitfp_log(
jitfp_exp(jitfp_imm(1.0)) jitfp_exp(jitfp_imm(1.0))
@ -140,7 +151,7 @@ main()
jit_ret(); jit_ret();
code.vptr(); code.vptr();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
printf("log e = \t%f\n", a); printf("log e = \t%f\n", a);
@ -148,7 +159,6 @@ main()
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer);
jitfp_sti_d(&a, jitfp_sti_d(&a,
jitfp_atn( jitfp_atn(
jitfp_imm(1.732050807657) jitfp_imm(1.732050807657)
@ -157,7 +167,7 @@ main()
jit_ret(); jit_ret();
code.vptr(); code.vptr();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
printf("pi = \t%f\n", a*3); printf("pi = \t%f\n", a*3);
@ -165,7 +175,6 @@ main()
jit_set_ip(codeBuffer); jit_set_ip(codeBuffer);
jit_leaf(0); jit_leaf(0);
jitfp_begin(buffer);
jitfp_sti_d(&a, jitfp_sti_d(&a,
jitfp_tan( jitfp_tan(
jitfp_ldi_d(&a) jitfp_ldi_d(&a)
@ -174,7 +183,7 @@ main()
jit_ret(); jit_ret();
code.vptr(); code.vptr();
#ifdef LIGHTNING_DISASSEMBLE #ifdef LIGHTNING_DISASSEMBLE
disassemble(stderr, codeBuffer, jit_get_ip().ptr); disassemble(stderr, (char *)codeBuffer, jit_get_ip().ptr);
#endif #endif
#ifndef LIGHTNING_CROSS #ifndef LIGHTNING_CROSS
printf("tan^2 pi/3 = \t%f\n", a*a); printf("tan^2 pi/3 = \t%f\n", a*a);

View file

@ -1,4 +1,5 @@
compare 1 1 0 1 1 compare -1 -1 0 1 1
nans 0 2 2 1 2
trunc -2 -2 0 2 2 trunc -2 -2 0 2 2
ceil -2 -2 0 3 3 ceil -2 -2 0 3 3
floor -3 -3 0 2 2 floor -3 -3 0 2 2