update parallel rsp

This commit is contained in:
Logan McNaughton committed 2024-01-14 08:20:53 -07:00
1 parent 14673b1b61
commit 6f90f88201
136 files changed
+23411 -5700

No files matched your search

+4
View File
@@ -14,7 +14,11 @@ namespace RSP
{
namespace JIT
{
#if TARGET_OS_TV // tvOS is 64bit but does not allow an infinite amount of VA space
static constexpr bool huge_va = false;
#else
static constexpr bool huge_va = std::numeric_limits<size_t>::max() > 0x100000000ull;
#endif
// On 64-bit systems, we will never allocate more than one block, this is important since we must ensure that
// relative jumps are reachable in 32-bits.
// We won't actually allocate 1 GB on 64-bit, but just reserve VA space for it, which we have basically an infinite amount of.
+16 -5
View File
@@ -1,4 +1,15 @@
/build-aux
+*
*.o
*.lo
*.la
.libs/
.deps/
*/.libs/
*/.deps/
autom4te.cache
aclocal.m4
depcomp
@@ -20,14 +31,14 @@ missing
size
stamp-h1
test-driver
check/.deps
doc/.deps
lib/.deps
m4/libtool.m4
m4/lt~obsolete.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
doc/mdate-sh
doc/texinfo.tex
lightning.pc
include/lightning.h
build-aux/
+3
View File
@@ -0,0 +1,3 @@
[submodule "gnulib"]
path = gnulib
url = git://git.sv.gnu.org/gnulib.git
+3 -3
View File
@@ -6,7 +6,7 @@
[subrepo]
remote = https://git.savannah.gnu.org/git/lightning.git
branch = master
commit = b0b8eb5e856c0d29053dc842e1919a2eb58c8cda
parent = 9f797430963d9cf0fcef7d963466f9cac7026de2
commit = 75e5274ba59feab99a2afcf329d890911ed01eaf
parent = b7d23a9d07791c7006d57c58ab1e442103741cd6
method = merge
cmdver = 0.4.1
cmdver = 0.4.5
+317 -13
View File
@@ -1,3 +1,307 @@
2023-02-09 Paulo Andrade <pcpa@gnu.org>
* check/Makefile.am: Update for new bit.tst test, to check the
new clor, clzr, ctor and ctzr instructions.
* check/all.tst: Update to verify encoding of new instructions.
* check/lightning.c: Update to have the lightning "assembler"
understanding the new instructions.
* include/lightning.h.in: Define new codes for new instructions.
* lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c, lib/jit_hppa.c,
lib/jit_ia64.c, lib/jit_loongarch.c, lib/jit_mips.c, lib/jit_ppc.c,
lib/jit_riscv.c, lib/jit_s390.c, lib/jit_sparc.c, lib/jit_x86.c:
Implement fallback version of new instructions.
* lib/jit_fallback.c: Actual implementation of the fallbacks of
the new instructions.
* lib/jit_names.c: Update to print debug information of new
instructions.
2023-01-26 Paulo Andrade <pcpa@gnu.org>
* check/riprel.c, check/riprel.ok: New check files.
* check/Makefile.am: Support for new riprel test.
* lib/jit_x86-cpu.c, lib/jit_x86-sse.c, lib/jit_x86.c: Implement
%rip relative addressing when reliable. Currently disabled for
x32 and _WIN32; could be added for positive relative addresses
only where it should work.
* lib/lightning.c: Correct problem added in previous patch due
to not testing on a 32 bit environment.
2023-01-23 Paulo Andrade <pcpa@gnu.org>
* lib/jit_mips-cpu.c, lib/jit_mips-cpu.c: Use pseudo instructions
"b" (BEQ(0,0,disp)) and "bal" (BGEZAL(0,disp)) for mips2, when an
unconditional branch or function call is known to be in range of a
relative jump. This should significantly reduce jit size generation.
2023-01-20 Paulo Andrade <pcpa@gnu.org>
* lib/jit_mips-cpu.c, lib/jit_mips.c, lib/jit_rewind.c: Adapt
code to implement a variable framesize and optimize frame pointer
for simple leaf functions.
2023-01-19 Paulo Andrade <pcpa@gnu.org>
* lib/jit_riscv.c, lib/jit_riscv-cpu.c: Adapt code to use a
variable framesize. Previously it was aligning the stack at
8 bytes, not 16. Now functions are called with a 16 byte aligned
stack.
2023-01-18 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_private.h: Include new framesize field
of jit_compiler_t; add new alist field for jit_function_t; add
new cvt_offset and need_stack fields specific to x86.
* lib/jit_x86.c, lib/jit_x86-cpu: Rewrite code to create stack
frames, so that less stack space can be used if no, or very few
callee save registers are modified in a function.
* jit_x86-sse.c, jit_x86-x87.c: Make CVT_OFFSET variable, and
dynamically allocated; this is required to avoid needing to
modify twice %rsp at function prologs, even if no stack space
is used.
2022-11-09 Paulo Andrade <pcpa@gnu.org>
* configure.ac: Add new --enable-devel-strong-type-checking
option.
* include/lightning.h.in: Rework to not need to know if
PACKED_STACK is defined, and add a new argument to _jit_arg,
_jit_putarg{r,i}, _jit_pusharg{r,i} and _jit_ret{r,i} to have
the same code path if PACKED_STACK is defined or not, and also
to implement STRONG_TYPE_CHECK enabled with the new
--enable-devel-strong-type-checking.
* include/lightning/jit_private.h: Add new macros to add assertions
for STRONG_TYPE_CHECK and avoid pasting tokens in jit_inc_synth*
when the token is not a static known value.
* lib/jit_aarch64.c: The first implementation of the new code,
working correctly in Apple M1 and with and without STRONG_TYPE_CHECK
in Linux.
2022-11-08 Paulo Andrade <pcpa@gnu.org>
Add support for packed stack arguments as used by Apple M1
aarch64 cpus. This requires a major redesign in how Lightning
works, because contrary to all other supported ports, in this
case arguments must be truncated and sign/zero extended if
passed in registers, but when receiving the argument, there
is no need to truncate and sign/zero extend.
Return values are also treated this way. The callee must
truncate sign/zero extend, not the caller.
check/Makefile.am: Add LIGHTNING_CFLAGS to AM_CFLAGS.
check/all.tst: Implement paired arg/getarg/pusharg/putarg/ret
codes to validate they do not generate assertions.
* check/allocar.tst, check/call.tst, check/fib.tst, check/put.tst,
check/stack.tst: Update to pass in all build types.
check/lightning.c: Add new codes for extra codes to handle
packed stack.
* configure.ac: Add a preprocessor define to know if packed stack
need is required. This is not really used, as it was moved to
jit_aarch64.h.
* doc/Makefile.am: Add LIGHTNING_CFLAGS to AM_CFLAGS.
* doc/rpn.c: Update to pass in all build types.
include/lightning.h.in: Add new codes and reorder enum.
* include/lightning/jit_aarch64.h: Detect condition of needing
a packed stack.
* lib/jit_aarch64-sz.c: Regenerate.
* lib/jit_aarch64.c: Major updates for packed stack.
* lib/jit_names.c: Updates for debug output.
* lib/lightning.c: Update for new codes.
2022-10-31 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
Add new skip instruction.
* .gitignore: Update from Gnulib.
* check/Makefile.am: Add tests.
* check/lightning.c: Handle skip instructions.
* check/protect.c: Rewrite with skip.
* check/skip.ok: New test.
* check/skip.tst: New test.
* doc/body.texi: Document the skip instruction.
* include/lightning.h.in: Add the skip instruction.
* lib/jit_aarch64-sz.c: Update for skip instruction.
* lib/jit_aarch64.c: Implement skip instruction.
* lib/jit_alpha-sz.c: Update for skip instruction.
* lib/jit_alpha.c: Implement skip instruction.
* lib/jit_arm-sz.c: Update for skip instruction.
* lib/jit_arm.c: Implement skip instruction.
* lib/jit_hppa-sz.c: Update for skip instruction.
* lib/jit_hppa.c: Implement skip instruction.
* lib/jit_ia64-sz.c: Update for skip instruction.
* lib/jit_ia64.c: Implement skip instruction.
* lib/jit_loongarch-sz.c: Update for skip instruction.
* lib/jit_loongarch.c: Implement skip instruction.
* lib/jit_mips-sz.c: Update for skip instruction.
* lib/jit_mips.c: Implement skip instruction.
* lib/jit_names.c: Update for skip instruction.
* lib/jit_ppc-sz.c: Update for skip instruction.
* lib/jit_ppc.c: Implement skip instruction.
* lib/jit_riscv-sz.c: Update for skip instruction.
* lib/jit_riscv.c: Implement skip instruction.
* lib/jit_s390-sz.c: Update for skip instruction.
* lib/jit_s390.c: Implement skip instruction.
* lib/jit_size.c: Treat align and skip in a special way.
* lib/jit_sparc-sz.c: Update for skip instruction.
* lib/jit_sparc.c: Implement skip instruction.
* lib/jit_x86-sz.c: Update for skip instruction.
* lib/jit_x86.c: Implement skip instruction.
* lib/lightning.c: Classify skip instruction.
2022-10-30 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
Add user-visible functions jit_protect and jit_unprotect.
* check/Makefile.am: Add test for jit_protect and jit_unprotect.
* check/protect.c: New test.
* doc/body.texi: Add documentation for jit_protect and
jit_unprotect.
* include/lightning.h.in: Add prototypes for jit_protect and
jit_unprotect.
* include/lightning/jit_private.h: Add a field to store the size
of the protected memory.
* lib/lightning.c: Remember the size of the protected memory and
implement the two new functions.
2022-10-12 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_loongarch.h, lib/jit_loongarch-cpu.c,
lib/jit_loongarch-fpu.c, lib/jit_loongarch-sz.c, lib/jit_loongarch.c:
New files implementing the first version of the new loongarch port.
* check/float.tst: Add preprocessor checks for NaN and +-Inf
values converted to integers for loongarch.
* configure.ac: Add check and conditionals for new architecture.
* include/lightning.h.in, check/lightning.c,
include/lightning/Makefile.am, include/lightning/jit_private.h,
lib/Makefile.am, lib/jit_size.c, lib/lightning.c: Update for new
port.
2022-10-05 Paulo Andrade <pcpa@gnu.org>
* check/lightning.c: Remove -Dmacro=value from usage and attempt
to parse it. It was buggy and not properly implemented. Now
it pass any extra options to the generated jit. To pass any
option starting with '-' need to also use '--'.
* check/collatz.e: New sample file showing an example of jit
generation.
2022-10-04 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_private.h: Add new flag to jit_block_t.
* lib/lightning.c: Rewrite register liveness and state at block
entry code to avoid a very expensive and non scaling code path.
Now it attempts to do as few as possible recomputations when
merging state of adjacent blocks, still doing one extra nop pass
(in the sense that it will not find any changes) to make sure the
logic is correct.
2022-09-30 Paulo Andrade <pcpa@gnu.org>
* include/lightning/jit_private.h: Implement new data structures
specific to riscv.
* lib/jit_disasm.c: Extra disassemble code for riscv constant pool.
* lib/jit_riscv-cpu.c: Modify movi to use constant pool if 3 or
more instructions are required to construct constant and modify
movi_p to use a pc relative load from a constant pool.
lib/jit_riscv-sz.c: Update for new constant pool code. Most
instructions that need 64 bit constants are significantly reduced.
* lib/jit_riscv.c: Implement most of the constant pool code.
* lib/jit_size.c: Update for estimate of code generation size.
* lib/lightning.c: Update for riscv specific code, and also make
sure to mprotect the constant pool as executable.
2022-09-08 Paulo Andrade <pcpa@gnu.org>
* lib/jit_fallback.c: Implement fallback compare and swap with
pthreads.
* check/Makefile.am: Update for new cas{r,i} simple test.
* check/catomic.c, check/catomic.ok: New test case for
simple compare and swap atomic operation.
* check/lightning.c: Add entries to be able to use
the new compare and swap atomic operation. Still missing
a general test, only the basic C version.
* include/lightning.h.in: Include pthread.h, even if not
needing a fallback compare and swap.
* include/lightning/jit_private.h: Add support for a register pair
in second argument. Required by the new casr and casi operations.
* lib/jit_aarch64-cpu.c, lib/jit_aarch64-sz.c, lib/jit_aarch64.c,
lib/jit_ppc-cpu.c, lib/jit_ppc-sz.c, lib/jit_ppc.c, lib/jit_x86-cpu.c,
lib/jit_x86-sz.c, lib/jit_x86.c: Implement inline code for compare
and swap.
* lib/jit_arm-cpu.c, lib/jit_arm-sz.c, lib/jit_arm.c: Implement
inline code for compare and swap if cpu is armv7, otherwise, use
a fallback with pthreads.
* lib/jit_alpha-cpu.c, lib/jit_alpha-sz.c, lib/jit_alpha.c,
lib/jit_hppa-cpu.c, lib/jit_hppa-sz.c, lib/jit_hppa.c,
lib/jit_ia64-cpu.c, lib/jit_ia64-sz.c, lib/jit_ia64.c,
lib/jit_mips-cpu.c, lib/jit_mips-sz.c, lib/jit_mips.c,
lib/jit_riscv-cpu.c, lib/jit_riscv-sz.c, lib/jit_riscv.c,
lib/jit_s390-cpu.c, lib/jit_s390-sz.c, lib/jit_s390.c,
lib/jit_sparc-cpu.c, lib/jit_sparc-sz.c, lib/jit_sparc.c: Implement
fallback compare and swap with pthreads. At least some of these
should be updated for inline code generation.
* lib/jit_names.c, lib/jit_print.c: lib/lightning.c: Update for the
new compare and swap operation.
* doc/body.texi: Add simple documentation of the compare and swap
new operation.
2022-08-12 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
Document jit_align.
* doc/body.texi: Add documentation for jit_align.
2022-05-14 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h.in: Reorder jit_mov{n,z}r in instruction list.
* lib/jit_alpha.c, lib/jit_alpha-cpu.c, lib/jit_hppa.c,
lib/jit_hppa-cpu.c, lib/jit_ia64.c, lib/jit_ia64-cpu.c,
lib/jit_riscv.c, lib/jit_riscv-cpu.c, lib/jit_s390.c,
lib/jit_s390-cpu.c, lib/jit_sparc.c, lib/jit_sparc-cpu.c:
Implement fallback jit_mov{n,z}r. These are a somewhat cheap
implementation, but should be reviewed for the arches that already
have a proper conditional move.
* lib/jit_arm-sz.c, lib/jit_mips-sz.c: Add missing maximum size
estimative and reorder.
* lib/jit_aarch64-sz.c, lib/jit_x86-sz.c, lib/jit_ppc-sz.c:
Reorder entry to match definition order.
* lib/jit_aarch64-sz.c, lib/jit_alpha-sz.c, lib/jit_hppa-sz.c,
lib/jit_ia64-sz.c, lib/jit_riscv-sz.c, lib/jit_s390-sz.c,
lib/jit_sparc-sz.c: Add heuristic value, basically the sum of
the cost of a movr + beqr.
* lib/jit_names.c: Add entries for debug output of mov{n,z}r.
* lib/lightning.c: Use proper bitmask in jit_classify.
2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
* check/Makefile.am: Add test for the live instruction.
* check/live.ok: New file.
* check/live.tst: New file.
* doc/body.texi: Add documentation for the live instruction and
for jit_get_reg/jit_get_unreg. Fix menu entries.
* include/lightning.h.in (jit_get_reg, jit_unget_reg): Expose the
macros in the public header file.
* include/lightning/jit_private.h (jit_get_reg, jit_unget_reg):
Remove the macros from the private header file.
2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
* Makefile.am, check/Makefile.am, doc/Makefile.am,
lib/Makefile.am: Include $(top_builddir)/include in include paths
for the autoconf-generated header file lightning.h.
2021-04-03 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
* doc/.gitignore: Add version.texi to list of ignored files.
* doc/version.texi: Remove file from version control.
2020-18-04 Paulo Andrade <pcpa@gnu.org>
* lib/jit_x86-cpu.c, lib/jit_x86.c: Implement %rip relative
calls and jumps on x86_64. Currently very conservative, assuming
a jit block can be larger than 2G, so, if a jump or call is in
the same jit generation, but target is unknown, use an indirect
branch (could have an option to assume a jit code block is
never larger than 2G). Also a deoptimization is that now does
not always generate ip relative jmpi; previously implicitly
assumed jmpi would never be larger than 2G. Overall still an
optimization.
2020-23-01 Paulo Andrade <pcpa@gnu.org>
* lib/lightning.c: Add a proper fix to the condition of considering
@@ -26,7 +330,7 @@
to the set of registers to scan for live range, what might
consume a lot of cpu time, doing nothing.
2019-09-16 Marc Nieper-WiÃkirchen <marc@nieper-wisskirchen.de>
2019-09-16 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
* include/lightning/jit_x86.h, lib/jit_x86.c: Correct x86_64
backend, made %r12 a callee-save register as dictated by the
@@ -65,7 +369,7 @@
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=925129
* THANKS: update.
2019-08-29 Marc Nieper-WiÃkirchen <marc@nieper-wisskirchen.de>
2019-08-29 Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
* include/lightning/jit_private.h: Move definition of offsetof
from the public header file here.
@@ -1415,7 +1719,7 @@
* include/lightning/jit_arm.h: Correct wrong jit_f macro
definition.
* include/lightning/jit_ia64.h, include/lightning/jit_ppc.h:
* include/lightning/jit_ia64.h, include/lightning/jit_ppc.h:
Correct wrong jit_r macro definition.
* lib/jit_x86-x87.c, lib/jit_x86.c: Actually use the
@@ -1884,7 +2188,7 @@
divr_f and divrd_d implementation.
* check/lightning.c: Add __ia64__ preprocessor define
on Itanium.
on Itanium.
* check/alu.inc, check/clobber.tst, check/float.tst: Define
several macros conditionally to __ia64__. This is required
@@ -2991,7 +3295,7 @@
* include/lightning/jit_x86.h: Correct typo in macro name.
* lib/jit_arm.c, lib/jit_arm-cpu.c, lib/jit_mips.c,
lib/jit_mips-cpu.c, lib/jit_ppc.c, lib/jit_ppc-cpu.c,
lib/jit_mips-cpu.c, lib/jit_ppc.c, lib/jit_ppc-cpu.c,
lib/jit_x86.c, lib/jit_x86-cpu.c: Correct wrong code to get
current jit function pointer.
@@ -3225,7 +3529,7 @@
* lightning/i386/core.h (jit_ldr_c, jit_ldxr_c, jit_ldr_s,
jit_ldxr_s): Move...
* lightning/i386/core-32.h: ... here.
* lightning/i386/core-64.h (jit_ldr_c, jit_ldxr_c, jit_ldr_s,
* lightning/i386/core-64.h (jit_ldr_c, jit_ldxr_c, jit_ldr_s):
Use movsbq and movswq.
2010-08-10 Paulo César Pereira de Andrade <pcpa@mandriva.com.br>
@@ -3306,11 +3610,11 @@
* lightning/ppc/funcs.h (jit_flush_code): modified the computation
of start/end. The pointer arithmetic was done without casting. It
prevented compilation with recent gcc versions.
prevented compilation with recent gcc versions.
* lightning/ppc/core.h (jit_pushr_i): The offset for the store was
incorrect. Should have been 4 bytes below SP (not above).
* lightning/ppc/core.h (jit_popr_i): The offset for the load was
incorrect. Should have been 0 (not +8).
* lightning/ppc/core.h (jit_popr_i): The offset for the load was
incorrect. Should have been 0 (not +8).
2008-06-17 Paolo Bonzini <bonzini@gnu.org>
@@ -3589,7 +3893,7 @@
* lightning/i386/fp-32.h: ... here.
* lightning/i386/fp-64.h: Write the code.
* lightning/sparc/fp.h: Fix jit_extr_{f_d,d_f} register order.
2006-11-22 Paolo Bonzini <bonzini@gnu.org>
* lightning/i386/asm-i386.h: Move x86-64 instructions...
@@ -3803,7 +4107,7 @@
2006-01-23 Paolo Bonzini <bonzini@gnu.org>
* configure.ac: Fix comments in config.h.in.
2005-11-25 Paolo Bonzini <bonzini@gnu.org>
* lightning/sparc/fp.h: Fix header comment.
@@ -4123,7 +4427,7 @@
* lightning/ppc/funcs.h: correctly align stack pointer
No changelogs for the assemblers (lightning directory) until 1.0
2003-03-27 Paolo Bonzini <bonzini@gnu.org>
* tests/printf2.c: new test
@@ -4135,7 +4439,7 @@ No changelogs for the assemblers (lightning directory) until 1.0
2001-01-19 Paolo Bonzini <bonzini@gnu.org>
* configure.in: support cross-assembling
* disass/bfd.h, disass/dis-asm.h, disass/dis-buf.c,
disass/i386-dis.c, disass/i386.h, disass/ppc-dis.c,
disass/ppc.h, disass/ppc-opc.c, disass/sparc-dis.c,
+6 -2
View File
@@ -1,5 +1,5 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
# Copyright 2000, 2001, 2002, 2012-2023 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
@@ -17,18 +17,22 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = \
gnulib-lib \
check \
doc \
include \
lib
EXTRA_DIST = m4/gnulib-cache.m4
pkgconfiglibdir = $(libdir)/pkgconfig
pkgconfiglib_DATA = lightning.pc
if get_jit_size
JIT_SIZE_PATH = "$(top_builddir)/jit_$(cpu)-sz.c"
AM_CPPFLAGS=-DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)'
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE $(LIGHTNING_CFLAGS)
AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
-D_GNU_SOURCE $(LIGHTNING_CFLAGS)
noinst_PROGRAMS = size
size_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
+2
View File
@@ -1,3 +1,5 @@
GNU lightning is a library to aid in making portable programs
that compile assembly code at run time. For more information,
look at the info documentation.
For help building lightning, see README-hacking.
+106
View File
@@ -0,0 +1,106 @@
This README-hacking file describes the development environment.
Everything related to the development of GNU lightning is on Savannah:
https://savannah.gnu.org/projects/lightning/.
* Working from the Repository
** Autotools
This distribution uses the latest stable versions of Automake, Autoconf. If
you are getting the sources from git (or change configure.ac), you'll need
to have these tools installed to (re)build. All
of these programs are available from ftp://ftp.gnu.org/gnu.
If you're using a GNU/Linux distribution, the easiest way to install these
packages depends on your system. The following shell command should work
for Debian-based systems such as Ubuntu:
$ sudo apt-get install autoconf automake
** Building
If you intend to do development work with lightning, it's useful to build
lightning with its disassembler feature enabled. This optional feature
requires additional dependencies. On Ubuntu, this command should work:
$ sudo apt-get install binutils-dev libiberty-dev zlib1g-dev
After getting the git sources, and installing the tools above, you can run
$ ./bootstrap
$ ./configure
$ make
$ make check
to do a fresh build. At this point, there should be no difference between
your local copy, and the master copy:
$ git diff
should output no difference.
After that first time, running make should suffice.
To install lightning:
$ sudo make install
** Gnulib
This distribution also uses Gnulib (https://www.gnu.org/software/gnulib) to
share common files, stored as a submodule in git.
** Updating
$ git pull
$ git submodule update
** Updating a submodule
To update a submodule, say gnulib, do as follows:
Get the most recent version of the master branch from git.
$ cd gnulib
$ git pull
Make sure GNU lightning can live with that version of gnulib.
$ cd ..
$ ./bootstrap
$ make distcheck
Register your changes.
$ git commit ...
----
Copyright 2021 Free Software Foundation, Inc.
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 3, 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 this program. If not, see
<http://www.gnu.org/licenses/>.
Local Variables:
mode: outline
fill-column: 76
End:
+1
View File
@@ -19,3 +19,4 @@ Holger Hans Peter Freyther <holger@moiji-mobile.com>
Jon Arintok <jon.arintok@gmail.com>
Bruno Haible <bruno@clisp.org>
Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de>
Paul Cercueil <paul@crapouillou.net>
-27
View File
@@ -1,28 +1 @@
* Validate that divrem in jit_x86-cpu.c is not modifying
the non result arguments. This is not verified by clobber.tst,
as it only checks registers not involved in the operation
(because it does not know about values being set as input
for the the operation).
* Write a simple higher level language implementation generating
jit with lightning, that could be some lisp or C like language.
* rerun ./configure --enable-devel-get-jit-size and regenerate
the related jit_$arch-sz.c for the ports where nodata is
meaningful:
hppa (done)
i586 (done)
ia64
mips o32 (done)
mips n32
mips n64
powerpc 32 (done)
powerpc 64 (done)
ppc
s390x (done)
sparc (done)
x86_64 (done)
Missing ones are due to no longer (remote) access to such hosts
and may be broken with jit_set_data(..., JIT_DISABLE_DATA).
(ia64 hp-ux or linx), (irix mips for 32 or 64 abi), and
(darwin ppc).
+1090
View File
File diff suppressed because it is too large. Load diff
+76
View File
@@ -0,0 +1,76 @@
# Bootstrap configuration.
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# gnulib modules used by this package.
gnulib_modules="
"
# gnulib library name.
gnulib_name=libgnu
# directories.
source_base=gnulib-lib
doc_base=gnulib-doc
# Additional xgettext options to use. Use "\\\newline" to break lines.
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--from-code=UTF-8\\\
--flag=asprintf:2:c-format --flag=vasprintf:2:c-format\\\
--flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\
--flag=wrapf:1:c-format\\\
'
# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]"
# appears in configure.ac, exclude some unnecessary files.
# Without grep's -E option (not portable enough, pre-configure),
# the following test is ugly. Also, this depends on the existence
# of configure.ac, not the obsolescent-named configure.in. But if
# you're using this infrastructure, you should care about such things.
gettext_external=0
grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null &&
gettext_external=1
grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null &&
gettext_external=1
if test $gettext_external = 1; then
# Gettext supplies these files, but we don't need them since
# we don't have an intl subdirectory.
excluded_files='
m4/glibc2.m4
m4/intdiv0.m4
m4/lcmessage.m4
m4/lock.m4
m4/printf-posix.m4
m4/size_max.m4
m4/uintmax_t.m4
m4/ulonglong.m4
m4/visibility.m4
m4/xsize.m4
'
fi
# Build prerequisites
buildreq="\
autoconf 2.59
automake 1.9.6
git 1.5.5
tar -
"
bootstrap_sync=true
+67
View File
@@ -0,0 +1,67 @@
*.nodata
nodata
*.log
*.trs
3to2
bswap
add
align
allocai
allocar
alu_add
alu_and
alu_com
alu_div
alu_lsh
alu_mul
alu_neg
alu_or
alu_rem
alu_rsb
alu_rsh
alu_sub
alu_xor
alux_add
alux_sub
bp
branch
call
carg
carry
catomic
ccall
clobber
ctramp
cva_list
cvt
divi
fib
float
fop_abs
fop_sqrt
hton
jmpr
ldsti
ldstr
ldstr-c
ldstxi
ldstxi-c
ldstxr
ldstxr-c
lightning
live
movzr
put
qalu_div
qalu_mul
range
ranger
ret
rpn
self
setcode
stack
tramp
va_list
varargs
+41 -16
View File
@@ -1,5 +1,5 @@
#
# Copyright 2012-2019 Free Software Foundation, Inc.
# Copyright 2012-2023 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
@@ -14,9 +14,11 @@
# License for more details.
#
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
-D_GNU_SOURCE $(LIGHTNING_CFLAGS)
check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list
check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list \
catomic protect riprel
lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
lightning_SOURCES = lightning.c
@@ -42,6 +44,15 @@ carg_SOURCES = carg.c
cva_list_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
cva_list_SOURCES = cva_list.c
catomic_LDADD = $(top_builddir)/lib/liblightning.la -lm -lpthread $(SHLIB)
catomic_SOURCES = catomic.c
protect_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
protect_SOURCES = protect.c
riprel_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
riprel_SOURCES = riprel.c
$(top_builddir)/lib/liblightning.la:
cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la
@@ -65,6 +76,7 @@ EXTRA_DIST = \
ldstxi-c.tst ldstxi-c.ok \
cvt.tst cvt.ok \
hton.tst hton.ok \
bswap.tst bswap.ok \
branch.tst branch.ok \
alu.inc \
alu_add.tst alu_add.ok \
@@ -82,6 +94,7 @@ EXTRA_DIST = \
alu_rsh.tst alu_rsh.ok \
alu_com.tst alu_com.ok \
alu_neg.tst alu_neg.ok \
movzr.tst movzr.ok \
fop_abs.tst fop_abs.ok \
fop_sqrt.tst fop_sqrt.ok \
varargs.tst varargs.ok \
@@ -91,6 +104,7 @@ EXTRA_DIST = \
call.tst call.ok \
float.tst float.ok \
jmpr.tst jmpr.ok \
live.tst live.ok \
put.tst put.ok \
qalu.inc \
qalu_mul.tst qalu_mul.ok \
@@ -98,8 +112,10 @@ EXTRA_DIST = \
range.tst range.ok \
ranger.tst ranger.ok \
ret.tst ret.ok \
skip.tst skip.ok \
tramp.tst tramp.ok \
va_list.tst va_list.ok \
bit.tst bit.ok \
check.sh \
check.x87.sh \
check.arm.sh check.swf.sh \
@@ -107,7 +123,8 @@ EXTRA_DIST = \
check.arm4.swf.sh \
check.nodata.sh \
check.x87.nodata.sh \
run-test all.tst
run-test all.tst \
collatz.tst factorial.tst
base_TESTS = \
3to2 add align allocai \
@@ -115,20 +132,21 @@ base_TESTS = \
ldstr ldsti \
ldstxr ldstxi \
ldstr-c ldstxr-c ldstxi-c \
cvt hton branch \
cvt hton bswap branch \
alu_add alux_add \
alu_sub alux_sub alu_rsb \
alu_mul alu_div alu_rem \
alu_and alu_or alu_xor \
alu_lsh alu_rsh \
alu_com alu_neg \
movzr \
fop_abs fop_sqrt \
varargs stack \
clobber carry call \
float jmpr put \
float jmpr live put \
qalu_mul qalu_div \
range ranger ret tramp \
va_list
range ranger ret skip tramp \
va_list bit
$(base_TESTS): check.sh
$(LN_S) $(srcdir)/check.sh $@
@@ -150,6 +168,7 @@ x87_TESTS = \
alu_and.x87 alu_or.x87 alu_xor.x87 \
alu_lsh.x87 alu_rsh.x87 \
alu_com.x87 alu_neg.x87 \
movzr.x87 \
fop_abs.x87 fop_sqrt.x87 \
varargs.x87 stack.x87 \
clobber.x87 carry.x87 call.x87 \
@@ -173,6 +192,7 @@ x87_nodata_TESTS = \
alu_and.x87.nodata alu_or.x87.nodata alu_xor.x87.nodata \
alu_lsh.x87.nodata alu_rsh.x87.nodata \
alu_com.x87.nodata alu_neg.x87.nodata \
movzr.x87.nodata \
fop_abs.x87.nodata fop_sqrt.x87.nodata \
varargs.x87.nodata stack.x87.nodata \
clobber.x87.nodata carry.x87.nodata call.x87.nodata \
@@ -191,13 +211,14 @@ arm_TESTS = \
rpn.arm ldstr.arm ldsti.arm \
ldstxr.arm ldstxi.arm \
ldstr-c.arm ldstxr-c.arm ldstxi-c.arm \
cvt.arm hton.arm branch.arm \
cvt.arm hton.arm bswap.arm branch.arm \
alu_add.arm alux_add.arm \
alu_sub.arm alux_sub.arm alu_rsb.arm \
alu_mul.arm alu_div.arm alu_rem.arm \
alu_and.arm alu_or.arm alu_xor.arm \
alu_lsh.arm alu_rsh.arm \
alu_com.arm alu_neg.arm \
movzr.arm \
fop_abs.arm fop_sqrt.arm \
varargs.arm stack.arm \
clobber.arm carry.arm call.arm \
@@ -216,13 +237,14 @@ swf_TESTS = \
rpn.swf ldstr.swf ldsti.swf \
ldstxr.swf ldstxi.swf \
ldstr-c.swf ldstxr-c.swf ldstxi-c.swf \
cvt.swf hton.swf branch.swf \
cvt.swf hton.swf bswap.swf branch.swf \
alu_add.swf alux_add.swf \
alu_sub.swf alux_sub.swf alu_rsb.swf \
alu_mul.swf alu_div.swf alu_rem.swf \
alu_and.swf alu_or.swf alu_xor.swf \
alu_lsh.swf alu_rsh.swf \
alu_com.swf alu_neg.swf \
movzr.swf \
fop_abs.swf fop_sqrt.swf \
varargs.swf stack.swf \
clobber.swf carry.swf call.swf \
@@ -239,13 +261,14 @@ arm_swf_TESTS = \
rpn.arm.swf ldstr.arm.swf ldsti.arm.swf \
ldstxr.arm.swf ldstxi.arm.swf \
ldstr-c.arm.swf ldstxr-c.arm.swf ldstxi-c.arm.swf \
cvt.arm.swf hton.arm.swf branch.arm.swf \
cvt.arm.swf hton.arm.swf bswap.arm.swf branch.arm.swf \
alu_add.arm.swf alux_add.arm.swf \
alu_sub.arm.swf alux_sub.arm.swf alu_rsb.arm.swf \
alu_mul.arm.swf alu_div.arm.swf alu_rem.arm.swf \
alu_and.arm.swf alu_or.arm.swf alu_xor.arm.swf \
alu_lsh.arm.swf alu_rsh.arm.swf \
alu_com.arm.swf alu_neg.arm.swf \
movzr.arm.swf \
fop_abs.arm.swf fop_sqrt.arm.swf \
varargs.arm.swf stack.arm.swf \
clobber.arm.swf carry.arm.swf call.arm.swf \
@@ -263,13 +286,14 @@ arm4_swf_TESTS = \
rpn.arm4.swf ldstr.arm4.swf ldsti.arm4.swf \
ldstxr.arm4.swf ldstxi.arm4.swf \
ldstr-c.arm4.swf ldstxr-c.arm4.swf ldstxi-c.arm4.swf \
cvt.arm4.swf hton.arm4.swf branch.arm4.swf \
alu_add.arm4.swf alux_add.arm4.swf \
cvt.arm4.swf hton.arm4.swf bswap.arm4.swf \
branch.arm4.swf alu_add.arm4.swf alux_add.arm4.swf \
alu_sub.arm4.swf alux_sub.arm4.swf alu_rsb.arm4.swf \
alu_mul.arm4.swf alu_div.arm4.swf alu_rem.arm4.swf \
alu_and.arm4.swf alu_or.arm4.swf alu_xor.arm4.swf \
alu_lsh.arm4.swf alu_rsh.arm4.swf \
alu_com.arm4.swf alu_neg.arm4.swf \
movzr.arm4.swf \
fop_abs.arm4.swf fop_sqrt.arm4.swf \
varargs.arm4.swf stack.arm4.swf \
clobber.arm4.swf carry.arm4.swf call.arm4.swf \
@@ -297,22 +321,23 @@ nodata_TESTS = \
alu_and.nodata alu_or.nodata alu_xor.nodata \
alu_lsh.nodata alu_rsh.nodata \
alu_com.nodata alu_neg.nodata \
movzr.nodata \
fop_abs.nodata fop_sqrt.nodata \
varargs.nodata stack.nodata \
clobber.nodata carry.nodata call.nodata \
float.nodata jmpr.nodata tramp.nodata \
range.nodata ranger.nodata put.nodata \
va_list.nodata
va_list.nodata bit.nodata
$(nodata_TESTS): check.nodata.sh
$(LN_S) $(srcdir)/check.nodata.sh $@
TESTS += $(nodata_TESTS)
endif
TESTS += ccall self setcode nodata ctramp carg cva_list
TESTS += ccall self setcode nodata ctramp carg cva_list catomic \
protect riprel
CLEANFILES = $(TESTS)
#TESTS_ENVIRONMENT=$(srcdir)/run-test;
debug: lightning
$(LIBTOOL) --mode=execute gdb lightning
+1 -1
View File
@@ -17,7 +17,7 @@ L2:
align $(__WORDSIZE / 8) /* possible nops */
L3:
jmpi L1
align $(__WORDSIZE / 8) /* possible nops */
align 32 /* Force nops */
L4:
prepare
pushargi fmt
+53 -7
View File
@@ -2,15 +2,16 @@
.code
prolog
allocai 32 $buf
arg $c
arg $uc
arg $s
arg $us
arg $i
arg_c $c
arg_c $uc
arg_s $s
arg_s $us
arg_i $i
arg_i $ui
#if __WORDSIZE == 64
arg $ui
arg $l
arg_l $l
#endif
arg $a
getarg_c %r0 $c
getarg_uc %r0 $uc
getarg_s %r0 $s
@@ -20,6 +21,25 @@
getarg_ui %r0 $ui
getarg_l %r0 $l
#endif
getarg %r0 $a
putargr_c %r0 $c
putargi_c 1 $c
putargr_uc %r0 $uc
putargi_uc 1 $uc
putargr_s %r0 $s
putargi_s 1 $s
putargr_us %r0 $us
putargi_us 1 $us
putargr_i %r0 $i
putargi_i 1 $ui
#if __WORDSIZE == 64
putargr_ui %r0 $ui
putargi_ui 1 $ui
putargr_l %r0 $l
putargi_l 1 $l
#endif
putargr %r0 $a
putargi 1 $a
addr %r0 %r1 %r2
addi %r0 %r1 2
addcr %r0 %r1 %r2
@@ -64,6 +84,10 @@
rshi_u %r0 %r1 2
negr %r0 %r1
comr %r0 %r1
clor %r0 %r1
clzr %r0 %r1
ctor %r0 %r1
ctzr %r0 %r1
ltr %r0 %r1 %r2
lti %r0 %r1 2
ltr_u %r0 %r1 %r2
@@ -205,6 +229,15 @@ label:
callr %r0
calli label
prepare
pushargr_c %r0
pushargr_uc %r0
pushargr_s %r0
pushargr_us %r0
pushargr_i %r0
#if __WORDSIZE == 64
pushargr_ui %r0
pushargr_l %r0
#endif
pushargr %r0
finishr %r0
prepare
@@ -212,6 +245,15 @@ label:
ellipsis
finishi 0x80000000
ret
retr_c %r1
retr_uc %r1
retr_s %r1
retr_us %r1
retr_i %r1
#if __WORDSIZE == 64
retr_ui %r1
retr_l %r1
#endif
retr %r1
reti 2
retval_c %r1
@@ -225,6 +267,8 @@ label:
#endif
arg_f $f
getarg_f %f1 $f
putargr_f %f1 $f
putargi_f 1.0 $f
addr_f %f0 %f1 %f2
addi_f %f0 %f1 0.5
subr_f %f0 %f1 %f2
@@ -323,6 +367,8 @@ unordi:
retval_f %f1
arg_d $f
getarg_d %f1 $f
putargr_d %f1 $f
putargi_d 1.0 $f
addr_d %f0 %f1 %f2
addi_d %f0 %f1 0.5
subr_d %f0 %f1 %f2
+62 -62
View File
@@ -55,7 +55,7 @@ fill##T##done: \
#define fill_us fill_s
#define fill_ui fill_i
#define ARG( T, N) arg $arg##T##N
#define ARG( T, N) arg##T $arg##T##N
#define ARGF( T, N) arg##T $arg##T##N
#define ARG1( K, T) ARG##K(T, 0)
#define ARG2( K, T) ARG1( K, T) ARG##K(T, 1)
@@ -74,56 +74,56 @@ fill##T##done: \
#define ARG15(K, T) ARG14(K, T) ARG##K(T, 14)
#define ARG16(K, T) ARG15(K, T) ARG##K(T, 15)
#define ARG_c(N) ARG##N( , _c)
#define ARG_uc(N) ARG##N( , _uc)
#define ARG_uc(N) ARG##N( , _c)
#define ARG_s(N) ARG##N( , _s)
#define ARG_us(N) ARG##N( , _us)
#define ARG_us(N) ARG##N( , _s)
#define ARG_i(N) ARG##N( , _i)
#define ARG_ui(N) ARG##N( , _ui)
#define ARG_ui(N) ARG##N( , _i)
#define ARG_l(N) ARG##N( , _l)
#define ARG_f(N) ARG##N(F, _f)
#define ARG_d(N) ARG##N(F, _d)
#define CHK(N, T, V) \
getarg %r0 $arg##T##V \
#define CHK(N, T, TT, V) \
getarg##T %r0 $arg##TT##V \
ldxi##T %r1 %v0 $(V * szof##T) \
beqr N##T##V %r0 %r1 \
calli @abort \
N##T##V:
#define CHKF(N, T, V) \
getarg##T %f0 $arg##T##V \
#define CHKF(N, T, TT, V) \
getarg##T %f0 $arg##TT##V \
ldxi##T %f1 %v0 $(V * szof##T) \
beqr##T N##T##V %f0 %f1 \
calli @abort \
N##T##V:
#define GET1( K, N, T, V) CHK##K(N, T, 0)
#define GET2( K, N, T, V) GET1( K, N, T, V) CHK##K(N, T, 1)
#define GET3( K, N, T, V) GET2( K, N, T, V) CHK##K(N, T, 2)
#define GET4( K, N, T, V) GET3( K, N, T, V) CHK##K(N, T, 3)
#define GET5( K, N, T, V) GET4( K, N, T, V) CHK##K(N, T, 4)
#define GET6( K, N, T, V) GET5( K, N, T, V) CHK##K(N, T, 5)
#define GET7( K, N, T, V) GET6( K, N, T, V) CHK##K(N, T, 6)
#define GET8( K, N, T, V) GET7( K, N, T, V) CHK##K(N, T, 7)
#define GET9( K, N, T, V) GET8( K, N, T, V) CHK##K(N, T, 8)
#define GET10(K, N, T, V) GET9( K, N, T, V) CHK##K(N, T, 9)
#define GET11(K, N, T, V) GET10(K, N, T, V) CHK##K(N, T, 10)
#define GET12(K, N, T, V) GET11(K, N, T, V) CHK##K(N, T, 11)
#define GET13(K, N, T, V) GET12(K, N, T, V) CHK##K(N, T, 12)
#define GET14(K, N, T, V) GET13(K, N, T, V) CHK##K(N, T, 13)
#define GET15(K, N, T, V) GET14(K, N, T, V) CHK##K(N, T, 14)
#define GET16(K, N, T, V) GET15(K, N, T, V) CHK##K(N, T, 15)
#define GET1( K, N, T, TT, V) CHK##K(N, T, TT, 0)
#define GET2( K, N, T, TT, V) GET1( K, N, T, TT, V) CHK##K(N, T, TT, 1)
#define GET3( K, N, T, TT, V) GET2( K, N, T, TT, V) CHK##K(N, T, TT, 2)
#define GET4( K, N, T, TT, V) GET3( K, N, T, TT, V) CHK##K(N, T, TT, 3)
#define GET5( K, N, T, TT, V) GET4( K, N, T, TT, V) CHK##K(N, T, TT, 4)
#define GET6( K, N, T, TT, V) GET5( K, N, T, TT, V) CHK##K(N, T, TT, 5)
#define GET7( K, N, T, TT, V) GET6( K, N, T, TT, V) CHK##K(N, T, TT, 6)
#define GET8( K, N, T, TT, V) GET7( K, N, T, TT, V) CHK##K(N, T, TT, 7)
#define GET9( K, N, T, TT, V) GET8( K, N, T, TT, V) CHK##K(N, T, TT, 8)
#define GET10(K, N, T, TT, V) GET9( K, N, T, TT, V) CHK##K(N, T, TT, 9)
#define GET11(K, N, T, TT, V) GET10(K, N, T, TT, V) CHK##K(N, T, TT, 10)
#define GET12(K, N, T, TT, V) GET11(K, N, T, TT, V) CHK##K(N, T, TT, 11)
#define GET13(K, N, T, TT, V) GET12(K, N, T, TT, V) CHK##K(N, T, TT, 12)
#define GET14(K, N, T, TT, V) GET13(K, N, T, TT, V) CHK##K(N, T, TT, 13)
#define GET15(K, N, T, TT, V) GET14(K, N, T, TT, V) CHK##K(N, T, TT, 14)
#define GET16(K, N, T, TT, V) GET15(K, N, T, TT, V) CHK##K(N, T, TT, 15)
#define GET_c(N, M) GET##N( , c##N, _c, M)
#define GET_uc(N, M) GET##N( , uc##N, _uc, M)
#define GET_s(N, M) GET##N( , s##N, _s, M)
#define GET_us(N, M) GET##N( , us##N, _us, M)
#define GET_i(N, M) GET##N( , i##N, _i, M)
#define GET_ui(N, M) GET##N( , ui##N, _ui, M)
#define GET_l(N, M) GET##N( , l##N, _l, M)
#define GET_f(N, M) GET##N(F, f##N, _f, M)
#define GET_d(N, M) GET##N(F, d##N, _d, M)
#define GET_c(N, M) GET##N( , c##N, _c, _c, M)
#define GET_uc(N, M) GET##N( , uc##N, _uc, _c, M)
#define GET_s(N, M) GET##N( , s##N, _s, _s, M)
#define GET_us(N, M) GET##N( , us##N, _us, _s, M)
#define GET_i(N, M) GET##N( , i##N, _i, _i, M)
#define GET_ui(N, M) GET##N( , ui##N, _ui, _i, M)
#define GET_l(N, M) GET##N( , l##N, _l, _l, M)
#define GET_f(N, M) GET##N(F, f##N, _f, _f, M)
#define GET_d(N, M) GET##N(F, d##N, _d, _d, M)
#define PUSH( T, V) pushargi V
#define PUSH( T, V) pushargi##T V
#define PUSHF( T, V) pushargi##T V
#define PUSH0( K, T) /**/
#define PUSH1( K, T) PUSH##K(T, 0)
@@ -161,14 +161,14 @@ test##T##_0: \
ret \
epilog
#define DEFN(N, M, T) \
#define DEFN(N, M, T, TT) \
name test##T##_##N \
test##T##_##N: \
prolog \
arg $argp \
/* stack buffer in %v0 */ \
getarg %v0 $argp \
ARG##T(N) \
ARG##TT(N) \
/* validate arguments */ \
GET##T(N, M) \
/* heap buffer in %v1 */ \
@@ -260,24 +260,24 @@ test##T##_17_done: \
ret \
epilog
#define DEF( T) \
#define DEF( T, TT) \
DEF0( T) \
DEFN( 1, 0, T) \
DEFN( 2, 1, T) \
DEFN( 3, 2, T) \
DEFN( 4, 3, T) \
DEFN( 5, 4, T) \
DEFN( 6, 5, T) \
DEFN( 7, 6, T) \
DEFN( 8, 7, T) \
DEFN( 9, 8, T) \
DEFN(10, 9, T) \
DEFN(11, 10, T) \
DEFN(12, 11, T) \
DEFN(13, 12, T) \
DEFN(14, 13, T) \
DEFN(15, 14, T) \
DEFN(16, 15, T) \
DEFN( 1, 0, T, TT) \
DEFN( 2, 1, T, TT) \
DEFN( 3, 2, T, TT) \
DEFN( 4, 3, T, TT) \
DEFN( 5, 4, T, TT) \
DEFN( 6, 5, T, TT) \
DEFN( 7, 6, T, TT) \
DEFN( 8, 7, T, TT) \
DEFN( 9, 8, T, TT) \
DEFN(10, 9, T, TT) \
DEFN(11, 10, T, TT) \
DEFN(12, 11, T, TT) \
DEFN(13, 12, T, TT) \
DEFN(14, 13, T, TT) \
DEFN(15, 14, T, TT) \
DEFN(16, 15, T, TT) \
DEFX(T)
#define CALL(T) calli test##T##_17
@@ -323,17 +323,17 @@ memcpy_done:
FILLF(_f)
FILLF(_d)
DEF(_c)
DEF(_uc)
DEF(_s)
DEF(_us)
DEF(_i)
DEF(_c, _c)
DEF(_uc, _c)
DEF(_s, _s)
DEF(_us, _s)
DEF(_i, _i)
#if __WORDSIZE == 64
DEF(_ui)
DEF(_l)
DEF(_ui, _i)
DEF(_l, _l)
#endif
DEF(_f)
DEF(_d)
DEF(_f, _f)
DEF(_d, _d)
name main
main:
+1
View File
@@ -0,0 +1 @@
ok
+881
View File
@@ -0,0 +1,881 @@
/* If the fallback clor, clzr, ctor and ctzr are used, it might be better
* to implement it as functions, as inlined it is almost as large as a
* function.
* Below is an example of how to do it.
*/
.data 4096
str_clo:
.c "clo"
str_clz:
.c "clz"
str_cto:
.c "cto"
str_ctz:
.c "ctz"
print_fmt:
#if __WORDSIZE == 64
.c "%s (0x%016lx) %s = %d\n"
#else
.c "%s (0x%08lx) %s = %d\n"
#endif
ok:
.c "ok\n"
#define BIT2(OP, ARG, RES, R0, R1) \
movi %R1 ARG \
OP##r %R0 %R1 \
beqi OP##R0##R1##ARG %R0 RES \
calli @abort \
OP##R0##R1##ARG:
#define BIT1(OP, ARG, RES, V0, V1, V2, R0, R1, R2) \
BIT2(OP, ARG, RES, V0, V0) \
BIT2(OP, ARG, RES, V0, V1) \
BIT2(OP, ARG, RES, V0, V2) \
BIT2(OP, ARG, RES, V0, R0) \
BIT2(OP, ARG, RES, V0, R1) \
BIT2(OP, ARG, RES, V0, R2)
#define BIT(OP, ARG, RES, V0, V1, V2, R0, R1, R2) \
BIT1(OP, ARG, RES, V1, V2, R0, R1, R2, V0) \
BIT1(OP, ARG, RES, V2, R0, R1, R2, V0, V1) \
BIT1(OP, ARG, RES, R0, R1, R2, V0, V1, V2) \
BIT1(OP, ARG, RES, R1, R2, V0, V1, V2, R0) \
BIT1(OP, ARG, RES, R2, V0, V1, V2, R0, R1)
#define CLO(ARG, RES) \
BIT(clo, ARG, RES, v0, v1, v2, r0, r1, r2)
#define CLZ(ARG, RES) \
BIT(clz, ARG, RES, v0, v1, v2, r0, r1, r2)
#define CTO(ARG, RES) \
BIT(cto, ARG, RES, v0, v1, v2, r0, r1, r2)
#define CTZ(ARG, RES) \
BIT(ctz, ARG, RES, v0, v1, v2, r0, r1, r2)
.code
jmpi main
/*
jit_uword_t cto(jit_uword_t r0) {
r0 = ~r0;
if (r0 == 0)
r0 = __WORDSIZE;
else
r0 = ctz(r0);
return r0;
}
*/
name cto
cto:
prolog
arg $in
getarg %r0 $in
comr %r0 %r0
bnei do_cto %r0 0
movi %r0 __WORDSIZE
jmpi done_cto
do_cto:
prepare
pushargr %r0
finishi ctz
retval %r0
done_cto:
retr %r0
epilog
/*
jit_uword_t clo(jit_uword_t r0) {
r0 = ~r0;
if (r0 == 0)
r0 = __WORDSIZE;
else
r0 = clz(r0);
return r0;
}
*/
name clo
clo:
prolog
arg $in
getarg %r0 $in
comr %r0 %r0
bnei do_clo %r0 0
movi %r0 __WORDSIZE
jmpi done_clo
do_clo:
prepare
pushargr %r0
finishi clz
retval %r0
done_clo:
retr %r0
epilog
/*
jit_uword_t clz(jit_word_t r1) {
jit_uword_t r0, r2;
if (r1 == 0)
r0 = __WORDSIZE;
else {
r0 = 0;
#if __WORDSIZE == 64
r2 = 0xffffffff00000000UL;
if (!(r1 & r2)) {
r1 <<= 32;
r0 += 32;
}
r2 <<= 16;
#else
r2 = 0xffff0000UL;
#endif
if (!(r1 & r2)) {
r1 <<= 16;
r0 += 16;
}
r2 <<= 8;
if (!(r1 & r2)) {
r1 <<= 8;
r0 += 8;
}
r2 <<= 4;
if (!(r1 & r2)) {
r1 <<= 4;
r0 += 4;
}
r2 <<= 2;
if (!(r1 & r2)) {
r1 <<= 2;
r0 += 2;
}
r2 <<= 1;
if (!(r1 & r2))
r0 += 1;
}
return r0;
}
*/
name clz
clz:
prolog
arg $in
getarg %r1 $in
bnei lun %r1 0
reti __WORDSIZE
lun:
movi %r0 0
#if __WORDSIZE == 64
movi %r2 0xffffffff00000000
bmsr l32 %r1 %r2
lshi %r1 %r1 32
addi %r0 %r0 32
l32:
lshi %r2 %r2 16
#else
movi %r2 0xffff0000
#endif
bmsr l16 %r1 %r2
lshi %r1 %r1 16
addi %r0 %r0 16
l16:
lshi %r2 %r2 8
bmsr l8 %r1 %r2
lshi %r1 %r1 8
addi %r0 %r0 8
l8:
lshi %r2 %r2 4
bmsr l4 %r1 %r2
lshi %r1 %r1 4
addi %r0 %r0 4
l4:
lshi %r2 %r2 2
bmsr l2 %r1 %r2
lshi %r1 %r1 2
addi %r0 %r0 2
l2:
lshi %r2 %r2 1
bmsr l1 %r1 %r2
addi %r0 %r0 1
l1:
retr %r0
epilog
/*
jit_uword_t ctz(jit_uword_t r1) {
jit_uword_t r0, r2;
if (r1 == 0)
r0 = __WORDSIZE;
else {
r0 = 0;
#if __WORDSIZE == 64
r2 = 0xffffffffUL;;
if (!(r1 & r2)) {
r1 >>= 32;
r0 += 32;
}
r2 >>= 16;
#else
r2 = 0xffffUL;;
#endif
if (!(r1 & r2)) {
r1 >>= 16;
r0 += 16;
}
r2 >>= 8;
if (!(r1 & r2)) {
r1 >>= 8;
r0 += 8;
}
r2 >>= 4;
if (!(r1 & r2)) {
r1 >>= 4;
r0 += 4;
}
r2 >>= 2;
if (!(r1 & r2)) {
r1 >>= 2;
r0 += 2;
}
r2 >>= 1;
if (!(r1 & r2))
r0 += 1;
}
return r0;
}
*/
name ctz
ctz:
prolog
arg $in
getarg %r1 $in
bnei tun %r1 0
reti __WORDSIZE
tun:
#if __WORDSIZE == 64
movi %r0 0
movi %r2 0xffffffff
bmsr t32 %r1 %r2
rshi_u %r1 %r1 32
addi %r0 %r0 32
t32:
rshi %r2 %r2 16
#else
movi %r2 0xffff
#endif
bmsr t16 %r1 %r2
rshi_u %r1 %r1 16
addi %r0 %r0 16
t16:
rshi %r2 %r2 8
bmsr t8 %r1 %r2
rshi_u %r1 %r1 8
addi %r0 %r0 8
t8:
rshi %r2 %r2 4
bmsr t4 %r1 %r2
rshi_u %r1 %r1 4
addi %r0 %r0 4
t4:
rshi %r2 %r2 2
bmsr t2 %r1 %r2
rshi_u %r1 %r1 2
addi %r0 %r0 2
t2:
rshi %r2 %r2 1
bmsr t1 %r1 %r2
addi %r0 %r0 1
t1:
retr %r0
epilog
/*
char *bitsprint(char *v0, jit_uword_t v1) {
jit_uword_t r0, r1;
memset(v0, '0', __WORDSIZE);
v0[__WORDSIZE] = 0;
for (r0 = 1L << (__WORDSIZE - 1), r1 = 0; r0; r0 >>= 1, ++r1) {
if (v1 & r0)
v0[r1] = '1';
}
return v0;
}
*/
name bitsprint
bitsprint:
prolog
arg $buf
arg $val
getarg %v0 $buf
getarg %v1 $val
prepare
pushargr %v0
pushargi '0'
pushargi __WORDSIZE
finishi @memset
movi %r0 0
addi %r1 %v0 __WORDSIZE
str_c %r1 %r0
movi %r0 $(1 << (__WORDSIZE - 1))
movi %r1 0
movi %r2 '1'
bitloop:
bmcr bitzero %v1 %r0
stxr_c %r1 %v0 %r2
bitzero:
addi %r1 %r1 1
rshi_u %r0 %r0 1
bnei bitloop %r0 0
retr %v0
epilog
/*
#if 0
int main(int argc, char *argv[]) {
jit_uword_t r0, v0, v1, v2;
char buf[80];
#if __WORDSIZE == 64
char *fmt = "%s (0x%016lx) %s = %d\n";
v0 = 0x8000000000000000UL;
v2 = 0xffffffffffffffffUL;
#else
char *fmt = "%s (0x%08lx) %s = %d\n";
v0 = 0x80000000UL;
v2 = 0xffffffffUL;
#endif
do {
v1 = v0 - 1;
r0 = clz(v0);
bitsprint(buf, v0);
printf(fmt, "clz", v0, buf, r0);
r0 = clo(v2);
bitsprint(buf, v2);
printf(fmt, "clo", v2, buf, r0);
r0 = ctz(v0);
bitsprint(buf, v0);
printf(fmt, "ctz", v0, buf, r0);
r0 = cto(v1);
bitsprint(buf, v1);
printf(fmt, "cto", v1, buf, r0);
v0 >>= 1;
v2 <<= 1;
} while ((jit_word_t)v1 > -1);
return 0;
}
#endif
*/
/* Make it "#if 1" for a "debug mode", that helps in regenerating tables,
* or temporary state while implementing optimized port specific versions. */
#if 0
#define CALL_FUNC 1
name main
main:
prolog
allocai 80 $buf
#if __WORDSIZE == 64
movi %v0 0x8000000000000000
movi %v2 0xffffffffffffffff
#else
movi %v0 0x80000000
movi %v2 0xffffffff
#endif
loop:
subi %v1 %v0 1
addi %r1 %fp $buf
prepare
pushargr %r1
pushargr %v0
finishi bitsprint
#if CALL_FUNC
prepare
pushargr %v0
finishi clz
retval %r0
#else
clzr %r0 %v0
#endif
addi %r1 %fp $buf
prepare
pushargi print_fmt
ellipsis
pushargi str_clz
pushargr %v0
pushargr %r1
pushargr %r0
finishi @printf
addi %r1 %fp $buf
prepare
pushargr %r1
pushargr %v2
finishi bitsprint
#if CALL_FUNC
prepare
pushargr %v2
finishi clo
retval %r0
#else
clor %r0 %v2
#endif
addi %r1 %fp $buf
prepare
pushargi print_fmt
ellipsis
pushargi str_clo
pushargr %v2
pushargr %r1
pushargr %r0
finishi @printf
addi %r1 %fp $buf
prepare
pushargr %r1
pushargr %v0
finishi bitsprint
#if CALL_FUNC
prepare
pushargr %v0
finishi ctz
retval %r0
#else
ctzr %r0 %v0
#endif
addi %r1 %fp $buf
prepare
pushargi print_fmt
ellipsis
pushargi str_ctz
pushargr %v0
pushargr %r1
pushargr %r0
finishi @printf
addi %r1 %fp $buf
prepare
pushargr %r1
pushargr %v1
finishi bitsprint
#if CALL_FUNC
prepare
pushargr %v1
finishi cto
retval %r0
#else
ctor %r0 %v1
#endif
addi %r1 %fp $buf
prepare
pushargi print_fmt
ellipsis
pushargi str_cto
pushargr %v1
pushargr %r1
pushargr %r0
finishi @printf
rshi_u %v0 %v0 1
lshi %v2 %v2 1
bgti loop %v1 -1
ret
epilog
#else
name main
main:
prolog
#if __WORDSIZE == 32
CLZ(0x80000000, 0)
CLO(0xffffffff, 32)
CTZ(0x80000000, 31)
CTO(0x7fffffff, 31)
CLZ(0x40000000, 1)
CLO(0xfffffffe, 31)
CTZ(0x40000000, 30)
CTO(0x3fffffff, 30)
CLZ(0x20000000, 2)
CLO(0xfffffffc, 30)
CTZ(0x20000000, 29)
CTO(0x1fffffff, 29)
CLZ(0x10000000, 3)
CLO(0xfffffff8, 29)
CTZ(0x10000000, 28)
CTO(0x0fffffff, 28)
CLZ(0x08000000, 4)
CLO(0xfffffff0, 28)
CTZ(0x08000000, 27)
CTO(0x07ffffff, 27)
CLZ(0x04000000, 5)
CLO(0xffffffe0, 27)
CTZ(0x04000000, 26)
CTO(0x03ffffff, 26)
CLZ(0x02000000, 6)
CLO(0xffffffc0, 26)
CTZ(0x02000000, 25)
CTO(0x01ffffff, 25)
CLZ(0x01000000, 7)
CLO(0xffffff80, 25)
CTZ(0x01000000, 24)
CTO(0x00ffffff, 24)
CLZ(0x00800000, 8)
CLO(0xffffff00, 24)
CTZ(0x00800000, 23)
CTO(0x007fffff, 23)
CLZ(0x00400000, 9)
CLO(0xfffffe00, 23)
CTZ(0x00400000, 22)
CTO(0x003fffff, 22)
CLZ(0x00200000, 10)
CLO(0xfffffc00, 22)
CTZ(0x00200000, 21)
CTO(0x001fffff, 21)
CLZ(0x00100000, 11)
CLO(0xfffff800, 21)
CTZ(0x00100000, 20)
CTO(0x000fffff, 20)
CLZ(0x00080000, 12)
CLO(0xfffff000, 20)
CTZ(0x00080000, 19)
CTO(0x0007ffff, 19)
CLZ(0x00040000, 13)
CLO(0xffffe000, 19)
CTZ(0x00040000, 18)
CTO(0x0003ffff, 18)
CLZ(0x00020000, 14)
CLO(0xffffc000, 18)
CTZ(0x00020000, 17)
CTO(0x0001ffff, 17)
CLZ(0x00010000, 15)
CLO(0xffff8000, 17)
CTZ(0x00010000, 16)
CTO(0x0000ffff, 16)
CLZ(0x00008000, 16)
CLO(0xffff0000, 16)
CTZ(0x00008000, 15)
CTO(0x00007fff, 15)
CLZ(0x00004000, 17)
CLO(0xfffe0000, 15)
CTZ(0x00004000, 14)
CTO(0x00003fff, 14)
CLZ(0x00002000, 18)
CLO(0xfffc0000, 14)
CTZ(0x00002000, 13)
CTO(0x00001fff, 13)
CLZ(0x00001000, 19)
CLO(0xfff80000, 13)
CTZ(0x00001000, 12)
CTO(0x00000fff, 12)
CLZ(0x00000800, 20)
CLO(0xfff00000, 12)
CTZ(0x00000800, 11)
CTO(0x000007ff, 11)
CLZ(0x00000400, 21)
CLO(0xffe00000, 11)
CTZ(0x00000400, 10)
CTO(0x000003ff, 10)
CLZ(0x00000200, 22)
CLO(0xffc00000, 10)
CTZ(0x00000200, 9)
CTO(0x000001ff, 9)
CLZ(0x00000100, 23)
CLO(0xff800000, 9)
CTZ(0x00000100, 8)
CTO(0x000000ff, 8)
CLZ(0x00000080, 24)
CLO(0xff000000, 8)
CTZ(0x00000080, 7)
CTO(0x0000007f, 7)
CLZ(0x00000040, 25)
CLO(0xfe000000, 7)
CTZ(0x00000040, 6)
CTO(0x0000003f, 6)
CLZ(0x00000020, 26)
CLO(0xfc000000, 6)
CTZ(0x00000020, 5)
CTO(0x0000001f, 5)
CLZ(0x00000010, 27)
CLO(0xf8000000, 5)
CTZ(0x00000010, 4)
CTO(0x0000000f, 4)
CLZ(0x00000008, 28)
CLO(0xf0000000, 4)
CTZ(0x00000008, 3)
CTO(0x00000007, 3)
CLZ(0x00000004, 29)
CLO(0xe0000000, 3)
CTZ(0x00000004, 2)
CTO(0x00000003, 2)
CLZ(0x00000002, 30)
CLO(0xc0000000, 2)
CTZ(0x00000002, 1)
CTO(0x00000001, 1)
CLZ(0x00000001, 31)
CLO(0x80000000, 1)
CTZ(0x00000001, 0)
CTO(0x00000000, 0)
CLZ(0x00000000, 32)
CLO(0x00000000, 0)
CTZ(0x00000000, 32)
CTO(0xffffffff, 32)
#else
CLZ(0x8000000000000000, 0)
CLO(0xffffffffffffffff, 64)
CTZ(0x8000000000000000, 63)
CTO(0x7fffffffffffffff, 63)
CLZ(0x4000000000000000, 1)
CLO(0xfffffffffffffffe, 63)
CTZ(0x4000000000000000, 62)
CTO(0x3fffffffffffffff, 62)
CLZ(0x2000000000000000, 2)
CLO(0xfffffffffffffffc, 62)
CTZ(0x2000000000000000, 61)
CTO(0x1fffffffffffffff, 61)
CLZ(0x1000000000000000, 3)
CLO(0xfffffffffffffff8, 61)
CTZ(0x1000000000000000, 60)
CTO(0x0fffffffffffffff, 60)
CLZ(0x0800000000000000, 4)
CLO(0xfffffffffffffff0, 60)
CTZ(0x0800000000000000, 59)
CTO(0x07ffffffffffffff, 59)
CLZ(0x0400000000000000, 5)
CLO(0xffffffffffffffe0, 59)
CTZ(0x0400000000000000, 58)
CTO(0x03ffffffffffffff, 58)
CLZ(0x0200000000000000, 6)
CLO(0xffffffffffffffc0, 58)
CTZ(0x0200000000000000, 57)
CTO(0x01ffffffffffffff, 57)
CLZ(0x0100000000000000, 7)
CLO(0xffffffffffffff80, 57)
CTZ(0x0100000000000000, 56)
CTO(0x00ffffffffffffff, 56)
CLZ(0x0080000000000000, 8)
CLO(0xffffffffffffff00, 56)
CTZ(0x0080000000000000, 55)
CTO(0x007fffffffffffff, 55)
CLZ(0x0040000000000000, 9)
CLO(0xfffffffffffffe00, 55)
CTZ(0x0040000000000000, 54)
CTO(0x003fffffffffffff, 54)
CLZ(0x0020000000000000, 10)
CLO(0xfffffffffffffc00, 54)
CTZ(0x0020000000000000, 53)
CTO(0x001fffffffffffff, 53)
CLZ(0x0010000000000000, 11)
CLO(0xfffffffffffff800, 53)
CTZ(0x0010000000000000, 52)
CTO(0x000fffffffffffff, 52)
CLZ(0x0008000000000000, 12)
CLO(0xfffffffffffff000, 52)
CTZ(0x0008000000000000, 51)
CTO(0x0007ffffffffffff, 51)
CLZ(0x0004000000000000, 13)
CLO(0xffffffffffffe000, 51)
CTZ(0x0004000000000000, 50)
CTO(0x0003ffffffffffff, 50)
CLZ(0x0002000000000000, 14)
CLO(0xffffffffffffc000, 50)
CTZ(0x0002000000000000, 49)
CTO(0x0001ffffffffffff, 49)
CLZ(0x0001000000000000, 15)
CLO(0xffffffffffff8000, 49)
CTZ(0x0001000000000000, 48)
CTO(0x0000ffffffffffff, 48)
CLZ(0x0000800000000000, 16)
CLO(0xffffffffffff0000, 48)
CTZ(0x0000800000000000, 47)
CTO(0x00007fffffffffff, 47)
CLZ(0x0000400000000000, 17)
CLO(0xfffffffffffe0000, 47)
CTZ(0x0000400000000000, 46)
CTO(0x00003fffffffffff, 46)
CLZ(0x0000200000000000, 18)
CLO(0xfffffffffffc0000, 46)
CTZ(0x0000200000000000, 45)
CTO(0x00001fffffffffff, 45)
CLZ(0x0000100000000000, 19)
CLO(0xfffffffffff80000, 45)
CTZ(0x0000100000000000, 44)
CTO(0x00000fffffffffff, 44)
CLZ(0x0000080000000000, 20)
CLO(0xfffffffffff00000, 44)
CTZ(0x0000080000000000, 43)
CTO(0x000007ffffffffff, 43)
CLZ(0x0000040000000000, 21)
CLO(0xffffffffffe00000, 43)
CTZ(0x0000040000000000, 42)
CTO(0x000003ffffffffff, 42)
CLZ(0x0000020000000000, 22)
CLO(0xffffffffffc00000, 42)
CTZ(0x0000020000000000, 41)
CTO(0x000001ffffffffff, 41)
CLZ(0x0000010000000000, 23)
CLO(0xffffffffff800000, 41)
CTZ(0x0000010000000000, 40)
CTO(0x000000ffffffffff, 40)
CLZ(0x0000008000000000, 24)
CLO(0xffffffffff000000, 40)
CTZ(0x0000008000000000, 39)
CTO(0x0000007fffffffff, 39)
CLZ(0x0000004000000000, 25)
CLO(0xfffffffffe000000, 39)
CTZ(0x0000004000000000, 38)
CTO(0x0000003fffffffff, 38)
CLZ(0x0000002000000000, 26)
CLO(0xfffffffffc000000, 38)
CTZ(0x0000002000000000, 37)
CTO(0x0000001fffffffff, 37)
CLZ(0x0000001000000000, 27)
CLO(0xfffffffff8000000, 37)
CTZ(0x0000001000000000, 36)
CTO(0x0000000fffffffff, 36)
CLZ(0x0000000800000000, 28)
CLO(0xfffffffff0000000, 36)
CTZ(0x0000000800000000, 35)
CTO(0x00000007ffffffff, 35)
CLZ(0x0000000400000000, 29)
CLO(0xffffffffe0000000, 35)
CTZ(0x0000000400000000, 34)
CTO(0x00000003ffffffff, 34)
CLZ(0x0000000200000000, 30)
CLO(0xffffffffc0000000, 34)
CTZ(0x0000000200000000, 33)
CTO(0x00000001ffffffff, 33)
CLZ(0x0000000100000000, 31)
CLO(0xffffffff80000000, 33)
CTZ(0x0000000100000000, 32)
CTO(0x00000000ffffffff, 32)
CLZ(0x0000000080000000, 32)
CLO(0xffffffff00000000, 32)
CTZ(0x0000000080000000, 31)
CTO(0x000000007fffffff, 31)
CLZ(0x0000000040000000, 33)
CLO(0xfffffffe00000000, 31)
CTZ(0x0000000040000000, 30)
CTO(0x000000003fffffff, 30)
CLZ(0x0000000020000000, 34)
CLO(0xfffffffc00000000, 30)
CTZ(0x0000000020000000, 29)
CTO(0x000000001fffffff, 29)
CLZ(0x0000000010000000, 35)
CLO(0xfffffff800000000, 29)
CTZ(0x0000000010000000, 28)
CTO(0x000000000fffffff, 28)
CLZ(0x0000000008000000, 36)
CLO(0xfffffff000000000, 28)
CTZ(0x0000000008000000, 27)
CTO(0x0000000007ffffff, 27)
CLZ(0x0000000004000000, 37)
CLO(0xffffffe000000000, 27)
CTZ(0x0000000004000000, 26)
CTO(0x0000000003ffffff, 26)
CLZ(0x0000000002000000, 38)
CLO(0xffffffc000000000, 26)
CTZ(0x0000000002000000, 25)
CTO(0x0000000001ffffff, 25)
CLZ(0x0000000001000000, 39)
CLO(0xffffff8000000000, 25)
CTZ(0x0000000001000000, 24)
CTO(0x0000000000ffffff, 24)
CLZ(0x0000000000800000, 40)
CLO(0xffffff0000000000, 24)
CTZ(0x0000000000800000, 23)
CTO(0x00000000007fffff, 23)
CLZ(0x0000000000400000, 41)
CLO(0xfffffe0000000000, 23)
CTZ(0x0000000000400000, 22)
CTO(0x00000000003fffff, 22)
CLZ(0x0000000000200000, 42)
CLO(0xfffffc0000000000, 22)
CTZ(0x0000000000200000, 21)
CTO(0x00000000001fffff, 21)
CLZ(0x0000000000100000, 43)
CLO(0xfffff80000000000, 21)
CTZ(0x0000000000100000, 20)
CTO(0x00000000000fffff, 20)
CLZ(0x0000000000080000, 44)
CLO(0xfffff00000000000, 20)
CTZ(0x0000000000080000, 19)
CTO(0x000000000007ffff, 19)
CLZ(0x0000000000040000, 45)
CLO(0xffffe00000000000, 19)
CTZ(0x0000000000040000, 18)
CTO(0x000000000003ffff, 18)
CLZ(0x0000000000020000, 46)
CLO(0xffffc00000000000, 18)
CTZ(0x0000000000020000, 17)
CTO(0x000000000001ffff, 17)
CLZ(0x0000000000010000, 47)
CLO(0xffff800000000000, 17)
CTZ(0x0000000000010000, 16)
CTO(0x000000000000ffff, 16)
CLZ(0x0000000000008000, 48)
CLO(0xffff000000000000, 16)
CTZ(0x0000000000008000, 15)
CTO(0x0000000000007fff, 15)
CLZ(0x0000000000004000, 49)
CLO(0xfffe000000000000, 15)
CTZ(0x0000000000004000, 14)
CTO(0x0000000000003fff, 14)
CLZ(0x0000000000002000, 50)
CLO(0xfffc000000000000, 14)
CTZ(0x0000000000002000, 13)
CTO(0x0000000000001fff, 13)
CLZ(0x0000000000001000, 51)
CLO(0xfff8000000000000, 13)
CTZ(0x0000000000001000, 12)
CTO(0x0000000000000fff, 12)
CLZ(0x0000000000000800, 52)
CLO(0xfff0000000000000, 12)
CTZ(0x0000000000000800, 11)
CTO(0x00000000000007ff, 11)
CLZ(0x0000000000000400, 53)
CLO(0xffe0000000000000, 11)
CTZ(0x0000000000000400, 10)
CTO(0x00000000000003ff, 10)
CLZ(0x0000000000000200, 54)
CLO(0xffc0000000000000, 10)
CTZ(0x0000000000000200, 9)
CTO(0x00000000000001ff, 9)
CLZ(0x0000000000000100, 55)
CLO(0xff80000000000000, 9)
CTZ(0x0000000000000100, 8)
CTO(0x00000000000000ff, 8)
CLZ(0x0000000000000080, 56)
CLO(0xff00000000000000, 8)
CTZ(0x0000000000000080, 7)
CTO(0x000000000000007f, 7)
CLZ(0x0000000000000040, 57)
CLO(0xfe00000000000000, 7)
CTZ(0x0000000000000040, 6)
CTO(0x000000000000003f, 6)
CLZ(0x0000000000000020, 58)
CLO(0xfc00000000000000, 6)
CTZ(0x0000000000000020, 5)
CTO(0x000000000000001f, 5)
CLZ(0x0000000000000010, 59)
CLO(0xf800000000000000, 5)
CTZ(0x0000000000000010, 4)
CTO(0x000000000000000f, 4)
CLZ(0x0000000000000008, 60)
CLO(0xf000000000000000, 4)
CTZ(0x0000000000000008, 3)
CTO(0x0000000000000007, 3)
CLZ(0x0000000000000004, 61)
CLO(0xe000000000000000, 3)
CTZ(0x0000000000000004, 2)
CTO(0x0000000000000003, 2)
CLZ(0x0000000000000002, 62)
CLO(0xc000000000000000, 2)
CTZ(0x0000000000000002, 1)
CTO(0x0000000000000001, 1)
CLZ(0x0000000000000001, 63)
CLO(0x8000000000000000, 1)
CTZ(0x0000000000000001, 0)
CTO(0x0000000000000000, 0)
CLZ(0x0000000000000000, 64)
CLO(0x0000000000000000, 0)
CTZ(0x0000000000000000, 64)
CTO(0xffffffffffffffff, 64)
#endif
prepare
pushargi ok
finishi @printf
reti 0
epilog
#endif
+1
View File
@@ -0,0 +1 @@
ok
+154
View File
@@ -0,0 +1,154 @@
.data 16
ok:
.c "ok\n"
#define us12_i 0x1234
#define us7f_i 0x7ff7
#define us80_i 0x8008
#define usff_i 0xffff
#define ui12_i 0x01234567
#define ui7f_i 0x7f7ff7f7
#define ui80_i 0x80800808
#define uiff_i 0xffffffff
#define ul12_i 0x0123456789abcdef
#define ul7f_i 0x7f7f7f7ff7f7f7f7
#define ul80_i 0x8080808008080808
#define ulff_i 0xffffffffffffffff
#if __WORDSIZE == 32
# define xus12_i 0xffff1234
# define xus7f_i 0x10107ff7
# define xus80_i 0x81188008
# define xusff_i 0xeaaeffff
#else
# define xus12_i 0xffffffffffff1234
# define xus7f_i 0x1010100101017ff7
# define xus80_i 0x8181811818818008
# define xusff_i 0xeaeaeaaeaeaeffff
# define xui12_i 0xffffffff01234567
# define xui7f_i 0x101001017f7ff7f7
# define xui80_i 0x8181181880800808
# define xuiff_i 0xeaeaaeaeffffffff
#endif
# define us12_o 0x3412
# define us7f_o 0xf77f
# define us80_o 0x0880
# define usff_o 0xffff
# define ui12_o 0x67452301
# define ui7f_o 0xf7f77f7f
# define ui80_o 0x08088080
# define uiff_o 0xffffffff
# define ul12_o 0xefcdab8967452301
# define ul7f_o 0xf7f7f7f77f7f7f7f
# define ul80_o 0x0808080880808080
# define ulff_o 0xffffffffffffffff
#define BSWAP4(I, O, T, R0, R1) \
movi %R0 I \
bswapr_##T %R1 %R0 \
beqi T##R0##R1##I %R1 O \
calli @abort \
T##R0##R1##I:
#define BSWAP3(T, R0, R1) \
BSWAP4(T##12_i, T##12_o, T, R0, R1) \
BSWAP4(x##T##12_i, T##12_o, T, R0, R1) \
BSWAP4(T##7f_i, T##7f_o, T, R0, R1) \
BSWAP4(x##T##7f_i, T##7f_o, T, R0, R1) \
BSWAP4(T##80_i, T##80_o, T, R0, R1) \
BSWAP4(x##T##80_i, T##80_o, T, R0, R1) \
BSWAP4(T##ff_i, T##ff_o, T, R0, R1) \
BSWAP4(x##T##ff_i, T##ff_o, T, R0, R1)
#define BSWAP3x(T, R0, R1) \
BSWAP4(T##12_i, T##12_o, T, R0, R1) \
BSWAP4(T##7f_i, T##7f_o, T, R0, R1) \
BSWAP4(T##80_i, T##80_o, T, R0, R1) \
BSWAP4(T##ff_i, T##ff_o, T, R0, R1)
#define BSWAP2(T, V0, V1, V2, R0, R1, R2) \
BSWAP3(T, V0, V0) \
BSWAP3(T, V0, V1) \
BSWAP3(T, V0, V2) \
BSWAP3(T, V0, R0) \
BSWAP3(T, V0, R1) \
BSWAP3(T, V0, R2) \
#define BSWAP2x(T, V0, V1, V2, R0, R1, R2) \
BSWAP3x(T, V0, V0) \
BSWAP3x(T, V0, V1) \
BSWAP3x(T, V0, V2) \
BSWAP3x(T, V0, R0) \
BSWAP3x(T, V0, R1) \
BSWAP3x(T, V0, R2) \
#define BSWAP1(T, V0, V1, V2, R0, R1, R2) \
BSWAP2(T, V0, V1, V2, R0, R1, R2) \
BSWAP2(T, V1, V2, R0, R1, R2, V0) \
BSWAP2(T, V2, R0, R1, R2, V0, V1) \
BSWAP2(T, R0, R1, R2, V0, V1, V2) \
BSWAP2(T, R1, R2, V0, V1, V2, R0) \
BSWAP2(T, R2, V0, V1, V2, R0, R1)
#define BSWAP1x(T, V0, V1, V2, R0, R1, R2) \
BSWAP2x(T, V0, V1, V2, R0, R1, R2) \
BSWAP2x(T, V1, V2, R0, R1, R2, V0) \
BSWAP2x(T, V2, R0, R1, R2, V0, V1) \
BSWAP2x(T, R0, R1, R2, V0, V1, V2) \
BSWAP2x(T, R1, R2, V0, V1, V2, R0) \
BSWAP2x(T, R2, V0, V1, V2, R0, R1)
#if __WORDSIZE == 32
# define BSWAP(V0, V1, V2, R0, R1, R2) \
BSWAP1(us, V0, V1, V2, R0, R1, R2) \
BSWAP1x(ui, V0, V1, V2, R0, R1, R2)
#else
# define BSWAP(V0, V1, V2, R0, R1, R2) \
BSWAP1(us, V0, V1, V2, R0, R1, R2) \
BSWAP1(ui, V0, V1, V2, R0, R1, R2) \
BSWAP1x(ul, V0, V1, V2, R0, R1, R2)
#endif
.code
prolog
/* simple sequence for easier disassembly reading and encoding check */
movi %r0 us12_i
bswapr_us %r1 %r0
beqi us %r1 us12_o
calli @abort
us:
movi %r0 xus12_i
bswapr_us %r1 %r0
beqi xus %r1 us12_o
calli @abort
xus:
movi %r0 ui12_i
bswapr_ui %r1 %r0
beqi ui %r1 ui12_o
calli @abort
ui:
#if __WORDSIZE == 64
movi %r0 xui12_i
bswapr_ui %r1 %r0
beqi xui %r1 ui12_o
calli @abort
xui:
movi %r0 ul12_i
bswapr_ul %r1 %r0
beqi ul %r1 ul12_o
calli @abort
ul:
#endif
BSWAP(v0, v1, v2, r0, r1, r2)
// just to know did not abort
prepare
pushargi ok
ellipsis
finishi @printf
ret
epilog
+28 -27
View File
@@ -1,10 +1,10 @@
#define def_wi(i) \
#define def_wi(i, ii) \
name _w##i \
_w##i: \
prolog \
arg $arg##i \
arg##ii $arg##i \
getarg##i %r0 $arg##i \
retr %r0 \
retr##i %r0 \
epilog
#define def_wf(f) \
name _w##f \
@@ -15,11 +15,11 @@ _w##f: \
truncr##f %r0 %f0 \
retr %r0 \
epilog
#define def_fi(f, i) \
#define def_fi(f, i, ii) \
name f##i \
f##i: \
prolog \
arg $arg##i \
arg##ii $arg##i \
getarg##i %r0 $arg##i \
extr##f %f0 %r0 \
retr##f %f0 \
@@ -52,33 +52,33 @@ bstr:
.code
jmpi main
def_wi(_c)
def_wi(_uc)
def_wi(_s)
def_wi(_us)
def_wi(_c, _c)
def_wi(_uc, _c)
def_wi(_s, _s)
def_wi(_us, _s)
#if __WORDSIZE == 64
def_wi(_i)
def_wi(_ui)
def_wi(_i, _i)
def_wi(_ui, _i)
#endif
def_wf(_f)
def_wf(_d)
def_fi(_f, _c)
def_fi(_f, _uc)
def_fi(_f, _s)
def_fi(_f, _us)
def_fi(_f, _i)
def_fi(_f, _c, _c)
def_fi(_f, _uc, _c)
def_fi(_f, _s, _s)
def_fi(_f, _us, _s)
def_fi(_f, _i, _i)
#if __WORDSIZE == 64
def_fi(_f, _ui)
def_fi(_f, _l)
def_fi(_f, _ui, _i)
def_fi(_f, _l, _l)
#endif
def_fi(_d, _c)
def_fi(_d, _uc)
def_fi(_d, _s)
def_fi(_d, _us)
def_fi(_d, _i)
def_fi(_d, _c, _c)
def_fi(_d, _uc, _c)
def_fi(_d, _s, _s)
def_fi(_d, _us, _s)
def_fi(_d, _i, _i)
#if __WORDSIZE == 64
def_fi(_d, _ui)
def_fi(_d, _l)
def_fi(_d, _ui, _i)
def_fi(_d, _l, _l)
#endif
def_f(_f)
def_f(_d)
@@ -91,7 +91,7 @@ main:
#define _call_w(n, i, a, r) \
prepare \
pushargi a \
pushargi##i a \
finishi _w##i \
retval %r0 \
extr##i %r0 %r0 \
@@ -111,7 +111,7 @@ _w##f##_##n:
#define call_wf(n, f, a, r) _call_wf(n, f, a, r)
#define _call_fi(n, f, i, a, r) \
prepare \
pushargi a \
pushargi##i a \
finishi f##i \
retval##f %f0 \
beqi##f f##i##n %f0 r \
@@ -196,6 +196,7 @@ f##g##n:
call_wf(__LINE__, _d, c7f, f7f)
call_wf(__LINE__, _d, wc80, f80)
call_wf(__LINE__, _d, wc81, f81)
call_fi(__LINE__, _f, _c, c7f, f7f)
call_fi(__LINE__, _f, _c, c80, f80)
call_fi(__LINE__, _f, _uc, c7f, f7f)
+16 -5
View File
@@ -58,8 +58,8 @@ int
main(int argc, char *argv[])
{
void (*code)(void);
jit_node_t *jmp, *pass;
jit_node_t *jw, *jf, *jd;
jit_node_t *jmp, *pass, *fail;
jit_node_t *jw, *jf, *jd;
jit_int32_t s1, s2, s3, s4, s5, s6, s7, s8,
s9, s10, s11, s12, s13, s14, s15, s16;
jit_node_t *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8,
@@ -172,10 +172,11 @@ main(int argc, char *argv[])
LOAD_ARG(16);
#undef LOAD_ARG
pass = jit_forward();
fail = jit_forward();
#define CHECK_ARG(N) \
do { \
jit_getarg(JIT_R0, a##N); \
jit_patch_at(jit_beqi(JIT_R0, 17 - N), pass); \
jit_patch_at(jit_bnei(JIT_R0, 17 - N), fail); \
} while (0)
CHECK_ARG(1);
CHECK_ARG(2);
@@ -194,6 +195,8 @@ main(int argc, char *argv[])
CHECK_ARG(15);
CHECK_ARG(16);
#undef CHECK_ARG
jit_patch_at(jit_jmpi(), pass);
jit_link(fail);
jit_calli(abort);
jit_link(pass);
jit_ret();
@@ -300,10 +303,11 @@ main(int argc, char *argv[])
LOAD_ARG(16);
#undef LOAD_ARG
pass = jit_forward();
fail = jit_forward();
#define CHECK_ARG(N) \
do { \
jit_getarg_f(JIT_F0, a##N); \
jit_patch_at(jit_beqi_f(JIT_F0, 17 - N), pass); \
jit_patch_at(jit_bnei_f(JIT_F0, 17 - N), fail); \
} while (0)
CHECK_ARG(1);
CHECK_ARG(2);
@@ -322,6 +326,8 @@ main(int argc, char *argv[])
CHECK_ARG(15);
CHECK_ARG(16);
#undef CHECK_ARG
jit_patch_at(jit_jmpi(), pass);
jit_link(fail);
jit_calli(abort);
jit_link(pass);
jit_ret();
@@ -428,10 +434,11 @@ main(int argc, char *argv[])
LOAD_ARG(16);
#undef LOAD_ARG
pass = jit_forward();
fail = jit_forward();
#define CHECK_ARG(N) \
do { \
jit_getarg_d(JIT_F0, a##N); \
jit_patch_at(jit_beqi_d(JIT_F0, 17 - N), pass); \
jit_patch_at(jit_bnei_d(JIT_F0, 17 - N), fail); \
} while (0)
CHECK_ARG(1);
CHECK_ARG(2);
@@ -450,6 +457,8 @@ main(int argc, char *argv[])
CHECK_ARG(15);
CHECK_ARG(16);
#undef CHECK_ARG
jit_patch_at(jit_jmpi(), pass);
jit_link(fail);
jit_calli(abort);
jit_link(pass);
jit_ret();
@@ -484,6 +493,7 @@ main(int argc, char *argv[])
jit_pushargi(1);
}
jit_patch_at(jit_finishi(NULL), jw);
jit_prepare();
{
jit_pushargi_f(16);
@@ -504,6 +514,7 @@ main(int argc, char *argv[])
jit_pushargi_f(1);
}
jit_patch_at(jit_finishi(NULL), jf);
jit_prepare();
{
jit_pushargi_d(16);
+191
View File
@@ -0,0 +1,191 @@
#include <lightning.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#if DEBUG
volatile
#endif
jit_word_t lock;
pthread_t tids[4];
#if DEBUG
int debug_offset(void)
{
int i;
pthread_t self = pthread_self();
for (i = 0; i < 4; ++i)
if (tids[i] == self)
return i;
return -1;
}
void debug_spin(void)
{
printf(" spin %d : %ld\n", debug_offset(), lock);
}
void debug_lock(void)
{
printf(" lock %d : %ld\n", debug_offset(), lock);
}
void debug_unlock(void)
{
printf("unlock %d : %ld\n", debug_offset(), lock);
}
#define DEBUG_SPIN() jit_calli(debug_spin)
#define DEBUG_LOCK() jit_calli(debug_lock)
#define DEBUG_UNLOCK() jit_calli(debug_unlock)
#else
#define DEBUG_SPIN() /**/
#define DEBUG_LOCK() /**/
#define DEBUG_UNLOCK() /**/
#endif
void alarm_handler(int unused)
{
_exit(1);
}
int
main(int argc, char *argv[])
{
jit_state_t *_jit;
void (*code)(void);
jit_node_t *jmpi_main, *label;
jit_node_t *func0, *func1, *func2, *func3;
jit_node_t *patch0, *patch1, *patch2, *patch3;
/* If there is any bug, do not hang in "make check" */
signal(SIGALRM, alarm_handler);
alarm(5);
init_jit(argv[0]);
_jit = jit_new_state();
jmpi_main = jit_jmpi();
#define defun(name, line) \
jit_name(#name); \
jit_note("catomic.c", line); \
name = jit_label(); \
jit_prolog(); \
jit_movi(JIT_V0, (jit_word_t)&lock); \
jit_movi(JIT_V1, 0); \
jit_movi(JIT_V2, line); \
/* spin until get the lock */ \
DEBUG_SPIN(); \
label = jit_label(); \
jit_casr(JIT_R0, JIT_V0, JIT_V1, JIT_V2); \
jit_patch_at(jit_beqi(JIT_R0, 0), label); \
/* lock acquired */ \
DEBUG_LOCK(); \
jit_prepare(); \
/* pretend to be doing something useful for 0.01 sec
* while holding the lock */ \
jit_pushargi(10000); \
jit_finishi(usleep); \
/* release lock */ \
DEBUG_UNLOCK(); \
jit_movi(JIT_V1, 0); \
jit_str(JIT_V0, JIT_V1); \
/* Now test casi */ \
jit_movi(JIT_V1, 0); \
jit_movi(JIT_V2, line); \
/* spin until get the lock */ \
DEBUG_SPIN(); \
label = jit_label(); \
jit_casi(JIT_R0, (jit_word_t)&lock, JIT_V1, JIT_V2); \
jit_patch_at(jit_beqi(JIT_R0, 0), label); \
/* lock acquired */ \
DEBUG_LOCK(); \
jit_prepare(); \
/* pretend to be doing something useful for 0.01 sec
* while holding the lock */ \
jit_pushargi(10000); \
jit_finishi(usleep); \
jit_prepare(); \
/* for make check, just print "ok" */ \
jit_pushargi((jit_word_t)"ok"); \
/*jit_pushargi((jit_word_t)#name);*/ \
jit_finishi(puts); \
/* release lock */ \
DEBUG_UNLOCK(); \
jit_movi(JIT_V1, 0); \
jit_str(JIT_V0, JIT_V1); \
jit_ret(); \
jit_epilog();
defun(func0, __LINE__);
defun(func1, __LINE__);
defun(func2, __LINE__);
defun(func3, __LINE__);
jit_patch(jmpi_main);
jit_name("main");
jit_note("catomic.c", __LINE__);
jit_prolog();
#define start(tid) \
/* set JIT_R0 to thread function */ \
jit_patch_at(jit_movi(JIT_R0, 0), func##tid); \
jit_prepare(); \
/* pthread_t first argument */ \
jit_pushargi((jit_word_t)(tids + tid)); \
/* pthread_attr_t second argument */ \
jit_pushargi((jit_word_t)NULL); \
/* start routine third argument */ \
jit_pushargr(JIT_R0); \
/* argument to start routine fourth argument */ \
jit_pushargi((jit_word_t)NULL); \
/* start thread */ \
jit_finishi(pthread_create);
/* spawn four threads */
start(0);
start(1);
start(2);
start(3);
#define join(tid) \
/* load pthread_t value in JIT_R0 */ \
jit_movi(JIT_R0, (jit_word_t)tids); \
if (__WORDSIZE == 64 && sizeof(pthread_t) == 4) \
jit_ldxi_i(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
else \
jit_ldxi(JIT_R0, JIT_R0, tid * sizeof(pthread_t)); \
jit_prepare(); \
jit_pushargr(JIT_R0); \
jit_pushargi((jit_word_t)NULL); \
jit_finishi(pthread_join);
/* wait for threads to finish */
join(0);
join(1);
join(2);
join(3);
jit_prepare();
jit_pushargi((jit_word_t)"ok");
jit_finishi(puts);
jit_ret();
jit_epilog();
code = jit_emit();
#if DEBUG
jit_disassemble();
#endif
jit_clear_state();
/* let first thread acquire the lock */
lock = 0;
(*code)();
jit_destroy_state();
finish_jit();
return (0);
}
+5
View File
@@ -0,0 +1,5 @@
ok
ok
ok
ok
ok
+14 -4
View File
@@ -132,6 +132,16 @@
# define _l15 _w15
#endif
#ifndef jit_arg_uc
# define jit_arg_uc jit_arg_c
#endif
#ifndef jit_arg_us
# define jit_arg_us jit_arg_s
#endif
#ifndef jit_arg_ui
# define jit_arg_ui jit_arg_i
#endif
/*
* Types
*/
@@ -624,7 +634,7 @@ main(int argc, char *argv[])
#define arg15(T) arg14(T) a15 = jit_arg##T();
#define get0(B,T,R) jit_movi##B(R##0,0);
#define get1(B,T,R) jit_getarg##B(R##0,a##1);
#define get1(B,T,R) jit_getarg##T(R##0,a##1);
#define get2(B,T,R) \
get1(B,T,R); \
jit_movr##B(R##1, R##0); \
@@ -707,7 +717,7 @@ main(int argc, char *argv[])
n##T##N = jit_name(strfy(n##T##N)); \
jit_note("ccall.c", __LINE__); \
jit_prolog(); \
arg##N(); \
arg##N(T); \
get##N(,T,JIT_R) \
jit_extr##T(JIT_R0, JIT_R0); \
jit_retr(JIT_R0); \
@@ -777,7 +787,7 @@ main(int argc, char *argv[])
#define calin(T,N) \
jit_prepare(); \
push##N() \
push##N(T) \
jit_finishi(C##T##N); \
jit_retval##T(JIT_R0); \
jmp = jit_beqi(JIT_R0, T##N); \
@@ -826,7 +836,7 @@ main(int argc, char *argv[])
#undef calfn
#define calin(T,N) \
jit_prepare(); \
push##N() \
push##N(T) \
jit_finishi(CJ##T##N); \
jit_retval##T(JIT_R0); \
jmp = jit_beqi(JIT_R0, T##N); \
+79
View File
@@ -0,0 +1,79 @@
.data 32
str:
.c "%lu\n"
.code
jmpi main
/*
* unsigned long collatz(unsigned long n) {
* unsigned long r = n;
* if (!(r & 1)) {
* r = r / 2;
* return r;
* }
* r = r * 3;
* r = r + 1;
* return r;
* }
*/
collatz:
prolog
arg $n
getarg %r0 $n
bmsi odd %r0 1
//divi_u %r0 %r0 2
rshi_u %r0 %r0 1
retr %r0
odd:
muli %r0 %r0 3
addi %r0 %r0 1
retr %r0
epilog
/*
* int main(int argc, char *argv[]) {
* unsigned long v;
* if (argc == 2)
* v = strtoul(argv[1], NULL, 0);
* else
* v = (1L << __WORDSIZE / 2) - 1;
* while (1) {
* printf("%ld\n", v);
* if (v <= 1)
* break;
* v = collatz(v);
* }
* return 0;
* }
*/
main:
prolog
arg $argc
arg $argv
getarg %r0 $argc
bnei default %r0 2
getarg %v0 $argv
ldxi %r0 %v0 $(__WORDSIZE >> 3)
prepare
pushargr %r0
pushargi 0
pushargi 0
finishi @strtoul
retval %v0
jmpi loop
default:
movi %v0 $((1 << __WORDSIZE / 2) - 1)
loop:
prepare
pushargi str
ellipsis
pushargr %v0
finishi @printf
blei_u done %v0 1
prepare
pushargr %v0
finishi collatz
retval %v0
jmpi loop
done:
reti 0
epilog
@@ -0,0 +1,73 @@
.data 32
str:
.c "%.0lf\n"
.code
jmpi main
/*
* double factorial(unsigned long n) {
* double r = 1;
* while (n > 1) {
* r *= n;
* --n;
* }
* return r;
* }
*/
factorial:
prolog
arg $n
getarg %r0 $n
movi_d %f0 1.0
extr_d %f1 %r0
movr_d %f2 %f0
loop:
bltr_d done %f1 %f2
mulr_d %f0 %f0 %f1
subr_d %f1 %f1 %f2
jmpi loop
done:
retr_d %f0
epilog
/*
* int main(int argc, char *argv[]) {
* unsigned long v;
* double d;
* if (argc == 2)
* v = strtoul(argv[1], NULL, 0);
* else
* v = 32;
* d = factorial(v);
* printf("%.0lf\n", d);
* return 0;
* }
*/
main:
prolog
arg $argc
arg $argv
getarg %r0 $argc
bnei default %r0 2
getarg %v0 $argv
ldxi %r0 %v0 $(__WORDSIZE >> 3)
prepare
pushargr %r0
pushargi 0
pushargi 0
finishi @strtoul
retval %v0
jmpi call
default:
movi %v0 32
call:
prepare
pushargr %v0
finishi factorial
retval_d %f0
prepare
pushargi str
ellipsis
pushargr_d %f0
finishi @printf
reti 0
epilog
+1 -1
View File
@@ -32,7 +32,7 @@ main:
arg $argc
arg $argv
getarg_i %r0 $argc
getarg %r0 $argc
blei default %r0 1
getarg %r0 $argv
addi %r0 %r0 $(__WORDSIZE >> 3)
+2 -2
View File
@@ -16,12 +16,12 @@ ok:
#if __mips__ || __sparc__ || __hppa__ || __riscv
# define wnan x7f
#elif __arm__ || __aarch64__ || __alpha__
#elif __arm__ || __aarch64__ || __alpha__ || __loongarch__
# define wnan 0
#else
# define wnan x80
#endif
#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390__ || __riscv
#if __mips__ || __arm__ || __ppc__ || __sparc__ || __hppa__ || __aarch64__ || __s390__ || __riscv || __loongarch__
# define wpinf x7f
#elif __alpha__
/* (at least) bug compatible with gcc 4.2.3 -ieee */
+158 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2022 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <lightning.h>
#include <dlfcn.h>
#include <math.h>
#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
# include <fpu_control.h>
@@ -269,10 +270,16 @@ static jit_pointer_t get_arg(void);
static jit_word_t get_imm(void);
static void live(void);
static void align(void); static void name(void);
static void skip(void);
static void prolog(void);
static void frame(void); static void tramp(void);
static void ellipsis(void);
static void allocai(void); static void allocar(void);
static void arg_c(void); static void arg_s(void);
static void arg_i(void);
#if __WORDSIZE == 64
static void arg_l(void);
#endif
static void arg(void);
static void getarg_c(void); static void getarg_uc(void);
static void getarg_s(void); static void getarg_us(void);
@@ -281,6 +288,15 @@ static void getarg_i(void);
static void getarg_ui(void); static void getarg_l(void);
#endif
static void getarg(void);
static void putargr_c(void); static void putargi_c(void);
static void putargr_uc(void); static void putargi_uc(void);
static void putargr_s(void); static void putargi_s(void);
static void putargr_us(void); static void putargi_us(void);
static void putargr_i(void); static void putargi_i(void);
#if __WORDSIZE == 64
static void putargr_ui(void); static void putargi_ui(void);
static void putargr_l(void); static void putargi_l(void);
#endif
static void putargr(void); static void putargi(void);
static void addr(void); static void addi(void);
static void addxr(void); static void addxi(void);
@@ -305,6 +321,8 @@ static void lshr(void); static void lshi(void);
static void rshr(void); static void rshi(void);
static void rshr_u(void); static void rshi_u(void);
static void negr(void); static void comr(void);
static void clor(void); static void clzr(void);
static void ctor(void); static void ctzr(void);
static void ltr(void); static void lti(void);
static void ltr_u(void); static void lti_u(void);
static void ler(void); static void lei(void);
@@ -315,6 +333,7 @@ static void ger_u(void); static void gei_u(void);
static void gtr(void); static void gti(void);
static void gtr_u(void); static void gti_u(void);
static void ner(void); static void nei(void);
static void casr(void); static void casi(void);
static void movr(void); static void movi(void);
static void extr_c(void); static void extr_uc(void);
static void extr_s(void); static void extr_us(void);
@@ -327,6 +346,12 @@ static void htonr_ui(void); static void ntohr_ui(void);
static void htonr_ul(void); static void ntohr_ul(void);
#endif
static void htonr(void); static void ntohr(void);
static void bswapr_us(void); static void bswapr_ui(void);
#if __WORDSIZE == 64
static void bswapr_ul(void);
#endif
static void bswapr(void);
static void movnr(void); static void movzr(void);
static void ldr_c(void); static void ldi_c(void);
static void ldr_uc(void); static void ldi_uc(void);
static void ldr_s(void); static void ldi_s(void);
@@ -384,9 +409,30 @@ static void bxsubr_u(void); static void bxsubi_u(void);
static void jmpr(void); static void jmpi(void);
static void callr(void); static void calli(void);
static void prepare(void);
static void pushargr_c(void); static void pushargi_c(void);
static void pushargr_uc(void); static void pushargi_uc(void);
static void pushargr_s(void); static void pushargi_s(void);
static void pushargr_us(void); static void pushargi_us(void);
static void pushargr_i(void); static void pushargi_i(void);
#if __WORDSIZE == 64
static void pushargr_ui(void); static void pushargi_ui(void);
static void pushargr_l(void); static void pushargi_l(void);
#endif
static void pushargr(void); static void pushargi(void);
static void finishr(void); static void finishi(void);
static void ret(void);
static void retr_c(void); static void reti_c(void);
static void retr_uc(void); static void reti_uc(void);
static void retr_s(void); static void reti_s(void);
static void retr_us(void); static void reti_us(void);
static void retr_i(void); static void reti_i(void);
#if __WORDSIZE == 64
static void retr_ui(void); static void reti_ui(void);
static void retr_l(void); static void reti_l(void);
#endif
static void retr(void); static void reti(void);
static void retval_c(void); static void retval_uc(void);
static void retval_s(void); static void retval_us(void);
@@ -583,10 +629,16 @@ static instr_t instr_vector[] = {
#define entry2(name, function) { NULL, name, function }
entry(live),
entry(align), entry(name),
entry(skip),
entry(prolog),
entry(frame), entry(tramp),
entry(ellipsis),
entry(allocai), entry(allocar),
entry(arg_c), entry(arg_s),
entry(arg_i),
#if __WORDSIZE == 64
entry(arg_l),
#endif
entry(arg),
entry(getarg_c), entry(getarg_uc),
entry(getarg_s), entry(getarg_us),
@@ -595,6 +647,16 @@ static instr_t instr_vector[] = {
entry(getarg_ui), entry(getarg_l),
#endif
entry(getarg),
entry(putargr_c), entry(putargi_c),
entry(putargr_uc), entry(putargi_uc),
entry(putargr_s), entry(putargi_s),
entry(putargr_us), entry(putargi_us),
entry(putargr_i), entry(putargi_i),
#if __WORDSIZE == 64
entry(putargr_ui), entry(putargi_ui),
entry(putargr_l), entry(putargi_l),
#endif
entry(putargr), entry(putargi),
entry(addr), entry(addi),
entry(addxr), entry(addxi),
@@ -619,6 +681,8 @@ static instr_t instr_vector[] = {
entry(rshr), entry(rshi),
entry(rshr_u), entry(rshi_u),
entry(negr), entry(comr),
entry(clor), entry(clzr),
entry(ctor), entry(ctzr),
entry(ltr), entry(lti),
entry(ltr_u), entry(lti_u),
entry(ler), entry(lei),
@@ -629,6 +693,7 @@ static instr_t instr_vector[] = {
entry(gtr), entry(gti),
entry(gtr_u), entry(gti_u),
entry(ner), entry(nei),
entry(casr), entry(casi),
entry(movr), entry(movi),
entry(extr_c), entry(extr_uc),
entry(extr_s), entry(extr_us),
@@ -641,6 +706,12 @@ static instr_t instr_vector[] = {
entry(htonr_ul), entry(ntohr_ul),
#endif
entry(htonr), entry(ntohr),
entry(bswapr_us), entry(bswapr_ui),
#if __WORDSIZE == 64
entry(bswapr_ul),
#endif
entry(bswapr),
entry(movnr), entry(movzr),
entry(ldr_c), entry(ldi_c),
entry(ldr_uc), entry(ldi_uc),
entry(ldr_s), entry(ldi_s),
@@ -698,9 +769,27 @@ static instr_t instr_vector[] = {
entry(jmpr), entry(jmpi),
entry(callr), entry(calli),
entry(prepare),
entry(pushargr_c), entry(pushargi_c),
entry(pushargr_uc), entry(pushargi_uc),
entry(pushargr_s), entry(pushargi_s),
entry(pushargr_us), entry(pushargi_us),
entry(pushargr_i), entry(pushargi_i),
#if __WORDSIZE == 64
entry(pushargr_ui), entry(pushargi_ui),
entry(pushargr_l), entry(pushargi_l),
#endif
entry(pushargr), entry(pushargi),
entry(finishr), entry(finishi),
entry(ret),
entry(retr_c), entry(reti_c),
entry(retr_uc), entry(reti_uc),
entry(retr_s), entry(reti_s),
entry(retr_us), entry(reti_us),
entry(retr_i), entry(reti_i),
#if __WORDSIZE == 64
entry(retr_ui), entry(reti_ui),
entry(retr_l), entry(reti_l),
#endif
entry(retr), entry(reti),
entry(retval_c), entry(retval_uc),
entry(retval_s), entry(retval_us),
@@ -1015,6 +1104,16 @@ name(void) \
jit_word_t im = get_imm(); \
jit_##name(r0, r1, r2, im); \
}
#define entry_ir_im_ir_ir(name) \
static void \
name(void) \
{ \
jit_gpr_t r0 = get_ireg(); \
jit_word_t im = get_imm(); \
jit_gpr_t r1 = get_ireg(), r2 = get_ireg(); \
jit_##name(r0, im, r1, r2); \
}
#define entry_ir_ir(name) \
static void \
name(void) \
@@ -1375,6 +1474,7 @@ live(void) {
jit_live(parser.regval);
}
entry_im(align)
entry_im(skip)
entry(prolog)
entry_im(frame) entry_im(tramp)
entry(ellipsis)
@@ -1388,6 +1488,11 @@ allocai(void) {
symbol->value.i = i;
}
entry_ir_ir(allocar)
entry_ca(arg_c) entry_ca(arg_s)
entry_ca(arg_i)
#if __WORDSIZE == 64
entry_ca(arg_l)
#endif
entry_ca(arg)
entry_ia(getarg_c) entry_ia(getarg_uc)
entry_ia(getarg_s) entry_ia(getarg_us)
@@ -1396,6 +1501,15 @@ entry_ia(getarg_i)
entry_ia(getarg_ui) entry_ia(getarg_l)
#endif
entry_ia(getarg)
entry_ia(putargr_c) entry_ima(putargi_c)
entry_ia(putargr_uc) entry_ima(putargi_uc)
entry_ia(putargr_s) entry_ima(putargi_s)
entry_ia(putargr_us) entry_ima(putargi_us)
entry_ia(putargr_i) entry_ima(putargi_i)
#if __WORDSIZE == 64
entry_ia(putargr_ui) entry_ima(putargi_ui)
entry_ia(putargr_l) entry_ima(putargi_l)
#endif
entry_ia(putargr) entry_ima(putargi)
entry_ir_ir_ir(addr) entry_ir_ir_im(addi)
entry_ir_ir_ir(addxr) entry_ir_ir_im(addxi)
@@ -1420,6 +1534,8 @@ entry_ir_ir_ir(lshr) entry_ir_ir_im(lshi)
entry_ir_ir_ir(rshr) entry_ir_ir_im(rshi)
entry_ir_ir_ir(rshr_u) entry_ir_ir_im(rshi_u)
entry_ir_ir(negr) entry_ir_ir(comr)
entry_ir_ir(clor) entry_ir_ir(clzr)
entry_ir_ir(ctor) entry_ir_ir(ctzr)
entry_ir_ir_ir(ltr) entry_ir_ir_im(lti)
entry_ir_ir_ir(ltr_u) entry_ir_ir_im(lti_u)
entry_ir_ir_ir(ler) entry_ir_ir_im(lei)
@@ -1430,6 +1546,7 @@ entry_ir_ir_ir(ger_u) entry_ir_ir_im(gei_u)
entry_ir_ir_ir(gtr) entry_ir_ir_im(gti)
entry_ir_ir_ir(gtr_u) entry_ir_ir_im(gti_u)
entry_ir_ir_ir(ner) entry_ir_ir_im(nei)
entry_ir_ir_ir_ir(casr) entry_ir_im_ir_ir(casi)
entry_ir_ir(movr)
static void
movi(void)
@@ -1489,6 +1606,12 @@ entry_ir_ir(htonr_ui) entry_ir_ir(ntohr_ui)
entry_ir_ir(htonr_ul) entry_ir_ir(ntohr_ul)
#endif
entry_ir_ir(htonr) entry_ir_ir(ntohr)
entry_ir_ir(bswapr_us) entry_ir_ir(bswapr_ui)
#if __WORDSIZE == 64
entry_ir_ir(bswapr_ul)
#endif
entry_ir_ir(bswapr)
entry_ir_ir_ir(movnr) entry_ir_ir_ir(movzr)
entry_ir_ir(ldr_c) entry_ir_pm(ldi_c)
entry_ir_ir(ldr_uc) entry_ir_pm(ldi_uc)
entry_ir_ir(ldr_s) entry_ir_pm(ldi_s)
@@ -1546,9 +1669,27 @@ entry_lb_ir_ir(bxsubr_u) entry_lb_ir_im(bxsubi_u)
entry_ir(jmpr) entry_lb(jmpi)
entry_ir(callr) entry_fn(calli)
entry(prepare)
entry_ir(pushargr_c) entry_im(pushargi_c)
entry_ir(pushargr_uc) entry_im(pushargi_uc)
entry_ir(pushargr_s) entry_im(pushargi_s)
entry_ir(pushargr_us) entry_im(pushargi_us)
entry_ir(pushargr_i) entry_im(pushargi_i)
#if __WORDSIZE == 64
entry_ir(pushargr_ui) entry_im(pushargi_ui)
entry_ir(pushargr_l) entry_im(pushargi_l)
#endif
entry_ir(pushargr) entry_im(pushargi)
entry_ir(finishr) entry_fn(finishi)
entry(ret)
entry_ir(retr_c) entry_im(reti_c)
entry_ir(retr_uc) entry_im(reti_uc)
entry_ir(retr_s) entry_im(reti_s)
entry_ir(retr_us) entry_im(reti_us)
entry_ir(retr_i) entry_im(reti_i)
#if __WORDSIZE == 64
entry_ir(retr_ui) entry_im(reti_ui)
entry_ir(retr_l) entry_im(reti_l)
#endif
entry_ir(retr) entry_im(reti)
entry_ir(retval_c) entry_ir(retval_uc)
entry_ir(retval_s) entry_ir(retval_us)
@@ -3791,11 +3932,16 @@ execute(int argc, char *argv[])
function = jit_emit();
if (flag_verbose > 1 || flag_disasm) {
jit_print();
fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
}
if (flag_verbose > 0 || flag_disasm) {
jit_disassemble();
fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
}
if (flag_verbose && argc) {
for (result = 0; result < argc; result++)
printf("argv[%d] = %s\n", result, argv[result]);
fprintf(stderr, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
}
jit_clear_state();
@@ -3996,12 +4142,11 @@ usage(void)
{
#if HAVE_GETOPT_LONG_ONLY
fprintf(stderr, "\
Usage: %s [jit assembler options] file [jit program options]\n\
Usage: %s [jit assembler options] file [--] [jit program options]\n\
Jit assembler options:\n\
-help Display this information\n\
-v[0-3] Verbose output level\n\
-d Do not use a data buffer\n\
-D<macro>[=<val>] Preprocessor options\n"
-d Do not use a data buffer\n"
# if defined(__i386__) && __WORDSIZE == 32
" -mx87=1 Force using x87 when sse2 available\n"
# endif
@@ -4017,11 +4162,10 @@ Jit assembler options:\n\
, progname);
#else
fprintf(stderr, "\
Usage: %s [jit assembler options] file [jit program options]\n\
Usage: %s [jit assembler options] file [--] [jit program options]\n\
Jit assembler options:\n\
-h Display this information\n\
-v Verbose output level\n\
-D<macro>[=<val>] Preprocessor options\n", progname);
-v Verbose output level\n", progname);
#endif
finish_jit();
exit(1);
@@ -4196,16 +4340,6 @@ main(int argc, char *argv[])
# define cc "gcc"
#endif
opt_short = snprintf(cmdline, sizeof(cmdline), cc " -E -x c %s", argv[opt_index]);
for (++opt_index; opt_index < argc; opt_index++) {
if (argv[opt_index][0] == '-')
opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short,
" %s", argv[opt_index]);
else {
--opt_index;
break;
}
}
opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short,
" -D__WORDSIZE=%d", __WORDSIZE);
@@ -4282,6 +4416,11 @@ main(int argc, char *argv[])
opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short,
" -D__alpha__=1");
#endif
#if defined(__loongarch__)
opt_short += snprintf(cmdline + opt_short,
sizeof(cmdline) - opt_short,
" -D__loongarch__=1");
#endif
if ((parser.fp = popen(cmdline, "r")) == NULL)
error("cannot execute %s", cmdline);
+1
View File
@@ -0,0 +1 @@
ok
+33
View File
@@ -0,0 +1,33 @@
.data 16
ok:
.c "ok"
.code
jmpi main
check_r0:
prolog
movi %v0 exit_r0
movi %r0 1
movi %r2 10
// on x86 this changes %rax on other arches could use %r0 as temporary
divi %r1 %r2 3
live %r0
// %r0 must still be 1
jmpr %v0
exit_r0:
retr %r0
epilog
main:
prolog
calli check_r0
retval %r1
beqi r0_ok %r1 1
calli @abort
r0_ok:
prepare
pushargi ok
finishi @puts
ret
epilog
+1
View File
@@ -0,0 +1 @@
ok
+62
View File
@@ -0,0 +1,62 @@
.data 8
ok:
.c "ok\n"
#define CMOVR(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R1 I0 \
movi %R2 I1 \
movi %R0 V \
OP##r##T %R0 %R1 %R2 \
beqi OP##T##N##r_##R0##R1##R2 %R0 V \
calli @abort \
OP##T##N##r_##R0##R1##R2:
/* reg0 = reg1 op reg0 */
#define CMOVR1(N, T, OP, I0, I1, V, R0, R1, R2) \
movi %R0 I1 \
movi %R1 I0 \
movi %R2 V \
OP##r##T %R0 %R1 %R0 \
beqr OP##T##N##r_1##R0##R1##R2 %R0 %R2 \
calli @abort \
OP##T##N##r_1##R0##R1##R2:
#define TEST_CMOV1(N, OP, I0, I1, V, R0, R1, R2) \
CMOVR(N, , OP, I0, I1, V, R0, R1, R2) \
CMOVR1(N, , OP, I0, I1, V, R0, R1, R2) \
#define TEST_CMOV(N, OP, I0, I1, V) \
TEST_CMOV1(N, OP, I0, I1, V, v0, v1, v2) \
TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r0) \
TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r1) \
TEST_CMOV1(N, OP, I0, I1, V, v0, v1, r2) \
TEST_CMOV1(N, OP, I0, I1, V, v1, v2, r1) \
TEST_CMOV1(N, OP, I0, I1, V, v1, v2, r2) \
TEST_CMOV1(N, OP, I0, I1, V, v2, r0, r1) \
TEST_CMOV1(N, OP, I0, I1, V, v2, r0, r2) \
TEST_CMOV1(N, OP, I0, I1, V, r0, r1, r2)
#define MOVZR(N, I0, I1, V) TEST_CMOV(N, movz, I0, I1, V)
#define MOVNR(N, I0, I1, V) TEST_CMOV(N, movn, I0, I1, V)
.code
prolog
MOVZR(0, 0x0, 0x0, 0x0)
MOVZR(1, 0xf7de, 0x0, 0xf7de)
MOVZR(2, 0x0, 0xdead, 0xdead)
MOVZR(3, 0xf7de, 0xdead, 0xdead)
MOVNR(0, 0x0, 0x0, 0x0)
MOVNR(1, 0xf7de, 0x0, 0x0)
MOVNR(2, 0x0, 0xdead, 0x0)
MOVNR(3, 0xf7de, 0xdead, 0xf7de)
prepare
pushargi ok
ellipsis
finishi @printf
ret
epilog
+59
View File
@@ -0,0 +1,59 @@
/*
* Simple test of (un)protecting a code buffer.
*/
#include <lightning.h>
#include <stdio.h>
#include <assert.h>
#define MARKER 10
int
main(int argc, char *argv[])
{
jit_state_t *_jit;
jit_node_t *load, *label, *ok;
unsigned char *ptr;
void (*function)(void);
int mmap_prot, mmap_flags;
init_jit(argv[0]);
_jit = jit_new_state();
jit_prolog();
load = jit_movi(JIT_R0, 0);
jit_ldr_c(JIT_R0, JIT_R0);
ok = jit_forward();
jit_patch_at(jit_beqi(JIT_R0, MARKER), ok);
jit_prepare();
jit_pushargi(1);
jit_finishi(exit);
label = jit_indirect();
jit_skip(1); /* Reserves enough space for a byte. */
jit_patch_at(load, label);
jit_link(ok);
jit_prepare();
jit_pushargi((jit_word_t)"%s\n");
jit_ellipsis();
jit_pushargi((jit_word_t)"ok");
jit_finishi(printf);
function = jit_emit();
if (function == NULL)
abort();
jit_unprotect ();
ptr = jit_address (label);
*ptr = MARKER;
jit_protect ();
jit_clear_state();
(*function)();
jit_destroy_state();
finish_jit();
return (0);
}
+89 -89
View File
@@ -9,49 +9,49 @@ ok:
putr:
prolog
frame 160
arg $ac
arg $auc
arg $as
arg $aus
arg $ai
arg_c $ac
arg_c $auc
arg_s $as
arg_s $aus
arg_i $ai
#if __WORDSIZE == 64
arg $aui
arg $al
arg_i $aui
arg_l $al
#endif
arg_f $af
arg_d $ad
arg $a
#if __WORDSIZE == 64
arg $_l
arg $_ui
arg_l $_l
arg_i $_ui
#endif
arg $_i
arg $_us
arg $_s
arg $_uc
arg $_c
arg_i $_i
arg_s $_us
arg_s $_s
arg_c $_uc
arg_c $_c
getarg_c %r0 $ac
negr %r0 %r0
putargr %r0 $ac
putargr_c %r0 $ac
getarg_uc %r0 $auc
negr %r0 %r0
putargr %r0 $auc
putargr_uc %r0 $auc
getarg_s %r0 $as
negr %r0 %r0
putargr %r0 $as
putargr_s %r0 $as
getarg_us %r0 $aus
negr %r0 %r0
putargr %r0 $aus
putargr_us %r0 $aus
getarg_i %r0 $ai
negr %r0 %r0
putargr %r0 $ai
putargr_i %r0 $ai
#if __WORDSIZE == 64
getarg_ui %r0 $aui
negr %r0 %r0
putargr %r0 $aui
putargr_ui %r0 $aui
getarg_l %r0 $al
negr %r0 %r0
putargr %r0 $al
putargr_l %r0 $al
#endif
getarg_f %f0 $af
negr_f %f0 %f0
@@ -65,49 +65,49 @@ putr:
#if __WORDSIZE == 64
getarg_l %r0 $_l
negr %r0 %r0
putargr %r0 $_l
putargr_l %r0 $_l
getarg_ui %r0 $_ui
negr %r0 %r0
putargr %r0 $_ui
putargr_ui %r0 $_ui
#endif
getarg_i %r0 $_i
negr %r0 %r0
putargr %r0 $_i
putargr_i %r0 $_i
getarg_us %r0 $_us
negr %r0 %r0
putargr %r0 $_us
putargr_us %r0 $_us
getarg_s %r0 $_s
negr %r0 %r0
putargr %r0 $_s
putargr_s %r0 $_s
getarg_uc %r0 $_uc
negr %r0 %r0
putargr %r0 $_uc
putargr_uc %r0 $_uc
getarg_c %r0 $_c
negr %r0 %r0
putargr %r0 $_c
putargr_c %r0 $_c
jmpi _putr
rputr:
putargi 17 $ac
putargi 16 $auc
putargi 15 $as
putargi 14 $aus
putargi 13 $ai
putargi_c 17 $ac
putargi_uc 16 $auc
putargi_s 15 $as
putargi_us 14 $aus
putargi_i 13 $ai
#if __WORDSIZE == 64
putargi 12 $aui
putargi 11 $al
putargi_ui 12 $aui
putargi_l 11 $al
#endif
putargi_f 10 $af
putargi_d 9 $ad
putargi 8 $a
#if __WORDSIZE == 64
putargi 7 $_l
putargi 6 $_ui
putargi_l 7 $_l
putargi_ui 6 $_ui
#endif
putargi 5 $_i
putargi 4 $_us
putargi 3 $_s
putargi 2 $_uc
putargi 1 $_c
putargi_i 5 $_i
putargi_us 4 $_us
putargi_s 3 $_s
putargi_uc 2 $_uc
putargi_c 1 $_c
jmpi _puti
rputi:
ret
@@ -117,27 +117,27 @@ rputi:
_putr:
prolog
tramp 160
arg $ac
arg $auc
arg $as
arg $aus
arg $ai
arg_c $ac
arg_c $auc
arg_s $as
arg_s $aus
arg_i $ai
#if __WORDSIZE == 64
arg $aui
arg $al
arg_i $aui
arg_l $al
#endif
arg_f $af
arg_d $ad
arg $a
#if __WORDSIZE == 64
arg $_l
arg $_ui
arg_l $_l
arg_i $_ui
#endif
arg $_i
arg $_us
arg $_s
arg $_uc
arg $_c
arg_i $_i
arg_s $_us
arg_s $_s
arg_c $_uc
arg_c $_c
getarg_c %r0 $ac
beqi rac %r0 -1
calli @abort
@@ -181,7 +181,7 @@ rad:
calli @abort
ra:
#if __WORDSIZE == 64
getarg %r0 $_l
getarg_l %r0 $_l
beqi r_l %r0 -11
calli @abort
r_l:
@@ -217,27 +217,27 @@ r_c:
_puti:
prolog
tramp 160
arg $ac
arg $auc
arg $as
arg $aus
arg $ai
arg_c $ac
arg_c $auc
arg_s $as
arg_s $aus
arg_i $ai
#if __WORDSIZE == 64
arg $aui
arg $al
arg_i $aui
arg_l $al
#endif
arg_f $af
arg_d $ad
arg $a
#if __WORDSIZE == 64
arg $_l
arg $_ui
arg_l $_l
arg_i $_ui
#endif
arg $_i
arg $_us
arg $_s
arg $_uc
arg $_c
arg_i $_i
arg_s $_us
arg_s $_s
arg_c $_uc
arg_c $_c
getarg_c %r0 $ac
beqi iac %r0 17
calli @abort
@@ -281,7 +281,7 @@ iad:
calli @abort
ia:
#if __WORDSIZE == 64
getarg %r0 $_l
getarg_l %r0 $_l
beqi i_l %r0 7
calli @abort
i_l:
@@ -390,27 +390,27 @@ fd2:
main:
prolog
prepare
pushargi 1
pushargi 2
pushargi 3
pushargi 4
pushargi 5
pushargi_c 1
pushargi_uc 2
pushargi_s 3
pushargi_us 4
pushargi_i 5
#if __WORDSIZE == 64
pushargi 6
pushargi 7
pushargi_ui 6
pushargi_l 7
#endif
pushargi_f 8
pushargi_d 9
pushargi 10
pushargi_f 8
pushargi_d 9
pushargi 10
#if __WORDSIZE == 64
pushargi 11
pushargi 12
pushargi_l 11
pushargi_ui 12
#endif
pushargi 13
pushargi 14
pushargi 15
pushargi 16
pushargi 17
pushargi_i 13
pushargi_us 14
pushargi_s 15
pushargi_uc 16
pushargi_c 17
finishi putr
prepare
pushargi 1
+173
View File
@@ -0,0 +1,173 @@
/*
* Simple test for x86_64 rip relative access that can also be useful
* on other ports when data is close to instruction pointer.
*/
#include <lightning.h>
#include <stdio.h>
#include <assert.h>
#include <sys/mman.h>
#if defined(__sgi)
# include <fcntl.h>
#endif
#include <unistd.h>
#ifndef MAP_ANON
# define MAP_ANON MAP_ANONYMOUS
# ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS 0
# endif
#endif
#if !defined(__sgi)
#define mmap_fd -1
#endif
int
main(int argc, char *argv[])
{
jit_uint8_t *ptr;
jit_state_t *_jit;
jit_word_t length;
#if defined(__sgi)
int mmap_fd;
#endif
void (*function)(void);
int mmap_prot, mmap_flags, result, pagesize;
int mult;
#if defined(__ia64__)
mult = 8;
#else
mult = 2;
#endif
pagesize = sysconf(_SC_PAGESIZE);
if (pagesize < 4096)
pagesize = 4096;
#if defined(__sgi)
mmap_fd = open("/dev/zero", O_RDWR);
#endif
mmap_prot = PROT_READ | PROT_WRITE;
#if !(__OpenBSD__ || __APPLE__)
mmap_prot |= PROT_EXEC;
#endif
#if __NetBSD__
mmap_prot = PROT_MPROTECT(mmap_prot);
mmap_flags = 0;
#else
mmap_flags = MAP_PRIVATE;
#endif
mmap_flags |= MAP_ANON;
ptr = mmap(NULL, pagesize * mult, mmap_prot, mmap_flags, mmap_fd, 0);
assert(ptr != MAP_FAILED);
#if defined(__sgi)
close(mmap_fd);
#endif
init_jit(argv[0]);
_jit = jit_new_state();
jit_prolog();
jit_movi(JIT_R0, 'c');
jit_sti_c(ptr + 0, JIT_R0);
jit_movi(JIT_R0, 'C');
jit_sti_c(ptr + 1, JIT_R0);
jit_movi(JIT_R0, 's');
jit_sti_s(ptr + 2, JIT_R0);
jit_movi(JIT_R0, 'S');
jit_sti_s(ptr + 4, JIT_R0);
jit_movi(JIT_R0, 'i');
jit_sti_i(ptr + 8, JIT_R0);
#if __WORDSIZE == 64
jit_movi(JIT_R0, 'I');
jit_sti_i(ptr + 12, JIT_R0);
jit_movi(JIT_R0, 'l');
jit_sti_l(ptr + 16, JIT_R0);
#endif
jit_movi_f(JIT_F0, 1.0);
jit_sti_f(ptr + 24, JIT_F0);
jit_movi_d(JIT_F0, 2.0);
jit_sti_d(ptr + 32, JIT_F0);
jit_ldi_c(JIT_R0, ptr + 0);
jit_ldi_s(JIT_R1, ptr + 2);
jit_ldi_i(JIT_R2, ptr + 8);
#if __WORDSIZE == 64
jit_ldi_l(JIT_V0, ptr + 16);
#endif
jit_prepare();
#if __WORDSIZE == 64
jit_pushargi((jit_word_t)"%c %c %c %c\n");
#else
jit_pushargi((jit_word_t)"%c %c %c l\n");
#endif
jit_ellipsis();
jit_pushargr(JIT_R0);
jit_pushargr(JIT_R1);
jit_pushargr(JIT_R2);
#if __WORDSIZE == 64
jit_pushargr(JIT_V0);
#endif
jit_finishi(printf);
jit_ldi_uc(JIT_R0, ptr + 1);
jit_ldi_us(JIT_R1, ptr + 4);
#if __WORDSIZE == 64
jit_ldi_ui(JIT_R2, ptr + 12);
#endif
jit_prepare();
#if __WORDSIZE == 64
jit_pushargi((jit_word_t)"%c %c %c\n");
#else
jit_pushargi((jit_word_t)"%c %c I\n");
#endif
jit_ellipsis();
jit_pushargr(JIT_R0);
jit_pushargr(JIT_R1);
#if __WORDSIZE == 64
jit_pushargr(JIT_R2);
#endif
jit_finishi(printf);
jit_ldi_f(JIT_F0, ptr + 24);
jit_extr_f_d(JIT_F0, JIT_F0);
jit_ldi_d(JIT_F1, ptr + 32);
jit_prepare();
jit_pushargi((jit_word_t)"%.1f %.1f\n");
jit_ellipsis();
jit_pushargr_d(JIT_F0);
jit_pushargr_d(JIT_F1);
jit_finishi(printf);
jit_realize();
jit_set_code(ptr + pagesize, pagesize * (mult - 1));
#if __NetBSD__ || __OpenBSD__ || __APPLE__
result = mprotect(ptr, pagesize, PROT_READ | PROT_WRITE);
assert(result == 0);
#endif
function = jit_emit();
if (function == NULL)
abort();
//jit_disassemble();
jit_clear_state();
#if __NetBSD__ || __OpenBSD__ || __APPLE__
result = mprotect(ptr + pagesize, pagesize, PROT_READ | PROT_EXEC);
assert(result == 0);
#endif
(*function)();
jit_destroy_state();
finish_jit();
munmap(ptr, pagesize * mult);
return (0);
}
+3
View File
@@ -0,0 +1,3 @@
c s i l
C S I
1.0 2.0
+21 -3
View File
@@ -31,14 +31,24 @@ main(int argc, char *argv[])
int mmap_fd;
#endif
void (*function)(void);
int mmap_prot, mmap_flags, result;
#if defined(__sgi)
mmap_fd = open("/dev/zero", O_RDWR);
#endif
ptr = mmap(NULL, 1024 * 1024,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
mmap_prot = PROT_READ | PROT_WRITE;
#if !(__OpenBSD__ || __APPLE__)
mmap_prot |= PROT_EXEC;
#endif
#if __NetBSD__
mmap_prot = PROT_MPROTECT(mmap_prot);
mmap_flags = 0;
#else
mmap_flags = MAP_PRIVATE;
#endif
mmap_flags |= MAP_ANON;
ptr = mmap(NULL, 1024 * 1024, mmap_prot, mmap_flags, mmap_fd, 0);
assert(ptr != MAP_FAILED);
#if defined(__sgi)
close(mmap_fd);
@@ -72,6 +82,10 @@ main(int argc, char *argv[])
if (function != NULL)
abort();
#if __NetBSD__
result = mprotect(ptr, 1024 * 1024, PROT_READ | PROT_WRITE);
assert(result == 0);
#endif
/* and calling again with enough space works */
jit_set_code(ptr, 1024 * 1024);
function = jit_emit();
@@ -79,6 +93,10 @@ main(int argc, char *argv[])
abort();
jit_clear_state();
#if __NetBSD__ || __OpenBSD__ || __APPLE__
result = mprotect(ptr, 1024 * 1024, PROT_READ | PROT_EXEC);
assert(result == 0);
#endif
(*function)();
jit_destroy_state();
finish_jit();
+1
View File
@@ -0,0 +1 @@
10
+13
View File
@@ -0,0 +1,13 @@
.data 32
fmt:
.c "%d\n"
.code
prolog
skip 4
prepare
pushargi fmt
ellipsis
pushargi 10
finishi @printf
ret
epilog
+62 -62
View File
@@ -55,7 +55,7 @@ fill##T##done: \
#define fill_us fill_s
#define fill_ui fill_i
#define ARG( T, N) arg $arg##T##N
#define ARG( T, N) arg##T $arg##T##N
#define ARGF( T, N) arg##T $arg##T##N
#define ARG1( K, T) ARG##K(T, 0)
#define ARG2( K, T) ARG1( K, T) ARG##K(T, 1)
@@ -74,56 +74,56 @@ fill##T##done: \
#define ARG15(K, T) ARG14(K, T) ARG##K(T, 14)
#define ARG16(K, T) ARG15(K, T) ARG##K(T, 15)
#define ARG_c(N) ARG##N( , _c)
#define ARG_uc(N) ARG##N( , _uc)
#define ARG_uc(N) ARG##N( , _c)
#define ARG_s(N) ARG##N( , _s)
#define ARG_us(N) ARG##N( , _us)
#define ARG_us(N) ARG##N( , _s)
#define ARG_i(N) ARG##N( , _i)
#define ARG_ui(N) ARG##N( , _ui)
#define ARG_ui(N) ARG##N( , _i)
#define ARG_l(N) ARG##N( , _l)
#define ARG_f(N) ARG##N(F, _f)
#define ARG_d(N) ARG##N(F, _d)
#define CHK(N, T, V) \
getarg %r0 $arg##T##V \
#define CHK(N, T, TT, V) \
getarg##T %r0 $arg##TT##V \
ldxi##T %r1 %v0 $(V * szof##T) \
beqr N##T##V %r0 %r1 \
calli @abort \
N##T##V:
#define CHKF(N, T, V) \
getarg##T %f0 $arg##T##V \
#define CHKF(N, T, TT, V) \
getarg##T %f0 $arg##TT##V \
ldxi##T %f1 %v0 $(V * szof##T) \
beqr##T N##T##V %f0 %f1 \
calli @abort \
N##T##V:
#define GET1( K, N, T, V) CHK##K(N, T, 0)
#define GET2( K, N, T, V) GET1( K, N, T, V) CHK##K(N, T, 1)
#define GET3( K, N, T, V) GET2( K, N, T, V) CHK##K(N, T, 2)
#define GET4( K, N, T, V) GET3( K, N, T, V) CHK##K(N, T, 3)
#define GET5( K, N, T, V) GET4( K, N, T, V) CHK##K(N, T, 4)
#define GET6( K, N, T, V) GET5( K, N, T, V) CHK##K(N, T, 5)
#define GET7( K, N, T, V) GET6( K, N, T, V) CHK##K(N, T, 6)
#define GET8( K, N, T, V) GET7( K, N, T, V) CHK##K(N, T, 7)
#define GET9( K, N, T, V) GET8( K, N, T, V) CHK##K(N, T, 8)
#define GET10(K, N, T, V) GET9( K, N, T, V) CHK##K(N, T, 9)
#define GET11(K, N, T, V) GET10(K, N, T, V) CHK##K(N, T, 10)
#define GET12(K, N, T, V) GET11(K, N, T, V) CHK##K(N, T, 11)
#define GET13(K, N, T, V) GET12(K, N, T, V) CHK##K(N, T, 12)
#define GET14(K, N, T, V) GET13(K, N, T, V) CHK##K(N, T, 13)
#define GET15(K, N, T, V) GET14(K, N, T, V) CHK##K(N, T, 14)
#define GET16(K, N, T, V) GET15(K, N, T, V) CHK##K(N, T, 15)
#define GET1( K, N, T, TT, V) CHK##K(N, T, TT, 0)
#define GET2( K, N, T, TT, V) GET1( K, N, T, TT, V) CHK##K(N, T, TT, 1)
#define GET3( K, N, T, TT, V) GET2( K, N, T, TT, V) CHK##K(N, T, TT, 2)
#define GET4( K, N, T, TT, V) GET3( K, N, T, TT, V) CHK##K(N, T, TT, 3)
#define GET5( K, N, T, TT, V) GET4( K, N, T, TT, V) CHK##K(N, T, TT, 4)
#define GET6( K, N, T, TT, V) GET5( K, N, T, TT, V) CHK##K(N, T, TT, 5)
#define GET7( K, N, T, TT, V) GET6( K, N, T, TT, V) CHK##K(N, T, TT, 6)
#define GET8( K, N, T, TT, V) GET7( K, N, T, TT, V) CHK##K(N, T, TT, 7)
#define GET9( K, N, T, TT, V) GET8( K, N, T, TT, V) CHK##K(N, T, TT, 8)
#define GET10(K, N, T, TT, V) GET9( K, N, T, TT, V) CHK##K(N, T, TT, 9)
#define GET11(K, N, T, TT, V) GET10(K, N, T, TT, V) CHK##K(N, T, TT, 10)
#define GET12(K, N, T, TT, V) GET11(K, N, T, TT, V) CHK##K(N, T, TT, 11)
#define GET13(K, N, T, TT, V) GET12(K, N, T, TT, V) CHK##K(N, T, TT, 12)
#define GET14(K, N, T, TT, V) GET13(K, N, T, TT, V) CHK##K(N, T, TT, 13)
#define GET15(K, N, T, TT, V) GET14(K, N, T, TT, V) CHK##K(N, T, TT, 14)
#define GET16(K, N, T, TT, V) GET15(K, N, T, TT, V) CHK##K(N, T, TT, 15)
#define GET_c(N, M) GET##N( , c##N, _c, M)
#define GET_uc(N, M) GET##N( , uc##N, _uc, M)
#define GET_s(N, M) GET##N( , s##N, _s, M)
#define GET_us(N, M) GET##N( , us##N, _us, M)
#define GET_i(N, M) GET##N( , i##N, _i, M)
#define GET_ui(N, M) GET##N( , ui##N, _ui, M)
#define GET_l(N, M) GET##N( , l##N, _l, M)
#define GET_f(N, M) GET##N(F, f##N, _f, M)
#define GET_d(N, M) GET##N(F, d##N, _d, M)
#define GET_c(N, M) GET##N( , c##N, _c, _c, M)
#define GET_uc(N, M) GET##N( , uc##N, _uc, _c, M)
#define GET_s(N, M) GET##N( , s##N, _s, _s, M)
#define GET_us(N, M) GET##N( , us##N, _us, _s, M)
#define GET_i(N, M) GET##N( , i##N, _i, _i, M)
#define GET_ui(N, M) GET##N( , ui##N, _ui, _i, M)
#define GET_l(N, M) GET##N( , l##N, _l, _l, M)
#define GET_f(N, M) GET##N(F, f##N, _f, _f, M)
#define GET_d(N, M) GET##N(F, d##N, _d, _d, M)
#define PUSH( T, V) pushargi V
#define PUSH( T, V) pushargi##T V
#define PUSHF( T, V) pushargi##T V
#define PUSH0( K, T) /**/
#define PUSH1( K, T) PUSH##K(T, 0)
@@ -161,14 +161,14 @@ test##T##_0: \
ret \
epilog
#define DEFN(N, M, T) \
#define DEFN(N, M, T, TT) \
name test##T##_##N \
test##T##_##N: \
prolog \
arg $argp \
/* stack buffer in %v0 */ \
getarg %v0 $argp \
ARG##T(N) \
ARG##TT(N) \
/* validate arguments */ \
GET##T(N, M) \
/* heap buffer in %v1 */ \
@@ -258,24 +258,24 @@ test##T##_17_done: \
ret \
epilog
#define DEF( T) \
#define DEF( T, TT) \
DEF0( T) \
DEFN( 1, 0, T) \
DEFN( 2, 1, T) \
DEFN( 3, 2, T) \
DEFN( 4, 3, T) \
DEFN( 5, 4, T) \
DEFN( 6, 5, T) \
DEFN( 7, 6, T) \
DEFN( 8, 7, T) \
DEFN( 9, 8, T) \
DEFN(10, 9, T) \
DEFN(11, 10, T) \
DEFN(12, 11, T) \
DEFN(13, 12, T) \
DEFN(14, 13, T) \
DEFN(15, 14, T) \
DEFN(16, 15, T) \
DEFN( 1, 0, T, TT) \
DEFN( 2, 1, T, TT) \
DEFN( 3, 2, T, TT) \
DEFN( 4, 3, T, TT) \
DEFN( 5, 4, T, TT) \
DEFN( 6, 5, T, TT) \
DEFN( 7, 6, T, TT) \
DEFN( 8, 7, T, TT) \
DEFN( 9, 8, T, TT) \
DEFN(10, 9, T, TT) \
DEFN(11, 10, T, TT) \
DEFN(12, 11, T, TT) \
DEFN(13, 12, T, TT) \
DEFN(14, 13, T, TT) \
DEFN(15, 14, T, TT) \
DEFN(16, 15, T, TT) \
DEFX(T)
#define CALL(T) calli test##T##_17
@@ -321,17 +321,17 @@ memcpy_done:
FILLF(_f)
FILLF(_d)
DEF(_c)
DEF(_uc)
DEF(_s)
DEF(_us)
DEF(_i)
DEF(_c, _c)
DEF(_uc, _c)
DEF(_s, _s)
DEF(_us, _s)
DEF(_i, _i)
#if __WORDSIZE == 64
DEF(_ui)
DEF(_l)
DEF(_ui, _i)
DEF(_l, _l)
#endif
DEF(_f)
DEF(_d)
DEF(_f, _f)
DEF(_d, _d)
name main
main:
+116 -54
View File
@@ -1,5 +1,5 @@
dnl
dnl Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
dnl Copyright 2000, 2001, 2002, 2012-2023 Free Software Foundation, Inc.
dnl
dnl This file is part of GNU lightning.
dnl
@@ -7,26 +7,29 @@ dnl GNU lightning is free software; you can redistribute it and/or modify it
dnl under the terms of the GNU Lesser General Public License as published
dnl by the Free Software Foundation; either version 3, or (at your option)
dnl any later version.
dnl
dnl
dnl GNU lightning is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
dnl License for more details.
dnl
AC_PREREQ(2.57)
AC_INIT([GNU lightning], 2.1.3, pcpa@gnu.org, lightning)
AC_PREREQ([2.71])
AC_INIT([GNU lightning],[2.2.1],[pcpa@gnu.org],[lightning])
AC_CONFIG_AUX_DIR([build-aux])
AC_CANONICAL_TARGET
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_CONFIG_MACRO_DIR(m4)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LIBTOOL
gl_EARLY
AM_PROG_AR
LT_INIT
gl_INIT
case "$target_cpu" in
ia64)
@@ -57,10 +60,16 @@ case "$target_cpu" in
fi ;;
*) ;;
esac ;;
aarch64)
case "$host_os" in
darwin*)
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DPACKED_STACK=1" ;;
*) ;;
esac ;;
*) ;;
esac
AC_CHECK_FUNCS(mremap ffsl getopt_long_only isnan isinf,,)
AC_CHECK_FUNCS(mmap mremap ffsl getopt_long_only isnan isinf,,)
AC_CHECK_HEADERS([getopt.h stdint.h],,,)
@@ -69,7 +78,7 @@ AC_ARG_ENABLE(disassembler,
[Enable jit disassembler using binutils]),
[DISASSEMBLER=$enableval], [DISASSEMBLER=auto])
if test "x$DISASSEMBLER" != "xno"; then
# FIXME need to check for libiberty first or will fail to link
AC_CHECK_LIB(iberty, htab_try_create, ,
[HAVE_IBERTY="no"])
AC_CHECK_LIB(bfd, bfd_init, ,
@@ -78,26 +87,50 @@ if test "x$DISASSEMBLER" != "xno"; then
[HAVE_Z="no"])
AC_CHECK_LIB(opcodes, init_disassemble_info, ,
[HAVE_OPCODES="no"])
if test "x$HAVE_IBERTY" = "xno" -o \
"x$HAVE_BFD" = "xno" -o \
"x$HAVE_Z" = "xno" -o \
"x$HAVE_OPCODES" = "xno"; then
if test "x$DISASSEMBLER" != "xauto"; then
AC_MSG_ERROR([binutils not found, see http://www.gnu.org/software/binutils/])
else
AC_MSG_WARN([binutils not found, see http://www.gnu.org/software/binutils/])
DISASSEMBLER="no"
fi
if test "x$HAVE_IBERTY" = "xno"; then
if test "x$DISASSEMBLER" = "xyes"; then
AC_MSG_ERROR([libiberty not found])
else
AC_MSG_WARN([libiberty not found])
DISASSEMBLER="no"
fi
fi
if test "x$HAVE_BFD" = "xno"; then
if test "x$DISASSEMBLER" = "xyes"; then
AC_MSG_ERROR([binutils BFD not found, see http://www.gnu.org/software/binutils/])
else
AC_MSG_WARN([binutils BFD not found, see http://www.gnu.org/software/binutils/])
DISASSEMBLER="no"
fi
fi
if test "x$HAVE_Z" = "xno"; then
if test "x$DISASSEMBLER" = "xyes"; then
AC_MSG_ERROR([zlib not found, see https://zlib.net/])
else
AC_MSG_WARN([zlib not found, see https://zlib.net/])
DISASSEMBLER="no"
fi
fi
if test "x$HAVE_OPCODES" = "xno"; then
if test "x$DISASSEMBLER" = "xyes"; then
AC_MSG_ERROR([binutils opcodes not found, see https://www.gnu.org/software/binutils/])
else
AC_MSG_WARN([binutils opcodes not found, see https://www.gnu.org/software/binutils/])
DISASSEMBLER="no"
fi
fi
fi
AM_CONDITIONAL(with_disassembler, [test "x$DISASSEMBLER" != "xno"])
if test "x$DISASSEMBLER" != "xno"; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1"
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -I$PWD/include -D_GNU_SOURCE"
CFLAGS="$CFLAGS -D_GNU_SOURCE"
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
#include <lightning.h>
#include <lightning/jit_private.h>
#include <dis-asm.h>
int main(int argc, char *argv[])
{
@@ -107,10 +140,22 @@ if test "x$DISASSEMBLER" != "xno"; then
return 0;
}
)], [ac_cv_test_new_disassembler=no],,)
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
#include <dis-asm.h>
int main(int argc, char *argv[])
{
struct disassemble_info dinfo;
INIT_DISASSEMBLE_INFO(dinfo, NULL, NULL, NULL);
return 0;
}
)], [ac_cv_test_new_disassemble_info=yes],[ac_cv_test_new_disassemble_info=no],)
CFLAGS="$save_CFLAGS"
if test "x$ac_cv_test_new_disassembler" != "xno"; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DBINUTILS_2_29=1"
fi
if test "x$ac_cv_test_new_disassemble_info" != "xno"; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DBINUTILS_2_38=1"
fi
fi
AC_ARG_ENABLE(devel-disassembler,
@@ -124,17 +169,6 @@ if test "x$DEVEL_DISASSEMBLER" != "xno"; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDEVEL_DISASSEMBLER=1"
fi
AC_ARG_ENABLE(assertions,
AS_HELP_STRING([--enable-assertions],
[Enable runtime code generation assertions]),
[DEBUG=$enableval], [DEBUG=auto])
if test "x$DEBUG" = xyes; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDEBUG=1"
else
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DNDEBUG"
DEBUG=no
fi
# This option is only useful during development.
AC_ARG_ENABLE(devel-get-jit-size,
AS_HELP_STRING([--enable-devel-get-jit-size],
@@ -142,11 +176,36 @@ AC_ARG_ENABLE(devel-get-jit-size,
[GET_JIT_SIZE=$enableval], [GET_JIT_SIZE=no])
AM_CONDITIONAL(get_jit_size, [test $GET_JIT_SIZE = yes])
case "$host_os" in
*bsd*|osf*) SHLIB="" ;;
*hpux*) SHLIB="-ldld" ;;
*) SHLIB="-ldl" ;;
esac
AC_ARG_ENABLE(assertions,
AS_HELP_STRING([--enable-assertions],
[Enable runtime code generation assertions]),
[DEBUG=$enableval], [DEBUG=auto])
# This option might be made default in the future
# Currently it is only useful to ensure existing code will work
# if PACKED_STACK is also defined.
AC_ARG_ENABLE(devel-strong-type-checking,
AS_HELP_STRING([--enable-devel-strong-type-checking],
[Devel mode for strong type checking]),
[STRONG_TYPE_CHECKING=$enableval], [STRONG_TYPE_CHECKING=no])
if test "x$DEBUG" = xyes -o x"$STRONG_TYPE_CHECKING" = xyes; then
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDEBUG=1"
else
LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DNDEBUG"
DEBUG=no
fi
AM_CONDITIONAL(strong_type_checking, [test $STRONG_TYPE_CHECKING = yes])
AC_CHECK_LIB(dl, dlopen, [HAVE_LIBDL="yes"])
AC_CHECK_LIB(dld, dlopen, [HAVE_LIBDLD="yes"])
if test "x$HAVE_LIBDL" = xyes; then
SHLIB="-ldl";
elif test "x$HAVE_LIBDLD" = xyes; then
SHLIB="-ldld";
else
SHLIB="";
fi
AC_SUBST(SHLIB)
cpu=
@@ -162,19 +221,21 @@ case "$target_cpu" in
s390*) cpu=s390 ;;
alpha*) cpu=alpha ;;
riscv*) cpu=riscv ;;
loongarch*) cpu=loongarch ;;
*) ;;
esac
AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm])
AM_CONDITIONAL(cpu_mips, [test cpu-$cpu = cpu-mips])
AM_CONDITIONAL(cpu_ppc, [test cpu-$cpu = cpu-ppc])
AM_CONDITIONAL(cpu_sparc, [test cpu-$cpu = cpu-sparc])
AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86])
AM_CONDITIONAL(cpu_ia64, [test cpu-$cpu = cpu-ia64])
AM_CONDITIONAL(cpu_hppa, [test cpu-$cpu = cpu-hppa])
AM_CONDITIONAL(cpu_aarch64, [test cpu-$cpu = cpu-aarch64])
AM_CONDITIONAL(cpu_s390, [test cpu-$cpu = cpu-s390])
AM_CONDITIONAL(cpu_alpha, [test cpu-$cpu = cpu-alpha])
AM_CONDITIONAL(cpu_riscv, [test cpu-$cpu = cpu-riscv])
AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm])
AM_CONDITIONAL(cpu_mips, [test cpu-$cpu = cpu-mips])
AM_CONDITIONAL(cpu_ppc, [test cpu-$cpu = cpu-ppc])
AM_CONDITIONAL(cpu_sparc, [test cpu-$cpu = cpu-sparc])
AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86])
AM_CONDITIONAL(cpu_ia64, [test cpu-$cpu = cpu-ia64])
AM_CONDITIONAL(cpu_hppa, [test cpu-$cpu = cpu-hppa])
AM_CONDITIONAL(cpu_aarch64, [test cpu-$cpu = cpu-aarch64])
AM_CONDITIONAL(cpu_s390, [test cpu-$cpu = cpu-s390])
AM_CONDITIONAL(cpu_alpha, [test cpu-$cpu = cpu-alpha])
AM_CONDITIONAL(cpu_riscv, [test cpu-$cpu = cpu-riscv])
AM_CONDITIONAL(cpu_loongarch, [test cpu-$cpu = cpu-loongarch])
# Test x87 if both, x87 and sse2 available
ac_cv_test_x86_x87=
@@ -184,16 +245,15 @@ ac_cv_test_arm_arm=
ac_cv_test_arm_swf=
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -I$PWD/include -D_GNU_SOURCE"
CFLAGS="$CFLAGS -D_GNU_SOURCE"
if test x$cpu = x; then
AC_MSG_ERROR([cpu $target_cpu not supported])
elif test $cpu = x86; then
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <lightning.h>
int main(void) {
int ac, flags;
unsigned int eax, ebx, ecx, edx;
if (__WORDSIZE == 64)
if (sizeof(long) == 8)
return 1;
__asm__ volatile ("pushfl;\n\t"
"popl %0;\n\t"
@@ -289,11 +349,13 @@ if test $ac_cv_header_stdint_h = yes; then
AC_SUBST(MAYBE_INCLUDE_STDINT_H, ["#include <stdint.h>"])
fi
AC_OUTPUT([Makefile
AC_CONFIG_FILES([Makefile
lightning.pc
gnulib-lib/Makefile
doc/Makefile
include/Makefile
include/lightning/Makefile
include/lightning.h
lib/Makefile
check/Makefile])
AC_OUTPUT
+11
View File
@@ -1,2 +1,13 @@
*.info*
stamp-*
/version.texi
texinfo.tex
mdate-sh
fact
ifib
incr
printf
rfib
rpn
+3 -2
View File
@@ -1,5 +1,5 @@
#
# Copyright 2012-2019 Free Software Foundation, Inc.
# Copyright 2012-2023 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
@@ -14,7 +14,8 @@
# License for more details.
#
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
AM_CFLAGS = -I $(top_builddir)/include -I$(top_srcdir)/include \
-D_GNU_SOURCE $(LIGHTNING_CFLAGS)
info_TEXINFOS = lightning.texi
MOSTLYCLEANFILES = lightning.tmp
+268 -51
View File
@@ -30,6 +30,7 @@ dynamic code generation.
* The instruction set:: The RISC instruction set used in GNU lightning
* GNU lightning examples:: GNU lightning's examples
* Reentrancy:: Re-entrant usage of GNU lightning
* Registers:: Accessing the whole register file
* Customizations:: Advanced code generation customizations
* Acknowledgements:: Acknowledgements for GNU lightning
@end menu
@@ -43,8 +44,8 @@ This document describes @value{TOPIC} the @lightning{} library for
dynamic code generation.
@end iftex
Dynamic code generation is the generation of machine code
at runtime. It is typically used to strip a layer of interpretation
Dynamic code generation is the generation of machine code
at runtime. It is typically used to strip a layer of interpretation
by allowing compilation to occur at runtime. One of the most
well-known applications of dynamic code generation is perhaps that
of interpreters that compile source code to an intermediate bytecode
@@ -53,7 +54,7 @@ approach effectively combines the portability of bytecode
representations with the speed of machine code. Another common
application of dynamic code generation is in the field of hardware
simulators and binary emulators, which can use the same techniques
to translate simulated instructions to the instructions of the
to translate simulated instructions to the instructions of the
underlying machine.
Yet other applications come to mind: for example, windowing
@@ -68,7 +69,7 @@ retargeted for each machine; in addition, coding a run-time code
generator is a tedious and error-prone task more than a difficult one.
@lightning{} provides a portable, fast and easily retargetable dynamic
code generation system.
code generation system.
To be portable, @lightning{} abstracts over current architectures'
quirks and unorthogonalities. The interface that it exposes to is that
@@ -88,7 +89,11 @@ assembles machine instructions without further tests.
@node Installation
@chapter Configuring and installing @lightning{}
The first thing to do to use @lightning{} is to configure the
Here we will assume that your system already has the dependencies
necessary to build @lightning{}. For more on dependencies, see
@lightning{}'s @file{README-hacking} file.
The first thing to do to build @lightning{} is to configure the
program, picking the set of macros to be used on the host
architecture; this configuration is automatically performed by
the @file{configure} shell script; to run it, merely type:
@@ -96,17 +101,30 @@ the @file{configure} shell script; to run it, merely type:
./configure
@end example
@lightning{} supports the @code{--enable-disassembler} option, that
enables linking to GNU binutils and optionally print human readable
The @file{configure} accepts the @code{--enable-disassembler} option,
hat enables linking to GNU binutils and optionally print human readable
disassembly of the jit code. This option can be disabled by the
@code{--disable-disassembler} option.
Another option that @file{configure} accepts is
@code{--enable-assertions}, which enables several consistency checks in
the run-time assemblers. These are not usually needed, so you can
decide to simply forget about it; also remember that these consistency
@file{configure} also accepts the @code{--enable-devel-disassembler},
option useful to check exactly hat machine instructions were generated
for a @lightning{} instrction. Basically mixing @code{jit_print} and
@code{jit_disassembly}.
The @code{--enable-assertions} option, which enables several consistency
hecks in the run-time assemblers. These are not usually needed, so you
can decide to simply forget about it; also remember that these consistency
checks tend to slow down your code generator.
The @code{--enable-devel-strong-type-checking} option that does extra type
checking using @code{assert}. This option also enables the
@code{--enable-assertions} unless it is explicitly disabled.
The option @code{--enable-devel-get-jit-size} should only be used
when doing updates or maintenance to lightning. It regenerates the
@code{jit_$ARCH]-sz.c} creating a table or maximum bytes usage when
translating a @lightning{} instruction to machine code.
After you've configured @lightning{}, run @file{make} as usual.
@lightning{} has an extensive set of tests to validate it is working
@@ -243,6 +261,8 @@ lshr O1 = O2 << O3
lshi O1 = O2 << O3
rshr _u O1 = O2 >> O3@footnote{The sign bit is propagated unless using the @code{_u} modifier.}
rshi _u O1 = O2 >> O3@footnote{The sign bit is propagated unless using the @code{_u} modifier.}
movzr O1 = O3 ? O1 : O2
movnr O1 = O3 ? O2 : O1
@end example
@item Four operand binary ALU operations
@@ -271,12 +291,27 @@ These accept two operands, both of which must be registers.
@example
negr _f _d O1 = -O2
comr O1 = ~O2
clor O1 = number of leading one bits
clzr O1 = number of leading zero bits
ctor O1 = number of trailing one bits
ctzr O1 = number of trailing zero bits
@end example
Note that @code{ctzr} is basically equivalent of a @code{C} call
@code{ffs} but indexed at bit zero, not one.
Contrary to @code{__builtin_ctz} and @code{__builtin_clz}, an input
value of zero is not an error, it just returns the number of bits
in a word, 64 if @lightning{} generates 64 bit instructions, otherwise
it returns 32.
The @code{clor} and @code{ctor} are just counterparts of the versions
that search for zero bits.
These unary ALU operations are only defined for float operands.
@example
absr _f _d O1 = fabs(O2)
sqrtr O1 = sqrt(O2)
sqrtr _f _d O1 = sqrt(O2)
@end example
Besides requiring the @code{r} modifier, there are no unary operations
@@ -365,6 +400,14 @@ htonr _us _ui _ul @r{Host-to-network (big endian) order}
ntohr _us _ui _ul @r{Network-to-host order }
@end example
@code{bswapr} can be used to unconditionally byte-swap an operand.
On little-endian architectures, @code{htonr} and @code{ntohr} resolve
to this.
The @code{_ul} variant is only available in 64-bit architectures.
@example
bswapr _us _ui _ul 01 = byte_swap(02)
@end example
@item Load operations
@code{ld} accepts two operands while @code{ldx} accepts three;
in both cases, the last can be either a register or an immediate
@@ -386,31 +429,33 @@ ldxi _c _uc _s _us _i _ui _l _f _d O1 = *(O2+O3)
both cases, the first can be either a register or an immediate
value. Values are sign-extended to fit a whole register.
@example
str _c _uc _s _us _i _ui _l _f _d *O1 = O2
sti _c _uc _s _us _i _ui _l _f _d *O1 = O2
stxr _c _uc _s _us _i _ui _l _f _d *(O1+O2) = O3
stxi _c _uc _s _us _i _ui _l _f _d *(O1+O2) = O3
str _c _s _i _l _f _d *O1 = O2
sti _c _s _i _l _f _d *O1 = O2
stxr _c _s _i _l _f _d *(O1+O2) = O3
stxi _c _s _i _l _f _d *(O1+O2) = O3
@end example
As for the load operations, the @code{_ui} and @code{_l} types are
only available in 64-bit architectures, and for convenience, there
is a version without a type modifier for integer or pointer operands
that uses the appropriate wordsize call.
Note that the unsigned type modifier is not available, as the store
only writes to the 1, 2, 4 or 8 sized memory address.
The @code{_l} type is only available in 64-bit architectures, and for
convenience, there is a version without a type modifier for integer or
pointer operands that uses the appropriate wordsize call.
@item Argument management
These are:
@example
prepare (not specified)
va_start (not specified)
pushargr _f _d
pushargi _f _d
pushargr _c _uc _s _us _i _ui _l _f _d
pushargi _c _uc _s _us _i _ui _l _f _d
va_push (not specified)
arg _f _d
arg _c _uc _s _us _i _ui _l _f _d
getarg _c _uc _s _us _i _ui _l _f _d
va_arg _d
putargr _f _d
putargi _f _d
putargr _c _uc _s _us _i _ui _l _f _d
putargi _c _uc _s _us _i _ui _l _f _d
ret (not specified)
retr _f _d
retr _c _uc _s _us _i _ui _l _f _d
reti _c _uc _s _us _i _ui _l _f _d
reti _f _d
va_end (not specified)
retval _c _uc _s _us _i _ui _l _f _d
@@ -429,6 +474,15 @@ the @code{pushargr} or @code{pushargi} to push the arguments @strong{in
left to right order}; and use @code{finish} or @code{call} (explained below)
to perform the actual call.
Note that @code{arg}, @code{pusharg}, @code{putarg} and @code{ret} when
handling integer types can be used without a type modifier.
It is suggested to use matching type modifiers to @code{arg}, @code{putarg}
and @code{getarg} otherwise problems will happen if generating jit for
environments that require arguments to be truncated and zero or sign
extended by the caller and/or excess arguments might be passed packed
in the stack. Currently only Apple systems with @code{aarch64} cpus are
known to have this restriction.
@code{va_start} returns a @code{C} compatible @code{va_list}. To fetch
arguments, use @code{va_arg} for integers and @code{va_arg_d} for doubles.
@code{va_push} is required when passing a @code{va_list} to another function,
@@ -550,6 +604,10 @@ bxsubr _u O2 -= O3@r{, goto }O1@r{ if no overflow}
bxsubi _u O2 -= O3@r{, goto }O1@r{ if no overflow}
@end example
Note that the @code{C} code does not have an @code{O1} argument. It is
required to always use the return value as an argument to @code{patch},
@code{patch_at} or @code{patch_abs}.
@item Jump and return operations
These accept one argument except @code{ret} and @code{jmpi} which
have none; the difference between @code{finishi} and @code{calli}
@@ -582,6 +640,20 @@ forward (not specified) @r{forward label}
indirect (not specified) @r{special simple label}
@end example
The following instruction is used to specify a minimal alignment for
the next instruction, usually with a label:
@example
align (not specified) @r{align code}
@end example
Similar to @code{align} is the next instruction, also usually used with
a label:
@example
skip (not specified) @r{skip code}
@end example
It is used to specify a minimal number of bytes of nops to be inserted
before the next instruction.
@code{label} is normally used as @code{patch_at} argument for backward
jumps.
@@ -634,6 +706,42 @@ that automatically binds the implicit label added by @code{patch} with
the @code{movi}, but on some special conditions it is required to create
an "unbound" label.
@code{align} is useful for creating multiple entry points to a
(trampoline) function that are all accessible through a single
function pointer. @code{align} receives an integer argument that
defines the minimal alignment of the address of a label directly
following the @code{align} instruction. The integer argument must be
a power of two and the effective alignment will be a power of two no
less than the argument to @code{align}. If the argument to
@code{align} is 16 or more, the effective alignment will match the
specified minimal alignment exactly.
@example
jit_node_t *forward, *label1, *label2, *jump;
unsigned char *addr1, *addr2;
forward = jit_forward();
jit_align(16);
label1 = jit_indirect(); @rem{/* first entry point */}
jump = jit_jmpi(); @rem{/* jump to first handler */}
jit_patch_at(jump, forward);
jit_align(16);
label2 = jit_indirect(); @rem{/* second entry point */}
... @rem{/* second handler */}
jit_jmpr(...);
jit_link(forward);
... @rem{/* first handler /*}
jit_jmpr(...);
...
jit_emit();
addr1 = jit_address(label1);
addr2 = jit_address(label2);
assert(addr2 - addr1 == 16); @rem{/* only one of the addresses needs to be remembered */}
@end example
@code{skip} is useful for reserving space in the code buffer that can
later be filled (possibly with the help of the pair of functions
@code{jit_unprotect} and @code{jit_protect}).
@item Function prolog
These macros are used to set up a function prolog. The @code{allocai}
@@ -695,6 +803,51 @@ in = arg @rem{! Same as above}
ret @rem{! Return to caller}
@end example
@item Register liveness
During code generation, @lightning{} occasionally needs scratch registers
or needs to use architecture-defined registers. For that, @lightning{}
internally maintains register liveness information.
In the following example, @code{qdivr} will need special registers like
@code{R0} on some architectures. As @lightning{} understands that
@code{R0} is used in the subsequent instruction, it will create
save/restore code for @code{R0} in case.
@example
...
qdivr V0, V1, V2, V3
movr V3, R0
...
@end example
The same is not true in the example that follows. Here, @code{R0} is
not alive after the division operation because @code{R0} is neither an
argument register nor a callee-save register. Thus, no save/restore
code for @code{R0} will be created in case.
@example
...
qdivr V0, V1, V2, V3
jmpr R1
...
@end example
The @code{live} instruction can be used to mark a register as live after
it as in the following example. Here, @code{R0} will be preserved
across the division.
@example
...
qdivr V0, V1, V2, V3
live R0
jmpr R1
...
@end example
The @code{live} instruction is useful at code entry and exit points,
like after and before a @code{callr} instruction.
@item Trampolines, continuations and tail call optimization
Frequently it is required to generate jit code that must jump to
@@ -821,7 +974,7 @@ will return non zero if the argument lives in a register. This call
is useful to know the live range of register arguments, as those
are very fast to read and write, but have volatile values.
@code{callee_save_p} exects a valid @code{JIT_Rn}, @code{JIT_Vn}, or
@code{callee_save_p} expects a valid @code{JIT_Rn}, @code{JIT_Vn}, or
@code{JIT_Fn}, and will return non zero if the register is callee
save. This call is useful because on several ports, the @code{JIT_Rn}
and @code{JIT_Fn} registers are actually callee save; no need
@@ -830,6 +983,34 @@ to save and load the values when making function calls.
@code{pointer_p} expects a pointer argument, and will return non
zero if the pointer is inside the generated jit code. Must be
called after @code{jit_emit} and before @code{jit_destroy_state}.
@item Atomic operations
Only compare-and-swap is implemented. It accepts four operands;
the second can be an immediate.
The first argument is set with a boolean value telling if the operation
did succeed.
Arguments must be different, cannot use the result register to also pass
an argument.
The second argument is the address of a machine word.
The third argument is the old value.
The fourth argument is the new value.
@example
casr 01 = (*O2 == O3) ? (*O2 = O4, 1) : 0
casi 01 = (*O2 == O3) ? (*O2 = O4, 1) : 0
@end example
If value at the address in the second argument is equal to the third
argument, the address value is atomically modified to the value of the
fourth argument and the first argument is set to a non zero value.
If the value at the address in the second argument is not equal to the
third argument nothing is done and the first argument is set to zero.
@end table
@node GNU lightning examples
@@ -1005,9 +1186,9 @@ programmer would write):
mov %i0, %g2 retl
inc %g2 inc %o0
mov %g2, %i0
restore
retl
nop
restore
retl
nop
@end example
In this case, @lightning{} introduces overhead to create a register
window (not knowing that the procedure is a leaf procedure) and to
@@ -1018,26 +1199,13 @@ maps to @code{%g2} on the SPARC).
@table @b
@item x86_64
@example
sub $0x30,%rsp
mov %rbp,(%rsp)
mov %rsp,%rbp
sub $0x18,%rsp
mov %rdi,%rax mov %rdi, %rax
add $0x1,%rax inc %rax
mov %rbp,%rsp
mov (%rsp),%rbp
add $0x30,%rsp
retq retq
mov %rdi,%rax
add $0x1,%rax
ret
@end example
In this case, the main overhead is due to the function's prolog and
epilog, and stack alignment after reserving stack space for word
to/from float conversions or moving data from/to x87 to/from SSE.
Note that besides allocating space to save callee saved registers,
no registers are saved/restored because @lightning{} notices those
registers are not modified. There is currently no logic to detect
if it needs to allocate stack space for type conversions neither
proper leaf function detection, but these are subject to change
(FIXME).
In this case, for the x86 port, @lightning{} has simple optimizations
to understand it is a leaf function, and that it is not required to
create a stack frame nor update the stack pointer.
@end table
@node printf
@@ -1201,7 +1369,7 @@ jit_node_t *compile_rpn(char *expr)
in = jit_arg();
stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
jit_getarg_i(JIT_R2, in);
jit_getarg(JIT_R2, in);
while (*expr) @{
char buf[32];
@@ -1480,7 +1648,7 @@ implementation and to avoid needing the user to keep adding an extra
argument to every call, as multiple jit states generating code in
paralell should be very uncommon.
@section Registers
@node Registers
@chapter Accessing the whole register file
As mentioned earlier in this chapter, all @lightning{} back-ends are
@@ -1496,6 +1664,33 @@ 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.
@section Scratch registers
For operations, @lightning{} does not support directly, like storing
a literal in memory, @code{jit_get_reg} and @code{jit_unget_reg} can be used to
acquire and release a scratch register as in the following pattern:
@example
jit_int32_t reg = jit_get_reg (jit_class_gpr);
jit_movi (reg, immediate);
jit_stxi (offsetof (some_struct, some_field), JIT_V0, reg);
jit_unget_reg (reg);
@end example
As @code{jit_get_reg} and @code{jit_unget_reg} may generate spills and
reloads but don't follow branches, the code between both must be in
the same basic block and must not contain any branches as in the
following (bad) example.
@example
jit_int32_t reg = jit_get_reg (jit_class_gpr);
jit_ldxi (reg, JIT_V0, offset);
jump = jit_bnei (reg, V0);
jit_movr (JIT_V1, reg);
jit_patch (jump);
jit_unget_reg (reg);
@end example
@node Customizations
@chapter Customizations
@@ -1527,6 +1722,28 @@ Get the current memory allocation function. Also, unlike the GNU GMP
counterpart, it is an error to pass @code{NULL} pointers as arguments.
@end deftypefun
@section Protection
Unless an alternate code buffer is used (see below), @code{jit_emit}
set the access protections that the code buffer's memory can be read and
executed, but not modified. One can use the following functions after
@code{jit_emit} but before @code{jit_clear} to temporarily lift the
protection:
@deftypefun void jit_unprotect ()
Changes the access protection that the code buffer's memory can be read and
modified. Before the emitted code can be invoked, @code{jit_protect}
has to be called to reset the change.
This procedure has no effect when an alternate code buffer (see below) is used.
@end deftypefun
@deftypefun void jit_protect ()
Changes the access protection that the code buffer's memory can be read and
executed.
This procedure has no effect when an alternate code buffer (see below) is used.
@end deftypefun
@section Alternate code buffer
To instruct @lightning{} to use an alternate code buffer it is required
to call @code{jit_realize} before @code{jit_emit}, and then query states
+1 -1
View File
@@ -24,7 +24,7 @@ jit_node_t *compile_rpn(char *expr)
fn = jit_note(NULL, 0);
jit_prolog();
in = jit_arg();
in = jit_arg_i();
stack_ptr = stack_base = jit_allocai (32 * sizeof (int));
jit_getarg_i(JIT_R2, in);
-4
View File
@@ -1,4 +0,0 @@
@set UPDATED 3 October 2017
@set UPDATED-MONTH October 2017
@set EDITION 2.1.3
@set VERSION 2.1.3
Submodule parallel-rsp/lightning/gnulib added at e54b645fc6.
@@ -0,0 +1,2 @@
/Makefile.am
/dummy.c
+1 -1
View File
@@ -1,5 +1,5 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
# Copyright 2000, 2001, 2002, 2012-2023 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
+211 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#if defined(__hpux) && defined(__hppa__)
# include <machine/param.h>
@@ -123,6 +124,11 @@ typedef jit_int32_t jit_bool_t;
typedef jit_int32_t jit_gpr_t;
typedef jit_int32_t jit_fpr_t;
#if !defined(__powerpc__) && \
(defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__))
#define __powerpc__ 1
#endif
#if defined(__i386__) || defined(__x86_64__)
# include <lightning/jit_x86.h>
#elif defined(__mips__)
@@ -145,6 +151,8 @@ typedef jit_int32_t jit_fpr_t;
# include <lightning/jit_alpha.h>
#elif defined(__riscv)
# include <lightning/jit_riscv.h>
#elif defined(__loongarch__)
# include <lightning/jit_loongarch.h>
#endif
#define jit_flag_node 0x0001 /* patch node not absolute */
@@ -182,6 +190,8 @@ typedef enum {
#define jit_align(u) jit_new_node_w(jit_code_align, u)
jit_code_live, jit_code_align,
jit_code_save, jit_code_load,
#define jit_skip(u) jit_new_node_w(jit_code_skip, u)
jit_code_skip,
#define jit_name(u) _jit_name(_jit,u)
jit_code_name,
#define jit_note(u, v) _jit_note(_jit, u, v)
@@ -202,27 +212,80 @@ typedef enum {
#define jit_allocar(u, v) _jit_allocar(_jit,u,v)
jit_code_allocai, jit_code_allocar,
#define jit_arg() _jit_arg(_jit)
jit_code_arg,
#define jit_arg_c() _jit_arg(_jit, jit_code_arg_c)
#define jit_arg_s() _jit_arg(_jit, jit_code_arg_s)
#define jit_arg_i() _jit_arg(_jit, jit_code_arg_i)
# if __WORDSIZE == 32
# define jit_arg() jit_arg_i()
#else
# define jit_arg_l() _jit_arg(_jit, jit_code_arg_l)
# define jit_arg() jit_arg_l()
#endif
jit_code_arg_c, jit_code_arg_s,
jit_code_arg_i, jit_code_arg_l,
#if __WORDSIZE == 32
# define jit_code_arg jit_code_arg_i
#else
# define jit_code_arg jit_code_arg_l
#endif
#define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v)
#define jit_getarg_uc(u,v) _jit_getarg_uc(_jit,u,v)
jit_code_getarg_c, jit_code_getarg_uc,
#define jit_getarg_s(u,v) _jit_getarg_s(_jit,u,v)
#define jit_getarg_us(u,v) _jit_getarg_us(_jit,u,v)
jit_code_getarg_s, jit_code_getarg_us,
#define jit_getarg_i(u,v) _jit_getarg_i(_jit,u,v)
#if __WORDSIZE == 32
# define jit_getarg(u,v) jit_getarg_i(u,v)
#else
# define jit_getarg(u,v) jit_getarg_l(u,v)
# define jit_getarg_ui(u,v) _jit_getarg_ui(_jit,u,v)
# define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v)
# define jit_getarg(u,v) jit_getarg_l(u,v)
#endif
jit_code_getarg_c, jit_code_getarg_uc,
jit_code_getarg_s, jit_code_getarg_us,
jit_code_getarg_i, jit_code_getarg_ui,
jit_code_getarg_l,
# define jit_putargr(u,v) _jit_putargr(_jit,u,v)
# define jit_putargi(u,v) _jit_putargi(_jit,u,v)
jit_code_putargr, jit_code_putargi,
#if __WORDSIZE == 32
# define jit_code_getarg jit_code_getarg_i
#else
# define jit_code_getarg jit_code_getarg_l
#endif
#define jit_putargr_c(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_c)
#define jit_putargi_c(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_c)
#define jit_putargr_uc(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_uc)
#define jit_putargi_uc(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_uc)
#define jit_putargr_s(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_s)
#define jit_putargi_s(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_s)
#define jit_putargr_us(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_us)
#define jit_putargi_us(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_us)
#define jit_putargr_i(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_i)
#define jit_putargi_i(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_i)
#if __WORDSIZE == 32
# define jit_putargr(u,v) jit_putargr_i(u,v)
# define jit_putargi(u,v) jit_putargi_i(u,v)
#else
# define jit_putargr_ui(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_ui)
# define jit_putargi_ui(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_ui)
# define jit_putargr_l(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_l)
# define jit_putargi_l(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_l)
# define jit_putargr(u,v) jit_putargr_l(u,v)
# define jit_putargi(u,v) jit_putargi_l(u,v)
#endif
jit_code_putargr_c, jit_code_putargi_c,
jit_code_putargr_uc, jit_code_putargi_uc,
jit_code_putargr_s, jit_code_putargi_s,
jit_code_putargr_us, jit_code_putargi_us,
jit_code_putargr_i, jit_code_putargi_i,
jit_code_putargr_ui, jit_code_putargi_ui,
jit_code_putargr_l, jit_code_putargi_l,
#if __WORDSIZE == 32
# define jit_code_putargr jit_code_putargr_i
# define jit_code_putargi jit_code_putargi_i
#else
# define jit_code_putargr jit_code_putargr_l
# define jit_code_putargi jit_code_putargi_l
#endif
#define jit_va_start(u) jit_new_node_w(jit_code_va_start, u)
jit_code_va_start,
@@ -339,6 +402,15 @@ typedef enum {
#define jit_movr(u,v) jit_new_node_ww(jit_code_movr,u,v)
#define jit_movi(u,v) jit_new_node_ww(jit_code_movi,u,v)
jit_code_movr, jit_code_movi,
#define jit_movnr(u,v,w) jit_new_node_www(jit_code_movnr,u,v,w)
#define jit_movzr(u,v,w) jit_new_node_www(jit_code_movzr,u,v,w)
jit_code_movnr, jit_code_movzr,
jit_code_casr, jit_code_casi,
#define jit_casr(u, v, w, x) jit_new_node_wwq(jit_code_casr, u, v, w, x)
#define jit_casi(u, v, w, x) jit_new_node_wwq(jit_code_casi, u, v, w, x)
#define jit_extr_c(u,v) jit_new_node_ww(jit_code_extr_c,u,v)
#define jit_extr_uc(u,v) jit_new_node_ww(jit_code_extr_uc,u,v)
jit_code_extr_c, jit_code_extr_uc,
@@ -351,6 +423,18 @@ typedef enum {
#endif
jit_code_extr_i, jit_code_extr_ui,
#define jit_bswapr_us(u,v) jit_new_node_ww(jit_code_bswapr_us,u,v)
jit_code_bswapr_us,
#define jit_bswapr_ui(u,v) jit_new_node_ww(jit_code_bswapr_ui,u,v)
jit_code_bswapr_ui,
#define jit_bswapr_ul(u,v) jit_new_node_ww(jit_code_bswapr_ul,u,v)
jit_code_bswapr_ul,
#if __WORDSIZE == 32
#define jit_bswapr(u,v) jit_new_node_ww(jit_code_bswapr_ui,u,v)
#else
#define jit_bswapr(u,v) jit_new_node_ww(jit_code_bswapr_ul,u,v)
#endif
#define jit_htonr_us(u,v) jit_new_node_ww(jit_code_htonr_us,u,v)
#define jit_ntohr_us(u,v) jit_new_node_ww(jit_code_htonr_us,u,v)
jit_code_htonr_us,
@@ -537,33 +621,106 @@ typedef enum {
#define jit_prepare() _jit_prepare(_jit)
jit_code_prepare,
#define jit_pushargr(u) _jit_pushargr(_jit,u)
#define jit_pushargi(u) _jit_pushargi(_jit,u)
jit_code_pushargr, jit_code_pushargi,
#define jit_pushargr_c(u) _jit_pushargr(_jit,u,jit_code_pushargr_c)
#define jit_pushargi_c(u) _jit_pushargi(_jit,u,jit_code_pushargi_c)
#define jit_pushargr_uc(u) _jit_pushargr(_jit,u,jit_code_pushargr_uc)
#define jit_pushargi_uc(u) _jit_pushargi(_jit,u,jit_code_pushargi_uc)
#define jit_pushargr_s(u) _jit_pushargr(_jit,u,jit_code_pushargr_s)
#define jit_pushargi_s(u) _jit_pushargi(_jit,u,jit_code_pushargi_s)
#define jit_pushargr_us(u) _jit_pushargr(_jit,u,jit_code_pushargr_us)
#define jit_pushargi_us(u) _jit_pushargi(_jit,u,jit_code_pushargi_us)
#define jit_pushargr_i(u) _jit_pushargr(_jit,u,jit_code_pushargr_i)
#define jit_pushargi_i(u) _jit_pushargi(_jit,u,jit_code_pushargi_i)
#if __WORDSIZE == 32
# define jit_pushargr(u) jit_pushargr_i(u)
# define jit_pushargi(u) jit_pushargi_i(u)
#else
# define jit_pushargr_ui(u) _jit_pushargr(_jit,u,jit_code_pushargr_ui)
# define jit_pushargi_ui(u) _jit_pushargi(_jit,u,jit_code_pushargi_ui)
# define jit_pushargr_l(u) _jit_pushargr(_jit,u,jit_code_pushargr_l)
# define jit_pushargi_l(u) _jit_pushargi(_jit,u,jit_code_pushargi_l)
# define jit_pushargr(u) jit_pushargr_l(u)
# define jit_pushargi(u) jit_pushargi_l(u)
#endif
jit_code_pushargr_c, jit_code_pushargi_c,
jit_code_pushargr_uc, jit_code_pushargi_uc,
jit_code_pushargr_s, jit_code_pushargi_s,
jit_code_pushargr_us, jit_code_pushargi_us,
jit_code_pushargr_i, jit_code_pushargi_i,
jit_code_pushargr_ui, jit_code_pushargi_ui,
jit_code_pushargr_l, jit_code_pushargi_l,
#if __WORDSIZE == 32
# define jit_code_pushargr jit_code_pushargr_i
# define jit_code_pushargi jit_code_pushargi_i
#else
# define jit_code_pushargr jit_code_pushargr_l
# define jit_code_pushargi jit_code_pushargi_l
#endif
#define jit_finishr(u) _jit_finishr(_jit,u)
#define jit_finishi(u) _jit_finishi(_jit,u)
jit_code_finishr, jit_code_finishi,
#define jit_ret() _jit_ret(_jit)
jit_code_ret,
#define jit_retr(u) _jit_retr(_jit,u)
#define jit_reti(u) _jit_reti(_jit,u)
jit_code_retr, jit_code_reti,
#define jit_retr_c(u) _jit_retr(_jit,u,jit_code_retr_c)
#define jit_reti_c(u) _jit_reti(_jit,u,jit_code_reti_c)
#define jit_retr_uc(u) _jit_retr(_jit,u,jit_code_retr_uc)
#define jit_reti_uc(u) _jit_reti(_jit,u,jit_code_reti_uc)
#define jit_retr_s(u) _jit_retr(_jit,u,jit_code_retr_s)
#define jit_reti_s(u) _jit_reti(_jit,u,jit_code_reti_s)
#define jit_retr_us(u) _jit_retr(_jit,u,jit_code_retr_us)
#define jit_reti_us(u) _jit_reti(_jit,u,jit_code_reti_us)
#define jit_retr_i(u) _jit_retr(_jit,u,jit_code_retr_i)
#define jit_reti_i(u) _jit_reti(_jit,u,jit_code_reti_i)
#if __WORDSIZE == 32
# define jit_retr(u) jit_retr_i(u)
# define jit_reti(u) jit_reti_i(u)
#else
# define jit_retr_ui(u) _jit_retr(_jit,u,jit_code_retr_ui)
# define jit_reti_ui(u) _jit_reti(_jit,u,jit_code_reti_ui)
# define jit_retr_l(u) _jit_retr(_jit,u,jit_code_retr_l)
# define jit_reti_l(u) _jit_reti(_jit,u,jit_code_reti_l)
# define jit_retr(u) jit_retr_l(u)
# define jit_reti(u) jit_reti_l(u)
#endif
jit_code_retr_c, jit_code_reti_c,
jit_code_retr_uc, jit_code_reti_uc,
jit_code_retr_s, jit_code_reti_s,
jit_code_retr_us, jit_code_reti_us,
jit_code_retr_i, jit_code_reti_i,
jit_code_retr_ui, jit_code_reti_ui,
jit_code_retr_l, jit_code_reti_l,
#if __WORDSIZE == 32
# define jit_code_retr jit_code_retr_i
# define jit_code_reti jit_code_reti_i
#else
# define jit_code_retr jit_code_retr_l
# define jit_code_reti jit_code_reti_l
#endif
#define jit_retval_c(u) _jit_retval_c(_jit,u)
#define jit_retval_uc(u) _jit_retval_uc(_jit,u)
jit_code_retval_c, jit_code_retval_uc,
#define jit_retval_s(u) _jit_retval_s(_jit,u)
#define jit_retval_us(u) _jit_retval_us(_jit,u)
jit_code_retval_s, jit_code_retval_us,
#define jit_retval_i(u) _jit_retval_i(_jit,u)
#if __WORDSIZE == 32
# define jit_retval(u) jit_retval_i(u)
#else
# define jit_retval(u) jit_retval_l(u)
# define jit_retval_ui(u) _jit_retval_ui(_jit,u)
# define jit_retval_l(u) _jit_retval_l(_jit,u)
# define jit_retval(u) jit_retval_l(u)
#endif
jit_code_retval_c, jit_code_retval_uc,
jit_code_retval_s, jit_code_retval_us,
jit_code_retval_i, jit_code_retval_ui,
jit_code_retval_l,
#if __WORDSIZE == 32
# define jit_code_retval jit_code_retval_i
#else
# define jit_code_retval jit_code_retval_l
#endif
#define jit_epilog() _jit_epilog(_jit)
jit_code_epilog,
@@ -891,6 +1048,14 @@ typedef enum {
#define jit_movr_d_w(u, v) jit_new_node_ww(jit_code_movr_d_w, u, v)
#define jit_movi_d_w(u, v) jit_new_node_wd(jit_code_movi_d_w, u, v)
#define jit_clor(u,v) jit_new_node_ww(jit_code_clor,u,v)
#define jit_clzr(u,v) jit_new_node_ww(jit_code_clzr,u,v)
jit_code_clor, jit_code_clzr,
#define jit_ctor(u,v) jit_new_node_ww(jit_code_ctor,u,v)
#define jit_ctzr(u,v) jit_new_node_ww(jit_code_ctzr,u,v)
jit_code_ctor, jit_code_ctzr,
jit_code_last_code
} jit_code_t;
@@ -931,7 +1096,8 @@ extern jit_int32_t _jit_allocai(jit_state_t*, jit_int32_t);
extern void _jit_allocar(jit_state_t*, jit_int32_t, jit_int32_t);
extern void _jit_ellipsis(jit_state_t*);
extern jit_node_t *_jit_arg(jit_state_t*);
extern jit_node_t *_jit_arg(jit_state_t*, jit_code_t);
extern void _jit_getarg_c(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_uc(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_s(jit_state_t*, jit_gpr_t, jit_node_t*);
@@ -941,19 +1107,24 @@ extern void _jit_getarg_i(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_ui(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_l(jit_state_t*, jit_gpr_t, jit_node_t*);
#endif
extern void _jit_putargr(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_putargi(jit_state_t*, jit_word_t, jit_node_t*);
extern void _jit_putargr(jit_state_t*, jit_gpr_t, jit_node_t*, jit_code_t);
extern void _jit_putargi(jit_state_t*, jit_word_t, jit_node_t*, jit_code_t);
extern void _jit_prepare(jit_state_t*);
extern void _jit_ellipsis(jit_state_t*);
extern void _jit_va_push(jit_state_t*, jit_gpr_t);
extern void _jit_pushargr(jit_state_t*, jit_gpr_t);
extern void _jit_pushargi(jit_state_t*, jit_word_t);
extern void _jit_pushargr(jit_state_t*, jit_gpr_t, jit_code_t);
extern void _jit_pushargi(jit_state_t*, jit_word_t, jit_code_t);
extern void _jit_finishr(jit_state_t*, jit_gpr_t);
extern jit_node_t *_jit_finishi(jit_state_t*, jit_pointer_t);
extern void _jit_ret(jit_state_t*);
extern void _jit_retr(jit_state_t*, jit_gpr_t);
extern void _jit_reti(jit_state_t*, jit_word_t);
extern void _jit_retr(jit_state_t*, jit_gpr_t, jit_code_t);
extern void _jit_reti(jit_state_t*, jit_word_t, jit_code_t);
extern void _jit_retval_c(jit_state_t*, jit_gpr_t);
extern void _jit_retval_uc(jit_state_t*, jit_gpr_t);
extern void _jit_retval_s(jit_state_t*, jit_gpr_t);
@@ -963,6 +1134,7 @@ extern void _jit_retval_i(jit_state_t*, jit_gpr_t);
extern void _jit_retval_ui(jit_state_t*, jit_gpr_t);
extern void _jit_retval_l(jit_state_t*, jit_gpr_t);
#endif
extern void _jit_epilog(jit_state_t*);
#define jit_patch(u) _jit_patch(_jit,u)
@@ -987,6 +1159,10 @@ extern void _jit_frame(jit_state_t*, jit_int32_t);
extern void _jit_tramp(jit_state_t*, jit_int32_t);
#define jit_emit() _jit_emit(_jit)
extern jit_pointer_t _jit_emit(jit_state_t*);
#define jit_unprotect() _jit_unprotect(_jit)
extern void _jit_unprotect(jit_state_t*);
#define jit_protect() _jit_protect(_jit)
extern void _jit_protect(jit_state_t*);
#define jit_print() _jit_print(_jit)
extern void _jit_print(jit_state_t*);
@@ -1011,6 +1187,12 @@ extern void _jit_retr_d(jit_state_t*, jit_fpr_t);
extern void _jit_reti_d(jit_state_t*, jit_float64_t);
extern void _jit_retval_d(jit_state_t*, jit_fpr_t);
#define jit_get_reg(s) _jit_get_reg(_jit,s)
extern jit_int32_t _jit_get_reg(jit_state_t*, jit_int32_t);
#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
extern void _jit_unget_reg(jit_state_t*, jit_int32_t);
#define jit_new_node(c) _jit_new_node(_jit,c)
extern jit_node_t *_jit_new_node(jit_state_t*, jit_code_t);
#define jit_new_node_w(c,u) _jit_new_node_w(_jit,c,u)
@@ -1053,6 +1235,10 @@ extern jit_node_t *_jit_new_node_www(jit_state_t*, jit_code_t,
extern jit_node_t *_jit_new_node_qww(jit_state_t*, jit_code_t,
jit_int32_t, jit_int32_t,
jit_word_t, jit_word_t);
#define jit_new_node_wwq(c,u,v,l,h) _jit_new_node_wwq(_jit,c,u,v,l,h)
extern jit_node_t *_jit_new_node_wwq(jit_state_t*, jit_code_t,
jit_word_t, jit_word_t,
jit_int32_t, jit_int32_t);
#define jit_new_node_wwf(c,u,v,w) _jit_new_node_wwf(_jit,c,u,v,w)
extern jit_node_t *_jit_new_node_wwf(jit_state_t*, jit_code_t,
jit_word_t, jit_word_t, jit_float32_t);
+211 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -24,6 +24,7 @@
#include <stdlib.h>
@MAYBE_INCLUDE_STDINT_H@
#include <string.h>
#include <pthread.h>
#if defined(__hpux) && defined(__hppa__)
# include <machine/param.h>
@@ -123,6 +124,11 @@ typedef jit_int32_t jit_bool_t;
typedef jit_int32_t jit_gpr_t;
typedef jit_int32_t jit_fpr_t;
#if !defined(__powerpc__) && \
(defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__))
#define __powerpc__ 1
#endif
#if defined(__i386__) || defined(__x86_64__)
# include <lightning/jit_x86.h>
#elif defined(__mips__)
@@ -145,6 +151,8 @@ typedef jit_int32_t jit_fpr_t;
# include <lightning/jit_alpha.h>
#elif defined(__riscv)
# include <lightning/jit_riscv.h>
#elif defined(__loongarch__)
# include <lightning/jit_loongarch.h>
#endif
#define jit_flag_node 0x0001 /* patch node not absolute */
@@ -182,6 +190,8 @@ typedef enum {
#define jit_align(u) jit_new_node_w(jit_code_align, u)
jit_code_live, jit_code_align,
jit_code_save, jit_code_load,
#define jit_skip(u) jit_new_node_w(jit_code_skip, u)
jit_code_skip,
#define jit_name(u) _jit_name(_jit,u)
jit_code_name,
#define jit_note(u, v) _jit_note(_jit, u, v)
@@ -202,27 +212,80 @@ typedef enum {
#define jit_allocar(u, v) _jit_allocar(_jit,u,v)
jit_code_allocai, jit_code_allocar,
#define jit_arg() _jit_arg(_jit)
jit_code_arg,
#define jit_arg_c() _jit_arg(_jit, jit_code_arg_c)
#define jit_arg_s() _jit_arg(_jit, jit_code_arg_s)
#define jit_arg_i() _jit_arg(_jit, jit_code_arg_i)
# if __WORDSIZE == 32
# define jit_arg() jit_arg_i()
#else
# define jit_arg_l() _jit_arg(_jit, jit_code_arg_l)
# define jit_arg() jit_arg_l()
#endif
jit_code_arg_c, jit_code_arg_s,
jit_code_arg_i, jit_code_arg_l,
#if __WORDSIZE == 32
# define jit_code_arg jit_code_arg_i
#else
# define jit_code_arg jit_code_arg_l
#endif
#define jit_getarg_c(u,v) _jit_getarg_c(_jit,u,v)
#define jit_getarg_uc(u,v) _jit_getarg_uc(_jit,u,v)
jit_code_getarg_c, jit_code_getarg_uc,
#define jit_getarg_s(u,v) _jit_getarg_s(_jit,u,v)
#define jit_getarg_us(u,v) _jit_getarg_us(_jit,u,v)
jit_code_getarg_s, jit_code_getarg_us,
#define jit_getarg_i(u,v) _jit_getarg_i(_jit,u,v)
#if __WORDSIZE == 32
# define jit_getarg(u,v) jit_getarg_i(u,v)
#else
# define jit_getarg(u,v) jit_getarg_l(u,v)
# define jit_getarg_ui(u,v) _jit_getarg_ui(_jit,u,v)
# define jit_getarg_l(u,v) _jit_getarg_l(_jit,u,v)
# define jit_getarg(u,v) jit_getarg_l(u,v)
#endif
jit_code_getarg_c, jit_code_getarg_uc,
jit_code_getarg_s, jit_code_getarg_us,
jit_code_getarg_i, jit_code_getarg_ui,
jit_code_getarg_l,
# define jit_putargr(u,v) _jit_putargr(_jit,u,v)
# define jit_putargi(u,v) _jit_putargi(_jit,u,v)
jit_code_putargr, jit_code_putargi,
#if __WORDSIZE == 32
# define jit_code_getarg jit_code_getarg_i
#else
# define jit_code_getarg jit_code_getarg_l
#endif
#define jit_putargr_c(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_c)
#define jit_putargi_c(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_c)
#define jit_putargr_uc(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_uc)
#define jit_putargi_uc(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_uc)
#define jit_putargr_s(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_s)
#define jit_putargi_s(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_s)
#define jit_putargr_us(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_us)
#define jit_putargi_us(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_us)
#define jit_putargr_i(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_i)
#define jit_putargi_i(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_i)
#if __WORDSIZE == 32
# define jit_putargr(u,v) jit_putargr_i(u,v)
# define jit_putargi(u,v) jit_putargi_i(u,v)
#else
# define jit_putargr_ui(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_ui)
# define jit_putargi_ui(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_ui)
# define jit_putargr_l(u,v) _jit_putargr(_jit,u,v,jit_code_putargr_l)
# define jit_putargi_l(u,v) _jit_putargi(_jit,u,v,jit_code_putargi_l)
# define jit_putargr(u,v) jit_putargr_l(u,v)
# define jit_putargi(u,v) jit_putargi_l(u,v)
#endif
jit_code_putargr_c, jit_code_putargi_c,
jit_code_putargr_uc, jit_code_putargi_uc,
jit_code_putargr_s, jit_code_putargi_s,
jit_code_putargr_us, jit_code_putargi_us,
jit_code_putargr_i, jit_code_putargi_i,
jit_code_putargr_ui, jit_code_putargi_ui,
jit_code_putargr_l, jit_code_putargi_l,
#if __WORDSIZE == 32
# define jit_code_putargr jit_code_putargr_i
# define jit_code_putargi jit_code_putargi_i
#else
# define jit_code_putargr jit_code_putargr_l
# define jit_code_putargi jit_code_putargi_l
#endif
#define jit_va_start(u) jit_new_node_w(jit_code_va_start, u)
jit_code_va_start,
@@ -339,6 +402,15 @@ typedef enum {
#define jit_movr(u,v) jit_new_node_ww(jit_code_movr,u,v)
#define jit_movi(u,v) jit_new_node_ww(jit_code_movi,u,v)
jit_code_movr, jit_code_movi,
#define jit_movnr(u,v,w) jit_new_node_www(jit_code_movnr,u,v,w)
#define jit_movzr(u,v,w) jit_new_node_www(jit_code_movzr,u,v,w)
jit_code_movnr, jit_code_movzr,
jit_code_casr, jit_code_casi,
#define jit_casr(u, v, w, x) jit_new_node_wwq(jit_code_casr, u, v, w, x)
#define jit_casi(u, v, w, x) jit_new_node_wwq(jit_code_casi, u, v, w, x)
#define jit_extr_c(u,v) jit_new_node_ww(jit_code_extr_c,u,v)
#define jit_extr_uc(u,v) jit_new_node_ww(jit_code_extr_uc,u,v)
jit_code_extr_c, jit_code_extr_uc,
@@ -351,6 +423,18 @@ typedef enum {
#endif
jit_code_extr_i, jit_code_extr_ui,
#define jit_bswapr_us(u,v) jit_new_node_ww(jit_code_bswapr_us,u,v)
jit_code_bswapr_us,
#define jit_bswapr_ui(u,v) jit_new_node_ww(jit_code_bswapr_ui,u,v)
jit_code_bswapr_ui,
#define jit_bswapr_ul(u,v) jit_new_node_ww(jit_code_bswapr_ul,u,v)
jit_code_bswapr_ul,
#if __WORDSIZE == 32
#define jit_bswapr(u,v) jit_new_node_ww(jit_code_bswapr_ui,u,v)
#else
#define jit_bswapr(u,v) jit_new_node_ww(jit_code_bswapr_ul,u,v)
#endif
#define jit_htonr_us(u,v) jit_new_node_ww(jit_code_htonr_us,u,v)
#define jit_ntohr_us(u,v) jit_new_node_ww(jit_code_htonr_us,u,v)
jit_code_htonr_us,
@@ -537,33 +621,106 @@ typedef enum {
#define jit_prepare() _jit_prepare(_jit)
jit_code_prepare,
#define jit_pushargr(u) _jit_pushargr(_jit,u)
#define jit_pushargi(u) _jit_pushargi(_jit,u)
jit_code_pushargr, jit_code_pushargi,
#define jit_pushargr_c(u) _jit_pushargr(_jit,u,jit_code_pushargr_c)
#define jit_pushargi_c(u) _jit_pushargi(_jit,u,jit_code_pushargi_c)
#define jit_pushargr_uc(u) _jit_pushargr(_jit,u,jit_code_pushargr_uc)
#define jit_pushargi_uc(u) _jit_pushargi(_jit,u,jit_code_pushargi_uc)
#define jit_pushargr_s(u) _jit_pushargr(_jit,u,jit_code_pushargr_s)
#define jit_pushargi_s(u) _jit_pushargi(_jit,u,jit_code_pushargi_s)
#define jit_pushargr_us(u) _jit_pushargr(_jit,u,jit_code_pushargr_us)
#define jit_pushargi_us(u) _jit_pushargi(_jit,u,jit_code_pushargi_us)
#define jit_pushargr_i(u) _jit_pushargr(_jit,u,jit_code_pushargr_i)
#define jit_pushargi_i(u) _jit_pushargi(_jit,u,jit_code_pushargi_i)
#if __WORDSIZE == 32
# define jit_pushargr(u) jit_pushargr_i(u)
# define jit_pushargi(u) jit_pushargi_i(u)
#else
# define jit_pushargr_ui(u) _jit_pushargr(_jit,u,jit_code_pushargr_ui)
# define jit_pushargi_ui(u) _jit_pushargi(_jit,u,jit_code_pushargi_ui)
# define jit_pushargr_l(u) _jit_pushargr(_jit,u,jit_code_pushargr_l)
# define jit_pushargi_l(u) _jit_pushargi(_jit,u,jit_code_pushargi_l)
# define jit_pushargr(u) jit_pushargr_l(u)
# define jit_pushargi(u) jit_pushargi_l(u)
#endif
jit_code_pushargr_c, jit_code_pushargi_c,
jit_code_pushargr_uc, jit_code_pushargi_uc,
jit_code_pushargr_s, jit_code_pushargi_s,
jit_code_pushargr_us, jit_code_pushargi_us,
jit_code_pushargr_i, jit_code_pushargi_i,
jit_code_pushargr_ui, jit_code_pushargi_ui,
jit_code_pushargr_l, jit_code_pushargi_l,
#if __WORDSIZE == 32
# define jit_code_pushargr jit_code_pushargr_i
# define jit_code_pushargi jit_code_pushargi_i
#else
# define jit_code_pushargr jit_code_pushargr_l
# define jit_code_pushargi jit_code_pushargi_l
#endif
#define jit_finishr(u) _jit_finishr(_jit,u)
#define jit_finishi(u) _jit_finishi(_jit,u)
jit_code_finishr, jit_code_finishi,
#define jit_ret() _jit_ret(_jit)
jit_code_ret,
#define jit_retr(u) _jit_retr(_jit,u)
#define jit_reti(u) _jit_reti(_jit,u)
jit_code_retr, jit_code_reti,
#define jit_retr_c(u) _jit_retr(_jit,u,jit_code_retr_c)
#define jit_reti_c(u) _jit_reti(_jit,u,jit_code_reti_c)
#define jit_retr_uc(u) _jit_retr(_jit,u,jit_code_retr_uc)
#define jit_reti_uc(u) _jit_reti(_jit,u,jit_code_reti_uc)
#define jit_retr_s(u) _jit_retr(_jit,u,jit_code_retr_s)
#define jit_reti_s(u) _jit_reti(_jit,u,jit_code_reti_s)
#define jit_retr_us(u) _jit_retr(_jit,u,jit_code_retr_us)
#define jit_reti_us(u) _jit_reti(_jit,u,jit_code_reti_us)
#define jit_retr_i(u) _jit_retr(_jit,u,jit_code_retr_i)
#define jit_reti_i(u) _jit_reti(_jit,u,jit_code_reti_i)
#if __WORDSIZE == 32
# define jit_retr(u) jit_retr_i(u)
# define jit_reti(u) jit_reti_i(u)
#else
# define jit_retr_ui(u) _jit_retr(_jit,u,jit_code_retr_ui)
# define jit_reti_ui(u) _jit_reti(_jit,u,jit_code_reti_ui)
# define jit_retr_l(u) _jit_retr(_jit,u,jit_code_retr_l)
# define jit_reti_l(u) _jit_reti(_jit,u,jit_code_reti_l)
# define jit_retr(u) jit_retr_l(u)
# define jit_reti(u) jit_reti_l(u)
#endif
jit_code_retr_c, jit_code_reti_c,
jit_code_retr_uc, jit_code_reti_uc,
jit_code_retr_s, jit_code_reti_s,
jit_code_retr_us, jit_code_reti_us,
jit_code_retr_i, jit_code_reti_i,
jit_code_retr_ui, jit_code_reti_ui,
jit_code_retr_l, jit_code_reti_l,
#if __WORDSIZE == 32
# define jit_code_retr jit_code_retr_i
# define jit_code_reti jit_code_reti_i
#else
# define jit_code_retr jit_code_retr_l
# define jit_code_reti jit_code_reti_l
#endif
#define jit_retval_c(u) _jit_retval_c(_jit,u)
#define jit_retval_uc(u) _jit_retval_uc(_jit,u)
jit_code_retval_c, jit_code_retval_uc,
#define jit_retval_s(u) _jit_retval_s(_jit,u)
#define jit_retval_us(u) _jit_retval_us(_jit,u)
jit_code_retval_s, jit_code_retval_us,
#define jit_retval_i(u) _jit_retval_i(_jit,u)
#if __WORDSIZE == 32
# define jit_retval(u) jit_retval_i(u)
#else
# define jit_retval(u) jit_retval_l(u)
# define jit_retval_ui(u) _jit_retval_ui(_jit,u)
# define jit_retval_l(u) _jit_retval_l(_jit,u)
# define jit_retval(u) jit_retval_l(u)
#endif
jit_code_retval_c, jit_code_retval_uc,
jit_code_retval_s, jit_code_retval_us,
jit_code_retval_i, jit_code_retval_ui,
jit_code_retval_l,
#if __WORDSIZE == 32
# define jit_code_retval jit_code_retval_i
#else
# define jit_code_retval jit_code_retval_l
#endif
#define jit_epilog() _jit_epilog(_jit)
jit_code_epilog,
@@ -891,6 +1048,14 @@ typedef enum {
#define jit_movr_d_w(u, v) jit_new_node_ww(jit_code_movr_d_w, u, v)
#define jit_movi_d_w(u, v) jit_new_node_wd(jit_code_movi_d_w, u, v)
#define jit_clor(u,v) jit_new_node_ww(jit_code_clor,u,v)
#define jit_clzr(u,v) jit_new_node_ww(jit_code_clzr,u,v)
jit_code_clor, jit_code_clzr,
#define jit_ctor(u,v) jit_new_node_ww(jit_code_ctor,u,v)
#define jit_ctzr(u,v) jit_new_node_ww(jit_code_ctzr,u,v)
jit_code_ctor, jit_code_ctzr,
jit_code_last_code
} jit_code_t;
@@ -931,7 +1096,8 @@ extern jit_int32_t _jit_allocai(jit_state_t*, jit_int32_t);
extern void _jit_allocar(jit_state_t*, jit_int32_t, jit_int32_t);
extern void _jit_ellipsis(jit_state_t*);
extern jit_node_t *_jit_arg(jit_state_t*);
extern jit_node_t *_jit_arg(jit_state_t*, jit_code_t);
extern void _jit_getarg_c(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_uc(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_s(jit_state_t*, jit_gpr_t, jit_node_t*);
@@ -941,19 +1107,24 @@ extern void _jit_getarg_i(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_ui(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_getarg_l(jit_state_t*, jit_gpr_t, jit_node_t*);
#endif
extern void _jit_putargr(jit_state_t*, jit_gpr_t, jit_node_t*);
extern void _jit_putargi(jit_state_t*, jit_word_t, jit_node_t*);
extern void _jit_putargr(jit_state_t*, jit_gpr_t, jit_node_t*, jit_code_t);
extern void _jit_putargi(jit_state_t*, jit_word_t, jit_node_t*, jit_code_t);
extern void _jit_prepare(jit_state_t*);
extern void _jit_ellipsis(jit_state_t*);
extern void _jit_va_push(jit_state_t*, jit_gpr_t);
extern void _jit_pushargr(jit_state_t*, jit_gpr_t);
extern void _jit_pushargi(jit_state_t*, jit_word_t);
extern void _jit_pushargr(jit_state_t*, jit_gpr_t, jit_code_t);
extern void _jit_pushargi(jit_state_t*, jit_word_t, jit_code_t);
extern void _jit_finishr(jit_state_t*, jit_gpr_t);
extern jit_node_t *_jit_finishi(jit_state_t*, jit_pointer_t);
extern void _jit_ret(jit_state_t*);
extern void _jit_retr(jit_state_t*, jit_gpr_t);
extern void _jit_reti(jit_state_t*, jit_word_t);
extern void _jit_retr(jit_state_t*, jit_gpr_t, jit_code_t);
extern void _jit_reti(jit_state_t*, jit_word_t, jit_code_t);
extern void _jit_retval_c(jit_state_t*, jit_gpr_t);
extern void _jit_retval_uc(jit_state_t*, jit_gpr_t);
extern void _jit_retval_s(jit_state_t*, jit_gpr_t);
@@ -963,6 +1134,7 @@ extern void _jit_retval_i(jit_state_t*, jit_gpr_t);
extern void _jit_retval_ui(jit_state_t*, jit_gpr_t);
extern void _jit_retval_l(jit_state_t*, jit_gpr_t);
#endif
extern void _jit_epilog(jit_state_t*);
#define jit_patch(u) _jit_patch(_jit,u)
@@ -987,6 +1159,10 @@ extern void _jit_frame(jit_state_t*, jit_int32_t);
extern void _jit_tramp(jit_state_t*, jit_int32_t);
#define jit_emit() _jit_emit(_jit)
extern jit_pointer_t _jit_emit(jit_state_t*);
#define jit_unprotect() _jit_unprotect(_jit)
extern void _jit_unprotect(jit_state_t*);
#define jit_protect() _jit_protect(_jit)
extern void _jit_protect(jit_state_t*);
#define jit_print() _jit_print(_jit)
extern void _jit_print(jit_state_t*);
@@ -1011,6 +1187,12 @@ extern void _jit_retr_d(jit_state_t*, jit_fpr_t);
extern void _jit_reti_d(jit_state_t*, jit_float64_t);
extern void _jit_retval_d(jit_state_t*, jit_fpr_t);
#define jit_get_reg(s) _jit_get_reg(_jit,s)
extern jit_int32_t _jit_get_reg(jit_state_t*, jit_int32_t);
#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
extern void _jit_unget_reg(jit_state_t*, jit_int32_t);
#define jit_new_node(c) _jit_new_node(_jit,c)
extern jit_node_t *_jit_new_node(jit_state_t*, jit_code_t);
#define jit_new_node_w(c,u) _jit_new_node_w(_jit,c,u)
@@ -1053,6 +1235,10 @@ extern jit_node_t *_jit_new_node_www(jit_state_t*, jit_code_t,
extern jit_node_t *_jit_new_node_qww(jit_state_t*, jit_code_t,
jit_int32_t, jit_int32_t,
jit_word_t, jit_word_t);
#define jit_new_node_wwq(c,u,v,l,h) _jit_new_node_wwq(_jit,c,u,v,l,h)
extern jit_node_t *_jit_new_node_wwq(jit_state_t*, jit_code_t,
jit_word_t, jit_word_t,
jit_int32_t, jit_int32_t);
#define jit_new_node_wwf(c,u,v,w) _jit_new_node_wwf(_jit,c,u,v,w)
extern jit_node_t *_jit_new_node_wwf(jit_state_t*, jit_code_t,
jit_word_t, jit_word_t, jit_float32_t);
@@ -1,5 +1,5 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
# Copyright 2000, 2001, 2002, 2012-2022 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
@@ -63,3 +63,7 @@ if cpu_riscv
lightning_include_HEADERS = \
jit_riscv.h
endif
if cpu_loongarch
lightning_include_HEADERS = \
jit_loongarch.h
endif
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -23,6 +23,10 @@
#define JIT_HASH_CONSTS 0
#define JIT_NUM_OPERANDS 3
#if __APPLE__
# define PACKED_STACK 1
#endif
/*
* Types
*/
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2019 Free Software Foundation, Inc.
* Copyright (C) 2014-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -106,6 +106,9 @@ typedef enum {
typedef struct {
jit_uint32_t version : 4;
/* this field originally was only used for the 'e' in armv5te.
* it can also be used to force hardware division, if setting
* version to 7, telling it is armv7r or better. */
jit_uint32_t extend : 1;
/* only generate thumb instructions for thumb2 */
jit_uint32_t thumb : 1;
@@ -117,6 +120,12 @@ typedef struct {
* due to some memory ordering constraint not being respected, so,
* disable by default */
jit_uint32_t ldrt_strt : 1;
/* assume functions called never match jit instruction set?
* that is libc, gmp, mpfr, etc functions are in thumb mode and jit
* is in arm mode, or the reverse, what may cause a crash upon return
* of that function if generating jit for a relative jump.
*/
jit_uint32_t exchange : 1;
} jit_cpu_t;
/*
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -117,4 +117,13 @@ typedef enum {
_NOREG,
} jit_reg_t;
typedef struct {
jit_uint32_t clz : 1;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_ia64_h */
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 Free Software Foundation, Inc.
*
* 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 3, 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.
*
* Authors:
* Paulo Cesar Pereira de Andrade
*/
#ifndef _jit_loongarch_h
#define _jit_loongarch_h
/*
* Types
*/
#define JIT_FP _FP
typedef enum {
#define jit_r_num() 9
#define jit_r(i) (_T0 - (i))
#define JIT_R0 _T0
#define JIT_R1 _T1
#define JIT_R2 _T2
#define JIT_R3 _T3
#define JIT_R4 _T4
#define JIT_R5 _T5
#define JIT_R6 _T6
#define JIT_R7 _T7
#define JIT_R8 _T8
_T8, _T7, _T6, _T5, _T4, _T3, _T2, _T1, _T0,
#define jit_v_num() 9
#define jit_v(i) (_S0 - (i))
#define JIT_V0 _S0
#define JIT_V1 _S1
#define JIT_V2 _S2
#define JIT_V3 _S3
#define JIT_V4 _S4
#define JIT_V5 _S5
#define JIT_V6 _S6
#define JIT_V7 _S7
#define JIT_V8 _S8
_S8, _S7, _S6, _S5, _S4, _S3, _S2, _S1, _S0,
_A7, _A6, _A5, _A4, _A3, _A2, _A1, _A0,
_FP,
_R21,
_ZERO,
_RA,
_TP,
_SP,
_FT0, _FT1, _FT2, _FT3, _FT4, _FT5, _FT6, _FT7,
_FT8, _FT9, _FT10, _FT11, _FT12, _FT13, _FT14, _FT15,
_FA7, _FA6, _FA5, _FA4, FA3, _FA2, _FA1, _FA0,
#define jit_f_num() 8
#define jit_f(i) (_FS0 - (i))
#define JIT_F0 _FS0
#define JIT_F1 _FS1
#define JIT_F2 _FS2
#define JIT_F3 _FS3
#define JIT_F4 _FS4
#define JIT_F5 _FS5
#define JIT_F6 _FS6
#define JIT_F7 _FS7
_FS7, _FS6, _FS5, _FS4, _FS3, _FS2, _FS1, _FS0,
#define JIT_NOREG _NOREG
_NOREG,
} jit_reg_t;
#endif /* _jit_loongarch_h */
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -34,9 +34,9 @@
typedef enum {
#define jit_r(i) (_V0 + (i))
#if NEW_ABI
# define jit_r_num() 7
# define jit_r_num() 8
#else
# define jit_r_num() 11
# define jit_r_num() 12
#endif
#define jit_v(i) (_S0 + (i))
#define jit_v_num() 8
@@ -55,6 +55,7 @@ typedef enum {
# define JIT_R4 _T6
# define JIT_R5 _T7
# define JIT_R6 _T8
# define JIT_R7 _T9
#else
# define JIT_R2 _T0
# define JIT_R3 _T1
@@ -65,6 +66,7 @@ typedef enum {
# define JIT_R8 _T6
# define JIT_R9 _T7
# define JIT_R10 _T8
# define JIT_R11 _T9
#endif
_V0, _V1,
#if !NEW_ABI
@@ -112,4 +114,13 @@ typedef enum {
_NOREG,
} jit_reg_t;
typedef struct {
jit_uint32_t release : 4;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_mips_h */
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -22,6 +22,9 @@
#define JIT_HASH_CONSTS 1
#define JIT_NUM_OPERANDS 3
#if defined(_AIX) && !defined(_CALL_AIX) && !defined(_CALL_LINUX)
# define _CALL_AIXDESC 1
#endif
/*
* Types
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -55,6 +55,26 @@
# define HIDDEN /**/
#endif
#if PACKED_STACK || STRONG_TYPE_CHECKING
# define assert_arg_type(code, expect) \
do assert((code) == (expect)); while (0)
# define assert_putarg_type(code, expect) \
do \
assert((((code) - jit_code_putargr_c) >> 2) == \
((expect) - jit_code_arg_c)); \
while (0)
#else
# define assert_arg_type(code, expect) \
do assert((int)(code) == (int)(expect) || \
(code) == jit_code_arg); while (0)
# define assert_putarg_type(code, expect) \
do \
assert(((((code) - jit_code_putargr_c) >> 2) == \
((expect) - jit_code_arg_c)) || \
((code) == jit_code_arg)); \
while (0)
#endif
#define rc(value) jit_class_##value
#define rn(reg) (jit_regno(_rvs[jit_regno(reg)].spec))
@@ -150,6 +170,13 @@ typedef jit_uint64_t jit_regset_t;
# define JIT_RET _A0
# define JIT_FRET _FA0
typedef jit_uint64_t jit_regset_t;
#elif defined(__loongarch__)
# define JIT_RA0 _A0
# define JIT_FA0 _FA0
# define JIT_SP _SP
# define JIT_RET _A0
# define JIT_FRET _FA0
typedef jit_uint64_t jit_regset_t;
#endif
#define jit_data(u,v,w) _jit_data(_jit,u,v,w)
@@ -167,48 +194,80 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
(!jit_regset_tstbit(&_jitc->regarg, regno) && \
!jit_regset_tstbit(&_jitc->regsav, regno))
#define jit_inc_synth(code) \
#define jit_code_inc_synth(code) \
do { \
(void)jit_new_node(jit_code_##code); \
(void)jit_new_node(code); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_w(code, u) \
#define jit_inc_synth(name) \
jit_code_inc_synth(jit_code_##name)
#define jit_code_inc_synth_w(code, u) \
do { \
(void)jit_new_node_w(jit_code_##code, u); \
(void)jit_new_node_w(code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_f(code, u) \
#define jit_inc_synth_w(name, u) \
jit_code_inc_synth_w(jit_code_##name, u)
#define jit_code_inc_synth_f(code, u) \
do { \
(void)jit_new_node_f(jit_code_##code, u); \
(void)jit_new_node_f(code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_d(code, u) \
#define jit_inc_synth_f(name, u) \
jit_code_inc_synth_f(jit_code_##name, u)
#define jit_code_inc_synth_d(code, u) \
do { \
(void)jit_new_node_d(jit_code_##code, u); \
(void)jit_new_node_d(code, u); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_ww(code, u, v) \
#define jit_inc_synth_d(name, u) \
jit_code_inc_synth_d(jit_code_##name, u)
#define jit_code_inc_synth_ww(code, u, v) \
do { \
(void)jit_new_node_ww(jit_code_##code, u, v); \
(void)jit_new_node_ww(code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_wp(code, u, v) \
#define jit_inc_synth_ww(name, u, v) \
jit_code_inc_synth_ww(jit_code_##name, u, v)
#define jit_code_inc_synth_wp(code, u, v) \
do { \
(void)jit_new_node_wp(jit_code_##code, u, v); \
(void)jit_new_node_wp(code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_fp(code, u, v) \
#define jit_inc_synth_wp(name, u, v) \
jit_code_inc_synth_wp(jit_code_##name, u, v)
#define jit_code_inc_synth_fp(code, u, v) \
do { \
(void)jit_new_node_fp(jit_code_##code, u, v); \
(void)jit_new_node_fp(code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_dp(code, u, v) \
#define jit_inc_synth_fp(name, u, v) \
jit_code_inc_synth_fp(jit_code_##name, u, v)
#define jit_code_inc_synth_dp(code, u, v) \
do { \
(void)jit_new_node_dp(jit_code_##code, u, v); \
(void)jit_new_node_dp(code, u, v); \
jit_synth_inc(); \
} while (0)
#define jit_inc_synth_dp(name, u, v) \
jit_code_inc_synth_dp(jit_code_##name, u, v)
#define jit_dec_synth() jit_synth_dec()
#define jit_link_alist(node) \
do { \
node->link = _jitc->function->alist; \
_jitc->function->alist = node; \
} while (0)
#define jit_check_frame() \
do { \
if (!_jitc->function->need_frame) { \
_jitc->again = 1; \
_jitc->function->need_frame = 1; \
} \
} while (0)
#define jit_diffsize() (stack_framesize - _jitc->framesize)
#define jit_framesize() (stack_framesize - jit_diffsize())
#define jit_selfsize() (_jitc->function->self.size - jit_diffsize())
#define jit_link_prolog() \
do { \
_jitc->tail->link = _jitc->function->prolog->link; \
@@ -241,8 +300,8 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#define jit_class_xpr 0x80000000 /* float / vector */
/* Used on sparc64 where %f0-%f31 can be encode for single float
* but %f32 to %f62 only as double precision */
#define jit_class_sng 0x10000000 /* Single precision float */
#define jit_class_dbl 0x20000000 /* Only double precision float */
#define jit_class_sng 0x00010000 /* Single precision float */
#define jit_class_dbl 0x00020000 /* Only double precision float */
#define jit_regno_patch 0x00008000 /* this is a register
* returned by a "user" call
* to jit_get_reg() */
@@ -264,8 +323,9 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#define jit_cc_a0_flt 0x00000020 /* arg0 is immediate float */
#define jit_cc_a0_dbl 0x00000040 /* arg0 is immediate double */
#define jit_cc_a0_arg 0x00000080 /* arg1 is an argument int id */
#define jit_cc_a1_reg 0x00000100 /* arg1 is a register */
#define jit_cc_a1_chg 0x00000200 /* arg1 is modified */
#define jit_cc_a0_cnd 0x00000100 /* arg1 is a conditinally set register */
#define jit_cc_a1_reg 0x00000200 /* arg1 is a register */
#define jit_cc_a1_chg 0x00000400 /* arg1 is modified */
#define jit_cc_a1_int 0x00001000 /* arg1 is immediate word */
#define jit_cc_a1_flt 0x00002000 /* arg1 is immediate float */
#define jit_cc_a1_dbl 0x00004000 /* arg1 is immediate double */
@@ -275,6 +335,7 @@ extern jit_node_t *_jit_data(jit_state_t*, const void*,
#define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
#define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
#define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
#define jit_cc_a2_rlh 0x00800000 /* arg2 is a register pair */
#if __ia64__ || (__sparc__ && __WORDSIZE == 64)
extern void
@@ -363,6 +424,8 @@ typedef struct jit_register jit_register_t;
# if DISASSEMBLER
typedef struct jit_data_info jit_data_info_t;
# endif
#elif __riscv
typedef struct jit_const jit_const_t;
#endif
union jit_data {
@@ -412,6 +475,9 @@ struct jit_block {
jit_node_t *label;
jit_regset_t reglive;
jit_regset_t regmask;
jit_bool_t again; /* Flag need to rebuild regset masks
* due to changes in live and unknown
* state. */
};
struct jit_value {
@@ -434,6 +500,12 @@ struct jit_data_info {
jit_uword_t code; /* pointer in code buffer */
jit_word_t length; /* length of constant vector */
};
#elif __riscv && __WORDSIZE == 64
struct jit_const {
jit_word_t value;
jit_word_t address;
jit_const_t *next;
};
#endif
struct jit_function {
@@ -454,9 +526,14 @@ struct jit_function {
} call;
jit_node_t *prolog;
jit_node_t *epilog;
jit_node_t *alist;
jit_int32_t *regoff;
jit_regset_t regset;
jit_int32_t stack;
#if defined(__i386__) || defined(__x86_64__)
jit_int32_t cvt_offset; /* allocai'd offset for x87<->xmm or
* fpr<->gpr transfer using the stack */
#endif
/* Helper for common jit generation pattern, used in GNU Smalltalk
* and possibly others, where a static frame layout is required or
@@ -465,11 +542,25 @@ struct jit_function {
jit_uint32_t define_frame : 1;
jit_uint32_t assume_frame : 1;
jit_uint32_t need_frame : 1; /* need frame pointer? */
jit_uint32_t need_stack : 1; /* need stack pointer? */
jit_uint32_t need_return : 1; /* not a leaf function */
/* alloca offset offset */
jit_int32_t aoffoff;
/* uses allocar flag */
jit_uint32_t allocar : 1;
#if __arm__
/* If will, or might use float registers and vfp is not available.
* Use the first 64 bytes always, as the access to the virtual float
* registers use hardcoded instructions that can only reach 64 byte
* displacements, and to keep code simpler, do not use temporaries. */
jit_uint32_t swf_offset : 1;
/* If need to call C functions for some operation, or variadic function */
jit_uint32_t save_reg_args : 1;
#endif
/* varargs state offsets */
jit_int32_t vaoff; /* offset of jit_va_list */
jit_int32_t vagp; /* first gp va argument */
@@ -490,7 +581,7 @@ struct jit_compiler {
jit_int32_t breg; /* base register for prolog/epilog */
#endif
#if __mips__ || __ia64__ || __alpha__ || \
(__sparc__ && __WORDSIZE == 64) || __riscv
(__sparc__ && __WORDSIZE == 64) || __riscv || __loongarch__
jit_int32_t carry;
#define jit_carry _jitc->carry
#endif
@@ -508,11 +599,14 @@ struct jit_compiler {
#endif
jit_uint32_t no_data : 1;
jit_uint32_t no_note : 1;
jit_int32_t framesize; /* space for callee save registers,
* frame pointer and return address */
jit_int32_t reglen; /* number of registers */
jit_regset_t regarg; /* cannot allocate */
jit_regset_t regsav; /* automatic spill only once */
jit_regset_t reglive; /* known live registers at some point */
jit_regset_t regmask; /* register mask to update reglive */
jit_regset_t explive; /* explicitly marked as live */
struct {
jit_uint8_t *end;
} code;
@@ -593,6 +687,27 @@ struct jit_compiler {
jit_word_t length;
} prolog;
jit_bool_t jump;
#elif __riscv && __WORDSIZE == 64
struct {
/* Hash table for constants to be resolved and patched */
struct {
jit_const_t **table; /* very simple hash table */
jit_word_t size; /* number of vectors in table */
jit_word_t count; /* number of distinct entries */
} hash;
struct {
jit_const_t **ptr; /* keep a single pointer */
jit_const_t *list; /* free list */
jit_word_t length; /* length of pool */
} pool;
/* Linear list for constants that cannot be encoded easily */
struct {
jit_word_t *instrs; /* list of direct movi instructions */
jit_word_t *values; /* list of direct movi constants */
jit_word_t offset; /* offset in instrs/values vector */
jit_word_t length; /* length of instrs/values vector */
} vector;
} consts;
#endif
#if GET_JIT_SIZE
/* Temporary storage to calculate instructions length */
@@ -616,6 +731,8 @@ struct jit_state {
struct {
jit_uint8_t *ptr;
jit_word_t length;
/* PROTECTED bytes starting at PTR are mprotect'd. */
jit_word_t protected;
} code;
struct {
jit_uint8_t *ptr;
@@ -672,14 +789,6 @@ _jit_regarg_set(jit_state_t*, jit_node_t*, jit_int32_t);
extern void
_jit_regarg_clr(jit_state_t*, jit_node_t*, jit_int32_t);
#define jit_get_reg(s) _jit_get_reg(_jit,s)
extern jit_int32_t
_jit_get_reg(jit_state_t*, jit_int32_t);
#define jit_unget_reg(r) _jit_unget_reg(_jit,r)
extern void
_jit_unget_reg(jit_state_t*, jit_int32_t);
#define jit_save(reg) _jit_save(_jit, reg)
extern void
_jit_save(jit_state_t*, jit_int32_t);
@@ -726,6 +835,7 @@ _emit_ldxi_d(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
extern void
_emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t);
extern void jit_init_print(void);
extern void jit_init_debug(const char*);
extern void jit_finish_debug(void);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Free Software Foundation, Inc.
* Copyright (C) 2019-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -65,4 +65,13 @@ typedef enum {
#define JIT_NOREG _NOREG
} jit_reg_t;
typedef struct {
jit_uint32_t flogr : 1;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_s390_h */
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -99,4 +99,13 @@ typedef enum {
_NOREG,
} jit_reg_t;
typedef struct {
jit_uint32_t lzcnt : 1;
} jit_cpu_t;
/*
* Initialization
*/
extern jit_cpu_t jit_cpu;
#endif /* _jit_sparc_h */
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -189,6 +189,10 @@ typedef struct {
jit_uint32_t avx : 1;
/* lahf/sahf available in 64 bits mode */
jit_uint32_t lahf : 1;
/* lzcnt and tzcnt? */
jit_uint32_t abm : 1;
/* adcx and adox instructions available? */
jit_uint32_t adx : 1;
} jit_cpu_t;
/*
+16 -5
View File
@@ -1,5 +1,5 @@
#
# Copyright 2000, 2001, 2002, 2012-2019 Free Software Foundation, Inc.
# Copyright 2000, 2001, 2002, 2012-2022 Free Software Foundation, Inc.
#
# This file is part of GNU lightning.
#
@@ -14,27 +14,34 @@
# License for more details.
#
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE $(LIGHTNING_CFLAGS)
AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
-D_GNU_SOURCE $(LIGHTNING_CFLAGS)
liblightning_LTLIBRARIES = liblightning.la
liblightning_la_LDFLAGS = -version-info 1:0:0
liblightning_la_LDFLAGS = -version-info 2:0:0
AM_CPPFLAGS =
if get_jit_size
JIT_SIZE_PATH = "$(top_builddir)/jit_$(cpu)-sz.c"
AM_CPPFLAGS=-DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)'
AM_CPPFLAGS += -DGET_JIT_SIZE=1 -DJIT_SIZE_PATH='$(JIT_SIZE_PATH)'
endif
if strong_type_checking
AM_CPPFLAGS += -DSTRONG_TYPE_CHECKING=1
endif
liblightningdir = $(libdir)
liblightning_la_SOURCES = \
jit_disasm.c \
jit_memory.c \
jit_names.c \
jit_note.c \
jit_print.c \
jit_size.c \
lightning.c
EXTRA_DIST = \
jit_names.c \
jit_fallback.c \
jit_rewind.c \
aarch64-logical-immediates.c \
jit_aarch64.c \
jit_aarch64-cpu.c \
jit_aarch64-fpu.c \
@@ -56,6 +63,10 @@ EXTRA_DIST = \
jit_ia64-cpu.c \
jit_ia64-fpu.c \
jit_ia64-sz.c \
jit_loongarch.c \
jit_loongarch-cpu.c \
jit_loongarch-fpu.c \
jit_loongarch-sz.c \
jit_mips.c \
jit_mips-cpu.c \
jit_mips-fpu.c \
@@ -0,0 +1,161 @@
// AArch64 Logical Immediate Encoding and Decoding
//
// I hereby place this code in the public domain, as per the terms of the
// CC0 license: https://creativecommons.org/publicdomain/zero/1.0/
#include <stdint.h>
#include <stdbool.h>
static inline int nonzeroCountTrailingZeros64(uint64_t n) {
return __builtin_ctzll(n);
}
static inline int countTrailingZeros64(uint64_t n) {
return n ? nonzeroCountTrailingZeros64(n) : 64;
}
static inline int nonzeroCountLeadingZeros64(uint64_t n) {
return __builtin_clzll(n);
}
static inline int nonzeroCountLeadingZeros32(uint32_t n) {
return __builtin_clz(n);
}
static inline uint64_t rotateRight64(uint64_t v, int n) {
// return __builtin_rotateright64(v, n);
return (v >> (n & 63)) | (v << (-n & 63));
}
static inline uint64_t clearTrailingOnes64(uint64_t n) {
return n & (n + 1);
}
#define ENCODE_FAILED (-1)
int encodeLogicalImmediate64(uint64_t val) {
// Consider an ARM64 logical immediate as a pattern of "o" ones preceded
// by "z" more-significant zeroes, repeated to fill a 64-bit integer.
// o > 0, z > 0, and the size (o + z) is a power of two in [2,64]. This
// part of the pattern is encoded in the fields "imms" and "N".
//
// "immr" encodes a further right rotate of the repeated pattern, allowing
// a wide range of useful bitwise constants to be represented.
//
// (The spec describes the "immr" rotate as rotating the "o + z" bit
// pattern before repeating it to fill 64-bits, but, as it's a repeating
// pattern, rotating afterwards is equivalent.)
// This encoding is not allowed to represent all-zero or all-one values.
if (val == 0 || ~val == 0)
return ENCODE_FAILED;
// To detect an immediate that may be encoded in this scheme, we first
// remove the right-rotate, by rotating such that the least significant
// bit is a one and the most significant bit is a zero.
//
// We do this by clearing any trailing one bits, then counting the
// trailing zeroes. This finds an "edge", where zero goes to one.
// We then rotate the original value right by that amount, moving
// the first one to the least significant bit.
int rotation = countTrailingZeros64(clearTrailingOnes64(val));
uint64_t normalized = rotateRight64(val, rotation & 63);
// Now we have normalized the value, and determined the rotation, we can
// determine "z" by counting the leading zeroes, and "o" by counting the
// trailing ones. (These will both be positive, as we already rejected 0
// and ~0, and rotated the value to start with a zero and end with a one.)
int zeroes = nonzeroCountLeadingZeros64(normalized);
int ones = nonzeroCountTrailingZeros64(~normalized);
int size = zeroes + ones;
// Detect the repeating pattern (by comparing every repetition to the
// one next to it, using rotate).
if (rotateRight64(val, size & 63) != val)
return ENCODE_FAILED;
// We do not need to further validate size to ensure it is a power of two
// between 2 and 64. The only "minimal" patterns that can repeat to fill a
// 64-bit value must have a length that is a factor of 64 (i.e. it is a
// power of two in the range [1,64]). And our pattern cannot be of length
// one (as we already rejected 0 and ~0).
//
// By "minimal" patterns I refer to patterns which do not themselves
// contain repetitions. For example, '010101' is a non-minimal pattern of
// a non-power-of-two length that can pass the above rotational test. It
// consists of the minimal pattern '01'. All our patterns are minimal, as
// they contain only one contiguous run of ones separated by at least one
// zero.
// Finally, we encode the values. "rotation" is the amount we rotated
// right by to "undo" the right-rotate encoded in immr, so must be
// negated.
// size 2: N=0 immr=00000r imms=11110s
// size 4: N=0 immr=0000rr imms=1110ss
// size 8: N=0 immr=000rrr imms=110sss
// size 16: N=0 immr=00rrrr imms=10ssss
// size 32: N=0 immr=0rrrrr imms=0sssss
// size 64: N=1 immr=rrrrrr imms=ssssss
int immr = -rotation & (size - 1);
int imms = -(size << 1) | (ones - 1);
int N = (size >> 6);
return (N << 12) | (immr << 6) | (imms & 0x3f);
}
int encodeLogicalImmediate32(uint32_t val) {
return encodeLogicalImmediate64(((uint64_t)val << 32) | val);
}
// Decoding!
bool isValidLogicalImmediate64(unsigned val) {
unsigned N = (val >> 12) & 1;
unsigned imms = val & 0x3f;
unsigned pattern = (N << 6) | (~imms & 0x3f);
return (pattern & (pattern - 1)) != 0;
}
bool isValidLogicalImmediate32(unsigned val) {
unsigned N = (val >> 12) & 1;
return N == 0 && isValidLogicalImmediate64(val);
}
#define DECODE_FAILED 0
// returns DECODE_FAILED (zero) if the encoding is invalid
uint64_t decodeLogicalImmediate64(unsigned val) {
// Fun way to generate the immediates with mask ^ (mask << S)
static const uint64_t mask_lookup[] = {
0xffffffffffffffff, // size = 64
0x00000000ffffffff, // size = 32
0x0000ffff0000ffff, // size = 16
0x00ff00ff00ff00ff, // size = 8
0x0f0f0f0f0f0f0f0f, // size = 4
0x3333333333333333, // size = 2
};
unsigned N = (val >> 12) & 1;
int immr = (val >> 6) & 0x3f;
unsigned imms = val & 0x3f;
unsigned pattern = (N << 6) | (~imms & 0x3f);
if (!(pattern & (pattern - 1))) return DECODE_FAILED;
int leading_zeroes = nonzeroCountLeadingZeros32(pattern);
unsigned imms_mask = 0x7fffffff >> leading_zeroes;
uint64_t mask = mask_lookup[leading_zeroes - 25];
unsigned S = (imms + 1) & imms_mask;
return rotateRight64(mask ^ (mask << S), immr);
}
uint32_t decodeLogicalImmediate32(unsigned val) {
unsigned N = (val >> 12) & 1;
if (N) return DECODE_FAILED;
return (uint32_t)decodeLogicalImmediate64(val);
}
+229 -152
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -210,7 +210,7 @@ typedef union {
jit_int32_t w;
# undef ui
} instr_t;
# define stack_framesize 160
# define s26_p(d) ((d) >= -33554432 && (d) <= 33554431)
# define ii(i) *_jit->pc.ui++ = i
# define ldr(r0,r1) ldr_l(r0,r1)
# define ldxr(r0,r1,r2) ldxr_l(r0,r1,r2)
@@ -290,6 +290,7 @@ typedef union {
# define A64_CBNZ 0x35000000
# define A64_B_C 0x54000000
# define A64_CSINC 0x1a800400
# define A64_CSSEL 0x1a800000
# define A64_REV 0xdac00c00
# define A64_UDIV 0x1ac00800
# define A64_SDIV 0x1ac00c00
@@ -317,6 +318,8 @@ typedef union {
# define A64_LDRSB 0x38e06800
# define A64_STR 0xf8206800
# define A64_LDR 0xf8606800
# define A64_LDAXR 0xc85ffc00
# define A64_STLXR 0xc800fc00
# define A64_STRH 0x78206800
# define A64_LDRH 0x78606800
# define A64_LDRSH 0x78a06800
@@ -346,6 +349,9 @@ typedef union {
# define A64_ORR 0x2a000000
# define A64_MOV 0x2a0003e0 /* AKA orr Rd,xzr,Rm */
# define A64_MVN 0x2a2003e0
# define A64_CLS 0x5ac01400
# define A64_CLZ 0x5ac01000
# define A64_RBIT 0x5ac00000
# define A64_UXTW 0x2a0003e0 /* AKA MOV */
# define A64_EOR 0x4a000000
# define A64_ANDS 0x6a000000
@@ -367,6 +373,9 @@ typedef union {
# define MOV(Rd,Rm) ox_x(A64_MOV|XS,Rd,Rm)
# define MVN(Rd,Rm) ox_x(A64_MVN|XS,Rd,Rm)
# define NEG(Rd,Rm) ox_x(A64_NEG|XS,Rd,Rm)
# define CLS(Rd,Rm) o_xx(A64_CLS|XS,Rd,Rm)
# define CLZ(Rd,Rm) o_xx(A64_CLZ|XS,Rd,Rm)
# define RBIT(Rd,Rm) o_xx(A64_RBIT|XS,Rd,Rm)
# define MOVN(Rd,Imm16) ox_h(A64_MOVN|XS,Rd,Imm16)
# define MOVN_16(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_16,Rd,Imm16)
# define MOVN_32(Rd,Imm16) ox_h(A64_MOVN|XS|MOVI_LSL_32,Rd,Imm16)
@@ -444,6 +453,8 @@ typedef union {
# define LDR(Rt,Rn,Rm) oxxx(A64_LDR,Rt,Rn,Rm)
# define LDRI(Rt,Rn,Imm12) oxxi(A64_LDRI,Rt,Rn,Imm12)
# define LDUR(Rt,Rn,Imm9) oxx9(A64_LDUR,Rt,Rn,Imm9)
# define LDAXR(Rt,Rn) o_xx(A64_LDAXR,Rt,Rn)
# define STLXR(Rs,Rt,Rn) oxxx(A64_STLXR,Rs,Rn,Rt)
# define STRB(Rt,Rn,Rm) oxxx(A64_STRB,Rt,Rn,Rm)
# define STRBI(Rt,Rn,Imm12) oxxi(A64_STRBI,Rt,Rn,Imm12)
# define STURB(Rt,Rn,Imm9) oxx9(A64_STURB,Rt,Rn,Imm9)
@@ -461,6 +472,7 @@ typedef union {
# define LDPI_PRE(Rt,Rt2,Rn,Simm7) oxxx7(A64_LDP_PRE|XS,Rt,Rt2,Rn,Simm7)
# define STPI_POS(Rt,Rt2,Rn,Simm7) oxxx7(A64_STP_POS|XS,Rt,Rt2,Rn,Simm7)
# define CSET(Rd,Cc) CSINC(Rd,XZR_REGNO,XZR_REGNO,Cc)
# define CSEL(Rd,Rn,Rm,Cc) oxxxc(A64_CSSEL|XS,Rd,Rn,Rm,Cc)
# define B(Simm26) o26(A64_B,Simm26)
# define BL(Simm26) o26(A64_BL,Simm26)
# define BR(Rn) o_x_(A64_BR,Rn)
@@ -572,8 +584,20 @@ static void _rshi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define rshr_u(r0,r1,r2) LSR(r0,r1,r2)
# define rshi_u(r0,r1,i0) _rshi_u(_jit,r0,r1,i0)
static void _rshi_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define negr(r0,r1) NEG(r0,r1)
# define comr(r0,r1) MVN(r0,r1)
# define clor(r0, r1) _clor(_jit, r0, r1)
static void _clor(jit_state_t*, jit_int32_t, jit_int32_t);
# define clzr(r0, r1) CLZ(r0,r1)
static void _clzr(jit_state_t*, jit_int32_t, jit_int32_t);
# define ctor(r0, r1) _ctor(_jit, r0, r1)
static void _ctor(jit_state_t*, jit_int32_t, jit_int32_t);
# define ctzr(r0, r1) _ctzr(_jit, r0, r1)
static void _ctzr(jit_state_t*, jit_int32_t, jit_int32_t);
# define andr(r0,r1,r2) AND(r0,r1,r2)
# define andi(r0,r1,i0) _andi(_jit,r0,r1,i0)
static void _andi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@@ -657,23 +681,22 @@ static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define stxr_l(r0,r1,r2) STR(r2,r1,r0)
# define stxi_l(i0,r0,r1) _stxi_l(_jit,i0,r0,r1)
static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ul(r0,r1) REV(r0,r1)
# else
# define htonr_us(r0,r1) extr_us(r0,r1)
# define htonr_ui(r0,r1) extr_ui(r0,r1)
# define htonr_ul(r0,r1) movr(r0,r1)
# endif
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ul(r0,r1) REV(r0,r1)
# define extr_c(r0,r1) SXTB(r0,r1)
# define extr_uc(r0,r1) UXTB(r0,r1)
# define extr_s(r0,r1) SXTH(r0,r1)
# define extr_us(r0,r1) UXTH(r0,r1)
# define extr_i(r0,r1) SXTW(r0,r1)
# define extr_ui(r0,r1) UXTW(r0,r1)
# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_word_t);
#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
# define movr(r0,r1) _movr(_jit,r0,r1)
static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
# define movi(r0,i0) _movi(_jit,r0,i0)
@@ -772,12 +795,12 @@ _bmxi(jit_state_t*,jit_int32_t,jit_word_t,jit_int32_t,jit_word_t);
# define bmci(i0,r0,i1) bmxi(BCC_EQ,i0,r0,i1)
# define jmpr(r0) BR(r0)
# define jmpi(i0) _jmpi(_jit,i0)
static void _jmpi(jit_state_t*,jit_word_t);
static jit_word_t _jmpi(jit_state_t*,jit_word_t);
# define jmpi_p(i0) _jmpi_p(_jit,i0)
static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
# define callr(r0) BLR(r0)
# define calli(i0) _calli(_jit,i0)
static void _calli(jit_state_t*,jit_word_t);
static jit_word_t _calli(jit_state_t*,jit_word_t);
# define calli_p(i0) _calli_p(_jit,i0)
static jit_word_t _calli_p(jit_state_t*,jit_word_t);
# define prolog(i0) _prolog(_jit,i0)
@@ -793,36 +816,17 @@ static void _patch_at(jit_state_t*,jit_word_t,jit_word_t);
#endif
#if CODE
/* https://dougallj.wordpress.com/2021/10/30/bit-twiddling-optimising-aarch64-logical-immediate-encoding-and-decoding/ */
#include "aarch64-logical-immediates.c"
static jit_int32_t
logical_immediate(jit_word_t imm)
{
/* There are 5334 possible immediate values, but to avoid the
* need of either too complex code or large lookup tables,
* only check for (simply) encodable common/small values */
switch (imm) {
case -16: return (0xf3b);
case -15: return (0xf3c);
case -13: return (0xf3d);
case -9: return (0xf3e);
case -8: return (0xf7c);
case -7: return (0xf7d);
case -5: return (0xf7e);
case -4: return (0xfbd);
case -3: return (0xfbe);
case -2: return (0xffe);
case 1: return (0x000);
case 2: return (0xfc0);
case 3: return (0x001);
case 4: return (0xf80);
case 6: return (0xfc1);
case 7: return (0x002);
case 8: return (0xf40);
case 12: return (0xf81);
case 14: return (0xfc2);
case 15: return (0x003);
case 16: return (0xf00);
default: return (-1);
jit_int32_t result = encodeLogicalImmediate64(imm);
if (result != ENCODE_FAILED) {
assert(isValidLogicalImmediate64(result));
return (result & 0xfff);
}
return (-1);
}
static void
@@ -903,7 +907,7 @@ static void
_o26(jit_state_t *_jit, jit_int32_t Op, jit_int32_t Simm26)
{
instr_t i;
assert(Simm26 >= -33554432 && Simm26 <= 33554431);
assert(s26_p(Simm26));
assert(!(Op & ~0xfc000000));
i.w = Op;
i.imm26.b = Simm26;
@@ -1375,6 +1379,41 @@ _rshi_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
}
}
static void
_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
CMPI(r2, 0);
CSEL(r0, r0, r1, CC_NE);
}
static void
_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
CMPI(r2, 0);
CSEL(r0, r0, r1, CC_EQ);
}
static void
_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
comr(r0, r1);
clzr(r0, r0);
}
static void
_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
RBIT(r0, r1);
clor(r0, r0);
}
static void
_ctzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
RBIT(r0, r1);
clzr(r0, r0);
}
static void
_andi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
@@ -1441,21 +1480,19 @@ _xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
}
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
static void
_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
htonr_ul(r0, r1);
bswapr_ul(r0, r1);
rshi_u(r0, r0, 48);
}
static void
_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
htonr_ul(r0, r1);
bswapr_ul(r0, r1);
rshi_u(r0, r0, 32);
}
#endif
static void
_ldi_c(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
@@ -1610,8 +1647,7 @@ static void
_ldxi_s(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
assert(!(i0 & 1));
if (i0 >= 0 && i0 <= 8191)
if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
LDRSHI(r0, r1, i0 >> 1);
else if (i0 > -256 && i0 < 0)
LDURSH(r0, r1, i0 & 0x1ff);
@@ -1636,8 +1672,7 @@ static void
_ldxi_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
assert(!(i0 & 1));
if (i0 >= 0 && i0 <= 8191)
if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
LDRHI(r0, r1, i0 >> 1);
else if (i0 > -256 && i0 < 0)
LDURH(r0, r1, i0 & 0x1ff);
@@ -1656,8 +1691,7 @@ static void
_ldxi_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
assert(!(i0 & 3));
if (i0 >= 0 && i0 <= 16383)
if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
LDRSWI(r0, r1, i0 >> 2);
else if (i0 > -256 && i0 < 0)
LDURSW(r0, r1, i0 & 0x1ff);
@@ -1682,8 +1716,7 @@ static void
_ldxi_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
assert(!(i0 & 3));
if (i0 >= 0 && i0 <= 16383)
if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
LDRWI(r0, r1, i0 >> 2);
else if (i0 > -256 && i0 < 0)
LDURW(r0, r1, i0 & 0x1ff);
@@ -1702,8 +1735,7 @@ static void
_ldxi_l(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
assert(!(i0 & 7));
if (i0 >= 0 && i0 <= 32767)
if (i0 >= 0 && i0 <= 32767 && !(i0 & 7))
LDRI(r0, r1, i0 >> 3);
else if (i0 > -256 && i0 < 0)
LDUR(r0, r1, i0 & 0x1ff);
@@ -1775,8 +1807,7 @@ static void
_stxi_s(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
assert(!(i0 & 1));
if (i0 >= 0 && i0 <= 8191)
if (i0 >= 0 && i0 <= 8191 && !(i0 & 1))
STRHI(r1, r0, i0 >> 1);
else if (i0 > -256 && i0 < 0)
STURH(r1, r0, i0 & 0x1ff);
@@ -1792,8 +1823,7 @@ static void
_stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
assert(!(i0 & 3));
if (i0 >= 0 && i0 <= 16383)
if (i0 >= 0 && i0 <= 16383 && !(i0 & 3))
STRWI(r1, r0, i0 >> 2);
else if (i0 > -256 && i0 < 0)
STURW(r1, r0, i0 & 0x1ff);
@@ -1809,8 +1839,7 @@ static void
_stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
assert(!(i0 & 7));
if (i0 >= 0 && i0 <= 32767)
if (i0 >= 0 && i0 <= 32767 && !(i0 & 7))
STRI(r1, r0, i0 >> 3);
else if (i0 > -256 && i0 < 0)
STUR(r1, r0, i0 & 0x1ff);
@@ -1822,6 +1851,33 @@ _stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
}
}
static void
_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
jit_int32_t r1_reg, iscasi;
jit_word_t retry, done, jump0, jump1;
if ((iscasi = (r1 == _NOREG))) {
r1_reg = jit_get_reg(jit_class_gpr);
r1 = rn(r1_reg);
movi(r1, i0);
}
/* retry: */
retry = _jit->pc.w;
LDAXR(r0, r1);
eqr(r0, r0, r2);
jump0 = beqi(_jit->pc.w, r0, 0); /* beqi done r0 0 */
STLXR(r3, r0, r1);
jump1 = bnei(_jit->pc.w, r0, 0); /* bnei retry r0 0 */
/* done: */
CSET(r0, CC_EQ);
done = _jit->pc.w;
patch_at(jump0, done);
patch_at(jump1, retry);
if (iscasi)
jit_unget_reg(r1_reg);
}
static void
_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
@@ -2126,20 +2182,22 @@ _bmxi(jit_state_t *_jit, jit_int32_t cc,
return (w);
}
static void
static jit_word_t
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t w;
jit_int32_t reg;
w = (i0 - _jit->pc.w) >> 2;
if (w >= -33554432 && w <= 33554431)
B(w);
jit_word_t d, w;
w = _jit->pc.w;
d = (i0 - w) >> 2;
if (s26_p(d))
B(d);
else {
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
movi(rn(reg), i0);
jmpr(rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
@@ -2154,20 +2212,22 @@ _jmpi_p(jit_state_t *_jit, jit_word_t i0)
return (w);
}
static void
static jit_word_t
_calli(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t w;
jit_int32_t reg;
w = (i0 - _jit->pc.w) >> 2;
if (w >= -33554432 && w <= 33554431)
BL(w);
jit_word_t d, w;
w = _jit->pc.w;
d = (i0 - w) >> 2;
if (s26_p(d))
BL(d);
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
callr(rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static jit_word_t
@@ -2182,20 +2242,13 @@ _calli_p(jit_state_t *_jit, jit_word_t i0)
return (w);
}
/*
* prolog and epilog not as "optimized" as one would like, but the
* problem of overallocating stack space to save callee save registers
* exists on all ports, and is still a todo to use a variable
* stack_framesize
* value, what would cause needing to patch some calls, most likely
* the offset of jit_arg* of stack arguments.
*/
static void
_prolog(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t reg;
jit_int32_t reg, rreg, offs;
if (_jitc->function->define_frame || _jitc->function->assume_frame) {
jit_int32_t frame = -_jitc->function->frame;
jit_check_frame();
assert(_jitc->function->self.aoff >= frame);
if (_jitc->function->assume_frame)
return;
@@ -2206,40 +2259,51 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
_jitc->function->stack = ((_jitc->function->self.alen -
/* align stack at 16 bytes */
_jitc->function->self.aoff) + 15) & -16;
STPI_POS(FP_REGNO, LR_REGNO, SP_REGNO, -(stack_framesize >> 3));
MOV_XSP(FP_REGNO, SP_REGNO);
#define SPILL(L, R, O) \
do { \
if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \
if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
STPI(L, R, SP_REGNO, O); \
else \
STRI(L, SP_REGNO, O); \
} \
else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
STRI(R, SP_REGNO, O + 1); \
} while (0)
SPILL(19, 20, 2);
SPILL(21, 22, 4);
SPILL(23, 24, 6);
SPILL(25, 26, 8);
SPILL(27, 28, 10);
#undef SPILL
#define SPILL(R, O) \
do { \
if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \
stxi_d(O, SP_REGNO, R); \
} while (0)
SPILL( 8, 96);
SPILL( 9, 104);
SPILL(10, 112);
SPILL(11, 120);
SPILL(12, 128);
SPILL(13, 136);
SPILL(14, 144);
SPILL(15, 152);
#undef SPILL
if (_jitc->function->stack)
if (!_jitc->function->need_frame) {
/* check if any callee save register needs to be saved */
for (reg = 0; reg < _jitc->reglen; ++reg)
if (jit_regset_tstbit(&_jitc->function->regset, reg) &&
(_rvs[reg].spec & jit_class_sav)) {
jit_check_frame();
break;
}
}
if (_jitc->function->need_frame) {
STPI_POS(FP_REGNO, LR_REGNO, SP_REGNO, -(jit_framesize() >> 3));
MOV_XSP(FP_REGNO, SP_REGNO);
}
/* callee save registers */
for (reg = 0, offs = 2; reg < jit_size(iregs);) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
for (rreg = reg + 1; rreg < jit_size(iregs); rreg++) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[rreg]))
break;
}
if (rreg < jit_size(iregs)) {
STPI(rn(iregs[reg]), rn(iregs[rreg]), SP_REGNO, offs);
offs += 2;
reg = rreg + 1;
}
else {
STRI(rn(iregs[reg]), SP_REGNO, offs);
++offs;
/* No pair found */
break;
}
}
else
++reg;
}
for (reg = 0, offs <<= 3; reg < jit_size(fregs); reg++) {
if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
stxi_d(offs, SP_REGNO, rn(fregs[reg]));
offs += sizeof(jit_float64_t);
}
}
if (_jitc->function->stack)
subi(SP_REGNO, SP_REGNO, _jitc->function->stack);
if (_jitc->function->allocar) {
reg = jit_get_reg(jit_class_gpr);
@@ -2248,6 +2312,7 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
jit_unget_reg(reg);
}
#if !__APPLE__
if (_jitc->function->self.call & jit_call_varargs) {
/* Save gp registers in the save area, if any is a vararg */
for (reg = 8 - _jitc->function->vagp / -8;
@@ -2265,53 +2330,55 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
stxi_d(_jitc->function->vaoff + offsetof(jit_va_list_t, q0) +
reg * 16 + offsetof(jit_qreg_t, l), FP_REGNO, rn(_V0 - reg));
}
#endif
}
static void
_epilog(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t reg, rreg, offs;
if (_jitc->function->assume_frame)
return;
if (_jitc->function->stack)
MOV_XSP(SP_REGNO, FP_REGNO);
#define LOAD(L, R, O) \
do { \
if (jit_regset_tstbit(&_jitc->function->regset, _R##L)) { \
if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
LDPI(L, R, SP_REGNO, O); \
else \
LDRI(L, SP_REGNO, O); \
} \
else if (jit_regset_tstbit(&_jitc->function->regset, _R##R)) \
LDRI(R, SP_REGNO, O + 1); \
} while (0)
LOAD(19, 20, 2);
LOAD(21, 22, 4);
LOAD(23, 24, 6);
LOAD(25, 26, 8);
LOAD(27, 28, 10);
#undef LOAD
#define LOAD(R, O) \
do { \
if (jit_regset_tstbit(&_jitc->function->regset, _V##R)) \
ldxi_d(R, SP_REGNO, O); \
} while (0)
LOAD( 8, 96);
LOAD( 9, 104);
LOAD(10, 112);
LOAD(11, 120);
LOAD(12, 128);
LOAD(13, 136);
LOAD(14, 144);
LOAD(15, 152);
#undef LOAD
LDPI_PRE(FP_REGNO, LR_REGNO, SP_REGNO, stack_framesize >> 3);
/* callee save registers */
for (reg = 0, offs = 2; reg < jit_size(iregs);) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
for (rreg = reg + 1; rreg < jit_size(iregs); rreg++) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[rreg]))
break;
}
if (rreg < jit_size(iregs)) {
LDPI(rn(iregs[reg]), rn(iregs[rreg]), SP_REGNO, offs);
offs += 2;
reg = rreg + 1;
}
else {
LDRI(rn(iregs[reg]), SP_REGNO, offs);
++offs;
/* No pair found */
break;
}
}
else
++reg;
}
for (reg = 0, offs <<= 3; reg < jit_size(fregs); reg++) {
if (jit_regset_tstbit(&_jitc->function->regset, fregs[reg])) {
ldxi_d(rn(fregs[reg]), SP_REGNO, offs);
offs += sizeof(jit_float64_t);
}
}
if (_jitc->function->need_frame)
LDPI_PRE(FP_REGNO, LR_REGNO, SP_REGNO, jit_framesize() >> 3);
RET();
}
static void
_vastart(jit_state_t *_jit, jit_int32_t r0)
{
#if !__APPLE__
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
@@ -2322,7 +2389,7 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
reg = jit_get_reg(jit_class_gpr);
/* Initialize stack pointer to the first stack argument. */
addi(rn(reg), FP_REGNO, _jitc->function->self.size);
addi(rn(reg), FP_REGNO, jit_selfsize());
stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
/* Initialize gp top pointer to the first stack argument. */
@@ -2342,11 +2409,16 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg));
jit_unget_reg(reg);
#else
assert(_jitc->function->self.call & jit_call_varargs);
addi(r0, FP_REGNO, jit_selfsize());
#endif
}
static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
#if !__APPLE__
jit_word_t ge_code;
jit_word_t lt_code;
jit_int32_t rg0, rg1;
@@ -2376,7 +2448,7 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
jit_unget_reg(rg1);
/* Jump over overflow code. */
lt_code = jmpi_p(_jit->pc.w);
lt_code = jmpi(_jit->pc.w);
/* Where to land if argument is in overflow area. */
patch_at(ge_code, _jit->pc.w);
@@ -2395,6 +2467,11 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
patch_at(lt_code, _jit->pc.w);
jit_unget_reg(rg0);
#else
assert(_jitc->function->self.call & jit_call_varargs);
ldr(r0, r1);
addi(r1, r1, sizeof(jit_word_t));
#endif
}
static void
@@ -2414,7 +2491,7 @@ _patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
ffc = i.w & 0xffc00000;
if (fc == A64_B || fc == A64_BL) {
d = (label - instr) >> 2;
assert(d >= -33554432 && d <= 33554431);
assert(s26_p(d));
i.imm26.b = d;
u.i[0] = i.w;
}
+8 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -862,6 +862,7 @@ dbopi(ltgt)
static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
#if !__APPLE__
jit_word_t ge_code;
jit_word_t lt_code;
jit_int32_t rg0, rg1;
@@ -891,7 +892,7 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
jit_unget_reg(rg1);
/* Jump over overflow code. */
lt_code = jmpi_p(_jit->pc.w);
lt_code = jmpi(_jit->pc.w);
/* Where to land if argument is in overflow area. */
patch_at(ge_code, _jit->pc.w);
@@ -910,5 +911,10 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
patch_at(lt_code, _jit->pc.w);
jit_unget_reg(rg0);
#else
assert(_jitc->function->self.call & jit_call_varargs);
ldr_d(r0, r1);
addi(r1, r1, sizeof(jit_float64_t));
#endif
}
#endif
+535 -30
View File
@@ -1,20 +1,25 @@
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 120
# if PACKED_STACK
#define JIT_INSTR_MAX 96
0, /* data */
0, /* live */
4, /* align */
12, /* align */
0, /* save */
0, /* load */
4, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
120, /* prolog */
96, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -22,11 +27,23 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
44, /* va_start */
64, /* va_arg */
72, /* va_arg_d */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
12, /* va_arg_d */
0, /* va_end */
4, /* addr */
20, /* addi */
@@ -95,29 +112,36 @@
8, /* nei */
4, /* movr */
16, /* movi */
8, /* movnr */
8, /* movzr */
28, /* casr */
36, /* casi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
8, /* bswapr_us */
8, /* bswapr_ui */
4, /* bswapr_ul */
8, /* htonr_us */
8, /* htonr_ui */
4, /* htonr_ul */
4, /* ldr_c */
12, /* ldi_c */
16, /* ldi_c */
4, /* ldr_uc */
12, /* ldi_uc */
16, /* ldi_uc */
4, /* ldr_s */
12, /* ldi_s */
16, /* ldi_s */
4, /* ldr_us */
12, /* ldi_us */
16, /* ldi_us */
4, /* ldr_i */
12, /* ldi_i */
16, /* ldi_i */
4, /* ldr_ui */
12, /* ldi_ui */
16, /* ldi_ui */
4, /* ldr_l */
12, /* ldi_l */
16, /* ldi_l */
8, /* ldxr_c */
20, /* ldxi_c */
4, /* ldxr_uc */
@@ -133,13 +157,13 @@
4, /* ldxr_l */
20, /* ldxi_l */
4, /* str_c */
12, /* sti_c */
16, /* sti_c */
4, /* str_s */
12, /* sti_s */
16, /* sti_s */
4, /* str_i */
12, /* sti_i */
16, /* sti_i */
4, /* str_l */
12, /* sti_l */
16, /* sti_l */
4, /* stxr_c */
20, /* stxi_c */
4, /* stxr_s */
@@ -189,17 +213,41 @@
8, /* bxsubr_u */
8, /* bxsubi_u */
4, /* jmpr */
20, /* jmpi */
4, /* jmpi */
4, /* callr */
20, /* calli */
16, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -259,11 +307,11 @@
4, /* movr_f */
8, /* movi_f */
8, /* ldr_f */
16, /* ldi_f */
20, /* ldi_f */
8, /* ldxr_f */
24, /* ldxi_f */
8, /* str_f */
16, /* sti_f */
20, /* sti_f */
8, /* stxr_f */
24, /* stxi_f */
8, /* bltr_f */
@@ -350,11 +398,11 @@
4, /* movr_d */
12, /* movi_d */
8, /* ldr_d */
16, /* ldi_d */
20, /* ldi_d */
8, /* ldxr_d */
24, /* ldxi_d */
8, /* str_d */
16, /* sti_d */
20, /* sti_d */
8, /* stxr_d */
24, /* stxi_d */
8, /* bltr_d */
@@ -399,4 +447,461 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
8, /* clo */
4, /* clz */
12, /* cto */
8, /* ctz */
# else /* PACKED_STACK */
#define JIT_INSTR_MAX 120
0, /* data */
0, /* live */
12, /* align */
0, /* save */
0, /* load */
4, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
120, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
12, /* va_arg_d */
0, /* va_end */
4, /* addr */
20, /* addi */
4, /* addcr */
12, /* addci */
4, /* addxr */
8, /* addxi */
4, /* subr */
20, /* subi */
4, /* subcr */
12, /* subci */
4, /* subxr */
8, /* subxi */
24, /* rsbi */
4, /* mulr */
20, /* muli */
12, /* qmulr */
20, /* qmuli */
12, /* qmulr_u */
20, /* qmuli_u */
4, /* divr */
20, /* divi */
4, /* divr_u */
12, /* divi_u */
20, /* qdivr */
16, /* qdivi */
20, /* qdivr_u */
16, /* qdivi_u */
12, /* remr */
28, /* remi */
12, /* remr_u */
20, /* remi_u */
4, /* andr */
20, /* andi */
4, /* orr */
20, /* ori */
4, /* xorr */
20, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
4, /* rshi */
4, /* rshr_u */
4, /* rshi_u */
4, /* negr */
4, /* comr */
8, /* ltr */
8, /* lti */
8, /* ltr_u */
8, /* lti_u */
8, /* ler */
8, /* lei */
8, /* ler_u */
8, /* lei_u */
8, /* eqr */
8, /* eqi */
8, /* ger */
8, /* gei */
8, /* ger_u */
8, /* gei_u */
8, /* gtr */
8, /* gti */
8, /* gtr_u */
8, /* gti_u */
8, /* ner */
8, /* nei */
4, /* movr */
16, /* movi */
8, /* movnr */
8, /* movzr */
28, /* casr */
36, /* casi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
8, /* bswapr_us */
8, /* bswapr_ui */
4, /* bswapr_ul */
8, /* htonr_us */
8, /* htonr_ui */
4, /* htonr_ul */
4, /* ldr_c */
16, /* ldi_c */
4, /* ldr_uc */
16, /* ldi_uc */
4, /* ldr_s */
16, /* ldi_s */
4, /* ldr_us */
16, /* ldi_us */
4, /* ldr_i */
16, /* ldi_i */
4, /* ldr_ui */
16, /* ldi_ui */
4, /* ldr_l */
16, /* ldi_l */
8, /* ldxr_c */
20, /* ldxi_c */
4, /* ldxr_uc */
20, /* ldxi_uc */
4, /* ldxr_s */
16, /* ldxi_s */
4, /* ldxr_us */
16, /* ldxi_us */
4, /* ldxr_i */
20, /* ldxi_i */
4, /* ldxr_ui */
16, /* ldxi_ui */
4, /* ldxr_l */
20, /* ldxi_l */
4, /* str_c */
16, /* sti_c */
4, /* str_s */
16, /* sti_s */
4, /* str_i */
16, /* sti_i */
4, /* str_l */
16, /* sti_l */
4, /* stxr_c */
20, /* stxi_c */
4, /* stxr_s */
20, /* stxi_s */
4, /* stxr_i */
20, /* stxi_i */
4, /* stxr_l */
20, /* stxi_l */
8, /* bltr */
8, /* blti */
8, /* bltr_u */
8, /* blti_u */
8, /* bler */
8, /* blei */
8, /* bler_u */
8, /* blei_u */
8, /* beqr */
24, /* beqi */
8, /* bger */
8, /* bgei */
8, /* bger_u */
8, /* bgei_u */
8, /* bgtr */
8, /* bgti */
8, /* bgtr_u */
8, /* bgti_u */
8, /* bner */
24, /* bnei */
8, /* bmsr */
8, /* bmsi */
8, /* bmcr */
8, /* bmci */
8, /* boaddr */
8, /* boaddi */
8, /* boaddr_u */
8, /* boaddi_u */
8, /* bxaddr */
8, /* bxaddi */
8, /* bxaddr_u */
8, /* bxaddi_u */
8, /* bosubr */
8, /* bosubi */
8, /* bosubr_u */
8, /* bosubi_u */
8, /* bxsubr */
8, /* bxsubi */
8, /* bxsubr_u */
8, /* bxsubi_u */
4, /* jmpr */
4, /* jmpi */
4, /* callr */
16, /* calli */
0, /* prepare */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
96, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
12, /* addi_f */
4, /* subr_f */
12, /* subi_f */
12, /* rsbi_f */
4, /* mulr_f */
12, /* muli_f */
4, /* divr_f */
12, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
8, /* ltr_f */
16, /* lti_f */
8, /* ler_f */
16, /* lei_f */
8, /* eqr_f */
16, /* eqi_f */
8, /* ger_f */
16, /* gei_f */
8, /* gtr_f */
16, /* gti_f */
8, /* ner_f */
16, /* nei_f */
8, /* unltr_f */
16, /* unlti_f */
8, /* unler_f */
16, /* unlei_f */
16, /* uneqr_f */
24, /* uneqi_f */
8, /* unger_f */
16, /* ungei_f */
8, /* ungtr_f */
16, /* ungti_f */
16, /* ltgtr_f */
24, /* ltgti_f */
8, /* ordr_f */
16, /* ordi_f */
8, /* unordr_f */
16, /* unordi_f */
8, /* truncr_f_i */
4, /* truncr_f_l */
4, /* extr_f */
4, /* extr_d_f */
4, /* movr_f */
8, /* movi_f */
8, /* ldr_f */
20, /* ldi_f */
8, /* ldxr_f */
24, /* ldxi_f */
8, /* str_f */
20, /* sti_f */
8, /* stxr_f */
24, /* stxi_f */
8, /* bltr_f */
16, /* blti_f */
8, /* bler_f */
16, /* blei_f */
8, /* beqr_f */
16, /* beqi_f */
8, /* bger_f */
16, /* bgei_f */
8, /* bgtr_f */
16, /* bgti_f */
8, /* bner_f */
16, /* bnei_f */
8, /* bunltr_f */
16, /* bunlti_f */
8, /* bunler_f */
16, /* bunlei_f */
16, /* buneqr_f */
24, /* buneqi_f */
8, /* bunger_f */
16, /* bungei_f */
8, /* bungtr_f */
16, /* bungti_f */
16, /* bltgtr_f */
24, /* bltgti_f */
8, /* bordr_f */
16, /* bordi_f */
8, /* bunordr_f */
16, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
12, /* addi_d */
4, /* subr_d */
12, /* subi_d */
12, /* rsbi_d */
4, /* mulr_d */
12, /* muli_d */
4, /* divr_d */
12, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
8, /* ltr_d */
16, /* lti_d */
8, /* ler_d */
16, /* lei_d */
8, /* eqr_d */
16, /* eqi_d */
8, /* ger_d */
16, /* gei_d */
8, /* gtr_d */
16, /* gti_d */
8, /* ner_d */
16, /* nei_d */
8, /* unltr_d */
16, /* unlti_d */
8, /* unler_d */
16, /* unlei_d */
16, /* uneqr_d */
24, /* uneqi_d */
8, /* unger_d */
16, /* ungei_d */
8, /* ungtr_d */
16, /* ungti_d */
16, /* ltgtr_d */
24, /* ltgti_d */
8, /* ordr_d */
16, /* ordi_d */
8, /* unordr_d */
16, /* unordi_d */
8, /* truncr_d_i */
4, /* truncr_d_l */
4, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
12, /* movi_d */
8, /* ldr_d */
20, /* ldi_d */
8, /* ldxr_d */
24, /* ldxi_d */
8, /* str_d */
20, /* sti_d */
8, /* stxr_d */
24, /* stxi_d */
8, /* bltr_d */
16, /* blti_d */
8, /* bler_d */
16, /* blei_d */
8, /* beqr_d */
20, /* beqi_d */
8, /* bger_d */
16, /* bgei_d */
8, /* bgtr_d */
16, /* bgti_d */
8, /* bner_d */
16, /* bnei_d */
8, /* bunltr_d */
16, /* bunlti_d */
8, /* bunler_d */
16, /* bunlei_d */
16, /* buneqr_d */
24, /* buneqi_d */
8, /* bunger_d */
16, /* bungei_d */
8, /* bungtr_d */
16, /* bungti_d */
16, /* bltgtr_d */
24, /* bltgti_d */
8, /* bordr_d */
16, /* bordi_d */
8, /* bunordr_d */
16, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
0, /* movr_w_f */
0, /* movr_ww_d */
0, /* movr_w_d */
0, /* movr_f_w */
0, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
8, /* clo */
4, /* clz */
12, /* cto */
8, /* ctz */
# endif
#endif /* __WORDSIZE */
File diff suppressed because it is too large. Load diff
+69 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2019 Free Software Foundation, Inc.
* Copyright (C) 2014-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -311,8 +311,21 @@ static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
# define movi_p(r0,i0) _movi_p(_jit,r0,i0)
static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
# define movnr(r0,r1,r2) CMOVNE(r2, r1, r0)
# define movzr(r0,r1,r2) CMOVEQ(r2, r1, r0)
# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_word_t);
#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
# define negr(r0,r1) NEGQ(r1,r0)
# define comr(r0,r1) NOT(r1,r0)
# define clor(r0, r1) _clor(_jit, r0, r1)
static void _clor(jit_state_t*, jit_int32_t, jit_int32_t);
# define clzr(r0, r1) CTLZ(r1, r0)
# define ctor(r0, r1) _ctor(_jit, r0, r1)
static void _ctor(jit_state_t*, jit_int32_t, jit_int32_t);
# define ctzr(r0, r1) CTTZ(r1, r0)
# define addr(r0,r1,r2) ADDQ(r1,r2,r0)
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@@ -622,21 +635,15 @@ static void _extr_us(jit_state_t*,jit_int32_t,jit_int32_t);
static void _extr_i(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_ui(r0,r1) _extr_ui(_jit,r0,r1)
static void _extr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ul(r0,r1) _htonr_ul(_jit,r0,r1)
static void _htonr_ul(jit_state_t*,jit_int32_t,jit_int32_t);
# else
# define htonr_us(r0,r1) extr_us(r0,r1)
# define htonr_ui(r0,r1) extr_ui(r0,r1)
# define htonr_ul(r0,r1) movr(r0,r1)
# endif
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ul(r0,r1) _bswapr_ul(_jit,r0,r1)
static void _bswapr_ul(jit_state_t*,jit_int32_t,jit_int32_t);
# define jmpr(r0) JMP(_R31_REGNO,r0,0)
# define jmpi(i0) _jmpi(_jit,i0)
static void _jmpi(jit_state_t*, jit_word_t);
static jit_word_t _jmpi(jit_state_t*, jit_word_t);
# define jmpi_p(i0) _jmpi_p(_jit,i0)
static jit_word_t _jmpi_p(jit_state_t*, jit_word_t);
#define callr(r0) _callr(_jit,r0)
@@ -811,6 +818,48 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
return (w);
}
static void
_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
jit_word_t jump0, jump1, again, done;
jit_int32_t iscasi, r1_reg;
if ((iscasi = (r1 == _NOREG))) {
r1_reg = jit_get_reg(jit_class_gpr);
r1 = rn(r1_reg);
movi(r1, i0);
}
again = _jit->pc.w; /* AGAIN */
LDQ_L(r0, r1, 0); /* Load r0 locked */
jump0 = bner(_jit->pc.w, r0, r2); /* bne FAIL r0 r2 */
movr(r0, r3); /* Move to r0 to attempt to store */
STQ_C(r0, r1, 0); /* r0 is an in/out argument */
jump1 = _jit->pc.w;
BEQ(r0, 0); /* beqi AGAIN r0 0 */
patch_at(jump1, again);
jump1 = _jit->pc.w;
BR(_R31_REGNO, 0); /* r0 set to 1 if store succeeded */
patch_at(jump0, _jit->pc.w); /* FAIL: */
movi(r0, 0); /* Already locked */
patch_at(jump1, _jit->pc.w);
if (iscasi)
jit_unget_reg(r1_reg);
}
static void
_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
comr(r0, r1);
clzr(r0, r0);
}
static void
_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
comr(r0, r1);
ctzr(r0, r0);
}
static void
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
@@ -2453,7 +2502,7 @@ _extr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
}
static void
_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
@@ -2465,7 +2514,7 @@ _htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
}
static void
_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
jit_int32_t t1;
@@ -2491,7 +2540,7 @@ _htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
}
static void
_htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
jit_int32_t t1;
@@ -2514,7 +2563,7 @@ _htonr_ul(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
jit_unget_reg(t0);
}
static void
static jit_word_t
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t w;
@@ -2524,7 +2573,8 @@ _jmpi(jit_state_t *_jit, jit_word_t i0)
if (_s21_p(d))
BR(_R31_REGNO, d);
else
(void)jmpi_p(i0);
w = jmpi_p(i0);
return (w);
}
static jit_word_t
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2019 Free Software Foundation, Inc.
* Copyright (C) 2014-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
+162 -112
View File
@@ -1,20 +1,23 @@
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 76
#define JIT_INSTR_MAX 88
0, /* data */
0, /* live */
4, /* align */
12, /* align */
0, /* save */
0, /* load */
4, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
76, /* prolog */
88, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -22,11 +25,23 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
20, /* va_start */
24, /* va_arg */
44, /* va_arg_d */
0, /* va_end */
4, /* addr */
32, /* addi */
@@ -47,18 +62,18 @@
56, /* qmuli */
12, /* qmulr_u */
32, /* qmuli_u */
48, /* divr */
72, /* divi */
48, /* divr_u */
72, /* divi_u */
56, /* qdivr */
56, /* qdivi */
56, /* qdivr_u */
56, /* qdivi_u */
48, /* remr */
72, /* remi */
48, /* remr_u */
72, /* remi_u */
44, /* divr */
68, /* divi */
44, /* divr_u */
68, /* divi_u */
52, /* qdivr */
52, /* qdivi */
52, /* qdivr_u */
52, /* qdivi_u */
44, /* remr */
68, /* remi */
44, /* remr_u */
68, /* remi_u */
4, /* andr */
32, /* andi */
4, /* orr */
@@ -95,12 +110,19 @@
12, /* nei */
4, /* movr */
32, /* movi */
4, /* movnr */
4, /* movzr */
32, /* casr */
60, /* casi */
8, /* extr_c */
8, /* extr_uc */
8, /* extr_s */
8, /* extr_us */
8, /* extr_i */
8, /* extr_ui */
16, /* bswapr_us */
36, /* bswapr_ui */
36, /* bswapr_ul */
16, /* htonr_us */
36, /* htonr_ui */
36, /* htonr_ul */
@@ -119,19 +141,19 @@
4, /* ldr_l */
32, /* ldi_l */
16, /* ldxr_c */
12, /* ldxi_c */
44, /* ldxi_c */
8, /* ldxr_uc */
4, /* ldxi_uc */
36, /* ldxi_uc */
16, /* ldxr_s */
12, /* ldxi_s */
44, /* ldxi_s */
8, /* ldxr_us */
4, /* ldxi_us */
36, /* ldxi_us */
8, /* ldxr_i */
4, /* ldxi_i */
36, /* ldxi_i */
16, /* ldxr_ui */
12, /* ldxi_ui */
44, /* ldxi_ui */
8, /* ldxr_l */
4, /* ldxi_l */
36, /* ldxi_l */
4, /* str_c */
32, /* sti_c */
4, /* str_s */
@@ -141,13 +163,13 @@
4, /* str_l */
32, /* sti_l */
8, /* stxr_c */
4, /* stxi_c */
36, /* stxi_c */
8, /* stxr_s */
4, /* stxi_s */
36, /* stxi_s */
8, /* stxr_i */
4, /* stxi_i */
36, /* stxi_i */
8, /* stxr_l */
4, /* stxi_l */
36, /* stxi_l */
8, /* bltr */
8, /* blti */
8, /* bltr_u */
@@ -188,18 +210,42 @@
32, /* bxsubi */
16, /* bxsubr_u */
16, /* bxsubi_u */
0, /* jmpr */
36, /* jmpi */
4, /* jmpr */
4, /* jmpi */
8, /* callr */
36, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -207,93 +253,93 @@
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
68, /* epilog */
76, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
8, /* addr_f */
32, /* addi_f */
40, /* addi_f */
8, /* subr_f */
32, /* subi_f */
32, /* rsbi_f */
40, /* subi_f */
40, /* rsbi_f */
8, /* mulr_f */
32, /* muli_f */
40, /* muli_f */
8, /* divr_f */
32, /* divi_f */
40, /* divi_f */
4, /* negr_f */
4, /* absr_f */
8, /* sqrtr_f */
32, /* ltr_f */
56, /* lti_f */
64, /* lti_f */
32, /* ler_f */
56, /* lei_f */
64, /* lei_f */
32, /* eqr_f */
56, /* eqi_f */
64, /* eqi_f */
32, /* ger_f */
56, /* gei_f */
64, /* gei_f */
32, /* gtr_f */
56, /* gti_f */
64, /* gti_f */
32, /* ner_f */
56, /* nei_f */
64, /* nei_f */
32, /* unltr_f */
56, /* unlti_f */
64, /* unlti_f */
32, /* unler_f */
56, /* unlei_f */
64, /* unlei_f */
32, /* uneqr_f */
56, /* uneqi_f */
64, /* uneqi_f */
32, /* unger_f */
56, /* ungei_f */
64, /* ungei_f */
32, /* ungtr_f */
56, /* ungti_f */
64, /* ungti_f */
32, /* ltgtr_f */
56, /* ltgti_f */
64, /* ltgti_f */
20, /* ordr_f */
44, /* ordi_f */
52, /* ordi_f */
20, /* unordr_f */
44, /* unordi_f */
52, /* unordi_f */
16, /* truncr_f_i */
16, /* truncr_f_l */
12, /* extr_f */
4, /* extr_d_f */
4, /* movr_f */
24, /* movi_f */
32, /* movi_f */
4, /* ldr_f */
32, /* ldi_f */
8, /* ldxr_f */
4, /* ldxi_f */
36, /* ldxi_f */
4, /* str_f */
32, /* sti_f */
8, /* stxr_f */
4, /* stxi_f */
36, /* stxi_f */
24, /* bltr_f */
48, /* blti_f */
56, /* blti_f */
24, /* bler_f */
48, /* blei_f */
56, /* blei_f */
24, /* beqr_f */
48, /* beqi_f */
56, /* beqi_f */
24, /* bger_f */
48, /* bgei_f */
56, /* bgei_f */
24, /* bgtr_f */
48, /* bgti_f */
56, /* bgti_f */
28, /* bner_f */
52, /* bnei_f */
60, /* bnei_f */
28, /* bunltr_f */
52, /* bunlti_f */
60, /* bunlti_f */
28, /* bunler_f */
52, /* bunlei_f */
60, /* bunlei_f */
28, /* buneqr_f */
52, /* buneqi_f */
60, /* buneqi_f */
28, /* bunger_f */
52, /* bungei_f */
60, /* bungei_f */
28, /* bungtr_f */
52, /* bungti_f */
60, /* bungti_f */
28, /* bltgtr_f */
52, /* bltgti_f */
60, /* bltgti_f */
12, /* bordr_f */
36, /* bordi_f */
44, /* bordi_f */
12, /* bunordr_f */
36, /* bunordi_f */
44, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
@@ -304,87 +350,87 @@
0, /* putargr_d */
0, /* putargi_d */
8, /* addr_d */
28, /* addi_d */
40, /* addi_d */
8, /* subr_d */
28, /* subi_d */
28, /* rsbi_d */
40, /* subi_d */
40, /* rsbi_d */
8, /* mulr_d */
28, /* muli_d */
40, /* muli_d */
8, /* divr_d */
28, /* divi_d */
40, /* divi_d */
4, /* negr_d */
4, /* absr_d */
8, /* sqrtr_d */
32, /* ltr_d */
52, /* lti_d */
64, /* lti_d */
32, /* ler_d */
52, /* lei_d */
64, /* lei_d */
32, /* eqr_d */
52, /* eqi_d */
64, /* eqi_d */
32, /* ger_d */
52, /* gei_d */
64, /* gei_d */
32, /* gtr_d */
52, /* gti_d */
64, /* gti_d */
32, /* ner_d */
52, /* nei_d */
64, /* nei_d */
32, /* unltr_d */
52, /* unlti_d */
64, /* unlti_d */
32, /* unler_d */
52, /* unlei_d */
64, /* unlei_d */
32, /* uneqr_d */
52, /* uneqi_d */
64, /* uneqi_d */
32, /* unger_d */
52, /* ungei_d */
64, /* ungei_d */
32, /* ungtr_d */
52, /* ungti_d */
64, /* ungti_d */
32, /* ltgtr_d */
52, /* ltgti_d */
64, /* ltgti_d */
20, /* ordr_d */
40, /* ordi_d */
52, /* ordi_d */
20, /* unordr_d */
40, /* unordi_d */
52, /* unordi_d */
16, /* truncr_d_i */
16, /* truncr_d_l */
12, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
20, /* movi_d */
32, /* movi_d */
4, /* ldr_d */
32, /* ldi_d */
8, /* ldxr_d */
4, /* ldxi_d */
36, /* ldxi_d */
4, /* str_d */
32, /* sti_d */
8, /* stxr_d */
4, /* stxi_d */
36, /* stxi_d */
24, /* bltr_d */
44, /* blti_d */
56, /* blti_d */
24, /* bler_d */
44, /* blei_d */
56, /* blei_d */
24, /* beqr_d */
44, /* beqi_d */
56, /* beqi_d */
24, /* bger_d */
44, /* bgei_d */
56, /* bgei_d */
24, /* bgtr_d */
44, /* bgti_d */
56, /* bgti_d */
28, /* bner_d */
48, /* bnei_d */
60, /* bnei_d */
28, /* bunltr_d */
48, /* bunlti_d */
60, /* bunlti_d */
28, /* bunler_d */
48, /* bunlei_d */
60, /* bunlei_d */
28, /* buneqr_d */
48, /* buneqi_d */
60, /* buneqi_d */
28, /* bunger_d */
48, /* bungei_d */
60, /* bungei_d */
28, /* bungtr_d */
48, /* bungti_d */
60, /* bungti_d */
28, /* bltgtr_d */
48, /* bltgti_d */
60, /* bltgti_d */
12, /* bordr_d */
32, /* bordi_d */
44, /* bordi_d */
12, /* bunordr_d */
32, /* bunordi_d */
44, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
@@ -399,4 +445,8 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
8, /* clo */
4, /* clz */
8, /* cto */
4, /* ctz */
#endif /* __WORDSIZE */
+95 -38
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2019 Free Software Foundation, Inc.
* Copyright (C) 2014-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -246,20 +246,18 @@ _jit_ret(jit_state_t *_jit)
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
_jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
jit_live(JIT_RET);
jit_code_inc_synth_w(code, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
_jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_inc_synth_w(reti, u);
jit_code_inc_synth_w(code, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
@@ -319,7 +317,7 @@ _jit_epilog(jit_state_t *_jit)
jit_bool_t
_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
{
if (u->code == jit_code_arg)
if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
return (jit_arg_reg_p(u->u.w));
assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
return (jit_arg_f_reg_p(u->u.w));
@@ -361,18 +359,22 @@ _jit_va_push(jit_state_t *_jit, jit_int32_t u)
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
_jit_arg(jit_state_t *_jit, jit_code_t code)
{
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function != NULL);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if STRONG_TYPE_CHECKING
assert(code >= jit_code_arg_c && code <= jit_code_arg);
#endif
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
offset = _jitc->function->self.size;
_jitc->function->self.size += 8;
}
node = jit_new_node_ww(jit_code_arg, offset,
node = jit_new_node_ww(code, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
@@ -417,7 +419,7 @@ _jit_arg_d(jit_state_t *_jit)
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _A0 - v->u.w);
@@ -429,7 +431,7 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _A0 - v->u.w);
@@ -441,7 +443,7 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _A0 - v->u.w);
@@ -453,7 +455,7 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _A0 - v->u.w);
@@ -465,7 +467,7 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _A0 - v->u.w);
@@ -477,7 +479,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _A0 - v->u.w);
@@ -489,7 +491,7 @@ _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_l);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _A0 - v->u.w);
@@ -499,10 +501,10 @@ _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u);
else
@@ -511,11 +513,11 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_A0 - v->u.w, u);
else {
@@ -610,10 +612,10 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
_jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargr, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_A0 - _jitc->function->call.argi, u);
@@ -627,11 +629,11 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
}
void
_jit_pushargi(jit_state_t *_jit, jit_int64_t u)
_jit_pushargi(jit_state_t *_jit, jit_int64_t u, jit_code_t code)
{
jit_int32_t regno;
assert(_jitc->function != NULL);
jit_inc_synth_w(pushargi, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_A0 - _jitc->function->call.argi, u);
@@ -863,6 +865,7 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node;
jit_uint8_t *data;
jit_word_t word;
jit_function_t func;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
@@ -978,11 +981,13 @@ _emit_code(jit_state_t *_jit)
jit_regarg_set(node, value);
switch (node->code) {
case jit_code_align:
assert(!(node->u.w & (node->u.w - 1)) &&
node->u.w <= sizeof(jit_word_t));
if (node->u.w == sizeof(jit_word_t) &&
(word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
nop(sizeof(jit_word_t) - word);
/* Must align to a power of two */
assert(!(node->u.w & (node->u.w - 1)));
if ((word = _jit->pc.w & (node->u.w - 1)))
nop(node->u.w - word);
break;
case jit_code_skip:
nop((node->u.w + 3) & ~3);
break;
case jit_code_note: case jit_code_name:
node->u.w = _jit->pc.w;
@@ -1086,12 +1091,25 @@ _emit_code(jit_state_t *_jit)
case_rr(hton, _us);
case_rr(hton, _ui);
case_rr(hton, _ul);
case_rr(bswap, _us);
case_rr(bswap, _ui);
case_rr(bswap, _ul);
case_rr(ext, _c);
case_rr(ext, _uc);
case_rr(ext, _s);
case_rr(ext, _us);
case_rr(ext, _i);
case_rr(ext, _ui);
case jit_code_casr:
casr(rn(node->u.w), rn(node->v.w),
rn(node->w.q.l), rn(node->w.q.h));
break;
case jit_code_casi:
casi(rn(node->u.w), node->v.w,
rn(node->w.q.l), rn(node->w.q.h));
break;
case_rrr(movn,);
case_rrr(movz,);
case_rr(mov,);
case jit_code_movi:
if (node->flag & jit_flag_node) {
@@ -1112,6 +1130,10 @@ _emit_code(jit_state_t *_jit)
break;
case_rr(neg,);
case_rr(com,);
case_rr(clo,);
case_rr(clz,);
case_rr(cto,);
case_rr(ctz,);
case_rrr(lt,);
case_rrw(lt,);
case_rrr(lt, _u);
@@ -1349,7 +1371,12 @@ _emit_code(jit_state_t *_jit)
if (temp->flag & jit_flag_patch)
jmpi(temp->u.w);
else {
word = jmpi_p(_jit->pc.w);
word = _jit->code.length -
(_jit->pc.uc - _jit->code.ptr);
if (_s21_p(word))
word = jmpi(_jit->pc.w);
else
word = jmpi_p(_jit->pc.w);
patch(word, node);
}
}
@@ -1378,6 +1405,7 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
memcpy(&undo.func, _jitc->function, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
@@ -1398,6 +1426,16 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
/* undo.func.self.aoff and undo.func.regset should not
* be undone, as they will be further updated, and are
* the reason of the undo. */
undo.func.self.aoff = _jitc->function->frame +
_jitc->function->self.aoff;
/* allocar information also does not need to be undone */
undo.func.aoffoff = _jitc->function->aoffoff;
undo.func.allocar = _jitc->function->allocar;
jit_regset_set(&undo.func.regset, &_jitc->function->regset);
memcpy(_jitc->function, &undo.func, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
@@ -1422,11 +1460,18 @@ _emit_code(jit_state_t *_jit)
case jit_code_live: case jit_code_ellipsis:
case jit_code_va_push:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_c: case jit_code_arg_s:
case jit_code_arg_i: case jit_code_arg_l:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_c: case jit_code_reti_c:
case jit_code_retr_uc: case jit_code_reti_uc:
case jit_code_retr_s: case jit_code_reti_s:
case jit_code_retr_us: case jit_code_reti_us:
case jit_code_retr_i: case jit_code_reti_i:
case jit_code_retr_ui: case jit_code_reti_ui:
case jit_code_retr_l: case jit_code_reti_l:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
@@ -1434,10 +1479,22 @@ _emit_code(jit_state_t *_jit)
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_c: case jit_code_putargi_c:
case jit_code_putargr_uc: case jit_code_putargi_uc:
case jit_code_putargr_s: case jit_code_putargi_s:
case jit_code_putargr_us: case jit_code_putargi_us:
case jit_code_putargr_i: case jit_code_putargi_i:
case jit_code_putargr_ui: case jit_code_putargi_ui:
case jit_code_putargr_l: case jit_code_putargi_l:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_c: case jit_code_pushargi_c:
case jit_code_pushargr_uc: case jit_code_pushargi_uc:
case jit_code_pushargr_s: case jit_code_pushargi_s:
case jit_code_pushargr_us: case jit_code_pushargi_us:
case jit_code_pushargr_i: case jit_code_pushargi_i:
case jit_code_pushargr_ui: case jit_code_pushargi_ui:
case jit_code_pushargr_l: case jit_code_pushargi_l:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
+420 -81
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -36,8 +36,8 @@
# define jit_armv5_p() (jit_cpu.version >= 5)
# define jit_armv5e_p() (jit_cpu.version > 5 || (jit_cpu.version == 5 && jit_cpu.extend))
# define jit_armv6_p() (jit_cpu.version >= 6)
# define jit_armv7r_p() 0
# define stack_framesize 48
# define jit_armv7_p() (jit_cpu.version >= 7)
# define jit_armv7r_p() (jit_cpu.version > 7 || (jit_cpu.version == 7 && jit_cpu.extend))
extern int __aeabi_idivmod(int, int);
extern unsigned __aeabi_uidivmod(unsigned, unsigned);
# define _R0_REGNO 0x00
@@ -140,8 +140,12 @@ extern unsigned __aeabi_uidivmod(unsigned, unsigned);
# define THUMB2_UMULL 0xfba00000
# define ARM_SMULL 0x00c00090
# define THUMB2_SMULL 0xfb800000
/* >> ARMv7r */
# define ARM_SDIV 0x07100010
# define ARM_UDIV 0x07300010
# define THUMB2_SDIV 0xfb90f0f0
# define THUMB2_UDIV 0xfbb0f0f0
/* << ARMv7r */
# define ARM_AND 0x00000000
# define THUMB_AND 0x4000
# define THUMB2_AND 0xea000000
@@ -179,7 +183,29 @@ extern unsigned __aeabi_uidivmod(unsigned, unsigned);
# define ARM_XTR8 0x00000400 /* ?xt? rotate 8 bits */
# define ARM_XTR16 0x00000800 /* ?xt? rotate 16 bits */
# define ARM_XTR24 0x00000c00 /* ?xt? rotate 24 bits */
# define ARM_LDREX 0x01900090
# define THUMB2_LDREX 0xe8500000
# define ARM_STREX 0x01800090
# define THUMB2_STREX 0xe8400000
/* << ARMv6* */
/* >> ARMv6t2 */
# define THUMB2_CLZ 0xfab0f080
# define THUMB2_RBIT 0xfa90f0a0
# define ARM_RBIT 0x06f00030
/* << ARMv6t2 */
# define ARM_CLZ 0x01600010
/* >> ARMv7 */
# define ARM_DMB 0xf57ff050
# define THUMB2_DMB 0xf3bf8f50
# define DMB_SY 0xf
# define DMB_ST 0xe
# define DMB_ISH 0xb
# define DMB_ISHST 0xa
# define DMB_NSH 0x7
# define DMB_NSHT 0x6
# define DMB_OSH 0x3
# define DMB_OSHST 0x2
/* << ARMv7 */
# define ARM_SHIFT 0x01a00000
# define ARM_R 0x00000010 /* register shift */
# define ARM_LSL 0x00000000
@@ -399,6 +425,12 @@ static void _tcit(jit_state_t*,unsigned int,int);
static void _tpp(jit_state_t*,int,int);
# define torl(o,rn,im) _torl(_jit,o,rn,im)
static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define DMB(im) dmb(im)
# define T2_DMB(im) tdmb(im)
# define dmb(im) _dmb(_jit, im)
static void _dmb(jit_state_t *_jit, int im);
# define tdmb(im) _tdmb(_jit, im)
static void _tdmb(jit_state_t *_jit, int im);
# define CC_MOV(cc,rd,rm) corrr(cc,ARM_MOV,0,rd,rm)
# define MOV(rd,rm) CC_MOV(ARM_CC_AL,rd,rm)
# define T1_MOV(rd,rm) is(THUMB_MOV|((_u4(rd)&8)<<4)|(_u4(rm)<<3)|(rd&7))
@@ -424,6 +456,12 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define NOT(rd,rm) CC_NOT(ARM_CC_AL,rd,rm)
# define T1_NOT(rd,rm) T1_MVN(rd,rm)
# define T2_NOT(rd,rm) T2_MVN(rd,rm)
# define T2_CLZ(rd,rm) torrr(THUMB2_CLZ,rm,rd,rm)
# define CC_CLZ(cc,rd,rm) corrrr(cc,ARM_CLZ,_R15_REGNO,rd,_R15_REGNO,rm)
# define CLZ(rd,rm) CC_CLZ(ARM_CC_AL,rd,rm)
# define T2_RBIT(rd,rm) torrr(THUMB2_RBIT,rm,rd,rm)
# define CC_RBIT(cc,rd,rm) corrrr(cc,ARM_RBIT,_R15_REGNO,rd,_R15_REGNO,rm)
# define RBIT(rd,rm) CC_RBIT(ARM_CC_AL,rd,rm)
# define NOP() MOV(_R0_REGNO, _R0_REGNO)
# define T1_NOP() is(0xbf00)
# define CC_ADD(cc,rd,rn,rm) corrr(cc,ARM_ADD,rn,rd,rm)
@@ -501,6 +539,10 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CC_UMULL(cc,rl,rh,rn,rm) corrrr(cc,ARM_UMULL,rh,rl,rm,rn)
# define UMULL(rl,rh,rn,rm) CC_UMULL(ARM_CC_AL,rl,rh,rn,rm)
# define T2_UMULL(rl,rh,rn,rm) torrrr(THUMB2_UMULL,rn,rl,rh,rm)
# define CC_SDIV(cc,rd,rn,rm) corrrr(cc,ARM_SDIV,rd,15,rn,rm)
# define SDIV(rd,rn,rm) CC_SDIV(ARM_CC_AL,rd,rm,rn)
# define CC_UDIV(cc,rd,rn,rm) corrrr(cc,ARM_UDIV,rd,15,rn,rm)
# define UDIV(rd,rn,rm) CC_UDIV(ARM_CC_AL,rd,rm,rn)
# define T2_SDIV(rd,rn,rm) torrr(THUMB2_SDIV,rn,rd,rm)
# define T2_UDIV(rd,rn,rm) torrr(THUMB2_UDIV,rn,rd,rm)
# define CC_AND(cc,rd,rn,rm) corrr(cc,ARM_AND,rn,rd,rm)
@@ -612,7 +654,7 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CMNI(rn,im) CC_CMNI(ARM_CC_AL,rn,im)
# define T2_CMNI(rn,im) torri(THUMB2_CMNI,rn,_R15_REGNO,im)
# define CC_TST(cc,rn,rm) corrr(cc,ARM_TST,rn,r0,rm)
# define TST(rn,rm) CC_TST(ARM_CC_AL,rn,rm)
# define TST(rn,rm) corrr(ARM_CC_AL,ARM_TST,rn,0,rm)
# define T1_TST(rn,rm) is(THUMB_TST|(_u3(rm)<<3)|_u3(rn))
# define T2_TST(rn,rm) torrr(THUMB2_TST,rn,_R15_REGNO,rm)
# define CC_TSTI(cc,rn,im) corri(cc,ARM_TST|ARM_I,rn,0,im)
@@ -718,6 +760,9 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CC_LDRDIN(cc,rt,rn,im) corri8(cc,ARM_LDRDI,rn,rt,im)
# define LDRDIN(rt,rn,im) CC_LDRDIN(ARM_CC_AL,rt,rn,im)
# define T2_LDRDIN(rt,rt2,rn,im) torrri8(THUMB2_LDRDI,rn,rt,rt2,im)
# define CC_LDREX(cc,rt,rn) corrrr(cc,ARM_LDREX,rn,rt,0xf,0xf)
# define LDREX(rt,rn) CC_LDREX(ARM_CC_AL,rt,rn)
# define T2_LDREX(rt,rn,im) torrri8(THUMB2_LDREX,rn,rt,0xf,im)
# define CC_STRB(cc,rt,rn,rm) corrr(cc,ARM_STRB|ARM_P,rn,rt,rm)
# define STRB(rt,rn,rm) CC_STRB(ARM_CC_AL,rt,rn,rm)
# define T1_STRB(rt,rn,rm) is(THUMB_STRB|(_u3(rm)<<6)|(_u3(rn)<<3)|_u3(rt))
@@ -771,6 +816,9 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CC_STRDIN(cc,rt,rn,im) corri8(cc,ARM_STRDI,rn,rt,im)
# define STRDIN(rt,rn,im) CC_STRDIN(ARM_CC_AL,rt,rn,im)
# define T2_STRDIN(rt,rt2,rn,im) torrri8(THUMB2_STRDI,rn,rt,rt2,im)
# define CC_STREX(cc,rd,rt,rn) corrrr(cc,ARM_STREX,rn,rd,0xf,rt)
# define STREX(rd,rt,rn) CC_STREX(ARM_CC_AL,rd,rt,rn)
# define T2_STREX(rd,rt,rn,im) torrri8(THUMB2_STREX,rn,rt,rd,im)
# define CC_LDMIA(cc,rn,im) corl(cc,ARM_M|ARM_M_L|ARM_M_I,rn,im)
# define LDMIA(rn,im) CC_LDMIA(ARM_CC_AL,rn,im)
# define CC_LDM(cc,rn,im) CC_LDMIA(cc,rn,im)
@@ -823,6 +871,8 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define T2_POP(im) tpp(THUMB2_POP,im)
# define jit_get_reg_args() \
do { \
CHECK_REG_ARGS(); \
jit_check_frame(); \
(void)jit_get_reg(_R0|jit_class_named|jit_class_gpr); \
(void)jit_get_reg(_R1|jit_class_named|jit_class_gpr); \
(void)jit_get_reg(_R2|jit_class_named|jit_class_gpr); \
@@ -843,10 +893,27 @@ static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
# define movi_p(r0,i0) _movi_p(_jit,r0,i0)
static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_word_t);
#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
# define comr(r0,r1) _comr(_jit,r0,r1)
static void _comr(jit_state_t*,jit_int32_t,jit_int32_t);
# define negr(r0,r1) _negr(_jit,r0,r1)
static void _negr(jit_state_t*,jit_int32_t,jit_int32_t);
# define clor(r0, r1) _clor(_jit, r0, r1)
static void _clor(jit_state_t*, jit_int32_t, jit_int32_t);
# define clzr(r0, r1) _clzr(_jit, r0, r1)
static void _clzr(jit_state_t*, jit_int32_t, jit_int32_t);
# define ctor(r0, r1) _ctor(_jit, r0, r1)
static void _ctor(jit_state_t*, jit_int32_t, jit_int32_t);
# define ctzr(r0, r1) _ctzr(_jit, r0, r1)
static void _ctzr(jit_state_t*, jit_int32_t, jit_int32_t);
# define addr(r0,r1,r2) _addr(_jit,r0,r1,r2)
static void _addr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
@@ -1091,15 +1158,10 @@ static void _sti_i(jit_state_t*,jit_word_t,jit_int32_t);
static void _stxr_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# define stxi_i(r0,r1,i0) _stxi_i(_jit,r0,r1,i0)
static void _stxi_i(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# else
# define htonr_us(r0,r1) extr_us(r0,r1)
# define htonr(r0,r1) movr(r0,r1)
# endif
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_c(r0,r1) _extr_c(_jit,r0,r1)
static void _extr_c(jit_state_t*,jit_int32_t,jit_int32_t);
# define extr_uc(r0,r1) _extr_uc(_jit,r0,r1)
@@ -1114,10 +1176,10 @@ static void _prolog(jit_state_t*,jit_node_t*);
static void _epilog(jit_state_t*,jit_node_t*);
# define callr(r0) _callr(_jit,r0)
static void _callr(jit_state_t*,jit_int32_t);
# define calli(i0) _calli(_jit,i0)
static void _calli(jit_state_t*,jit_word_t);
# define calli_p(i0) _calli_p(_jit,i0)
static jit_word_t _calli_p(jit_state_t*,jit_word_t);
# define calli(i0,i1) _calli(_jit,i0,i1)
static void _calli(jit_state_t*,jit_word_t,jit_bool_t);
# define calli_p(i0,i1) _calli_p(_jit,i0,i1)
static jit_word_t _calli_p(jit_state_t*,jit_word_t,jit_bool_t);
# define vastart(r0) _vastart(_jit, r0)
static void _vastart(jit_state_t*, jit_int32_t);
# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
@@ -1493,7 +1555,7 @@ _tpp(jit_state_t *_jit, int o, int im)
assert(!(o & 0x0000ffff));
if (o == THUMB2_PUSH)
assert(!(im & 0x8000));
assert(__builtin_popcount(im & 0x1fff) > 1);
assert(__builtin_popcount(im & 0x7fff) > 1);
thumb.i = o|im;
iss(thumb.s[0], thumb.s[1]);
}
@@ -1509,6 +1571,22 @@ _torl(jit_state_t *_jit, int o, int rn, int im)
iss(thumb.s[0], thumb.s[1]);
}
static void
_dmb(jit_state_t *_jit, int im)
{
assert(!(im & 0xfffffff0));
ii(ARM_DMB|im);
}
static void
_tdmb(jit_state_t *_jit, int im)
{
jit_thumb_t thumb;
assert(!(im & 0xfffffff0));
thumb.i = THUMB2_DMB | im;
iss(thumb.s[0], thumb.s[1]);
}
static void
_nop(jit_state_t *_jit, jit_int32_t i0)
{
@@ -1582,6 +1660,86 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
return (w);
}
static void
_movznr(jit_state_t *_jit, int ct, jit_int32_t r0,
jit_int32_t r1, jit_int32_t r2)
{
if (jit_thumb_p()) {
if (r2 < 7)
T1_CMPI(r2, 0);
else
T2_CMPI(r2, 0);
IT(ct);
T1_MOV(r0, r1);
} else {
CMPI(r2, 0);
CC_MOV(ct, r0, r1);
}
}
static void
_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
_movznr(_jit, ARM_CC_NE, r0, r1, r2);
}
static void
_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
_movznr(_jit, ARM_CC_EQ, r0, r1, r2);
}
static void
_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
jit_int32_t r1_reg, iscasi;
jit_word_t retry, done, jump0, jump1;
if (!jit_armv7_p())
fallback_casx(r0, r1, r2, r3, i0);
else {
if ((iscasi = (r1 == _NOREG))) {
r1_reg = jit_get_reg(jit_class_gpr);
r1 = rn(r1_reg);
movi(r1, i0);
}
if (jit_thumb_p()) {
T2_DMB(DMB_ISH);
/* retry: */
retry = _jit->pc.w;
T2_LDREX(r0, r1, 0);
eqr(r0, r0, r2);
jump0 = beqi(_jit->pc.w, r0, 0); /* beqi done r0 0 */
T2_STREX(r0, r3, r1, 0);
jump1 = bnei(_jit->pc.w, r0, 0); /* bnei retry r0 0 */
/* r0 = 0 if memory updated, 1 otherwise */
xori(r0, r0, 1);
/* done: */
done = _jit->pc.w;
T2_DMB(DMB_ISH);
}
else {
DMB(DMB_ISH);
/* retry: */
retry = _jit->pc.w;
LDREX(r0, r1);
eqr(r0, r0, r2);
jump0 = beqi(_jit->pc.w, r0, 0); /* beqi done r0 0 */
STREX(r0, r3, r1);
jump1 = bnei(_jit->pc.w, r0, 0); /* bnei retry r0 0 */
/* r0 = 0 if memory updated, 1 otherwise */
xori(r0, r0, 1);
/* done: */
done = _jit->pc.w;
DMB(DMB_ISH);
}
patch_at(arm_patch_jump, jump0, done);
patch_at(arm_patch_jump, jump1, retry);
if (iscasi)
jit_unget_reg(r1_reg);
}
}
static void
_comr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
@@ -1608,6 +1766,53 @@ _negr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
RSBI(r0, r1, 0);
}
static void
_clzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (!jit_thumb_p() && jit_armv5e_p())
CLZ(r0, r1);
else if (jit_thumb_p() && jit_armv7_p()) { /* armv6t2 actually */
T2_CLZ(r0, r1);
}
else
fallback_clz(r0, r0);
}
static void
_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
comr(r0, r1);
clzr(r0, r0);
}
static void
_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_armv7_p()) { /* armv6t2 actually */
if (jit_thumb_p())
T2_RBIT(r0, r1);
else
RBIT(r0, r1);
clor(r0, r0);
}
else
fallback_cto(r0, r1);
}
static void
_ctzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_armv7_p()) { /* armv6t2 actually */
if (jit_thumb_p())
T2_RBIT(r0, r1);
else
RBIT(r0, r1);
clzr(r0, r0);
}
else
fallback_ctz(r0, r1);
}
static void
_addr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
@@ -2103,8 +2308,12 @@ _divrem(jit_state_t *_jit, int div, int sign,
static void
_divr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (jit_armv7r_p() && jit_thumb_p())
T2_SDIV(r0, r1, r2);
if (jit_armv7r_p()) {
if (jit_thumb_p())
T2_SDIV(r0, r1, r2);
else
SDIV(r0, r1, r2);
}
else
divrem(1, 1, r0, r1, r2);
}
@@ -2122,8 +2331,12 @@ _divi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
static void
_divr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
if (jit_armv7r_p() && jit_thumb_p())
T2_UDIV(r0, r1, r2);
if (jit_armv7r_p()) {
if (jit_thumb_p())
T2_UDIV(r0, r1, r2);
else
UDIV(r0, r1, r2);
}
else
divrem(1, 0, r0, r1, r2);
}
@@ -2183,7 +2396,23 @@ _iqdivi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
static void
_remr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
divrem(0, 1, r0, r1, r2);
if (jit_armv7r_p()) {
jit_int32_t reg;
if (r0 == r1 || r0 == r2) {
reg = jit_get_reg(jit_class_gpr);
divr(rn(reg), r1, r2);
mulr(rn(reg), r2, rn(reg));
subr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
else {
divr(r0, r1, r2);
mulr(r0, r2, r0);
subr(r0, r1, r0);
}
}
else
divrem(0, 1, r0, r1, r2);
}
static void
@@ -2199,7 +2428,23 @@ _remi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
static void
_remr_u(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
divrem(0, 0, r0, r1, r2);
if (jit_armv7r_p()) {
jit_int32_t reg;
if (r0 == r1 || r0 == r2) {
reg = jit_get_reg(jit_class_gpr);
divr_u(rn(reg), r1, r2);
mulr(rn(reg), r2, rn(reg));
subr(r0, r1, rn(reg));
jit_unget_reg(reg);
}
else {
divr_u(r0, r1, r2);
mulr(r0, r2, r0);
subr(r0, r1, r0);
}
}
else
divrem(0, 0, r0, r1, r2);
}
static void
@@ -2612,8 +2857,8 @@ _jmpi_p(jit_state_t *_jit, jit_word_t i0, jit_bool_t i1)
jit_word_t w;
jit_word_t d;
jit_int32_t reg;
/* i1 means jump is reachable in signed 24 bits */
if (i1) {
/* Assume jump is not longer than 23 bits if inside jit */
w = _jit->pc.w;
/* if thumb and in thumb mode */
if (jit_thumb_p() && _jitc->thumb) {
@@ -3576,11 +3821,9 @@ _stxi_i(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
}
}
# if __BYTE_ORDER == __LITTLE_ENDIAN
static void
_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
if (jit_thumb_p()) {
if ((r0|r1) < 8)
T1_REV(r0, r1);
@@ -3594,20 +3837,14 @@ _htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
rshi_u(r0, r0, 16);
}
else {
t0 = jit_get_reg(jit_class_gpr);
rshi(rn(t0), r1, 8);
andi(r0, r1, 0xff);
andi(rn(t0), rn(t0), 0xff);
lshi(r0, r0, 8);
orr(r0, r0, rn(t0));
jit_unget_reg(t0);
generic_bswapr_us(_jit, r0, r1);
}
}
}
/* inline glibc htonl (without register clobber) */
static void
_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_thumb_p()) {
@@ -3629,7 +3866,6 @@ _htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
}
}
}
#endif
static void
_extr_c(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
@@ -3715,14 +3951,29 @@ _callr(jit_state_t *_jit, jit_int32_t r0)
}
static void
_calli(jit_state_t *_jit, jit_word_t i0)
_calli(jit_state_t *_jit, jit_word_t i0, jit_bool_t exchange_p)
{
jit_word_t d;
jit_int32_t reg;
d = ((i0 - _jit->pc.w) >> 2) - 2;
if (!jit_exchange_p() && !jit_thumb_p() && _s24P(d))
BLI(d & 0x00ffffff);
if (!exchange_p) {
if (jit_thumb_p()) {
if (jit_exchange_p())
/* skip switch from arm to thumb
* exchange_p set to zero means a jit function
* call in the same jit code buffer */
d = ((i0 + 8 - _jit->pc.w) >> 1) - 2;
else
d = ((i0 - _jit->pc.w) >> 1) - 2;
}
else d = ((i0 - _jit->pc.w) >> 2) - 2;
if (_s24P(d)) {
if (jit_thumb_p()) T2_BLI(encode_thumb_jump(d));
else BLI(d & 0x00ffffff);
}
else goto fallback;
}
else {
fallback:
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
if (jit_thumb_p())
@@ -3734,28 +3985,44 @@ _calli(jit_state_t *_jit, jit_word_t i0)
}
static jit_word_t
_calli_p(jit_state_t *_jit, jit_word_t i0)
_calli_p(jit_state_t *_jit, jit_word_t i0, jit_bool_t i1)
{
jit_word_t w;
jit_word_t d;
jit_int32_t reg;
reg = jit_get_reg(jit_class_gpr);
w = _jit->pc.w;
movi_p(rn(reg), i0);
if (jit_thumb_p())
T1_BLX(rn(reg));
else
BLX(rn(reg));
jit_unget_reg(reg);
/* i1 means call is reachable in signed 24 bits */
if (i1) {
w = _jit->pc.w;
if (jit_thumb_p()) d = ((i0 - _jit->pc.w) >> 1) - 2;
else d = ((i0 - _jit->pc.w) >> 2) - 2;
assert(_s24P(d));
if (jit_thumb_p()) T2_BLI(encode_thumb_jump(d));
else BLI(d & 0x00ffffff);
}
else {
reg = jit_get_reg(jit_class_gpr);
w = _jit->pc.w;
movi_p(rn(reg), i0);
if (jit_thumb_p())
T1_BLX(rn(reg));
else
BLX(rn(reg));
jit_unget_reg(reg);
}
return (w);
}
static void
_prolog(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t reg;
jit_int32_t reg, mask, count;
if (_jitc->function->define_frame || _jitc->function->assume_frame) {
jit_int32_t frame = -_jitc->function->frame;
jit_check_frame();
assert(_jitc->function->self.aoff >= frame);
if (jit_swf_p())
CHECK_SWF_OFFSET();
CHECK_REG_ARGS();
if (_jitc->function->assume_frame) {
if (jit_thumb_p() && !_jitc->thumb)
_jitc->thumb = _jit->pc.w;
@@ -3768,38 +4035,66 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
_jitc->function->stack = ((_jitc->function->self.alen -
/* align stack at 8 bytes */
_jitc->function->self.aoff) + 7) & -8;
/* If this jit_check_frame() succeeds, it actually is just a need_stack,
* usually for arguments, so, allocai was not called, but pusharg*
* was called increasing stack size, for negative access offsets.
* This can be optimized for one less prolog instruction, that is,
* do not create the frame pointer, and only add _jitc->function->stack
* to sp, and on epilog, instead of moving fp to sp, just add negative
* value of _jitc->function->stack. Since this condition requires a
* large function body for excess arguments to called function, keep
* things a bit simpler for now, as this is the only place need_stack
* would be useful. */
if (_jitc->function->stack)
jit_check_frame();
for (reg = mask = count = 0; reg < jit_size(iregs); reg++) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
mask |= 1 << rn(iregs[reg]);
++count;
}
}
/* One extra register to keep stack 8 bytes aligned */
if (count & 1) {
for (reg = 4; reg < 10; reg++) {
if (!(mask & (1 << reg))) {
mask |= 1 << reg;
break;
}
}
}
if (_jitc->function->need_frame || _jitc->function->need_return)
mask |= (1 << _FP_REGNO) | (1 << _LR_REGNO);
if (!jit_swf_p() && _jitc->function->save_reg_args &&
!(_jitc->function->self.call & jit_call_varargs))
mask |= 0xf;
if (jit_thumb_p()) {
/* switch to thumb mode (better approach would be to
* ORR 1 address being called, but no clear distinction
* of what is a pointer to a jit function, or if patching
* a pointer to a jit function) */
ADDI(_R12_REGNO, _R15_REGNO, 1);
BX(_R12_REGNO);
if (jit_exchange_p()) {
ADDI(_R12_REGNO, _R15_REGNO, 1);
BX(_R12_REGNO);
}
if (!_jitc->thumb)
_jitc->thumb = _jit->pc.w;
if (jit_cpu.abi) {
if (jit_swf_p() || (_jitc->function->save_reg_args &&
(_jitc->function->self.call & jit_call_varargs)))
T2_PUSH(0xf);
T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
VPUSH_F64(_D8_REGNO, 8);
}
else {
T2_PUSH(0xf);
T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
if (mask)
T2_PUSH(mask);
}
else {
if (jit_cpu.abi) {
if (jit_swf_p() || (_jitc->function->save_reg_args &&
(_jitc->function->self.call & jit_call_varargs)))
PUSH(0xf);
PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
VPUSH_F64(_D8_REGNO, 8);
}
else {
PUSH(0xf);
PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
if (mask)
PUSH(mask);
}
movr(_FP_REGNO, _SP_REGNO);
if (_jitc->function->need_frame)
movr(_FP_REGNO, _SP_REGNO);
if (_jitc->function->stack)
subi(_SP_REGNO, _SP_REGNO, _jitc->function->stack);
if (_jitc->function->allocar) {
@@ -3813,17 +4108,41 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
static void
_epilog(jit_state_t *_jit, jit_node_t *node)
{
jit_int32_t reg, mask, count;
if (_jitc->function->assume_frame)
return;
movr(_SP_REGNO, _FP_REGNO);
if (jit_cpu.abi)
VPOP_F64(_D8_REGNO, 8);
if (jit_thumb_p())
T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
else
POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
addi(_SP_REGNO, _SP_REGNO, 16);
for (reg = mask = count = 0; reg < jit_size(iregs); reg++) {
if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg])) {
mask |= 1 << rn(iregs[reg]);
++count;
}
}
/* One extra register to keep stack 8 bytes aligned */
if (count & 1) {
for (reg = 4; reg < 10; reg++) {
if (!(mask & (1 << reg))) {
mask |= 1 << reg;
break;
}
}
}
if (_jitc->function->need_frame || _jitc->function->need_return)
mask |= (1 << _FP_REGNO) | (1 << _LR_REGNO);
if (_jitc->function->need_frame)
movr(_SP_REGNO, _FP_REGNO);
if (!jit_swf_p() && _jitc->function->save_reg_args &&
!(_jitc->function->self.call & jit_call_varargs))
addi(_SP_REGNO, _SP_REGNO, 16);
if (mask) {
if (jit_thumb_p())
T2_POP(mask);
else
POP(mask);
}
if (jit_swf_p() || (_jitc->function->save_reg_args &&
(_jitc->function->self.call & jit_call_varargs)))
addi(_SP_REGNO, _SP_REGNO, 16);
if (jit_thumb_p())
T1_BX(_LR_REGNO);
else
@@ -3841,8 +4160,7 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
* The -16 is to account for the 4 argument registers
* always saved, and _jitc->function->vagp is to account
* for declared arguments. */
addi(r0, _FP_REGNO, _jitc->function->self.size -
16 + _jitc->function->vagp);
addi(r0, _FP_REGNO, jit_selfsize() - 16 + _jitc->function->vagp);
}
static void
@@ -3869,7 +4187,28 @@ _patch_at(jit_state_t *_jit,
jit_word_t w;
} u;
u.w = instr;
if (kind == arm_patch_jump) {
if (kind == arm_patch_call) {
if (jit_thumb_p() && (jit_uword_t)instr >= _jitc->thumb) {
code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
assert((thumb.i & THUMB2_BLI) == THUMB2_BLI);
/* skip code to switch from arm to thumb mode */
if (jit_exchange_p())
d = ((label + 8 - instr) >> 1) - 2;
else
d = ((label - instr) >> 1) - 2;
assert(_s24P(d));
thumb.i = THUMB2_BLI | encode_thumb_jump(d);
thumb2code(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
}
else {
thumb.i = u.i[0];
assert((thumb.i & 0x0f000000) == ARM_BLI);
d = ((label - instr) >> 2) - 2;
assert(_s24P(d));
u.i[0] = (thumb.i & 0xff000000) | (d & 0x00ffffff);
}
}
else if (kind == arm_patch_jump) {
if (jit_thumb_p() && (jit_uword_t)instr >= _jitc->thumb) {
code2thumb(thumb.s[0], thumb.s[1], u.s[0], u.s[1]);
if ((thumb.i & THUMB2_B) == THUMB2_B) {
+95 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -564,6 +564,8 @@ _swf_ff(jit_state_t *_jit, float(*i0)(float),
jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -581,6 +583,8 @@ _swf_dd(jit_state_t *_jit, double (*i0)(double),
jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -614,6 +618,8 @@ _swf_fff(jit_state_t *_jit, float (*i0)(float, float),
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -635,6 +641,8 @@ _swf_ddd(jit_state_t *_jit, double (*i0)(double, double),
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -684,6 +692,8 @@ _swf_fff_(jit_state_t *_jit, float (*i0)(float, float),
jit_float32_t f;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.f = i1;
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -706,6 +716,8 @@ _swf_rsbi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float32_t i0)
jit_float32_t f;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.f = i0;
movi(_R0_REGNO, data.i);
if (jit_fpr_p(r1))
@@ -729,7 +741,8 @@ _swf_ddd_(jit_state_t *_jit, double (*i0)(double, double),
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.d = i1;
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
@@ -769,6 +782,8 @@ _swf_rsbi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_float64_t i0)
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.d = i0;
movi(_R0_REGNO, data.i[0]);
movi(_R1_REGNO, data.i[1]);
@@ -805,6 +820,8 @@ _swf_iff(jit_state_t *_jit, int (*i0)(float, float),
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_get_reg_args();
if (jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -823,6 +840,8 @@ _swf_idd(jit_state_t *_jit, int (*i0)(double, double),
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_get_reg_args();
if (jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -861,6 +880,8 @@ _swf_iff_(jit_state_t *_jit, int (*i0)(float, float),
jit_float32_t f;
} data;
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.f = i1;
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -881,6 +902,8 @@ _swf_idd_(jit_state_t *_jit, int (*i0)(double, double),
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.d = i1;
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
@@ -907,6 +930,8 @@ _swf_iunff(jit_state_t *_jit, int (*i0)(float, float),
{
jit_word_t instr;
jit_get_reg_args();
if (jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -952,6 +977,8 @@ _swf_iundd(jit_state_t *_jit, int (*i0)(double, double),
{
jit_word_t instr;
jit_get_reg_args();
if (jit_fpr_p(r1) || jit_fpr_p(r2))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -1033,6 +1060,8 @@ _swf_iunff_(jit_state_t *_jit, int (*i0)(float, float),
jit_float32_t f;
} data;
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.f = i1;
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -1077,6 +1106,8 @@ _swf_iundd_(jit_state_t *_jit, int (*i0)(double, double),
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
data.d = i1;
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
@@ -1135,6 +1166,8 @@ _swf_bff(jit_state_t *_jit, int (*i0)(float, float), int cc,
{
jit_word_t w, d;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
else
@@ -1168,6 +1201,8 @@ _swf_bdd(jit_state_t *_jit, int (*i0)(double, double), int cc,
{
jit_word_t w, d;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
@@ -1221,6 +1256,8 @@ _swf_bff_(jit_state_t *_jit, int (*i0)(float, float), int cc,
} data;
jit_word_t w, d;
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
data.f = i2;
if (jit_fpr_p(r0))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
@@ -1256,6 +1293,8 @@ _swf_bdd_(jit_state_t *_jit, int (*i0)(double, double), int cc,
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
data.d = i2;
if (jit_fpr_p(r0)) {
if (!jit_thumb_p() && jit_armv5e_p())
@@ -1296,6 +1335,8 @@ _swf_bunff(jit_state_t *_jit, int eq,
{
jit_word_t w, d, j0, j1;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
else
@@ -1366,6 +1407,8 @@ _swf_bundd(jit_state_t *_jit, int eq,
{
jit_word_t w, d, j0, j1;
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
@@ -1473,6 +1516,8 @@ _swf_bunff_(jit_state_t *_jit, int eq,
jit_word_t w, d, j0, j1;
data.f = i1;
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r0) + 8);
else
@@ -1541,6 +1586,8 @@ _swf_bundd_(jit_state_t *_jit, int eq,
jit_float64_t d;
} data;
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
data.d = i1;
if (jit_fpr_p(r0)) {
if (!jit_thumb_p() && jit_armv5e_p())
@@ -1622,6 +1669,8 @@ static void
_swf_extr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
movr(_R0_REGNO, r1);
swf_call(__aeabi_i2f, i2f, _R1_REGNO);
if (jit_fpr_p(r0))
@@ -1635,6 +1684,8 @@ static void
_swf_extr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
movr(_R0_REGNO, r1);
swf_call(__aeabi_i2d, i2d, _R2_REGNO);
if (jit_fpr_p(r0)) {
@@ -1656,6 +1707,8 @@ static void
_swf_extr_d_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -1680,6 +1733,8 @@ static void
_swf_extr_f_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_get_reg_args();
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -1709,6 +1764,8 @@ _swf_truncr_f_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
jit_word_t slow_not_nan;
#endif
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1))
swf_ldrin(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
else
@@ -1763,6 +1820,8 @@ _swf_truncr_d_i(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
jit_word_t slow_not_nan;
#endif
jit_get_reg_args();
if (jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p())
LDRDIN(_R0_REGNO, _FP_REGNO, swf_off(r1) + 8);
@@ -1823,6 +1882,8 @@ _swf_movr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (r0 != r1) {
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
@@ -1844,6 +1905,8 @@ _swf_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (r0 != r1) {
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (!jit_thumb_p() && jit_armv5e_p() &&
(reg = jit_get_reg_pair()) != JIT_NOREG) {
@@ -1894,6 +1957,8 @@ _swf_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
jit_float32_t f;
} data;
jit_int32_t reg;
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
data.f = i0;
if (jit_fpr_p(r0)) {
reg = jit_get_reg(jit_class_gpr);
@@ -1913,6 +1978,8 @@ _swf_movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t i0)
jit_int32_t i[2];
jit_float64_t d;
} data;
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
data.d = i0;
if (jit_fpr_p(r0)) {
if (!jit_thumb_p() && jit_armv5e_p() &&
@@ -1941,6 +2008,8 @@ static void
_swf_absr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
@@ -1966,6 +2035,8 @@ static void
_swf_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
@@ -2013,6 +2084,8 @@ static void
_swf_negr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
@@ -2038,6 +2111,8 @@ static void
_swf_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0) || jit_fpr_p(r1))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r1)) {
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
@@ -2170,6 +2245,7 @@ _swf_ldr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
ldxi_i(rn(reg), r1, 0);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
@@ -2184,6 +2260,7 @@ _swf_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
(reg = jit_get_reg_pair()) != JIT_NOREG) {
LDRDI(rn(reg), r1, 0);
@@ -2212,6 +2289,7 @@ _swf_ldi_f(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t reg;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
ldi_i(rn(reg), i0);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
@@ -2225,6 +2303,8 @@ static void
_swf_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
movi(rn(rg0), i0);
@@ -2258,6 +2338,7 @@ _swf_ldxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t reg;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
ldxr_i(rn(reg), r1, r2);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
@@ -2272,6 +2353,7 @@ _swf_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
LDRD(rn(rg0), r1, r2);
@@ -2307,6 +2389,8 @@ static void
_swf_ldxi_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (jit_fpr_p(r0))
CHECK_SWF_OFFSET();
if (jit_fpr_p(r0)) {
reg = jit_get_reg(jit_class_gpr);
ldxi_i(rn(reg), r1, i0);
@@ -2322,6 +2406,7 @@ _swf_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
((i0 >= 0 && i0 <= 255) || (i0 < 0 && i0 >= -255)) &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
@@ -2391,6 +2476,7 @@ _swf_str_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r1)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
stxi_i(0, r0, rn(reg));
@@ -2405,6 +2491,7 @@ _swf_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r1)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
(reg = jit_get_reg_pair()) != JIT_NOREG) {
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8);
@@ -2435,6 +2522,7 @@ _swf_sti_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t reg;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
sti_i(i0, rn(reg));
@@ -2449,6 +2537,7 @@ _swf_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r0)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
rg1 = jit_get_reg(jit_class_gpr);
@@ -2488,6 +2577,7 @@ _swf_stxr_f(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t reg;
if (jit_fpr_p(r2)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r2) + 8);
stxr_i(r1, r0, rn(reg));
@@ -2502,6 +2592,7 @@ _swf_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r2)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
LDRDIN(rn(rg0), _FP_REGNO, swf_off(r2) + 8);
@@ -2538,6 +2629,7 @@ _swf_stxi_f(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (jit_fpr_p(r1)) {
CHECK_SWF_OFFSET();
reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
stxi_i(i0, r0, rn(reg));
@@ -2552,6 +2644,7 @@ _swf_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t rg0, rg1;
if (jit_fpr_p(r1)) {
CHECK_SWF_OFFSET();
if (!jit_thumb_p() && jit_armv5e_p() &&
((i0 >= 0 && i0 <= 255) || (i0 < 0 && i0 >= -255)) &&
(rg0 = jit_get_reg_pair()) != JIT_NOREG) {
+286 -184
View File
@@ -1,12 +1,13 @@
#if __WORDSIZE == 32
#if defined(__ARM_PCS_VFP)
#define JIT_INSTR_MAX 48
#define JIT_INSTR_MAX 50
0, /* data */
0, /* live */
2, /* align */
14, /* align */
0, /* save */
0, /* load */
4, /* skip */
2, /* #name */
0, /* #note */
0, /* label */
@@ -15,7 +16,10 @@
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -23,8 +27,20 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
16, /* va_arg_d */
@@ -48,18 +64,18 @@
12, /* qmuli */
4, /* qmulr_u */
8, /* qmuli_u */
40, /* divr */
48, /* divi */
40, /* divr_u */
44, /* divi_u */
34, /* qdivr */
38, /* qdivi */
34, /* qdivr_u */
38, /* qdivi_u */
40, /* remr */
48, /* remi */
40, /* remr_u */
44, /* remi_u */
32, /* divr */
36, /* divi */
24, /* divr_u */
28, /* divi_u */
18, /* qdivr */
22, /* qdivi */
18, /* qdivr_u */
22, /* qdivi_u */
24, /* remr */
32, /* remi */
24, /* remr_u */
28, /* remi_u */
4, /* andr */
12, /* andi */
4, /* orr */
@@ -96,12 +112,19 @@
14, /* nei */
4, /* movr */
8, /* movi */
8, /* movnr */
8, /* movzr */
42, /* casr */
50, /* casi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
8, /* bswapr_us */
4, /* bswapr_ui */
0, /* bswapr_ul */
8, /* htonr_us */
4, /* htonr_ui */
0, /* htonr_ul */
@@ -194,13 +217,37 @@
4, /* callr */
20, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -349,7 +396,7 @@
8, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
16, /* movi_d */
32, /* movi_d */
4, /* ldr_d */
12, /* ldi_d */
8, /* ldxr_d */
@@ -363,7 +410,7 @@
12, /* bler_d */
28, /* blei_d */
12, /* beqr_d */
28, /* beqi_d */
36, /* beqi_d */
12, /* bger_d */
28, /* bgei_d */
12, /* bgtr_d */
@@ -400,17 +447,22 @@
12, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
8, /* clo */
4, /* clz */
12, /* cto */
8, /* ctz */
#endif /* __ARM_PCS_VFP */
#endif /* __WORDSIZE */
#if __WORDSIZE == 32
#if !defined(__ARM_PCS_VFP)
#define JIT_INSTR_MAX 160
#define JIT_INSTR_MAX 50
0, /* data */
0, /* live */
2, /* align */
18, /* align */
0, /* save */
0, /* load */
4, /* skip */
2, /* #name */
0, /* #note */
0, /* label */
@@ -419,7 +471,10 @@
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -427,8 +482,20 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
28, /* va_arg_d */
@@ -452,18 +519,18 @@
12, /* qmuli */
4, /* qmulr_u */
8, /* qmuli_u */
40, /* divr */
48, /* divi */
40, /* divr_u */
44, /* divi_u */
34, /* qdivr */
38, /* qdivi */
34, /* qdivr_u */
38, /* qdivi_u */
40, /* remr */
48, /* remi */
40, /* remr_u */
44, /* remi_u */
32, /* divr */
36, /* divi */
24, /* divr_u */
28, /* divi_u */
18, /* qdivr */
22, /* qdivi */
18, /* qdivr_u */
22, /* qdivi_u */
24, /* remr */
32, /* remi */
24, /* remr_u */
28, /* remi_u */
4, /* andr */
12, /* andi */
4, /* orr */
@@ -500,12 +567,19 @@
14, /* nei */
4, /* movr */
8, /* movi */
8, /* movnr */
8, /* movzr */
42, /* casr */
46, /* casi */
8, /* extr_c */
4, /* extr_uc */
8, /* extr_s */
8, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
20, /* bswapr_us */
16, /* bswapr_ui */
0, /* bswapr_ul */
20, /* htonr_us */
16, /* htonr_ui */
0, /* htonr_ul */
@@ -598,13 +672,37 @@
4, /* callr */
20, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -612,57 +710,57 @@
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
160, /* epilog */
30, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
40, /* addr_f */
40, /* addi_f */
40, /* subr_f */
40, /* subi_f */
40, /* rsbi_f */
40, /* mulr_f */
40, /* muli_f */
40, /* divr_f */
40, /* divi_f */
24, /* addr_f */
24, /* addi_f */
24, /* subr_f */
24, /* subi_f */
24, /* rsbi_f */
24, /* mulr_f */
24, /* muli_f */
24, /* divr_f */
24, /* divi_f */
12, /* negr_f */
12, /* absr_f */
36, /* sqrtr_f */
40, /* ltr_f */
44, /* lti_f */
40, /* ler_f */
44, /* lei_f */
40, /* eqr_f */
44, /* eqi_f */
40, /* ger_f */
44, /* gei_f */
40, /* gtr_f */
44, /* gti_f */
44, /* ner_f */
48, /* nei_f */
72, /* unltr_f */
80, /* unlti_f */
72, /* unler_f */
80, /* unlei_f */
72, /* uneqr_f */
80, /* uneqi_f */
72, /* unger_f */
80, /* ungei_f */
72, /* ungtr_f */
80, /* ungti_f */
76, /* ltgtr_f */
84, /* ltgti_f */
44, /* ordr_f */
48, /* ordi_f */
72, /* unordr_f */
80, /* unordi_f */
36, /* truncr_f_i */
20, /* sqrtr_f */
24, /* ltr_f */
30, /* lti_f */
24, /* ler_f */
32, /* lei_f */
24, /* eqr_f */
30, /* eqi_f */
24, /* ger_f */
30, /* gei_f */
24, /* gtr_f */
30, /* gti_f */
28, /* ner_f */
32, /* nei_f */
56, /* unltr_f */
64, /* unlti_f */
56, /* unler_f */
64, /* unlei_f */
56, /* uneqr_f */
64, /* uneqi_f */
56, /* unger_f */
64, /* ungei_f */
56, /* ungtr_f */
64, /* ungti_f */
60, /* ltgtr_f */
68, /* ltgti_f */
28, /* ordr_f */
32, /* ordi_f */
56, /* unordr_f */
64, /* unordi_f */
20, /* truncr_f_i */
0, /* truncr_f_l */
36, /* extr_f */
38, /* extr_d_f */
28, /* extr_f */
22, /* extr_d_f */
8, /* movr_f */
12, /* movi_f */
16, /* movi_f */
8, /* ldr_f */
16, /* ldi_f */
8, /* ldxr_f */
@@ -671,34 +769,34 @@
16, /* sti_f */
8, /* stxr_f */
16, /* stxi_f */
44, /* bltr_f */
48, /* blti_f */
44, /* bler_f */
48, /* blei_f */
44, /* beqr_f */
52, /* beqi_f */
44, /* bger_f */
48, /* bgei_f */
44, /* bgtr_f */
48, /* bgti_f */
44, /* bner_f */
48, /* bnei_f */
44, /* bunltr_f */
48, /* bunlti_f */
44, /* bunler_f */
48, /* bunlei_f */
76, /* buneqr_f */
84, /* buneqi_f */
44, /* bunger_f */
48, /* bungei_f */
44, /* bungtr_f */
48, /* bungti_f */
76, /* bltgtr_f */
84, /* bltgti_f */
44, /* bordr_f */
48, /* bordi_f */
44, /* bunordr_f */
48, /* bunordi_f */
28, /* bltr_f */
32, /* blti_f */
28, /* bler_f */
32, /* blei_f */
28, /* beqr_f */
48, /* beqi_f */
28, /* bger_f */
32, /* bgei_f */
28, /* bgtr_f */
32, /* bgti_f */
28, /* bner_f */
32, /* bnei_f */
28, /* bunltr_f */
32, /* bunlti_f */
28, /* bunler_f */
32, /* bunlei_f */
60, /* buneqr_f */
68, /* buneqi_f */
28, /* bunger_f */
32, /* bungei_f */
28, /* bungtr_f */
32, /* bungti_f */
60, /* bltgtr_f */
68, /* bltgti_f */
28, /* bordr_f */
32, /* bordi_f */
28, /* bunordr_f */
32, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
@@ -708,52 +806,52 @@
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
50, /* addr_d */
52, /* addi_d */
50, /* subr_d */
52, /* subi_d */
52, /* rsbi_d */
50, /* mulr_d */
52, /* muli_d */
50, /* divr_d */
52, /* divi_d */
34, /* addr_d */
36, /* addi_d */
34, /* subr_d */
36, /* subi_d */
36, /* rsbi_d */
34, /* mulr_d */
36, /* muli_d */
34, /* divr_d */
36, /* divi_d */
20, /* negr_d */
20, /* absr_d */
42, /* sqrtr_d */
44, /* ltr_d */
48, /* lti_d */
44, /* ler_d */
48, /* lei_d */
44, /* eqr_d */
48, /* eqi_d */
44, /* ger_d */
48, /* gei_d */
44, /* gtr_d */
48, /* gti_d */
48, /* ner_d */
52, /* nei_d */
82, /* unltr_d */
88, /* unlti_d */
82, /* unler_d */
88, /* unlei_d */
82, /* uneqr_d */
88, /* uneqi_d */
82, /* unger_d */
88, /* ungei_d */
82, /* ungtr_d */
88, /* ungti_d */
86, /* ltgtr_d */
92, /* ltgti_d */
48, /* ordr_d */
52, /* ordi_d */
82, /* unordr_d */
88, /* unordi_d */
36, /* truncr_d_i */
26, /* sqrtr_d */
28, /* ltr_d */
34, /* lti_d */
28, /* ler_d */
36, /* lei_d */
28, /* eqr_d */
34, /* eqi_d */
28, /* ger_d */
34, /* gei_d */
28, /* gtr_d */
34, /* gti_d */
32, /* ner_d */
36, /* nei_d */
66, /* unltr_d */
72, /* unlti_d */
66, /* unler_d */
72, /* unlei_d */
66, /* uneqr_d */
72, /* uneqi_d */
66, /* unger_d */
72, /* ungei_d */
66, /* ungtr_d */
72, /* ungti_d */
70, /* ltgtr_d */
76, /* ltgti_d */
32, /* ordr_d */
36, /* ordi_d */
66, /* unordr_d */
72, /* unordi_d */
20, /* truncr_d_i */
0, /* truncr_d_l */
36, /* extr_d */
38, /* extr_f_d */
22, /* extr_f_d */
16, /* movr_d */
20, /* movi_d */
32, /* movi_d */
16, /* ldr_d */
24, /* ldi_d */
20, /* ldxr_d */
@@ -762,34 +860,34 @@
24, /* sti_d */
20, /* stxr_d */
28, /* stxi_d */
48, /* bltr_d */
52, /* blti_d */
48, /* bler_d */
52, /* blei_d */
48, /* beqr_d */
60, /* beqi_d */
48, /* bger_d */
52, /* bgei_d */
48, /* bgtr_d */
52, /* bgti_d */
48, /* bner_d */
52, /* bnei_d */
48, /* bunltr_d */
52, /* bunlti_d */
48, /* bunler_d */
52, /* bunlei_d */
84, /* buneqr_d */
92, /* buneqi_d */
48, /* bunger_d */
52, /* bungei_d */
48, /* bungtr_d */
52, /* bungti_d */
84, /* bltgtr_d */
92, /* bltgti_d */
48, /* bordr_d */
52, /* bordi_d */
48, /* bunordr_d */
52, /* bunordi_d */
32, /* bltr_d */
36, /* blti_d */
32, /* bler_d */
36, /* blei_d */
32, /* beqr_d */
52, /* beqi_d */
32, /* bger_d */
36, /* bgei_d */
32, /* bgtr_d */
36, /* bgti_d */
32, /* bner_d */
36, /* bnei_d */
32, /* bunltr_d */
36, /* bunlti_d */
32, /* bunler_d */
36, /* bunlei_d */
68, /* buneqr_d */
76, /* buneqi_d */
32, /* bunger_d */
36, /* bungei_d */
32, /* bungtr_d */
36, /* bungti_d */
68, /* bltgtr_d */
76, /* bltgti_d */
32, /* bordr_d */
36, /* bordi_d */
32, /* bunordr_d */
36, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
@@ -804,5 +902,9 @@
12, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
8, /* clo */
4, /* clz */
12, /* cto */
8, /* ctz */
#endif /* __ARM_PCS_VFP */
#endif /* __WORDSIZE */
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -1255,7 +1255,7 @@ _vfp_movi_f(jit_state_t *_jit, jit_int32_t r0, jit_float32_t i0)
if (jit_fpr_p(r0)) {
/* float arguments are packed, for others,
* lightning only address even registers */
if (!(r0 & 1) && (r0 - 16) >= 0 &&
if (!(r0 & 1) && (r0 - 32) >= 0 &&
((code = encode_vfp_double(1, 0, u.i, u.i)) != -1 ||
(code = encode_vfp_double(1, 1, ~u.i, ~u.i)) != -1))
VIMM(code, r0);
+324 -116
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -21,6 +21,8 @@
# include <stdio.h>
#endif
#define stack_framesize 48
#define jit_arg_reg_p(i) ((i) >= 0 && (i) < 4)
#define jit_arg_f_reg_p(i) ((i) >= 0 && (i) < 16)
#define jit_arg_d_reg_p(i) ((i) >= 0 && (i) < 15)
@@ -28,12 +30,12 @@
#define arm_patch_node 0x80000000
#define arm_patch_word 0x40000000
#define arm_patch_jump 0x20000000
#define arm_patch_load 0x00000000
#define arm_patch_load 0x10000000
#define arm_patch_call 0x08000000
#define jit_fpr_p(rn) ((rn) > 15)
#define arg_base() \
(stack_framesize - 16 + (jit_cpu.abi ? 64 : 0))
#define arg_base() (stack_framesize - 16)
#define arg_offset(n) \
((n) < 4 ? arg_base() + ((n) << 2) : (n))
@@ -42,10 +44,32 @@
* arm mode, what may cause a crash upon return of that function
* if generating jit for a relative jump.
*/
#define jit_exchange_p() 1
#define jit_exchange_p() jit_cpu.exchange
/* FIXME is it really required to not touch _R10? */
#define CHECK_REG_ARGS() \
do { \
if (!_jitc->function->save_reg_args) \
_jitc->again = _jitc->function->save_reg_args = 1; \
} while (0)
#define CHECK_SWF_OFFSET() \
do { \
if (!_jitc->function->swf_offset) { \
_jitc->again = _jitc->function->save_reg_args = \
_jitc->function->swf_offset = 1; \
_jitc->function->self.aoff = -64; \
} \
} while (0)
#define CHECK_RETURN() \
do { \
if (!_jitc->function->need_frame && \
!_jitc->function->need_return) \
_jitc->again = _jitc->function->need_return = 1; \
} while (0)
/*
* Types
*/
@@ -59,8 +83,8 @@ typedef jit_pointer_t jit_va_list;
/*
* Prototypes
*/
#define jit_make_arg(node) _jit_make_arg(_jit,node)
static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*);
#define jit_make_arg(node,code) _jit_make_arg(_jit,node,code)
static jit_node_t *_jit_make_arg(jit_state_t*,jit_node_t*,jit_code_t);
#define jit_make_arg_f(node) _jit_make_arg_f(_jit,node)
static jit_node_t *_jit_make_arg_f(jit_state_t*,jit_node_t*);
#define jit_make_arg_d(node) _jit_make_arg_d(_jit,node)
@@ -77,8 +101,10 @@ static void _load_const(jit_state_t*,jit_bool_t,jit_int32_t,jit_word_t);
static void _flush_consts(jit_state_t*);
#define invalidate_consts() _invalidate_consts(_jit)
static void _invalidate_consts(jit_state_t*);
#define patch(instr, node) _patch(_jit, instr, node)
static void _patch(jit_state_t*,jit_word_t,jit_node_t*);
#define compute_framesize() _compute_framesize(_jit)
static void _compute_framesize(jit_state_t*);
#define patch(instr, node, kind) _patch(_jit, instr, node, kind)
static void _patch(jit_state_t*,jit_word_t,jit_node_t*,jit_int32_t);
#if defined(__GNUC__)
/* libgcc */
@@ -90,6 +116,7 @@ extern void __clear_cache(void *, void *);
# include "jit_arm-cpu.c"
# include "jit_arm-swf.c"
# include "jit_arm-vfp.c"
# include "jit_fallback.c"
#undef PROTO
/*
@@ -148,6 +175,10 @@ jit_register_t _rvs[] = {
{ _NOREG, "<none>" },
};
static jit_int32_t iregs[] = {
_R4, _R5, _R6, _R7, _R8, _R9,
};
/*
* Implementation
*/
@@ -201,6 +232,14 @@ jit_get_cpu(void)
/* armv6t2 todo (software float and thumb2) */
if (!jit_cpu.vfp && jit_cpu.thumb)
jit_cpu.thumb = 0;
/* FIXME need test environments for the below. For the moment just
* be very conservative */
/* force generation of code assuming jit and function libraries called
* instruction set do not match */
jit_cpu.exchange = 1;
/* do not generate hardware integer division by default */
if (jit_cpu.version == 7)
jit_cpu.extend = 0;
}
void
@@ -244,15 +283,10 @@ _jit_prolog(jit_state_t *_jit)
}
_jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
_jitc->function->self.size = stack_framesize;
if (jit_cpu.abi)
_jitc->function->self.size += 64;
_jitc->function->self.argi = _jitc->function->self.argf =
_jitc->function->self.alen = 0;
if (jit_swf_p())
/* 8 soft float registers */
_jitc->function->self.aoff = -64;
else
_jitc->function->self.aoff = 0;
_jitc->function->self.alen = _jitc->function->self.aoff = 0;
_jitc->function->swf_offset = _jitc->function->save_reg_args =
_jitc->function->need_return = 0;
_jitc->function->self.call = jit_call_default;
jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
_jitc->reglen * sizeof(jit_int32_t));
@@ -278,6 +312,9 @@ jit_int32_t
_jit_allocai(jit_state_t *_jit, jit_int32_t length)
{
assert(_jitc->function);
if (jit_swf_p())
CHECK_SWF_OFFSET();
jit_check_frame();
switch (length) {
case 0: case 1: break;
case 2: _jitc->function->self.aoff &= -2; break;
@@ -326,20 +363,18 @@ _jit_ret(jit_state_t *_jit)
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
_jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
jit_inc_synth_w(retr, u);
if (JIT_RET != u)
jit_movr(JIT_RET, u);
jit_live(JIT_RET);
jit_code_inc_synth_w(code, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
_jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_inc_synth_w(reti, u);
jit_code_inc_synth_w(code, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
@@ -421,7 +456,7 @@ _jit_epilog(jit_state_t *_jit)
jit_bool_t
_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
{
if (u->code != jit_code_arg) {
if (!(u->code >= jit_code_arg_c && u->code <= jit_code_arg)) {
if (u->code == jit_code_arg_f) {
if (jit_cpu.abi)
return (jit_arg_f_reg_p(u->u.w));
@@ -436,7 +471,7 @@ _jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
}
static jit_node_t *
_jit_make_arg(jit_state_t *_jit, jit_node_t *node)
_jit_make_arg(jit_state_t *_jit, jit_node_t *node, jit_code_t code)
{
jit_int32_t offset;
if (jit_arg_reg_p(_jitc->function->self.argi))
@@ -446,7 +481,7 @@ _jit_make_arg(jit_state_t *_jit, jit_node_t *node)
_jitc->function->self.size += sizeof(jit_word_t);
}
if (node == (jit_node_t *)0)
node = jit_new_node(jit_code_arg);
node = jit_new_node(code);
else
link_node(node);
node->u.w = offset;
@@ -533,9 +568,10 @@ _jit_ellipsis(jit_state_t *_jit)
else {
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
CHECK_REG_ARGS();
if (jit_cpu.abi && _jitc->function->self.argf)
rewind_prolog();
/* First 4 stack addresses are always spilled r0-r3 */
/* First 4 stack addresses need to be spilled r0-r3 */
if (jit_arg_reg_p(_jitc->function->self.argi))
_jitc->function->vagp = _jitc->function->self.argi * 4;
else
@@ -558,16 +594,21 @@ _jit_va_push(jit_state_t *_jit, jit_int32_t u)
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
_jit_arg(jit_state_t *_jit, jit_code_t code)
{
assert(_jitc->function);
return (jit_make_arg((jit_node_t*)0));
assert(!(_jitc->function->self.call & jit_call_varargs));
#if STRONG_TYPE_CHECKING
assert(code >= jit_code_arg_c && code <= jit_code_arg);
#endif
return (jit_make_arg((jit_node_t*)0, code));
}
jit_node_t *
_jit_arg_f(jit_state_t *_jit)
{
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
return (jit_make_arg_f((jit_node_t*)0));
}
@@ -575,103 +616,141 @@ jit_node_t *
_jit_arg_d(jit_state_t *_jit)
{
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
return (jit_make_arg_d((jit_node_t*)0));
}
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_node_t *node = NULL;
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_swf_p())
jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
jit_ldxi_c(u, JIT_FP, v->u.w);
node = jit_ldxi_c(u, JIT_FP, v->u.w);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_node_t *node = NULL;
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_swf_p())
jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
jit_ldxi_uc(u, JIT_FP, v->u.w);
node = jit_ldxi_uc(u, JIT_FP, v->u.w);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_node_t *node = NULL;
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_swf_p())
jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
jit_ldxi_s(u, JIT_FP, v->u.w);
node = jit_ldxi_s(u, JIT_FP, v->u.w);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_node_t *node = NULL;
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_swf_p())
jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
jit_ldxi_us(u, JIT_FP, v->u.w);
node = jit_ldxi_us(u, JIT_FP, v->u.w);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
jit_node_t *node = NULL;
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_swf_p())
jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
jit_ldxi_i(u, JIT_FP, v->u.w);
node = jit_ldxi_i(u, JIT_FP, v->u.w);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
jit_node_t *node = NULL;
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_swf_p())
jit_stxi(arg_offset(v->u.w), JIT_FP, u);
node = jit_stxi(arg_offset(v->u.w), JIT_FP, u);
else if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
jit_stxi(v->u.w, JIT_FP, u);
node = jit_stxi(v->u.w, JIT_FP, u);
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
jit_int32_t regno;
jit_node_t *node = NULL;
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_swf_p()) {
regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u);
jit_stxi(arg_offset(v->u.w), JIT_FP, regno);
node = jit_stxi(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else if (jit_arg_reg_p(v->u.w))
@@ -679,30 +758,41 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
else {
regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u);
jit_stxi(v->u.w, JIT_FP, regno);
node = jit_stxi(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(getarg_f, u, v);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(u, JIT_FA0 - v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w);
node = jit_ldxi_f(u, JIT_FP, v->u.w);
}
else if (jit_swf_p())
jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w));
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_w_f(u, JIT_RA0 - v->u.w);
else
jit_ldxi_f(u, JIT_FP, v->u.w);
node = jit_ldxi_f(u, JIT_FP, v->u.w);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
@@ -710,21 +800,27 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_f);
jit_inc_synth_wp(putargr_f, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_f(JIT_FA0 - v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u);
node = jit_stxi_f(v->u.w, JIT_FP, u);
}
else if (jit_swf_p())
jit_stxi_f(arg_offset(v->u.w), JIT_FP, u);
node = jit_stxi_f(arg_offset(v->u.w), JIT_FP, u);
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_f_w(JIT_RA0 - v->u.w, u);
else
jit_stxi_f(v->u.w, JIT_FP, u);
node = jit_stxi_f(v->u.w, JIT_FP, u);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
@@ -732,7 +828,8 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
{
jit_int32_t regno;
jit_int32_t regno;
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_f);
jit_inc_synth_fp(putargi_f, u, v);
if (jit_cpu.abi) {
@@ -741,14 +838,14 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
else {
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
jit_stxi_f(v->u.w, JIT_FP, regno);
node = jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
}
else if (jit_swf_p()) {
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno);
node = jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else {
@@ -757,30 +854,41 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
if (jit_arg_reg_p(v->u.w))
jit_movr_f_w(JIT_RA0 - v->u.w, regno);
else
jit_stxi_f(v->u.w, JIT_FP, regno);
node = jit_stxi_f(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(getarg_d, u, v);
if (jit_cpu.abi && !(_jitc->function->self.call & jit_call_varargs)) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(u, JIT_FA0 - v->u.w);
else
jit_ldxi_d(u, JIT_FP, v->u.w);
node = jit_ldxi_d(u, JIT_FP, v->u.w);
}
else if (jit_swf_p())
jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w));
node = jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w));
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_ww_d(u, JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1));
else
jit_ldxi_d(u, JIT_FP, v->u.w);
node = jit_ldxi_d(u, JIT_FP, v->u.w);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
@@ -788,21 +896,27 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_d);
jit_inc_synth_wp(putargr_d, u, v);
if (jit_cpu.abi) {
if (jit_arg_f_reg_p(v->u.w))
jit_movr_d(JIT_FA0 - v->u.w, u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
node = jit_stxi_d(v->u.w, JIT_FP, u);
}
else if (jit_swf_p())
jit_stxi_d(arg_offset(v->u.w), JIT_FP, u);
node = jit_stxi_d(arg_offset(v->u.w), JIT_FP, u);
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), u);
else
jit_stxi_d(v->u.w, JIT_FP, u);
node = jit_stxi_d(v->u.w, JIT_FP, u);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
@@ -810,7 +924,8 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
{
jit_int32_t regno;
jit_int32_t regno;
jit_node_t *node = NULL;
assert(v->code == jit_code_arg_d);
jit_inc_synth_dp(putargi_d, u, v);
if (jit_cpu.abi) {
@@ -819,14 +934,14 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
else {
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
jit_stxi_d(v->u.w, JIT_FP, regno);
node = jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
}
else if (jit_swf_p()) {
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno);
node = jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else {
@@ -835,17 +950,22 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
if (jit_arg_reg_p(v->u.w))
jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), regno);
else
jit_stxi_d(v->u.w, JIT_FP, regno);
node = jit_stxi_d(v->u.w, JIT_FP, regno);
jit_unget_reg(regno);
}
if (node) {
CHECK_REG_ARGS();
jit_link_alist(node);
jit_check_frame();
}
jit_dec_synth();
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
_jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(JIT_RA0 - _jitc->function->call.argi, u);
@@ -859,11 +979,11 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
_jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(JIT_RA0 - _jitc->function->call.argi, u);
@@ -1147,6 +1267,7 @@ _emit_code(jit_state_t *_jit)
jit_node_t *node;
jit_uint8_t *data;
jit_word_t word;
jit_function_t func;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
@@ -1292,7 +1413,7 @@ _emit_code(jit_state_t *_jit)
else { \
word = name##r##type(_jit->pc.w, \
rn(node->v.w), rn(node->w.w)); \
patch(word, node); \
patch(word, node, arm_patch_jump); \
} \
break
#define case_bvv(name, type) \
@@ -1317,7 +1438,7 @@ _emit_code(jit_state_t *_jit)
word = vfp_##name##r##type(_jit->pc.w, \
rn(node->v.w), \
rn(node->w.w)); \
patch(word, node); \
patch(word, node, arm_patch_jump); \
} \
break
#define case_brw(name, type) \
@@ -1331,7 +1452,7 @@ _emit_code(jit_state_t *_jit)
else { \
word = name##i##type(_jit->pc.w, \
rn(node->v.w), node->w.w); \
patch(word, node); \
patch(word, node, arm_patch_jump); \
} \
break;
#define case_bvf(name) \
@@ -1356,7 +1477,7 @@ _emit_code(jit_state_t *_jit)
word = vfp_##name##i_f(_jit->pc.w, \
rn(node->v.w), \
node->w.f); \
patch(word, node); \
patch(word, node, arm_patch_jump); \
} \
break
#define case_bvd(name) \
@@ -1381,7 +1502,7 @@ _emit_code(jit_state_t *_jit)
word = vfp_##name##i_d(_jit->pc.w, \
rn(node->v.w), \
node->w.d); \
patch(word, node); \
patch(word, node, arm_patch_jump); \
} \
break
#if DEVEL_DISASSEMBLER
@@ -1399,11 +1520,16 @@ _emit_code(jit_state_t *_jit)
jit_regarg_set(node, value);
switch (node->code) {
case jit_code_align:
assert(!(node->u.w & (node->u.w - 1)) &&
node->u.w <= sizeof(jit_word_t));
if (node->u.w == sizeof(jit_word_t) &&
(word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
nop(sizeof(jit_word_t) - word);
/* Must align to a power of two */
assert(!(node->u.w & (node->u.w - 1)));
if ((word = _jit->pc.w & (node->u.w - 1)))
nop(node->u.w - word);
break;
case jit_code_skip:
if (jit_thumb_p())
nop((node->u.w + 1) & ~1);
else
nop((node->u.w + 3) & ~3);
break;
case jit_code_note: case jit_code_name:
if (must_align_p(node->next))
@@ -1456,6 +1582,10 @@ _emit_code(jit_state_t *_jit)
case_rrw(rsh, _u);
case_rr(neg,);
case_rr(com,);
case_rr(clo,);
case_rr(clz,);
case_rr(cto,);
case_rr(ctz,);
case_rrr(and,);
case_rrw(and,);
case_rrr(or,);
@@ -1498,11 +1628,23 @@ _emit_code(jit_state_t *_jit)
case_wrr(stx, _i);
case_rr(hton, _us);
case_rr(hton, _ui);
case_rr(bswap, _us);
case_rr(bswap, _ui);
case_rr(ext, _c);
case_rr(ext, _uc);
case_rr(ext, _s);
case_rr(ext, _us);
case jit_code_casr:
casr(rn(node->u.w), rn(node->v.w),
rn(node->w.q.l), rn(node->w.q.h));
break;
case jit_code_casi:
casi(rn(node->u.w), node->v.w,
rn(node->w.q.l), rn(node->w.q.h));
break;
case_rr(mov,);
case_rrr(movn,);
case_rrr(movz,);
case jit_code_movi:
if (node->flag & jit_flag_node) {
temp = node->v.n;
@@ -1514,7 +1656,7 @@ _emit_code(jit_state_t *_jit)
assert(temp->code == jit_code_label ||
temp->code == jit_code_epilog);
word = movi_p(rn(node->u.w), temp->u.w);
patch(word, node);
patch(word, node, arm_patch_word);
}
}
else
@@ -1753,6 +1895,7 @@ _emit_code(jit_state_t *_jit)
case_bvv(bunord, _d);
case_bvd(bunord);
case jit_code_jmpr:
jit_check_frame();
jmpr(rn(node->u.w));
flush_consts();
break;
@@ -1764,36 +1907,59 @@ _emit_code(jit_state_t *_jit)
if (temp->flag & jit_flag_patch)
jmpi(temp->u.w);
else {
word = jmpi_p(_jit->pc.w, 1);
patch(word, node);
word = _jit->code.length -
(_jit->pc.uc - _jit->code.ptr);
if (jit_thumb_p()) word >>= 1;
else word >>= 2;
word -= 2;
value = _s24P(word);
word = jmpi_p(_jit->pc.w, value);
patch(word, node, value ?
arm_patch_jump : arm_patch_word);
}
}
else
else {
jit_check_frame();
jmpi(node->u.w);
}
flush_consts();
break;
case jit_code_callr:
jit_check_frame();
callr(rn(node->u.w));
break;
case jit_code_calli:
if (node->flag & jit_flag_node) {
CHECK_RETURN();
temp = node->u.n;
assert(temp->code == jit_code_label ||
temp->code == jit_code_epilog);
if (temp->flag & jit_flag_patch)
calli(temp->u.w);
calli(temp->u.w, 0);
else {
word = calli_p(_jit->pc.w);
patch(word, node);
word = _jit->code.length -
(_jit->pc.uc - _jit->code.ptr);
if (jit_exchange_p())
word -= 8;
if (jit_thumb_p()) word >>= 1;
else word >>= 2;
word -= 2;
value = _s24P(word);
word = calli_p(_jit->pc.w, value);
patch(word, node, value ?
arm_patch_call : arm_patch_word);
}
}
else
calli(node->u.w);
else {
jit_check_frame();
calli(node->u.w, jit_exchange_p());
}
break;
case jit_code_prolog:
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
memcpy(&undo.func, _jitc->function, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
@@ -1807,6 +1973,8 @@ _emit_code(jit_state_t *_jit)
#endif
restart_function:
_jitc->again = 0;
compute_framesize();
patch_alist(0);
prolog(node);
break;
case jit_code_epilog:
@@ -1821,6 +1989,21 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
/* undo.func.self.aoff and undo.func.regset should not
* be undone, as they will be further updated, and are
* the reason of the undo. */
undo.func.self.aoff = _jitc->function->frame +
_jitc->function->self.aoff;
undo.func.need_frame = _jitc->function->need_frame;
undo.func.need_return = _jitc->function->need_return;
jit_regset_set(&undo.func.regset, &_jitc->function->regset);
/* allocar information also does not need to be undone */
undo.func.aoffoff = _jitc->function->aoffoff;
undo.func.allocar = _jitc->function->allocar;
/* swf_offset and check_reg_args must also not be undone */
undo.func.swf_offset = _jitc->function->swf_offset;
undo.func.save_reg_args = _jitc->function->save_reg_args;
memcpy(_jitc->function, &undo.func, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
@@ -1833,6 +2016,7 @@ _emit_code(jit_state_t *_jit)
if (_jitc->data_info.ptr)
_jitc->data_info.offset = undo.info_offset;
#endif
patch_alist(1);
goto restart_function;
}
/* remember label is defined */
@@ -1895,21 +2079,34 @@ _emit_code(jit_state_t *_jit)
case jit_code_live: case jit_code_ellipsis:
case jit_code_va_push:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg:
case jit_code_arg_c: case jit_code_arg_s:
case jit_code_arg_i:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_c: case jit_code_reti_c:
case jit_code_retr_uc: case jit_code_reti_uc:
case jit_code_retr_s: case jit_code_reti_s:
case jit_code_retr_us: case jit_code_reti_us:
case jit_code_retr_i: case jit_code_reti_i:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_c: case jit_code_putargi_c:
case jit_code_putargr_uc: case jit_code_putargi_uc:
case jit_code_putargr_s: case jit_code_putargi_s:
case jit_code_putargr_us: case jit_code_putargi_us:
case jit_code_putargr_i: case jit_code_putargi_i:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_c: case jit_code_pushargi_c:
case jit_code_pushargr_uc: case jit_code_pushargi_uc:
case jit_code_pushargr_s: case jit_code_pushargi_s:
case jit_code_pushargr_us: case jit_code_pushargi_us:
case jit_code_pushargr_i: case jit_code_pushargi_i:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
@@ -1972,7 +2169,10 @@ _emit_code(jit_state_t *_jit)
node = _jitc->patches.ptr[offset].node;
word = _jitc->patches.ptr[offset].inst;
if (!jit_thumb_p() &&
(node->code == jit_code_movi || node->code == jit_code_calli)) {
(node->code == jit_code_movi ||
(node->code == jit_code_calli &&
(_jitc->patches.ptr[offset].kind & ~arm_patch_node) ==
arm_patch_word))) {
/* calculate where to patch word */
value = *(jit_int32_t *)word;
assert((value & 0x0f700000) == ARM_LDRI);
@@ -1999,6 +2199,7 @@ _emit_code(jit_state_t *_jit)
# include "jit_arm-cpu.c"
# include "jit_arm-swf.c"
# include "jit_arm-vfp.c"
# include "jit_fallback.c"
#undef CODE
void
@@ -2241,24 +2442,31 @@ _invalidate_consts(jit_state_t *_jit)
}
static void
_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
_compute_framesize(jit_state_t *_jit)
{
jit_int32_t reg;
_jitc->framesize = sizeof(jit_word_t) * 2; /* lr+fp */
for (reg = 0; reg < jit_size(iregs); reg++)
if (jit_regset_tstbit(&_jitc->function->regset, iregs[reg]))
_jitc->framesize += sizeof(jit_word_t);
if (_jitc->function->save_reg_args)
_jitc->framesize += 16;
/* Make sure functions called have a 8 byte aligned stack */
_jitc->framesize = (_jitc->framesize + 7) & -8;
}
static void
_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node, jit_int32_t kind)
{
jit_int32_t flag;
jit_int32_t kind;
assert(node->flag & jit_flag_node);
if (node->code == jit_code_movi) {
if (node->code == jit_code_movi)
flag = node->v.n->flag;
kind = arm_patch_word;
}
else {
else
flag = node->u.n->flag;
if (node->code == jit_code_calli ||
(node->code == jit_code_jmpi && !(node->flag & jit_flag_node)))
kind = arm_patch_word;
else
kind = arm_patch_jump;
}
assert(!(flag & jit_flag_patch));
kind |= arm_patch_node;
if (_jitc->patches.offset >= _jitc->patches.length) {
+54 -56
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -50,7 +50,21 @@ static asymbol *disasm_synthetic;
static long disasm_num_symbols;
static long disasm_num_synthetic;
static jit_state_t *disasm_jit;
#define disasm_stream stdout
static FILE *disasm_stream;
#endif
#if BINUTILS_2_38
static int fprintf_styled(void * stream, enum disassembler_style style, const char* fmt, ...)
{
va_list args;
int r;
va_start(args, fmt);
r = vfprintf(disasm_stream, fmt, args);
va_end(args);
return r;
}
#endif
/*
@@ -59,6 +73,7 @@ static jit_state_t *disasm_jit;
void
jit_init_debug(const char *progname)
{
jit_init_print();
#if DISASSEMBLER
bfd_init();
@@ -73,64 +88,29 @@ jit_init_debug(const char *progname)
}
bfd_check_format(disasm_bfd, bfd_object);
bfd_check_format(disasm_bfd, bfd_archive);
if (!disasm_stream)
disasm_stream = stderr;
#if BINUTILS_2_38
INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf, fprintf_styled);
#else
INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf);
# if defined(__i386__) || defined(__x86_64__)
disasm_info.arch = bfd_arch_i386;
# if defined(__x86_64__)
# if __WORDSIZE == 32
disasm_info.mach = bfd_mach_x64_32;
# else
disasm_info.mach = bfd_mach_x86_64;
# endif
# else
disasm_info.mach = bfd_mach_i386_i386;
# endif
# endif
# if defined(__powerpc__)
disasm_info.arch = bfd_arch_powerpc;
disasm_info.mach = bfd_mach_ppc64;
# if HAVE_DISASSEMBLE_INIT_FOR_TARGET
#endif
disasm_info.arch = bfd_get_arch(disasm_bfd);
disasm_info.mach = bfd_get_mach(disasm_bfd);
# if HAVE_DISASSEMBLE_INIT_FOR_TARGET
disassemble_init_for_target(&disasm_info);
# elif HAVE_DISASSEMBLE_INIT_POWERPC
disassemble_init_powerpc(&disasm_info);
# endif
# if defined(__powerpc64__)
# endif
# if defined(__powerpc64__)
disasm_info.disassembler_options = "64";
# endif
# if HAVE_DISASSEMBLE_INIT_FOR_TARGET
disassemble_init_for_target(&disasm_info);
# elif HAVE_DISASSEMBLE_INIT_POWERPC
disassemble_init_powerpc(&disasm_info);
# endif
# endif
# if defined(__sparc__)
# if defined(__sparc__) || defined(__s390__) || defined(__s390x__)
disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
# endif
# if defined(__s390__) || defined(__s390x__)
disasm_info.arch = bfd_arch_s390;
# if __WORDSIZE == 32
disasm_info.mach = bfd_mach_s390_31;
# else
disasm_info.mach = bfd_mach_s390_64;
# endif
disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
disasm_info.disassembler_options = "zarch";
# endif
# if defined(__alpha__)
disasm_info.arch = bfd_arch_alpha;
disasm_info.mach = bfd_mach_alpha_ev6;
# endif
# if defined(__hppa__)
disasm_info.arch = bfd_arch_hppa;
disasm_info.mach = bfd_mach_hppa10;
# endif
# if defined(__riscv)
disasm_info.arch = bfd_arch_riscv;
# if __WORDSIZE == 32
disasm_info.mach = bfd_mach_riscv32;
# else
disasm_info.mach = bfd_mach_riscv64;
# endif
# endif
disasm_info.print_address_func = disasm_print_address;
@@ -276,7 +256,7 @@ disasm_print_address(bfd_vma addr, struct disassemble_info *info)
int line;
char buffer[address_buffer_length];
sprintf(buffer, address_buffer_format, (long long)addr);
sprintf(buffer, address_buffer_format, addr);
(*info->fprintf_func)(info->stream, "0x%s", buffer);
# define _jit disasm_jit
@@ -339,7 +319,10 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
char *name, *old_name;
char *file, *old_file;
int line, old_line;
#if __arm__
#if __riscv && __WORDSIZE == 64
jit_word_t *vector;
jit_int32_t offset;
#elif __arm__
jit_int32_t offset;
jit_bool_t data_info;
jit_int32_t data_offset;
@@ -352,6 +335,10 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
jit_uword_t prevw;
#endif
#if __riscv && __WORDSIZE == 64
end -= _jitc->consts.hash.count * 8;
#endif
#if __arm__
data_info = _jitc && _jitc->data_info.ptr;
data_offset = 0;
@@ -374,7 +361,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
}
while (node && (jit_uword_t)(prevw + node->offset) == (jit_uword_t)pc) {
jit_print_node(node);
fputc('\n', stdout);
fputc('\n', disasm_stream);
prevw += node->offset;
node = node->next;
}
@@ -419,11 +406,22 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
old_line = line;
}
bytes = sprintf(buffer, address_buffer_format, (long long)pc);
bytes = sprintf(buffer, address_buffer_format, pc);
(*disasm_info.fprintf_func)(disasm_stream, "%*c0x%s\t",
16 - bytes, ' ', buffer);
pc += (*disasm_print)(pc, &disasm_info);
putc('\n', disasm_stream);
}
#if __riscv && __WORDSIZE == 64
for (vector = (jit_word_t *)end, offset = 0;
offset < _jitc->consts.hash.count; offset++) {
bytes = sprintf(buffer, address_buffer_format,
(long long)end + offset * sizeof(jit_word_t));
(*disasm_info.fprintf_func)(disasm_stream,
"%*c0x%s\t.quad\t0x%016lx\t# (%ld)\n",
16 - bytes, ' ', buffer,
vector[offset], vector[offset]);
}
#endif
}
#endif
+332
View File
@@ -0,0 +1,332 @@
#if PROTO
#define fallback_save(r0) _fallback_save(_jit, r0)
static void _fallback_save(jit_state_t*, jit_int32_t);
#define fallback_load(r0) _fallback_load(_jit, r0)
static void _fallback_load(jit_state_t*, jit_int32_t);
#define fallback_save_regs(r0) _fallback_save_regs(_jit, r0)
static void _fallback_save_regs(jit_state_t*, jit_int32_t);
#define fallback_load_regs(r0) _fallback_load_regs(_jit, r0)
static void _fallback_load_regs(jit_state_t*, jit_int32_t);
#define fallback_calli(i0, i1) _fallback_calli(_jit, i0, i1)
static void _fallback_calli(jit_state_t*, jit_word_t, jit_word_t);
#define fallback_casx(r0,r1,r2,r3,im) _fallback_casx(_jit,r0,r1,r2,r3,im)
static void _fallback_casx(jit_state_t *, jit_int32_t, jit_int32_t,
jit_int32_t, jit_int32_t, jit_word_t);
#define fallback_clo(r0,r1) _fallback_clo(_jit,r0,r1)
static void _fallback_clo(jit_state_t*, jit_int32_t, jit_int32_t);
#define fallback_clz(r0,r1) _fallback_clz(_jit,r0,r1)
static void _fallback_clz(jit_state_t*, jit_int32_t, jit_int32_t);
#define fallback_cto(r0,r1) _fallback_cto(_jit,r0,r1)
static void _fallback_cto(jit_state_t*, jit_int32_t, jit_int32_t);
#define fallback_ctz(r0,r1) _fallback_ctz(_jit,r0,r1)
static void _fallback_ctz(jit_state_t*, jit_int32_t, jit_int32_t);
# if defined(__ia64__)
# define fallback_patch_jmpi(inst,lbl) \
do { \
sync(); \
patch_at(jit_code_jmpi, inst, lbl); \
} while (0)
# else
# define fallback_patch_jmpi(inst,lbl) fallback_patch_at(inst,lbl)
# endif
# if defined(__arm__)
# define fallback_patch_at(inst,lbl) patch_at(arm_patch_jump,inst,lbl)
# elif defined(__ia64__)
# define fallback_patch_at(inst,lbl) \
do { \
sync(); \
patch_at(jit_code_bnei, inst, lbl); \
} while (0);
# else
# define fallback_patch_at(inst,lbl) patch_at(inst,lbl)
# endif
# if defined(__mips__)
# define fallback_jmpi(i0) jmpi(i0,NULL,1)
# elif defined(__arm__)
# define fallback_jmpi(i0) jmpi_p(i0,1)
# elif defined(__s390__) || defined(__s390x__)
# define fallback_jmpi(i0) jmpi(i0,1)
# else
# define fallback_jmpi(i0) jmpi(i0)
# endif
# if defined(__mips__)
# define fallback_bnei(i0,r0,i1) bnei(i0,r0,i1,NULL)
# elif defined(__s390__) || defined(__s390x__)
# define fallback_bnei(i0,r0,i1) bnei_p(i0,r0,i1)
# else
# define fallback_bnei(i0,r0,i1) bnei(i0,r0,i1)
# endif
# if defined(__s390__) || defined(__s390x__)
# define fallback_bmsr(i0,r0,r1) bmsr_p(i0,r0,r1)
# else
# define fallback_bmsr(i0,r0,r1) bmsr(i0,r0,r1)
# endif
#endif
#if CODE
static void
_fallback_save(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t offset, regno, spec;
for (offset = 0; offset < JIT_R_NUM; offset++) {
spec = _rvs[offset].spec;
regno = jit_regno(spec);
if (regno == r0) {
if (!(spec & jit_class_sav))
stxi(_jitc->function->regoff[JIT_R(offset)], rn(JIT_FP), regno);
break;
}
}
}
static void
_fallback_load(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t offset, regno, spec;
for (offset = 0; offset < JIT_R_NUM; offset++) {
spec = _rvs[offset].spec;
regno = jit_regno(spec);
if (regno == r0) {
if (!(spec & jit_class_sav))
ldxi(regno, rn(JIT_FP), _jitc->function->regoff[JIT_R(offset)]);
break;
}
}
}
static void
_fallback_save_regs(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t regno, spec;
for (regno = 0; regno < _jitc->reglen; regno++) {
spec = _rvs[regno].spec;
if ((jit_regset_tstbit(&_jitc->regarg, regno) ||
jit_regset_tstbit(&_jitc->reglive, regno)) &&
!(spec & jit_class_sav)) {
if (!_jitc->function->regoff[regno]) {
_jitc->function->regoff[regno] =
jit_allocai(spec & jit_class_gpr ?
sizeof(jit_word_t) : sizeof(jit_float64_t));
_jitc->again = 1;
}
if ((spec & jit_class_gpr) && rn(regno) == r0)
continue;
jit_regset_setbit(&_jitc->regsav, regno);
if (spec & jit_class_gpr)
emit_stxi(_jitc->function->regoff[regno], JIT_FP, regno);
else
emit_stxi_d(_jitc->function->regoff[regno], JIT_FP, regno);
}
}
}
static void
_fallback_load_regs(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t regno, spec;
for (regno = 0; regno < _jitc->reglen; regno++) {
spec = _rvs[regno].spec;
if ((jit_regset_tstbit(&_jitc->regarg, regno) ||
jit_regset_tstbit(&_jitc->reglive, regno)) &&
!(spec & jit_class_sav)) {
if ((spec & jit_class_gpr) && rn(regno) == r0)
continue;
jit_regset_setbit(&_jitc->regsav, regno);
if (spec & jit_class_gpr)
emit_ldxi(regno, JIT_FP, _jitc->function->regoff[regno]);
else
emit_ldxi_d(regno, JIT_FP, _jitc->function->regoff[regno]);
}
}
}
static void
_fallback_calli(jit_state_t *_jit, jit_word_t i0, jit_word_t i1)
{
# if defined(__arm__)
movi(rn(_R0), i1);
# elif defined(__hppa__)
movi(_R26_REGNO, i1);
# endif
# if defined(__arm__)
calli(i0, jit_exchange_p());
# elif defined(__mips__)
calli(i0, NULL, 0);
# elif defined(__powerpc__) && _CALL_SYSV
calli(i0, 0);
# elif defined(__s390__) || defined(__s390x__)
calli(i0, 0);
# else
calli(i0);
# endif
}
static void
_fallback_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
jit_int32_t r1_reg, iscasi;
jit_word_t jump, done;
/* XXX only attempts to fallback cas for lightning jit code */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if ((iscasi = r1 == _NOREG)) {
r1_reg = jit_get_reg(jit_class_gpr|jit_class_sav);
r1 = rn(r1_reg);
movi(r1, i0);
}
fallback_save_regs(r0);
fallback_calli((jit_word_t)pthread_mutex_lock, (jit_word_t)&mutex);
fallback_load(r1);
ldr(r0, r1);
fallback_load(r2);
eqr(r0, r0, r2);
fallback_save(r0);
jump = fallback_bnei(_jit->pc.w, r0, 1);
fallback_load(r3);
# if __WORDSIZE == 32
str_i(r1, r3);
# else
str_l(r1, r3);
# endif
/* done: */
done = _jit->pc.w;
fallback_calli((jit_word_t)pthread_mutex_unlock, (jit_word_t)&mutex);
fallback_load(r0);
fallback_patch_at(jump, done);
fallback_load_regs(r0);
if (iscasi)
jit_unget_reg(r1_reg);
}
static void
_fallback_clo(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t clz, done;
comr(r0, r1);
clz = fallback_bnei(_jit->pc.w, r0, 0);
movi(r0, __WORDSIZE);
done = fallback_jmpi(_jit->pc.w);
fallback_patch_at(clz, _jit->pc.w);
fallback_clz(r0, r0);
fallback_patch_jmpi(done, _jit->pc.w);
}
static void
_fallback_clz(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t r1_reg, r2, r2_reg;
jit_word_t clz, l32, l16, l8, l4, l2, l1;
l32 = fallback_bnei(_jit->pc.w, r1, 0);
movi(r0, __WORDSIZE);
clz = fallback_jmpi(_jit->pc.w);
fallback_patch_at(l32, _jit->pc.w);
r2_reg = jit_get_reg(jit_class_gpr);
r2 = rn(r2_reg);
r1_reg = jit_get_reg(jit_class_gpr);
movr(rn(r1_reg), r1);
r1 = rn(r1_reg);
movi(r0, 0);
# if __WORDSIZE == 64
movi(r2, 0xffffffff00000000UL);
l32 = fallback_bmsr(_jit->pc.w, r1, r2);
lshi(r1, r1, 32);
addi(r0, r0, 32);
fallback_patch_at(l32, _jit->pc.w);
lshi(r2, r2, 16);
# else
movi(r2, 0xffff0000UL);
# endif
l16 = fallback_bmsr(_jit->pc.w, r1, r2);
lshi(r1, r1, 16);
addi(r0, r0, 16);
fallback_patch_at(l16, _jit->pc.w);
lshi(r2, r2, 8);
l8 = fallback_bmsr(_jit->pc.w, r1, r2);
lshi(r1, r1, 8);
addi(r0, r0, 8);
fallback_patch_at(l8, _jit->pc.w);
lshi(r2, r2, 4);
l4 = fallback_bmsr(_jit->pc.w, r1, r2);
lshi(r1, r1, 4);
addi(r0, r0, 4);
fallback_patch_at(l4, _jit->pc.w);
lshi(r2, r2, 2);
l2 = fallback_bmsr(_jit->pc.w, r1, r2);
lshi(r1, r1, 2);
addi(r0, r0, 2);
fallback_patch_at(l2, _jit->pc.w);
lshi(r2, r2, 1);
l1 = fallback_bmsr(_jit->pc.w, r1, r2);
addi(r0, r0, 1);
fallback_patch_at(l1, _jit->pc.w);
fallback_patch_jmpi(clz, _jit->pc.w);
jit_unget_reg(r2_reg);
jit_unget_reg(r1_reg);
}
static void
_fallback_cto(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_word_t ctz, done;
comr(r0, r1);
ctz = fallback_bnei(_jit->pc.w, r0, 0);
movi(r0, __WORDSIZE);
done = fallback_jmpi(_jit->pc.w);
fallback_patch_at(ctz, _jit->pc.w);
fallback_ctz(r0, r0);
fallback_patch_jmpi(done, _jit->pc.w);
}
static void
_fallback_ctz(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t r1_reg, r2, r2_reg;
jit_word_t ctz, l32, l16, l8, l4, l2, l1;
l32 = fallback_bnei(_jit->pc.w, r1, 0);
movi(r0, __WORDSIZE);
ctz = fallback_jmpi(_jit->pc.w);
fallback_patch_at(l32, _jit->pc.w);
r2_reg = jit_get_reg(jit_class_gpr);
r2 = rn(r2_reg);
r1_reg = jit_get_reg(jit_class_gpr);
movr(rn(r1_reg), r1);
r1 = rn(r1_reg);
movi(r0, 0);
# if __WORDSIZE == 64
movi(r2, 0xffffffffUL);
l32 = fallback_bmsr(_jit->pc.w, r1, r2);
rshi_u(r1, r1, 32);
addi(r0, r0, 32);
fallback_patch_at(l32, _jit->pc.w);
rshi(r2, r2, 16);
# else
movi(r2, 0xffffUL);
# endif
l16 = fallback_bmsr(_jit->pc.w, r1, r2);
rshi_u(r1, r1, 16);
addi(r0, r0, 16);
fallback_patch_at(l16, _jit->pc.w);
rshi(r2, r2, 8);
l8 = fallback_bmsr(_jit->pc.w, r1, r2);
rshi_u(r1, r1, 8);
addi(r0, r0, 8);
fallback_patch_at(l8, _jit->pc.w);
rshi(r2, r2, 4);
l4 = fallback_bmsr(_jit->pc.w, r1, r2);
rshi_u(r1, r1, 4);
addi(r0, r0, 4);
fallback_patch_at(l4, _jit->pc.w);
rshi(r2, r2, 2);
l2 = fallback_bmsr(_jit->pc.w, r1, r2);
rshi_u(r1, r1, 2);
addi(r0, r0, 2);
fallback_patch_at(l2, _jit->pc.w);
rshi(r2, r2, 1);
l1 = fallback_bmsr(_jit->pc.w, r1, r2);
addi(r0, r0, 1);
fallback_patch_at(l1, _jit->pc.w);
fallback_patch_jmpi(ctz, _jit->pc.w);
jit_unget_reg(r2_reg);
jit_unget_reg(r1_reg);
}
#endif
+125 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -648,18 +648,25 @@ static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
#define movi_p(r0,i0) _movi_p(_jit,r0,i0)
static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
# define bswapr_us(r0, r1) _bswapr_us(_jit, r0, r1)
static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ui(r0, r1) _bswapr_ui(_jit, r0, r1)
static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_word_t);
#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
#define comr(r0,r1) UADDCM(_R0_REGNO,r1,r0)
#define negr(r0,r1) SUB(_R0_REGNO,r1,r0)
#define extr_c(r0,r1) EXTRWR(r1,31,8,r0)
#define extr_uc(r0,r1) EXTRWR_U(r1,31,8,r0)
#define extr_s(r0,r1) EXTRWR(r1,31,16,r0)
#define extr_us(r0,r1) EXTRWR_U(r1,31,16,r0)
#if __BYTE_ORDER == __BIG_ENDIAN
# define htonr_us(r0,r1) extr_us(r0,r1)
# define htonr_ui(r0,r1) movr(r0,r1)
#else
# error need htonr implementation
#endif
#define addr(r0,r1,r2) ADD(r1,r2,r0)
#define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@@ -907,7 +914,7 @@ static jit_word_t _bxsubi_u(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t);
#define jmpr(r0) _jmpr(_jit,r0)
static void _jmpr(jit_state_t*,jit_int32_t);
#define jmpi(i0) _jmpi(_jit,i0)
static void _jmpi(jit_state_t*,jit_word_t);
static jit_word_t _jmpi(jit_state_t*,jit_word_t);
#define jmpi_p(i0) _jmpi_p(_jit,i0)
static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
#define callr(r0) _callr(_jit,r0)
@@ -1633,6 +1640,108 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
return (w);
}
static void
_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (r0 == r1) {
reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), r1);
EXTRWR_U(rn(reg), 23, 8, r0);
DEPWR(rn(reg), 23, 8, r0);
jit_unget_reg(reg);
}
else {
EXTRWR_U(r1, 23, 8, r0);
DEPWR(r1, 23, 8, r0);
}
}
static void
_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
if (r0 == r1) {
reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), r1);
SHRPWI(rn(reg), rn(reg), 16, r0);
DEPWR(r0, 15, 8, r0);
SHRPWI(rn(reg), r0, 8, r0);
jit_unget_reg(reg);
}
else {
SHRPWI(r1, r1, 16, r0);
DEPWR(r0, 15, 8, r0);
SHRPWI(r1, r0, 8, r0);
}
}
static void
_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_word_t w;
w = beqi(_jit->pc.w, r2, 0);
COPY(r1, r0);
patch_at(w, _jit->pc.w);
}
static void
_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_word_t w;
w = bnei(_jit->pc.w, r2, 0);
COPY(r1, r0);
patch_at(w, _jit->pc.w);
}
static void
_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
#if defined(__linux__) && defined(SYS_atomic_cmpxchg_32) && __WORDSIZE == 32
/* Not defined, and unlikely to ever be defined, but could be a way to do it */
movi(_R26_REGNO, SYS_atomic_cmpxchg_32);
if (r1 == _NOREG)
movi(_R25_REGNO, i0);
else
movr(_R25_REGNO, r1);
movr(_R24_REGNO, r2);
movr(_R23_REGNO, r3);
/* Should only fail for an invalid or unaligned address.
* Do not handle this condition. */
calli(syscall);
movr(r0, _R28_REGNO);
#else
/*
* The only atomic operations are LDCW and LDCD, that load a value,
* and store zero at the address atomically. The (semaphore) address
* must be 16 byte aligned.
*/
fallback_casx(r0, r1, r2, r3, i0);
/*
* It is important to be aware of the delayed nature of cache flush and
* purge operations, and to use SYNC instructions to force completion
* where necessary. The following example illustrates this.
* Consider two processes sharing a memory location x which is protected
* by a semaphore s.
*
* process A on Processor 1 | process B on Processor 2 | note
* -------------------------+---------------------------+------------
* LDCW s | | A acquires semaphore
* PDC x | | A executes purge
* SYNC | | Force completion of purge
* STW s | | A releases semaphore
* | LDCW s | B acquires semaphore
* | STW x
*
* In the absence of the SYNC instruction, it would be possible for
* process B's store to x to complete before the purge of x is completed
* (since the purge may have been delayed). The purge of x could then
* destroy the new value.
*/
#endif
}
static void
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
@@ -2561,17 +2670,19 @@ _jmpr(jit_state_t *_jit, jit_int32_t r0)
BV_N(_R0_REGNO, r0);
}
static void
static jit_word_t
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t w;
w = ((i0 - _jit->pc.w) >> 2) - 2;
if (w >= -32768 && w <= 32767)
B_N(w, _R0_REGNO);
jit_word_t d, w;
w = _jit->pc.w;
d = ((i0 - w) >> 2) - 2;
if (d >= -32768 && d <= 32767)
B_N(d, _R0_REGNO);
else {
movi(_R1_REGNO, w);
movi(_R1_REGNO, d);
BV_N(_R0_REGNO, _R1_REGNO);
}
return (w);
}
static jit_word_t
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
+158 -107
View File
@@ -1,20 +1,24 @@
#if __WORDSIZE == 32
#define JIT_INSTR_MAX 64
#define JIT_INSTR_MAX 196
0, /* data */
0, /* live */
0, /* align */
28, /* align */
0, /* save */
0, /* load */
0, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
64, /* prolog */
156, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -22,11 +26,23 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
20, /* va_arg_d */
0, /* va_end */
4, /* addr */
12, /* addi */
@@ -40,13 +56,13 @@
12, /* subci */
4, /* subxr */
8, /* subxi */
16, /* rsbi */
28, /* mulr */
36, /* muli */
12, /* rsbi */
48, /* mulr */
56, /* muli */
40, /* qmulr */
44, /* qmuli */
32, /* qmulr_u */
40, /* qmuli_u */
52, /* qmulr_u */
60, /* qmuli_u */
36, /* divr */
40, /* divi */
36, /* divr_u */
@@ -95,15 +111,22 @@
8, /* nei */
4, /* movr */
8, /* movi */
12, /* movnr */
12, /* movzr */
88, /* casr */
96, /* casi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
12, /* bswapr_us */
16, /* bswapr_ui */
0, /* bswapr_ul */
4, /* htonr_us */
4, /* htonr_ui */
0, /* htonr_l */
0, /* htonr_ul */
8, /* ldr_c */
12, /* ldi_c */
4, /* ldr_uc */
@@ -119,15 +142,15 @@
0, /* ldr_l */
0, /* ldi_l */
8, /* ldxr_c */
8, /* ldxi_c */
12, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
8, /* ldxi_uc */
8, /* ldxr_s */
8, /* ldxi_s */
12, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
8, /* ldxi_us */
4, /* ldxr_i */
4, /* ldxi_i */
8, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
0, /* ldxr_l */
@@ -141,11 +164,11 @@
0, /* str_l */
0, /* sti_l */
8, /* stxr_c */
4, /* stxi_c */
12, /* stxi_c */
8, /* stxr_s */
4, /* stxi_s */
12, /* stxi_s */
8, /* stxr_i */
4, /* stxi_i */
12, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
8, /* bltr */
@@ -188,18 +211,42 @@
16, /* bxsubi */
16, /* bxsubr_u */
20, /* bxsubi_u */
0, /* jmpr */
4, /* jmpr */
12, /* jmpi */
40, /* callr */
44, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -207,93 +254,93 @@
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
64, /* epilog */
196, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
16, /* addi_f */
24, /* addi_f */
4, /* subr_f */
16, /* subi_f */
16, /* rsbi_f */
24, /* subi_f */
24, /* rsbi_f */
4, /* mulr_f */
16, /* muli_f */
24, /* muli_f */
4, /* divr_f */
16, /* divi_f */
24, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
16, /* ltr_f */
28, /* lti_f */
36, /* lti_f */
16, /* ler_f */
28, /* lei_f */
36, /* lei_f */
16, /* eqr_f */
28, /* eqi_f */
36, /* eqi_f */
16, /* ger_f */
28, /* gei_f */
36, /* gei_f */
16, /* gtr_f */
28, /* gti_f */
36, /* gti_f */
16, /* ner_f */
28, /* nei_f */
36, /* nei_f */
16, /* unltr_f */
28, /* unlti_f */
36, /* unlti_f */
16, /* unler_f */
28, /* unlei_f */
36, /* unlei_f */
16, /* uneqr_f */
28, /* uneqi_f */
36, /* uneqi_f */
16, /* unger_f */
28, /* ungei_f */
36, /* ungei_f */
16, /* ungtr_f */
28, /* ungti_f */
36, /* ungti_f */
16, /* ltgtr_f */
28, /* ltgti_f */
36, /* ltgti_f */
16, /* ordr_f */
28, /* ordi_f */
36, /* ordi_f */
16, /* unordr_f */
28, /* unordi_f */
12, /* truncr_f_i */
36, /* unordi_f */
16, /* truncr_f_i */
0, /* truncr_f_l */
12, /* extr_f */
20, /* extr_f */
4, /* extr_d_f */
4, /* movr_f */
12, /* movi_f */
20, /* movi_f */
4, /* ldr_f */
12, /* ldi_f */
4, /* ldxr_f */
4, /* ldxi_f */
8, /* ldxr_f */
12, /* ldxi_f */
4, /* str_f */
12, /* sti_f */
8, /* stxr_f */
4, /* stxi_f */
12, /* stxi_f */
16, /* bltr_f */
28, /* blti_f */
36, /* blti_f */
16, /* bler_f */
28, /* blei_f */
36, /* blei_f */
16, /* beqr_f */
28, /* beqi_f */
36, /* beqi_f */
16, /* bger_f */
28, /* bgei_f */
36, /* bgei_f */
16, /* bgtr_f */
28, /* bgti_f */
36, /* bgti_f */
16, /* bner_f */
28, /* bnei_f */
36, /* bnei_f */
16, /* bunltr_f */
28, /* bunlti_f */
36, /* bunlti_f */
16, /* bunler_f */
28, /* bunlei_f */
36, /* bunlei_f */
16, /* buneqr_f */
28, /* buneqi_f */
36, /* buneqi_f */
16, /* bunger_f */
28, /* bungei_f */
36, /* bungei_f */
16, /* bungtr_f */
28, /* bungti_f */
36, /* bungti_f */
16, /* bltgtr_f */
28, /* bltgti_f */
36, /* bltgti_f */
16, /* bordr_f */
28, /* bordi_f */
36, /* bordi_f */
16, /* bunordr_f */
28, /* bunordi_f */
36, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
@@ -304,87 +351,87 @@
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
24, /* addi_d */
32, /* addi_d */
4, /* subr_d */
24, /* subi_d */
24, /* rsbi_d */
32, /* subi_d */
32, /* rsbi_d */
4, /* mulr_d */
24, /* muli_d */
32, /* muli_d */
4, /* divr_d */
24, /* divi_d */
32, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
16, /* ltr_d */
36, /* lti_d */
44, /* lti_d */
16, /* ler_d */
36, /* lei_d */
44, /* lei_d */
16, /* eqr_d */
36, /* eqi_d */
44, /* eqi_d */
16, /* ger_d */
36, /* gei_d */
44, /* gei_d */
16, /* gtr_d */
36, /* gti_d */
44, /* gti_d */
16, /* ner_d */
36, /* nei_d */
44, /* nei_d */
16, /* unltr_d */
36, /* unlti_d */
44, /* unlti_d */
16, /* unler_d */
36, /* unlei_d */
44, /* unlei_d */
16, /* uneqr_d */
36, /* uneqi_d */
44, /* uneqi_d */
16, /* unger_d */
36, /* ungei_d */
44, /* ungei_d */
16, /* ungtr_d */
36, /* ungti_d */
44, /* ungti_d */
16, /* ltgtr_d */
36, /* ltgti_d */
44, /* ltgti_d */
16, /* ordr_d */
36, /* ordi_d */
44, /* ordi_d */
16, /* unordr_d */
36, /* unordi_d */
12, /* truncr_d_i */
44, /* unordi_d */
16, /* truncr_d_i */
0, /* truncr_d_l */
12, /* extr_d */
20, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
20, /* movi_d */
28, /* movi_d */
4, /* ldr_d */
12, /* ldi_d */
4, /* ldxr_d */
4, /* ldxi_d */
8, /* ldxr_d */
12, /* ldxi_d */
4, /* str_d */
12, /* sti_d */
8, /* stxr_d */
4, /* stxi_d */
12, /* stxi_d */
16, /* bltr_d */
36, /* blti_d */
44, /* blti_d */
16, /* bler_d */
36, /* blei_d */
44, /* blei_d */
16, /* beqr_d */
36, /* beqi_d */
44, /* beqi_d */
16, /* bger_d */
36, /* bgei_d */
44, /* bgei_d */
16, /* bgtr_d */
36, /* bgti_d */
44, /* bgti_d */
16, /* bner_d */
36, /* bnei_d */
44, /* bnei_d */
16, /* bunltr_d */
36, /* bunlti_d */
44, /* bunlti_d */
16, /* bunler_d */
36, /* bunlei_d */
44, /* bunlei_d */
16, /* buneqr_d */
36, /* buneqi_d */
44, /* buneqi_d */
16, /* bunger_d */
36, /* bungei_d */
44, /* bungei_d */
16, /* bungtr_d */
36, /* bungti_d */
44, /* bungti_d */
16, /* bltgtr_d */
36, /* bltgti_d */
44, /* bltgti_d */
16, /* bordr_d */
36, /* bordi_d */
44, /* bordi_d */
16, /* bunordr_d */
36, /* bunordi_d */
44, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
@@ -399,4 +446,8 @@
0, /* movi_d_ww */
0, /* movr_d_w */
0, /* movi_d_w */
160, /* clo */
140, /* clz */
164, /* cto */
144, /* ctz */
#endif /* __WORDSIZE */
+98 -34
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -19,12 +19,17 @@
#include <lightning.h>
#include <lightning/jit_private.h>
#if defined(__linux__)
# include <sys/syscall.h>
# include <unistd.h>
#endif
#define jit_arg_reg_p(i) (i >= 0 && i < 4)
#define PROTO 1
# include "jit_hppa-cpu.c"
# include "jit_hppa-fpu.c"
# include "jit_fallback.c"
#undef PROTO
/*
@@ -240,18 +245,18 @@ _jit_ret(jit_state_t *_jit)
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
_jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
jit_inc_synth_w(retr, u);
jit_code_inc_synth_w(code, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
_jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_inc_synth_w(reti, u);
jit_code_inc_synth_w(code, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
@@ -305,7 +310,7 @@ _jit_epilog(jit_state_t *_jit)
jit_bool_t
_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
{
assert(u->code == jit_code_arg ||
assert((u->code >= jit_code_arg_c && u->code <= jit_code_arg) ||
u->code == jit_code_arg_f || u->code == jit_code_arg_d);
return (jit_arg_reg_p(u->u.w));
}
@@ -338,17 +343,21 @@ _jit_va_push(jit_state_t *_jit, jit_int32_t u)
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
_jit_arg(jit_state_t *_jit, jit_code_t code)
{
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if STRONG_TYPE_CHECKING
assert(code >= jit_code_arg_c && code <= jit_code_arg);
#endif
_jitc->function->self.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else
offset = _jitc->function->self.size;
node = jit_new_node_ww(jit_code_arg, offset,
node = jit_new_node_ww(code, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
@@ -401,7 +410,7 @@ _jit_arg_d(jit_state_t *_jit)
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_c, u, v);
if (v->u.w >= 0)
jit_extr_c(u, _R26 - v->u.w);
@@ -413,7 +422,7 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_uc, u, v);
if (v->u.w >= 0)
jit_extr_uc(u, _R26 - v->u.w);
@@ -425,7 +434,7 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_s, u, v);
if (v->u.w >= 0)
jit_extr_s(u, _R26 - v->u.w);
@@ -437,7 +446,7 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_us, u, v);
if (v->u.w >= 0)
jit_extr_us(u, _R26 - v->u.w);
@@ -449,7 +458,7 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_i, u, v);
if (v->u.w >= 0)
jit_movr(u, _R26 - v->u.w);
@@ -459,10 +468,10 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (v->u.w >= 0)
jit_movr(_R26 - v->u.w, u);
else
@@ -471,11 +480,11 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (v->u.w >= 0)
jit_movi(_R26 - v->u.w, u);
else {
@@ -570,10 +579,10 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
_jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@@ -586,11 +595,11 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
_jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
_jitc->function->call.size -= sizeof(jit_word_t);
if (jit_arg_reg_p(_jitc->function->call.argi)) {
@@ -854,6 +863,7 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
jit_function_t func;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
@@ -969,11 +979,13 @@ _emit_code(jit_state_t *_jit)
jit_regarg_set(node, value);
switch (node->code) {
case jit_code_align:
assert(!(node->u.w & (node->u.w - 1)) &&
node->u.w <= sizeof(jit_word_t));
if (node->u.w == sizeof(jit_word_t) &&
(word = _jit->pc.w & (sizeof(jit_word_t) - 1)))
nop(sizeof(jit_word_t) - word);
/* Must align to a power of two */
assert(!(node->u.w & (node->u.w - 1)));
if ((word = _jit->pc.w & (node->u.w - 1)))
nop(node->u.w - word);
break;
case jit_code_skip:
nop((node->u.w + 3) & ~3);
break;
case jit_code_note: case jit_code_name:
node->u.w = _jit->pc.w;
@@ -1026,6 +1038,16 @@ _emit_code(jit_state_t *_jit)
case_rrw(rsh,);
case_rrr(rsh, _u);
case_rrw(rsh, _u);
case_rrr(movn,);
case_rrr(movz,);
case jit_code_casr:
casr(rn(node->u.w), rn(node->v.w),
rn(node->w.q.l), rn(node->w.q.h));
break;
case jit_code_casi:
casi(rn(node->u.w), node->v.w,
rn(node->w.q.l), rn(node->w.q.h));
break;
case_rr(mov,);
case jit_code_movi:
if (node->flag & jit_flag_node) {
@@ -1046,12 +1068,22 @@ _emit_code(jit_state_t *_jit)
break;
case_rr(neg,);
case_rr(com,);
#define clor(r0, r1) fallback_clo(r0, r1)
#define clzr(r0, r1) fallback_clz(r0, r1)
#define ctor(r0, r1) fallback_cto(r0, r1)
#define ctzr(r0, r1) fallback_ctz(r0, r1)
case_rr(clo,);
case_rr(clz,);
case_rr(cto,);
case_rr(ctz,);
case_rr(ext, _c);
case_rr(ext, _uc);
case_rr(ext, _s);
case_rr(ext, _us);
case_rr(hton, _us);
case_rr(hton, _ui);
case_rr(bswap, _us);
case_rr(bswap, _ui);
case_rrr(lt,);
case_rrw(lt,);
case_rrr(lt, _u);
@@ -1323,7 +1355,12 @@ _emit_code(jit_state_t *_jit)
if (temp->flag & jit_flag_patch)
jmpi(temp->u.w);
else {
word = jmpi_p(_jit->pc.w);
word = _jit->code.length -
(_jit->pc.uc - _jit->code.ptr);
if (word >= -32768 && word <= 32767)
word = jmpi(_jit->pc.w);
else
word = jmpi_p(_jit->pc.w);
patch(word, node);
}
}
@@ -1352,6 +1389,7 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
memcpy(&undo.func, _jitc->function, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
@@ -1372,6 +1410,18 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
/* undo.func.self.aoff and undo.func.regset should not
* be undone, as they will be further updated, and are
* the reason of the undo.
* Note that for hppa use '-' instead of '+' as hppa
* stack grows up */
undo.func.self.aoff = _jitc->function->frame -
_jitc->function->self.aoff;
jit_regset_set(&undo.func.regset, &_jitc->function->regset);
/* allocar information also does not need to be undone */
undo.func.aoffoff = _jitc->function->aoffoff;
undo.func.allocar = _jitc->function->allocar;
memcpy(_jitc->function, &undo.func, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
@@ -1393,24 +1443,37 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_live: case jit_code_ellipsis:
case jit_code_va_push:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_c: case jit_code_arg_s:
case jit_code_arg_i:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_c: case jit_code_reti_c:
case jit_code_retr_uc: case jit_code_reti_uc:
case jit_code_retr_s: case jit_code_reti_s:
case jit_code_retr_us: case jit_code_reti_us:
case jit_code_retr_i: case jit_code_reti_i:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
case jit_code_getarg_s: case jit_code_getarg_us:
case jit_code_getarg_i:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_c: case jit_code_putargi_c:
case jit_code_putargr_uc: case jit_code_putargi_uc:
case jit_code_putargr_s: case jit_code_putargi_s:
case jit_code_putargr_us: case jit_code_putargi_us:
case jit_code_putargr_i: case jit_code_putargi_i:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_c: case jit_code_pushargi_c:
case jit_code_pushargr_uc: case jit_code_pushargi_uc:
case jit_code_pushargr_s: case jit_code_pushargi_s:
case jit_code_pushargr_us: case jit_code_pushargi_us:
case jit_code_pushargr_i: case jit_code_pushargi_i:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
@@ -1455,6 +1518,7 @@ _emit_code(jit_state_t *_jit)
#define CODE 1
# include "jit_hppa-cpu.c"
# include "jit_hppa-fpu.c"
# include "jit_fallback.c"
#undef CODE
void
+185 -63
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -1175,6 +1175,8 @@ static void _X5(jit_state_t*,jit_word_t,
#define ZXT2(r1,r3) I29(0x11,r3,r1)
#define ZXT4(r1,r3) I29(0x12,r3,r1)
# define nop(i0) _nop(_jit,i0)
static void _nop(jit_state_t*, jit_int32_t);
#define addr(r0,r1,r2) ADD(r0,r1,r2)
#define addi(r0,r1,i0) _addi(_jit,r0,r1,i0)
static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@@ -1299,6 +1301,16 @@ static void _gti_u(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
static void _ner(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
#define nei(r0,r1,i0) _nei(_jit,r0,r1,i0)
static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
#define bitswap(r0, r1) _bitswap(_jit, r0, r1)
static void _bitswap(jit_state_t*, jit_int32_t, jit_int32_t);
#define clor(r0, r1) _clor(_jit, r0, r1)
static void _clor(jit_state_t*, jit_int32_t, jit_int32_t);
#define clzr(r0, r1) _clzr(_jit, r0, r1)
static void _clzr(jit_state_t*, jit_int32_t, jit_int32_t);
#define ctor(r0, r1) _ctor(_jit, r0, r1)
static void _ctor(jit_state_t*, jit_int32_t, jit_int32_t);
#define ctzr(r0, r1) _ctzr(_jit, r0, r1)
static void _ctzr(jit_state_t*, jit_int32_t, jit_int32_t);
#define negr(r0,r1) subr(r0,0,r1)
#define comr(r0,r1) ANDCMI(r0,-1,r1)
#define movr(r0,r1) _movr(_jit,r0,r1)
@@ -1307,17 +1319,20 @@ static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
#define movi_p(r0,i0) _movi_p(_jit,r0,i0)
static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define htonr_us(r0,r1) _htonr_us(_jit,r0,r1)
static void _htonr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ui(r0,r1) _htonr_ui(_jit,r0,r1)
static void _htonr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define htonr_ul(r0,r1) MUX1(r0,r1,MUX_REV)
#else
# define htonr_us(r0,r1) extr_us(r0,r1)
# define htonr_ui(r0,r1) extr_ui(r0,r1)
# define htonr_ul(r0,r1) movr(r0,r1)
#endif
# define movnr(r0,r1,r2) _movnr(_jit,r0,r1,r2)
static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define movzr(r0,r1,r2) _movzr(_jit,r0,r1,r2)
static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
# define casx(r0, r1, r2, r3, i0) _casx(_jit, r0, r1, r2, r3, i0)
static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
jit_int32_t,jit_int32_t,jit_word_t);
#define casr(r0, r1, r2, r3) casx(r0, r1, r2, r3, 0)
#define casi(r0, i0, r1, r2) casx(r0, _NOREG, r1, r2, i0)
# define bswapr_us(r0,r1) _bswapr_us(_jit,r0,r1)
static void _bswapr_us(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ui(r0,r1) _bswapr_ui(_jit,r0,r1)
static void _bswapr_ui(jit_state_t*,jit_int32_t,jit_int32_t);
# define bswapr_ul(r0,r1) MUX1(r0,r1,MUX_REV)
#define extr_c(r0,r1) SXT1(r0,r1)
#define extr_uc(r0,r1) ZXT1(r0,r1)
#define extr_s(r0,r1) SXT2(r0,r1)
@@ -1495,7 +1510,7 @@ static void _stxi_l(jit_state_t*,jit_word_t,jit_int32_t,jit_int32_t);
#define jmpr(r0) _jmpr(_jit,r0)
static void _jmpr(jit_state_t*,jit_int32_t);
#define jmpi(i0) _jmpi(_jit,i0)
static void _jmpi(jit_state_t*,jit_word_t);
static jit_word_t _jmpi(jit_state_t*,jit_word_t);
#define jmpi_p(i0) _jmpi_p(_jit,i0)
static jit_word_t _jmpi_p(jit_state_t*,jit_word_t);
#define callr(r0) _callr(_jit,r0)
@@ -1512,7 +1527,7 @@ static void _epilog(jit_state_t*,jit_node_t*);
static void _vastart(jit_state_t*, jit_int32_t);
# define vaarg(r0, r1) _vaarg(_jit, r0, r1)
static void _vaarg(jit_state_t*, jit_int32_t, jit_int32_t);
#define patch_at(node,instr,label) _patch_at(_jit,node,instr,label)
#define patch_at(code,instr,label) _patch_at(_jit,code,instr,label)
static void _patch_at(jit_state_t*,jit_code_t,jit_word_t,jit_word_t);
#endif
@@ -2451,7 +2466,7 @@ _I9(jit_state_t *_jit, jit_word_t _p,
TSTREG1(r3);
TSTPRED(_p);
TSTREG1(r1);
inst((7L<<37)|(1L<<34)|(1L<<34)|(1L<<33)|
inst((7L<<37)|(1L<<34)|(1L<<33)|
(x2<<30)|(1L<<28)|(r3<<20)|(r1<<6)|_p, INST_I);
SETREG(r1);
}
@@ -3026,7 +3041,7 @@ _M29(jit_state_t *_jit, jit_word_t _p,
jit_word_t ar, jit_word_t r2)
{
assert(!(_p & ~0x3fL));
assert(!(ar & ~0x7L));
assert(!(ar & ~0x7fL));
assert(!(r2 & ~0x7fL));
TSTREG1(r2);
TSTPRED(_p);
@@ -3450,6 +3465,104 @@ _X5(jit_state_t *_jit, jit_word_t _p,
inst((i1<<36)|(1L<<27)|(y<<26)|(i20<<6)|_p, INST_X);
}
static void
_nop(jit_state_t *_jit, jit_int32_t i0)
{
for (; i0 > 0; i0 -= 8) {
NOP_M(0);
sync();
}
assert(i0 == 0);
}
static void
_bitswap(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0, t1, t2, t3, t4;
movr(r0, r1);
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
movi(rn(t0), __WORDSIZE == 32 ? 0x55555555L : 0x5555555555555555L);
rshi_u(rn(t1), r0, 1); /* t1 = v >> 1 */
andr(rn(t1), rn(t1), rn(t0)); /* t1 &= t0 */
andr(rn(t2), r0, rn(t0)); /* t2 = v & t0*/
lshi(rn(t2), rn(t2), 1); /* t2 <<= 1 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
movi(rn(t0), __WORDSIZE == 32 ? 0x33333333L : 0x3333333333333333L);
rshi_u(rn(t1), r0, 2); /* t1 = v >> 2 */
andr(rn(t1), rn(t1), rn(t0)); /* t1 &= t0 */
andr(rn(t2), r0, rn(t0)); /* t2 = v & t0*/
lshi(rn(t2), rn(t2), 2); /* t2 <<= 2 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
movi(rn(t0), __WORDSIZE == 32 ? 0x0f0f0f0fL : 0x0f0f0f0f0f0f0f0fL);
rshi_u(rn(t1), r0, 4); /* t1 = v >> 4 */
andr(rn(t1), rn(t1), rn(t0)); /* t1 &= t0 */
andr(rn(t2), r0, rn(t0)); /* t2 = v & t0*/
lshi(rn(t2), rn(t2), 4); /* t2 <<= 4 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
movi(rn(t0), __WORDSIZE == 32 ? 0x00ff00ffL : 0x00ff00ff00ff00ffL);
rshi_u(rn(t1), r0, 8); /* t1 = v >> 8 */
andr(rn(t1), rn(t1), rn(t0)); /* t1 &= t0 */
andr(rn(t2), r0, rn(t0)); /* t2 = v & t0*/
lshi(rn(t2), rn(t2), 8); /* t2 <<= 8 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
movi(rn(t0), 0x0000ffff0000ffffL);
rshi_u(rn(t1), r0, 16); /* t1 = v >> 16 */
andr(rn(t1), rn(t1), rn(t0)); /* t1 &= t0 */
andr(rn(t2), r0, rn(t0)); /* t2 = v & t0*/
lshi(rn(t2), rn(t2), 16); /* t2 <<= 16 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
rshi_u(rn(t1), r0, 32); /* t1 = v >> 32 */
lshi(rn(t2), r0, 32); /* t2 = v << 32 */
orr(r0, rn(t1), rn(t2)); /* v = t1 | t2 */
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
static void
_clzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_cpu.clz)
CLZ(r0, r1);
else
fallback_clz(r0, r1);
}
static void
_clor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_cpu.clz) {
comr(r0, r1);
clzr(r0, r0);
}
else
fallback_clo(r0, r1);
}
static void
_ctor(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_cpu.clz) {
bitswap(r0, r1);
clor(r0, r0);
}
else
fallback_cto(r0, r1);
}
static void
_ctzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
if (jit_cpu.clz) {
bitswap(r0, r1);
clzr(r0, r0);
}
else
fallback_ctz(r0, r1);
}
static void
_movr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
@@ -3483,6 +3596,53 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
return (w);
}
static void
_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
CMP_EQ(PR_6, PR_7, r2, GR_0);
MOV_p(r0, r1, PR_7);
}
static void
_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
CMP_EQ(PR_6, PR_7, r2, GR_0);
MOV_p(r0, r1, PR_6);
}
static void
_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
{
jit_int32_t r1_reg, iscasi;
if ((iscasi = (r1 == _NOREG))) {
r1_reg = jit_get_reg(jit_class_gpr);
r1 = rn(r1_reg);
movi(r1, i0);
}
sync();
MOV_M_ar_rn(AR_CCV, r2);
CMPXCHG8_ACQ(r0, r1, r3);
eqr(r0, r0, r2);
if (iscasi)
jit_unget_reg(r1_reg);
}
static void
_bswapr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
bswapr_ul(r0, r1);
rshi_u(r0, r0, 48);
}
static void
_bswapr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
bswapr_ul(r0, r1);
rshi_u(r0, r0, 32);
}
static void
_addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
@@ -3949,48 +4109,6 @@ _xori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
}
}
#if __BYTE_ORDER == __LITTLE_ENDIAN
static void
_htonr_us(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
t0 = jit_get_reg(jit_class_gpr);
rshi(rn(t0), r1, 8);
andi(r0, r1, 0xff);
andi(rn(t0), rn(t0), 0xff);
lshi(r0, r0, 8);
orr(r0, r0, rn(t0));
jit_unget_reg(t0);
}
static void
_htonr_ui(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t t0;
jit_int32_t t1;
jit_int32_t t2;
t0 = jit_get_reg(jit_class_gpr);
t1 = jit_get_reg(jit_class_gpr);
t2 = jit_get_reg(jit_class_gpr);
rshi(rn(t0), r1, 24);
rshi(rn(t1), r1, 16);
rshi(rn(t2), r1, 8);
andi(rn(t0), rn(t0), 0xff);
andi(rn(t1), rn(t1), 0xff);
andi(rn(t2), rn(t2), 0xff);
andi(r0, r1, 0xff);
lshi(r0, r0, 24);
lshi(rn(t1), rn(t1), 8);
orr(r0, r0, rn(t0));
lshi(rn(t2), rn(t2), 16);
orr(r0, r0, rn(t1));
orr(r0, r0, rn(t2));
jit_unget_reg(t2);
jit_unget_reg(t1);
jit_unget_reg(t0);
}
#endif
static void
_lshi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
@@ -5125,16 +5243,18 @@ _jmpr(jit_state_t *_jit, jit_int32_t r0)
BR(BR_6);
}
static void
static jit_word_t
_jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_word_t d;
jit_word_t d, w;
sync();
d = ((jit_word_t)i0 - _jit->pc.w) >> 4;
w = _jit->pc.w;
d = ((jit_word_t)i0 - w) >> 4;
if (d >= -16777216 && d <= 16777215)
BRI(d);
else
BRL(d);
return (w);
}
static jit_word_t
@@ -5380,14 +5500,16 @@ _patch_at(jit_state_t *_jit, jit_code_t code,
i1 = (ic >> 61) & 0x1L;
i41 = (ic >> 22) & 0x1ffffffffffL;
i20 = ic & 0xfffffL;
assert((tm & ~1) == TM_M_L_X_ &&
if (!((tm & ~1) == TM_M_L_X_ &&
(s2 & 0xfL<<37) == (0xcL<<37) &&
s0 == nop_m);
s0 == nop_m))
goto short_jump;
s1 = i41;
s2 &= (0xcL<<37)|(0x7L<<33)|(1L<<12);
s2 |= (i1<<36)|(i20<<13);
break;
default:
short_jump:
/* Only B1 in slot 0 expected due to need to either
* a stop to update predicates, or a sync before
* unconditional short branch */
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
+62 -12
View File
@@ -1,11 +1,11 @@
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 224
#define JIT_INSTR_MAX 608
0, /* data */
0, /* live */
0, /* align */
48, /* align */
0, /* save */
0, /* load */
16, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
@@ -14,7 +14,10 @@
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
@@ -22,8 +25,20 @@
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr */
0, /* putargi */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
16, /* va_start */
32, /* va_arg */
32, /* va_arg_d */
@@ -95,14 +110,21 @@
32, /* nei */
16, /* movr */
16, /* movi */
16, /* movnr */
16, /* movzr */
48, /* casr */
64, /* casi */
16, /* extr_c */
16, /* extr_uc */
16, /* extr_s */
16, /* extr_us */
16, /* extr_i */
16, /* extr_ui */
64, /* htonr_us */
160, /* htonr_ui */
32, /* bswapr_us */
32, /* bswapr_ui */
16, /* bswapr_ul */
32, /* htonr_us */
32, /* htonr_ui */
16, /* htonr_ul */
16, /* ldr_c */
32, /* ldi_c */
@@ -193,13 +215,37 @@
32, /* callr */
48, /* calli */
0, /* prepare */
0, /* pushargr */
0, /* pushargi */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr */
0, /* reti */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
@@ -399,4 +445,8 @@
0, /* movi_d_ww */
16, /* movr_d_w */
32, /* movi_d_w */
608, /* clo */
544, /* clz */
608, /* cto */
544, /* ctz */
#endif /* __WORDSIZE */
+107 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -52,11 +52,13 @@ extern void __clear_cache(void *, void *);
#define PROTO 1
# include "jit_ia64-cpu.c"
# include "jit_ia64-fpu.c"
# include "jit_fallback.c"
#undef PROTO
/*
* Initialization
*/
jit_cpu_t jit_cpu;
jit_register_t _rvs[] = {
/* Always 0 */
{ 0, "r0" },
@@ -238,6 +240,11 @@ jit_register_t _rvs[] = {
void
jit_get_cpu(void)
{
jit_word_t clz = -1;
__asm__ volatile("tf.nz.unc p6,p7=32;(p6)mov %0=1;(p7)mov %0=0"
: "=r" (clz));
assert(clz == 0 || clz == 1);
jit_cpu.clz = clz;
}
void
@@ -344,18 +351,18 @@ _jit_ret(jit_state_t *_jit)
}
void
_jit_retr(jit_state_t *_jit, jit_int32_t u)
_jit_retr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
jit_inc_synth_w(retr, u);
jit_code_inc_synth_w(code, u);
jit_movr(JIT_RET, u);
jit_ret();
jit_dec_synth();
}
void
_jit_reti(jit_state_t *_jit, jit_word_t u)
_jit_reti(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_inc_synth_w(reti, u);
jit_code_inc_synth_w(code, u);
jit_movi(JIT_RET, u);
jit_ret();
jit_dec_synth();
@@ -409,9 +416,10 @@ _jit_epilog(jit_state_t *_jit)
jit_bool_t
_jit_arg_register_p(jit_state_t *_jit, jit_node_t *u)
{
assert(u->code == jit_code_arg ||
u->code == jit_code_arg_f || u->code == jit_code_arg_d);
return (jit_arg_reg_p(u->u.w));
if (u->code >= jit_code_arg_c && u->code <= jit_code_arg)
return (jit_arg_reg_p(u->u.w));
assert(u->code == jit_code_arg_f || u->code == jit_code_arg_d);
return (jit_arg_reg_p(u->u.w) || jit_arg_reg_p(u->u.w - 8));
}
void
@@ -441,18 +449,22 @@ _jit_va_push(jit_state_t *_jit, jit_int32_t u)
}
jit_node_t *
_jit_arg(jit_state_t *_jit)
_jit_arg(jit_state_t *_jit, jit_code_t code)
{
jit_node_t *node;
jit_int32_t offset;
assert(_jitc->function);
assert(!(_jitc->function->self.call & jit_call_varargs));
#if STRONG_TYPE_CHECKING
assert(code >= jit_code_arg_c && code <= jit_code_arg);
#endif
if (jit_arg_reg_p(_jitc->function->self.argi))
offset = _jitc->function->self.argi++;
else {
offset = _jitc->function->self.size;
_jitc->function->self.size += sizeof(jit_word_t);
}
node = jit_new_node_ww(jit_code_arg, offset,
node = jit_new_node_ww(code, offset,
++_jitc->function->self.argn);
jit_link_prolog();
return (node);
@@ -507,7 +519,7 @@ _jit_arg_d(jit_state_t *_jit)
void
_jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_c, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, _R32 + v->u.w);
@@ -519,7 +531,7 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_c);
jit_inc_synth_wp(getarg_uc, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, _R32 + v->u.w);
@@ -531,7 +543,7 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_s, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, _R32 + v->u.w);
@@ -543,7 +555,7 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_s);
jit_inc_synth_wp(getarg_us, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, _R32 + v->u.w);
@@ -555,7 +567,7 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_i, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_i(u, _R32 + v->u.w);
@@ -567,7 +579,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_i);
jit_inc_synth_wp(getarg_ui, u, v);
if (jit_arg_reg_p(v->u.w))
jit_extr_ui(u, _R32 + v->u.w);
@@ -579,7 +591,7 @@ _jit_getarg_ui(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
void
_jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
assert_arg_type(v->code, jit_code_arg_l);
jit_inc_synth_wp(getarg_l, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(u, _R32 + v->u.w);
@@ -589,10 +601,10 @@ _jit_getarg_l(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
_jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v, jit_code_t code)
{
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargr, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movr(_R32 + v->u.w, u);
else
@@ -601,11 +613,11 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
}
void
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
_jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v, jit_code_t code)
{
jit_int32_t regno;
assert(v->code == jit_code_arg);
jit_inc_synth_wp(putargi, u, v);
assert_putarg_type(code, v->code);
jit_code_inc_synth_wp(code, u, v);
if (jit_arg_reg_p(v->u.w))
jit_movi(_R32 + v->u.w, u);
else {
@@ -712,10 +724,10 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
}
void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u)
_jit_pushargr(jit_state_t *_jit, jit_int32_t u, jit_code_t code)
{
assert(_jitc->function);
jit_inc_synth_w(pushargr, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movr(_OUT0 + _jitc->function->call.argi, u);
@@ -729,11 +741,11 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
}
void
_jit_pushargi(jit_state_t *_jit, jit_word_t u)
_jit_pushargi(jit_state_t *_jit, jit_word_t u, jit_code_t code)
{
jit_int32_t regno;
assert(_jitc->function);
jit_inc_synth_w(pushargi, u);
jit_code_inc_synth_w(code, u);
jit_link_prepare();
if (jit_arg_reg_p(_jitc->function->call.argi)) {
jit_movi(_OUT0 + _jitc->function->call.argi, u);
@@ -972,6 +984,7 @@ _emit_code(jit_state_t *_jit)
struct {
jit_node_t *node;
jit_word_t word;
jit_function_t func;
#if DEVEL_DISASSEMBLER
jit_word_t prevw;
#endif
@@ -1116,9 +1129,14 @@ _emit_code(jit_state_t *_jit)
jit_regarg_set(node, value);
switch (node->code) {
case jit_code_align:
assert(!(node->u.w & (node->u.w - 1)) &&
node->u.w <= sizeof(jit_word_t));
/* nothing done */
assert(!(node->u.w & (node->u.w - 1)));
sync();
if (node->u.w > 8)
nop(node->u.w - 8);
break;
case jit_code_skip:
sync();
nop((node->u.w + 7) & ~7);
break;
case jit_code_note: case jit_code_name:
sync();
@@ -1175,6 +1193,20 @@ _emit_code(jit_state_t *_jit)
case_rrw(rsh, _u);
case_rr(neg,);
case_rr(com,);
case_rr(clo,);
case_rr(clz,);
case_rr(cto,);
case_rr(ctz,);
case jit_code_casr:
casr(rn(node->u.w), rn(node->v.w),
rn(node->w.q.l), rn(node->w.q.h));
break;
case jit_code_casi:
casi(rn(node->u.w), node->v.w,
rn(node->w.q.l), rn(node->w.q.h));
break;
case_rrr(movn,);
case_rrr(movz,);
case_rr(mov,);
case jit_code_movi:
if (node->flag & jit_flag_node) {
@@ -1196,6 +1228,9 @@ _emit_code(jit_state_t *_jit)
case_rr(hton, _us);
case_rr(hton, _ui);
case_rr(hton, _ul);
case_rr(bswap, _us);
case_rr(bswap, _ui);
case_rr(bswap, _ul);
case_rr(ext, _c);
case_rr(ext, _uc);
case_rr(ext, _s);
@@ -1489,7 +1524,12 @@ _emit_code(jit_state_t *_jit)
if (temp->flag & jit_flag_patch)
jmpi(temp->u.w);
else {
word = jmpi_p(_jit->pc.w);
word = _jit->code.length -
(_jit->pc.uc - _jit->code.ptr);
if (word >= -16777216 && word <= 16777215)
word = jmpi(_jit->pc.w);
else
word = jmpi_p(_jit->pc.w);
patch(word, node);
}
}
@@ -1518,6 +1558,7 @@ _emit_code(jit_state_t *_jit)
_jitc->function = _jitc->functions.ptr + node->w.w;
undo.node = node;
undo.word = _jit->pc.w;
memcpy(&undo.func, _jitc->function, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
undo.prevw = prevw;
#endif
@@ -1556,6 +1597,16 @@ _emit_code(jit_state_t *_jit)
temp->flag &= ~jit_flag_patch;
node = undo.node;
_jit->pc.w = undo.word;
/* undo.func.self.aoff and undo.func.regset should not
* be undone, as they will be further updated, and are
* the reason of the undo. */
undo.func.self.aoff = _jitc->function->frame +
_jitc->function->self.aoff;
jit_regset_set(&undo.func.regset, &_jitc->function->regset);
/* allocar information also does not need to be undone */
undo.func.aoffoff = _jitc->function->aoffoff;
undo.func.allocar = _jitc->function->allocar;
memcpy(_jitc->function, &undo.func, sizeof(undo.func));
#if DEVEL_DISASSEMBLER
prevw = undo.prevw;
#endif
@@ -1584,14 +1635,21 @@ _emit_code(jit_state_t *_jit)
case jit_code_va_arg_d:
vaarg_d(rn(node->u.w), rn(node->v.w));
break;
case jit_code_live:
case jit_code_arg: case jit_code_ellipsis:
case jit_code_live: case jit_code_ellipsis:
case jit_code_va_push:
case jit_code_allocai: case jit_code_allocar:
case jit_code_arg_c: case jit_code_arg_s:
case jit_code_arg_i: case jit_code_arg_l:
case jit_code_arg_f: case jit_code_arg_d:
case jit_code_va_end:
case jit_code_ret:
case jit_code_retr: case jit_code_reti:
case jit_code_retr_c: case jit_code_reti_c:
case jit_code_retr_uc: case jit_code_reti_uc:
case jit_code_retr_s: case jit_code_reti_s:
case jit_code_retr_us: case jit_code_reti_us:
case jit_code_retr_i: case jit_code_reti_i:
case jit_code_retr_ui: case jit_code_reti_ui:
case jit_code_retr_l: case jit_code_reti_l:
case jit_code_retr_f: case jit_code_reti_f:
case jit_code_retr_d: case jit_code_reti_d:
case jit_code_getarg_c: case jit_code_getarg_uc:
@@ -1599,10 +1657,22 @@ _emit_code(jit_state_t *_jit)
case jit_code_getarg_i: case jit_code_getarg_ui:
case jit_code_getarg_l:
case jit_code_getarg_f: case jit_code_getarg_d:
case jit_code_putargr: case jit_code_putargi:
case jit_code_putargr_c: case jit_code_putargi_c:
case jit_code_putargr_uc: case jit_code_putargi_uc:
case jit_code_putargr_s: case jit_code_putargi_s:
case jit_code_putargr_us: case jit_code_putargi_us:
case jit_code_putargr_i: case jit_code_putargi_i:
case jit_code_putargr_ui: case jit_code_putargi_ui:
case jit_code_putargr_l: case jit_code_putargi_l:
case jit_code_putargr_f: case jit_code_putargi_f:
case jit_code_putargr_d: case jit_code_putargi_d:
case jit_code_pushargr: case jit_code_pushargi:
case jit_code_pushargr_c: case jit_code_pushargi_c:
case jit_code_pushargr_uc: case jit_code_pushargi_uc:
case jit_code_pushargr_s: case jit_code_pushargi_s:
case jit_code_pushargr_us: case jit_code_pushargi_us:
case jit_code_pushargr_i: case jit_code_pushargi_i:
case jit_code_pushargr_ui: case jit_code_pushargi_ui:
case jit_code_pushargr_l: case jit_code_pushargi_l:
case jit_code_pushargr_f: case jit_code_pushargi_f:
case jit_code_pushargr_d: case jit_code_pushargi_d:
case jit_code_retval_c: case jit_code_retval_uc:
@@ -1688,6 +1758,7 @@ _emit_code(jit_state_t *_jit)
#define CODE 1
# include "jit_ia64-cpu.c"
# include "jit_ia64-fpu.c"
# include "jit_fallback.c"
#undef CODE
void
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,452 @@
#if __WORDSIZE == 64
#define JIT_INSTR_MAX 88
0, /* data */
0, /* live */
28, /* align */
0, /* save */
0, /* load */
4, /* skip */
0, /* #name */
0, /* #note */
0, /* label */
88, /* prolog */
0, /* ellipsis */
0, /* va_push */
0, /* allocai */
0, /* allocar */
0, /* arg_c */
0, /* arg_s */
0, /* arg_i */
0, /* arg_l */
0, /* getarg_c */
0, /* getarg_uc */
0, /* getarg_s */
0, /* getarg_us */
0, /* getarg_i */
0, /* getarg_ui */
0, /* getarg_l */
0, /* putargr_c */
0, /* putargi_c */
0, /* putargr_uc */
0, /* putargi_uc */
0, /* putargr_s */
0, /* putargi_s */
0, /* putargr_us */
0, /* putargi_us */
0, /* putargr_i */
0, /* putargi_i */
0, /* putargr_ui */
0, /* putargi_ui */
0, /* putargr_l */
0, /* putargi_l */
4, /* va_start */
8, /* va_arg */
8, /* va_arg_d */
0, /* va_end */
4, /* addr */
20, /* addi */
12, /* addcr */
28, /* addci */
28, /* addxr */
28, /* addxi */
4, /* subr */
20, /* subi */
12, /* subcr */
28, /* subci */
28, /* subxr */
28, /* subxi */
24, /* rsbi */
4, /* mulr */
20, /* muli */
12, /* qmulr */
24, /* qmuli */
12, /* qmulr_u */
24, /* qmuli_u */
4, /* divr */
20, /* divi */
4, /* divr_u */
20, /* divi_u */
12, /* qdivr */
12, /* qdivi */
12, /* qdivr_u */
12, /* qdivi_u */
4, /* remr */
20, /* remi */
4, /* remr_u */
20, /* remi_u */
4, /* andr */
20, /* andi */
4, /* orr */
20, /* ori */
4, /* xorr */
20, /* xori */
4, /* lshr */
4, /* lshi */
4, /* rshr */
4, /* rshi */
4, /* rshr_u */
4, /* rshi_u */
4, /* negr */
4, /* comr */
4, /* ltr */
4, /* lti */
4, /* ltr_u */
4, /* lti_u */
8, /* ler */
4, /* lei */
8, /* ler_u */
4, /* lei_u */
12, /* eqr */
12, /* eqi */
8, /* ger */
8, /* gei */
8, /* ger_u */
8, /* gei_u */
4, /* gtr */
8, /* gti */
4, /* gtr_u */
8, /* gti_u */
8, /* ner */
8, /* nei */
4, /* movr */
16, /* movi */
12, /* movnr */
12, /* movzr */
32, /* casr */
44, /* casi */
4, /* extr_c */
4, /* extr_uc */
4, /* extr_s */
4, /* extr_us */
4, /* extr_i */
4, /* extr_ui */
8, /* bswapr_us */
8, /* bswapr_ui */
4, /* bswapr_ul */
8, /* htonr_us */
8, /* htonr_ui */
4, /* htonr_ul */
4, /* ldr_c */
20, /* ldi_c */
4, /* ldr_uc */
20, /* ldi_uc */
4, /* ldr_s */
20, /* ldi_s */
4, /* ldr_us */
20, /* ldi_us */
4, /* ldr_i */
20, /* ldi_i */
4, /* ldr_ui */
20, /* ldi_ui */
4, /* ldr_l */
20, /* ldi_l */
4, /* ldxr_c */
16, /* ldxi_c */
4, /* ldxr_uc */
16, /* ldxi_uc */
4, /* ldxr_s */
16, /* ldxi_s */
4, /* ldxr_us */
16, /* ldxi_us */
4, /* ldxr_i */
16, /* ldxi_i */
4, /* ldxr_ui */
16, /* ldxi_ui */
4, /* ldxr_l */
16, /* ldxi_l */
4, /* str_c */
20, /* sti_c */
4, /* str_s */
20, /* sti_s */
4, /* str_i */
20, /* sti_i */
4, /* str_l */
20, /* sti_l */
4, /* stxr_c */
16, /* stxi_c */
4, /* stxr_s */
16, /* stxi_s */
4, /* stxr_i */
16, /* stxi_i */
4, /* stxr_l */
16, /* stxi_l */
4, /* bltr */
8, /* blti */
4, /* bltr_u */
8, /* blti_u */
8, /* bler */
12, /* blei */
8, /* bler_u */
12, /* blei_u */
4, /* beqr */
20, /* beqi */
4, /* bger */
8, /* bgei */
4, /* bger_u */
8, /* bgei_u */
8, /* bgtr */
12, /* bgti */
8, /* bgtr_u */
12, /* bgti_u */
4, /* bner */
20, /* bnei */
8, /* bmsr */
8, /* bmsi */
8, /* bmcr */
8, /* bmci */
32, /* boaddr */
36, /* boaddi */
16, /* boaddr_u */
20, /* boaddi_u */
32, /* bxaddr */
36, /* bxaddi */
16, /* bxaddr_u */
20, /* bxaddi_u */
32, /* bosubr */
36, /* bosubi */
16, /* bosubr_u */
20, /* bosubi_u */
32, /* bxsubr */
36, /* bxsubi */
16, /* bxsubr_u */
20, /* bxsubi_u */
4, /* jmpr */
20, /* jmpi */
4, /* callr */
20, /* calli */
0, /* prepare */
0, /* pushargr_c */
0, /* pushargi_c */
0, /* pushargr_uc */
0, /* pushargi_uc */
0, /* pushargr_s */
0, /* pushargi_s */
0, /* pushargr_us */
0, /* pushargi_us */
0, /* pushargr_i */
0, /* pushargi_i */
0, /* pushargr_ui */
0, /* pushargi_ui */
0, /* pushargr_l */
0, /* pushargi_l */
0, /* finishr */
0, /* finishi */
0, /* ret */
0, /* retr_c */
0, /* reti_c */
0, /* retr_uc */
0, /* reti_uc */
0, /* retr_s */
0, /* reti_s */
0, /* retr_us */
0, /* reti_us */
0, /* retr_i */
0, /* reti_i */
0, /* retr_ui */
0, /* reti_ui */
0, /* retr_l */
0, /* reti_l */
0, /* retval_c */
0, /* retval_uc */
0, /* retval_s */
0, /* retval_us */
0, /* retval_i */
0, /* retval_ui */
0, /* retval_l */
88, /* epilog */
0, /* arg_f */
0, /* getarg_f */
0, /* putargr_f */
0, /* putargi_f */
4, /* addr_f */
12, /* addi_f */
4, /* subr_f */
12, /* subi_f */
12, /* rsbi_f */
4, /* mulr_f */
12, /* muli_f */
4, /* divr_f */
12, /* divi_f */
4, /* negr_f */
4, /* absr_f */
4, /* sqrtr_f */
8, /* ltr_f */
16, /* lti_f */
8, /* ler_f */
16, /* lei_f */
8, /* eqr_f */
16, /* eqi_f */
8, /* ger_f */
16, /* gei_f */
8, /* gtr_f */
16, /* gti_f */
8, /* ner_f */
16, /* nei_f */
8, /* unltr_f */
16, /* unlti_f */
8, /* unler_f */
16, /* unlei_f */
8, /* uneqr_f */
16, /* uneqi_f */
8, /* unger_f */
16, /* ungei_f */
8, /* ungtr_f */
16, /* ungti_f */
8, /* ltgtr_f */
16, /* ltgti_f */
8, /* ordr_f */
16, /* ordi_f */
12, /* unordr_f */
20, /* unordi_f */
8, /* truncr_f_i */
8, /* truncr_f_l */
8, /* extr_f */
4, /* extr_d_f */
4, /* movr_f */
8, /* movi_f */
4, /* ldr_f */
20, /* ldi_f */
4, /* ldxr_f */
16, /* ldxi_f */
4, /* str_f */
20, /* sti_f */
4, /* stxr_f */
16, /* stxi_f */
8, /* bltr_f */
16, /* blti_f */
8, /* bler_f */
16, /* blei_f */
8, /* beqr_f */
16, /* beqi_f */
8, /* bger_f */
16, /* bgei_f */
8, /* bgtr_f */
16, /* bgti_f */
8, /* bner_f */
16, /* bnei_f */
8, /* bunltr_f */
16, /* bunlti_f */
8, /* bunler_f */
16, /* bunlei_f */
8, /* buneqr_f */
16, /* buneqi_f */
8, /* bunger_f */
16, /* bungei_f */
8, /* bungtr_f */
16, /* bungti_f */
8, /* bltgtr_f */
16, /* bltgti_f */
8, /* bordr_f */
16, /* bordi_f */
8, /* bunordr_f */
16, /* bunordi_f */
0, /* pushargr_f */
0, /* pushargi_f */
0, /* retr_f */
0, /* reti_f */
0, /* retval_f */
0, /* arg_d */
0, /* getarg_d */
0, /* putargr_d */
0, /* putargi_d */
4, /* addr_d */
20, /* addi_d */
4, /* subr_d */
20, /* subi_d */
16, /* rsbi_d */
4, /* mulr_d */
20, /* muli_d */
4, /* divr_d */
20, /* divi_d */
4, /* negr_d */
4, /* absr_d */
4, /* sqrtr_d */
8, /* ltr_d */
24, /* lti_d */
8, /* ler_d */
24, /* lei_d */
8, /* eqr_d */
24, /* eqi_d */
8, /* ger_d */
24, /* gei_d */
8, /* gtr_d */
24, /* gti_d */
8, /* ner_d */
24, /* nei_d */
8, /* unltr_d */
24, /* unlti_d */
8, /* unler_d */
24, /* unlei_d */
8, /* uneqr_d */
24, /* uneqi_d */
8, /* unger_d */
24, /* ungei_d */
8, /* ungtr_d */
24, /* ungti_d */
8, /* ltgtr_d */
24, /* ltgti_d */
8, /* ordr_d */
24, /* ordi_d */
12, /* unordr_d */
28, /* unordi_d */
8, /* truncr_d_i */
8, /* truncr_d_l */
8, /* extr_d */
4, /* extr_f_d */
4, /* movr_d */
16, /* movi_d */
4, /* ldr_d */
20, /* ldi_d */
4, /* ldxr_d */
16, /* ldxi_d */
4, /* str_d */
20, /* sti_d */
4, /* stxr_d */
16, /* stxi_d */
8, /* bltr_d */
20, /* blti_d */
8, /* bler_d */
20, /* blei_d */
8, /* beqr_d */
24, /* beqi_d */
8, /* bger_d */
24, /* bgei_d */
8, /* bgtr_d */
24, /* bgti_d */
8, /* bner_d */
24, /* bnei_d */
8, /* bunltr_d */
24, /* bunlti_d */
8, /* bunler_d */
24, /* bunlei_d */
8, /* buneqr_d */
24, /* buneqi_d */
8, /* bunger_d */
24, /* bungei_d */
8, /* bungtr_d */
24, /* bungti_d */
8, /* bltgtr_d */
24, /* bltgti_d */
8, /* bordr_d */
20, /* bordi_d */
8, /* bunordr_d */
24, /* bunordi_d */
0, /* pushargr_d */
0, /* pushargi_d */
0, /* retr_d */
0, /* reti_d */
0, /* retval_d */
4, /* movr_w_f */
0, /* movr_ww_d */
4, /* movr_w_d */
0, /* movr_f_w */
4, /* movi_f_w */
0, /* movr_d_ww */
0, /* movi_d_ww */
4, /* movr_d_w */
12, /* movi_d_w */
4, /* clo */
4, /* clz */
4, /* cto */
4, /* ctz */
#endif /* __WORDSIZE */
File diff suppressed because it is too large. Load diff
+1 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2019 Free Software Foundation, Inc.
* Copyright (C) 2013-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -19,7 +19,6 @@
#include <lightning.h>
#include <lightning/jit_private.h>
#include <sys/mman.h>
/*
* Prototypes
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2019 Free Software Foundation, Inc.
* Copyright (C) 2012-2023 Free Software Foundation, Inc.
*
* This file is part of GNU lightning.
*
@@ -220,7 +220,7 @@ static void _divi_d(jit_state_t*,jit_int32_t,jit_int32_t,jit_float64_t*);
# define sqrtr_f(r0,r1) SQRT_S(r0,r1)
# define sqrtr_d(r0,r1) SQRT_D(r0,r1)
# define movr_w_f(r0, r1) MTC1(r1, r0)
# define movr_f_w(r0, r1) MFC1(r1, r0)
# define movr_f_w(r0, r1) MFC1(r0, r1)
# define movi_f_w(r0, i0) _movi_f_w(_jit, r0, i0)
static void _movi_f_w(jit_state_t*,jit_int32_t,jit_float32_t*);
# define extr_f(r0, r1) _extr_f(_jit, r0, r1)
Loaded 100 of 136 files, more files were not shown because too many files have changed in this diff. Show more