Author: markmason
Date: 2007-01-17 15:17:41 -0500 (Wed, 17 Jan 2007)
New Revision: 71227

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/cpu-mips.md
   trunk/mono/mono/mini/exceptions-mips.c
   trunk/mono/mono/mini/inssel-long.brg
   trunk/mono/mono/mini/inssel-long32-mips.brg
   trunk/mono/mono/mini/inssel-mips.brg
   trunk/mono/mono/mini/mini-mips.c
   trunk/mono/mono/mini/mini-mips.h
   trunk/mono/mono/mini/mini-ops.h
Log:
        * inssel-long.brg: patch to deal with mips missing flags
        * inssel-long32-mips.brg: implement overflow checks
        * insset-mips.brg: implement overflow checks
        * mini-mips.h: implement conditional exception handling
        * mini-mips.c: add mips_emit_exc_by_name(), implement 
conditional exception handling.
          Remove unused code, minor cleanups.
        * exceptions-mips.c: minor cleanups
        * mini-ops.h: add mips conditional exception ops
        * cpu-mips.md: add mips conditional exception ops

These changes contributed under the MIT/X11 license.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-01-17 20:03:33 UTC (rev 71226)
+++ trunk/mono/mono/mini/ChangeLog      2007-01-17 20:17:41 UTC (rev 71227)
@@ -1,4 +1,16 @@
+2007-01-17 Mark Mason <[EMAIL PROTECTED]>
 
+       * inssel-long.brg: patch to deal with mips missing flags
+       * inssel-long32-mips.brg: implement overflow checks
+       * insset-mips.brg: implement overflow checks
+       * mini-mips.h: implement conditional exception handling
+       * mini-mips.c: add mips_emit_exc_by_name(), implement conditional 
exception handling.
+         Remove unused code, minor cleanups.
+       * exceptions-mips.c: minor cleanups
+       * mini-ops.h: add mips conditional exception ops
+       * cpu-mips.md: add mips conditional exception ops
+
+       
 Wed Jan 17 19:22:34 CET 2007 Paolo Molaro <[EMAIL PROTECTED]>
 
        * inssel.brg: patch from Mark Mason <[EMAIL PROTECTED]>

Modified: trunk/mono/mono/mini/cpu-mips.md
===================================================================
--- trunk/mono/mono/mini/cpu-mips.md    2007-01-17 20:03:33 UTC (rev 71226)
+++ trunk/mono/mono/mini/cpu-mips.md    2007-01-17 20:17:41 UTC (rev 71227)
@@ -142,10 +142,10 @@
 add: dest:i src1:i src2:i len:4
 sub: dest:i src1:i src2:i len:4
 mul: dest:i src1:i src2:i len:20
-div: dest:i src1:i src2:i len:40
-div.un: dest:i src1:i src2:i len:40
-rem: dest:i src1:i src2:i len:48
-rem.un: dest:i src1:i src2:i len:28
+div: dest:i src1:i src2:i len:72
+div.un: dest:i src1:i src2:i len:72
+rem: dest:i src1:i src2:i len:72
+rem.un: dest:i src1:i src2:i len:72
 and: dest:i src1:i src2:i len:4
 or: dest:i src1:i src2:i len:4
 xor: dest:i src1:i src2:i len:4
@@ -563,3 +563,31 @@
 mips_sltiu: dest:i src1:i len:4
 mips_sltu: dest:i src1:i src2:i len:4
 mips_xori: dest:i src1:i len:4
+mips_cond_exc_eq: src1:i src2:i len:40
+mips_cond_exc_ge: src1:i src2:i len:40
+mips_cond_exc_gt: src1:i src2:i len:40
+mips_cond_exc_le: src1:i src2:i len:40
+mips_cond_exc_lt: src1:i src2:i len:40
+mips_cond_exc_ne_un: src1:i src2:i len:40
+mips_cond_exc_ge_un: src1:i src2:i len:40
+mips_cond_exc_gt_un: src1:i src2:i len:40
+mips_cond_exc_le_un: src1:i src2:i len:40
+mips_cond_exc_lt_un: src1:i src2:i len:40
+mips_cond_exc_ov: src1:i src2:i len:40
+mips_cond_exc_no: src1:i src2:i len:40
+mips_cond_exc_c: src1:i src2:i len:40
+mips_cond_exc_nc: src1:i src2:i len:40
+mips_cond_exc_ieq: src1:i src2:i len:40
+mips_cond_exc_ige: src1:i src2:i len:40
+mips_cond_exc_igt: src1:i src2:i len:40
+mips_cond_exc_ile: src1:i src2:i len:40
+mips_cond_exc_ilt: src1:i src2:i len:40
+mips_cond_exc_ine_un: src1:i src2:i len:40
+mips_cond_exc_ige_un: src1:i src2:i len:40
+mips_cond_exc_igt_un: src1:i src2:i len:40
+mips_cond_exc_ile_un: src1:i src2:i len:40
+mips_cond_exc_ilt_un: src1:i src2:i len:40
+mips_cond_exc_iov: src1:i src2:i len:40
+mips_cond_exc_ino: src1:i src2:i len:40
+mips_cond_exc_ic: src1:i src2:i len:40
+mips_cond_exc_inc: src1:i src2:i len:40

Modified: trunk/mono/mono/mini/exceptions-mips.c
===================================================================
--- trunk/mono/mono/mini/exceptions-mips.c      2007-01-17 20:03:33 UTC (rev 
71226)
+++ trunk/mono/mono/mini/exceptions-mips.c      2007-01-17 20:17:41 UTC (rev 
71227)
@@ -120,13 +120,12 @@
        static int inited = 0;
        guint8 *code;
        int alloc_size;
-       int offset = 16;
+       int offset;
 
        if (inited)
                return start;
 
        inited = 1;
-
        code = start;
 
        alloc_size = 64;
@@ -136,6 +135,7 @@
        mips_sw (code, mips_ra, mips_sp, alloc_size + MIPS_RET_ADDR_OFFSET);
 
        /* Save global registers on stack (s0 - s7) */
+       offset = 16;
        mips_sw (code, mips_s0, mips_sp, offset); offset += 4;
        mips_sw (code, mips_s1, mips_sp, offset); offset += 4;
        mips_sw (code, mips_s2, mips_sp, offset); offset += 4;
@@ -146,7 +146,7 @@
        mips_sw (code, mips_s7, mips_sp, offset); offset += 4;
        mips_sw (code, mips_fp, mips_sp, offset); offset += 4;
 
-       /* Restore global registers (s0-s7) */
+       /* Restore global registers from MonoContext, including the frame 
pointer */
        mips_lw (code, mips_s0, mips_a0, G_STRUCT_OFFSET (MonoContext, 
sc_regs[mips_s0]));
        mips_lw (code, mips_s1, mips_a0, G_STRUCT_OFFSET (MonoContext, 
sc_regs[mips_s1]));
        mips_lw (code, mips_s2, mips_a0, G_STRUCT_OFFSET (MonoContext, 
sc_regs[mips_s2]));

Modified: trunk/mono/mono/mini/inssel-long.brg
===================================================================
--- trunk/mono/mono/mini/inssel-long.brg        2007-01-17 20:03:33 UTC (rev 
71226)
+++ trunk/mono/mono/mini/inssel-long.brg        2007-01-17 20:17:41 UTC (rev 
71227)
@@ -228,103 +228,83 @@
 }
 
 reg: OP_LCONV_TO_OVF_I1 (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 127, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -128, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I1_UN (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 127, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U1 (reg) {
        /* probe value to be within 0 to 255 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xff);
 }
 
 reg: OP_LCONV_TO_OVF_U1_UN (reg) {
        /* probe value to be within 0 to 255 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xff);
 }
 
 reg: OP_LCONV_TO_OVF_I2 (reg) {
        /* Probe value to be within -32768 and 32767 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 32767, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -32768, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I2_UN (reg) {
        /* Probe value to be within 0 and 32767 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 32767, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U2 (reg) {
        /* Probe value to be within 0 and 65535 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xffff);
 }
 
 reg: OP_LCONV_TO_OVF_U2_UN (reg) {
        /* Probe value to be within 0 and 65535 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xffff);
 }
 
 reg: OP_LCONV_TO_OVF_I4 (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0x7fffffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -2147483648);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 0x7fffffff, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -2147483648, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I4_UN (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0x7fffffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0x7fffffff, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U4 (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffffUL);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 0xffffffffUL, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U4_UN (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffffffff, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I_UN (reg),
 reg: OP_LCONV_TO_OVF_I8_UN (reg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
-
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U8 (reg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
-
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
@@ -357,8 +337,7 @@
 }
 
 reg: CEE_CONV_OVF_U8 (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 

Modified: trunk/mono/mono/mini/inssel-long32-mips.brg
===================================================================
--- trunk/mono/mono/mini/inssel-long32-mips.brg 2007-01-17 20:03:33 UTC (rev 
71226)
+++ trunk/mono/mono/mini/inssel-long32-mips.brg 2007-01-17 20:17:41 UTC (rev 
71227)
@@ -272,37 +272,136 @@
 }
 
 lreg: OP_LADD (lreg, i8con) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, 
state->right->tree->inst_ls_word);
-       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_temp, state->reg1, 
state->left->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, 
state->left->reg1);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg2, state->left->reg2, 
state->right->tree->inst_ms_word);
-       MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, mips_temp, state->reg2);
+       MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
 }
 
-lreg: OP_LADD (lreg, lreg),
-lreg: OP_LADD_OVF (lreg, lreg),
+lreg: OP_LADD (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, 
state->left->reg1);
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, 
state->right->reg2);
+       MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
+}
+
+lreg: OP_LADD_OVF (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+       int tmp3 = mono_regstate_next_int (s->rs);
+       int tmp4 = mono_regstate_next_int (s->rs);
+       int tmp5 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, 
state->right->reg1);
+
+       /* tmp1 holds the carry from the low 32-bit to the high 32-bits */
+
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->reg1, 
state->left->reg1);
+
+       /* add the high 32-bits, and add in the carry from the low 32-bits */
+
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, 
state->right->reg2);
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp5, state->reg2);
+
+       /* Overflow happens if
+        *      neg + neg = pos    or
+        *      pos + pos = neg
+        * XOR of the high bits returns 0 if the signs match
+        * XOR of that with the high bit of the result return 1 if overflow.
+        */
+
+       /* tmp1 = 0 if the signs of the two inputs match, 1 otherwise */
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, 
state->right->reg2);
+
+       /* set tmp2 = 0 if bit31 of results matches is different than the 
operands */
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->reg2, state->right->reg2);
+       MONO_EMIT_NEW_UNALU (s, CEE_NOT, tmp2, tmp2);
+
+       /* OR(tmp1, tmp2) = 0 if both conditions are true */
+       MONO_EMIT_NEW_BIALU (s, CEE_OR, tmp3, tmp2, tmp1);
+
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
+
+       /* Now, if (tmp4 == 0) then overflow */
+       MONO_EMIT_NEW_COMPARE_EXC (s, EQ, tmp4, mips_zero, "OverflowException");
+}
+
 lreg: OP_LADD_OVF_UN (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+
        MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, 
state->right->reg1);
-       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, state->reg1, 
state->left->reg1);
-       /* MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException"); */
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, 
state->left->reg1);
        MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, 
state->right->reg2);
-       MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, mips_at, state->reg2);
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp1, state->reg2);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->reg2, 
state->left->reg2);
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, 
"OverflowException");
 }
 
 lreg: OP_LSUB (lreg, i8con) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+
        MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, 
state->right->tree->inst_ls_word);
-       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_temp, state->left->reg1, 
state->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, 
state->reg1);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, state->left->reg2, 
state->right->tree->inst_ms_word);
-       MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, mips_temp);
+       MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
 }
 
-lreg: OP_LSUB (lreg, lreg),
-lreg: OP_LSUB_OVF (lreg, lreg),
+lreg: OP_LSUB (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, 
state->reg1);
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, 
state->right->reg2);
+       MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
+}
+
+lreg: OP_LSUB_OVF (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+       int tmp3 = mono_regstate_next_int (s->rs);
+       int tmp4 = mono_regstate_next_int (s->rs);
+       int tmp5 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->left->reg1, 
state->reg1);
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, 
state->right->reg2);
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp5);
+
+       /* Overflow happens if
+        *      neg - pos = pos    or
+        *      pos - neg = neg
+        * XOR of bit31 of the lhs & rhs = 1 if the signs are different
+        *
+        * tmp1 = (lhs ^ rhs)
+        * tmp2 = (lhs ^ result)
+        * if ((tmp1 < 0) & (tmp2 < 0)) then overflow
+        */
+
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, 
state->right->reg2);
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->left->reg2, state->reg2);
+       MONO_EMIT_NEW_BIALU (s, CEE_AND, tmp3, tmp2, tmp1);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
+
+       /* Now, if (tmp4 == 1) then overflow */
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp4, mips_zero, 
"OverflowException");
+}
+
 lreg: OP_LSUB_OVF_UN (lreg, lreg) {
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+
        MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, 
state->right->reg1);
-       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, state->left->reg1, 
state->reg1);
-       /* MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException"); */
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, 
state->reg1);
        MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, 
state->right->reg2);
-       MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, mips_at);
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp1);
+
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->left->reg2, 
state->reg2);
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, 
"OverflowException");
 }
 
 lreg: OP_LAND (lreg, lreg) {   
@@ -868,8 +967,7 @@
 }
 
 lreg: CEE_CONV_OVF_U8 (reg) {
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
@@ -947,13 +1045,10 @@
 }
 
 reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
 
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 127, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -128, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
 }
 
@@ -963,22 +1058,18 @@
        MONO_NEW_LABEL (s, is_negative);
        MONO_NEW_LABEL (s, end_label);
 
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, 
"OverflowException");
 
        MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, 
mips_zero, is_negative);
 
        /* Positive */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 127, 
"OverflowException");
        MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
 
        /* Negative */
        mono_bblock_add_inst (s->cbb, is_negative);
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
-       MONO_EMIT_NEW_COND_EXC (s, LT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -128, 
"OverflowException");
        mono_bblock_add_inst (s->cbb, end_label);
 
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
@@ -986,12 +1077,10 @@
 
 reg: OP_LCONV_TO_OVF_U1_UN (lreg),
 reg: OP_LCONV_TO_OVF_U1 (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
 
        /* probe value to be within 0 to 255 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xff);
 }
 
@@ -1001,103 +1090,83 @@
        MONO_NEW_LABEL (s, is_negative);
        MONO_NEW_LABEL (s, end_label);
 
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, 
"OverflowException");
 
        MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, 
mips_zero, is_negative);
 
        /* Positive */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 32767, 
"OverflowException");
        MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
 
        /* Negative */
        mono_bblock_add_inst (s->cbb, is_negative);
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
-       MONO_EMIT_NEW_COND_EXC (s, LT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -32768, 
"OverflowException");
        mono_bblock_add_inst (s->cbb, end_label);
 
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
 
        /* Probe value to be within -32768 and 32767 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
-       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 32767, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -32768, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U2_UN (lreg),
 reg: OP_LCONV_TO_OVF_U2 (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
 
        /* Probe value to be within 0 and 65535 */
-       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
-       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, 
"OverflowException");
        MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, 
state->left->reg1, 0xffff);
 }
 
 
 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: OP_LCONV_TO_OVF_U4 (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
-reg: OP_LCONV_TO_OVF_I (lreg) {
-       tree->dreg = state->reg1;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = state->left->reg2;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
 reg: OP_LCONV_TO_OVF_I4_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, 
"OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, 
"OverflowException");
        MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
 }
 
+reg: OP_LCONV_TO_OVF_I (lreg),
 reg: OP_LCONV_TO_OVF_I4 (lreg) {
-       tree->dreg = state->reg1;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = state->left->reg2;
-       tree->opcode = OP_LCONV_TO_OVF_I;
-       mono_bblock_add_inst (s->cbb, tree);
+       int tmp_reg = mono_regstate_next_int (s->rs);
+
+       /* Overflows if reg2 != sign extension of reg1 */
+       MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, tmp_reg, state->left->reg1, 
31);
+
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, state->left->reg2, tmp_reg, 
"OverflowException");
+       MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, 
"OverflowException");
 
        MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
 }
 
 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
-       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, 
"OverflowException");
 
        MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);

Modified: trunk/mono/mono/mini/inssel-mips.brg
===================================================================
--- trunk/mono/mono/mini/inssel-mips.brg        2007-01-17 20:03:33 UTC (rev 
71226)
+++ trunk/mono/mono/mini/inssel-mips.brg        2007-01-17 20:17:41 UTC (rev 
71227)
@@ -618,6 +618,7 @@
        int soffset = vt->inst_offset;
        int doffset = ai->offset;
 
+       //g_printf ("OP_OUTARG_VT: LDOBJ\n");
        for (i = 0; i < nregs; ++i) {
                dreg = mono_regstate_next_int (s->rs);
                MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, vt->inst_basereg, soffset);
@@ -625,7 +626,7 @@
                soffset += sizeof (gpointer);
                doffset += sizeof (gpointer);
        }
-       //g_print ("vt size: %d at R%d + %d\n", ai->offset, vt->inst_basereg, 
vt->inst_offset);
+       //g_printf ("vt size: %d at R%d + %d\n", ai->offset, vt->inst_basereg, 
vt->inst_offset);
        if (ovf_size != 0) {
                mini_emit_memcpy (s, vt->inst_basereg, doffset, 
vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0);
        }
@@ -636,6 +637,8 @@
        MonoMIPSArgInfo *ai = tree->backend.data;
        int start_reg = ai->reg;
        int nregs = ai->size;
+
+       //g_printf ("OP_OUTARG_VT: ICONST\n");
        if (nregs) {
                tree->opcode = OP_SETREGIMM;
                tree->dreg = mono_regstate_next_int (s->rs);
@@ -652,6 +655,8 @@
        MonoMIPSArgInfo *ai = tree->backend.data;
        int start_reg = ai->reg;
        int nregs = ai->size;
+
+       //g_printf ("OP_OUTARG_VT: reg\n");
        if (nregs) {
                tree->opcode = OP_SETREG;
                tree->dreg = mono_regstate_next_int (s->rs);
@@ -783,19 +788,84 @@
 }
 
 reg: CEE_ADD_OVF (reg, reg) "0" {
-       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, 
state->right->reg1);
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+       int tmp3 = mono_regstate_next_int (s->rs);
+       int tmp4 = mono_regstate_next_int (s->rs);
+       int tmp5 = mono_regstate_next_int (s->rs);
+
+       /* add the operands */
+
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, 
state->right->reg1);
+
+       /* Overflow happens if
+        *      neg + neg = pos    or
+        *      pos + pos = neg
+        *
+        * (bit31s of operands match) AND (bit31 of operand != bit31 of result)
+        * XOR of the high bit returns 0 if the signs match
+        * XOR of that with the high bit of the result return 1 if overflow.
+        */
+
+       /* tmp1 = 0 if the signs of the two inputs match, 1 otherwise */
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg1, 
state->right->reg1);
+
+       /* set tmp2 = 0 if bit31 of results matches is different than the 
operands */
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->reg1, state->right->reg1);
+       MONO_EMIT_NEW_UNALU (s, CEE_NOT, tmp3, tmp2);
+
+       /* OR(tmp1, tmp2) = 0 if both conditions are true */
+       MONO_EMIT_NEW_BIALU (s, CEE_OR, tmp4, tmp3, tmp1);
+
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp5, tmp4, 31);
+
+       /* Now, if (tmp4 == 0) then overflow */
+       MONO_EMIT_NEW_COMPARE_EXC (s, EQ, tmp5, mips_zero, "OverflowException");
 }
 
 reg: CEE_ADD_OVF_UN (reg, reg) "0" {
-       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, 
state->right->reg1);
+       int tmp1 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, 
state->left->reg1);
+/*     MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp1, mips_zero, 
"OverflowException"); */
 }
 
 reg: CEE_SUB_OVF (reg, reg) "0" {
-       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, 
state->right->reg1);
+       int tmp1 = mono_regstate_next_int (s->rs);
+       int tmp2 = mono_regstate_next_int (s->rs);
+       int tmp3 = mono_regstate_next_int (s->rs);
+       int tmp4 = mono_regstate_next_int (s->rs);
+       int tmp5 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, 
state->right->reg1);
+
+       /* Overflow happens if
+        *      neg - pos = pos    or
+        *      pos - neg = neg
+        * XOR of bit31 of the lhs & rhs = 1 if the signs are different
+        *
+        * tmp1 = (lhs ^ rhs)
+        * tmp2 = (lhs ^ result)
+        * if ((tmp1 < 0) & (tmp2 < 0)) then overflow
+        */
+
+       /* tmp3 = 1 if the signs of the two inputs differ */
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->left->reg1, state->reg1);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_MIPS_SLTI, tmp3, tmp1, 0);
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_MIPS_SLTI, tmp4, tmp2, 0);
+       MONO_EMIT_NEW_BIALU (s, CEE_AND, tmp5, tmp4, tmp3);
+
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp5, mips_zero, 
"OverflowException");
 }
 
 reg: CEE_SUB_OVF_UN (reg, reg) "0" {
-       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, 
state->right->reg1);
+       int tmp1 = mono_regstate_next_int (s->rs);
+
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, 
state->right->reg1);
+       MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, 
state->reg1);
+       MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp1, mips_zero, 
"OverflowException");
 }
 
 

Modified: trunk/mono/mono/mini/mini-mips.c
===================================================================
--- trunk/mono/mono/mini/mini-mips.c    2007-01-17 20:03:33 UTC (rev 71226)
+++ trunk/mono/mono/mini/mini-mips.c    2007-01-17 20:17:41 UTC (rev 71227)
@@ -57,42 +57,13 @@
  * to cfg->bb_exit as far as the big branch handling is concerned
  */
 
-#define EMIT_SYSTEM_EXCEPTION_NAME_LEN 5
 #define EMIT_SYSTEM_EXCEPTION_NAME(exc_name)            \
         do {                                                        \
-               mono_add_patch_info (cfg, code - cfg->native_code,   \
-                                    MONO_PATCH_INFO_EXC, exc_name);    \
-               mips_lui (code, mips_t9, mips_zero, 0);                 \
-               mips_addiu (code, mips_t9, mips_t9, 0);                 \
-               mips_jalr (code, mips_t9, mips_ra);                     \
-               mips_nop (code);                                        \
+               code = mips_emit_exc_by_name (code, exc_name);  \
                cfg->bb_exit->max_offset += 16;                         \
        } while (0) 
 
 
-/* XXX - need to actually test the condition - not just bne */
-#define EMIT_COND_SYSTEM_EXCEPTION_FLAGS(b0,b1,exc_name)            \
-        do {                                                        \
-               mips_bne (code, mips_at, mips_zero, 5);                 \
-               mips_nop (code);                                        \
-               EMIT_SYSTEM_EXCEPTION_NAME(exc_name);                   \
-               cfg->bb_exit->max_offset += 8;                          \
-       } while (0) 
-
-#define EMIT_COND_SYSTEM_EXCEPTION(cond,exc_name) \
-        do { \
-               switch (cond) { \
-               case CEE_BEQ: \
-                       mips_bne (code, mips_at, mips_zero, 5);  \
-                       break; \
-               default: \
-                       g_assert_not_reached();  \
-               } \
-               mips_nop (code); \
-               EMIT_SYSTEM_EXCEPTION_NAME(exc_name); \
-               cfg->bb_exit->max_offset += 8; \
-       } while (0) 
-
 #define emit_linuxthreads_tls(code,dreg,key) do {\
                int off1, off2; \
                off1 = offsets_from_pthread_key ((key), &off2); \
@@ -169,6 +140,20 @@
 }
 #endif
 
+static guint8 *
+mips_emit_exc_by_name(guint8 *code, char *name)
+{
+       guint32 addr;
+
+       mips_load_const (code, mips_a0, name);
+       addr = (guint32) mono_arch_get_throw_exception_by_name ();
+       mips_load_const (code, mips_t9, addr);
+       mips_jalr (code, mips_t9, mips_ra);
+       mips_nop (code);
+
+       return code;
+}
+
 /* XXX - big-endian dependent? */
 void
 patch_lui_addiu(guint32 *ip, guint32 val)
@@ -1503,8 +1488,8 @@
                                ins->opcode = map_to_reg_reg_op (ins->opcode);
                        }
                        break;
-               case OP_SUB_IMM:
 #if 0
+               case OP_SUB_IMM:
                        if (!mips_is_imm16 (-ins->inst_imm)) {
                                NEW_INS (cfg, temp, OP_ICONST);
                                temp->inst_c0 = ins->inst_imm;
@@ -1512,12 +1497,12 @@
                                ins->sreg2 = temp->dreg;
                                ins->opcode = map_to_reg_reg_op (ins->opcode);
                        }
-#endif
                        break;
+#endif
+#if 0
                case OP_AND_IMM:
                case OP_OR_IMM:
                case OP_XOR_IMM:
-#if 0
                        if ((ins->inst_imm & 0xffff0000) && (ins->inst_imm & 
0xffff)) {
                                NEW_INS (cfg, temp, OP_ICONST);
                                temp->inst_c0 = ins->inst_imm;
@@ -1525,12 +1510,12 @@
                                ins->sreg2 = temp->dreg;
                                ins->opcode = map_to_reg_reg_op (ins->opcode);
                        }
-#endif
                        break;
+#endif
+#if 0
                case OP_SBB_IMM:
                case OP_SUBCC_IMM:
                case OP_ADC_IMM:
-#if 0
                        NEW_INS (cfg, temp, OP_ICONST);
                        temp->inst_c0 = ins->inst_imm;
                        temp->dreg = mono_regstate_next_int (cfg->rs);
@@ -1538,8 +1523,8 @@
                        ins->opcode = map_to_reg_reg_op (ins->opcode);
                        break;
 #endif
-               case OP_COMPARE_IMM:
 #if 0
+               case OP_COMPARE_IMM:
                        if (compare_opcode_is_unsigned (ins->next->opcode)) {
                                if (!ppc_is_uimm16 (ins->inst_imm)) {
                                        NEW_INS (cfg, temp, OP_ICONST);
@@ -1557,10 +1542,10 @@
                                        ins->opcode = map_to_reg_reg_op 
(ins->opcode);
                                }
                        }
-#endif
                        break;
-               case OP_MUL_IMM:
+#endif
 #if 0
+               case OP_MUL_IMM:
                        if (ins->inst_imm == 1) {
                                ins->opcode = OP_MOVE;
                                break;
@@ -1583,8 +1568,9 @@
                                ins->sreg2 = temp->dreg;
                                ins->opcode = map_to_reg_reg_op (ins->opcode);
                        }
-#endif
                        break;
+#endif
+#if 0
                case OP_LOAD_MEMBASE:
                case OP_LOADI4_MEMBASE:
                case OP_LOADU4_MEMBASE:
@@ -1600,7 +1586,6 @@
                case OP_STOREI1_MEMBASE_REG:
                case OP_STORER4_MEMBASE_REG:
                case OP_STORER8_MEMBASE_REG:
-#if 0
                        /* we can do two things: load the immed in a register
                         * and use an indexed load, or see if the immed can be
                         * represented as an ad_imm + a load with a smaller 
offset
@@ -1613,13 +1598,13 @@
                        temp->dreg = mono_regstate_next_int (cfg->rs);
                        ins->sreg2 = temp->dreg;
                        ins->opcode = map_to_reg_reg_op (ins->opcode);
-#endif
                        break;
+#endif
+#if 0
                case OP_STORE_MEMBASE_IMM:
                case OP_STOREI1_MEMBASE_IMM:
                case OP_STOREI2_MEMBASE_IMM:
                case OP_STOREI4_MEMBASE_IMM:
-#if 0
                        NEW_INS (cfg, temp, OP_ICONST);
                        temp->inst_c0 = ins->inst_imm;
                        temp->dreg = mono_regstate_next_int (cfg->rs);
@@ -1627,10 +1612,8 @@
                        ins->opcode = map_to_reg_reg_op (ins->opcode);
                        last_ins = temp;
                        goto loop_start; /* make it handle the possibly big 
ins->inst_offset */
+                       break;
 #endif
-#if 1
-                       ;
-#endif
                }
                last_ins = ins;
                ins = ins->next;
@@ -1924,7 +1907,6 @@
                                        imm = ins->inst_imm & 0xffff;
                                }
                        }
-
 #if 0
                        if (ins->next) {
                                switch (ins->next->opcode) {
@@ -2073,10 +2055,24 @@
                                mips_and (code, ins->dreg, ins->sreg1, mips_at);
                        }
                        break;
-               case CEE_DIV: {
-                       guint32 *divisor_is_zero = (guint32 *)(void *)code;
+               case CEE_DIV:
+               case CEE_REM: {
+                       guint32 *divisor_is_m1;
+                       guint32 *divisor_is_zero;
 
+                       /* */
+                       mips_addiu (code, mips_at, mips_zero, 0xffff);
+                       divisor_is_m1 = (guint32 *)code;
+                       mips_bne (code, ins->sreg2, mips_at, 0);
+                       mips_nop (code);
+
+                       /* Divide by -1 -- throw exception */
+                       EMIT_SYSTEM_EXCEPTION_NAME("ArithmeticException");
+
+                       mips_patch (divisor_is_m1, (guint32)code);
+
                        /* Put divide in branch delay slot */
+                       divisor_is_zero = (guint32 *)code;
                        mips_bne (code, ins->sreg2, mips_zero, 0);
                        mips_div (code, ins->sreg1, ins->sreg2);
 
@@ -2084,7 +2080,10 @@
                        EMIT_SYSTEM_EXCEPTION_NAME("DivideByZeroException");
 
                        mips_patch (divisor_is_zero, (guint32)code);
-                       mips_mflo (code, ins->dreg);
+                       if (ins->opcode == CEE_DIV)
+                               mips_mflo (code, ins->dreg);
+                       else
+                               mips_mfhi (code, ins->dreg);
                        break;
                }
                case CEE_DIV_UN: {
@@ -2113,40 +2112,6 @@
 #endif
                        g_assert_not_reached();
                        break;
-               case CEE_REM: {
-                       /* XXX */
-#if 1
-                       guint32 *divisor_is_zero = (guint32 *)(void *)code;
-
-                       /* Put divide in branch delay slot */
-                       mips_bne (code, ins->sreg2, mips_zero, 0);
-                       mips_div (code, ins->sreg1, ins->sreg2);
-
-                       /* Divide by zero -- throw exception */
-                       EMIT_SYSTEM_EXCEPTION_NAME("DivideByZeroException");
-
-                       mips_patch (divisor_is_zero, (guint32)code);
-                       mips_mfhi (code, ins->dreg);
-                       break;
-#else
-                       guint32 *divisor_is_m1;
-                       ppc_cmpi (code, 0, 0, ins->sreg2, -1);
-                       divisor_is_m1 = (guint32 *)(void *)code;
-                       ppc_bc (code, PPC_BR_FALSE | PPC_BR_LIKELY, PPC_BR_EQ, 
0);
-                       ppc_lis (code, ppc_r11, 0x8000);
-                       ppc_cmp (code, 0, 0, ins->sreg1, ppc_r11);
-                       EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_TRUE, 
PPC_BR_EQ, "ArithmeticException");
-                       mips_patch (divisor_is_m1, (guint32)code);
-                       ppc_divwod (code, ppc_r11, ins->sreg1, ins->sreg2);
-                       ppc_mfspr (code, ppc_r0, ppc_xer);
-                       ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
-                       /* FIXME: use OverflowException for 0x80000000/-1 */
-                       EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_FALSE, 
PPC_BR_EQ, "DivideByZeroException");
-                       ppc_mullw (code, ppc_r11, ppc_r11, ins->sreg2);
-                       ppc_subf (code, ins->dreg, ppc_r11, ins->sreg1);
-#endif
-                       break;
-               }
                case CEE_REM_UN: {
                        guint32 *divisor_is_zero = (guint32 *)(void *)code;
 
@@ -2235,20 +2200,23 @@
                        mips_nop (code);
 #endif
                        break;
-               case CEE_MUL_OVF:
-#if 1
-                       mips_mul (code, ins->dreg, ins->sreg1, ins->sreg2);
-#else
+               case CEE_MUL_OVF: {
+                       guint32 *patch;
                        mips_mult (code, ins->sreg1, ins->sreg2);
                        mips_mflo (code, ins->dreg);
                        mips_mfhi (code, mips_at);
                        mips_nop (code);
                        mips_nop (code);
-#endif
-                       /* XXX - Throw exception if we overflowed */
+                       mips_sra (code, mips_temp, ins->dreg, 31);
+                       patch = (guint32 *)(void *)code;
+                       mips_beq (code, mips_temp, mips_at, 0);
+                       mips_nop (code);
+                       EMIT_SYSTEM_EXCEPTION_NAME("OverflowException");
+                       mips_patch (patch, (guint32)code);
                        break;
+               }
                case CEE_MUL_OVF_UN:
-#if 1
+#if 0
                        mips_mul (code, ins->dreg, ins->sreg1, ins->sreg2);
 #else
                        mips_mult (code, ins->sreg1, ins->sreg2);
@@ -2349,12 +2317,14 @@
                                ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
                        }
                        if (!cfg->method->save_lmf) {
-                               /*for (i = 31; i >= 14; --i) {
+#if 0
+                               for (i = 31; i >= 14; --i) {
                                        if (cfg->used_float_regs & (1 << i)) {
                                                pos += sizeof (double);
                                                ppc_lfd (code, i, -pos, 
cfg->frame_reg);
                                        }
-                               }*/
+                               }
+#endif
                                for (i = 31; i >= 13; --i) {
                                        if (cfg->used_int_regs & (1 << i)) {
                                                pos += sizeof (gulong);
@@ -2599,72 +2569,109 @@
                        mips_nop (code);
                        mips_move (code, ins->dreg, mips_zero);
                        break;
+
                case OP_COND_EXC_EQ:
-               case OP_COND_EXC_NE_UN:
-               case OP_COND_EXC_LT:
-               case OP_COND_EXC_LT_UN:
-               case OP_COND_EXC_GT:
-               case OP_COND_EXC_GT_UN:
                case OP_COND_EXC_GE:
-               case OP_COND_EXC_GE_UN:
+               case OP_COND_EXC_GT:
                case OP_COND_EXC_LE:
+               case OP_COND_EXC_LT:
+               case OP_COND_EXC_NE_UN:
+               case OP_COND_EXC_GE_UN:
+               case OP_COND_EXC_GT_UN:
                case OP_COND_EXC_LE_UN:
-#if 0 /* Don't raise conditional exceptions at the moment */
+               case OP_COND_EXC_LT_UN:
+
+               case OP_COND_EXC_OV:
+               case OP_COND_EXC_NO:
+               case OP_COND_EXC_C:
+               case OP_COND_EXC_NC:
+
+               case OP_COND_EXC_IEQ:
+               case OP_COND_EXC_IGE:
+               case OP_COND_EXC_IGT:
+               case OP_COND_EXC_ILE:
+               case OP_COND_EXC_ILT:
+               case OP_COND_EXC_INE_UN:
+               case OP_COND_EXC_IGE_UN:
+               case OP_COND_EXC_IGT_UN:
+               case OP_COND_EXC_ILE_UN:
+               case OP_COND_EXC_ILT_UN:
+
+               case OP_COND_EXC_IOV:
+               case OP_COND_EXC_INO:
+               case OP_COND_EXC_IC:
+               case OP_COND_EXC_INC:
+                       /* Should be re-mapped to OP_MIPS_B* by 
*.inssel-mips.brg */
+                       g_warning ("unsupported conditional exception %s\n", 
mono_inst_name (ins->opcode));
+                       g_assert_not_reached ();
+                       break;
+
+               case OP_MIPS_COND_EXC_EQ:
+               case OP_MIPS_COND_EXC_GE:
+               case OP_MIPS_COND_EXC_GT:
+               case OP_MIPS_COND_EXC_LE:
+               case OP_MIPS_COND_EXC_LT:
+               case OP_MIPS_COND_EXC_NE_UN:
+               case OP_MIPS_COND_EXC_GE_UN:
+               case OP_MIPS_COND_EXC_GT_UN:
+               case OP_MIPS_COND_EXC_LE_UN:
+               case OP_MIPS_COND_EXC_LT_UN:
+
+               case OP_MIPS_COND_EXC_OV:
+               case OP_MIPS_COND_EXC_NO:
+               case OP_MIPS_COND_EXC_C:
+               case OP_MIPS_COND_EXC_NC:
+
+               case OP_MIPS_COND_EXC_IEQ:
+               case OP_MIPS_COND_EXC_IGE:
+               case OP_MIPS_COND_EXC_IGT:
+               case OP_MIPS_COND_EXC_ILE:
+               case OP_MIPS_COND_EXC_ILT:
+               case OP_MIPS_COND_EXC_INE_UN:
+               case OP_MIPS_COND_EXC_IGE_UN:
+               case OP_MIPS_COND_EXC_IGT_UN:
+               case OP_MIPS_COND_EXC_ILE_UN:
+               case OP_MIPS_COND_EXC_ILT_UN:
+
+               case OP_MIPS_COND_EXC_IOV:
+               case OP_MIPS_COND_EXC_INO:
+               case OP_MIPS_COND_EXC_IC:
+               case OP_MIPS_COND_EXC_INC: {
+                       guint32 *skip;
+                       guint32 *throw;
+
+                       /* If the condition is true, raise the exception */
+
+                       /* need to reverse test to skip around exception 
raising */
+
+                       /* For the moment, branch around a branch to avoid 
reversing
+                          the tests. */
+
+                       /* Remember, an unpatched branch to 0 branches to the 
delay slot */
+                       throw = (guint32 *)(void *)code;
                        switch (ins->opcode) {
-                       case OP_COND_EXC_EQ:
-                               mips_bne (code, mips_at, mips_zero, 5);
+                       case OP_MIPS_COND_EXC_EQ:
+                               mips_beq (code, ins->sreg1, ins->sreg2, 0);
+                               mips_nop (code);
                                break;
-                       case OP_COND_EXC_NE_UN:
-                               mips_beq (code, mips_at, mips_zero, 5);
+                       case OP_MIPS_COND_EXC_NE_UN:
+                               mips_bne (code, ins->sreg1, ins->sreg2, 0);
+                               mips_nop (code);
                                break;
-                       case OP_COND_EXC_LT:
-                       case OP_COND_EXC_LT_UN:
-                               mips_bgez (code, mips_at, 5);
-                               break;
-                       case OP_COND_EXC_GT:
-                       case OP_COND_EXC_GT_UN:
-                               mips_blez (code, mips_at, 5);
-                               break;
-                       case OP_COND_EXC_GE:
-                       case OP_COND_EXC_GE_UN:
-                               mips_bltz (code, mips_at, 5);
-                               break;
-                       case OP_COND_EXC_LE:
-                       case OP_COND_EXC_LE_UN:
-                               mips_bgtz (code, mips_at, 5);
-                               break;
+                       default:
+                               /* Not yet implemented */
+                               g_warning ("NYI conditional exception %s\n", 
mono_inst_name (ins->opcode));
+                               g_assert_not_reached ();
                        }
+                       skip = (guint32 *)(void *)code;
+                       mips_beq (code, mips_zero, mips_zero, 0);
                        mips_nop (code);
-                       mono_add_patch_info (cfg, code - cfg->native_code,
-                                            MONO_PATCH_INFO_EXC, ins->inst_p1);
-                       mips_lui (code, mips_t9, mips_zero, 0);
-                       mips_addiu (code, mips_t9, mips_t9, 0);
-                       mips_jalr (code, mips_t9, mips_ra);
-                       mips_nop (code);
+                       mips_patch (throw, (guint32)code);
+                       code = mips_emit_exc_by_name (code, ins->inst_p1);
+                       mips_patch (skip, (guint32)code);
                        cfg->bb_exit->max_offset += 24;
-#endif
                        break;
-               case OP_COND_EXC_C:
-                       g_assert_not_reached();
-#if 0
-                       /* check XER [0-3] (SO, OV, CA): we can't use mcrxr
-                        */
-                       ppc_mfspr (code, ppc_r0, ppc_xer);
-                       ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
-                       EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_FALSE, 
PPC_BR_EQ, "OverflowException");
-#endif
-                       break;
-               case OP_COND_EXC_OV:
-                       g_assert_not_reached();
-#if 0
-                       ppc_mcrxr (code, 0);
-                       EMIT_COND_SYSTEM_EXCEPTION (CEE_BGT - CEE_BEQ, 
ins->inst_p1);
-#endif
-                       break;
-               case OP_COND_EXC_NC:
-               case OP_COND_EXC_NO:
-                       g_assert_not_reached ();
-                       break;
+               }
                case CEE_BEQ:
                case CEE_BNE_UN:
                case CEE_BLT:
@@ -2676,6 +2683,7 @@
                case CEE_BLE:
                case CEE_BLE_UN:
                        /* Should be re-mapped to OP_MIPS_B* by 
*.inssel-mips.brg */
+                       g_warning ("unsupported conditional set %s\n", 
mono_inst_name (ins->opcode));
                        g_assert_not_reached ();
                        break;
                case OP_MIPS_BEQ:
@@ -2805,17 +2813,17 @@
                        mips_cvtds (code, ins->dreg, ins->dreg);
                        break;
                case CEE_CONV_R_UN: {
-                       g_assert_not_reached();
-#if 0
-                       static const guint64 adjust_val = 0x4330000000000000ULL;
-                       ppc_addis (code, ppc_r0, ppc_r0, 0x4330);
-                       ppc_stw (code, ppc_r0, -8, ppc_sp);
-                       ppc_stw (code, ins->sreg1, -4, ppc_sp);
-                       ppc_load (code, ppc_r11, &adjust_val);
-                       ppc_lfd (code, ins->dreg, -8, ppc_sp);
-                       ppc_lfd (code, ppc_f0, 0, ppc_r11);
-                       ppc_fsub (code, ins->dreg, ins->dreg, ppc_f0);
-#endif
+                       static const guint64 adjust_val = 0x41F0000000000000ULL;
+
+                       /* convert unsigned int to double */
+                       mips_mtc1 (code, mips_ftemp, ins->sreg1);
+                       mips_bgez (code, ins->sreg1, 5);
+                       mips_cvtdw (code, ins->dreg, mips_ftemp);
+
+                       mips_load (code, mips_at, (guint32) &adjust_val);
+                       mips_ldc1  (code, mips_ftemp, mips_at, 0);
+                       mips_faddd (code, ins->dreg, ins->dreg, mips_ftemp);
+                       /* target is here */
                        break;
                }
                case CEE_CONV_R4:
@@ -2856,37 +2864,10 @@
                        g_assert_not_reached ();
                        /* Implemented as helper calls */
                        break;
-               case OP_LCONV_TO_OVF_I: {
-#if 1
-                       if (ins->dreg != ins->sreg1)
-                               mips_move (code, ins->dreg, ins->sreg1);
-#else
-                       guint32 *negative_branch, *msword_positive_branch, 
*msword_negative_branch, *ovf_ex_target;
-                       g_assert_not_reached();
-                       // Check if its negative
-                       ppc_cmpi (code, 0, 0, ins->sreg1, 0);
-                       negative_branch = (guint32 *)(void *)code;
-                       ppc_bc (code, PPC_BR_TRUE, PPC_BR_LT, 0);
-                       // Its positive msword == 0
-                       ppc_cmpi (code, 0, 0, ins->sreg2, 0);
-                       msword_positive_branch = (guint32 *)(void *)code;
-                       ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0);
-
-                       ovf_ex_target = (guint32 *)(void *)code;
-                       EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_ALWAYS, 0, 
"OverflowException");
-                       // Negative
-                       mips_patch (negative_branch, (guint32)code);
-                       ppc_cmpi (code, 0, 0, ins->sreg2, -1);
-                       msword_negative_branch = (guint32 *)(void *)code;
-                       ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
-                       mips_patch (msword_negative_branch, 
(guint32)ovf_ex_target);
-                       
-                       mips_patch (msword_positive_branch, (guint32)code);
-                       if (ins->dreg != ins->sreg1)
-                               ppc_mr (code, ins->dreg, ins->sreg1);
-#endif
+               case OP_LCONV_TO_OVF_I:
+                       g_assert_not_reached ();
+                       /* split up by brg file */
                        break;
-               }
                case OP_SQRT:
                        mips_fsqrtd (code, ins->dreg, ins->sreg1);
                        break;
@@ -3133,13 +3114,13 @@
                        /* from OP_AOTCONST : lui + addiu */
                        patch_lui_addiu ((guint32 *)(void *)ip, 
(guint32)target);
                        continue;
+#if 0
                case MONO_PATCH_INFO_EXC_NAME:
                        g_assert_not_reached ();
                        *((gconstpointer *)(void *)(ip + 1)) = 
patch_info->data.name;
                        continue;
+#endif
                case MONO_PATCH_INFO_NONE:
-               case MONO_PATCH_INFO_BB_OVF:
-               case MONO_PATCH_INFO_EXC_OVF:
                        /* everything is dealt with at epilog output time */
                        continue;
                default:
@@ -3763,6 +3744,7 @@
 void
 mono_arch_emit_exceptions (MonoCompile *cfg)
 {
+#if 0
        MonoJumpInfo *patch_info;
        int i;
        guint8 *code;
@@ -3777,6 +3759,7 @@
         * 24 is the simulated call to throw_exception_by_name
         */
        for (patch_info = cfg->patch_info; patch_info; patch_info = 
patch_info->next) {
+#if 0
                if (patch_info->type == MONO_PATCH_INFO_EXC) {
                        i = exception_id_by_name (patch_info->data.target);
                        g_assert (i < MONO_EXC_INTRINS_NUM);
@@ -3784,18 +3767,6 @@
                                max_epilog_size += 12;
                                exc_throw_found [i] = TRUE;
                        }
-               } else if (patch_info->type == MONO_PATCH_INFO_BB_OVF)
-                       max_epilog_size += 12;
-#if 0
-               else if (patch_info->type == MONO_PATCH_INFO_EXC_OVF) {
-                       MonoOvfJump *ovfj = (MonoOvfJump 
*)patch_info->data.target;
-                       i = exception_id_by_name (ovfj->data.exception);
-                       g_assert (i < MONO_EXC_INTRINS_NUM);
-                       if (!exc_throw_found [i]) {
-                               max_epilog_size += 12;
-                               exc_throw_found [i] = TRUE;
-                       }
-                       max_epilog_size += 8;
                }
 #endif
        }
@@ -3811,52 +3782,8 @@
        /* add code to raise exceptions */
        for (patch_info = cfg->patch_info; patch_info; patch_info = 
patch_info->next) {
                switch (patch_info->type) {
-#if 0
-               case MONO_PATCH_INFO_BB_OVF: {
-                       MonoOvfJump *ovfj = (MonoOvfJump 
*)patch_info->data.target;
-                       guint32 *ip = (guint32 *)(void *)(patch_info->ip.i + 
cfg->native_code);
-                       /* patch the initial jump */
-                       mips_patch (ip, (guint32)code);
-                       mips_bne (code, ovfj->b0_cond, ovfj->b1_cond, 2);
-                       mips_nop (code);
-                       mips_lui (code, mips_at, mips_zero, 0);
-                       mips_addiu (code, mips_at, mips_at, 0);
-                       mips_jr (code, mips_at);
-                       mips_patch ((guint32 *)(void *)(code - 4), (guint32)(ip 
+ 1)); /* jump back after the initial branch */
-                       mips_nop (code);
-                       /* jump back to the true target */
-                       mips_jump (code, 0);
-                       ip = (guint32 *)(void *)(ovfj->data.bb->native_offset + 
cfg->native_code);
-                       mips_patch ((guint32 *)(void *)(code - 4), (guint32)ip);
-                       mips_nop (code);
-                       break;
-               }
-               case MONO_PATCH_INFO_EXC_OVF: {
-                       MonoOvfJump *ovfj = (MonoOvfJump 
*)patch_info->data.target;
-                       MonoJumpInfo *newji;
-                       guint32 *ip = (guint32 *)(void *)(patch_info->ip.i + 
cfg->native_code);
-                       unsigned char *bcl = code;
-
-                       /* patch the initial jump: we arrived here with a call 
*/
-                       mips_patch (ip, (guint32)code);
-                       mips_bne (code, ovfj->b0_cond, ovfj->b1_cond, 0);
-                       mips_nop (code);
-                       mips_jump (code, 0);
-                       /* jump back after the initial branch */
-                       mips_patch ((guint32 *)(void *)(code - 4), (guint32)(ip 
+ 1));
-                       mips_nop (code);
-                       /* patch the conditional jump to the right handler */
-                       /* make it processed next */
-                       newji = mono_mempool_alloc (cfg->mempool, sizeof 
(MonoJumpInfo));
-                       newji->type = MONO_PATCH_INFO_EXC;
-                       newji->ip.i = bcl - cfg->native_code;
-                       newji->data.target = ovfj->data.exception;
-                       newji->next = patch_info->next;
-                       patch_info->next = newji;
-                       break;
-               }
-#endif
                case MONO_PATCH_INFO_EXC: {
+#if 0
                        //unsigned char *ip = patch_info->ip.i + 
cfg->native_code;
 
                        i = exception_id_by_name (patch_info->data.target);
@@ -3877,6 +3804,9 @@
                        /* Turn into a Relative patch, pointing at code stub */
                        patch_info->type = MONO_PATCH_INFO_METHOD_REL;
                        patch_info->data.offset = exc_throw_pos[i] - 
cfg->native_code;
+#else
+                       g_assert_not_reached();
+#endif
                        break;
                }
                default:
@@ -3888,7 +3818,7 @@
        cfg->code_len = code - cfg->native_code;
 
        g_assert (cfg->code_len < cfg->code_size);
-
+#endif
 }
 
 /*

Modified: trunk/mono/mono/mini/mini-mips.h
===================================================================
--- trunk/mono/mono/mini/mini-mips.h    2007-01-17 20:03:33 UTC (rev 71226)
+++ trunk/mono/mono/mini/mini-mips.h    2007-01-17 20:17:41 UTC (rev 71227)
@@ -354,17 +354,17 @@
        do { \
                switch (cmp_op) { \
                case CEE_BEQ: \
-                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK(cfg, OP_MIPS_BEQ, 
sreg1, sreg2, block); \
+                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BEQ, 
sreg1, sreg2, block); \
                        break; \
                case CEE_BNE_UN: \
-                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK(cfg, OP_MIPS_BNE, 
sreg1, sreg2, block); \
+                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BNE, 
sreg1, sreg2, block); \
                        break; \
                case CEE_BLT_UN: \
                        MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg1, 
sreg2); \
-                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK(cfg, OP_MIPS_BNE, 
mips_at, mips_zero, block); \
+                       MONO_EMIT_NEW_BRANCH_BIREG_BLOCK (cfg, OP_MIPS_BNE, 
mips_at, mips_zero, block); \
                        break; \
                default: \
-                       g_assert_not_reached(); \
+                       g_assert_not_reached (); \
                } \
        } while (0)
 #endif
@@ -384,6 +384,76 @@
        } while (0)
 #endif
 
+#define        MONO_EMIT_NEW_MIPS_COND_EXC(cfg,cond,sr1,sr2,name) do { \
+                MonoInst *inst; \
+               inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); 
\
+               inst->opcode = cond;  \
+                inst->inst_p1 = (char*)name; \
+               inst->sreg1 = sr1; \
+               inst->sreg2 = sr2; \
+               mono_bblock_add_inst ((cfg)->cbb, inst); \
+       } while (0)
+
+#ifndef MONO_EMIT_NEW_COMPARE_EXC
+#define MONO_EMIT_NEW_COMPARE_EXC(cfg, cmp_op, sreg1, sreg2, exc) do { \
+               switch (OP_MIPS_COND_EXC_##cmp_op) { \
+               case OP_MIPS_COND_EXC_EQ: \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, OP_MIPS_COND_EXC_EQ, 
sreg1, sreg2, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_NE_UN: \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, 
OP_MIPS_COND_EXC_NE_UN, sreg1, sreg2, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_GT: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg2, 
sreg1); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, 
OP_MIPS_COND_EXC_NE_UN, mips_at, mips_zero, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_GT_UN: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg2, 
sreg1); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, 
OP_MIPS_COND_EXC_NE_UN, mips_at, mips_zero, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_LE: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg2, 
sreg1); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, OP_MIPS_COND_EXC_EQ, 
mips_at, mips_zero, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_LE_UN: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg2, 
sreg1); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, OP_MIPS_COND_EXC_EQ, 
mips_at, mips_zero, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_LT: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLT, mips_at, sreg1, 
sreg2); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, 
OP_MIPS_COND_EXC_NE_UN, mips_at, mips_zero, exc); \
+                       break; \
+               case OP_MIPS_COND_EXC_LT_UN: \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_MIPS_SLTU, mips_at, sreg1, 
sreg2); \
+                       MONO_EMIT_NEW_MIPS_COND_EXC (cfg, 
OP_MIPS_COND_EXC_NE_UN, mips_at, mips_zero, exc); \
+                       break; \
+               default: \
+                       g_warning ("unknown comparison %s\n", #cmp_op); \
+                       g_assert_not_reached (); \
+               } \
+       } while (0)
+#endif
+
+#ifndef MONO_EMIT_NEW_COMPARE_IMM_EXC
+#define MONO_EMIT_NEW_COMPARE_IMM_EXC(cfg, cmp_op, sreg1, imm, exc) do { \
+               guint32 cmp_reg; \
+               if (!(imm)) { \
+                       cmp_reg = mips_zero; \
+               } \
+               else { \
+                       cmp_reg = mips_at; \
+                       MONO_EMIT_NEW_ICONST (cfg, cmp_reg, (imm)); \
+               } \
+               MONO_EMIT_NEW_COMPARE_EXC (cfg, cmp_op, sreg1, cmp_reg, exc); \
+       } while (0)
+#endif
+
+#ifndef MONO_EMIT_NEW_ICOMPARE_IMM_EXC
+#define MONO_EMIT_NEW_ICOMPARE_IMM_EXC(cfg, cmp_op, sreg1, imm, exc) do { \
+               MONO_EMIT_NEW_COMPARE_IMM_EXC(cfg, cmp_op, sreg1, imm, exc); \
+       } while (0)
+#endif
+
 typedef struct {
        gint8 reg;
        gint8 size;

Modified: trunk/mono/mono/mini/mini-ops.h
===================================================================
--- trunk/mono/mono/mini/mini-ops.h     2007-01-17 20:03:33 UTC (rev 71226)
+++ trunk/mono/mono/mini/mini-ops.h     2007-01-17 20:17:41 UTC (rev 71227)
@@ -770,4 +770,37 @@
 MINI_OP(OP_MIPS_SLTIU, "mips_sltiu")
 MINI_OP(OP_MIPS_SLTU,  "mips_sltu")
 MINI_OP(OP_MIPS_XORI,  "mips_xori")
+
+MINI_OP(OP_MIPS_COND_EXC_EQ, "mips_cond_exc_eq")
+MINI_OP(OP_MIPS_COND_EXC_GE, "mips_cond_exc_ge")
+MINI_OP(OP_MIPS_COND_EXC_GT, "mips_cond_exc_gt")
+MINI_OP(OP_MIPS_COND_EXC_LE, "mips_cond_exc_le")
+MINI_OP(OP_MIPS_COND_EXC_LT, "mips_cond_exc_lt")
+MINI_OP(OP_MIPS_COND_EXC_NE_UN, "mips_cond_exc_ne_un")
+MINI_OP(OP_MIPS_COND_EXC_GE_UN, "mips_cond_exc_ge_un")
+MINI_OP(OP_MIPS_COND_EXC_GT_UN, "mips_cond_exc_gt_un")
+MINI_OP(OP_MIPS_COND_EXC_LE_UN, "mips_cond_exc_le_un")
+MINI_OP(OP_MIPS_COND_EXC_LT_UN, "mips_cond_exc_lt_un")
+
+MINI_OP(OP_MIPS_COND_EXC_OV, "mips_cond_exc_ov")
+MINI_OP(OP_MIPS_COND_EXC_NO, "mips_cond_exc_no")
+MINI_OP(OP_MIPS_COND_EXC_C, "mips_cond_exc_c")
+MINI_OP(OP_MIPS_COND_EXC_NC, "mips_cond_exc_nc")
+
+MINI_OP(OP_MIPS_COND_EXC_IEQ, "mips_cond_exc_ieq")
+MINI_OP(OP_MIPS_COND_EXC_IGE, "mips_cond_exc_ige")
+MINI_OP(OP_MIPS_COND_EXC_IGT, "mips_cond_exc_igt")
+MINI_OP(OP_MIPS_COND_EXC_ILE, "mips_cond_exc_ile")
+MINI_OP(OP_MIPS_COND_EXC_ILT, "mips_cond_exc_ilt")
+MINI_OP(OP_MIPS_COND_EXC_INE_UN, "mips_cond_exc_ine_un")
+MINI_OP(OP_MIPS_COND_EXC_IGE_UN, "mips_cond_exc_ige_un")
+MINI_OP(OP_MIPS_COND_EXC_IGT_UN, "mips_cond_exc_igt_un")
+MINI_OP(OP_MIPS_COND_EXC_ILE_UN, "mips_cond_exc_ile_un")
+MINI_OP(OP_MIPS_COND_EXC_ILT_UN, "mips_cond_exc_ilt_un")
+
+MINI_OP(OP_MIPS_COND_EXC_IOV, "mips_cond_exc_iov")
+MINI_OP(OP_MIPS_COND_EXC_INO, "mips_cond_exc_ino")
+MINI_OP(OP_MIPS_COND_EXC_IC, "mips_cond_exc_ic")
+MINI_OP(OP_MIPS_COND_EXC_INC, "mips_cond_exc_inc")
+
 #endif

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to