Author: leo
Date: Thu Feb  9 13:13:24 2006
New Revision: 11493

Modified:
   trunk/src/jit/ppc/core.jit
   trunk/src/jit/ppc/jit_emit.h
Log:
PIC/JIT - ppc: implement recursive subs

* implement function calls and arg passing
* ppc calling conventions are, well, strange (I said that already)
* now ppc runs also:

./parrot -Oc -Cj examples/shootout/ack.pir


Modified: trunk/src/jit/ppc/core.jit
==============================================================================
--- trunk/src/jit/ppc/core.jit  (original)
+++ trunk/src/jit/ppc/core.jit  Thu Feb  9 13:13:24 2006
@@ -948,8 +948,14 @@ Parrot_set_p_pc {
 ; which adds unneeded overhead - convert to normal ops
 ; or just JIT (TODO)  the 2 easy ones
 Parrot_set_args_pc {
-    jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
-    jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
+    if (jit_info->code_type == JIT_CODE_FILE) {
+       jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
+       jit_emit_stw(NATIVECODE, ISR1, offsetof(Interp, current_args), r16);
+    }
+    else  {
+        jit_set_args_pc(jit_info, interpreter, 
+            jit_info->flags & JIT_CODE_RECURSIVE);
+    }
 }
 
 extern Parrot_set_returns_pc {
@@ -967,20 +973,46 @@ extern Parrot_returncc {
     else {
        /* fetch args[n+1] -> retval */
         if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
+           jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
            jit_emit_lwz(jit_info->native_ptr, r3, 4 + jit_info->n_args * 4, 
r5);
-       }
-
-       /* return sequence */
-       jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
-        if (!(jit_info->flags & JIT_CODE_RECURSIVE)) {
            jit_emit_lwz(jit_info->native_ptr, r31, -4, r1);
+           jit_emit_lwz(jit_info->native_ptr, r0, 8, r1);   /* get link reg */
+           jit_emit_mtlr(jit_info->native_ptr, r0);   /* move to link reg */
        }
-       jit_emit_lwz(jit_info->native_ptr, r0, 8, r1);   /* opt */
-       jit_emit_mtlr(jit_info->native_ptr, r0);   /* opt */
        jit_emit_blr(jit_info->native_ptr);
     }
 }
 
+Parrot_pic_callr___pc {
+    int offset, here, op_i;
+    struct PackFile_Constant ** constants;
+    PMC *sig_params, *sig_result;
+    opcode_t *params;
+    int skip;
+
+    constants = CONTEXT(interpreter->ctx)->constants;
+    params = jit_info->optimizer->sections->begin;
+    sig_params = constants[params[1]]->u.key;
+    op_i = 2 + SIG_ELEMS(sig_params);
+
+    offset = jit_info->arena.op_map[op_i].offset;
+    /* TODO preserve necessary regs */
+    assert(*CUR_OPCODE == PARROT_OP_get_results_pc);
+    constants = CONTEXT(interpreter->ctx)->constants;
+    sig_result = constants[CUR_OPCODE[1]]->u.key;
+    if (!SIG_ELEMS(sig_result))
+       skip = -1;
+    else 
+       skip = MAP(2);      /* skip result - save rest */
+    jit_save_regs_call(jit_info, interpreter, skip);
+
+    here = NATIVECODE - jit_info->arena.start;
+    offset -= here;
+    _emit_bx(NATIVECODE, 1, offset); /* bl */
+
+    jit_restore_regs_call(jit_info, interpreter, skip);
+}
+
 extern Parrot_get_params_pc {
     if (jit_info->code_type == JIT_CODE_FILE)
        Parrot_jit_normal_op(jit_info, interpreter);
@@ -990,8 +1022,21 @@ extern Parrot_get_params_pc {
 }
 
 Parrot_get_results_pc {
-    jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
-    jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx.state), r16);
-    jit_emit_stw(NATIVECODE, ISR1, 
-            offsetof(parrot_context_t, current_results), ISR2);
+    if (jit_info->code_type == JIT_CODE_FILE) {
+       jit_emit_mov_ri_i(NATIVECODE, ISR1, jit_info->cur_op);
+       jit_emit_lwz(NATIVECODE, ISR2, offsetof(Interp, ctx.state), r16);
+       jit_emit_stw(NATIVECODE, ISR1, 
+               offsetof(parrot_context_t, current_results), ISR2);
+    }
+    else {
+       struct PackFile_Constant ** constants;
+       PMC *sig_result;
+
+       constants = CONTEXT(interpreter->ctx)->constants;
+       sig_result = constants[CUR_OPCODE[1]]->u.key;
+       if (!SIG_ELEMS(sig_result))
+           return;
+       /* result is r3 TODO Nums */
+       jit_emit_mov_rr(NATIVECODE, MAP(2), r3);
+    }
 }

Modified: trunk/src/jit/ppc/jit_emit.h
==============================================================================
--- trunk/src/jit/ppc/jit_emit.h        (original)
+++ trunk/src/jit/ppc/jit_emit.h        Thu Feb  9 13:13:24 2006
@@ -12,6 +12,8 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <limits.h>
+#include "parrot/oplib/ops.h"
+
 #ifndef CACHELINESIZE
    /* TODO this should be determined by configure */
 #  if PARROT_EXEC_OS_AIX
@@ -814,7 +816,9 @@ jit_set_returns_pc(Parrot_jit_info_t *ji
     INTVAL *sig_bits, sig;
 
     sig_pmc = CONTEXT(interpreter->ctx)->constants[CUR_OPCODE[1]]->u.key;
-    sig_bits = PMC_data(sig_pmc);
+    if (!SIG_ELEMS(sig_pmc))
+        return;
+    sig_bits = SIG_ARRAY(sig_pmc);
     sig = sig_bits[0];
     if (!recursive) {
         /* ISR2 <- args[0] */ 
@@ -844,6 +848,101 @@ jit_set_returns_pc(Parrot_jit_info_t *ji
     }
 }
 
+static void
+jit_set_args_pc(Parrot_jit_info_t *jit_info, Interp * interpreter, 
+        int recursive)
+{
+    PMC *sig_args, *sig_params;
+    INTVAL *sig_bits, sig, i, n;
+    struct PackFile_Constant ** constants;
+    opcode_t *params;
+    char params_map;
+
+    if (!recursive) {
+        /* create args array */
+        internal_exception(1, "set_args_jit - can't do that yet ");
+    }
+
+    constants = CONTEXT(interpreter->ctx)->constants;
+    sig_args = constants[CUR_OPCODE[1]]->u.key;
+    if (!SIG_ELEMS(sig_args))
+        return;
+    params = jit_info->optimizer->sections->begin;
+    sig_params = constants[params[1]]->u.key;
+    ASSERT_SIG_PMC(sig_params);
+    sig_bits = SIG_ARRAY(sig_args);
+    n = SIG_ELEMS(sig_args);  
+    for (i = 0; i < n; ++i) {
+        sig = sig_bits[i];
+        /* move args to params regs */
+        params_map = jit_info->optimizer->map_branch[2 + i];
+        /* TODO check for overlaps/collision */
+        switch (sig & (PARROT_ARG_TYPE_MASK|PARROT_ARG_CONSTANT)) {
+            case PARROT_ARG_INTVAL:
+                jit_emit_mov_rr(NATIVECODE, params_map, MAP(2 + i));
+                break;
+            case PARROT_ARG_INTVAL|PARROT_ARG_CONSTANT:
+                jit_emit_mov_ri_i(NATIVECODE, params_map, CUR_OPCODE[2 + i]);
+                break;
+            default:
+                internal_exception(1, "set_args_jit - unknown typ");
+                break;
+        }
+    }
+}
+
+/*
+ * preserve registers around a functioncall
+ * 
+ * b) all used register around a call (skip >= 0 := return result
+ *    TODO save N regs for b) too
+ */
+static void 
+jit_save_regs_call(Parrot_jit_info_t *jit_info, Interp * interpreter, int skip)
+{
+    int i, used_i, save_i;
+    const jit_arch_regs *reg_info;
+
+    /* create stack frame 24 link + 32 params -> 64 */
+    jit_emit_stwu(jit_info->native_ptr, r1, -64, r1);
+    used_i = CONTEXT(interpreter->ctx)->n_regs_used[REGNO_INT];
+    reg_info = &jit_info->arch_info->regs[jit_info->code_type]; 
+    for (i = 0; i < used_i; ++i) {
+        if (reg_info->map_I[i] == skip)
+            continue;
+        /* we use param area sp+24 := r3, sp+52 := r10 */
+        jit_emit_stw(jit_info->native_ptr, reg_info->map_I[i], 24 + i*4, r1);
+    }
+    /* preserve link register */
+    jit_emit_mflr(jit_info->native_ptr, r0);    /* optional */
+    jit_emit_stw(jit_info->native_ptr, r0, 8, r1); /* stw     r0,8(r1) */
+}
+
+static void 
+jit_restore_regs_call(Parrot_jit_info_t *jit_info, Interp * interpreter, 
+        int skip)
+{
+
+    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]; 
+    /* note - reversed order of jit_save_regs  */
+    for (i = used_i - 1; i >= 0; --i) {
+        if (reg_info->map_I[i] == skip)
+            continue;
+        /* we use param area sp+24 := r3, sp+52 := r10 */
+        jit_emit_lwz(jit_info->native_ptr, reg_info->map_I[i], 24 + i*4, r1);
+    }
+    /* restore link reg */
+    jit_emit_lwz(jit_info->native_ptr, r0, 8, r1);   
+    jit_emit_mtlr(jit_info->native_ptr, r0);   
+    /* pop stack frame */
+    jit_emit_lwz(jit_info->native_ptr, r1, 0, r1);
+    /* TODO other types */
+}
+
 #if JIT_EMIT == 0
 
 /*
@@ -901,8 +1000,8 @@ Parrot_jit_begin_sub_regs(Parrot_jit_inf
     jit_emit_stw(jit_info->native_ptr, r0, 8, r1); /* stw     r0,8(r1) */
     /* preserve r31 */
     jit_emit_stw(jit_info->native_ptr, r31, -4, r1); 
-    /* 24 linkage area, 0 params , 1 word local, roundup => 32 */
-    jit_emit_stwu(jit_info->native_ptr, r1, -32, r1);
+    /* 24 linkage area, 32 params , 1 word local, roundup => 32 */
+    jit_emit_stwu(jit_info->native_ptr, r1, -64, r1);
     /* r31 = 0 - needed for load immediate */
     jit_emit_xor_rrr(jit_info->native_ptr, r31, r31, r31);
 
@@ -928,10 +1027,6 @@ Parrot_jit_begin_sub_regs(Parrot_jit_inf
         /* re-emit call */
         offs = NATIVECODE - L1;
         _emit_bx(L1, 1, offs); /* bl */
-        /* TODO this is a part of call */
-        jit_emit_mflr(jit_info->native_ptr, r0);
-        jit_emit_stw(jit_info->native_ptr, r0, 8, r1); /* stw     r0,8(r1) */
-        jit_emit_stwu(jit_info->native_ptr, r1, -32, r1);
     }
 }
 
@@ -1061,7 +1156,7 @@ static const char intval_map[INT_REGISTE
     };
 
 static const char intval_map_sub[] =
-    { r3, r4, r6, r7, r8, r9, r10 };
+    { r4, r6, r7, r8, r9, r10 };
 /*
  * f0, f13 are used as scratch registers
  * f1  - f12 are (additional) volatile registers
@@ -1138,8 +1233,8 @@ static const jit_arch_info arch_info = {
         },
         {
             Parrot_jit_begin_sub,   /* emit code prologue */
-            7,                  /* 7 mapped ints */
-            7,                  /* all volatile */
+            6,                  /* 6 mapped ints */
+            6,                  /* all volatile */
             intval_map_sub,
             12,                  /* mapped float regs */
             12,                  /* all volatile */
@@ -1147,10 +1242,10 @@ static const jit_arch_info arch_info = {
         },
         {
             Parrot_jit_begin_sub_regs,  /* emit code prologue */
-            7,                  /* 7 mapped ints */
-            7,                  /* all volatile */
+            6,                  /* 6 mapped ints */
+            6,                  /* all volatile */
             intval_map_sub,
-            12,                  /* 12 mapped float regs */
+            0,                  /* TODO 12 mapped float regs */
             12,                  /* all volatile */
             floatval_map_sub
         }

Reply via email to