]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add support for the param area for x86_64 and enable it by default (It's
authorKlaus Treichel <ktreichel@web.de>
Sat, 24 May 2008 19:40:43 +0000 (19:40 +0000)
committerKlaus Treichel <ktreichel@web.de>
Sat, 24 May 2008 19:40:43 +0000 (19:40 +0000)
part of the X86_64 SysV abi).

ChangeLog
jit/jit-rules-x86-64.c
jit/jit-rules-x86-64.h
jit/jit-rules-x86-64.ins

index a4c22b833a7f4c866835f8af34f0518bcdc2fcc1..5a6b53685a316f81f92ebae388daacb92822ce21 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2008-05-24  Klaus Treichel  <ktreichel@web.de>
+
+       * jit/jit-rules-x86-64.c (_jit_gen_prolog, _jit_gen_epilog): Add
+       support for the param area.
+       (_jit_setup_call_stack): Define this function only if not using
+       the param area.
+       (_jit_create_call_setup_insns): Call _jit_fix_call_stack with
+       and without usage of the param area.
+       (_jit_create_call_return_insns): Declare the locals abi and
+       current_param only if built without support of the param area to
+       avoid compiler warnings.
+
+       * jit/jit-rules-x86-64.ins: Add the support of the
+       JIT_OP_SET_PARAM_* opcodes for param area support.
+
+       * jit/jit-rules-x86-64.h: Define JIT_USE_PARAM_AREA and do some
+       code cleanup and reformatting.
+
 2008-05-23  Juan Jesus Garcia de Soria  <juanj.g_soria@grupobbva.com>
 
        * jit/jit-alloc.c (jit_malloc_exec, jit_free_exec): on win32 use
index 8bb5e48bd0300cb46c28958be35439e8d3aba75c..a9e2a2676d2cccc7a7ce2aaf8b26cfae5b291e22 100644 (file)
@@ -2167,6 +2167,16 @@ _jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
        /* add the register save area to the initial frame size */
        frame_size += (regs_to_save << 3);
 
+#ifdef JIT_USE_PARAM_AREA
+       /* Add the param area to the frame_size if the additional offset
+          doesnt cause the offsets in the register saves become 4 bytes */
+       if(func->builder->param_area_size > 0 &&
+          (func->builder->param_area_size <= 0x50 || regs_to_save == 0))
+       {
+               frame_size += func->builder->param_area_size;
+       }
+#endif /* JIT_USE_PARAM_AREA */
+
        /* Make sure that the framesize is a multiple of 16 bytes */
        /* so that the final RSP will be alligned on a 16byte boundary. */
        frame_size = (frame_size + 0xf) & ~0xf;
@@ -2178,7 +2188,18 @@ _jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
 
        if(regs_to_save > 0)
        {
-               int current_offset = 0;
+               int current_offset;
+#ifdef JIT_USE_PARAM_AREA
+               if(func->builder->param_area_size > 0 &&
+                  func->builder->param_area_size <= 0x50)
+               {
+                       current_offset = func->builder->param_area_size;
+               }
+               else
+#endif /* JIT_USE_PARAM_AREA */
+               {
+                       current_offset = 0;
+               }
 
                /* Save registers that we need to preserve */
                for(reg = 0; reg <= 14; ++reg)
@@ -2192,6 +2213,12 @@ _jit_gen_prolog(jit_gencode_t gen, jit_function_t func, void *buf)
                        }
                }
        }
+#ifdef JIT_USE_PARAM_AREA
+       if(func->builder->param_area_size > 0x50 && regs_to_save > 0)
+       {
+               x86_64_sub_reg_imm_size(inst, X86_64_RSP, func->builder->param_area_size, 8);
+       }
+#endif /* JIT_USE_PARAM_AREA */
 
        /* Copy the prolog into place and return the adjusted entry position */
        reg = (int)(inst - prolog);
@@ -2233,6 +2260,26 @@ _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
        gen->epilog_fixup = 0;
 
        /* Restore the used callee saved registers */
+#ifdef JIT_USE_PARAM_AREA
+       if(func->builder->param_area_size > 0)
+       {
+               current_offset = func->builder->param_area_size;
+       }
+       else
+       {
+               current_offset = 0;
+       }
+       for(reg = 0; reg <= 14; ++reg)
+       {
+               if(jit_reg_is_used(gen->touched, reg) &&
+                  (_jit_reg_info[reg].flags & JIT_REG_CALL_USED) == 0)
+               {
+                       x86_64_mov_reg_membase_size(inst, _jit_reg_info[reg].cpu_reg,
+                                                   X86_64_RSP, current_offset, 8);
+                       current_offset += 8;
+               }
+       }
+#else /* !JIT_USE_PARAM_AREA */
        if(gen->stack_changed)
        {
                int frame_size = func->builder->frame_size;
@@ -2282,6 +2329,7 @@ _jit_gen_epilog(jit_gencode_t gen, jit_function_t func)
                        }
                }
        }
+#endif /* !JIT_USE_PARAM_AREA */
 
        /* Restore stackpointer and frame register */
        x86_64_mov_reg_reg_size(inst, X86_64_RSP, X86_64_RBP, 8);
@@ -2838,6 +2886,7 @@ _jit_fix_call_stack(jit_param_passing_t *passing)
        }
 }
 
+#ifndef JIT_USE_PARAM_AREA
 /*
  * Setup the call stack before pushing any parameters.
  * This is used usually for pushing pad words for alignment.
@@ -2867,6 +2916,7 @@ _jit_setup_call_stack(jit_function_t func, jit_param_passing_t *passing)
        }
        return 1;
 }
+#endif /* !JIT_USE_PARAM_AREA */
 
 /*
  * Push a parameter onto the stack.
@@ -3473,15 +3523,15 @@ int _jit_create_call_setup_insns
                passing.params[current_param].value = args[current_param];
        }
 
+       /* Let the backend do final adjustments to the passing area */
+       _jit_fix_call_stack(&passing);
+
 #ifdef JIT_USE_PARAM_AREA
        if(passing.stack_size > func->builder->param_area_size)
        {
                func->builder->param_area_size = passing.stack_size;
        }
 #else
-       /* Let the backend do final adjustments to the passing area */
-       _jit_fix_call_stack(&passing);
-
        /* Flush deferred stack pops from previous calls if too many
           parameters have collected up on the stack since last time */
        if(!jit_insn_flush_defer_pop(func, 32 - passing.stack_size))
@@ -3596,11 +3646,11 @@ _jit_create_call_return_insns(jit_function_t func, jit_type_t signature,
                                                          jit_value_t *args, unsigned int num_args,
                                                          jit_value_t return_value, int is_nested)
 {
-       int abi = jit_type_get_abi(signature);
        jit_type_t return_type;
        int ptr_return;
-       int current_param;
 #ifndef JIT_USE_PARAM_AREA
+       int abi = jit_type_get_abi(signature);
+       int current_param;
        jit_param_passing_t passing;
        _jit_param_t param[num_args];
        _jit_param_t nested_param;
index 6256c2caf1bfae13b6984a4de58884961d5569ac..569d42940a86e23ea1e7ea6da4f8b1847a0e4520 100644 (file)
@@ -100,7 +100,7 @@ extern      "C" {
 /*
  * Preferred alignment for the start of functions.
  */
-#define        JIT_FUNCTION_ALIGNMENT  32
+#define        JIT_FUNCTION_ALIGNMENT          32
 
 /*
  * Define this to 1 if the platform allows reads and writes on
@@ -112,12 +112,13 @@ extern    "C" {
 /*
  * Parameter passing rules.
  */
+#define        JIT_INITIAL_STACK_OFFSET        (2 * sizeof(void *))
+#define        JIT_INITIAL_FRAME_SIZE          0
+
 /*
-#define        JIT_CDECL_WORD_REG_PARAMS               {5, 4, 2, 1, 6, 7, -1}
-#define        JIT_MAX_WORD_REG_PARAMS                 6
-*/
-#define        JIT_INITIAL_STACK_OFFSET                (2 * sizeof(void *))
-#define        JIT_INITIAL_FRAME_SIZE                  0
+ * We are using the param area on x86_64
+ */
+#define JIT_USE_PARAM_AREA
 
 #ifdef __cplusplus
 };
index f9b6489f121cda9572d350ec9b0d89ddb42ad1f5..3587a6cb126f0d2767056e79b0ae5a64128c551c 100644 (file)
@@ -429,6 +429,84 @@ JIT_OP_POP_STACK:
                gen->stack_changed = 1;
        }
 
+/*
+ * Parameter passing via parameter area
+ */
+
+JIT_OP_SET_PARAM_INT: note
+       [imm, imm] -> {
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, $1, 4);
+       }
+       [reg, imm] -> {
+               x86_64_mov_membase_reg_size(inst, X86_64_RSP, $2, $1, 4);
+       }
+
+JIT_OP_SET_PARAM_LONG: note
+       [imm, imm, if("$1 >= jit_min_int && $1 <= jit_max_int")] -> {
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, $1, 8);
+       }
+       [imm, imm] -> {
+               jit_int *ptr = (jit_int *)&($1);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2 + 4, ptr[1], 4);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, ptr[0], 4);
+       }
+       [reg, imm] -> {
+               x86_64_mov_membase_reg_size(inst, X86_64_RSP, $2, $1, 8);
+       }
+
+JIT_OP_SET_PARAM_FLOAT32: note
+       [imm, imm] -> {
+               jit_int *ptr = (jit_int *)($1);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, ptr[0], 4);
+       }
+       [xreg, imm] -> {
+               x86_64_movss_membase_reg(inst, X86_64_RSP, $2, $1);
+       }
+
+JIT_OP_SET_PARAM_FLOAT64: note
+       [imm, imm] -> {
+               jit_int *ptr = (jit_int *)($1);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2 + 4, ptr[1], 4);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, ptr[0], 4);
+       }
+       [xreg, imm] -> {
+               x86_64_movsd_membase_reg(inst, X86_64_RSP, $2, $1);
+       }
+
+JIT_OP_SET_PARAM_NFLOAT: note
+       [imm, imm] -> {
+               jit_int *ptr = (jit_int *)($1);
+               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+               {
+                       x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2 + 8, ptr[2], 4);
+               }
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2 + 4, ptr[1], 4);
+               x86_64_mov_membase_imm_size(inst, X86_64_RSP, $2, ptr[0], 4);
+       }
+       [freg, imm] -> {
+               if(sizeof(jit_nfloat) != sizeof(jit_float64))
+               {
+                       x86_64_fstp_membase_size(inst, X86_64_RSP, $2, 10);
+               }
+               else
+               {
+                       x86_64_fstp_membase_size(inst, X86_64_RSP, $2, 8);
+               }
+       }
+
+JIT_OP_SET_PARAM_STRUCT: note
+       [reg, imm, clobber(creg), clobber(xreg)] -> {
+               /* Handle arbitrary-sized structures */
+               jit_nint offset = jit_value_get_nint_constant(insn->dest);
+               /* TODO: Maybe we should check for sizes > 2GB? */
+               inst = memory_copy(gen, inst, X86_64_RSP, offset, $1, 0, $2);
+       }
+
+
+/*
+ * Opcodes to handle return values
+ */
+
 JIT_OP_FLUSH_SMALL_STRUCT:
        [] -> {
                inst = flush_return_struct(inst, insn->value1);