mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-23 20:05:32 +02:00
Implement the new jit_set_data interface.
* include/lightning.h, include/lightning/jit_private.h, lib/lightning.c: Implement the new jit_set_data() interface, and the new jit_get_data() helper. Like jit_set_code(), jit_realize() should be called before jit_set_data(). The most common usage should be jit_set_data(JIT_DISABLE_DATA | JIT_DISABLE_NOTE), to force synthesize any float/double constant in the stack and not generate any debug information. * lib/jit_note.c: Minor change to debug note generation as now it uses an alternate temporary data buffer during constants and debug generation to accommodate the possibility of the user setting an alternate data buffer. * lib/jit_hppa-fpu.c, lib/jit_s390x.c, lib/jit_s390x-cpu.c, lib/jit_s390x-fpu.c, lib/jit_sparc.c, lib/jit_sparc-fpu.c, lib/jit_x86-sse.c, lib/jit_x86-x87.c: Implement jit_set_data. * lib/jit_hppa-sz.c, lib/jit_sparc-sz.c, lib/jit_x86-sz.c, lib/jit_s390x-sz.c: Update for several instructions that now have a different maximum length due to jit_set_data. * lib/jit_mips-fpu.c: Implement jit_set_data, but missing validation on n32 and n64 abis (and/or big endian). * lib/jit_mips-sz.c: Update for changes in o32. * lib/jit_ppc-fpu.c: Implement jit_set_data, but missing validation on Darwin PPC. * lib/jit_ppc-sz.c: Update for changes in powerpc 32 and 64 bit. * lib/jit_ia64-fpu.c: Implement untested jit_set_data. * TODO: Add note to list ports that were not tested for the new jit_set_data() feature, due to no longer having access to them. * check/nodata.c: New file implementing a simple test exercising several different conditions created by jit_set_data(). * check/check.nodata.sh: New file implementing a wrapper over the existing *.tst files, that runs all tests without using a data buffer for constants; only meaningful (and enabled) on architectures that used to store float/double constants on a read only data buffer. * configure.ac, check/Makefile.am: Update for the new test cases. * check/lightning.c: Implement the new "-d" option that sets an internal flag to call jit_set_data() disable constants and debug, that is, using only a pure code buffer.
This commit is contained in:
parent
79bc3d03dd
commit
33ee2337c7
28 changed files with 1103 additions and 470 deletions
|
@ -16,7 +16,7 @@
|
|||
|
||||
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
|
||||
|
||||
check_PROGRAMS = lightning ccall self setcode
|
||||
check_PROGRAMS = lightning ccall self setcode nodata
|
||||
|
||||
lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
|
||||
lightning_SOURCES = lightning.c
|
||||
|
@ -30,6 +30,9 @@ self_SOURCES = self.c
|
|||
setcode_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
|
||||
setcode_SOURCES = setcode.c
|
||||
|
||||
nodata_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
|
||||
nodata_SOURCES = nodata.c
|
||||
|
||||
$(top_builddir)/lib/liblightning.la:
|
||||
cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la
|
||||
|
||||
|
@ -81,6 +84,8 @@ EXTRA_DIST = \
|
|||
check.sh \
|
||||
check.x87.sh \
|
||||
check.arm.sh check.swf.sh \
|
||||
check.nodata.sh \
|
||||
check.x87.nodata.sh \
|
||||
run-test all.tst
|
||||
|
||||
base_TESTS = \
|
||||
|
@ -130,6 +135,28 @@ x87_TESTS = \
|
|||
$(x87_TESTS): check.x87.sh
|
||||
$(LN_S) $(srcdir)/check.x87.sh $@
|
||||
TESTS += $(x87_TESTS)
|
||||
|
||||
#x87_nodata_TESTS = $(addsuffix .x87.nodata, $(base_TESTS))
|
||||
x87_nodata_TESTS = \
|
||||
3to2.x87.nodata add.x87.nodata allocai.x87.nodata \
|
||||
bp.x87.nodata divi.x87.nodata fib.x87.nodata rpn.x87.nodata \
|
||||
ldstr.x87.nodata ldsti.x87.nodata \
|
||||
ldstxr.x87.nodata ldstxi.x87.nodata \
|
||||
ldstr-c.x87.nodata ldstxr-c.x87.nodata ldstxi-c.x87.nodata \
|
||||
cvt.x87.nodata branch.x87.nodata \
|
||||
alu_add.x87.nodata alux_add.x87.nodata \
|
||||
alu_sub.x87.nodata alux_sub.x87.nodata \
|
||||
alu_mul.x87.nodata alu_div.x87.nodata alu_rem.x87.nodata \
|
||||
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 \
|
||||
fop_abs.x87.nodata fop_sqrt.x87.nodata \
|
||||
varargs.x87.nodata stack.x87.nodata \
|
||||
clobber.x87.nodata carry.x87.nodata call.x87.nodata \
|
||||
float.x87.nodata
|
||||
$(x87_nodata_TESTS): check.x87.nodata.sh
|
||||
$(LN_S) $(srcdir)/check.x87.nodata.sh $@
|
||||
TESTS += $(x87_nodata_TESTS)
|
||||
endif
|
||||
|
||||
if test_arm_arm
|
||||
|
@ -180,7 +207,31 @@ $(swf_TESTS): check.swf.sh
|
|||
TESTS += $(swf_TESTS)
|
||||
endif
|
||||
|
||||
TESTS += ccall self setcode
|
||||
if test_nodata
|
||||
#nodata_TESTS = $(addsuffix .nodata, $(base_TESTS))
|
||||
nodata_TESTS = \
|
||||
3to2.nodata add.nodata allocai.nodata \
|
||||
bp.nodata divi.nodata fib.nodata rpn.nodata \
|
||||
ldstr.nodata ldsti.nodata \
|
||||
ldstxr.nodata ldstxi.nodata \
|
||||
ldstr-c.nodata ldstxr-c.nodata ldstxi-c.nodata \
|
||||
cvt.nodata branch.nodata \
|
||||
alu_add.nodata alux_add.nodata \
|
||||
alu_sub.nodata alux_sub.nodata \
|
||||
alu_mul.nodata alu_div.nodata alu_rem.nodata \
|
||||
alu_and.nodata alu_or.nodata alu_xor.nodata \
|
||||
alu_lsh.nodata alu_rsh.nodata \
|
||||
alu_com.nodata alu_neg.nodata \
|
||||
fop_abs.nodata fop_sqrt.nodata \
|
||||
varargs.nodata stack.nodata \
|
||||
clobber.nodata carry.nodata call.nodata \
|
||||
float.nodata
|
||||
$(nodata_TESTS): check.nodata.sh
|
||||
$(LN_S) $(srcdir)/check.nodata.sh $@
|
||||
TESTS += $(nodata_TESTS)
|
||||
endif
|
||||
|
||||
TESTS += ccall self setcode nodata
|
||||
CLEANFILES = $(TESTS)
|
||||
|
||||
#TESTS_ENVIRONMENT=$(srcdir)/run-test;
|
||||
|
|
15
check/check.nodata.sh
Executable file
15
check/check.nodata.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
test=`basename $0 | sed -e 's|\.nodata$||'`
|
||||
./lightning -d $srcdir/$test.tst | tr -d \\r > $test.out
|
||||
if test $? != 0; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
cmp -s $srcdir/$test.ok $test.out
|
||||
result=$?
|
||||
if test $result != 0; then
|
||||
diff $srcdir/$test.ok $test.out
|
||||
rm $test.out
|
||||
exit 1
|
||||
fi
|
||||
rm $test.out
|
|
@ -548,6 +548,7 @@ static void rehash(hash_t *hash);
|
|||
*/
|
||||
static jit_state_t *_jit;
|
||||
static int flag_verbose;
|
||||
static int flag_data;
|
||||
static int flag_disasm;
|
||||
static char *progname;
|
||||
static parser_t parser;
|
||||
|
@ -3664,6 +3665,11 @@ execute(int argc, char *argv[])
|
|||
patch = next;
|
||||
}
|
||||
|
||||
if (flag_data == 0) {
|
||||
jit_realize();
|
||||
jit_set_data(NULL, 0, JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
|
||||
}
|
||||
|
||||
function = jit_emit();
|
||||
if (flag_verbose > 1 || flag_disasm) {
|
||||
jit_print();
|
||||
|
@ -3876,6 +3882,7 @@ 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"
|
||||
# if defined(__i386__) && __WORDSIZE == 32
|
||||
" -mx87=1 Force using x87 when sse2 available\n"
|
||||
|
@ -3906,9 +3913,10 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
#if HAVE_GETOPT_LONG_ONLY
|
||||
static const char *short_options = "v::";
|
||||
static const char *short_options = "dv::";
|
||||
static struct option long_options[] = {
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "data", 2, 0, 'd' },
|
||||
# if defined(__i386__) && __WORDSIZE == 32
|
||||
{ "mx87", 2, 0, '7' },
|
||||
# endif
|
||||
|
@ -3939,6 +3947,7 @@ main(int argc, char *argv[])
|
|||
DL_HANDLE = dlopen(NULL, RTLD_LAZY);
|
||||
#endif
|
||||
|
||||
flag_data = 1;
|
||||
#if HAVE_GETOPT_LONG_ONLY
|
||||
for (;;) {
|
||||
if ((opt_short = getopt_long_only(argc, argv, short_options,
|
||||
|
@ -3958,6 +3967,9 @@ main(int argc, char *argv[])
|
|||
else
|
||||
flag_verbose = 1;
|
||||
break;
|
||||
case 'd':
|
||||
flag_data = 0;
|
||||
break;
|
||||
#if defined(__i386__) && __WORDSIZE == 32
|
||||
case '7':
|
||||
if (optarg) {
|
||||
|
@ -4022,9 +4034,11 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
#else
|
||||
while ((opt_short = getopt(argc, argv, "hv")) >= 0) {
|
||||
while ((opt_short = getopt(argc, argv, "hvd")) >= 0) {
|
||||
if (opt_short == 'v')
|
||||
++flag_verbose;
|
||||
else if (opt_short == 'd')
|
||||
flag_data = 0;
|
||||
else
|
||||
usage();
|
||||
}
|
||||
|
|
106
check/nodata.c
Normal file
106
check/nodata.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Simple test of using an alternate buffer for the code.
|
||||
*/
|
||||
|
||||
#include <lightning.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <sys/mman.h>
|
||||
#if defined(__sgi)
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
jit_uint8_t *data;
|
||||
jit_state_t *_jit;
|
||||
jit_word_t data_length;
|
||||
jit_word_t note_length;
|
||||
#if defined(__sgi)
|
||||
int mmap_fd;
|
||||
#endif
|
||||
void (*function)(void);
|
||||
|
||||
void
|
||||
gencode(jit_word_t flags)
|
||||
{
|
||||
jit_word_t offset;
|
||||
jit_word_t length;
|
||||
|
||||
_jit = jit_new_state();
|
||||
|
||||
jit_name("main");
|
||||
jit_prolog();
|
||||
jit_prepare();
|
||||
jit_pushargi((jit_word_t)"%f\n");
|
||||
jit_ellipsis();
|
||||
jit_pushargi_d(1.5);
|
||||
jit_finishi(printf);
|
||||
jit_note("nodata.c", __LINE__);
|
||||
|
||||
/* call to jit_realize() is only required when using an alternate
|
||||
* code buffer. Note that not using mmap'ed memory may not work
|
||||
* on several ports and/or operating system versions */
|
||||
jit_realize();
|
||||
|
||||
if (jit_get_data(&data_length, ¬e_length) != NULL)
|
||||
abort();
|
||||
|
||||
length = 0;
|
||||
if (!(flags & JIT_DISABLE_DATA))
|
||||
length += data_length;
|
||||
if (!(flags & JIT_DISABLE_NOTE))
|
||||
length += note_length;
|
||||
|
||||
/* check that a too small buffer fails */
|
||||
if (flags)
|
||||
jit_set_data(length ? data : NULL, length, flags);
|
||||
|
||||
/* and calling again with enough space works */
|
||||
offset = (length + 7) & -8;
|
||||
function = jit_emit();
|
||||
if (function == NULL)
|
||||
abort();
|
||||
|
||||
jit_clear_state();
|
||||
(*function)();
|
||||
jit_destroy_state();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
#if defined(__sgi)
|
||||
mmap_fd = open("/dev/zero", O_RDWR);
|
||||
#endif
|
||||
|
||||
data = mmap(NULL, 4096,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, mmap_fd, 0);
|
||||
assert(data != MAP_FAILED);
|
||||
#if defined(__sgi)
|
||||
close(mmap_fd);
|
||||
#endif
|
||||
|
||||
init_jit(argv[0]);
|
||||
|
||||
gencode(0);
|
||||
gencode(JIT_DISABLE_DATA);
|
||||
gencode(JIT_DISABLE_NOTE);
|
||||
gencode(JIT_DISABLE_DATA | JIT_DISABLE_NOTE);
|
||||
|
||||
finish_jit();
|
||||
|
||||
munmap(data, 4096);
|
||||
|
||||
return (0);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue