diff options
author | Pekka Enberg <penberg@kernel.org> | 2012-02-16 20:14:33 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-02-16 20:14:33 +0200 |
commit | eb24d14163585aea24c21781390bb661a839b9a3 (patch) | |
tree | 3733cf12c39608c6672cb2e42530e38c5597e730 | |
parent | 779fcdb69ffddd416a0b2504569829259a5a81d4 (diff) | |
download | jato-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.h | 5 | ||||
-rw-r--r-- | arch/x86/args.c | 2 | ||||
-rw-r--r-- | arch/x86/include/arch/registers_64.h | 2 | ||||
-rw-r--r-- | arch/x86/insn-selector_64.brg | 1 | ||||
-rw-r--r-- | include/jit/args.h | 2 | ||||
-rw-r--r-- | jit/args.c | 14 | ||||
-rw-r--r-- | jit/object-bc.c | 2 |
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) @@ -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; |