Author: zoltan
Date: 2005-03-06 16:28:08 -0500 (Sun, 06 Mar 2005)
New Revision: 41492

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/cpu-amd64.md
   trunk/mono/mono/mini/inssel-amd64.brg
   trunk/mono/mono/mini/inssel.brg
   trunk/mono/mono/mini/mini-amd64.c
   trunk/mono/mono/mini/mini-amd64.h
   trunk/mono/mono/mini/mini-ops.h
Log:
2005-03-06  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini-ops.h: Add OP_F<xx>_MEMBASE opcodes.

        * inssel.brg: Add MONO_EMIT_BIALU_MEMBASE macro.

        * cpu-amd64.md inssel-amd64.brg mini-amd64.h mini-amd64.brg: Finish SSE2
        support and enable it by default. Also add OP_F<xxx>_MEMBASE opcodes.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/ChangeLog      2005-03-06 21:28:08 UTC (rev 41492)
@@ -1,5 +1,12 @@
 2005-03-06  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * mini-ops.h: Add OP_F<xx>_MEMBASE opcodes.
+
+       * inssel.brg: Add MONO_EMIT_BIALU_MEMBASE macro.
+
+       * cpu-amd64.md inssel-amd64.brg mini-amd64.h mini-amd64.brg: Finish SSE2
+       support and enable it by default. Also add OP_F<xxx>_MEMBASE opcodes.
+
        * basic-float.cs: Add rounding regression test.
 
        * mini-amd64.c (INST_IGNORES_CFLAGS): Add more instructions.

Modified: trunk/mono/mono/mini/cpu-amd64.md
===================================================================
--- trunk/mono/mono/mini/cpu-amd64.md   2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/cpu-amd64.md   2005-03-06 21:28:08 UTC (rev 41492)
@@ -472,6 +472,11 @@
 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_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
+float_clt_membase: dest:i src1:f src2:b len:35
+float_clt_un_membase: dest:i src1:f src2:b len:42
 float_conv_to_u: dest:i src1:f len:46
 fmove: dest:f src1:f len:8
 call_handler: len:14

Modified: trunk/mono/mono/mini/inssel-amd64.brg
===================================================================
--- trunk/mono/mono/mini/inssel-amd64.brg       2005-03-06 21:25:22 UTC (rev 
41491)
+++ trunk/mono/mono/mini/inssel-amd64.brg       2005-03-06 21:28:08 UTC (rev 
41492)
@@ -613,29 +613,70 @@
 # either improve the local register allocator or
 # emit coarse opcodes which saves EAX for us.
 
-reg: OP_CEQ (OP_COMPARE (freg, freg)) {        
-       MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
-                        state->left->right->reg1);
-}
 
-reg: OP_CLT (OP_COMPARE (freg, freg)) {        
-       MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
-                        state->left->right->reg1);
-}
+reg: OP_CEQ (OP_COMPARE (freg, freg)),
+reg: OP_CLT (OP_COMPARE (freg, freg)),
+reg: OP_CGT (OP_COMPARE (freg, freg)),
+reg: OP_CLT_UN (OP_COMPARE (freg, freg)),
+reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
+       int opcode;
 
-reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {     
-       MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, 
state->left->left->reg1,
-                        state->left->right->reg1);
-}
+       switch (tree->opcode) {
+       case OP_CEQ:
+               opcode = OP_FCEQ;
+               break;
+       case OP_CLT:
+               opcode = OP_FCLT;
+               break;
+       case OP_CGT:
+               opcode = OP_FCGT;
+               break;
+       case OP_CLT_UN:
+               opcode = OP_FCLT_UN;
+               break;
+       case OP_CGT_UN:
+               opcode = OP_FCGT_UN;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
 
-reg: OP_CGT (OP_COMPARE (freg, freg)) {        
-       MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
+       MONO_EMIT_BIALU (s, tree, opcode, state->reg1, state->left->left->reg1,
                         state->left->right->reg1);
 }
 
-reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {     
-       MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, 
state->left->left->reg1,
-                        state->left->right->reg1);
+reg: OP_CEQ (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CLT (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CGT (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CGT_UN (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CLT_UN (OP_COMPARE (freg, CEE_LDIND_R8 (base))) {
+       MonoInst *base = state->left->right->left->tree;
+       int opcode;
+
+       switch (tree->opcode) {
+       case OP_CEQ:
+               opcode = OP_FCEQ_MEMBASE;
+               break;
+       case OP_CLT:
+               opcode = OP_FCLT_MEMBASE;
+               break;
+       case OP_CGT:
+               opcode = OP_FCGT_MEMBASE;
+               break;
+       case OP_CLT_UN:
+               opcode = OP_FCLT_UN_MEMBASE;
+               break;
+       case OP_CGT_UN:
+               opcode = OP_FCGT_UN_MEMBASE;
+               break;
+       default:
+               break;
+       }
+
+       MONO_EMIT_BIALU_MEMBASE (s, tree, opcode, state->reg1, 
state->left->left->reg1, base->inst_basereg, base->inst_offset);
+} cost {
+       MBCOND (mono_amd64_is_sse2 ());
+       return 0;
 }
 
 # fpcflags overwrites EAX, but this does not matter for statements
@@ -715,34 +756,19 @@
 reg: CEE_ADD(reg, CEE_LDIND_I4 (base)) {
        MonoInst *base = state->right->left->tree;
 
-       tree->dreg = state->reg1;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = base->inst_basereg; 
-       tree->inst_offset = base->inst_offset; 
-       tree->opcode = OP_X86_ADD_MEMBASE; 
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_ADD_MEMBASE, state->reg1, 
state->left->reg1, base->inst_basereg, base->inst_offset);
 } 
 
 reg: CEE_SUB(reg, CEE_LDIND_I4 (base)) {
        MonoInst *base = state->right->left->tree;
 
-       tree->dreg = state->reg1;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = base->inst_basereg; 
-       tree->inst_offset = base->inst_offset; 
-       tree->opcode = OP_X86_SUB_MEMBASE; 
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_SUB_MEMBASE, state->reg1, 
state->left->reg1, base->inst_basereg, base->inst_offset);
 } 
 
 reg: CEE_MUL(reg, CEE_LDIND_I4 (base)) {
        MonoInst *base = state->right->left->tree;
 
-       tree->dreg = state->reg1;
-       tree->sreg1 = state->left->reg1;
-       tree->sreg2 = base->inst_basereg; 
-       tree->inst_offset = base->inst_offset; 
-       tree->opcode = OP_X86_MUL_MEMBASE; 
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_MUL_MEMBASE, state->reg1, 
state->left->reg1, base->inst_basereg, base->inst_offset);
 } 
 
 reg: OP_LSHL (reg, reg) "0" {

Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg     2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/inssel.brg     2005-03-06 21:28:08 UTC (rev 41492)
@@ -78,6 +78,15 @@
                mono_bblock_add_inst (cfg->cbb, inst); \
        } while (0)
 
+#define MONO_EMIT_BIALU_MEMBASE(cfg,tree,op,dr,sr,basereg,offset) do { \
+                               tree->opcode = op; \
+                               tree->dreg = dr; \
+                               tree->sreg1 = sr; \
+                               tree->sreg2 = basereg; \
+                               tree->inst_offset = offset; \
+                               mono_bblock_add_inst (s->cbb, tree); \
+       } while (0)
+
 #define MONO_EMIT_LOAD_MEMBASE(cfg,inst,dr,base,offset) do { \
                 (inst)->opcode = OP_LOAD_MEMBASE; \
                 (inst)->dreg = dr; \

Modified: trunk/mono/mono/mini/mini-amd64.c
===================================================================
--- trunk/mono/mono/mini/mini-amd64.c   2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-amd64.c   2005-03-06 21:28:08 UTC (rev 41492)
@@ -30,7 +30,7 @@
 static gint thread_tls_offset = -1;
 
 /* Use SSE2 instructions for fp arithmetic */
-static gboolean use_sse2 = FALSE;
+static gboolean use_sse2 = TRUE;
 
 /* xmm15 is reserved for use by some opcodes */
 #define AMD64_CALLEE_FREGS 0xef
@@ -69,6 +69,16 @@
  *   are domain specific.   
  */
 
+/*
+ * Floating point comparison results:
+ *                  ZF PF CF
+ * A > B            0  0  0
+ * A < B            0  0  1
+ * A = B            1  0  0
+ * A > B            0  0  0
+ * UNORDERED        1  1  1
+ */
+
 #define NOT_IMPLEMENTED g_assert_not_reached ()
 
 const char*
@@ -688,6 +698,12 @@
        return opts;
 }
 
+gboolean
+mono_amd64_is_sse2 (void)
+{
+       return use_sse2;
+}
+
 static gboolean
 is_regsize_var (MonoType *t) {
        if (t->byref)
@@ -2923,7 +2939,7 @@
 emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int 
size, gboolean is_signed)
 {
        if (use_sse2) {
-               amd64_sse_cvtsd2si_reg_reg (code, dreg, sreg);
+               amd64_sse_cvttsd2si_reg_reg (code, dreg, sreg);
        }
        else {
                amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8);
@@ -4398,7 +4414,11 @@
                }
                case OP_FCOMPARE:
                        if (use_sse2) {
-                               amd64_sse_comisd_reg_reg (code, ins->sreg1, 
ins->sreg2);
+                               /* 
+                                * The two arguments are swapped because the 
fbranch instructions
+                                * depend on this for the non-sse case to work.
+                                */
+                               amd64_sse_comisd_reg_reg (code, ins->sreg2, 
ins->sreg1);
                                break;
                        }
                        if (cfg->opt & MONO_OPT_FCMOV) {
@@ -4450,7 +4470,7 @@
                                 */
                                amd64_alu_reg_reg (code, X86_XOR, ins->dreg, 
ins->dreg);
                                if (use_sse2)
-                                       amd64_sse_comisd_reg_reg (code, 
ins->sreg1, ins->sreg2);
+                                       amd64_sse_comisd_reg_reg (code, 
ins->sreg2, ins->sreg1);
                                else {
                                        amd64_fcomip (code, 1);
                                        amd64_fstp (code, 0);
@@ -4501,7 +4521,7 @@
                                guchar *unordered_check;
                                amd64_alu_reg_reg (code, X86_XOR, ins->dreg, 
ins->dreg);
                                if (use_sse2)
-                                       amd64_sse_comisd_reg_reg (code, 
ins->sreg1, ins->sreg2);
+                                       amd64_sse_comisd_reg_reg (code, 
ins->sreg2, ins->sreg1);
                                else {
                                        amd64_fcomip (code, 1);
                                        amd64_fstp (code, 0);
@@ -4539,6 +4559,57 @@
                        if (ins->dreg != AMD64_RAX) 
                                amd64_pop_reg (code, AMD64_RAX);
                        break;
+               case OP_FCLT_MEMBASE:
+               case OP_FCGT_MEMBASE:
+               case OP_FCLT_UN_MEMBASE:
+               case OP_FCGT_UN_MEMBASE:
+               case OP_FCEQ_MEMBASE: {
+                       guchar *unordered_check, *jump_to_end;
+                       int x86_cond;
+                       g_assert (use_sse2);
+
+                       amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                       amd64_sse_comisd_reg_membase (code, ins->sreg1, 
ins->sreg2, ins->inst_offset);
+
+                       switch (ins->opcode) {
+                       case OP_FCEQ_MEMBASE:
+                               x86_cond = X86_CC_EQ;
+                               break;
+                       case OP_FCLT_MEMBASE:
+                       case OP_FCLT_UN_MEMBASE:
+                               x86_cond = X86_CC_LT;
+                               break;
+                       case OP_FCGT_MEMBASE:
+                       case OP_FCGT_UN_MEMBASE:
+                               x86_cond = X86_CC_GT;
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                       }
+
+                       unordered_check = code;
+                       x86_branch8 (code, X86_CC_P, 0, FALSE);
+                       amd64_set_reg (code, x86_cond, ins->dreg, FALSE);
+
+                       switch (ins->opcode) {
+                       case OP_FCEQ_MEMBASE:
+                       case OP_FCLT_MEMBASE:
+                       case OP_FCGT_MEMBASE:
+                               amd64_patch (unordered_check, code);
+                               break;
+                       case OP_FCLT_UN_MEMBASE:
+                       case OP_FCGT_UN_MEMBASE:
+                               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;
+                       default:
+                               break;
+                       }
+                       break;
+               }
                case OP_FBEQ:
                        if (use_sse2 || (cfg->opt & MONO_OPT_FCMOV)) {
                                guchar *jump = code;

Modified: trunk/mono/mono/mini/mini-amd64.h
===================================================================
--- trunk/mono/mono/mini/mini-amd64.h   2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-amd64.h   2005-03-06 21:28:08 UTC (rev 41492)
@@ -229,6 +229,9 @@
 void
 mono_amd64_tramp_init (void);
 
+gboolean
+mono_amd64_is_sse2 (void);
+
 /* FIXME: */
 //#define MONO_ARCH_BIGMUL_INTRINS 1
 

Modified: trunk/mono/mono/mini/mini-ops.h
===================================================================
--- trunk/mono/mono/mini/mini-ops.h     2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-ops.h     2005-03-06 21:28:08 UTC (rev 41492)
@@ -338,6 +338,12 @@
 MINI_OP(OP_FCLT,   "float_clt")
 MINI_OP(OP_FCLT_UN,"float_clt_un")
 
+MINI_OP(OP_FCEQ_MEMBASE,   "float_ceq_membase")
+MINI_OP(OP_FCGT_MEMBASE,   "float_cgt_membase")
+MINI_OP(OP_FCGT_UN_MEMBASE,"float_cgt_un_membase")
+MINI_OP(OP_FCLT_MEMBASE,   "float_clt_membase")
+MINI_OP(OP_FCLT_UN_MEMBASE,"float_clt_un_membase")
+
 MINI_OP(OP_FCONV_TO_U, "float_conv_to_u")
 
 MINI_OP(OP_GROUP, "group")

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

Reply via email to