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

Reply via email to