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 */
}