Author: leo
Date: Tue Feb  7 12:20:14 2006
New Revision: 11467

Modified:
   trunk/include/parrot/jit.h
   trunk/src/jit.c
   trunk/src/jit/i386/core.jit
   trunk/src/jit/i386/jit_emit.h
Log:
PIC/JIT - x86: prepare for recursive subs

* create a recursive flag and remember it in jit_info
* if we are JITting recursive subs, an outer sub fetches arguments
  from the args array into registers and calls the inner recursive 
  function


Modified: trunk/include/parrot/jit.h
==============================================================================
--- trunk/include/parrot/jit.h  (original)
+++ trunk/include/parrot/jit.h  Tue Feb  7 12:20:14 2006
@@ -168,7 +168,10 @@ typedef enum {
     JIT_CODE_SUB_REGS_ONLY,
 
     /* size */
-    JIT_CODE_TYPES
+    JIT_CODE_TYPES,
+    /* special cases */  
+    JIT_CODE_RECURSIVE     = 0x10,
+    JIT_CODE_SUB_REGS_ONLY_REC = JIT_CODE_SUB_REGS_ONLY|JIT_CODE_RECURSIVE
 } enum_jit_code_type;
 
 /*  Parrot_jit_info_t
@@ -193,6 +196,7 @@ typedef struct {
     Parrot_jit_optimizer_t          *optimizer;
     Parrot_jit_constant_pool_t      *constant_pool;
     enum_jit_code_type              code_type; 
+    int                             flags;
     const struct jit_arch_info_t    *arch_info;
     int                              n_args;
 #  if EXEC_CAPABLE

Modified: trunk/src/jit.c
==============================================================================
--- trunk/src/jit.c     (original)
+++ trunk/src/jit.c     Tue Feb  7 12:20:14 2006
@@ -1385,6 +1385,14 @@ parrot_build_asm(Interp *interpreter, 
     const jit_arch_info *arch_info;
     int needs_fs;       /* fetch/store */
 
+    jit_info = interpreter->code->jit_info =
+            mem_sys_allocate(sizeof(Parrot_jit_info_t));
+
+    jit_info->flags     = jit_type & JIT_CODE_RECURSIVE;
+    jit_type &= ~ JIT_CODE_RECURSIVE;
+    jit_info->code_type = jit_type;
+    needs_fs = jit_type != JIT_CODE_SUB_REGS_ONLY;
+
 #if EXEC_CAPABLE
     if (objfile) {
         op_func = op_exec;
@@ -1392,21 +1400,20 @@ parrot_build_asm(Interp *interpreter, 
     }
     else
 #endif
+    {
         op_func = op_jit;
+        jit_info->objfile = NULL;
+    }
 
-    needs_fs = jit_type != JIT_CODE_SUB_REGS_ONLY;
+    /* reset some exctall bits - all is JITed
+     */
     if (jit_type == JIT_CODE_SUB_REGS_ONLY) {
         op_func[PARROT_OP_set_returns_pc].extcall = 0;
         op_func[PARROT_OP_get_params_pc].extcall = 0;
     }
-    jit_info = interpreter->code->jit_info =
-            mem_sys_allocate(sizeof(Parrot_jit_info_t));
-
-    jit_info->code_type = jit_type;
+    /* get register mappings and such */
     arch_info = jit_info->arch_info = Parrot_jit_init(interpreter);
 
-    jit_info->objfile = NULL;
-
     /*
      * check if IMCC did all he work. If yes, we got a PF segment with
      * register allocation information inside.
@@ -1474,6 +1481,7 @@ parrot_build_asm(Interp *interpreter, 
      * function. So we have to generate an appropriate function
      * prologue, that makes all this look like a normal function ;)
      */
+    jit_info->cur_op = cur_section->begin;
     (arch_info->regs[jit_type].jit_begin)(jit_info, interpreter);
     /*
      *   op_map holds the offset from arena.start

Modified: trunk/src/jit/i386/core.jit
==============================================================================
--- trunk/src/jit/i386/core.jit (original)
+++ trunk/src/jit/i386/core.jit Tue Feb  7 12:20:14 2006
@@ -1434,27 +1434,9 @@ Parrot_set_args_pc {
 extern Parrot_set_returns_pc {
     if (jit_info->code_type == JIT_CODE_FILE)
         Parrot_jit_normal_op(jit_info, interpreter);
-    else {
-        PMC *sig_pmc;
-        INTVAL *sig_bits, sig;
-
-        sig_pmc = CONTEXT(interpreter->ctx)->constants[CUR_OPCODE[1]]->u.key;
-        sig_bits = PMC_data(sig_pmc);
-        sig = sig_bits[0];
-        /* mov 16(%ebp), %eax - fetch args ptr */
-        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
-        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EAX, emit_None, 1, 0);
-        switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
-            case PARROT_ARG_INTVAL:
-                emitm_movl_r_m(NATIVECODE, MAP(2), emit_EAX, 0, 1, 0);
-                break;
-            case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
-                emitm_movl_i_m(NATIVECODE, *INT_CONST[2], emit_EAX, 0, 1, 0);
-                break;
-            default:
-                internal_exception(1, "set_returns_jit - unknown tyep");
-                break;
-        }
+    else  {
+        jit_set_returns_pc(jit_info, interpreter, 
+            jit_info->flags & JIT_CODE_RECURSIVE);
     }
 }
 
@@ -1462,21 +1444,15 @@ extern Parrot_returncc {
     if (jit_info->code_type == JIT_CODE_FILE)
         Parrot_jit_restart_op(jit_info, interpreter);
     else {
-        int i, used_i, save_i;
-        const jit_arch_regs *reg_info;
-
         /* restore pushed regs if any */
-        used_i = CONTEXT(interpreter->ctx)->n_regs_used[REGNO_INT];
-        reg_info = &jit_info->arch_info->regs[jit_info->code_type]; 
-        save_i = reg_info->n_preserved_I;
-        /* note - reversed order of Parrot_jit_begin_sub_regs */
-        for (i = used_i - 1; i >= save_i; --i)
-            emitm_popl_r(jit_info->native_ptr, reg_info->map_I[i]);
-        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
-        /* retval = pc is at 4 + n_args * 4 */
-        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EAX, emit_None, 1, 
-                4 + jit_info->n_args * 4);
-        jit_emit_stack_frame_leave(NATIVECODE);
+        if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
+            jit_restore_regs(jit_info, interpreter);
+            emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
+            /* retval = pc is at 4 + n_args * 4 */
+            emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EAX, emit_None, 1, 
+                    4 + jit_info->n_args * 4);
+            jit_emit_stack_frame_leave(NATIVECODE);
+        }
         emitm_ret(NATIVECODE);
     }
 }
@@ -1484,18 +1460,8 @@ extern Parrot_returncc {
 extern Parrot_get_params_pc {
     if (jit_info->code_type == JIT_CODE_FILE)
         Parrot_jit_normal_op(jit_info, interpreter);
-    else {
-        PMC *sig_pmc;
-        INTVAL *sig_bits, i, n;
-
-        sig_pmc = CONTEXT(interpreter->ctx)->constants[CUR_OPCODE[1]]->u.key;
-        sig_bits = PMC_data(sig_pmc);
-        n = PMC_int_val(sig_pmc);
-        jit_info->n_args = n;
-        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
-        for (i = 0; i < n; ++i)
-            emitm_movl_m_r(NATIVECODE, MAP(2+i), emit_EAX, emit_None, 
-                    1, 4 + i*4);
+    else if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
+        jit_get_params_pc(jit_info, interpreter);
     }
 }
 

Modified: trunk/src/jit/i386/jit_emit.h
==============================================================================
--- trunk/src/jit/i386/jit_emit.h       (original)
+++ trunk/src/jit/i386/jit_emit.h       Tue Feb  7 12:20:14 2006
@@ -2765,11 +2765,82 @@ Parrot_jit_vtable_newp_ic_op(Parrot_jit_
 
 #  endif /* JIT_CGP */
 
+#define NATIVECODE jit_info->native_ptr
+#define CUR_OPCODE jit_info->cur_op
+static void
+jit_get_params_pc(Parrot_jit_info_t *jit_info, Interp * interpreter)
+{
+    PMC *sig_pmc;
+    INTVAL *sig_bits, i, n;
+
+    sig_pmc = CONTEXT(interpreter->ctx)->constants[CUR_OPCODE[1]]->u.key;
+    sig_bits = PMC_data(sig_pmc);
+    n = PMC_int_val(sig_pmc);
+    jit_info->n_args = n;
+    emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
+    for (i = 0; i < n; ++i)
+        emitm_movl_m_r(NATIVECODE, MAP(2+i), emit_EAX, emit_None, 
+                1, 4 + i*4);
+}
+
+static void 
+jit_restore_regs(Parrot_jit_info_t *jit_info, Interp * interpreter)
+{
+
+    int i, used_i, save_i;
+    const jit_arch_regs *reg_info;
+
+    used_i = CONTEXT(interpreter->ctx)->n_regs_used[REGNO_INT];
+    reg_info = &jit_info->arch_info->regs[jit_info->code_type]; 
+    save_i = reg_info->n_preserved_I;
+    /* note - reversed order of Parrot_jit_begin_sub_regs */
+    for (i = used_i - 1; i >= save_i; --i)
+        emitm_popl_r(jit_info->native_ptr, reg_info->map_I[i]);
+}
+
+static void
+jit_set_returns_pc(Parrot_jit_info_t *jit_info, Interp * interpreter, 
+        int recursive)
+{
+    PMC *sig_pmc;
+    INTVAL *sig_bits, sig;
+
+    sig_pmc = CONTEXT(interpreter->ctx)->constants[CUR_OPCODE[1]]->u.key;
+    sig_bits = PMC_data(sig_pmc);
+    sig = sig_bits[0];
+    if (!recursive) {
+        /* mov 16(%ebp), %eax - fetch args ptr */
+        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EBP, emit_None, 1, 16);
+        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EAX, emit_None, 1, 0);
+    }
+    /*
+     * recursive returns according to ABI */
+    switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
+        case PARROT_ARG_INTVAL:
+            if (recursive) {
+                jit_emit_mov_rr_i(NATIVECODE, emit_EAX, MAP(2));
+            }
+            else {
+                emitm_movl_r_m(NATIVECODE, MAP(2), emit_EAX, 0, 1, 0);
+            }
+            break;
+        case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
+            if (recursive) {
+                jit_emit_mov_ri_i(NATIVECODE, emit_EAX, CUR_OPCODE[2]);
+            }
+            else {
+                emitm_movl_i_m(NATIVECODE, CUR_OPCODE[2], emit_EAX, 0, 1, 0);
+            }
+            break;
+        default:
+            internal_exception(1, "set_returns_jit - unknown tyep");
+            break;
+    }
+}
 #if JIT_EMIT == 0
 
 static void
-Parrot_jit_dofixup(Parrot_jit_info_t *jit_info,
-                   Interp * interpreter)
+Parrot_jit_dofixup(Parrot_jit_info_t *jit_info, Interp * interpreter)
 {
     Parrot_jit_fixup_t *fixup, *next;
     char *fixup_ptr;
@@ -2974,6 +3045,32 @@ Parrot_jit_begin_sub_regs(Parrot_jit_inf
     save_i = reg_info->n_preserved_I;
     for (i = save_i; i < used_i; ++i)
         emitm_pushl_r(jit_info->native_ptr, reg_info->map_I[i]);
+    /* when it's a recursive sub, we fetch params to registers
+     * and all a inner helper sub, which run with registers only
+     */
+    if (jit_info->flags & JIT_CODE_RECURSIVE) {
+        char * L1;
+        jit_get_params_pc(jit_info, interpreter);
+        /* remember fixup position - call sub */
+        L1 = NATIVECODE;
+        emitm_calll(NATIVECODE, 0);
+        /* fetch args to %edx */
+        emitm_movl_m_r(NATIVECODE, emit_EDX, emit_EBP, emit_None, 1, 16);
+        emitm_movl_m_r(NATIVECODE, emit_ECX, emit_EDX, emit_None, 1, 0);
+        /* store return value *INTVAL* %eax into result location */
+        /* XXX numbers */
+        emitm_movl_r_m(NATIVECODE, emit_EAX, emit_ECX, 0, 1, 0);
+        /* fetch pc and return it */
+        emitm_movl_m_r(NATIVECODE, emit_EAX, emit_EDX, emit_None, 1, 
+                    4 + jit_info->n_args * 4);
+        /* restore pushed callee saved */
+        jit_restore_regs(jit_info, interpreter);
+        jit_emit_stack_frame_leave(NATIVECODE);
+        emitm_ret(NATIVECODE);
+        /* fixup call statement */
+        L1[1] = NATIVECODE - L1 - 5;
+    }
+    /* TODO be sure we got a label here in map_branch */
 }
 
 

Reply via email to