1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-28 22:10:29 +02:00

Implement jit_frame and jit_tramp interfaces

* include/lightning.h, include/lightning/jit_private.h,
	lib/jit_aarch64-cpu.c, lib/jit_alpha-cpu.c, lib/jit_arm-cpu.c,
	lib/jit_hppa-cpu.c, lib/jit_ia64-cpu.c, lib/jit_mips-cpu.c,
	lib/jit_ppc-cpu.c, lib/jit_s390x-cpu.c, lib/jit_sparc-cpu.c,
	lib/jit_x86-cpu.c, lib/lightning.c: Implement the new
	jit_frame and jit_tramp interfaces, that allow writing
	trampoline like calls, where a single dispatcher jit buffer
	is written, and later other jit buffers are created, with
	the same stack frame layout as the dispatcher. This is the
	logic that GNU Smalltalk used in lightning 1.x, and is required
	to make a sane port for lighting 2.x.

	* jit_ia64-cpu.c: Implement support for jit_frame and jit_tramp,
	and also correct wrong encoding for B4 instructions, that
	implement jmpr, as well as correct reverse logic in _jmpr,
	that was moving the branch register to the jump register,
	and not vice-versa.
	Also, if a stack frame is to be assumed, always assume it may
	call a function with up to 8 arguments, regardless of the
	hint frame argument.

	* lib/jit_arm.c: Add a new must_align_p() interface to ensure
	function prologs are always aligned. This condition was
	previously always true, somewhat by accident, but with
	jit_tramp it is not guaranteed.

	* jit_ia64-cpu.c: lib/jit_ppc.c: Add minor special handling
	required to implement jit_tramp, where a function descriptor
	should not be added before a prolog, as jit_tramp means omit
	prolog.

	* check/lightning.c: Update test driver for the new interfaces.

	* check/Makefile.am, check/tramp.tst, check/tramp.ok: Add
	a simple test and example of the jit_frame and jit_tramp
	usage implementing a simple Fibonacci function using a
	simulation of an interpreter stack and how it would handle
	state in language specific variables.

	* doc/body.texi: Add documentation for jit_frame and
	jit_tramp.
This commit is contained in:
pcpa 2014-10-14 17:04:40 -03:00
parent 20a2f1f9c5
commit 839341a498
20 changed files with 284 additions and 15 deletions

View file

@ -55,6 +55,8 @@ typedef union _jit_thumb_t {
static jit_int32_t _jit_get_reg_pair(jit_state_t*);
#define jit_unget_reg_pair(rn) _jit_unget_reg_pair(_jit,rn)
static void _jit_unget_reg_pair(jit_state_t*,jit_int32_t);
# define must_align_p(node) _must_align_p(_jit, node)
static jit_bool_t _must_align_p(jit_state_t*,jit_node_t*);
#define load_const(uniq,r0,i0) _load_const(_jit,uniq,r0,i0)
static void _load_const(jit_state_t*,jit_bool_t,jit_int32_t,jit_word_t);
#define flush_consts() _flush_consts(_jit)
@ -1042,9 +1044,13 @@ _emit_code(jit_state_t *_jit)
jit_regarg_set(node, value);
switch (node->code) {
case jit_code_note: case jit_code_name:
if (must_align_p(node->next))
nop(2);
node->u.w = _jit->pc.w;
break;
case jit_code_label:
if (must_align_p(node->next))
nop(2);
/* remember label is defined */
node->flag |= jit_flag_patch;
node->u.w = _jit->pc.w;
@ -1665,6 +1671,30 @@ _jit_unget_reg_pair(jit_state_t *_jit, jit_int32_t reg)
}
}
/* A prolog must be aligned at mod 4 bytes boundary.
* This condition was not being required to be tested by
* accident previously, but with the jit_frame and jit_tramp
* code it is required */
static jit_bool_t
_must_align_p(jit_state_t *_jit, jit_node_t *node)
{
if (jit_thumb_p() && (_jit->pc.w & 3)) {
for (; node; node = node->next) {
switch (node->code) {
case jit_code_note:
case jit_code_name:
case jit_code_label:
break;
case jit_code_prolog:
return (1);
default:
return (0);
}
}
}
return (0);
}
static void
_load_const(jit_state_t *_jit, jit_bool_t uniq, jit_int32_t r0, jit_word_t i0)
{