This rule is needed to compile code like this: public int foo() { return 1 / 0; }
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- arch/x86/emit-code.c | 8 +++++++- arch/x86/include/arch/instruction.h | 1 + arch/x86/insn-selector_32.brg | 15 +++++++++++++++ arch/x86/lir-printer.c | 7 +++++++ arch/x86/use-def.c | 3 ++- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index f7b629d..d66d9f0 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -849,6 +849,12 @@ static void emit_div_membase_reg(struct buffer *buf, struct operand *src, __emit_div_mul_membase_eax(buf, src, dest, 0x07); } +static void emit_div_reg_reg(struct buffer *buf, struct operand *src, + struct operand *dest) +{ + __emit_div_mul_reg_eax(buf, src, dest, 0x07); +} + static void __emit_shift_reg_reg(struct buffer *buf, struct operand *src, struct operand *dest, unsigned char opc_ext) @@ -1003,6 +1009,7 @@ struct emitter emitters[] = { DECL_EMITTER(INSN_CMP_MEMBASE_REG, emit_cmp_membase_reg, TWO_OPERANDS), DECL_EMITTER(INSN_CMP_REG_REG, emit_cmp_reg_reg, TWO_OPERANDS), DECL_EMITTER(INSN_DIV_MEMBASE_REG, emit_div_membase_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_DIV_REG_REG, emit_div_reg_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_MEMBASE, emit_mov_imm_membase, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_REG, emit_mov_imm_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMLOCAL_REG, emit_mov_memlocal_reg, TWO_OPERANDS), @@ -1564,4 +1571,3 @@ void emit_trampoline(struct compilation_unit *cu, void *call_target, } #endif /* CONFIG_X86_32 */ - diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index 72b9698..5e38144 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -68,6 +68,7 @@ enum insn_type { INSN_CMP_MEMBASE_REG, INSN_CMP_REG_REG, INSN_DIV_MEMBASE_REG, + INSN_DIV_REG_REG, INSN_JE_BRANCH, INSN_JGE_BRANCH, INSN_JG_BRANCH, diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg index 12f7e9e..fce1f50 100644 --- a/arch/x86/insn-selector_32.brg +++ b/arch/x86/insn-selector_32.brg @@ -306,6 +306,21 @@ reg: OP_DIV(reg, EXPR_LOCAL) 1 div_reg_local(state, s, tree); } +reg: OP_DIV(reg, reg) 1 +{ + struct var_info *edx; + struct var_info *result; + + edx = get_fixed_var(s->b_parent, REG_EDX); + result = get_fixed_var(s->b_parent, REG_EAX); + + state->reg1 = result; + + select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, state->left->reg1, result)); + select_insn(s, tree, reg_reg_insn(INSN_CLTD_REG_REG, result, edx)); + select_insn(s, tree, reg_reg_insn(INSN_DIV_REG_REG, state->right->reg1, result)); +} + reg: OP_DIV_64(reg, reg) 1 { emulate_op_64(state, s, tree, emulate_ldiv, J_LONG); diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c index c5c6348..195f80e 100644 --- a/arch/x86/lir-printer.c +++ b/arch/x86/lir-printer.c @@ -240,6 +240,12 @@ static int print_div_membase_reg(struct string *str, struct insn *insn) return print_membase_reg(str, insn); } +static int print_div_reg_reg(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_reg_reg(str, insn); +} + static int print_je_branch(struct string *str, struct insn *insn) { print_func_name(str); @@ -502,6 +508,7 @@ static print_insn_fn insn_printers[] = { [INSN_CMP_MEMBASE_REG] = print_cmp_membase_reg, [INSN_CMP_REG_REG] = print_cmp_reg_reg, [INSN_DIV_MEMBASE_REG] = print_div_membase_reg, + [INSN_DIV_REG_REG] = print_div_reg_reg, [INSN_JE_BRANCH] = print_je_branch, [INSN_JGE_BRANCH] = print_jge_branch, [INSN_JG_BRANCH] = print_jg_branch, diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index a0555c9..95342ad 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -42,7 +42,8 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_CLTD_REG_REG, USE_SRC | DEF_SRC | DEF_DST), DECLARE_INFO(INSN_CMP_IMM_REG, USE_DST), DECLARE_INFO(INSN_CMP_MEMBASE_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN_DIV_MEMBASE_REG, USE_SRC | DEF_DST), + DECLARE_INFO(INSN_DIV_MEMBASE_REG, USE_SRC | DEF_DST | DEF_EAX | DEF_EDX), + DECLARE_INFO(INSN_DIV_REG_REG, USE_SRC | DEF_DST | DEF_EAX | DEF_EDX), DECLARE_INFO(INSN_JE_BRANCH, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_JGE_BRANCH, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_JG_BRANCH, USE_NONE | DEF_NONE), -- 1.6.0.6 ------------------------------------------------------------------------------ Are you an open source citizen? Join us for the Open Source Bridge conference! Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250. Need another reason to go? 24-hour hacker lounge. Register today! http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel