1
Fork 0
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:
pcpa 2014-10-14 17:04:13 -03:00
parent 1d75fe625a
commit 20a2f1f9c5
12 changed files with 144 additions and 87 deletions

View file

@ -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

View file

@ -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));

View file

@ -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));

View file

@ -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:

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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> */