Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- arch/x86/insn-selector.brg | 112 ++++++++++++++++++++++++++++++-------------- include/jit/expression.h | 1 + jit/expression.c | 5 ++ jit/tree-printer.c | 1 + 4 files changed, 83 insertions(+), 36 deletions(-)
diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg index 50ec45f..fedf194 100644 --- a/arch/x86/insn-selector.brg +++ b/arch/x86/insn-selector.brg @@ -707,22 +707,40 @@ reg: EXPR_INVOKE(arg) 1 select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, edx, state->reg2)); } +freg: EXPR_FINVOKEINTERFACE(arg) 1 +{ + enum vm_type ret_vm_type; + struct var_info *esp; + struct expression *expr; + struct vm_method *method; + + expr = to_expr(tree); + method = expr->target_method; + + ret_vm_type = method_return_type(method); + state->reg1 = get_var(s->b_parent, ret_vm_type); + + invokeinterface(state, s, tree); + + esp = get_fixed_var(s->b_parent, MACH_REG_xSP); + + if (ret_vm_type == J_FLOAT) { + select_insn(s, tree, membase_insn(INSN_FSTP_MEMBASE, esp, -4)); + select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_XMM, esp, -4, state->reg1)); + } else { + select_insn(s, tree, membase_insn(INSN_FSTP_64_MEMBASE, esp, -8)); + select_insn(s, tree, membase_reg_insn(INSN_MOV_64_MEMBASE_XMM, esp, -8, state->reg1)); + } +} + reg: EXPR_INVOKEINTERFACE(arg) 1 { struct var_info *eax, *edx = NULL; - struct var_info *call_target; - struct compilation_unit *cu; - unsigned long method_offset; - struct vm_method *method; struct expression *expr; - struct insn *call_insn; - int nr_stack_args; + struct vm_method *method; expr = to_expr(tree); method = expr->target_method; - cu = method->compilation_unit; - - method_offset = expr_method_index(expr) * sizeof(void *); eax = get_fixed_var(s->b_parent, MACH_REG_xAX); state->reg1 = get_var(s->b_parent, J_INT); @@ -732,33 +750,7 @@ reg: EXPR_INVOKEINTERFACE(arg) 1 state->reg2 = get_var(s->b_parent, J_INT); } - /* object reference */ - call_target = state->left->reg1; - - /* object class */ - select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_REG, - call_target, offsetof(struct vm_object, class), call_target)); - - /* itable entry */ - select_insn(s, tree, imm_reg_insn(INSN_ADD_IMM_REG, - offsetof(struct vm_class, itable) + method->itable_index * 4, - call_target)); - - /* hidden parameter to the conflict resolution stub */ - select_insn(s, tree, imm_reg_insn(INSN_MOV_IMM_REG, - (unsigned long) method, eax)); - - /* invoke method */ - call_insn = reg_insn(INSN_CALL_REG, call_target); - - select_insn(s, tree, call_insn); - - nr_stack_args = get_stack_args_count(method); - if (nr_stack_args) - method_args_cleanup(s, tree, nr_stack_args); - - if (opt_trace_invoke_verbose) - select_trace_return_value(s, tree, method); + invokeinterface(state, s, tree); select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, eax, state->reg1)); if (edx != NULL) @@ -3072,6 +3064,54 @@ static void invokevirtual(struct _MBState *state, struct basic_block *s, struct select_trace_return_value(s, tree, method); } +static void invokeinterface(struct _MBState *state, struct basic_block *s, struct tree_node *tree) +{ + struct var_info *eax; + struct var_info *call_target; + struct compilation_unit *cu; + unsigned long method_offset; + struct vm_method *method; + struct expression *expr; + struct insn *call_insn; + int nr_stack_args; + + expr = to_expr(tree); + method = expr->target_method; + cu = method->compilation_unit; + + eax = get_fixed_var(s->b_parent, MACH_REG_xAX); + + method_offset = expr_method_index(expr) * sizeof(void *); + + /* object reference */ + call_target = state->left->reg1; + + /* object class */ + select_insn(s, tree, membase_reg_insn(INSN_MOV_MEMBASE_REG, + call_target, offsetof(struct vm_object, class), call_target)); + + /* itable entry */ + select_insn(s, tree, imm_reg_insn(INSN_ADD_IMM_REG, + offsetof(struct vm_class, itable) + method->itable_index * 4, + call_target)); + + /* hidden parameter to the conflict resolution stub */ + select_insn(s, tree, imm_reg_insn(INSN_MOV_IMM_REG, + (unsigned long) method, eax)); + + /* invoke method */ + call_insn = reg_insn(INSN_CALL_REG, call_target); + + select_insn(s, tree, call_insn); + + nr_stack_args = get_stack_args_count(method); + if (nr_stack_args) + method_args_cleanup(s, tree, nr_stack_args); + + if (opt_trace_invoke_verbose) + select_trace_return_value(s, tree, method); +} + static void emit_code(struct basic_block *bb, MBState *state, int goal) { MBState *kids[2]; diff --git a/include/jit/expression.h b/include/jit/expression.h index e1cfbfa..605ee60 100644 --- a/include/jit/expression.h +++ b/include/jit/expression.h @@ -39,6 +39,7 @@ enum expression_type { EXPR_INVOKE, EXPR_FINVOKE, EXPR_INVOKEINTERFACE, + EXPR_FINVOKEINTERFACE, EXPR_INVOKEVIRTUAL, EXPR_FINVOKEVIRTUAL, EXPR_ARGS_LIST, diff --git a/jit/expression.c b/jit/expression.c index be1de1b..25b9fc7 100644 --- a/jit/expression.c +++ b/jit/expression.c @@ -54,6 +54,7 @@ int expr_nr_kids(struct expression *expr) case EXPR_FLOAT_INSTANCE_FIELD: case EXPR_INVOKE: case EXPR_INVOKEINTERFACE: + case EXPR_FINVOKEINTERFACE: case EXPR_INVOKEVIRTUAL: case EXPR_FINVOKE: case EXPR_FINVOKEVIRTUAL: @@ -127,6 +128,7 @@ int expr_is_pure(struct expression *expr) case EXPR_INVOKE: case EXPR_INVOKEVIRTUAL: case EXPR_INVOKEINTERFACE: + case EXPR_FINVOKEINTERFACE: case EXPR_FINVOKE: case EXPR_FINVOKEVIRTUAL: case EXPR_NEWARRAY: @@ -437,6 +439,9 @@ struct expression *invokeinterface_expr(struct vm_method *target) enum vm_type return_type; return_type = method_return_type(target); + if (vm_type_is_float(return_type)) + return __invoke_expr(EXPR_FINVOKEINTERFACE, return_type, target); + return __invoke_expr(EXPR_INVOKEINTERFACE, return_type, target); } diff --git a/jit/tree-printer.c b/jit/tree-printer.c index 7783f55..cd8fdec 100644 --- a/jit/tree-printer.c +++ b/jit/tree-printer.c @@ -1088,6 +1088,7 @@ static print_expr_fn expr_printers[] = { [EXPR_FLOAT_INSTANCE_FIELD] = print_float_instance_field_expr, [EXPR_INVOKE] = print_invoke_expr, [EXPR_INVOKEINTERFACE] = print_invokeinterface_expr, + [EXPR_FINVOKEINTERFACE] = print_invokeinterface_expr, [EXPR_INVOKEVIRTUAL] = print_invokevirtual_expr, [EXPR_FINVOKE] = print_invoke_expr, [EXPR_FINVOKEVIRTUAL] = print_invokevirtual_expr, -- 1.6.0.6 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel