Instruction is used to perform a near jump to absolute address which value is read from register. There is no such instruction in x86 so this is emited as PUSH_REG and a following RET.
Signed-off-by: Tomek Grabiec <[email protected]> --- arch/x86/emit-code_32.c | 12 ++++++++++++ arch/x86/include/arch/instruction.h | 1 + arch/x86/lir-printer.c | 7 +++++++ arch/x86/use-def.c | 1 + 4 files changed, 21 insertions(+), 0 deletions(-) diff --git a/arch/x86/emit-code_32.c b/arch/x86/emit-code_32.c index 5160cce..f0dda72 100644 --- a/arch/x86/emit-code_32.c +++ b/arch/x86/emit-code_32.c @@ -451,6 +451,17 @@ void emit_ret(struct buffer *buf) emit(buf, 0xc3); } +static void __emit_jmp_reg_direct(struct buffer *buf, enum machine_reg reg) +{ + __emit_push_reg(buf, reg); + emit_ret(buf); +} + +static void emit_jmp_reg_direct(struct buffer *buf, struct operand *operand) +{ + __emit_jmp_reg_direct(buf, mach_reg(&operand->reg)); +} + void emit_epilog(struct buffer *buf, unsigned long nr_locals) { if (nr_locals) @@ -813,6 +824,7 @@ static struct emitter emitters[] = { DECL_EMITTER(INSN_JLE_BRANCH, emit_jle_branch, BRANCH), DECL_EMITTER(INSN_JL_BRANCH, emit_jl_branch, BRANCH), DECL_EMITTER(INSN_JMP_BRANCH, emit_jmp_branch, BRANCH), + DECL_EMITTER(INSN_JMP_REG_DIRECT, emit_jmp_reg_direct, SINGLE_OPERAND), DECL_EMITTER(INSN_JNE_BRANCH, emit_jne_branch, BRANCH), DECL_EMITTER(INSN_MOV_IMM_MEMBASE, emit_mov_imm_membase, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_REG, emit_mov_imm_reg, TWO_OPERANDS), diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index ac75e40..66df092 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -74,6 +74,7 @@ enum insn_type { INSN_JLE_BRANCH, INSN_JL_BRANCH, INSN_JMP_BRANCH, + INSN_JMP_REG_DIRECT, INSN_JNE_BRANCH, INSN_MOV_IMM_MEMBASE, INSN_MOV_IMM_REG, diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c index dfbd5d9..7d3b46f 100644 --- a/arch/x86/lir-printer.c +++ b/arch/x86/lir-printer.c @@ -261,6 +261,12 @@ static int print_jmp_branch(struct string *str, struct insn *insn) return print_branch(str, &insn->operand); } +static int print_jmp_reg_direct(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_reg(str, &insn->operand); +} + static int print_jne_branch(struct string *str, struct insn *insn) { print_func_name(str); @@ -471,6 +477,7 @@ static print_insn_fn insn_printers[] = { [INSN_JLE_BRANCH] = print_jle_branch, [INSN_JL_BRANCH] = print_jl_branch, [INSN_JMP_BRANCH] = print_jmp_branch, + [INSN_JMP_REG_DIRECT] = print_jmp_reg_direct, [INSN_JNE_BRANCH] = print_jne_branch, [INSN_MOV_IMM_MEMBASE] = print_mov_imm_membase, [INSN_MOV_IMM_REG] = print_mov_imm_reg, diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index 37d5bfc..f57a258 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -48,6 +48,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_JLE_BRANCH, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_JL_BRANCH, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_JMP_BRANCH, USE_NONE | DEF_NONE), + DECLARE_INFO(INSN_JMP_REG_DIRECT, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_JNE_BRANCH, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_MOV_IMM_MEMBASE, USE_DST), DECLARE_INFO(INSN_MOV_IMM_REG, DEF_DST), -- 1.6.0.6 ------------------------------------------------------------------------------ The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com _______________________________________________ Jatovm-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/jatovm-devel
