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

Properly handle jit_tramp and function descriptors

* lib/jit_ia64.c, lib/jit_ppc.c: Correct handling of function
	descriptor when first prolog is a jit_tramp prolog. The
	test case was using the same jit_context_t, so was not
	triggering this condition.

	* lib/jit_ppc-cpu.c: Properly handle jump displacements that
	do not fit on 24 powerpc. This required changing from previous
	"mtlr reg, blr" to "mtctr reg, bctr" to properly handle
	the logic to "hide" function descriptors, but that would
	also be required as the proper jit_jmpr when/if implementing
	optimizations to leaf functions (was working with blr because
	it is saved/reloaded in prolog/epilog).
This commit is contained in:
pcpa 2014-10-24 14:31:41 -02:00
parent 9c5e2b511e
commit 0c6f675c8a
4 changed files with 95 additions and 13 deletions

View file

@ -2985,8 +2985,13 @@ _stxi_l(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
static void
_jmpr(jit_state_t *_jit, jit_int32_t r0)
{
#if 0
MTLR(r0);
BLR();
#else
MTCTR(r0);
BCTR();
#endif
}
/* pc relative jump */
@ -2995,11 +3000,16 @@ _jmpi(jit_state_t *_jit, jit_word_t i0)
{
jit_int32_t reg;
jit_word_t w, d;
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
w = _jit->pc.w;
d = (i0 - w) & ~3;
B(d);
jit_unget_reg(reg);
if (can_sign_extend_jump_p(d))
B(d);
else {
reg = jit_get_reg(jit_class_gpr|jit_class_nospill);
w = movi_p(rn(reg), i0);
jmpr(rn(reg));
jit_unget_reg(reg);
}
return (w);
}
@ -3237,6 +3247,47 @@ _patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label)
u.i[0] = (u.i[0] & ~0x3fffffd) | (d & 0x3fffffe);
break;
case 15: /* LI */
#if __WORDSIZE == 32
# define MTCTR_OFF 2
# define BCTR_OFF 3
#else
# define MTCTR_OFF 6
# define BCTR_OFF 7
#endif
/* movi reg label; jmpr reg */
if (_jitc->jump &&
#if 0
/* check for MLTR(reg) */
(u.i[MTCTR_OFF] >> 26) == 31 &&
((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 8 &&
((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 &&
/* check for BLR */
u.i[BCTR_OFF] == 0x4e800020) {
#else
/* check for MTCTR(reg) */
(u.i[MTCTR_OFF] >> 26) == 31 &&
((u.i[MTCTR_OFF] >> 16) & 0x3ff) == 9 &&
((u.i[MTCTR_OFF] >> 1) & 0x3ff) == 467 &&
/* check for BCTR */
u.i[BCTR_OFF] == 0x4e800420) {
#endif
/* zero is used for toc and env, so, quick check
* if this is a "jmpi main" like initial jit
* instruction */
if (((long *)label)[1] == 0 && ((long *)label)[2] == 0) {
for (d = 0; d < _jitc->prolog.offset; d++) {
/* not so pretty, but hides powerpc
* specific abi intrinsics and/or
* implementation from user */
if (_jitc->prolog.ptr[d] == label) {
label += sizeof(void*) * 3;
break;
}
}
}
}
#undef BCTR_OFF
#undef MTCTR_OFF
#if __WORDSIZE == 32
assert(!(u.i[0] & 0x1f0000));
u.i[0] = (u.i[0] & ~0xffff) | ((label >> 16) & 0xffff);