aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-02-16 20:14:33 +0200
committerPekka Enberg <penberg@kernel.org>2012-02-16 20:14:33 +0200
commiteb24d14163585aea24c21781390bb661a839b9a3 (patch)
tree3733cf12c39608c6672cb2e42530e38c5597e730
parent779fcdb69ffddd416a0b2504569829259a5a81d4 (diff)
downloadjato-eb24d14163585aea24c21781390bb661a839b9a3.tar.gz
x86-64: Fix multianewarray code generation
This patch fixes multianewarray code generation on x86-64. Now that we already use proper varargs for vm_object_alloc_multi_array() the only thing remaining is making sure arguments are passed in correct registers and that we don't mess up the stack pointer after the call to vm_object_alloc_multi_array(). Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--arch/mmix/include/arch/registers.h5
-rw-r--r--arch/x86/args.c2
-rw-r--r--arch/x86/include/arch/registers_64.h2
-rw-r--r--arch/x86/insn-selector_64.brg1
-rw-r--r--include/jit/args.h2
-rw-r--r--jit/args.c14
-rw-r--r--jit/object-bc.c2
7 files changed, 21 insertions, 7 deletions
diff --git a/arch/mmix/include/arch/registers.h b/arch/mmix/include/arch/registers.h
index a856b670..a2d0aa42 100644
--- a/arch/mmix/include/arch/registers.h
+++ b/arch/mmix/include/arch/registers.h
@@ -41,4 +41,9 @@ static inline enum vm_type reg_default_type(enum machine_reg reg)
return GPR_VM_TYPE;
}
+static inline enum machine_reg args_map_alloc_gpr(int gpr)
+{
+ return gpr;
+}
+
#endif /* __JIT_REGISTERS_H */
diff --git a/arch/x86/args.c b/arch/x86/args.c
index 143d2c5b..4480555d 100644
--- a/arch/x86/args.c
+++ b/arch/x86/args.c
@@ -35,7 +35,7 @@
#ifdef CONFIG_X86_64
-static enum machine_reg args_map_alloc_gpr(int gpr)
+enum machine_reg args_map_alloc_gpr(int gpr)
{
switch (gpr) {
case 0:
diff --git a/arch/x86/include/arch/registers_64.h b/arch/x86/include/arch/registers_64.h
index 117f5eca..09877f8d 100644
--- a/arch/x86/include/arch/registers_64.h
+++ b/arch/x86/include/arch/registers_64.h
@@ -117,4 +117,6 @@ static inline bool is_xmm_reg(enum machine_reg reg)
return reg >= NR_GP_REGISTERS && reg < NR_FP_REGISTERS;
}
+enum machine_reg args_map_alloc_gpr(int gpr);
+
#endif /* X86_REGISTERS_64_H */
diff --git a/arch/x86/insn-selector_64.brg b/arch/x86/insn-selector_64.brg
index 7f48e98a..c881d31c 100644
--- a/arch/x86/insn-selector_64.brg
+++ b/arch/x86/insn-selector_64.brg
@@ -987,7 +987,6 @@ reg: EXPR_MULTIANEWARRAY(arg)
select_safepoint_insn(s, tree, rel_insn(INSN_CALL_REL, (unsigned long) vm_object_alloc_multi_array));
select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, xax, state->reg1));
- method_args_cleanup(s, tree, dimension + 2);
select_exception_test(s, tree);
}
diff --git a/include/jit/args.h b/include/jit/args.h
index e22d1e02..fcaaab39 100644
--- a/include/jit/args.h
+++ b/include/jit/args.h
@@ -9,7 +9,7 @@
#include <assert.h>
struct expression *convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method *method);
-struct expression *convert_native_args(struct stack *mimic_stack, unsigned long nr_args);
+struct expression *convert_native_args(struct stack *mimic_stack, unsigned long start_arg, unsigned long nr_args);
#ifndef CONFIG_ARGS_MAP
static inline int args_map_init(struct vm_method *method)
diff --git a/jit/args.c b/jit/args.c
index ece2eb23..b7e46aec 100644
--- a/jit/args.c
+++ b/jit/args.c
@@ -140,13 +140,17 @@ convert_args(struct stack *mimic_stack, unsigned long nr_args, struct vm_method
}
static struct expression *
-insert_native_arg(struct expression *root, struct expression *expr)
+insert_native_arg(struct expression *root, struct expression *expr, unsigned long idx)
{
struct expression *_expr;
_expr = arg_expr(expr);
_expr->bytecode_offset = expr->bytecode_offset;
+#ifdef CONFIG_ARGS_MAP
+ _expr->arg_reg = args_map_alloc_gpr(idx);
+#endif
+
if (!root)
return _expr;
@@ -158,7 +162,7 @@ insert_native_arg(struct expression *root, struct expression *expr)
* with the native VM call. All arguments are passed on stack.
*/
struct expression *
-convert_native_args(struct stack *mimic_stack, unsigned long nr_args)
+convert_native_args(struct stack *mimic_stack, unsigned long start_arg, unsigned long nr_args)
{
struct expression *args_list = NULL;
unsigned long i;
@@ -170,7 +174,11 @@ convert_native_args(struct stack *mimic_stack, unsigned long nr_args)
for (i = 0; i < nr_args; i++) {
struct expression *expr = stack_pop(mimic_stack);
- args_list = insert_native_arg(args_list, expr);
+
+ assert(expr->vm_type != J_FLOAT);
+ assert(expr->vm_type != J_DOUBLE);
+
+ args_list = insert_native_arg(args_list, expr, nr_args + start_arg - i - 1);
}
out:
diff --git a/jit/object-bc.c b/jit/object-bc.c
index 16945f69..8a22c51e 100644
--- a/jit/object-bc.c
+++ b/jit/object-bc.c
@@ -465,7 +465,7 @@ int convert_multianewarray(struct parse_context *ctx)
if (!arrayref)
return warn("out of memory"), -ENOMEM;
- args_list = convert_native_args(ctx->bb->mimic_stack, dimension);
+ args_list = convert_native_args(ctx->bb->mimic_stack, 2, dimension);
arrayref->multianewarray_dimensions = &args_list->node;