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