1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-01 01:40:21 +02:00

Implement and document the new jit_indirect call.

* include/lightning.h, lib/lightning.c: Add the new
	jit_indirect() call, that returns a special label node,
	and tells lightning that the label may be the target of
	an indirect jump.

	* doc/body.texi: Document the new jit_indirect() call, and
	add examples of different ways to create labels and branches.
This commit is contained in:
pcpa 2014-03-06 18:20:29 -03:00
parent c146f06793
commit a9433b5a2c
4 changed files with 88 additions and 2 deletions

View file

@ -1,3 +1,13 @@
2014-06-03 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h, lib/lightning.c: Add the new
jit_indirect() call, that returns a special label node,
and tells lightning that the label may be the target of
an indirect jump.
* doc/body.texi: Document the new jit_indirect() call, and
add examples of different ways to create labels and branches.
2014-23-02 Paulo Andrade <pcpa@gnu.org> 2014-23-02 Paulo Andrade <pcpa@gnu.org>
* lib/jit_x86.c: Rewrite previous patch to inline save/restore * lib/jit_x86.c: Rewrite previous patch to inline save/restore

View file

@ -22,7 +22,7 @@ both retargetable and very fast.
@menu @menu
* Overview:: What GNU lightning is * Overview:: What GNU lightning is
* Installation:: Configuring and installing GNU lightning * Installation:: Configuring and installing GNU lightning
* The instruction set:: The RISC instruction set used i GNU lightning * The instruction set:: The RISC instruction set used in GNU lightning
* GNU lightning examples:: GNU lightning's examples * GNU lightning examples:: GNU lightning's examples
* Reentrancy:: Re-entrant usage of GNU lightning * Reentrancy:: Re-entrant usage of GNU lightning
* Acknowledgements:: Acknowledgements for GNU lightning * Acknowledgements:: Acknowledgements for GNU lightning
@ -501,6 +501,66 @@ Like branch instruction, @code{jmpi} also returns a value which is to
be used to compile forward branches. @xref{Fibonacci, , Fibonacci be used to compile forward branches. @xref{Fibonacci, , Fibonacci
numbers}. numbers}.
@item Labels
There are 3 @lightning{} instructions to create labels:
@example
label (not specified) @r{simple label}
forward (not specified) @r{forward label}
indirect (not specified) @r{special simple label}
@end example
@code{label} is normally used as @code{patch_at} argument for backward
jumps.
@example
jit_node_t *jump, *label;
label = jit_label();
...
jump = jit_beqr(JIT_R0, JIT_R1);
jit_patch_at(jump, label);
@end example
@code{forward} is used to patch code generation before the actual
position of the label is known.
@example
jit_node_t *jump, *label;
label = jit_forward();
jump = jit_beqr(JIT_R0, JIT_R1);
jit_patch_at(jump, label);
...
jit_link(label);
@end example
@code{indirect} is useful when creating jump tables, and tells
@lightning{} to not optimize out a label that is not the target of
any jump, because an indirect jump may land where it is defined.
@example
jit_node_t *jump, *label;
...
jmpr(JIT_R0); @rem{/* may jump to label */}
...
label = jit_indirect();
@end example
@code{indirect} is an special case of @code{note} and @code{name}
because it is a valid argument to @code{address}.
Note that the usual idiom to write the previous example is
@example
jit_node_t *addr, *jump;
addr = jit_movi(JIT_R0, 0); @rem{/* immediate is ignored */}
...
jmpr(JIT_R0);
...
jit_patch(addr); @rem{/* implicit label added */}
@end example
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.
@item Function prolog @item Function prolog
These macros are used to set up a function prolog. The @code{allocai} These macros are used to set up a function prolog. The @code{allocai}

View file

@ -174,6 +174,7 @@ typedef enum {
#define jit_note(u, v) _jit_note(_jit, u, v) #define jit_note(u, v) _jit_note(_jit, u, v)
#define jit_label() _jit_label(_jit) #define jit_label() _jit_label(_jit)
#define jit_forward() _jit_forward(_jit) #define jit_forward() _jit_forward(_jit)
#define jit_indirect() _jit_indirect(_jit)
#define jit_link(u) _jit_link(_jit,u) #define jit_link(u) _jit_link(_jit,u)
jit_code_note, jit_code_label, jit_code_note, jit_code_label,
@ -841,6 +842,7 @@ extern jit_node_t *_jit_name(jit_state_t*, char*);
extern jit_node_t *_jit_note(jit_state_t*, char*, int); extern jit_node_t *_jit_note(jit_state_t*, char*, int);
extern jit_node_t *_jit_label(jit_state_t*); extern jit_node_t *_jit_label(jit_state_t*);
extern jit_node_t *_jit_forward(jit_state_t*); extern jit_node_t *_jit_forward(jit_state_t*);
extern jit_node_t *_jit_indirect(jit_state_t*);
extern void _jit_link(jit_state_t*, jit_node_t*); extern void _jit_link(jit_state_t*, jit_node_t*);
extern void _jit_prolog(jit_state_t*); extern void _jit_prolog(jit_state_t*);

View file

@ -548,7 +548,10 @@ _jit_address(jit_state_t *_jit, jit_node_t *node)
{ {
assert(_jitc->done); assert(_jitc->done);
assert(node && assert(node &&
(node->code == jit_code_note || node->code == jit_code_name)); /* If a node type that is documented to be a fixed marker */
(node->code == jit_code_note || node->code == jit_code_name ||
/* If another special fixed marker, returned by jit_indirect() */
(node->code == jit_code_label && (node->flag & jit_flag_use))));
return ((jit_pointer_t)node->u.w); return ((jit_pointer_t)node->u.w);
} }
@ -1083,6 +1086,17 @@ _jit_forward(jit_state_t *_jit)
return (jit_new_node_no_link(jit_code_label)); return (jit_new_node_no_link(jit_code_label));
} }
jit_node_t *
_jit_indirect(jit_state_t *_jit)
{
jit_node_t *node;
node = jit_label();
node->flag |= jit_flag_use;
return (node);
}
void void
_jit_link(jit_state_t *_jit, jit_node_t *node) _jit_link(jit_state_t *_jit, jit_node_t *node)
{ {