author | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2014年10月24日 14:31:41 -0200 |
---|---|---|
committer | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2014年10月24日 14:31:41 -0200 |
commit | 0c6f675c8a026826b2482db9f978d422ef1f5328 (patch) | |
tree | 30bdd152cd6106e74ee39abcff57973133f59f9b | |
parent | 9c5e2b511ec6f80a350d756d4464acfb10373ee4 (diff) | |
download | lightning-0c6f675c8a026826b2482db9f978d422ef1f5328.tar.gz |
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | lib/jit_ia64.c | 16 | ||||
-rw-r--r-- | lib/jit_ppc-cpu.c | 57 | ||||
-rw-r--r-- | lib/jit_ppc.c | 20 |
@@ -1,3 +1,18 @@ +2014年10月24日 Paulo Andrade <pcpa@gnu.org> + + * 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 <pcpa@gnu.org> * include/lightning.h, lib/lightning.c: Add three predicates diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index f35f396..e3c6554 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 2f65d36..18f4096 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); } @@ -3238,6 +3248,47 @@ _patch_at(jit_state_t *_jit, jit_word_t instr, jit_word_t label) 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); assert((u.i[1] & 0xfc000000) >> 26 == 24); /* ORI */ diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index cbc5dda..8ef6119 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)); |