diff --git a/ChangeLog b/ChangeLog index 29f7dace6..d352f0c5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2015-02-02 Paulo Andrade + + * configure.ac, include/lightning/jit_private.h, + lib/jit_aarch64.c, lib/jit_alpha.c, lib/jit_arm.c, + lib/jit_disasm.c, lib/jit_hppa.c, lib/jit_ia64.c, + lib/jit_mips.c, lib/jit_ppc.c, lib/jit_print.c, + lib/jit_s390.c, lib/jit_sparc.c, lib/jit_x86.c: Add a new + --enable-devel-disassembler option, that should be used + during development, or lightning debug. This option + intermixes previous jit_print and jit_disassemble + output, making it easier to visualize what lightning + call was used, and what code was generated. + 2015-01-31 Paulo Andrade * lib/jit_arm-cpu.c, lib/jit_arm.c: Only limit to 24 bit diff --git a/configure.ac b/configure.ac index d26e7777b..b27da4a92 100644 --- a/configure.ac +++ b/configure.ac @@ -95,6 +95,17 @@ if test "x$DISASSEMBLER" != "xno"; then LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1" fi +AC_ARG_ENABLE(devel-disassembler, + AS_HELP_STRING([--enable-devel-disassembler], + [Enable extra disassembly options]), + [DEVEL_DISASSEMBLER=$enableval], [DEVEL_DISASSEMBLER=no]) +if test "x$DEVEL_DISASSEMBLER" != "xno"; then + if test "x$DISASSEMBLER" = "xno"; then + AC_MSG_ERROR(devel-disassembler needs disassembler enabled) + fi + LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDEVEL_DISASSEMBLER=1" +fi + AC_ARG_ENABLE(assertions, AS_HELP_STRING([--enable-assertions], [Enable runtime code generation assertions]), diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index 32aa31c1c..b88463b26 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -303,6 +303,9 @@ struct jit_node { jit_data_t v; jit_data_t w; jit_node_t *link; +#if DEVEL_DISASSEMBLER + jit_uword_t offset; +#endif }; struct jit_block { @@ -618,6 +621,9 @@ extern void _jit_set_note(jit_state_t*, jit_note_t*, char*, int, jit_int32_t); #define jit_annotate() _jit_annotate(_jit) extern void _jit_annotate(jit_state_t*); +#define jit_print_node(u) _jit_print_node(_jit,u) +extern void _jit_print_node(jit_state_t*,jit_node_t*); + extern jit_pointer_t jit_memcpy(jit_pointer_t,const void*,jit_word_t); extern jit_pointer_t jit_memmove(jit_pointer_t,const void*,jit_word_t); extern void jit_alloc(jit_pointer_t*, jit_word_t); diff --git a/lib/jit_aarch64.c b/lib/jit_aarch64.c index 7da15a543..411571962 100644 --- a/lib/jit_aarch64.c +++ b/lib/jit_aarch64.c @@ -791,6 +791,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_alpha.c b/lib/jit_alpha.c index e3c78caf9..cfd91cf4e 100644 --- a/lib/jit_alpha.c +++ b/lib/jit_alpha.c @@ -784,6 +784,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_arm.c b/lib/jit_arm.c index 8b5abb10e..77466383e 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1186,6 +1186,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index 86e54416b..7b45aa1a8 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -327,6 +327,9 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) bfd_vma pc = (jit_uword_t)code; bfd_vma end = (jit_uword_t)code + length; char buffer[address_buffer_length]; +#if DEVEL_DISASSEMBLER + jit_node_t *node; +#endif #if __arm__ data_info = _jitc && _jitc->data_info.ptr; @@ -338,7 +341,19 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) old_file = old_name = NULL; old_line = 0; disasm_jit = _jit; +#if DEVEL_DISASSEMBLER + node = _jitc->head; +#endif while (pc < end) { +#if DEVEL_DISASSEMBLER + while (node && node->offset < (jit_uword_t)pc) + node = node->next; + while (node && node->offset == (jit_uword_t)pc) { + jit_print_node(node); + fputc('\n', stdout); + node = node->next; + } +#endif #if __arm__ again: if (data_info) { diff --git a/lib/jit_hppa.c b/lib/jit_hppa.c index 37f36509f..3a7913821 100644 --- a/lib/jit_hppa.c +++ b/lib/jit_hppa.c @@ -804,6 +804,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_ia64.c b/lib/jit_ia64.c index 86fea1378..59c915392 100644 --- a/lib/jit_ia64.c +++ b/lib/jit_ia64.c @@ -913,6 +913,10 @@ _emit_code(jit_state_t *_jit) value = jit_classify(node->code); #if GET_JIT_SIZE sync(); +#endif +#if DEVEL_DISASSEMBLER + sync(); + node->offset = _jit->pc.w; #endif jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_mips.c b/lib/jit_mips.c index 60ec598cf..6ee35fbca 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -1069,6 +1069,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index a5e4a761f..3abaf7557 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -931,6 +931,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_print.c b/lib/jit_print.c index 790a268d0..073568e44 100644 --- a/lib/jit_print.c +++ b/lib/jit_print.c @@ -45,51 +45,58 @@ void _jit_print(jit_state_t *_jit) { jit_node_t *node; + + if ((node = _jitc->head)) { + jit_print_node(node); + for (node = node->next; node; node = node->next) { + print_chr('\n'); + jit_print_node(node); + } + print_chr('\n'); + } +} + +void +_jit_print_node(jit_state_t *_jit, jit_node_t *node) +{ jit_block_t *block; - jit_bool_t first; jit_int32_t value; jit_int32_t offset; - first = 0; - for (node = _jitc->head; node; node = node->next) { - if (!first) - print_chr('\n'); - else - first = 0; - if (node->code == jit_code_label || - node->code == jit_code_prolog || node->code == jit_code_epilog) { - print_chr('L'); - print_dec(node->v.w); - print_chr(':'); - block = _jitc->blocks.ptr + node->v.w; - for (offset = 0; offset < _jitc->reglen; offset++) { - if (jit_regset_tstbit(&block->reglive, offset)) { - print_chr(' '); - print_reg(offset); - } + if (node->code == jit_code_label || + node->code == jit_code_prolog || node->code == jit_code_epilog) { + print_chr('L'); + print_dec(node->v.w); + print_chr(':'); + block = _jitc->blocks.ptr + node->v.w; + for (offset = 0; offset < _jitc->reglen; offset++) { + if (jit_regset_tstbit(&block->reglive, offset)) { + print_chr(' '); + print_reg(offset); } - if (node->code == jit_code_prolog || - node->code == jit_code_epilog) { - print_str(" /* "); - print_str(code_name[node->code]); - print_str(" */"); - } - continue; } - value = jit_classify(node->code) & - (jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh| - jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl| - jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl); - if (value & jit_cc_a0_jmp) - print_str(" "); - else - print_chr('\t'); - print_str(code_name[node->code]); - switch (node->code) { + if (node->code == jit_code_prolog || + node->code == jit_code_epilog) { + print_str(" /* "); + print_str(code_name[node->code]); + print_str(" */"); + } + return; + } + value = jit_classify(node->code) & + (jit_cc_a0_int|jit_cc_a0_jmp|jit_cc_a0_reg|jit_cc_a0_rlh| + jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl| + jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl); + if (value & jit_cc_a0_jmp) + print_str(" "); + else + print_chr('\t'); + print_str(code_name[node->code]); + switch (node->code) { r: - print_chr(' '); print_reg(node->u.w); continue; + print_chr(' '); print_reg(node->u.w); return; w: - print_chr(' '); print_hex(node->u.w); continue; + print_chr(' '); print_hex(node->u.w); return; n: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -98,72 +105,72 @@ _jit_print(jit_state_t *_jit) print_chr('L'); print_dec(node->u.n->v.w); } - continue; + return; r_r: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_reg(node->v.w); continue; + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); return; r_w: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_hex(node->v.w); continue; + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_hex(node->v.w); return; r_f: - print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->u.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float32_t *)node->v.n->u.w); else print_flt(node->v.f); - continue; + return; r_d: - print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->u.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float64_t *)node->v.n->u.w); else print_flt(node->v.d); - continue; + return; w_r: - print_chr(' '); print_hex(node->u.w); - print_chr(' '); print_reg(node->v.w); continue; + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_reg(node->v.w); return; r_r_r: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_reg(node->v.w); - print_chr(' '); print_reg(node->w.w); continue; + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; r_r_w: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_reg(node->v.w); - print_chr(' '); print_hex(node->w.w); continue; + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; q_r_r: - print_str(" ("); print_reg(node->u.q.l); - print_chr(' '); print_reg(node->u.q.h); - print_str(") "); print_reg(node->v.w); - print_chr(' '); print_reg(node->w.w); continue; + print_str(" ("); print_reg(node->u.q.l); + print_chr(' '); print_reg(node->u.q.h); + print_str(") "); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; q_r_w: - print_str(" ("); print_reg(node->u.q.l); - print_chr(' '); print_reg(node->u.q.h); - print_str(") "); print_reg(node->v.w); - print_chr(' '); print_hex(node->w.w); continue; + print_str(" ("); print_reg(node->u.q.l); + print_chr(' '); print_reg(node->u.q.h); + print_str(") "); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; r_r_f: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float32_t *)node->w.n->u.w); else print_flt(node->w.f); - continue; + return; r_r_d: - print_chr(' '); print_reg(node->u.w); - print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->u.w); + print_chr(' '); print_reg(node->v.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float64_t *)node->w.n->u.w); else print_flt(node->w.d); - continue; + return; w_r_r: - print_chr(' '); print_hex(node->u.w); - print_chr(' '); print_reg(node->v.w); - print_chr(' '); print_reg(node->w.w); continue; + print_chr(' '); print_hex(node->u.w); + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; n_r_r: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -172,8 +179,8 @@ _jit_print(jit_state_t *_jit) print_chr('L'); print_dec(node->u.n->v.w); } - print_chr(' '); print_reg(node->v.w); - print_chr(' '); print_reg(node->w.w); continue; + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->w.w); return; n_r_w: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -182,8 +189,8 @@ _jit_print(jit_state_t *_jit) print_chr('L'); print_dec(node->u.n->v.w); } - print_chr(' '); print_reg(node->v.w); - print_chr(' '); print_hex(node->w.w); continue; + print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_hex(node->w.w); return; n_r_f: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -192,13 +199,13 @@ _jit_print(jit_state_t *_jit) print_chr('L'); print_dec(node->u.n->v.w); } - print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->v.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float32_t *)node->w.n->u.w); else print_flt(node->w.f); - continue; + return; n_r_d: print_chr(' '); if (!(node->flag & jit_flag_node)) @@ -207,82 +214,80 @@ _jit_print(jit_state_t *_jit) print_chr('L'); print_dec(node->u.n->v.w); } - print_chr(' '); print_reg(node->v.w); + print_chr(' '); print_reg(node->v.w); print_chr(' '); if (node->flag & jit_flag_data) print_flt(*(jit_float64_t *)node->w.n->u.w); else print_flt(node->w.d); - continue; - case jit_code_name: - print_chr(' '); - if (node->v.p && _jitc->emit) - print_str(node->v.n->u.p); - break; - case jit_code_note: - print_chr(' '); - if (node->v.p && _jitc->emit) - print_str(node->v.n->u.p); - if (node->v.p && _jitc->emit && node->w.w) - print_chr(':'); - if (node->w.w) - print_dec(node->w.w); - break; - case jit_code_data: - case jit_code_label: - case jit_code_prolog: case jit_code_epilog: - break; - case jit_code_save: case jit_code_load: - goto r; - default: - switch (value) { - case jit_cc_a0_reg: - case jit_cc_a0_reg|jit_cc_a0_chg: - case jit_cc_a0_reg|jit_cc_a0_jmp: - goto r; - case jit_cc_a0_int: - goto w; - case jit_cc_a0_jmp: - goto n; - case jit_cc_a0_reg|jit_cc_a1_reg: - goto r_r; - case jit_cc_a0_reg|jit_cc_a1_int: - goto r_w; - case jit_cc_a0_reg|jit_cc_a1_flt: - goto r_f; - case jit_cc_a0_reg|jit_cc_a1_dbl: - goto r_d; - case jit_cc_a0_int|jit_cc_a1_reg: - goto w_r; - case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg: - goto r_r_r; - case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int: - goto r_r_w; - case jit_cc_a0_reg|jit_cc_a0_rlh| - jit_cc_a1_reg|jit_cc_a2_reg: - goto q_r_r; - case jit_cc_a0_reg|jit_cc_a0_rlh| - jit_cc_a1_reg|jit_cc_a2_int: - goto q_r_w; - case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_flt: - goto r_r_f; - case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_dbl: - goto r_r_d; - case jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg: - goto w_r_r; - case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg: - goto n_r_r; - case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int: - goto n_r_w; - case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt: - goto n_r_f; - case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl: - goto n_r_d; - default: - abort(); - } - break; - } + return; + case jit_code_name: + print_chr(' '); + if (node->v.p && _jitc->emit) + print_str(node->v.n->u.p); + break; + case jit_code_note: + print_chr(' '); + if (node->v.p && _jitc->emit) + print_str(node->v.n->u.p); + if (node->v.p && _jitc->emit && node->w.w) + print_chr(':'); + if (node->w.w) + print_dec(node->w.w); + break; + case jit_code_data: + case jit_code_label: + case jit_code_prolog: case jit_code_epilog: + break; + case jit_code_save: case jit_code_load: + goto r; + default: + switch (value) { + case jit_cc_a0_reg: + case jit_cc_a0_reg|jit_cc_a0_chg: + case jit_cc_a0_reg|jit_cc_a0_jmp: + goto r; + case jit_cc_a0_int: + goto w; + case jit_cc_a0_jmp: + goto n; + case jit_cc_a0_reg|jit_cc_a1_reg: + goto r_r; + case jit_cc_a0_reg|jit_cc_a1_int: + goto r_w; + case jit_cc_a0_reg|jit_cc_a1_flt: + goto r_f; + case jit_cc_a0_reg|jit_cc_a1_dbl: + goto r_d; + case jit_cc_a0_int|jit_cc_a1_reg: + goto w_r; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_reg: + goto r_r_r; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_int: + goto r_r_w; + case jit_cc_a0_reg|jit_cc_a0_rlh| + jit_cc_a1_reg|jit_cc_a2_reg: + goto q_r_r; + case jit_cc_a0_reg|jit_cc_a0_rlh| + jit_cc_a1_reg|jit_cc_a2_int: + goto q_r_w; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_flt: + goto r_r_f; + case jit_cc_a0_reg|jit_cc_a1_reg|jit_cc_a2_dbl: + goto r_r_d; + case jit_cc_a0_int|jit_cc_a1_reg|jit_cc_a2_reg: + goto w_r_r; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_reg: + goto n_r_r; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_int: + goto n_r_w; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_flt: + goto n_r_f; + case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl: + goto n_r_d; + default: + abort(); + } + break; } - print_chr('\n'); } diff --git a/lib/jit_s390.c b/lib/jit_s390.c index bbeb86bb0..c811acedf 100644 --- a/lib/jit_s390.c +++ b/lib/jit_s390.c @@ -808,6 +808,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_sparc.c b/lib/jit_sparc.c index 8924cf9c5..a0ebd940c 100644 --- a/lib/jit_sparc.c +++ b/lib/jit_sparc.c @@ -823,6 +823,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) { diff --git a/lib/jit_x86.c b/lib/jit_x86.c index 87f6dc2f0..7b43bd3c5 100644 --- a/lib/jit_x86.c +++ b/lib/jit_x86.c @@ -1351,6 +1351,9 @@ _emit_code(jit_state_t *_jit) if (_jit->pc.uc >= _jitc->code.end) return (NULL); +#if DEVEL_DISASSEMBLER + node->offset = _jit->pc.w; +#endif value = jit_classify(node->code); jit_regarg_set(node, value); switch (node->code) {