From 20a2f1f9c539c6b7509f9a32ef926b9b9dd98cc9 Mon Sep 17 00:00:00 2001 From: pcpa Date: Tue, 14 Oct 2014 17:04:13 -0300 Subject: [PATCH] Allow jit_jmpi on an immediate constant address. * lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c, lib/jit_hppa.c, lib/jit_ia64.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_s390x.c, lib/jit_sparc.c, lib/jit_x86.c, lib/lightning.c: Allow jit_jmpi on a target that is not a node. This may lead to hard to debug code generation, but is a required feature for certain generators, like the ones that used lightning 1.2x. Note that previously, but not really well documented, it was instructed to use: jit_movi(rn, addr); jit_jmpr(rn); but now, plain: jit_patch_abs(jit_jmpi(), addr); should also work. --- ChangeLog | 16 ++++++++++++++++ lib/jit_aarch64.c | 20 ++++++++++++-------- lib/jit_alpha.c | 20 ++++++++++++-------- lib/jit_arm.c | 20 ++++++++++++-------- lib/jit_hppa.c | 21 ++++++++++++--------- lib/jit_ia64.c | 24 ++++++++++++++---------- lib/jit_mips.c | 20 ++++++++++++-------- lib/jit_ppc.c | 25 ++++++++++++++----------- lib/jit_s390x.c | 20 ++++++++++++-------- lib/jit_sparc.c | 20 ++++++++++++-------- lib/jit_x86.c | 20 ++++++++++++-------- lib/lightning.c | 5 ++++- 12 files changed, 144 insertions(+), 87 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa8b3ebdf..578003452 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2014-09-29 Paulo Andrade + + * lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c, + lib/jit_hppa.c, lib/jit_ia64.c, lib/jit_mips.c, + lib/jit_ppc.c, lib/jit_s390x.c, lib/jit_sparc.c, + lib/jit_x86.c, lib/lightning.c: Allow jit_jmpi on a + target that is not a node. This may lead to hard to + debug code generation, but is a required feature for + certain generators, like the ones that used lightning + 1.2x. Note that previously, but not really well + documented, it was instructed to use: + jit_movi(rn, addr); jit_jmpr(rn); + but now, plain: + jit_patch_abs(jit_jmpi(), addr); + should also work. + 2014-09-24 Paulo Andrade * lib/jit_x86-sz.c: Generate information about instruction diff --git a/lib/jit_aarch64.c b/lib/jit_aarch64.c index ca522a597..94c52b73b 100644 --- a/lib/jit_aarch64.c +++ b/lib/jit_aarch64.c @@ -1070,15 +1070,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_alpha.c b/lib/jit_alpha.c index cb91370ce..84b055cec 100644 --- a/lib/jit_alpha.c +++ b/lib/jit_alpha.c @@ -1097,15 +1097,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 62d8e8af7..bdafcddd5 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1385,15 +1385,19 @@ _emit_code(jit_state_t *_jit) flush_consts(); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); flush_consts(); break; case jit_code_callr: diff --git a/lib/jit_hppa.c b/lib/jit_hppa.c index 192da9391..289542fad 100644 --- a/lib/jit_hppa.c +++ b/lib/jit_hppa.c @@ -1059,16 +1059,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - /* no support for jump outside jit */ - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index 6abf1a7fc..ee2ebcd92 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -1214,17 +1214,21 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - if (_jit->pc.uc == _jit->code.ptr + 16) - _jitc->jump = 1; - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + if (_jit->pc.uc == _jit->code.ptr + 16) + _jitc->jump = 1; + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 88f128cd9..3eec489cb 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -1343,15 +1343,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index 501b22323..758f52ad9 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -1236,20 +1236,23 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: + if (node->flag & jit_flag_node) { #if __powerpc__ - if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3) - _jitc->jump = 1; + if (_jit->pc.uc == _jit->code.ptr + sizeof(void*) * 3) + _jitc->jump = 1; #endif - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - /* no support for jump outside jit */ - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi(_jit->pc.w); - patch(word, node); + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_s390x.c b/lib/jit_s390x.c index 184780bb4..99802a584 100644 --- a/lib/jit_s390x.c +++ b/lib/jit_s390x.c @@ -1052,15 +1052,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_sparc.c b/lib/jit_sparc.c index f1f4bffc5..81a9f5c23 100644 --- a/lib/jit_sparc.c +++ b/lib/jit_sparc.c @@ -1055,15 +1055,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi_p(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi_p(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/jit_x86.c b/lib/jit_x86.c index dc386bea2..747741d5b 100644 --- a/lib/jit_x86.c +++ b/lib/jit_x86.c @@ -1668,15 +1668,19 @@ _emit_code(jit_state_t *_jit) jmpr(rn(node->u.w)); break; case jit_code_jmpi: - temp = node->u.n; - assert(temp->code == jit_code_label || - temp->code == jit_code_epilog); - if (temp->flag & jit_flag_patch) - jmpi(temp->u.w); - else { - word = jmpi(_jit->pc.w); - patch(word, node); + if (node->flag & jit_flag_node) { + temp = node->u.n; + assert(temp->code == jit_code_label || + temp->code == jit_code_epilog); + if (temp->flag & jit_flag_patch) + jmpi(temp->u.w); + else { + word = jmpi(_jit->pc.w); + patch(word, node); + } } + else + jmpi(node->u.w); break; case jit_code_callr: callr(rn(node->u.w)); diff --git a/lib/lightning.c b/lib/lightning.c index 1516bd40b..8642cf89a 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -2295,6 +2295,8 @@ _shortcut_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) for (next = jump->next; next; next = next->next) { switch (next->code) { case jit_code_jmpi: + if (!(next->flag & jit_flag_node)) + return (0); if (jump->link == node) jump->link = node->link; else { @@ -2500,7 +2502,8 @@ _reverse_jump(jit_state_t *_jit, jit_node_t *prev, jit_node_t *node) return (0); /* =>