Signed-off-by: Tomek Grabiec <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel