mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-04 22:40:25 +02:00
Allow jit_jmpi on an immediate constant address.
* lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c, lib/jit_hppa.c, lib/jit_ia64.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_s390x.c, lib/jit_sparc.c, lib/jit_x86.c, lib/lightning.c: Allow jit_jmpi on a target that is not a node. This may lead to hard to debug code generation, but is a required feature for certain generators, like the ones that used lightning 1.2x. Note that previously, but not really well documented, it was instructed to use: jit_movi(rn, addr); jit_jmpr(rn); but now, plain: jit_patch_abs(jit_jmpi(), addr); should also work.
This commit is contained in:
parent
1d75fe625a
commit
20a2f1f9c5
12 changed files with 144 additions and 87 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
2014-09-29 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
|
* lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c,
|
||||||
|
lib/jit_hppa.c, lib/jit_ia64.c, lib/jit_mips.c,
|
||||||
|
lib/jit_ppc.c, lib/jit_s390x.c, lib/jit_sparc.c,
|
||||||
|
lib/jit_x86.c, lib/lightning.c: Allow jit_jmpi on a
|
||||||
|
target that is not a node. This may lead to hard to
|
||||||
|
debug code generation, but is a required feature for
|
||||||
|
certain generators, like the ones that used lightning
|
||||||
|
1.2x. Note that previously, but not really well
|
||||||
|
documented, it was instructed to use:
|
||||||
|
jit_movi(rn, addr); jit_jmpr(rn);
|
||||||
|
but now, plain:
|
||||||
|
jit_patch_abs(jit_jmpi(), addr);
|
||||||
|
should also work.
|
||||||
|
|
||||||
2014-09-24 Paulo Andrade <pcpa@gnu.org>
|
2014-09-24 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
* lib/jit_x86-sz.c: Generate information about instruction
|
* lib/jit_x86-sz.c: Generate information about instruction
|
||||||
|
|
|
@ -1070,15 +1070,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1097,15 +1097,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1385,15 +1385,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
flush_consts();
|
flush_consts();
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
flush_consts();
|
flush_consts();
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
|
|
|
@ -1059,16 +1059,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
/* no support for jump outside jit */
|
temp->code == jit_code_epilog);
|
||||||
if (temp->flag & jit_flag_patch)
|
if (temp->flag & jit_flag_patch)
|
||||||
jmpi(temp->u.w);
|
jmpi(temp->u.w);
|
||||||
else {
|
else {
|
||||||
word = jmpi_p(_jit->pc.w);
|
word = jmpi_p(_jit->pc.w);
|
||||||
patch(word, node);
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1214,17 +1214,21 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
if (_jit->pc.uc == _jit->code.ptr + 16)
|
if (node->flag & jit_flag_node) {
|
||||||
_jitc->jump = 1;
|
if (_jit->pc.uc == _jit->code.ptr + 16)
|
||||||
temp = node->u.n;
|
_jitc->jump = 1;
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1343,15 +1343,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1236,20 +1236,23 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
|
if (node->flag & jit_flag_node) {
|
||||||
#if __powerpc__
|
#if __powerpc__
|
||||||
if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
|
if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3)
|
||||||
_jitc->jump = 1;
|
_jitc->jump = 1;
|
||||||
#endif
|
#endif
|
||||||
temp = node->u.n;
|
temp = node->u.n;
|
||||||
assert(temp->code == jit_code_label ||
|
assert(temp->code == jit_code_label ||
|
||||||
temp->code == jit_code_epilog);
|
temp->code == jit_code_epilog);
|
||||||
/* no support for jump outside jit */
|
if (temp->flag & jit_flag_patch)
|
||||||
if (temp->flag & jit_flag_patch)
|
jmpi(temp->u.w);
|
||||||
jmpi(temp->u.w);
|
else {
|
||||||
else {
|
word = jmpi(_jit->pc.w);
|
||||||
word = jmpi(_jit->pc.w);
|
patch(word, node);
|
||||||
patch(word, node);
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1052,15 +1052,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1055,15 +1055,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi_p(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi_p(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -1668,15 +1668,19 @@ _emit_code(jit_state_t *_jit)
|
||||||
jmpr(rn(node->u.w));
|
jmpr(rn(node->u.w));
|
||||||
break;
|
break;
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
temp = node->u.n;
|
if (node->flag & jit_flag_node) {
|
||||||
assert(temp->code == jit_code_label ||
|
temp = node->u.n;
|
||||||
temp->code == jit_code_epilog);
|
assert(temp->code == jit_code_label ||
|
||||||
if (temp->flag & jit_flag_patch)
|
temp->code == jit_code_epilog);
|
||||||
jmpi(temp->u.w);
|
if (temp->flag & jit_flag_patch)
|
||||||
else {
|
jmpi(temp->u.w);
|
||||||
word = jmpi(_jit->pc.w);
|
else {
|
||||||
patch(word, node);
|
word = jmpi(_jit->pc.w);
|
||||||
|
patch(word, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
jmpi(node->u.w);
|
||||||
break;
|
break;
|
||||||
case jit_code_callr:
|
case jit_code_callr:
|
||||||
callr(rn(node->u.w));
|
callr(rn(node->u.w));
|
||||||
|
|
|
@ -2295,6 +2295,8 @@ _shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
|
||||||
for (next = jump->next; next; next = next->next) {
|
for (next = jump->next; next; next = next->next) {
|
||||||
switch (next->code) {
|
switch (next->code) {
|
||||||
case jit_code_jmpi:
|
case jit_code_jmpi:
|
||||||
|
if (!(next->flag & jit_flag_node))
|
||||||
|
return (0);
|
||||||
if (jump->link == node)
|
if (jump->link == node)
|
||||||
jump->link = node->link;
|
jump->link = node->link;
|
||||||
else {
|
else {
|
||||||
|
@ -2500,7 +2502,8 @@ _reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node)
|
||||||
return (0);
|
return (0);
|
||||||
/* =><cond_jump L0> <jump L1> <label L0> */
|
/* =><cond_jump L0> <jump L1> <label L0> */
|
||||||
local_next = node->next;
|
local_next = node->next;
|
||||||
if (local_next->code != jit_code_jmpi)
|
if (local_next->code != jit_code_jmpi ||
|
||||||
|
!(local_next->flag & jit_flag_node))
|
||||||
return (0);
|
return (0);
|
||||||
/* <cond_jump L0> =><jump L1> <label L0> */
|
/* <cond_jump L0> =><jump L1> <label L0> */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue