mirror of
https://github.com/simple64/simple64.git
synced 2026-11-15 04:09:21 +01:00
update parallel rsp
This commit is contained in:
1 parent
14673b1b61
commit
6f90f88201
136 files changed
+23411
-5700
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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/
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "gnulib"]
|
||||
path = gnulib
|
||||
url = git://git.sv.gnu.org/gnulib.git
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
@@ -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:
|
||||
@@ -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>
|
||||
@@ -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).
|
||||
Executable
+1090
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ok
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
ok
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
@@ -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); \
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ok
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
ok
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
c s i l
|
||||
C S I
|
||||
1.0 2.0
|
||||
@@ -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();
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
10
|
||||
@@ -0,0 +1,13 @@
|
||||
.data 32
|
||||
fmt:
|
||||
.c "%d\n"
|
||||
.code
|
||||
prolog
|
||||
skip 4
|
||||
prepare
|
||||
pushargi fmt
|
||||
ellipsis
|
||||
pushargi 10
|
||||
finishi @printf
|
||||
ret
|
||||
epilog
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -1,2 +1,13 @@
|
||||
*.info*
|
||||
stamp-*
|
||||
/version.texi
|
||||
|
||||
texinfo.tex
|
||||
mdate-sh
|
||||
|
||||
fact
|
||||
ifib
|
||||
incr
|
||||
printf
|
||||
rfib
|
||||
rpn
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
+1
Submodule parallel-rsp/lightning/gnulib added at e54b645fc6.
@@ -0,0 +1,2 @@
|
||||
/Makefile.am
|
||||
/dummy.c
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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,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,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 */
|
||||
@@ -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:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,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,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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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,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,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 */
|
||||
@@ -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,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
@@ -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
Reference in new issue
Block a user