Ver código fonte

* mono/tests/exception6.cs: added tests for SUB_OVF, SUB_OVF_UN
* x86.brg: impl. ADD_OVF_UN, SUB_OVF, SUB_OVF_UN

svn path=/trunk/mono/; revision=1975

Dietmar Maurer 24 anos atrás
pai
commit
35e4412f79
5 arquivos alterados com 86 adições e 2 exclusões
  1. 1 0
      ChangeLog
  2. 1 0
      mono/jit/ChangeLog
  3. 6 0
      mono/jit/jit.c
  4. 26 1
      mono/jit/x86.brg
  5. 52 1
      mono/tests/exception6.cs

+ 1 - 0
ChangeLog

@@ -1,6 +1,7 @@
 2002-01-14  Dietmar Maurer  <[email protected]>
 
 	* mono/tests/exception6.cs: new tests for ADD_OVF, MUL_OVF
+	added tests for SUB_OVF, SUB_OVF_UN
 
 2001-12-21  Dietmar Maurer  <[email protected]>
 

+ 1 - 0
mono/jit/ChangeLog

@@ -2,6 +2,7 @@
 
 	* x86.brg: bug fix in CONV_OVF_I1_UN
 	impl. ADD_OVF, MUL_OVF
+	impl. ADD_OVF_UN, SUB_OVF, SUB_OVF_UN
 
 Fri Jan 11 20:06:22 CET 2002 Paolo Molaro <[email protected]>
 

+ 6 - 0
mono/jit/jit.c

@@ -1167,7 +1167,10 @@ mono_analyze_flow (MonoFlowGraph *cfg)
 		case CEE_POP:
 		case CEE_ADD:
 		case CEE_ADD_OVF:
+		case CEE_ADD_OVF_UN:
 		case CEE_SUB:
+		case CEE_SUB_OVF:
+		case CEE_SUB_OVF_UN:
 		case CEE_AND:
 		case CEE_OR:
 		case CEE_XOR:
@@ -2499,7 +2502,10 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
 		MAKE_BI_ALU (ADD)
 		MAKE_BI_ALU (ADD_OVF)
+		MAKE_BI_ALU (ADD_OVF_UN)
 		MAKE_BI_ALU (SUB)
+		MAKE_BI_ALU (SUB_OVF)
+		MAKE_BI_ALU (SUB_OVF_UN)
 		MAKE_BI_ALU (AND)
 		MAKE_BI_ALU (OR)
 		MAKE_BI_ALU (XOR)

+ 26 - 1
mono/jit/x86.brg

@@ -164,7 +164,8 @@ void *MEMCOPY (void *dest, const void *src, size_t n);
 %term STIND_I1 STIND_I2 STIND_I4 STIND_I8 STIND_R4 STIND_R8 STIND_OBJ
 %term ADDR_L ADDR_G ARG_I4 ARG_I8 ARG_R4 ARG_R8 ARG_OBJ ARG_STRING CALL_I4 CALL_I8 CALL_R8 CALL_VOID
 %term BREAK SWITCH BR RET_VOID RET RET_OBJ ENDFINALLY
-%term ADD ADD_OVF SUB MUL MUL_OVF MUL_OVF_UN DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT
+%term ADD ADD_OVF ADD_OVF_UN SUB SUB_OVF SUB_OVF_UN MUL MUL_OVF MUL_OVF_UN 
+%term DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT
 %term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN 
 %term CEQ CLT CGT
 %term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_U8 CONV_R4 CONV_R8
@@ -813,6 +814,14 @@ reg: ADD_OVF (reg, reg) {
 		x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
 
+reg: ADD_OVF_UN (reg, reg) {
+	x86_alu_reg_reg (s->code, X86_ADD, tree->left->reg1, tree->right->reg1);
+	EMIT_COND_EXCEPTION (X86_CC_NC, get_exception_overflow ());	
+
+	if (tree->reg1 != tree->left->reg1)
+		x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+}
+
 reg: SUB (reg, CONST_I4) "MB_USE_OPT1(0)" {
 	if (tree->right->data.i == 1)
 		x86_dec_reg (s->code, tree->left->reg1);
@@ -830,6 +839,22 @@ reg: SUB (reg, reg) {
 		x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
 
+reg: SUB_OVF (reg, reg) {
+	x86_alu_reg_reg (s->code, X86_SUB, tree->left->reg1, tree->right->reg1);
+	EMIT_COND_EXCEPTION (X86_CC_NO, get_exception_overflow ());	
+
+	if (tree->reg1 != tree->left->reg1)
+		x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+}
+
+reg: SUB_OVF_UN (reg, reg) {
+	x86_alu_reg_reg (s->code, X86_SUB, tree->left->reg1, tree->right->reg1);
+	EMIT_COND_EXCEPTION (X86_CC_NC, get_exception_overflow ());	
+
+	if (tree->reg1 != tree->left->reg1)
+		x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+}
+
 reg: CEQ (reg, reg) {
 	x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
 	x86_set_reg (s->code, X86_CC_EQ, tree->reg1, TRUE);

+ 52 - 1
mono/tests/exception6.cs

@@ -7,6 +7,46 @@ public class Ex {
 		
 		checked {
 
+			ocount = 0;
+			try {
+				int a = Int32.MinValue + 1;
+				int t = a--;
+			} catch {
+				ocount++;
+			}
+			if (ocount != 0)
+				return 1;
+
+			ocount = 0;
+			try {
+				int a = Int32.MinValue;
+				int t = a--;
+			} catch {
+				ocount++;
+			}
+			if (ocount != 1)
+				return 1;
+
+			ocount = 0;
+			try {
+				uint a = 1;
+				uint t = a--;
+			} catch {
+				ocount++;
+			}
+			if (ocount != 0)
+				return 1;
+
+			ocount = 0;
+			try {
+				uint a = 0;
+				uint t = a--;
+			} catch {
+				ocount++;
+			}
+			if (ocount != 1)
+				return 1;
+
 			ocount = 0;
 			try {
 				sbyte a = 126;
@@ -54,7 +94,18 @@ public class Ex {
 			}
 			if (ocount != 1)
 				return 1;
-		
+
+			/*
+			ocount = 0;
+			try {
+				uint a = 0xffffffff;
+				uint t = a*2;
+			} catch {
+				ocount++;
+			}
+			if (ocount != 1)
+				return 1;
+			*/
 		}
 		
 		return 0;