]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add support for outgoing parameter areas, which should reduce
authorRhys Weatherley <rweather@southern-storm.com.au>
Thu, 10 Jun 2004 02:05:56 +0000 (02:05 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Thu, 10 Jun 2004 02:05:56 +0000 (02:05 +0000)
the overhead of function calls that involve stacked arguments
on non-x86 platforms; use parameter areas in the ARM back end.

ChangeLog
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

index 614f44260e14efc3c33835e30b1ac6ed6e273090..3fade0d756e0da822396b1b092be0141d79076c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,26 @@
 
+2004-06-10  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * 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  <rweather@southern-storm.com.au>
 
        * jit/jit-rules-arm.c (flush_constants): update the instruction
        * 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  <rweather@southern-storm.com.au>
 
        * jit/Makefile.am, jit/jit-cpuid-x86.c, jit/jit-cpuid-x86.h:
index efed07f6ebc7694c9114b8729d2236cc46575326..1ce9cc1c0e2b0a64d7aa1b4c412d7a6bfb520010 100644 (file)
@@ -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;
index ef1710ac5d09a869cb18e288684d458fc497b59c..5223b51729911c255e746cfa7f22aa88bd8a81c3 100644 (file)
@@ -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.
index 79fe5ab5b862349f5b85e5bb1fa4f1d9239b311b..e6ad1a7f9945a910385d0ccd3a4823ba3c55a6e4 100644 (file)
@@ -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);
index 878177ec270ffd3a0e48d8b79caaed1b50eea1f9..46235ec1aa927b0488cc4e9708da97a851e1e4bd 100644 (file)
@@ -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
index ffb21f7679f269d6d5d0e393694d077b75626250..db56d07ef714b01b112fe47aba45f2b5c6c3d5a6 100644 (file)
@@ -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;
+
 };
 
 /*
index 08ef9999352453ac960364dd46a75ea03cc97b74..39a0fc549e564567620d5af86ecc7006a230f52d 100644 (file)
@@ -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):
index c985ef0bacc12c136e93660a0b83cd0810e74598..f71ed9b0e592e71526f6ee10d865e052a6236ede 100644 (file)
@@ -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.
index da6f3f972f761ba0fe831f6d852325235b986deb..b937d58245b9c24f6741183e244655ae5e2c1399 100644 (file)
@@ -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);
index adf80c678cb68a1444f22577aab16d9f29df8beb..db3a6b547c9153d03e5a9c84624b3169faa86a66 100644 (file)
@@ -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.
  */
index 1bb8917222b6d2167881db268fe2abf032e3d963..38b9a8687943850225f1f69ca1e0811caa27db27 100644 (file)
@@ -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()))