Author: leo
Date: Tue Jan 10 14:46:39 2006
New Revision: 11066
Modified:
trunk/src/jit/ppc/jit_emit.h
Log:
Math - Divide by zero #8
* throw exception for JIT/ppc div instructions
Modified: trunk/src/jit/ppc/jit_emit.h
==============================================================================
--- trunk/src/jit/ppc/jit_emit.h (original)
+++ trunk/src/jit/ppc/jit_emit.h Tue Jan 10 14:46:39 2006
@@ -284,9 +284,13 @@ enum { JIT_PPC_CALL, JIT_PPC_BRANCH, JIT
# define jit_emit_mul_rrr(pc, D, A, B) \
jit_emit_3reg(pc, 31, D, A, B, 0, 235, 0);
-# define jit_emit_div_rrr(pc, D, A, B) \
+# define jit_emit_div_rrr_no_check(pc, D, A, B) \
jit_emit_3reg(pc, 31, D, A, B, 0, 491, 0);
+# define jit_emit_cmp_ri(pc, ra, simm) \
+ _emit_cmpi(pc, 11, 0, ra, simm);
+
+
# define jit_emit_and_rrr(pc, D, A, B) \
jit_emit_3reg_x(pc, 31, A, D, B, 28, 0)
@@ -408,7 +412,7 @@ enum { JIT_PPC_CALL, JIT_PPC_BRANCH, JIT
# define jit_emit_fadd_rrr(pc, D, A, B) jit_emit_3a(pc, 63, D, A, B, 0, 21, 0)
# define jit_emit_fsub_rrr(pc, D, A, B) jit_emit_3a(pc, 63, D, A, B, 0, 20, 0)
# define jit_emit_fmul_rrr(pc, D, A, B) jit_emit_3a(pc, 63, D, A, 0, B, 25, 0)
-# define jit_emit_fdiv_rrr(pc, D, A, B) jit_emit_3a(pc, 63, D, A, B, 0, 18, 0)
+# define jit_emit_fdiv_rrr_no_check(pc, D, A, B) jit_emit_3a(pc, 63, D, A, B,
0, 18, 0)
# define jit_emit_fsel(pc, D, A, B, C) jit_emit_3a(pc, 63, D, A, B, C, 23, 0)
# define jit_emit_fabs_rrr(pc, D, A) jit_emit_3reg_x(pc, 63, D, 0, A, 264, 0)
@@ -462,9 +466,6 @@ enum { JIT_PPC_CALL, JIT_PPC_BRANCH, JIT
*(pc++) = simm >> 8; \
*(pc++) = (char)simm
-# define jit_emit_cmp_ri(pc, ra, simm) \
- _emit_cmpi(pc, 11, 0, ra, simm);
-
/* Branch conditional to immediate
*
* +--------------------------------------------------------------------+
@@ -617,6 +618,70 @@ jit_emit_bx(Parrot_jit_info_t *jit_info,
pc, RTYPE_DATA1, "const_table", -2);
#endif /* EXEC_CAPABLE */
+static char *
+div_rrr(Parrot_jit_info_t *jit_info, char D, char A, char B)
+{
+ char *jmp_ptr, *sav_ptr;
+ static const char* div_by_zero = "Divide by zero";
+ char *pc = jit_info->native_ptr;
+
+ jit_emit_cmp_ri(pc, B, 0);
+ /* remember PC */
+ jmp_ptr = pc;
+ /* emit jump past exception code, dummy offset */
+ _emit_bc(pc, BNE, 0, 0, 0);
+ jit_emit_mov_rr(pc, r3, r16); /* interp */
+ jit_emit_mov_ri_i(pc, r4, 0); /* NULL */
+ jit_emit_mov_ri_i(pc, r5, E_ZeroDivisionError); /* type */
+ jit_emit_mov_ri_i(pc, r6, div_by_zero);
+ jit_info->native_ptr = pc;
+ jit_emit_call_func(pc, (void*) real_exception);
+ pc = jit_info->native_ptr;
+ /* fixup above jump */
+ sav_ptr = pc;
+ pc = jmp_ptr;
+ _emit_bc(pc, BNE, ((long)(sav_ptr - jmp_ptr)), 0, 0);
+ /* restore PC */
+ pc = sav_ptr;
+ jit_emit_div_rrr_no_check(pc, D, A, B);
+ return pc;
+}
+
+static char *
+fdiv_rrr(Parrot_jit_info_t *jit_info, char D, char A, char B)
+{
+ char *jmp_ptr, *sav_ptr;
+ static const char* div_by_zero = "Divide by zero";
+ char *pc = jit_info->native_ptr;
+ static const double zero = 0.0;
+
+ jit_emit_mov_ri_i(pc, ISR1, &zero);
+ jit_emit_lfd(pc, f1, 0, ISR1);
+
+ jit_emit_fcmp_rr(pc, B, f1); /* XXX be sure it's unmapped */
+ /* remember PC */
+ jmp_ptr = pc;
+ /* emit jump past exception code, dummy offset */
+ _emit_bc(pc, BNE, 0, 0, 0);
+ jit_emit_mov_rr(pc, r3, r16); /* interp */
+ jit_emit_mov_ri_i(pc, r4, 0); /* NULL */
+ jit_emit_mov_ri_i(pc, r5, E_ZeroDivisionError); /* type */
+ jit_emit_mov_ri_i(pc, r6, div_by_zero);
+ jit_info->native_ptr = pc;
+ jit_emit_call_func(pc, (void*) real_exception);
+ pc = jit_info->native_ptr;
+ /* fixup above jump */
+ sav_ptr = pc;
+ pc = jmp_ptr;
+ _emit_bc(pc, BNE, ((long)(sav_ptr - jmp_ptr)), 0, 0);
+ /* restore PC */
+ pc = sav_ptr;
+ jit_emit_fdiv_rrr_no_check(pc, D, A, B);
+ return pc;
+}
+# define jit_emit_div_rrr(pc, D, A, B) pc = div_rrr(jit_info, D, A, B)
+# define jit_emit_fdiv_rrr(pc, D, A, B) pc = fdiv_rrr(jit_info, D, A, B)
+
#endif /* JIT_EMIT */
void Parrot_ppc_jit_restore_nonvolatile_registers(void);