diff --git a/ChangeLog b/ChangeLog index 85804e673..25583956f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2014-10-24 Paulo Andrade + + * 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). + 2014-10-21 Paulo Andrade * include/lightning.h, lib/lightning.c: Add three predicates diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index f35f396dc..e3c655449 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -762,10 +762,18 @@ _emit_code(jit_state_t *_jit) undo.patch_offset = 0; undo.prolog_offset = 0; - /* code may start with a jump so add an initial function descriptor */ - word = _jit->pc.w + 16; - il(word); /* addr */ - il(0); /* gp */ + for (node = _jitc->head; node; node = node->next) + if (node->code != jit_code_label && + node->code != jit_code_note && + node->code != jit_code_name) + break; + if (node && (node->code != jit_code_prolog || + !(_jitc->functions.ptr + node->w.w)->assume_frame)) { + /* code may start with a jump so add an initial function descriptor */ + word = _jit->pc.w + 16; + il(word); /* addr */ + il(0); /* gp */ + } #define case_rr(name, type) \ case jit_code_##name##r##type: \ name##r##type(rn(node->u.w), rn(node->v.w)); \ diff --git a/lib/jit_ppc-cpu.c b/lib/jit_ppc-cpu.c index 2f65d36b5..18f40968f 100644 --- a/lib/jit_ppc-cpu.c +++ b/lib/jit_ppc-cpu.c @@ -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); diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index cbc5ddaab..8ef61198f 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -778,11 +778,19 @@ _emit_code(jit_state_t *_jit) #if __powerpc__ undo.prolog_offset = 0; - /* code may start with a jump so add an initial function descriptor */ - word = _jit->pc.w + sizeof(void*) * 3; - iw(word); /* addr */ - iw(0); /* toc */ - iw(0); /* env */ + for (node = _jitc->head; node; node = node->next) + if (node->code != jit_code_label && + node->code != jit_code_note && + node->code != jit_code_name) + break; + if (node && (node->code != jit_code_prolog || + !(_jitc->functions.ptr + node->w.w)->assume_frame)) { + /* code may start with a jump so add an initial function descriptor */ + word = _jit->pc.w + sizeof(void*) * 3; + iw(word); /* addr */ + iw(0); /* toc */ + iw(0); /* env */ + } #endif #define case_rr(name, type) \ @@ -1262,7 +1270,7 @@ _emit_code(jit_state_t *_jit) } } else - jmpi(node->u.w); + (void)jmpi_p(node->u.w); break; case jit_code_callr: callr(rn(node->u.w));