diff --git a/doc/using.texi b/doc/using.texi index fa6a0b4b2..3a8578ab5 100644 --- a/doc/using.texi +++ b/doc/using.texi @@ -104,10 +104,12 @@ which, like the x86, are poor of registers; anyway, backends can specify the actual number of available caller- and callee-save registers. -In addition, there is a special @code{RET} register which contains -the return value. You should always remember, however, that writing -this register could overwrite either a general-purpose register or -an incoming parameter, depending on the architecture. +In addition, there is a special @code{RET} register which contains the +return value of the current function (@emph{not} the return value of +callees---use the @code{retval} instruction for this). You should +always remember, however, that writing this register could overwrite +either a general-purpose register or an incoming parameter, depending +on the architecture. There are at least six floating-point registers, named @code{FPR0} to @code{FPR5}. These are separate from the integer registers on @@ -285,6 +287,7 @@ prepare i f d pusharg c uc s us i ui l ul p f d getarg c uc s us i ui l ul p f d arg c uc s us i ui l ul p f d +retval c uc s us i ui l ul p @end example Of these, the first two are used by the caller, while the last two @@ -315,6 +318,13 @@ that generates other code, so they will be treated more specifically in @ref{GNU lightning macros, , Generating code at run-time}. +Finally, the @code{retval} instruction fetches the return value of a +called function in a register. The @code{retval} instruction takes a +register argument and copies the return value of the previously called +function in that register. A function should put its own return value +in the @code{RET} register before returning. @xref{Fibonacci, the +Fibonacci numbers}, for an example. + You should observe a few rules when using these macros. First of all, it is not allowed to call functions with more than six arguments; this was done to simplify and speed up the implementation on diff --git a/tests/Makefile.am b/tests/Makefile.am index 763b73c58..69cc0396a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,12 @@ AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lightning/$(cpu) -check_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay add bp testfp funcfp rpnfp modi ldxi divi movi -noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok bp.ok modi.ok ldxi.ok divi.ok movi.ok +check_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay \ + add bp testfp funcfp rpnfp modi ldxi divi movi ret + +noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok \ + fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok \ + bp.ok modi.ok ldxi.ok divi.ok movi.ok ret.ok + EXTRA_DIST = $(noinst_DATA) run-test if DISASS @@ -9,6 +14,8 @@ LDADD = $(top_builddir)/opcode/libdisass.a endif if REGRESSION_TESTING -TESTS = fib fibit fibdelay incr printf printf2 rpn add bp testfp funcfp rpnfp modi ldxi divi movi +TESTS = fib fibit fibdelay incr printf printf2 rpn add bp \ + testfp funcfp rpnfp modi ldxi divi movi ret + TESTS_ENVIRONMENT=$(srcdir)/run-test endif diff --git a/tests/Makefile.in b/tests/Makefile.in index e06f7a386..ae65e726c 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -41,7 +41,7 @@ check_PROGRAMS = fibit$(EXEEXT) incr$(EXEEXT) printf$(EXEEXT) \ printf2$(EXEEXT) rpn$(EXEEXT) fib$(EXEEXT) fibdelay$(EXEEXT) \ add$(EXEEXT) bp$(EXEEXT) testfp$(EXEEXT) funcfp$(EXEEXT) \ rpnfp$(EXEEXT) modi$(EXEEXT) ldxi$(EXEEXT) divi$(EXEEXT) \ - movi$(EXEEXT) + movi$(EXEEXT) ret$(EXEEXT) subdir = tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -106,6 +106,10 @@ printf2_OBJECTS = printf2.$(OBJEXT) printf2_LDADD = $(LDADD) @DISASS_TRUE@printf2_DEPENDENCIES = \ @DISASS_TRUE@ $(top_builddir)/opcode/libdisass.a +ret_SOURCES = ret.c +ret_OBJECTS = ret.$(OBJEXT) +ret_LDADD = $(LDADD) +@DISASS_TRUE@ret_DEPENDENCIES = $(top_builddir)/opcode/libdisass.a rpn_SOURCES = rpn.c rpn_OBJECTS = rpn.$(OBJEXT) rpn_LDADD = $(LDADD) @@ -126,10 +130,11 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = add.c bp.c divi.c fib.c fibdelay.c fibit.c funcfp.c incr.c \ - ldxi.c modi.c movi.c printf.c printf2.c rpn.c rpnfp.c testfp.c -DIST_SOURCES = add.c bp.c divi.c fib.c fibdelay.c fibit.c funcfp.c \ - incr.c ldxi.c modi.c movi.c printf.c printf2.c rpn.c rpnfp.c \ + ldxi.c modi.c movi.c printf.c printf2.c ret.c rpn.c rpnfp.c \ testfp.c +DIST_SOURCES = add.c bp.c divi.c fib.c fibdelay.c fibit.c funcfp.c \ + incr.c ldxi.c modi.c movi.c printf.c printf2.c ret.c rpn.c \ + rpnfp.c testfp.c DATA = $(noinst_DATA) ETAGS = etags CTAGS = ctags @@ -235,10 +240,15 @@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lightning/$(cpu) -noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok bp.ok modi.ok ldxi.ok divi.ok movi.ok +noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok \ + fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok \ + bp.ok modi.ok ldxi.ok divi.ok movi.ok ret.ok + EXTRA_DIST = $(noinst_DATA) run-test @DISASS_TRUE@LDADD = $(top_builddir)/opcode/libdisass.a -@REGRESSION_TESTING_TRUE@TESTS = fib fibit fibdelay incr printf printf2 rpn add bp testfp funcfp rpnfp modi ldxi divi movi +@REGRESSION_TESTING_TRUE@TESTS = fib fibit fibdelay incr printf printf2 rpn add bp \ +@REGRESSION_TESTING_TRUE@ testfp funcfp rpnfp modi ldxi divi movi ret + @REGRESSION_TESTING_TRUE@TESTS_ENVIRONMENT = $(srcdir)/run-test all: all-am @@ -315,6 +325,9 @@ printf$(EXEEXT): $(printf_OBJECTS) $(printf_DEPENDENCIES) printf2$(EXEEXT): $(printf2_OBJECTS) $(printf2_DEPENDENCIES) @rm -f printf2$(EXEEXT) $(LINK) $(printf2_LDFLAGS) $(printf2_OBJECTS) $(printf2_LDADD) $(LIBS) +ret$(EXEEXT): $(ret_OBJECTS) $(ret_DEPENDENCIES) + @rm -f ret$(EXEEXT) + $(LINK) $(ret_LDFLAGS) $(ret_OBJECTS) $(ret_LDADD) $(LIBS) rpn$(EXEEXT): $(rpn_OBJECTS) $(rpn_DEPENDENCIES) @rm -f rpn$(EXEEXT) $(LINK) $(rpn_LDFLAGS) $(rpn_OBJECTS) $(rpn_LDADD) $(LIBS) @@ -344,6 +357,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/movi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printf2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ret.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpnfp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testfp.Po@am__quote@ diff --git a/tests/ret.c b/tests/ret.c new file mode 100644 index 000000000..f072adcbf --- /dev/null +++ b/tests/ret.c @@ -0,0 +1,72 @@ +/******************************** -*- C -*- **************************** + * + * Test `JIT_RET' + * + ***********************************************************************/ + + +/* Contributed by Ludovic Courtès. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "lightning.h" + +typedef int (* int_return_int_t) (int); + +static int +identity (int arg) +{ + return arg; +} + +static int_return_int_t +generate_function_proxy (int_return_int_t func) +{ + static char buffer[1024]; + int_return_int_t result; + int arg; + + result = (int_return_int_t)(jit_set_ip (buffer).ptr); + jit_prolog (1); + arg = jit_arg_i (); + jit_getarg_i (JIT_R1, arg); + + /* Reset `JIT_RET'. */ + jit_movi_i (JIT_RET, -1); + + /* Invoke a FUNC. */ + jit_prepare (1); + jit_pusharg_i (JIT_R1); + (void)jit_finish (func); + + /* Copy the result of FUNC from `JIT_RET' into our own result register. */ + jit_retval_i (JIT_RET); + + jit_ret (); + jit_flush_code (buffer, jit_get_ip ().ptr); + + return result; +} + + +int +main (int argc, char *argv[]) +{ + int_return_int_t identity_proxy; + + identity_proxy = generate_function_proxy (identity); + if (identity_proxy (7777) != 7777) + { + printf ("failed: got %i instead of %i\n", + identity_proxy (7777), 7777); + return 1; + } + else + printf ("succeeded\n"); + + return 0; +} diff --git a/tests/ret.ok b/tests/ret.ok new file mode 100644 index 000000000..774a5c0df --- /dev/null +++ b/tests/ret.ok @@ -0,0 +1 @@ +succeeded