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>
|
||||
|
||||
* lib/jit_x86.c: Rewrite previous patch to inline save/restore
|
||||
|
|
|
@ -22,7 +22,7 @@ both retargetable and very fast.
|
|||
@menu
|
||||
* Overview:: What GNU lightning is
|
||||
* 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
|
||||
* Reentrancy:: Re-entrant usage of 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
|
||||
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
|
||||
|
||||
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_label() _jit_label(_jit)
|
||||
#define jit_forward() _jit_forward(_jit)
|
||||
#define jit_indirect() _jit_indirect(_jit)
|
||||
#define jit_link(u) _jit_link(_jit,u)
|
||||
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_label(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_prolog(jit_state_t*);
|
||||
|
|
|
@ -548,7 +548,10 @@ _jit_address(jit_state_t *_jit, jit_node_t *node)
|
|||
{
|
||||
assert(_jitc->done);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1083,6 +1086,17 @@ _jit_forward(jit_state_t *_jit)
|
|||
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
|
||||
_jit_link(jit_state_t *_jit, jit_node_t *node)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue