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:
parent
c146f06793
commit
a9433b5a2c
4 changed files with 88 additions and 2 deletions
10
ChangeLog
10
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue