From 1287a2d4486d0281ed97e309c83bd3d38131fbd0 Mon Sep 17 00:00:00 2001 From: pcpa Date: Fri, 28 Dec 2012 10:28:50 -0200 Subject: [PATCH] Correct extra regressions found by the call.tst test case. * lib/jit_arm.c, lib/jit_mips-cpu.c, lib/jit_mips.c: Correct regressions when patching jit_calli for a forward function. * lib/jit_ppc-cpu.c: Correct wrong arguments to ANDI opcode in jit_getarg_u{c,s} implementation. --- ChangeLog | 8 ++++++++ lib/jit_arm.c | 40 ++++++++++++++++------------------------ lib/jit_mips-cpu.c | 16 +++++++++++++--- lib/jit_mips.c | 2 +- lib/jit_ppc-cpu.c | 4 ++-- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ab7d7c34..a4e89ad41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2012-12-27 Paulo Andrade + + * lib/jit_arm.c, lib/jit_mips-cpu.c, lib/jit_mips.c: Correct + regressions when patching jit_calli for a forward function. + + * lib/jit_ppc-cpu.c: Correct wrong arguments to ANDI opcode + in jit_getarg_u{c,s} implementation. + 2012-12-23 Paulo Andrade * check/call.ok, check/call.tst: New test cases to validate diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 0a110707a..1b3bd8c23 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1468,26 +1468,21 @@ _jit_emit(jit_state_t *_jit) assert(_jit->patches.ptr[offset].kind & arm_patch_node); node = _jit->patches.ptr[offset].node; word = _jit->patches.ptr[offset].inst; - if (node->code == jit_code_movi) { - if (jit_thumb_p()) - value = node->v.n->u.w; - else { - /* calculate where to patch word */ - value = *(jit_int32_t *)word; - assert((value & 0x0f700000) == ARM_LDRI); - /* offset may become negative (-4) if last instruction - * before unconditional branch and data following - * FIXME can this cause issues in the preprocessor prefetch - * or something else? should not, as the constants are after - * an unconditional jump */ - if (value & ARM_P) value = value & 0x00000fff; - else value = -(value & 0x00000fff); - word = word + 8 + value; - value = node->v.n->u.w; - } - } - else - value = node->u.n->u.w; + if (!jit_thumb_p() && + (node->code == jit_code_movi || node->code == jit_code_calli)) { + /* calculate where to patch word */ + value = *(jit_int32_t *)word; + assert((value & 0x0f700000) == ARM_LDRI); + /* offset may become negative (-4) if last instruction + * before unconditional branch and data following + * FIXME can this cause issues in the preprocessor prefetch + * or something else? should not, as the constants are after + * an unconditional jump */ + if (value & ARM_P) value = value & 0x00000fff; + else value = -(value & 0x00000fff); + word = word + 8 + value; + } + value = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w; patch_at(_jit->patches.ptr[offset].kind & ~arm_patch_node, word, value); } @@ -1715,12 +1710,9 @@ _patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node) } else { flag = node->u.n->flag; -#if 1 - /* should work if #if 0'ed, but better to avoid the goto fallback */ - if (node->code == jit_code_calli && jit_thumb_p()) + if (node->code == jit_code_calli) kind = arm_patch_word; else -#endif kind = arm_patch_jump; } assert(!(flag & jit_flag_patch)); diff --git a/lib/jit_mips-cpu.c b/lib/jit_mips-cpu.c index 5e5c598db..311326032 100644 --- a/lib/jit_mips-cpu.c +++ b/lib/jit_mips-cpu.c @@ -654,7 +654,9 @@ static jit_word_t _bmci(jit_state_t*,jit_word_t,jit_int32_t,jit_word_t); # define callr(r0) _callr(_jit, r0) static void _callr(jit_state_t*,jit_int32_t); # define calli(i0) _calli(_jit, i0) -static jit_word_t _calli(jit_state_t*,jit_word_t); +static void _calli(jit_state_t*,jit_word_t); +# define calli_p(i0) _calli_p(_jit, i0) +static jit_word_t _calli_p(jit_state_t*,jit_word_t); # define prolog(node) _prolog(_jit, node) static void _prolog(jit_state_t*,jit_node_t*); # define epilog(node) _epilog(_jit, node) @@ -2681,13 +2683,21 @@ _callr(jit_state_t *_jit, jit_int32_t r0) NOP(1); } -static jit_word_t +static void _calli(jit_state_t *_jit, jit_word_t i0) +{ + movi(_T9_REGNO, i0); + JALR(_T9_REGNO); + NOP(1); +} + +static jit_word_t +_calli_p(jit_state_t *_jit, jit_word_t i0) { jit_word_t word; word = _jit->pc.w; - movi(_T9_REGNO, i0); + movi_p(_T9_REGNO, i0); JALR(_T9_REGNO); NOP(1); diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 1773b5db1..80ac40d1a 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -1180,7 +1180,7 @@ _jit_emit(jit_state_t *_jit) temp = node->u.n; assert(temp->code == jit_code_label || temp->code == jit_code_epilog); - word = calli(temp->u.w); + word = calli_p(temp->u.w); if (!(temp->flag & jit_flag_patch)) patch(word, node); } diff --git a/lib/jit_ppc-cpu.c b/lib/jit_ppc-cpu.c index ee1509df1..c0c6c70c1 100644 --- a/lib/jit_ppc-cpu.c +++ b/lib/jit_ppc-cpu.c @@ -362,9 +362,9 @@ static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t); # define negr(r0,r1) NEG(r0,r1) # define comr(r0,r1) NOT(r0,r1) # define extr_c(r0,r1) EXTSB(r0,r1) -# define extr_uc(r0,r1) ANDI_(r0,r0,0xff) +# define extr_uc(r0,r1) ANDI_(r0,r1,0xff) # define extr_s(r0,r1) EXTSH(r0,r1) -# define extr_us(r0,r1) ANDI_(r0,r0,0xffff) +# define extr_us(r0,r1) ANDI_(r0,r1,0xffff) # if __BYTE_ORDER == __BIG_ENDIAN # define htonr(r0,r1) movr(r0,r1) # else