From: Rhys Weatherley Date: Thu, 10 Jun 2004 02:05:56 +0000 (+0000) Subject: Add support for outgoing parameter areas, which should reduce X-Git-Tag: r.0.0.4~22 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=8fd3a119dc9cc93848c66348817b215b8e236724;p=francis%2Flibjit.git Add support for outgoing parameter areas, which should reduce the overhead of function calls that involve stacked arguments on non-x86 platforms; use parameter areas in the ARM back end. --- diff --git a/ChangeLog b/ChangeLog index 614f442..3fade0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,26 @@ +2004-06-10 Rhys Weatherley + + * jit/jit-apply-arm.c, jit/jit-gen-arm.c, jit/jit-gen-arm.h, + jit/jit-rules-arm.c, jit/jit-rules-arm.h, jit/jit-rules-arm.sel, + tools/gen-sel-parser.y: redesign the ARM code generation macros + so that they have stronger protection against buffer overruns. + + * jit/jit-rules-arm.sel: flush the constant pool after unconditional + branches, to try to minimize the probability that the pool will + be flushed in the middle of a loop body. + + * jit/jit-dump.c: dump the hex address of external functions, + to aid with debugging native disassembly dumps. + + * include/jit/jit-insn.h, include/jit/jit-opcode.h, + include/jit/jit-plus.h, jit/jit-insn.c, jit/jit-internal.h, + jit/jit-interp.c, jit/jit-opcode.c, jit/jit-rules-arm.c, + jit/jit-rules-arm.sel, jitplus/jit-plus-function.cpp: + add support for outgoing parameter areas, which should reduce + the overhead of function calls that involve stacked arguments + on non-x86 platforms; use parameter areas in the ARM back end. + 2004-06-09 Rhys Weatherley * jit/jit-rules-arm.c (flush_constants): update the instruction @@ -15,18 +37,6 @@ * jit/jit-rules-arm.c (_jit_gen_load_value): use ARM register pairs properly for "long" and "float64" values. - * jit/jit-apply-arm.c, jit/jit-gen-arm.c, jit/jit-gen-arm.h, - jit/jit-rules-arm.c, jit/jit-rules-arm.h, jit/jit-rules-arm.sel, - tools/gen-sel-parser.y: redesign the ARM code generation macros - so that they have stronger protection against buffer overruns. - - * jit/jit-rules-arm.sel: flush the constant pool after unconditional - branches, to try to minimize the probability that the pool will - be flushed in the middle of a loop body. - - * jit/jit-dump.c: dump the hex address of external functions, - to aid with debugging native disassembly dumps. - 2004-06-08 Rhys Weatherley * jit/Makefile.am, jit/jit-cpuid-x86.c, jit/jit-cpuid-x86.h: diff --git a/include/jit/jit-insn.h b/include/jit/jit-insn.h index efed07f..1ce9cc1 100644 --- a/include/jit/jit-insn.h +++ b/include/jit/jit-insn.h @@ -251,6 +251,11 @@ jit_value_t jit_insn_import int jit_insn_push(jit_function_t func, jit_value_t value) JIT_NOTHROW; int jit_insn_push_ptr (jit_function_t func, jit_value_t value, jit_type_t type) JIT_NOTHROW; +int jit_insn_set_param + (jit_function_t func, jit_value_t value, jit_nint offset) JIT_NOTHROW; +int jit_insn_set_param_ptr + (jit_function_t func, jit_value_t value, jit_type_t type, + jit_nint offset) JIT_NOTHROW; int jit_insn_pop_stack(jit_function_t func, jit_nint num_items) JIT_NOTHROW; int jit_insn_defer_pop_stack (jit_function_t func, jit_nint num_items) JIT_NOTHROW; diff --git a/include/jit/jit-opcode.h b/include/jit/jit-opcode.h index ef1710a..5223b51 100644 --- a/include/jit/jit-opcode.h +++ b/include/jit/jit-opcode.h @@ -447,66 +447,72 @@ extern "C" { #define JIT_OP_PUSH_STRUCT 0x016E #define JIT_OP_POP_STACK 0x016F #define JIT_OP_FLUSH_SMALL_STRUCT 0x0170 +#define JIT_OP_SET_PARAM_INT 0x0171 +#define JIT_OP_SET_PARAM_LONG 0x0172 +#define JIT_OP_SET_PARAM_FLOAT32 0x0173 +#define JIT_OP_SET_PARAM_FLOAT64 0x0174 +#define JIT_OP_SET_PARAM_NFLOAT 0x0175 +#define JIT_OP_SET_PARAM_STRUCT 0x0176 /* * Pointer-relative loads and stores. */ -#define JIT_OP_LOAD_RELATIVE_SBYTE 0x0171 -#define JIT_OP_LOAD_RELATIVE_UBYTE 0x0172 -#define JIT_OP_LOAD_RELATIVE_SHORT 0x0173 -#define JIT_OP_LOAD_RELATIVE_USHORT 0x0174 -#define JIT_OP_LOAD_RELATIVE_INT 0x0175 -#define JIT_OP_LOAD_RELATIVE_LONG 0x0176 -#define JIT_OP_LOAD_RELATIVE_FLOAT32 0x0177 -#define JIT_OP_LOAD_RELATIVE_FLOAT64 0x0178 -#define JIT_OP_LOAD_RELATIVE_NFLOAT 0x0179 -#define JIT_OP_LOAD_RELATIVE_STRUCT 0x017A -#define JIT_OP_STORE_RELATIVE_BYTE 0x017B -#define JIT_OP_STORE_RELATIVE_SHORT 0x017C -#define JIT_OP_STORE_RELATIVE_INT 0x017D -#define JIT_OP_STORE_RELATIVE_LONG 0x017E -#define JIT_OP_STORE_RELATIVE_FLOAT32 0x017F -#define JIT_OP_STORE_RELATIVE_FLOAT64 0x0180 -#define JIT_OP_STORE_RELATIVE_NFLOAT 0x0181 -#define JIT_OP_STORE_RELATIVE_STRUCT 0x0182 -#define JIT_OP_ADD_RELATIVE 0x0183 +#define JIT_OP_LOAD_RELATIVE_SBYTE 0x0177 +#define JIT_OP_LOAD_RELATIVE_UBYTE 0x0178 +#define JIT_OP_LOAD_RELATIVE_SHORT 0x0179 +#define JIT_OP_LOAD_RELATIVE_USHORT 0x017A +#define JIT_OP_LOAD_RELATIVE_INT 0x017B +#define JIT_OP_LOAD_RELATIVE_LONG 0x017C +#define JIT_OP_LOAD_RELATIVE_FLOAT32 0x017D +#define JIT_OP_LOAD_RELATIVE_FLOAT64 0x017E +#define JIT_OP_LOAD_RELATIVE_NFLOAT 0x017F +#define JIT_OP_LOAD_RELATIVE_STRUCT 0x0180 +#define JIT_OP_STORE_RELATIVE_BYTE 0x0181 +#define JIT_OP_STORE_RELATIVE_SHORT 0x0182 +#define JIT_OP_STORE_RELATIVE_INT 0x0183 +#define JIT_OP_STORE_RELATIVE_LONG 0x0184 +#define JIT_OP_STORE_RELATIVE_FLOAT32 0x0185 +#define JIT_OP_STORE_RELATIVE_FLOAT64 0x0186 +#define JIT_OP_STORE_RELATIVE_NFLOAT 0x0187 +#define JIT_OP_STORE_RELATIVE_STRUCT 0x0188 +#define JIT_OP_ADD_RELATIVE 0x0189 /* * Array element loads and stores. */ -#define JIT_OP_LOAD_ELEMENT_SBYTE 0x0184 -#define JIT_OP_LOAD_ELEMENT_UBYTE 0x0185 -#define JIT_OP_LOAD_ELEMENT_SHORT 0x0186 -#define JIT_OP_LOAD_ELEMENT_USHORT 0x0187 -#define JIT_OP_LOAD_ELEMENT_INT 0x0188 -#define JIT_OP_LOAD_ELEMENT_LONG 0x0189 -#define JIT_OP_LOAD_ELEMENT_FLOAT32 0x018A -#define JIT_OP_LOAD_ELEMENT_FLOAT64 0x018B -#define JIT_OP_LOAD_ELEMENT_NFLOAT 0x018C -#define JIT_OP_STORE_ELEMENT_BYTE 0x018D -#define JIT_OP_STORE_ELEMENT_SHORT 0x018E -#define JIT_OP_STORE_ELEMENT_INT 0x018F -#define JIT_OP_STORE_ELEMENT_LONG 0x0190 -#define JIT_OP_STORE_ELEMENT_FLOAT32 0x0191 -#define JIT_OP_STORE_ELEMENT_FLOAT64 0x0192 -#define JIT_OP_STORE_ELEMENT_NFLOAT 0x0193 +#define JIT_OP_LOAD_ELEMENT_SBYTE 0x018A +#define JIT_OP_LOAD_ELEMENT_UBYTE 0x018B +#define JIT_OP_LOAD_ELEMENT_SHORT 0x018C +#define JIT_OP_LOAD_ELEMENT_USHORT 0x018D +#define JIT_OP_LOAD_ELEMENT_INT 0x018E +#define JIT_OP_LOAD_ELEMENT_LONG 0x018F +#define JIT_OP_LOAD_ELEMENT_FLOAT32 0x0190 +#define JIT_OP_LOAD_ELEMENT_FLOAT64 0x0191 +#define JIT_OP_LOAD_ELEMENT_NFLOAT 0x0192 +#define JIT_OP_STORE_ELEMENT_BYTE 0x0193 +#define JIT_OP_STORE_ELEMENT_SHORT 0x0194 +#define JIT_OP_STORE_ELEMENT_INT 0x0195 +#define JIT_OP_STORE_ELEMENT_LONG 0x0196 +#define JIT_OP_STORE_ELEMENT_FLOAT32 0x0197 +#define JIT_OP_STORE_ELEMENT_FLOAT64 0x0198 +#define JIT_OP_STORE_ELEMENT_NFLOAT 0x0199 /* * Block operations. */ -#define JIT_OP_MEMCPY 0x0194 -#define JIT_OP_MEMMOVE 0x0195 -#define JIT_OP_MEMSET 0x0196 +#define JIT_OP_MEMCPY 0x019A +#define JIT_OP_MEMMOVE 0x019B +#define JIT_OP_MEMSET 0x019C /* * Allocate memory from the stack. */ -#define JIT_OP_ALLOCA 0x0197 +#define JIT_OP_ALLOCA 0x019D /* * The number of opcodes in the above list. */ -#define JIT_OP_NUM_OPCODES 0x0198 +#define JIT_OP_NUM_OPCODES 0x019E /* * Opcode information. diff --git a/include/jit/jit-plus.h b/include/jit/jit-plus.h index 79fe5ab..e6ad1a7 100644 --- a/include/jit/jit-plus.h +++ b/include/jit/jit-plus.h @@ -313,6 +313,9 @@ public: jit_value insn_import(jit_value value); void insn_push(const jit_value& value); void insn_push_ptr(const jit_value& value, jit_type_t type); + void insn_set_param(const jit_value& value, jit_nint offset); + void insn_set_param_ptr + (const jit_value& value, jit_type_t type, jit_nint offset); void insn_return(const jit_value& value); void insn_return(); void insn_return_ptr(const jit_value& value, jit_type_t type); diff --git a/jit/jit-insn.c b/jit/jit-insn.c index 878177e..46235ec 100644 --- a/jit/jit-insn.c +++ b/jit/jit-insn.c @@ -5955,6 +5955,133 @@ int jit_insn_push_ptr } } +/*@ + * @deftypefun int jit_insn_set_param (jit_function_t func, jit_value_t value, jit_nint offset) + * Set the parameter slot at @code{offset} in the outgoing parameter area + * to @code{value}. This may be used instead of @code{jit_insn_push} + * if it is more efficient to store directly to the stack than to push. + * The outgoing parameter area is allocated within the frame when + * the function is first entered. + * + * You normally wouldn't call this yourself - it is used internally + * by the CPU back ends to set up the stack for a subroutine call. + * @end deftypefun +@*/ +int jit_insn_set_param(jit_function_t func, jit_value_t value, jit_nint offset) +{ + jit_type_t type; + if(!value) + { + return 0; + } + type = jit_type_promote_int(jit_type_normalize(jit_value_get_type(value))); + switch(type->kind) + { + case JIT_TYPE_SBYTE: + case JIT_TYPE_UBYTE: + case JIT_TYPE_SHORT: + case JIT_TYPE_USHORT: + case JIT_TYPE_INT: + case JIT_TYPE_UINT: + { + return create_note(func, JIT_OP_SET_PARAM_INT, value, + jit_value_create_nint_constant + (func, jit_type_nint, offset)); + } + /* Not reached */ + + case JIT_TYPE_LONG: + case JIT_TYPE_ULONG: + { + return create_note(func, JIT_OP_SET_PARAM_LONG, value, + jit_value_create_nint_constant + (func, jit_type_nint, offset)); + } + /* Not reached */ + + case JIT_TYPE_FLOAT32: + { + return create_note(func, JIT_OP_SET_PARAM_FLOAT32, value, + jit_value_create_nint_constant + (func, jit_type_nint, offset)); + } + /* Not reached */ + + case JIT_TYPE_FLOAT64: + { + return create_note(func, JIT_OP_SET_PARAM_FLOAT64, value, + jit_value_create_nint_constant + (func, jit_type_nint, offset)); + } + /* Not reached */ + + case JIT_TYPE_NFLOAT: + { + return create_note(func, JIT_OP_SET_PARAM_NFLOAT, value, + jit_value_create_nint_constant + (func, jit_type_nint, offset)); + } + /* Not reached */ + + case JIT_TYPE_STRUCT: + case JIT_TYPE_UNION: + { + /* We need the address of the value for "push_struct" */ + value = jit_insn_address_of(func, value); + if(!value) + { + return 0; + } + return apply_ternary + (func, JIT_OP_SET_PARAM_STRUCT, + jit_value_create_nint_constant(func, jit_type_nint, offset), + value, + jit_value_create_nint_constant + (func, jit_type_nint, (jit_nint)jit_type_get_size(type))); + } + /* Not reached */ + } + return 1; +} + +/*@ + * @deftypefun int jit_insn_set_param_ptr (jit_function_t func, jit_value_t value, jit_type_t type, jit_nint offset) + * Same as @code{jit_insn_set_param_ptr}, except that the parameter is + * at @code{*value}. + * @end deftypefun +@*/ +int jit_insn_set_param_ptr + (jit_function_t func, jit_value_t value, jit_type_t type, jit_nint offset) +{ + if(!value || !type) + { + return 0; + } + switch(jit_type_normalize(type)->kind) + { + case JIT_TYPE_STRUCT: + case JIT_TYPE_UNION: + { + /* Set the structure into the parameter area by address */ + return apply_ternary + (func, JIT_OP_SET_PARAM_STRUCT, + jit_value_create_nint_constant(func, jit_type_nint, offset), + value, + jit_value_create_nint_constant + (func, jit_type_nint, (jit_nint)jit_type_get_size(type))); + } + /* Not reached */ + + default: + { + /* Load the value from the address and set it normally */ + return jit_insn_set_param + (func, jit_insn_load_relative(func, value, 0, type), offset); + } + /* Not reached */ + } +} + /*@ * @deftypefun int jit_insn_pop_stack (jit_function_t func, jit_nint num_items) * Pop @code{num_items} items from the function call stack. You normally diff --git a/jit/jit-internal.h b/jit/jit-internal.h index ffb21f7..db56d07 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -331,6 +331,9 @@ struct _jit_builder /* Number of stack items that are queued for a deferred pop */ jit_nint deferred_items; + /* Size of the outgoing parameter area in the frame */ + jit_nint param_area_size; + }; /* diff --git a/jit/jit-interp.c b/jit/jit-interp.c index 08ef999..39a0fc5 100644 --- a/jit/jit-interp.c +++ b/jit/jit-interp.c @@ -4485,6 +4485,12 @@ void _jit_run_function(jit_function_interp_t func, jit_item *args, VMCASE(JIT_OP_PUSH_FLOAT64): VMCASE(JIT_OP_PUSH_NFLOAT): VMCASE(JIT_OP_FLUSH_SMALL_STRUCT): + VMCASE(JIT_OP_SET_PARAM_INT): + VMCASE(JIT_OP_SET_PARAM_LONG): + VMCASE(JIT_OP_SET_PARAM_FLOAT32): + VMCASE(JIT_OP_SET_PARAM_FLOAT64): + VMCASE(JIT_OP_SET_PARAM_NFLOAT): + VMCASE(JIT_OP_SET_PARAM_STRUCT): VMCASE(JIT_OP_ENTER_FINALLY): VMCASE(JIT_OP_ENTER_FILTER): VMCASE(JIT_OP_CALL_FILTER_RETURN): diff --git a/jit/jit-opcode.c b/jit/jit-opcode.c index c985ef0..f71ed9b 100644 --- a/jit/jit-opcode.c +++ b/jit/jit-opcode.c @@ -463,6 +463,12 @@ jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES] = { {"push_struct", F_(EMPTY, ANY, PTR) | NINT_ARG}, {"pop_stack", F_(EMPTY, INT, EMPTY) | NINT_ARG}, {"flush_small_struct", F_(EMPTY, ANY, EMPTY)}, + {"set_param_int", F_(EMPTY, INT, PTR)}, + {"set_param_long", F_(EMPTY, LONG, PTR)}, + {"set_param_float32", F_(EMPTY, FLOAT32, PTR)}, + {"set_param_float64", F_(EMPTY, FLOAT64, PTR)}, + {"set_param_nfloat", F_(EMPTY, NFLOAT, PTR)}, + {"set_param_struct", F_(PTR, PTR, PTR)}, /* * Pointer-relative loads and stores. diff --git a/jit/jit-rules-arm.c b/jit/jit-rules-arm.c index da6f3f9..b937d58 100644 --- a/jit/jit-rules-arm.c +++ b/jit/jit-rules-arm.c @@ -559,6 +559,7 @@ int _jit_create_call_setup_insns unsigned int index; unsigned int num_stack_args; unsigned int word_regs; + unsigned int param_offset; /* Determine which values are going to end up in registers */ word_regs = 0; @@ -589,12 +590,29 @@ int _jit_create_call_setup_insns } num_stack_args = num_args - index; - /* Push all of the stacked arguments in reverse order */ + /* Determine the highest parameter offset */ + param_offset = 0; + for(index = 0; index < num_stack_args; ++index) + { + size = jit_type_get_size + (jit_value_get_type(args[num_args - 1 - index])); + param_offset += ROUND_STACK(size); + } + if(param_offset > (unsigned int)(func->builder->param_area_size)) + { + func->builder->param_area_size = (jit_nint)param_offset; + } + + /* Set all of the stacked arguments in reverse order. We set them + into the outgoing parameter area, which allows us to avoid constantly + updating the stack pointer when pushing stacked arguments */ while(num_stack_args > 0) { --num_stack_args; --num_args; - if(!jit_insn_push(func, args[num_args])) + size = jit_type_get_size(jit_value_get_type(args[num_args])); + param_offset -= ROUND_STACK(size); + if(!jit_insn_set_param(func, args[num_args], (jit_nint)param_offset)) { return 0; } @@ -662,48 +680,12 @@ int _jit_create_call_return_insns jit_value_t *args, unsigned int num_args, jit_value_t return_value, int is_nested) { - jit_nint pop_bytes; - unsigned int size; jit_type_t return_type; int ptr_return; - /* Calculate the number of bytes that we need to pop */ + /* Bail out now if we don't need to worry about return values */ return_type = jit_type_normalize(jit_type_get_return(signature)); ptr_return = jit_type_return_via_pointer(return_type); - pop_bytes = 0; - while(num_args > 0) - { - --num_args; - size = jit_type_get_size(jit_value_get_type(args[num_args])); - pop_bytes += ROUND_STACK(size); - } - if(ptr_return) - { - pop_bytes += sizeof(void *); - } - if(is_nested) - { - pop_bytes += sizeof(void *); - } - if(pop_bytes > (ARM_NUM_PARAM_REGS * sizeof(void *))) - { - pop_bytes -= (ARM_NUM_PARAM_REGS * sizeof(void *)); - } - else - { - pop_bytes = 0; - } - - /* Pop the bytes from the system stack */ - if(pop_bytes > 0) - { - if(!jit_insn_pop_stack(func, pop_bytes)) - { - return 0; - } - } - - /* Bail out now if we don't need to worry about return values */ if(!return_value || ptr_return) { return 0; @@ -783,6 +765,7 @@ void *_jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf) the space for the registers that we just saved. The pc, lr, and fp registers are always saved, so account for them too */ frame_size = func->builder->frame_size - (saved + 3 * sizeof(void *)); + frame_size += (unsigned int)(func->builder->param_area_size); if(frame_size > 0) { arm_alu_reg_imm(inst, ARM_SUB, ARM_SP, ARM_SP, frame_size); diff --git a/jit/jit-rules-arm.sel b/jit/jit-rules-arm.sel index adf80c6..db3a6b5 100644 --- a/jit/jit-rules-arm.sel +++ b/jit/jit-rules-arm.sel @@ -1148,6 +1148,114 @@ JIT_OP_FLUSH_SMALL_STRUCT: } } +JIT_OP_SET_PARAM_INT: unary_note + [reg] -> { + arm_store_membase(inst, $1, ARM_SP, insn->value2->address); + } + +JIT_OP_SET_PARAM_LONG: manual + [] -> { + arm_inst_buf inst; + _jit_regs_force_out(gen, insn->value1, 0); + _jit_gen_fix_value(insn->value1); + jit_gen_load_inst_ptr(gen, inst); + if(insn->value1->is_constant) + { + mov_reg_imm + (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + mov_reg_imm + (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address + 4); + } + else + { + arm_load_membase(inst, ARM_WORK, ARM_FP, + insn->value1->frame_offset); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + arm_load_membase(inst, ARM_WORK, ARM_FP, + insn->value1->frame_offset + 4); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address + 4); + } + jit_gen_save_inst_ptr(gen, inst); + } + +JIT_OP_SET_PARAM_FLOAT32 (JIT_ARM_HAS_FLOAT_REGS): unary_note + [freg] -> { + arm_store_membase_float32(inst, $1, ARM_SP, insn->value2->address); + } + +JIT_OP_SET_PARAM_FLOAT32 (!JIT_ARM_HAS_FLOAT_REGS): manual + [] -> { + arm_inst_buf inst; + _jit_regs_force_out(gen, insn->value1, 0); + _jit_gen_fix_value(insn->value1); + jit_gen_load_inst_ptr(gen, inst); + if(insn->value1->is_constant) + { + mov_reg_imm + (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + } + else + { + arm_load_membase(inst, ARM_WORK, ARM_FP, + insn->value1->frame_offset); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + } + jit_gen_save_inst_ptr(gen, inst); + } + +JIT_OP_SET_PARAM_FLOAT64, JIT_OP_SET_PARAM_NFLOAT + (JIT_ARM_HAS_FLOAT_REGS): unary_note + [freg] -> { + arm_store_membase_float64(inst, $1, ARM_SP, insn->value2->address); + } + +JIT_OP_SET_PARAM_FLOAT64, JIT_OP_SET_PARAM_NFLOAT + (!JIT_ARM_HAS_FLOAT_REGS): manual + [] -> { + arm_inst_buf inst; + _jit_regs_force_out(gen, insn->value1, 0); + _jit_gen_fix_value(insn->value1); + jit_gen_load_inst_ptr(gen, inst); + if(insn->value1->is_constant) + { + mov_reg_imm + (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[0]); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + mov_reg_imm + (gen, &inst, ARM_WORK, ((int *)(insn->value1->address))[1]); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address + 4); + } + else + { + arm_load_membase(inst, ARM_WORK, ARM_FP, + insn->value1->frame_offset); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address); + arm_load_membase(inst, ARM_WORK, ARM_FP, + insn->value1->frame_offset + 4); + arm_store_membase + (inst, ARM_WORK, ARM_SP, insn->value2->address + 4); + } + jit_gen_save_inst_ptr(gen, inst); + } + +JIT_OP_SET_PARAM_STRUCT: unary_note + [reg] -> { + /* TODO */ + TODO(); + } + /* * Pointer-relative loads and stores. */ diff --git a/jitplus/jit-plus-function.cpp b/jitplus/jit-plus-function.cpp index 1bb8917..38b9a86 100644 --- a/jitplus/jit-plus-function.cpp +++ b/jitplus/jit-plus-function.cpp @@ -645,6 +645,8 @@ jit_value jit_function::get_struct_pointer() * @deftypemethodx jit_function jit_value insn_import (jit_value value) * @deftypemethodx jit_function void insn_push ({const jit_value&} value) * @deftypemethodx jit_function void insn_push_ptr ({const jit_value&} value, jit_type_t type) + * @deftypemethodx jit_function void insn_set_param ({const jit_value&} value, jit_nint offset) + * @deftypemethodx jit_function void insn_set_param_ptr ({const jit_value&} value, jit_type_t type, jit_nint offset) * @deftypemethodx jit_function void insn_return ({const jit_value&} value) * @deftypemethodx jit_function void insn_return () * @deftypemethodx jit_function void insn_return_ptr ({const jit_value&} value, jit_type_t type) @@ -1213,6 +1215,23 @@ void jit_function::insn_push_ptr(const jit_value& value, jit_type_t type) } } +void jit_function::insn_set_param(const jit_value& value, jit_nint offset) +{ + if(!jit_insn_set_param(func, value.raw(), offset)) + { + out_of_memory(); + } +} + +void jit_function::insn_set_param_ptr + (const jit_value& value, jit_type_t type, jit_nint offset) +{ + if(!jit_insn_set_param_ptr(func, value.raw(), type, offset)) + { + out_of_memory(); + } +} + void jit_function::insn_return(const jit_value& value) { if(!jit_insn_return(func, value.raw()))