Author: zoltan
Date: 2007-11-20 20:52:09 -0500 (Tue, 20 Nov 2007)
New Revision: 90057

Modified:
   branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
   branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md
   branches/vargaz/mini-linear-il/mono/mono/mini/driver.c
   branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
   branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h
   branches/vargaz/mini-linear-il/mono/mono/mini/mini.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
Log:
2007-11-21  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini-ops.h: Add CMOV opcodes.

        * cpu-amd64.md mini-amd64.c: Implement CMOV opcodes.

        * local-propagation.c: Add a branch->conditional move transformation 
pass.

        * driver.c: Add CMOV to default optimizations.


Modified: branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog     2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog     2007-11-21 
01:52:09 UTC (rev 90057)
@@ -1,3 +1,13 @@
+2007-11-21  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * mini-ops.h: Add CMOV opcodes.
+
+       * cpu-amd64.md mini-amd64.c: Implement CMOV opcodes.
+
+       * local-propagation.c: Add a branch->conditional move transformation 
pass.
+
+       * driver.c: Add CMOV to default optimizations.
+       
 2007-11-20  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * mini-ops.h: Add OP_IMIN,OP_IMAX,OP_LMIN,OP_LMAX opcodes.

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md  2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md  2007-11-21 
01:52:09 UTC (rev 90057)
@@ -537,3 +537,25 @@
 long_bge_un: len:64
 long_ble: len:64
 long_ble_un: len:64
+
+cmov_ieq: dest:i src1:i src2:i len:16 clob:1
+cmov_ige: dest:i src1:i src2:i len:16 clob:1
+cmov_igt: dest:i src1:i src2:i len:16 clob:1
+cmov_ile: dest:i src1:i src2:i len:16 clob:1
+cmov_ilt: dest:i src1:i src2:i len:16 clob:1
+cmov_ine_un: dest:i src1:i src2:i len:16 clob:1
+cmov_ige_un: dest:i src1:i src2:i len:16 clob:1
+cmov_igt_un: dest:i src1:i src2:i len:16 clob:1
+cmov_ile_un: dest:i src1:i src2:i len:16 clob:1
+cmov_ilt_un: dest:i src1:i src2:i len:16 clob:1
+
+cmov_leq: dest:i src1:i src2:i len:16 clob:1
+cmov_lge: dest:i src1:i src2:i len:16 clob:1
+cmov_lgt: dest:i src1:i src2:i len:16 clob:1
+cmov_lle: dest:i src1:i src2:i len:16 clob:1
+cmov_llt: dest:i src1:i src2:i len:16 clob:1
+cmov_lne_un: dest:i src1:i src2:i len:16 clob:1
+cmov_lge_un: dest:i src1:i src2:i len:16 clob:1
+cmov_lgt_un: dest:i src1:i src2:i len:16 clob:1
+cmov_lle_un: dest:i src1:i src2:i len:16 clob:1
+cmov_llt_un: dest:i src1:i src2:i len:16 clob:1

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/driver.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/driver.c      2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/driver.c      2007-11-21 
01:52:09 UTC (rev 90057)
@@ -124,6 +124,7 @@
        MONO_OPT_INTRINS |  \
        MONO_OPT_LOOP |  \
        MONO_OPT_EXCEPTION |  \
+    MONO_OPT_CMOV |  \
        MONO_OPT_AOT)
 
 #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP)
@@ -264,6 +265,7 @@
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSA,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION,
+       MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_CMOV,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_EXCEPTION | MONO_OPT_ABCREM | 
MONO_OPT_SSAPRE,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | 
MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | 
MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_ABCREM,

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c   
2007-11-21 01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/local-propagation.c   
2007-11-21 01:52:09 UTC (rev 90057)
@@ -1542,6 +1542,35 @@
        }
 }
 
+/* FIXME: Add more instructions */
+#define INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == 
OP_ICONST) || (ins->opcode == OP_I8CONST) || (ins->opcode == OP_VZERO) || 
(ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == 
OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || 
(ins->opcode == OP_INEG) || (ins->opcode == OP_LNEG) || (ins->opcode == 
OP_ISUB))
+
+static const int int_cmov_opcodes [] = {
+       OP_CMOV_IEQ,
+       OP_CMOV_INE_UN,
+       OP_CMOV_ILE,
+       OP_CMOV_IGE,
+       OP_CMOV_ILT,
+       OP_CMOV_IGT,
+       OP_CMOV_ILE_UN,
+       OP_CMOV_IGE_UN,
+       OP_CMOV_ILT_UN,
+       OP_CMOV_IGT_UN
+};
+
+static const int long_cmov_opcodes [] = {
+       OP_CMOV_LEQ,
+       OP_CMOV_LNE_UN,
+       OP_CMOV_LLE,
+       OP_CMOV_LGE,
+       OP_CMOV_LLT,
+       OP_CMOV_LGT,
+       OP_CMOV_LLE_UN,
+       OP_CMOV_LGE_UN,
+       OP_CMOV_LLT_UN,
+       OP_CMOV_LGT_UN
+};
+
 /**
  * mono_local_deadce:
  *
@@ -1620,9 +1649,17 @@
 
                        if ((ins->opcode == OP_MOVE) && get_vreg_to_inst (cfg, 
ins->dreg)) {
                                if (ins_index + 1 < nins) {
-                                       MonoInst *def = reverse [ins_index + 1];
+                                       int j;
+                                       MonoInst *def;
                                        const char *spec2 = INS_INFO 
(def->opcode);
 
+                                       j = ins_index + 1;
+                                       def = reverse [ins_index + 1];
+                                       while ((j < nins) && (def->opcode == 
OP_NOP)) {
+                                               j ++;
+                                               def = reverse [j];
+                                       }
+
                                        /* 
                                         * Perform a limited kind of reverse 
copy propagation, i.e.
                                         * transform B <- FOO; A <- B into A <- 
FOO
@@ -1714,3 +1751,197 @@
                }
        }
 }
+
+void
+mono_branch_to_cmov (MonoCompile *cfg)
+{
+       MonoBasicBlock *bb;
+       gboolean changed = FALSE;
+
+       if (!(cfg->opt & MONO_OPT_CMOV))
+               return;
+
+       /* 
+        * This pass requires somewhat optimized IR code so it should be run 
after
+        * local cprop/deadce.
+        */
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               MonoBasicBlock *bb1, *bb2;
+
+               /* Look for the IR code generated from cond ? a : b
+                * which is:
+                * BB:
+                * b<cond> [BB1BB2]
+                * BB1:
+                * <var> <- <a>
+                * br BB3
+                * BB2:
+                * <var> <- <b>
+                * br BB3
+                */
+               if (bb->out_count != 2)
+                       continue;
+
+               bb1 = bb->out_bb [0];
+               bb2 = bb->out_bb [1];
+
+               if (bb1->in_count == 1 && bb2->in_count == 1 && bb1->out_count 
== 1 && bb2->out_count == 1 && bb1->out_bb [0] == bb2->out_bb [0]) {
+                       MonoInst *prev, *compare, *branch, *ins1, *ins2, *cmov, 
*move, *tmp;
+                       gboolean simple, ret;
+                       int dreg, tmp_reg;
+                       CompType comp_type;
+
+                       /* 
+                        * Check that bb1 and bb2 are 'simple' and both assign 
to the same
+                        * variable.
+                        */
+                       /* FIXME: Get rid of the nops earlier */
+                       ins1 = bb1->code;
+                       while (ins1 && ins1->opcode == OP_NOP)
+                               ins1 = ins1->next;
+                       ins2 = bb2->code;
+                       while (ins2 && ins2->opcode == OP_NOP)
+                               ins2 = ins2->next;
+                       if (!(ins1 && ins2 && ins1->dreg == ins2->dreg && 
ins1->dreg != -1))
+                               continue;
+
+                       simple = TRUE;
+                       for (tmp = ins1->next; tmp; tmp = tmp->next)
+                               if (!((tmp->opcode == OP_NOP) || (tmp->opcode 
== OP_BR)))
+                                       simple = FALSE;
+                                       
+                       for (tmp = ins2->next; tmp; tmp = tmp->next)
+                               if (!((tmp->opcode == OP_NOP) || (tmp->opcode 
== OP_BR)))
+                                       simple = FALSE;
+
+                       if (!simple)
+                               continue;
+
+                       /* We move ins1/ins2 before the compare so they should 
have no side effect */
+                       if (!(INS_HAS_NO_SIDE_EFFECT (ins1) && 
INS_HAS_NO_SIDE_EFFECT (ins2)))
+                               continue;
+
+                       if (bb->last_ins && bb->last_ins->opcode == OP_BR_REG)
+                               continue;
+
+                       /* Find the compare instruction */
+                       prev = NULL;
+                       compare = bb->code;
+                       g_assert (compare);
+                       while (compare->next && !MONO_IS_COND_BRANCH_OP 
(compare->next)) {
+                               prev = compare;
+                               compare = compare->next;
+                       }
+                       g_assert (compare->next && MONO_IS_COND_BRANCH_OP 
(compare->next));
+                       branch = compare->next;
+
+                       /* Moving ins1/ins2 could change the comparison */
+                       /* FIXME: */
+                       if (!((compare->sreg1 != ins1->dreg) && (compare->sreg2 
!= ins1->dreg)))
+                               continue;
+
+                       /* FIXME: */
+                       comp_type = mono_opcode_to_type (branch->opcode, 
compare->opcode);
+                       if (!((comp_type == CMP_TYPE_I) || (comp_type == 
CMP_TYPE_L)))
+                               continue;
+
+                       /* FIXME: */
+                       /* ins->type might not be set */
+                       if (INS_INFO (ins1->opcode) [MONO_INST_DEST] != 'i')
+                               continue;
+
+                       if (cfg->verbose_level > 2) {
+                               printf ("\tBranch -> CMove optimization in BB%d 
on\n", bb->block_num);
+                               printf ("\t\t"); mono_print_ins (compare);
+                               printf ("\t\t"); mono_print_ins (compare->next);
+                               printf ("\t\t"); mono_print_ins (ins1);
+                               printf ("\t\t"); mono_print_ins (ins2);
+                       }
+
+                       changed = TRUE;
+
+                       //printf ("HIT!\n");
+
+                       /* Assignments to the return register must remain at 
the end of bbs */
+                       if (cfg->ret)
+                               ret = ins1->dreg == cfg->ret->dreg;
+                       else
+                               ret = FALSE;
+
+                       tmp_reg = mono_alloc_dreg (cfg, STACK_I4);
+                       dreg = ins1->dreg;
+
+                       /* Rewrite ins1 to emit to tmp_reg */
+                       ins1->dreg = tmp_reg;
+
+                       if (ret) {
+                               dreg = mono_alloc_dreg (cfg, STACK_I4);
+                               ins2->dreg = dreg;
+                       }
+
+                       /* Remove ins1/ins2 from bb1/bb2 */
+                       bb1->code = bb1->last_ins = NULL;
+                       bb2->code = bb2->last_ins = NULL;
+
+                       /* Move ins1 and ins2 before the comparison */
+                       /* ins1 comes first to avoid ins1 overwriting an 
argument of ins2 */
+                       /* FIXME: Move this to a helper function */
+                       if (prev == NULL) {
+                               bb->code = ins1;
+                       } else {
+                               prev->next = ins1;
+                       }
+                       ins1->next = ins2;
+                       ins2->next = compare;
+
+                       /* Add cmov instruction */
+                       MONO_INST_NEW (cfg, cmov, OP_NOP);
+                       cmov->dreg = dreg;
+                       cmov->sreg1 = dreg;
+                       cmov->sreg2 = tmp_reg;
+                       switch (mono_opcode_to_type (branch->opcode, 
compare->opcode)) {
+                       case CMP_TYPE_I:
+                               cmov->opcode = int_cmov_opcodes 
[mono_opcode_to_cond (branch->opcode)];
+                               break;
+                       case CMP_TYPE_L:
+                               cmov->opcode = long_cmov_opcodes 
[mono_opcode_to_cond (branch->opcode)];
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                       }
+                       compare->next = cmov;
+                       cmov->next = branch;
+
+                       if (ret) {
+                               /* Add an extra move */
+                               MONO_INST_NEW (cfg, move, OP_MOVE);
+                               move->dreg = cfg->ret->dreg;
+                               move->sreg1 = dreg;
+                               cmov->next = move;
+                               move->next = branch;
+                       }
+
+                       /* Rewrite the branch */
+                       branch->opcode = OP_BR;
+                       branch->inst_target_bb = bb1->out_bb [0];
+                       mono_link_bblock (cfg, bb, branch->inst_target_bb);
+
+                       /* Reorder bblocks */
+                       mono_unlink_bblock (cfg, bb, bb1);
+                       mono_unlink_bblock (cfg, bb, bb2);
+                       mono_unlink_bblock (cfg, bb1, bb1->out_bb [0]);
+                       mono_unlink_bblock (cfg, bb2, bb2->out_bb [0]);
+
+                       /* Merge bb1 and its successor if possible */
+                       if ((bb->out_bb [0]->in_count == 1) && (bb->out_bb [0] 
!= cfg->bb_exit) &&
+                               (bb->region == bb->out_bb [0]->region)) {
+                               // FIXME:
+                               //mono_merge_basic_blocks (bb, bb->out_bb [0]);
+                       }
+               }
+       }
+
+       if (changed)
+               /* Merging bblocks could make some variables local */
+               mono_handle_global_vregs (cfg);
+}

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c        
2007-11-21 01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c        
2007-11-21 01:52:09 UTC (rev 90057)
@@ -1023,6 +1023,12 @@
        }
 }
 
+void
+mono_link_bblock (MonoCompile *cfg, MonoBasicBlock *from, MonoBasicBlock* to)
+{
+       link_bblock (cfg, from, to);
+}
+
 /**
  * mono_find_block_region:
  *
@@ -10696,6 +10702,7 @@
  *   remove the op_ opcodes from the cpu-..md files, clean up the cpu-..md 
files.
  * - make the cpu_ tables smaller when the usage of the cee_ opcodes is 
removed.
  * - optimize mono_regstate2_alloc_int/float.
+ * - fix the pessimistic handling of variables accessed in exception handler 
blocks.
  * - need to write a tree optimization pass, but the creation of trees is 
difficult, i.e.
  *   parts of the tree could be separated by other instructions, killing the 
tree
  *   arguments, or stores killing loads etc. Also, should we fold loads into 
other

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2007-11-21 
01:52:09 UTC (rev 90057)
@@ -3670,6 +3670,32 @@
                case OP_LBLE_UN:
                        EMIT_COND_BRANCH (ins, cc_table [mono_opcode_to_cond 
(ins->opcode)], cc_signed_table [mono_opcode_to_cond (ins->opcode)]);
                        break;
+
+               case OP_CMOV_IEQ:
+               case OP_CMOV_IGE:
+               case OP_CMOV_IGT:
+               case OP_CMOV_ILE:
+               case OP_CMOV_ILT:
+               case OP_CMOV_INE_UN:
+               case OP_CMOV_IGE_UN:
+               case OP_CMOV_IGT_UN:
+               case OP_CMOV_ILE_UN:
+               case OP_CMOV_ILT_UN:
+               case OP_CMOV_LEQ:
+               case OP_CMOV_LGE:
+               case OP_CMOV_LGT:
+               case OP_CMOV_LLE:
+               case OP_CMOV_LLT:
+               case OP_CMOV_LNE_UN:
+               case OP_CMOV_LGE_UN:
+               case OP_CMOV_LGT_UN:
+               case OP_CMOV_LLE_UN:
+               case OP_CMOV_LLT_UN:
+                       g_assert (ins->dreg == ins->sreg1);
+                       /* This needs to operate on 64 bit values */
+                       amd64_cmov_reg (code, cc_table [mono_opcode_to_cond 
(ins->opcode)], cc_signed_table [mono_opcode_to_cond (ins->opcode)], ins->dreg, 
ins->sreg2);
+                       break;
+
                case CEE_NOT:
                case OP_LNOT:
                        amd64_not_reg (code, ins->sreg1);

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c        
2007-11-21 01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-codegen.c        
2007-11-21 01:52:09 UTC (rev 90057)
@@ -1919,6 +1919,8 @@
        case OP_FCEQ:
        case OP_COND_EXC_EQ:
        case OP_COND_EXC_IEQ:
+       case OP_CMOV_IEQ:
+       case OP_CMOV_LEQ:
                return CMP_EQ;
        case CEE_BNE_UN:
        case OP_IBNE_UN:
@@ -1926,16 +1928,22 @@
        case OP_FBNE_UN:
        case OP_COND_EXC_NE_UN:
        case OP_COND_EXC_INE_UN:
+       case OP_CMOV_INE_UN:
+       case OP_CMOV_LNE_UN:
                return CMP_NE;
        case CEE_BLE:
        case OP_IBLE:
        case OP_LBLE:
        case OP_FBLE:
+       case OP_CMOV_ILE:
+       case OP_CMOV_LLE:
                return CMP_LE;
        case CEE_BGE:
        case OP_IBGE:
        case OP_LBGE:
        case OP_FBGE:
+       case OP_CMOV_IGE:
+       case OP_CMOV_LGE:
                return CMP_GE;
        case CEE_BLT:
        case OP_CLT:
@@ -1947,6 +1955,8 @@
        case OP_FCLT:
        case OP_COND_EXC_LT:
        case OP_COND_EXC_ILT:
+       case OP_CMOV_ILT:
+       case OP_CMOV_LLT:
                return CMP_LT;
        case CEE_BGT:
        case OP_CGT:
@@ -1958,6 +1968,8 @@
        case OP_FCGT:
        case OP_COND_EXC_GT:
        case OP_COND_EXC_IGT:
+       case OP_CMOV_IGT:
+       case OP_CMOV_LGT:
                return CMP_GT;
 
        case CEE_BLE_UN:
@@ -1966,11 +1978,15 @@
        case OP_FBLE_UN:
        case OP_COND_EXC_LE_UN:
        case OP_COND_EXC_ILE_UN:
+       case OP_CMOV_ILE_UN:
+       case OP_CMOV_LLE_UN:
                return CMP_LE_UN;
        case CEE_BGE_UN:
        case OP_IBGE_UN:
        case OP_LBGE_UN:
        case OP_FBGE_UN:
+       case OP_CMOV_IGE_UN:
+       case OP_CMOV_LGE_UN:
                return CMP_GE_UN;
        case CEE_BLT_UN:
        case OP_CLT_UN:
@@ -1982,6 +1998,8 @@
        case OP_FCLT_UN:
        case OP_COND_EXC_LT_UN:
        case OP_COND_EXC_ILT_UN:
+       case OP_CMOV_ILT_UN:
+       case OP_CMOV_LLT_UN:
                return CMP_LT_UN;
        case CEE_BGT_UN:
        case OP_CGT_UN:
@@ -1993,6 +2011,8 @@
        case OP_FBGT_UN:
        case OP_COND_EXC_GT_UN:
        case OP_COND_EXC_IGT_UN:
+       case OP_CMOV_IGT_UN:
+       case OP_CMOV_LGT_UN:
                return CMP_GT_UN;
        default:
                printf ("%s\n", mono_inst_name (opcode));

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h    2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h    2007-11-21 
01:52:09 UTC (rev 90057)
@@ -601,6 +601,37 @@
 MINI_OP(OP_ATOMIC_EXCHANGE_I8, "atomic_exchange_i8", IREG, IREG, IREG)
 MINI_OP(OP_MEMORY_BARRIER, "memory_barrier", NONE, NONE, NONE)
 
+/* Conditional move opcodes.
+ * Must be in the same order as the matching CEE_B... opcodes
+ * sreg2 will be assigned to dreg if the condition is true.
+ * sreg1 should be equal to dreg and models the fact the instruction doesn't 
necessary
+ * modify dreg. The sreg1==dreg condition could be violated by SSA, so the 
local
+ * register allocator or the code generator should generate a mov dreg, sreg1 
before
+ * the cmov in those cases.
+ * These opcodes operate on pointer sized values.
+ */
+MINI_OP(OP_CMOV_IEQ,    "cmov_ieq", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_IGE,    "cmov_ige", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_IGT,    "cmov_igt", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_ILE,    "cmov_ile", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_ILT,    "cmov_ilt", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_INE_UN, "cmov_ine_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_IGE_UN, "cmov_ige_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_IGT_UN, "cmov_igt_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_ILE_UN, "cmov_ile_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_ILT_UN, "cmov_ilt_un", IREG, IREG, IREG)
+
+MINI_OP(OP_CMOV_LEQ,    "cmov_leq", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LGE,    "cmov_lge", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LGT,    "cmov_lgt", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LLE,    "cmov_lle", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LLT,    "cmov_llt", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LNE_UN, "cmov_lne_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LGE_UN, "cmov_lge_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LGT_UN, "cmov_lgt_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LLE_UN, "cmov_lle_un", IREG, IREG, IREG)
+MINI_OP(OP_CMOV_LLT_UN, "cmov_llt_un", IREG, IREG, IREG)
+
 /* Arch specific opcodes */
 #if defined(__i386__) || defined(__x86_64__)
 MINI_OP(OP_X86_TEST_NULL,          "x86_test_null", NONE, NONE, NONE)

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini.c        2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini.c        2007-11-21 
01:52:09 UTC (rev 90057)
@@ -11918,6 +11918,7 @@
                /* This must be done _before_ global reg alloc and _after_ 
decompose */
                mono_handle_global_vregs (cfg);
                mono_local_deadce (cfg);
+               mono_branch_to_cmov (cfg);
        }
 
        /* after method_to_ir */

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini.h        2007-11-21 
01:48:11 UTC (rev 90056)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini.h        2007-11-21 
01:52:09 UTC (rev 90057)
@@ -1011,6 +1011,7 @@
 guint32   mono_alloc_freg                   (MonoCompile *cfg) MONO_INTERNAL;
 guint32   mono_alloc_preg                   (MonoCompile *cfg) MONO_INTERNAL;
 guint32   mono_alloc_dreg                   (MonoCompile *cfg, MonoStackType 
stack_type) MONO_INTERNAL;
+void      mono_link_bblock                  (MonoCompile *cfg, MonoBasicBlock 
*from, MonoBasicBlock* to) MONO_INTERNAL;
 void      mono_unlink_bblock                (MonoCompile *cfg, MonoBasicBlock 
*from, MonoBasicBlock* to) MONO_INTERNAL;
 void      mono_merge_basic_blocks           (MonoBasicBlock *bb, 
MonoBasicBlock *bbn) MONO_INTERNAL;
 void      mono_blockset_print               (MonoCompile *cfg, MonoBitSet 
*set, const char *name, guint idom) MONO_INTERNAL;
@@ -1142,11 +1143,12 @@
 CompRelation      mono_opcode_to_cond (int opcode) MONO_INTERNAL;
 CompType          mono_opcode_to_type (int opcode, int cmp_opcode) 
MONO_INTERNAL;
 
-void              mono_decompose_long_opts (MonoCompile *cfg);
-void              mono_decompose_vtype_opts (MonoCompile *cfg);
-void              mono_decompose_array_access_opts (MonoCompile *cfg);
-void              mono_handle_global_vregs (MonoCompile *cfg);
-void              mono_spill_global_vars (MonoCompile *cfg);
+void              mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_decompose_array_access_opts (MonoCompile *cfg) 
MONO_INTERNAL;
+void              mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_spill_global_vars (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_branch_to_cmov (MonoCompile *cfg) MONO_INTERNAL;
 
 /* methods that must be provided by the arch-specific port */
 void      mono_arch_init                        (void) MONO_INTERNAL;

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

Reply via email to