[mono/mono] [4 commits] f047afac: [jit] Add some missing compare instructions which will make it easier to optimize inlined boolean expressions.

"Rodrigo Kumpera ([email protected])" <[email protected]> Mon, 4 Nov 2013 20:53:06 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014224e3edc2-02d6e28a-70a1-4f79-bb65-095ef15cb16a-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/1ba345570fd7...0261d6fceac6

   Commit: f047afaccbcb7c8d63400b91d61ec717c1301b40
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-04 20:36:50 GMT
      URL: https://github.com/mono/mono/commit/f047afaccbcb7c8d63400b91d61ec717c1301b40

[jit] Add some missing compare instructions which will make it easier to optimize inlined boolean expressions.

Changed paths:
  M mono/mini/mini-codegen.c
  M mono/mini/mini-ops.h

Modified: mono/mini/mini-codegen.c
===================================================================
@@ -2337,6 +2337,8 @@ enum {
 	case OP_CMOV_IEQ:
 	case OP_CMOV_LEQ:
 		return CMP_EQ;
+	case OP_FCNEQ:
+	case OP_ICNEQ:
 	case OP_IBNE_UN:
 	case OP_LBNE_UN:
 	case OP_FBNE_UN:
@@ -2345,12 +2347,16 @@ enum {
 	case OP_CMOV_INE_UN:
 	case OP_CMOV_LNE_UN:
 		return CMP_NE;
+	case OP_FCLE:
+	case OP_ICLE:
 	case OP_IBLE:
 	case OP_LBLE:
 	case OP_FBLE:
 	case OP_CMOV_ILE:
 	case OP_CMOV_LLE:
 		return CMP_LE;
+	case OP_FCGE:
+	case OP_ICGE:
 	case OP_IBGE:
 	case OP_LBGE:
 	case OP_FBGE:
@@ -2382,6 +2388,7 @@ enum {
 	case OP_CMOV_LGT:
 		return CMP_GT;
 
+	case OP_ICLE_UN:
 	case OP_IBLE_UN:
 	case OP_LBLE_UN:
 	case OP_FBLE_UN:
@@ -2390,6 +2397,8 @@ enum {
 	case OP_CMOV_ILE_UN:
 	case OP_CMOV_LLE_UN:
 		return CMP_LE_UN;
+
+	case OP_ICGE_UN:
 	case OP_IBGE_UN:
 	case OP_LBGE_UN:
 	case OP_FBGE_UN:

Modified: mono/mini/mini-ops.h
===================================================================
@@ -421,6 +421,12 @@
 MINI_OP(OP_ICLT,   "int_clt", IREG, NONE, NONE)
 MINI_OP(OP_ICLT_UN,"int_clt_un", IREG, NONE, NONE)
 
+MINI_OP(OP_ICNEQ,  "int_cneq", IREG, NONE, NONE)
+MINI_OP(OP_ICGE,   "int_cge", IREG, NONE, NONE)
+MINI_OP(OP_ICLE,   "int_cle", IREG, NONE, NONE)
+MINI_OP(OP_ICGE_UN,"int_cge_un", IREG, NONE, NONE)
+MINI_OP(OP_ICLE_UN,"int_cle_un", IREG, NONE, NONE)
+
 MINI_OP(OP_IBEQ,    "int_beq", NONE, NONE, NONE)
 MINI_OP(OP_IBGE,    "int_bge", NONE, NONE, NONE)
 MINI_OP(OP_IBGT,    "int_bgt", NONE, NONE, NONE)
@@ -504,6 +510,10 @@
 MINI_OP(OP_FCLT,   "float_clt", IREG, FREG, FREG)
 MINI_OP(OP_FCLT_UN,"float_clt_un", IREG, FREG, FREG)
 
+MINI_OP(OP_FCNEQ,  "float_cneq", IREG, FREG, FREG)
+MINI_OP(OP_FCGE,   "float_cge", IREG, FREG, FREG)
+MINI_OP(OP_FCLE,   "float_cle", IREG, FREG, FREG)
+
 MINI_OP(OP_FCEQ_MEMBASE,   "float_ceq_membase", IREG, FREG, IREG)
 MINI_OP(OP_FCGT_MEMBASE,   "float_cgt_membase", IREG, FREG, IREG)
 MINI_OP(OP_FCGT_UN_MEMBASE,"float_cgt_un_membase", IREG, FREG, IREG)

   Commit: b44597cb491b39191aafd2df0d67877eab12fa76
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-04 20:36:54 GMT
      URL: https://github.com/mono/mono/commit/b44597cb491b39191aafd2df0d67877eab12fa76

[jit]Add x86 support for the new compare instructions.

Changed paths:
  M mono/mini/cpu-x86.md
  M mono/mini/mini-x86.c

Modified: mono/mini/cpu-x86.md
===================================================================
@@ -241,6 +241,9 @@ float_cgt: dest:y src1:f src2:f len:25
 float_cgt_un: dest:y src1:f src2:f len:37
 float_clt: dest:y src1:f src2:f len:25
 float_clt_un: dest:y src1:f src2:f len:32
+float_cneq: dest:y src1:f src2:f len:25
+float_cge: dest:y src1:f src2:f len:37
+float_cle: dest:y src1:f src2:f len:37
 float_conv_to_u: dest:i src1:f len:36
 call_handler: len:11 clob:c
 aot_const: dest:i len:5
@@ -347,6 +350,12 @@ int_cgt_un: dest:y len:6
 int_clt: dest:y len:6
 int_clt_un: dest:y len:6
 
+int_cneq: dest:y len:6
+int_cge: dest:y len:6
+int_cle: dest:y len:6
+int_cge_un: dest:y len:6
+int_cle_un: dest:y len:6
+
 cond_exc_ieq: len:6
 cond_exc_ine_un: len:6
 cond_exc_ilt: len:6

Modified: mono/mini/mini-x86.c
===================================================================
@@ -3384,6 +3384,12 @@ enum {
 		case OP_BR_REG:
 			x86_jump_reg (code, ins->sreg1);
 			break;
+		case OP_ICNEQ:
+		case OP_ICGE:
+		case OP_ICLE:
+		case OP_ICGE_UN:
+		case OP_ICLE_UN:
+
 		case OP_CEQ:
 		case OP_CLT:
 		case OP_CLT_UN:
@@ -3818,6 +3824,7 @@ enum {
 			x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
 			break;
 		case OP_FCEQ:
+		case OP_FCNEQ:
 			if (cfg->opt & MONO_OPT_FCMOV) {
 				/* zeroing the register at the start results in 
 				 * shorter and faster code (we can also remove the widening op)
@@ -3828,8 +3835,19 @@ enum {
 				x86_fstp (code, 0);
 				unordered_check = code;
 				x86_branch8 (code, X86_CC_P, 0, FALSE);
-				x86_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
-				x86_patch (unordered_check, code);
+				if (ins->opcode == OP_FCEQ) {
+					x86_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
+					x86_patch (unordered_check, code);
+				} else {
+					guchar *jump_to_end;
+					x86_set_reg (code, X86_CC_NE, ins->dreg, FALSE);
+					jump_to_end = code;
+					x86_jump8 (code, 0);
+					x86_patch (unordered_check, code);
+					x86_inc_reg (code, ins->dreg);
+					x86_patch (jump_to_end, code);
+				}
+
 				break;
 			}
 			if (ins->dreg != X86_EAX) 
@@ -3838,7 +3856,7 @@ enum {
 			EMIT_FPCOMPARE(code);
 			x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
 			x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4000);
-			x86_set_reg (code, X86_CC_EQ, ins->dreg, TRUE);
+			x86_set_reg (code, ins->opcode == OP_FCEQ ? X86_CC_EQ : X86_CC_NE, ins->dreg, TRUE);
 			x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
 
 			if (ins->dreg != X86_EAX) 
@@ -3890,6 +3908,44 @@ enum {
 			if (ins->dreg != X86_EAX) 
 				x86_pop_reg (code, X86_EAX);
 			break;
+		case OP_FCLE: {
+			guchar *unordered_check;
+			guchar *jump_to_end;
+			if (cfg->opt & MONO_OPT_FCMOV) {
+				/* zeroing the register at the start results in
+				 * shorter and faster code (we can also remove the widening op)
+				 */
+				x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+				x86_fcomip (code, 1);
+				x86_fstp (code, 0);
+				unordered_check = code;
+				x86_branch8 (code, X86_CC_P, 0, FALSE);
+				x86_set_reg (code, X86_CC_NB, ins->dreg, FALSE);
+				x86_patch (unordered_check, code);
+				break;
+			}
+			if (ins->dreg != X86_EAX)
+				x86_push_reg (code, X86_EAX);
+
+			EMIT_FPCOMPARE(code);
+			x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
+			x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+			unordered_check = code;
+			x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+
+			x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
+			x86_set_reg (code, X86_CC_NE, ins->dreg, TRUE);
+			x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
+			jump_to_end = code;
+			x86_jump8 (code, 0);
+			x86_patch (unordered_check, code);
+			x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+			x86_patch (jump_to_end, code);
+
+			if (ins->dreg != X86_EAX)
+				x86_pop_reg (code, X86_EAX);
+			break;
+		}
 		case OP_FCGT:
 		case OP_FCGT_UN:
 			if (cfg->opt & MONO_OPT_FCMOV) {
@@ -3933,6 +3989,44 @@ enum {
 			if (ins->dreg != X86_EAX) 
 				x86_pop_reg (code, X86_EAX);
 			break;
+		case OP_FCGE: {
+			guchar *unordered_check;
+			guchar *jump_to_end;
+			if (cfg->opt & MONO_OPT_FCMOV) {
+				/* zeroing the register at the start results in
+				 * shorter and faster code (we can also remove the widening op)
+				 */
+				x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+				x86_fcomip (code, 1);
+				x86_fstp (code, 0);
+				unordered_check = code;
+				x86_branch8 (code, X86_CC_P, 0, FALSE);
+				x86_set_reg (code, X86_CC_NA, ins->dreg, FALSE);
+				x86_patch (unordered_check, code);
+				break;
+			}
+			if (ins->dreg != X86_EAX)
+				x86_push_reg (code, X86_EAX);
+
+			EMIT_FPCOMPARE(code);
+			x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
+			x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+			unordered_check = code;
+			x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+
+			x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
+			x86_set_reg (code, X86_CC_GE, ins->dreg, TRUE);
+			x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
+			jump_to_end = code;
+			x86_jump8 (code, 0);
+			x86_patch (unordered_check, code);
+			x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+			x86_patch (jump_to_end, code);
+
+			if (ins->dreg != X86_EAX)
+				x86_pop_reg (code, X86_EAX);
+			break;
+		}
 		case OP_FBEQ:
 			if (cfg->opt & MONO_OPT_FCMOV) {
 				guchar *jump = code;

   Commit: 86add8950f44bcd0db87f2a2cebe50f0b4b1a165
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-04 20:36:58 GMT
      URL: https://github.com/mono/mono/commit/86add8950f44bcd0db87f2a2cebe50f0b4b1a165

 [jit]Add amd64 support for the new compare instructions.

Changed paths:
  M mono/mini/cpu-amd64.md
  M mono/mini/mini-amd64.c

Modified: mono/mini/cpu-amd64.md
===================================================================
@@ -246,6 +246,9 @@ float_cgt: dest:i src1:f src2:f len:35
 float_cgt_un: dest:i src1:f src2:f len:48
 float_clt: dest:i src1:f src2:f len:35
 float_clt_un: dest:i src1:f src2:f len:42
+float_cneq: dest:i src1:f src2:f len:42
+float_cge: dest:i src1:f src2:f len:35
+float_cle: dest:i src1:f src2:f len:35
 float_ceq_membase: dest:i src1:f src2:b len:35
 float_cgt_membase: dest:i src1:f src2:b len:35
 float_cgt_un_membase: dest:i src1:f src2:b len:48
@@ -370,6 +373,13 @@ int_cgt: dest:c len:8
 int_cgt_un: dest:c len:8
 int_clt: dest:c len:8
 int_clt_un: dest:c len:8
+
+int_cneq: dest:c len:8
+int_cge: dest:c len:8
+int_cle: dest:c len:8
+int_cge_un: dest:c len:8
+int_cle_un: dest:c len:8
+
 int_beq: len:8
 int_bne_un: len:8
 int_blt: len:8

Modified: mono/mini/mini-amd64.c
===================================================================
@@ -5146,6 +5146,12 @@
 		case OP_BR_REG:
 			amd64_jump_reg (code, ins->sreg1);
 			break;
+		case OP_ICNEQ:
+		case OP_ICGE:
+		case OP_ICLE:
+		case OP_ICGE_UN:
+		case OP_ICLE_UN:
+
 		case OP_CEQ:
 		case OP_LCEQ:
 		case OP_ICEQ:
@@ -5414,6 +5420,7 @@
 			 */
 			amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
 			break;
+		case OP_FCNEQ:
 		case OP_FCEQ: {
 			/* zeroing the register at the start results in 
 			 * shorter and faster code (we can also remove the widening op)
@@ -5423,8 +5430,19 @@
 			amd64_sse_comisd_reg_reg (code, ins->sreg1, ins->sreg2);
 			unordered_check = code;
 			x86_branch8 (code, X86_CC_P, 0, FALSE);
-			amd64_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
-			amd64_patch (unordered_check, code);
+
+			if (ins->opcode == OP_FCEQ) {
+				amd64_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
+				amd64_patch (unordered_check, code);
+			} else {
+				guchar *jump_to_end;
+				amd64_set_reg (code, X86_CC_NE, ins->dreg, FALSE);
+				jump_to_end = code;
+				x86_jump8 (code, 0);
+				amd64_patch (unordered_check, code);
+				amd64_inc_reg (code, ins->dreg);
+				amd64_patch (jump_to_end, code);
+			}
 			break;
 		}
 		case OP_FCLT:
@@ -5448,6 +5466,16 @@
 				amd64_set_reg (code, X86_CC_GT, ins->dreg, FALSE);
 			}
 			break;
+		case OP_FCLE: {
+			guchar *unordered_check;
+			amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+			amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
+			unordered_check = code;
+			x86_branch8 (code, X86_CC_P, 0, FALSE);
+			amd64_set_reg (code, X86_CC_NB, ins->dreg, FALSE);
+			amd64_patch (unordered_check, code);
+			break;
+		}
 		case OP_FCGT:
 		case OP_FCGT_UN: {
 			/* zeroing the register at the start results in 
@@ -5466,6 +5494,17 @@
 			}
 			break;
 		}
+		case OP_FCGE: {
+			guchar *unordered_check;
+			amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+			amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
+			unordered_check = code;
+			x86_branch8 (code, X86_CC_P, 0, FALSE);
+			amd64_set_reg (code, X86_CC_NA, ins->dreg, FALSE);
+			amd64_patch (unordered_check, code);
+			break;
+		}
+		
 		case OP_FCLT_MEMBASE:
 		case OP_FCGT_MEMBASE:
 		case OP_FCLT_UN_MEMBASE:

   Commit: 0261d6fceac6d46fe992baed79587005b85042df
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-04 20:48:01 GMT
      URL: https://github.com/mono/mono/commit/0261d6fceac6d46fe992baed79587005b85042df

[jit] Cleanup a bit how we handle small structs.

Changed paths:
  M mono/mini/mini-x86.c

Modified: mono/mini/mini-x86.c
===================================================================
@@ -331,16 +331,19 @@ static const guint32 *callconv_param_regs(MonoMethodSignature *sig)
 		ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
 
 		/* Special case structs with only a float member */
-		if ((info->native_size == 8) && (info->num_fields == 1) && (info->fields [0].field->type->type == MONO_TYPE_R8)) {
-			ainfo->storage = ArgValuetypeInReg;
-			ainfo->pair_storage [0] = ArgOnDoubleFpStack;
-			return;
+		if (info->num_fields == 1) {
+			int ftype = info->fields [0].field->type->type;
+			if ((info->native_size == 8) && (ftype == MONO_TYPE_R8)) {
+				ainfo->storage = ArgValuetypeInReg;
+				ainfo->pair_storage [0] = ArgOnDoubleFpStack;
+				return;
+			}
+			if ((info->native_size == 4) && (ftype == MONO_TYPE_R4)) {
+				ainfo->storage = ArgValuetypeInReg;
+				ainfo->pair_storage [0] = ArgOnFloatFpStack;
+				return;
+			}
 		}
-		if ((info->native_size == 4) && (info->num_fields == 1) && (info->fields [0].field->type->type == MONO_TYPE_R4)) {
-			ainfo->storage = ArgValuetypeInReg;
-			ainfo->pair_storage [0] = ArgOnFloatFpStack;
-			return;
-		}		
 		if ((info->native_size == 1) || (info->native_size == 2) || (info->native_size == 4) || (info->native_size == 8)) {
 			ainfo->storage = ArgValuetypeInReg;
 			ainfo->pair_storage [0] = ArgInIReg;


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