diff --git a/ChangeLog b/ChangeLog index 22b52dd8a..29f7dace6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-01-31 Paulo Andrade + + * lib/jit_arm-cpu.c, lib/jit_arm.c: Only limit to 24 bit + displacement non conditional jump in the same jit_state_t. + 2015-01-19 Paulo Andrade * doc/body.texi: Reorder documentation, making jit_frame diff --git a/lib/jit_arm-cpu.c b/lib/jit_arm-cpu.c index 6f4ae6f67..a54b4efb3 100644 --- a/lib/jit_arm-cpu.c +++ b/lib/jit_arm-cpu.c @@ -966,8 +966,8 @@ static void _nei(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t); static void _jmpr(jit_state_t*,jit_int32_t); # define jmpi(i0) _jmpi(_jit,i0) static void _jmpi(jit_state_t*,jit_word_t); -# define jmpi_p(i0) _jmpi_p(_jit,i0) -static jit_word_t _jmpi_p(jit_state_t*,jit_word_t); +# define jmpi_p(i0, i1) _jmpi_p(_jit,i0, i1) +static jit_word_t _jmpi_p(jit_state_t*,jit_word_t,jit_bool_t); # define bccr(cc,i0,r0,r1) _bccr(_jit,cc,i0,r0,r1) static jit_word_t _bccr(jit_state_t*,int,jit_word_t,jit_int32_t,jit_int32_t); # define bcci(cc,i0,r0,i1) _bcci(_jit,cc,i0,r0,i1) @@ -2570,52 +2570,63 @@ _jmpi(jit_state_t *_jit, jit_word_t i0) { jit_word_t w; jit_word_t d; + jit_int32_t reg; w = _jit->pc.w; /* if thumb and in thumb mode */ if (jit_thumb_p() && _jitc->thumb) { d = ((i0 - w) >> 1) - 2; if (d >= -1024 && d <= 1023) T1_B(d & 0x7ff); - else { - assert(_s24P(d)); + else if (_s24P(d)) T2_B(encode_thumb_jump(d)); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); } } else { d = ((i0 - w) >> 2) - 2; - assert(_s24P(d)); - B(d & 0x00ffffff); + if (_s24P(d)) + B(d & 0x00ffffff); + else { + reg = jit_get_reg(jit_class_gpr|jit_class_nospill); + movi(rn(reg), i0); + jmpr(rn(reg)); + jit_unget_reg(reg); + } } } static jit_word_t -_jmpi_p(jit_state_t *_jit, jit_word_t i0) +_jmpi_p(jit_state_t *_jit, jit_word_t i0, jit_bool_t i1) { -#if 0 - jit_word_t w; - jit_int32_t reg; - 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); -#else jit_word_t w; jit_word_t d; - w = _jit->pc.w; - /* if thumb and in thumb mode */ - if (jit_thumb_p() && _jitc->thumb) { - d = ((i0 - w) >> 1) - 2; - assert(_s24P(d)); - T2_B(encode_thumb_jump(d)); + jit_int32_t reg; + if (i1) { + /* Assume jump is not longer than 23 bits if inside jit */ + w = _jit->pc.w; + /* if thumb and in thumb mode */ + if (jit_thumb_p() && _jitc->thumb) { + d = ((i0 - w) >> 1) - 2; + assert(_s24P(d)); + T2_B(encode_thumb_jump(d)); + } + else { + d = ((i0 - w) >> 2) - 2; + assert(_s24P(d)); + B(d & 0x00ffffff); + } } else { - d = ((i0 - w) >> 2) - 2; - assert(_s24P(d)); - B(d & 0x00ffffff); + 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); -#endif } static jit_word_t diff --git a/lib/jit_arm.c b/lib/jit_arm.c index e0e680f78..6edac9454 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1555,7 +1555,8 @@ _emit_code(jit_state_t *_jit) if (temp->flag & jit_flag_patch) jmpi(temp->u.w); else { - word = jmpi_p(_jit->pc.w); + word = jmpi_p(_jit->pc.w, + !!(node->flag & jit_flag_node)); patch(word, node); } } @@ -2002,7 +2003,8 @@ _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) } else { flag = node->u.n->flag; - if (node->code == jit_code_calli) + if (node->code == jit_code_calli || + (node->code == jit_code_jmpi && !(node->flag & jit_flag_node))) kind = arm_patch_word; else kind = arm_patch_jump;