# New Ticket Created by Jason Gloudon
# Please include the string: [perl #19729]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=19729 >
This patch adds JIT support for restart and similar ops.
--
Jason
-- attachment 1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/46899/36851/696709/restart.patch
Index: jit/sun4/jit_emit.h
===================================================================
RCS file: /cvs/public/parrot/jit/sun4/jit_emit.h,v
retrieving revision 1.18
diff -u -r1.18 jit_emit.h
--- jit/sun4/jit_emit.h 1 Dec 2002 12:51:23 -0000 1.18
+++ jit/sun4/jit_emit.h 5 Jan 2003 04:01:03 -0000
@@ -287,7 +287,7 @@
#define Parrot_jit_intrp emitm_i(0)
/* The register holding the address of I0 */
-#define Parrot_jit_regbase emitm_i(1)
+#define Parrot_jit_regbase emitm_i(2)
/* The register containing the address of the opmap */
#define Parrot_jit_opmap emitm_i(3)
@@ -300,6 +300,32 @@
/* The offset of a Parrot register from the base register */
#define Parrot_jit_regoff(a, i) (unsigned)(a) - (unsigned)(Parrot_jit_regbase_ptr(i))
+/* Generate a jump to a bytecode address - uses the temporary register */
+static void
+Parrot_jit_bytejump(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp *interpreter, int reg_num)
+{
+
+ /* Construct the starting address of the byte code */
+ emitm_sethi(jit_info->native_ptr, emitm_hi22(interpreter->code->byte_code),
+ Parrot_jit_tmp);
+ emitm_or_i(jit_info->native_ptr, Parrot_jit_tmp,
+ emitm_lo10(interpreter->code->byte_code), Parrot_jit_tmp);
+
+ /* Calculates the offset into op_map shadow array
+ * assuming sizeof(opcode_t) == sizeof(opmap array entry) */
+ emitm_sub_r(jit_info->native_ptr, reg_num, Parrot_jit_tmp,
+ Parrot_jit_tmp);
+
+ /* Load the address of the native code from op_map */
+ emitm_ld_r(jit_info->native_ptr, Parrot_jit_opmap, Parrot_jit_tmp,
+ Parrot_jit_tmp);
+
+ /* This jumps to the address from op_map */
+ emitm_jumpl_i(jit_info->native_ptr, Parrot_jit_tmp, 0, Parrot_jit_tmp);
+ emitm_nop(jit_info->native_ptr);
+}
+
/* Generate conditional branch to offset from current parrot op */
static void Parrot_jit_bicc(Parrot_jit_info_t *jit_info, int cond, int annul,
opcode_t disp)
@@ -505,9 +531,14 @@
}
}
-void Parrot_jit_begin(Parrot_jit_info_t *jit_info,
+void
+Parrot_jit_begin(Parrot_jit_info_t *jit_info,
struct Parrot_Interp * interpreter)
{
+ /* generated code is called as jit_code(interpreter, pc)
+ * so interpreter is in i0 and pc in i1.
+ * i1 is reusable once past the jump. interpreter is preserved in i0
+ */
int ireg0_offset;
/* Standard Prolog */
@@ -531,8 +562,10 @@
emitm_sethi(jit_info->native_ptr,
emitm_hi22(jit_info->arena.op_map), Parrot_jit_opmap);
emitm_or_i(jit_info->native_ptr,
- emitm_i(3), emitm_lo10(jit_info->arena.op_map), Parrot_jit_opmap);
- /* TODO emit restart code s. i386 */
+ Parrot_jit_opmap, emitm_lo10(jit_info->arena.op_map), Parrot_jit_opmap);
+
+ /* Jump to the current pc */
+ Parrot_jit_bytejump(jit_info, interpreter, emitm_i(1));
}
void Parrot_jit_normal_op(Parrot_jit_info_t *jit_info,
@@ -555,21 +588,27 @@
struct Parrot_Interp * interpreter)
{
Parrot_jit_normal_op(jit_info, interpreter);
+ Parrot_jit_bytejump(jit_info, interpreter, emitm_o(0));
+}
- emitm_sethi(jit_info->native_ptr, emitm_hi22(interpreter->code->byte_code),
- emitm_l(1));
- emitm_or_i(jit_info->native_ptr, emitm_l(1),
- emitm_lo10(interpreter->code->byte_code), emitm_l(1));
-
- /* This calculates offset into op_map shadow array */
- emitm_sub_r(jit_info->native_ptr, emitm_o(0), emitm_l(1), emitm_o(0));
+#undef Parrot_jit_restart_op
+void Parrot_jit_restart_op(Parrot_jit_info_t *jit_info,
+ struct Parrot_Interp * interpreter)
+{
+ Parrot_jit_normal_op(jit_info, interpreter);
- /* Load the address of the native code from op_map */
- emitm_ld_r(jit_info->native_ptr, emitm_i(3), emitm_o(0), emitm_o(0));
+ /* Test whether the return value is 0 */
+ emitm_subcc_r(jit_info->native_ptr, emitm_o(0), emitm_g(0), emitm_g(0));
- /* This jumps to the address from op_map */
- emitm_jumpl_i(jit_info->native_ptr, emitm_o(0), 0, emitm_g(0));
+ /* If the return pc is not zero skip the next 3 instructions */
+ emitm_bicc(jit_info->native_ptr, 0, emitm_bne, 4);
emitm_nop(jit_info->native_ptr);
+
+ /* Return if the return pc is 0 */
+ emitm_ret(jit_info->native_ptr);
+ emitm_restore_i(jit_info->native_ptr, emitm_g(0), emitm_g(0), emitm_g(0));
+
+ Parrot_jit_bytejump(jit_info, interpreter, emitm_o(0));
}
/* move reg to mem (i.e. intreg) */