2008-12-05 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 5 Dec 2008 12:51:34 +0000 (12:51 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 5 Dec 2008 12:51:34 +0000 (12:51 -0000)
* simd-intrinsics.c (simd_intrinsic_emit_equality): Adapt to support Vector4f.

* simd-intrinsics.c: Kill useless enum.

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

mono/mini/ChangeLog
mono/mini/simd-intrinsics.c

index 61c413401e2aecbb7c79346b84e1dc18b7daef22..e65d7e23e6ca3a3775ddd232a4331e971c393165 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-05  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * simd-intrinsics.c (simd_intrinsic_emit_equality): Adapt to support Vector4f.
+
+       * simd-intrinsics.c: Kill useless enum.
+
 2008-12-04  Mark Mason   <mmason@upwardaccess.com>
 
        * cpu-mips.md: add long_conv_to_ovf_i4_2
index 8ad46feee51ff77bc6ffc37653e639ddbdba1c0a..f84fbc2682d8bb51cbf26f50d5d1f7f0320d23a4 100644 (file)
@@ -82,11 +82,6 @@ enum {
        SIMD_EMIT_PREFETCH
 };
 
-enum {
-       SIMD_CMP_EQUALS,
-       SIMD_CMP_NOT_EQUALS
-};
-
 #ifdef HAVE_ARRAY_ELEM_INIT
 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
 #define MSGSTRFIELD1(line) str##line
@@ -170,8 +165,10 @@ static const SimdIntrinsc vector4f_intrinsics[] = {
        { SN_op_BitwiseAnd, OP_ANDPS, SIMD_EMIT_BINARY },
        { SN_op_BitwiseOr, OP_ORPS, SIMD_EMIT_BINARY },
        { SN_op_Division, OP_DIVPS, SIMD_EMIT_BINARY },
+       { SN_op_Equality, OP_COMPPS, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
        { SN_op_ExclusiveOr, OP_XORPS, SIMD_EMIT_BINARY },
        { SN_op_Explicit, 0, SIMD_EMIT_CAST }, 
+       { SN_op_Inequality, OP_COMPPS, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
        { SN_op_Multiply, OP_MULPS, SIMD_EMIT_BINARY },
        { SN_op_Subtraction, OP_SUBPS, SIMD_EMIT_BINARY },
        { SN_set_W, 3, SIMD_EMIT_SETTER },
@@ -296,10 +293,10 @@ static const SimdIntrinsc vector4ui_intrinsics[] = {
        { SN_op_Addition, OP_PADDD, SIMD_EMIT_BINARY },
        { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
        { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, SIMD_CMP_EQUALS, SIMD_EMIT_EQUALITY,  },
+       { SN_op_Equality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
        { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
        { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, SIMD_CMP_NOT_EQUALS, SIMD_EMIT_EQUALITY },
+       { SN_op_Inequality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
        { SN_op_LeftShift, OP_PSHLD, SIMD_EMIT_SHIFT },
        { SN_op_Multiply, OP_PMULD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
        { SN_op_RightShift, OP_PSHRD, SIMD_EMIT_SHIFT },
@@ -335,10 +332,10 @@ static const SimdIntrinsc vector4i_intrinsics[] = {
        { SN_op_Addition, OP_PADDD, SIMD_EMIT_BINARY },
        { SN_op_BitwiseAnd, OP_PAND, SIMD_EMIT_BINARY },
        { SN_op_BitwiseOr, OP_POR, SIMD_EMIT_BINARY },
-       { SN_op_Equality, SIMD_CMP_EQUALS, SIMD_EMIT_EQUALITY,  },
+       { SN_op_Equality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_EQ },
        { SN_op_ExclusiveOr, OP_PXOR, SIMD_EMIT_BINARY },
        { SN_op_Explicit, 0, SIMD_EMIT_CAST },
-       { SN_op_Inequality, SIMD_CMP_NOT_EQUALS, SIMD_EMIT_EQUALITY },
+       { SN_op_Inequality, OP_PCMPEQD, SIMD_EMIT_EQUALITY, SIMD_VERSION_SSE1, SIMD_COMP_NEQ },
        { SN_op_LeftShift, OP_PSHLD, SIMD_EMIT_SHIFT },
        { SN_op_Multiply, OP_PMULD, SIMD_EMIT_BINARY, SIMD_VERSION_SSE41 },
        { SN_op_RightShift, OP_PSARD, SIMD_EMIT_SHIFT },
@@ -1140,6 +1137,12 @@ simd_intrinsic_emit_shift (const SimdIntrinsc *intrinsic, MonoCompile *cfg, Mono
        return ins;
 }
 
+static inline gboolean
+mono_op_is_packed_compare (int op)
+{
+       return op >= OP_PCMPEQB && op <= OP_PCMPEQQ;
+}
+
 static MonoInst*
 simd_intrinsic_emit_equality (const SimdIntrinsc *intrinsic, MonoCompile *cfg, MonoMethod *cmethod, MonoInst **args)
 {
@@ -1150,13 +1153,14 @@ simd_intrinsic_emit_equality (const SimdIntrinsc *intrinsic, MonoCompile *cfg, M
        right_vreg = get_simd_vreg (cfg, cmethod, args [1]);
        
 
-       MONO_INST_NEW (cfg, ins, OP_PCMPEQD);
+       MONO_INST_NEW (cfg, ins, intrinsic->opcode);
        ins->klass = cmethod->klass;
        ins->sreg1 = left_vreg;
        ins->sreg2 = right_vreg;
        ins->type = STACK_VTYPE;
        ins->klass = cmethod->klass;
        ins->dreg = tmp_vreg = alloc_ireg (cfg);
+       ins->inst_c0 = intrinsic->flags;
        MONO_ADD_INS (cfg->cbb, ins);
 
        /*FIXME the next ops are SSE specific*/
@@ -1167,10 +1171,15 @@ simd_intrinsic_emit_equality (const SimdIntrinsc *intrinsic, MonoCompile *cfg, M
        ins->dreg = tmp_vreg = alloc_ireg (cfg);
        MONO_ADD_INS (cfg->cbb, ins);
 
-       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_vreg, 0xFFFF);
-       NEW_UNALU (cfg, ins, intrinsic->opcode == SIMD_CMP_EQUALS ? OP_CEQ : OP_CLT_UN, tmp_vreg, -1);
-       MONO_ADD_INS (cfg->cbb, ins);
-
+       /*FP ops have a not equal instruction, which means that we must test the results with OR semantics.*/
+       if (mono_op_is_packed_compare (intrinsic->opcode) || intrinsic->flags == SIMD_COMP_EQ) {
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_vreg, 0xFFFF);
+               NEW_UNALU (cfg, ins, intrinsic->flags == SIMD_COMP_EQ ? OP_CEQ : OP_CLT_UN, tmp_vreg, -1);
+       } else {
+               MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, tmp_vreg, 0);
+               NEW_UNALU (cfg, ins, OP_CGT_UN, tmp_vreg, -1);
+       }
+       MONO_ADD_INS (cfg->cbb, ins);   
        return ins;
 }