Author: zoltan
Date: 2005-03-21 13:12:45 -0500 (Mon, 21 Mar 2005)
New Revision: 42052

Modified:
   branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/ChangeLog
   branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/cpu-amd64.md
   branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-amd64.c
   branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-ops.h
Log:
2005-03-21  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini-amd64.c (mono_arch_local_regalloc): Split the arch-dependent
        and the arch independent parts of the allocator.

        * mini-ops.h cpu-amd64.md mini-amd64.c: Implement a lowering pass to
        decompose some opcodes into simpler ones.


Modified: branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/ChangeLog
===================================================================
--- branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/ChangeLog     
2005-03-21 18:11:45 UTC (rev 42051)
+++ branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/ChangeLog     
2005-03-21 18:12:45 UTC (rev 42052)
@@ -1,3 +1,11 @@
+2005-03-21  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * mini-amd64.c (mono_arch_local_regalloc): Split the arch-dependent
+       and the arch independent parts of the allocator.
+
+       * mini-ops.h cpu-amd64.md mini-amd64.c: Implement a lowering pass to
+       decompose some opcodes into simpler ones.
+
 2005-03-20  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * mini-x86.c (emit_tls_get): Move tls handling into a separate helper 
function.

Modified: branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/cpu-amd64.md
===================================================================
--- branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/cpu-amd64.md  
2005-03-21 18:11:45 UTC (rev 42051)
+++ branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/cpu-amd64.md  
2005-03-21 18:12:45 UTC (rev 42052)
@@ -280,7 +280,7 @@
 reg:
 regoffset:
 label:
-store_membase_imm: dest:b len:15
+store_membase_imm: dest:b len:13
 store_membase_reg: dest:b src1:i len:9
 storei8_membase_reg: dest:b src1:i len:9
 storei1_membase_imm: dest:b len:11
@@ -289,7 +289,7 @@
 storei2_membase_reg: dest:b src1:i len:9
 storei4_membase_imm: dest:b len:13
 storei4_membase_reg: dest:b src1:i len:9
-storei8_membase_imm: dest:b len:18
+storei8_membase_imm: dest:b len:13
 storer4_membase_reg: dest:b src1:f len:14
 storer8_membase_reg: dest:b src1:f len:9
 load_membase: dest:i src1:b len:15
@@ -299,11 +299,12 @@
 loadu2_membase: dest:i src1:b len:9
 loadi4_membase: dest:i src1:b len:9
 loadu4_membase: dest:i src1:b len:9
-loadi8_membase: dest:i src1:b len:18
+loadi8_membase: dest:i src1:b len:10
 loadr4_membase: dest:f src1:b len:16
 loadr8_membase: dest:f src1:b len:16
 loadr8_spill_membase: src1:b len:9
 loadu4_mem: dest:i len:10
+amd64_loadi8_memindex: dest:i src1:i src2:i len:10
 move: dest:i src1:i len:4
 setreg: dest:i src1:i len:4
 add_imm: dest:i src1:i len:8 clob:1

Modified: branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-amd64.c
===================================================================
--- branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-amd64.c  
2005-03-21 18:11:45 UTC (rev 42051)
+++ branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-amd64.c  
2005-03-21 18:12:45 UTC (rev 42052)
@@ -1543,6 +1543,114 @@
        bb->last_ins = last_ins;
 }
 
+static void
+insert_after_ins (MonoBasicBlock *bb, MonoInst *ins, MonoInst *to_insert)
+{
+       if (ins == NULL) {
+               ins = bb->code;
+               bb->code = to_insert;
+               to_insert->next = ins;
+       }
+       else {
+               to_insert->next = ins->next;
+               ins->next = to_insert;
+       }
+}
+
+#define NEW_INS(cfg,dest,op) do {      \
+               (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof 
(MonoInst));       \
+               (dest)->opcode = (op);  \
+        insert_after_ins (bb, last_ins, (dest)); \
+       } while (0)
+
+/*
+ * mono_arch_lowering_pass:
+ *
+ *  Converts complex opcodes into simpler ones so that each IR instruction
+ * corresponds to one machine instruction.
+ */
+static void
+mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
+{
+       MonoInst *ins, *temp, *last_ins = NULL;
+       ins = bb->code;
+
+       if (bb->max_ireg > cfg->rs->next_vireg)
+               cfg->rs->next_vireg = bb->max_ireg;
+       if (bb->max_freg > cfg->rs->next_vfreg)
+               cfg->rs->next_vfreg = bb->max_freg;
+
+       /*
+        * FIXME: Need to add more instructions, but the current machine 
+        * description can't model some parts of the composite instructions like
+        * cdq.
+        */
+       while (ins) {
+               switch (ins->opcode) {
+               case OP_DIV_IMM:
+               case OP_REM_IMM:
+               case OP_IDIV_IMM:
+               case OP_IREM_IMM:
+                       NEW_INS (cfg, temp, OP_ICONST);
+                       temp->inst_c0 = ins->inst_imm;
+                       temp->dreg = mono_regstate_next_int (cfg->rs);
+                       switch (ins->opcode) {
+                       case OP_DIV_IMM:
+                               ins->opcode = OP_LDIV;
+                               break;
+                       case OP_REM_IMM:
+                               ins->opcode = OP_LREM;
+                               break;
+                       case OP_IDIV_IMM:
+                               ins->opcode = OP_IDIV;
+                               break;
+                       case OP_IREM_IMM:
+                               ins->opcode = OP_IREM;
+                               break;
+                       }
+                       ins->sreg2 = temp->dreg;
+                       break;
+               case OP_COMPARE_IMM:
+                       if (!amd64_is_imm32 (ins->inst_imm)) {
+                               NEW_INS (cfg, temp, OP_I8CONST);
+                               temp->inst_c0 = ins->inst_imm;
+                               temp->dreg = mono_regstate_next_int (cfg->rs);
+                               ins->opcode = OP_COMPARE;
+                               ins->sreg2 = temp->dreg;
+                       }
+                       break;
+               case OP_LOAD_MEMBASE:
+               case OP_LOADI8_MEMBASE:
+                       if (!amd64_is_imm32 (ins->inst_offset)) {
+                               NEW_INS (cfg, temp, OP_I8CONST);
+                               temp->inst_c0 = ins->inst_offset;
+                               temp->dreg = mono_regstate_next_int (cfg->rs);
+                               ins->opcode = OP_AMD64_LOADI8_MEMINDEX;
+                               ins->inst_indexreg = temp->dreg;
+                       }
+                       break;
+               case OP_STORE_MEMBASE_IMM:
+               case OP_STOREI8_MEMBASE_IMM:
+                       if (!amd64_is_imm32 (ins->inst_imm)) {
+                               NEW_INS (cfg, temp, OP_I8CONST);
+                               temp->inst_c0 = ins->inst_imm;
+                               temp->dreg = mono_regstate_next_int (cfg->rs);
+                               ins->opcode = OP_STOREI8_MEMBASE_REG;
+                               ins->sreg2 = temp->dreg;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               last_ins = ins;
+               ins = ins->next;
+       }
+       bb->last_ins = last_ins;
+
+       bb->max_ireg = cfg->rs->next_vireg;
+       bb->max_freg = cfg->rs->next_vfreg;
+}
+
 static const int 
 branch_cc_table [] = {
        X86_CC_EQ, X86_CC_GE, X86_CC_GT, X86_CC_LE, X86_CC_LT,
@@ -2102,13 +2210,15 @@
        RegTrack *reginfo1, *reginfo2, *reginfod;
        InstList *tmp, *reversed = NULL;
        const char *spec;
-       guint32 src1_mask, src2_mask, dest_mask;
        GList *fspill_list = NULL;
        gboolean fp;
        int fspill = 0;
 
        if (!bb->code)
                return;
+
+       mono_arch_lowering_pass (cfg, bb);
+
        rs->next_vireg = bb->max_ireg;
        rs->next_vfreg = bb->max_freg;
        mono_regstate_assign (rs);
@@ -2293,176 +2403,50 @@
        DEBUG (print_regtrack (reginfof, rs->next_vfreg));
        tmp = reversed;
        while (tmp) {
-               int prev_dreg, prev_sreg1, prev_sreg2, clob_dreg, sreg1_fixed;
-               dest_mask = src1_mask = src2_mask = AMD64_CALLEE_REGS;
+               int prev_dreg, prev_sreg1, prev_sreg2, clob_dreg;
+               int dest_dreg, dest_sreg1, dest_sreg2, clob_reg;
+               guint32 dreg_mask, sreg1_mask, sreg2_mask;
                --i;
                ins = tmp->data;
                spec = ins_spec [ins->opcode];
                prev_dreg = -1;
                clob_dreg = -1;
-               sreg1_fixed = -1;
+               clob_reg = -1;
+               dest_dreg = -1;
+               dest_sreg1 = -1;
+               dest_sreg2 = -1;
+               dreg_mask = dreg_is_fp (ins) ? MONO_ARCH_CALLEE_FREGS : 
MONO_ARCH_CALLEE_REGS;
+               sreg1_mask = sreg1_is_fp (ins) ? MONO_ARCH_CALLEE_FREGS : 
MONO_ARCH_CALLEE_REGS;
+               sreg2_mask = sreg2_is_fp (ins) ? MONO_ARCH_CALLEE_FREGS : 
MONO_ARCH_CALLEE_REGS;
+
                DEBUG (g_print ("processing:"));
                DEBUG (print_ins (i, ins));
+
+               /*
+                * ARCH DEPENDENT CODE
+                */
                if (spec [MONO_INST_CLOB] == 's') {
                        /*
                         * Shift opcodes, SREG2 must be RCX
                         */
-                       if (rs->ifree_mask & (1 << AMD64_RCX)) {
-                               if (ins->sreg2 < MONO_MAX_IREGS) {
-                                       /* Argument already in hard reg, need 
to copy */
-                                       MonoInst *copy = create_copy_ins (cfg, 
AMD64_RCX, ins->sreg2, NULL, FALSE);
-                                       insert_before_ins (ins, tmp, copy);
-                               }
-                               else {
-                                       DEBUG (g_print ("\tshortcut assignment 
of R%d to ECX\n", ins->sreg2));
-                                       assign_ireg (rs, ins->sreg2, AMD64_RCX);
-                               }
-                       } else {
-                               int need_ecx_spill = TRUE;
-                               /* 
-                                * we first check if src1/dreg is already 
assigned a register
-                                * and then we force a spill of the var 
assigned to ECX.
-                                */
-                               /* the destination register can't be ECX */
-                               dest_mask &= ~ (1 << AMD64_RCX);
-                               src1_mask &= ~ (1 << AMD64_RCX);
-                               val = rs->iassign [ins->dreg];
-                               /* 
-                                * the destination register is already assigned 
to ECX:
-                                * we need to allocate another register for it 
and then
-                                * copy from this to ECX.
-                                */
-                               if (val == AMD64_RCX && ins->dreg != 
ins->sreg2) {
-                                       int new_dest;
-                                       new_dest = alloc_int_reg (cfg, tmp, 
ins, dest_mask, ins->dreg, reginfo [ins->dreg].flags);
-                                       g_assert (new_dest >= 0);
-                                       DEBUG (g_print ("\tclob:s changing dreg 
R%d to %s from ECX\n", ins->dreg, mono_arch_regname (new_dest)));
-
-                                       rs->isymbolic [new_dest] = ins->dreg;
-                                       rs->iassign [ins->dreg] = new_dest;
-                                       clob_dreg = ins->dreg;
-                                       ins->dreg = new_dest;
-                                       create_copy_ins (cfg, AMD64_RCX, 
new_dest, ins, FALSE);
-                                       need_ecx_spill = FALSE;
-                                       /*DEBUG (g_print ("\tforced spill of 
R%d\n", ins->dreg));
-                                       val = get_register_force_spilling (cfg, 
tmp, ins, ins->dreg);
-                                       rs->iassign [ins->dreg] = val;
-                                       rs->isymbolic [val] = prev_dreg;
-                                       ins->dreg = val;*/
-                               }
-                               if (is_global_ireg (ins->sreg2)) {
-                                       MonoInst *copy = create_copy_ins (cfg, 
AMD64_RCX, ins->sreg2, NULL, FALSE);
-                                       insert_before_ins (ins, tmp, copy);
-                               }
-                               else {
-                                       val = rs->iassign [ins->sreg2];
-                                       if (val >= 0 && val != AMD64_RCX) {
-                                               MonoInst *move = 
create_copy_ins (cfg, AMD64_RCX, val, NULL, FALSE);
-                                               DEBUG (g_print ("\tmoved arg 
from R%d (%d) to ECX\n", val, ins->sreg2));
-                                               move->next = ins;
-                                               g_assert_not_reached ();
-                                               /* FIXME: where is move 
connected to the instruction list? */
-                                               //tmp->prev->data->next = move;
-                                       }
-                                       else {
-                                               if (val == AMD64_RCX)
-                                               need_ecx_spill = FALSE;
-                                       }
-                               }
-                               if (need_ecx_spill && !(rs->ifree_mask & (1 << 
AMD64_RCX))) {
-                                       DEBUG (g_print ("\tforced spill of 
R%d\n", rs->isymbolic [AMD64_RCX]));
-                                       get_register_force_spilling (cfg, tmp, 
ins, rs->isymbolic [AMD64_RCX], FALSE);
-                                       mono_regstate_free_int (rs, AMD64_RCX);
-                               }
-                               if (!is_global_ireg (ins->sreg2))
-                                       /* force-set sreg2 */
-                                       assign_ireg (rs, ins->sreg2, AMD64_RCX);
-                       }
-                       ins->sreg2 = AMD64_RCX;
-               } else if (spec [MONO_INST_CLOB] == 'd') { 
-                       /*
-                        * DIVISION/REMAINER
-                        */
-                       int dest_reg = AMD64_RAX;
-                       int clob_reg = AMD64_RDX;
-                       if (spec [MONO_INST_DEST] == 'd') {
-                               dest_reg = AMD64_RDX; /* reminder */
+                       dest_sreg2 = AMD64_RCX;
+               }
+               else if (spec [MONO_INST_CLOB] == 'd') {
+                       if (spec [MONO_INST_DEST] == 'd')
                                clob_reg = AMD64_RAX;
-                       }
-                       if (is_global_ireg (ins->dreg))
-                               val = ins->dreg;
                        else
-                               val = rs->iassign [ins->dreg];
-                       if (0 && val >= 0 && val != dest_reg && 
!(rs->ifree_mask & (1 << dest_reg))) {
-                               DEBUG (g_print ("\tforced spill of R%d\n", 
rs->isymbolic [dest_reg]));
-                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [dest_reg], FALSE);
-                               mono_regstate_free_int (rs, dest_reg);
-                       }
-                       if (val < 0) {
-                               if (val < -1) {
-                                       /* the register gets spilled after this 
inst */
-                                       int spill = -val -1;
-                                       dest_mask = 1 << clob_reg;
-                                       prev_dreg = ins->dreg;
-                                       val = mono_regstate_alloc_int (rs, 
dest_mask);
-                                       if (val < 0)
-                                               val = get_register_spilling 
(cfg, tmp, ins, dest_mask, ins->dreg, FALSE);
-                                       rs->iassign [ins->dreg] = val;
-                                       if (spill)
-                                               create_spilled_store (cfg, 
spill, val, prev_dreg, ins, FALSE);
-                                       DEBUG (g_print ("\tassigned dreg %s to 
dest R%d\n", mono_arch_regname (val), ins->dreg));
-                                       rs->isymbolic [val] = prev_dreg;
-                                       ins->dreg = val;
-                               } else {
-                                       DEBUG (g_print ("\tshortcut assignment 
of R%d to %s\n", ins->dreg, mono_arch_regname (dest_reg)));
-                                       prev_dreg = ins->dreg;
-                                       assign_ireg (rs, ins->dreg, dest_reg);
-                                       ins->dreg = dest_reg;
-                                       val = dest_reg;
-                               }
-                       }
+                               clob_reg = AMD64_RDX;
 
-                       //DEBUG (g_print ("dest reg in div assigned: %s\n", 
mono_arch_regname (val)));
-                       if (val != dest_reg) { /* force a copy */
-                               create_copy_ins (cfg, val, dest_reg, ins, 
FALSE);
-                               if (!(rs->ifree_mask & (1 << dest_reg)) && 
rs->isymbolic [dest_reg] >= MONO_MAX_IREGS) {
-                                       DEBUG (g_print ("\tforced spill of 
R%d\n", rs->isymbolic [dest_reg]));
-                                       get_register_force_spilling (cfg, tmp, 
ins, rs->isymbolic [dest_reg], FALSE);
-                                       mono_regstate_free_int (rs, dest_reg);
-                               }
-                       }
-                       if (!(rs->ifree_mask & (1 << clob_reg)) && (clob_reg != 
val) && (rs->isymbolic [clob_reg] >= MONO_MAX_IREGS)) {
-                               DEBUG (g_print ("\tforced spill of clobbered 
reg R%d\n", rs->isymbolic [clob_reg]));
-                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [clob_reg], FALSE);
-                               mono_regstate_free_int (rs, clob_reg);
-                       }
-                       src1_mask = 1 << AMD64_RAX;
-                       src2_mask = 1 << AMD64_RCX;
+                       /* RDX is set to 0 by the opcode implementation */
+                       sreg2_mask &= ~ (1 << AMD64_RDX);
                }
-               if (spec [MONO_INST_DEST] == 'l') {
-                       int hreg;
-                       val = rs->iassign [ins->dreg];
-                       /* check special case when dreg have been moved from 
ecx (clob shift) */
-                       if (spec [MONO_INST_CLOB] == 's' && clob_dreg != -1)
-                               hreg = clob_dreg + 1;
-                       else
-                               hreg = ins->dreg + 1;
+               if (spec [MONO_INST_DEST] == 'a')
+                       dest_dreg = AMD64_RAX;
+               if (spec [MONO_INST_DEST] == 'd')
+                       dest_dreg = AMD64_RDX;
+               if (spec [MONO_INST_SRC1] == 'a')
+                       dest_sreg1 = AMD64_RAX;
 
-                       /* base prev_dreg on fixed hreg, handle clob case */
-                       val = hreg - 1;
-
-                       if (val != rs->isymbolic [AMD64_RAX] && 
!(rs->ifree_mask & (1 << AMD64_RAX))) {
-                               DEBUG (g_print ("\t(long-low) forced spill of 
R%d\n", rs->isymbolic [AMD64_RAX]));
-                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [AMD64_RAX], FALSE);
-                               mono_regstate_free_int (rs, AMD64_RAX);
-                       }
-                       if (hreg != rs->isymbolic [AMD64_RDX] && 
!(rs->ifree_mask & (1 << AMD64_RDX))) {
-                               DEBUG (g_print ("\t(long-high) forced spill of 
R%d\n", rs->isymbolic [AMD64_RDX]));
-                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [AMD64_RDX], FALSE);
-                               mono_regstate_free_int (rs, AMD64_RDX);
-                       }
-               }
-
                /*
                 * TRACK FP STACK
                 */
@@ -2532,80 +2516,89 @@
                }
 
                /*
-                * TRACK DREG
+                * TRACK FIXED SREG2
                 */
-               fp = dreg_is_fp (ins);
-               if (spec [MONO_INST_DEST] == 'L') {
-                       int hreg;
-                       val = rs->iassign [ins->dreg];
-                       /* check special case when dreg have been moved from 
ecx (clob shift) */
-                       if (spec [MONO_INST_CLOB] == 's' && clob_dreg != -1)
-                               hreg = clob_dreg + 1;
-                       else
-                               hreg = ins->dreg + 1;
+               if (dest_sreg2 != -1) {
+                       if (rs->ifree_mask & (1 << dest_sreg2)) {
+                               if (is_global_ireg (ins->sreg2)) {
+                                       /* Argument already in hard reg, need 
to copy */
+                                       MonoInst *copy = create_copy_ins (cfg, 
dest_sreg2, ins->sreg2, NULL, FALSE);
+                                       insert_before_ins (ins, tmp, copy);
+                               }
+                               else {
+                                       DEBUG (g_print ("\tshortcut assignment 
of R%d to %s\n", ins->sreg2, mono_arch_regname (dest_sreg2)));
+                                       assign_ireg (rs, ins->sreg2, 
dest_sreg2);
+                               }
+                       } else {
+                               int need_spill = TRUE;
 
-                       /* base prev_dreg on fixed hreg, handle clob case */
-                       prev_dreg = hreg - 1;
+                               dreg_mask &= ~ (1 << dest_sreg2);
+                               sreg1_mask &= ~ (1 << dest_sreg2);
 
-                       if (val < 0) {
-                               int spill = 0;
-                               if (val < -1) {
-                                       /* the register gets spilled after this 
inst */
-                                       spill = -val -1;
+                               /* 
+                                * First check if dreg is assigned to 
dest_sreg2, since we
+                                * can't spill a dreg.
+                                */
+                               val = rs->iassign [ins->dreg];
+                               if (val == dest_sreg2 && ins->dreg != 
ins->sreg2) {
+                                       /* 
+                                        * the destination register is already 
assigned to 
+                                        * dest_sreg2: we need to allocate 
another register for it 
+                                        * and then copy from this to 
dest_sreg2.
+                                        */
+                                       int new_dest;
+                                       new_dest = alloc_int_reg (cfg, tmp, 
ins, dreg_mask, ins->dreg, reginfo [ins->dreg].flags);
+                                       g_assert (new_dest >= 0);
+                                       DEBUG (g_print ("\tchanging dreg R%d to 
%s from %s\n", ins->dreg, mono_arch_regname (new_dest), mono_arch_regname 
(dest_sreg2)));
+
+                                       assign_ireg (rs, ins->dreg, new_dest);
+                                       clob_dreg = ins->dreg;
+                                       ins->dreg = new_dest;
+                                       create_copy_ins (cfg, dest_sreg2, 
new_dest, ins, FALSE);
+                                       need_spill = FALSE;
                                }
-                               val = alloc_int_reg (cfg, tmp, ins, dest_mask, 
ins->dreg, reginfo [ins->dreg].flags);
-                               rs->iassign [ins->dreg] = val;
-                               if (spill)
-                                       create_spilled_store (cfg, spill, val, 
prev_dreg, ins, FALSE);
-                       }
 
-                       DEBUG (g_print ("\tassigned dreg (long) %s to dest 
R%d\n", mono_arch_regname (val), hreg - 1));
- 
-                       rs->isymbolic [val] = hreg - 1;
-                       ins->dreg = val;
-                       
-                       val = rs->iassign [hreg];
-                       if (val < 0) {
-                               int spill = 0;
-                               if (val < -1) {
-                                       /* the register gets spilled after this 
inst */
-                                       spill = -val -1;
+                               if (is_global_ireg (ins->sreg2)) {
+                                       MonoInst *copy = create_copy_ins (cfg, 
dest_sreg2, ins->sreg2, NULL, FALSE);
+                                       insert_before_ins (ins, tmp, copy);
                                }
-                               val = alloc_int_reg (cfg, tmp, ins, dest_mask, 
hreg, reginfo [hreg].flags);
-                               rs->iassign [hreg] = val;
-                               if (spill)
-                                       create_spilled_store (cfg, spill, val, 
hreg, ins, FALSE);
-                       }
+                               else {
+                                       val = rs->iassign [ins->sreg2];
+                                       if (val == dest_sreg2) {
+                                               /* sreg2 is already assigned to 
the correct register */
+                                               need_spill = FALSE;
+                                       }
+                                       else if ((val >= 0) || (val < -1)) {
+                                               /* FIXME: sreg2 already 
assigned to another register */
+                                               g_assert_not_reached ();
+                                       }
+                               }
 
-                       DEBUG (g_print ("\tassigned hreg (long-high) %s to dest 
R%d\n", mono_arch_regname (val), hreg));
-                       rs->isymbolic [val] = hreg;
-                       /* save reg allocating into unused */
-                       ins->unused = val;
+                               if (need_spill) {
+                                       DEBUG (g_print ("\tforced spill of 
R%d\n", rs->isymbolic [dest_sreg2]));
+                                       get_register_force_spilling (cfg, tmp, 
ins, rs->isymbolic [dest_sreg2], FALSE);
+                                       mono_regstate_free_int (rs, dest_sreg2);
+                               }
 
-                       /* check if we can free our long reg */
-                       if (reg_is_freeable (val, FALSE) && hreg >= 0 && 
reginfo [hreg].born_in >= i) {
-                               DEBUG (g_print ("\tfreeable %s (R%d) (born in 
%d)\n", mono_arch_regname (val), hreg, reginfo [hreg].born_in));
-                               mono_regstate_free_int (rs, val);
+                               if (!is_global_ireg (ins->sreg2))
+                                       /* force-set sreg2 */
+                                       assign_ireg (rs, ins->sreg2, 
dest_sreg2);
                        }
+                       ins->sreg2 = dest_sreg2;
                }
-               else if ((!fp || (fp && use_sse2)) && (is_soft_reg (ins->dreg, 
fp))) {
-                       int hreg;
-                       val = rassign (cfg, ins->dreg, fp);
 
-                       if (spec [MONO_INST_DEST] == 'a')
-                               dest_mask = (1 << AMD64_RAX);
+               /*
+                * TRACK DREG
+                */
+               fp = dreg_is_fp (ins);
+               if (spec [MONO_INST_DEST] && (!fp || (fp && use_sse2)) && 
is_soft_reg (ins->dreg, fp))
+                       prev_dreg = ins->dreg;
 
-                       if (spec [MONO_INST_DEST] == 'l') {
-                               /* check special case when dreg have been moved 
from ecx (clob shift) */
-                               if (spec [MONO_INST_CLOB] == 's' && clob_dreg 
!= -1)
-                                       hreg = clob_dreg + 1;
-                               else
-                                       hreg = ins->dreg + 1;
+               if ((!fp || (fp && use_sse2)) && (is_soft_reg (ins->dreg, fp))) 
{
+                       if (dest_dreg != -1)
+                               dreg_mask = (1 << dest_dreg);
 
-                               /* base prev_dreg on fixed hreg, handle clob 
case */
-                               prev_dreg = hreg - 1;
-                       } else
-                               prev_dreg = ins->dreg;
+                       val = rassign (cfg, ins->dreg, fp);
 
                        if (val < 0) {
                                int spill = 0;
@@ -2613,83 +2606,66 @@
                                        /* the register gets spilled after this 
inst */
                                        spill = -val -1;
                                }
-                               val = alloc_reg (cfg, tmp, ins, fp ? 
MONO_ARCH_CALLEE_FREGS : dest_mask, ins->dreg, reginfo [ins->dreg].flags, fp);
+                               val = alloc_reg (cfg, tmp, ins, dreg_mask, 
ins->dreg, reginfo [ins->dreg].flags, fp);
                                assign_reg (rs, ins->dreg, val, fp);
                                if (spill)
                                        create_spilled_store (cfg, spill, val, 
prev_dreg, ins, fp);
                        }
                        DEBUG (g_print ("\tassigned dreg %s to dest R%d\n", 
mono_amd64_regname (val, fp), ins->dreg));
                        ins->dreg = val;
+               }
 
-                       /* handle cases where lreg needs to be eax:edx */
-                       if (spec [MONO_INST_DEST] == 'l') {
-                               /* check special case when dreg have been moved 
from ecx (clob shift) */
-                               int hreg = prev_dreg + 1;
-                               val = rs->iassign [hreg];
-                               if (val < 0) {
-                                       int spill = 0;
-                                       if (val < -1) {
-                                               /* the register gets spilled 
after this inst */
-                                               spill = -val -1;
-                                       }
-                                       val = alloc_int_reg (cfg, tmp, ins, 
dest_mask, hreg, reginfo [hreg].flags);
-                                       rs->iassign [hreg] = val;
-                                       if (spill)
-                                               create_spilled_store (cfg, 
spill, val, hreg, ins, fp);
-                               }
-                               DEBUG (g_print ("\tassigned hreg %s to dest 
R%d\n", mono_amd64_regname (val,fp), hreg));
-                               rs->isymbolic [val] = hreg;
-                               if (ins->dreg == AMD64_RAX) {
-                                       if (val != AMD64_RDX)
-                                               create_copy_ins (cfg, val, 
AMD64_RDX, ins, FALSE);
-                               } else if (ins->dreg == AMD64_RDX) {
-                                       if (val == AMD64_RAX) {
-                                               /* swap */
-                                               g_assert_not_reached ();
-                                       } else {
-                                               /* two forced copies */
-                                               create_copy_ins (cfg, val, 
AMD64_RDX, ins, FALSE);
-                                               create_copy_ins (cfg, 
ins->dreg, AMD64_RAX, ins, FALSE);
-                                       }
-                               } else {
-                                       if (val == AMD64_RDX) {
-                                               create_copy_ins (cfg, 
ins->dreg, AMD64_RAX, ins, FALSE);
-                                       } else {
-                                               /* two forced copies */
-                                               create_copy_ins (cfg, val, 
AMD64_RDX, ins, FALSE);
-                                               create_copy_ins (cfg, 
ins->dreg, AMD64_RAX, ins, FALSE);
-                                       }
-                               }
-                               if (reg_is_freeable (val, FALSE) && hreg >= 0 
&& reginfo [hreg].born_in >= i) {
-                                       DEBUG (g_print ("\tfreeable %s 
(R%d)\n", mono_arch_regname (val), hreg));
-                                       mono_regstate_free_int (rs, val);
-                               }
-                       } else if (spec [MONO_INST_DEST] == 'a' && ins->dreg != 
AMD64_RAX && spec [MONO_INST_CLOB] != 'd') {
-                               /* this instruction only outputs to EAX, need 
to copy */
-                               create_copy_ins (cfg, ins->dreg, AMD64_RAX, 
ins, FALSE);
-                       } else if (spec [MONO_INST_DEST] == 'd' && ins->dreg != 
AMD64_RDX && spec [MONO_INST_CLOB] != 'd') {
-                               create_copy_ins (cfg, ins->dreg, AMD64_RDX, 
ins, FALSE);
+               if ((!fp || (fp && use_sse2)) && prev_dreg >= 0 && is_soft_reg 
(prev_dreg, fp) && (fp ? reginfof : reginfo) [prev_dreg].born_in >= i) {
+                       /* 
+                        * In theory, we could free up the hreg even if the 
vreg is alive,
+                        * but branches inside bblocks force us to assign the 
same hreg
+                        * to a vreg every time it is encountered.
+                        */
+                       int dreg = rassign (cfg, prev_dreg, fp);
+                       g_assert (dreg >= 0);
+                       DEBUG (g_print ("\tfreeable %s (R%d) (born in %d)\n", 
mono_amd64_regname (dreg, fp), prev_dreg, (fp ? reginfof : reginfo) 
[prev_dreg].born_in));
+                       if (fp)
+                               mono_regstate_free_float (rs, dreg);
+                       else
+                               mono_regstate_free_int (rs, dreg);
+               }
+
+               if ((dest_dreg != -1) && (ins->dreg != dest_dreg)) {
+                       /* this instruction only outputs to dest_dreg, need to 
copy */
+                       if (!(rs->ifree_mask & (1 << dest_dreg)) && 
rs->isymbolic [dest_dreg] >= MONO_MAX_IREGS) {
+                               DEBUG (g_print ("\tforced spill of R%d\n", 
rs->isymbolic [dest_dreg]));
+                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [dest_dreg], FALSE);
+                               mono_regstate_free_int (rs, dest_dreg);
                        }
+
+                       create_copy_ins (cfg, ins->dreg, dest_dreg, ins, fp);
+                       ins->dreg = dest_dreg;
                }
 
-               if (use_sse2 && spec [MONO_INST_DEST] == 'f' && reg_is_freeable 
(ins->dreg, TRUE) && prev_dreg >= 0 && reginfof [prev_dreg].born_in >= i) {
-                       DEBUG (g_print ("\tfreeable %s (R%d) (born in %d)\n", 
mono_arch_fregname (ins->dreg), prev_dreg, reginfof [prev_dreg].born_in));
-                       mono_regstate_free_float (rs, ins->dreg);
+               /*
+                * TRACK CLOBBERING
+                */
+               if ((clob_reg != -1) && (!(rs->ifree_mask & (1 << clob_reg)))) {
+                       DEBUG (g_print ("\tforced spill of clobbered reg 
R%d\n", rs->isymbolic [clob_reg]));
+                       get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [clob_reg], FALSE);
+                       mono_regstate_free_int (rs, clob_reg);
                }
-               if (spec [MONO_INST_DEST] != 'f' && reg_is_freeable (ins->dreg, 
FALSE) && prev_dreg >= 0 && reginfo [prev_dreg].born_in >= i) {
-                       DEBUG (g_print ("\tfreeable %s (R%d) (born in %d)\n", 
mono_arch_regname (ins->dreg), prev_dreg, reginfo [prev_dreg].born_in));
-                       mono_regstate_free_int (rs, ins->dreg);
-               }
 
                if (spec [MONO_INST_CLOB] == 'c') {
                        int j, s, dreg;
-                       MonoCallInst *call = (MonoCallInst*)ins;
-                       GSList *list;
                        guint32 clob_mask;
 
                        clob_mask = AMD64_CALLEE_REGS;
-                       dreg = dreg_is_fp (ins) ? -1 : ins->dreg;
 
+                       /*
+                        * Need to avoid spilling the dreg since the dreg is 
not really
+                        * clobbered by the call.
+                        */
+                       if ((prev_dreg != -1) && !dreg_is_fp (ins))
+                               dreg = rassign (cfg, prev_dreg, dreg_is_fp 
(ins));
+                       else
+                               dreg = -1;
+
                        for (j = 0; j < MONO_MAX_IREGS; ++j) {
                                s = 1 << j;
                                if ((clob_mask & s) && !(rs->ifree_mask & s) && 
(j != ins->sreg1) && (j != dreg)) {
@@ -2700,17 +2676,28 @@
 
                        if (use_sse2) {
                                clob_mask = AMD64_CALLEE_FREGS;
-                               dreg = dreg_is_fp (ins) ? ins->dreg : -1;
+                               if ((prev_dreg != -1) && dreg_is_fp (ins))
+                                       dreg = rassign (cfg, prev_dreg, 
dreg_is_fp (ins));
+                               else
+                                       dreg = -1;
 
                                for (j = 0; j < MONO_MAX_FREGS; ++j) {
                                        s = 1 << j;
-                                       if ((clob_mask & s) && !(rs->ffree_mask 
& s) && (j != ins->sreg1) && (j != dreg)) {
+                                       if ((clob_mask & s) && !(rs->ffree_mask 
& s) && (j != ins->sreg1)) {
                                                get_register_force_spilling 
(cfg, tmp, ins, rs->fsymbolic [j], TRUE);
                                                mono_regstate_free_float (rs, 
j);
                                        }
                                }
                        }
+               }
 
+               /*
+                * TRACK ARGUMENT REGS
+                */
+               if (spec [MONO_INST_CLOB] == 'c') {
+                       MonoCallInst *call = (MonoCallInst*)ins;
+                       GSList *list;
+
                        /* 
                         * This needs to be done before assigning sreg1, so 
sreg1 will
                         * not be assigned one of the argument regs.
@@ -2761,87 +2748,61 @@
                                g_slist_free (call->out_freg_args);
                }
 
-               if (spec [MONO_INST_SRC1] == 'a') {
-                       sreg1_fixed = AMD64_RAX;
-                       src1_mask = 1 << AMD64_RAX;
-
-                       if (!(rs->ifree_mask & (1 << AMD64_RAX))) {
-                               DEBUG (g_print ("\tforced spill of R%d\n", 
rs->isymbolic [AMD64_RAX]));
-                               get_register_force_spilling (cfg, tmp, ins, 
rs->isymbolic [AMD64_RAX], FALSE);
-                               mono_regstate_free_int (rs, AMD64_RAX);
-                       }
-                       if (ins->sreg1 < MONO_MAX_IREGS) {
-                               /* The argument is already in a hard reg, need 
to copy */
-                               MonoInst *copy = create_copy_ins (cfg, 
AMD64_RAX, ins->sreg1, NULL, FALSE);
-                               insert_before_ins (ins, tmp, copy);
-                       }
-                       else {
-                               val = rs->iassign [ins->sreg1];
-                               g_assert (rs->iassign [ins->sreg1] <= -1);
-                               if (val < -1) {
-                                       int spill = -val -1;
-
-                                       MonoInst *store = create_spilled_store 
(cfg, spill, AMD64_RAX, ins->sreg1, NULL, FALSE);
-                                       insert_before_ins (ins, tmp, store);
-                               }
-
-                               /* force-set sreg1 */
-                               assign_ireg (rs, ins->sreg1, AMD64_RAX);
-                       }
-                       ins->sreg1 = AMD64_RAX;
-               }
-
                /*
                 * TRACK SREG1
                 */
                fp = sreg1_is_fp (ins);
-               if ((spec [MONO_INST_DEST] == 'L') && (spec [MONO_INST_SRC1] == 
'L')) {
-                       /* force source to be same as dest */
-                       rs->iassign [ins->sreg1] = ins->dreg;
-                       rs->iassign [ins->sreg1 + 1] = ins->unused;
+               if ((!fp || (fp && use_sse2))) {
+                       if (dest_sreg1 != -1) {
+                               sreg1_mask = 1 << dest_sreg1;
 
-                       DEBUG (g_print ("\tassigned sreg1 (long) %s to sreg1 
R%d\n", mono_arch_regname (ins->dreg), ins->sreg1));
-                       DEBUG (g_print ("\tassigned sreg1 (long-high) %s to 
sreg1 R%d\n", mono_arch_regname (ins->unused), ins->sreg1 + 1));
-
-                       ins->sreg1 = ins->dreg;
-                       /* 
-                        * No need for saving the reg, we know that src1=dest 
in this cases
-                        * ins->inst_c0 = ins->unused;
-                        */
-
-                       /* make sure that we remove them from free mask */
-                       rs->ifree_mask &= ~ (1 << ins->dreg);
-                       rs->ifree_mask &= ~ (1 << ins->unused);
-               }
-               else if ((!fp || (fp && use_sse2)) && (is_soft_reg (ins->sreg1, 
fp))) {
-                       val = rassign (cfg, ins->sreg1, fp);
-                       prev_sreg1 = ins->sreg1;
-                       if (val < 0) {
-                               int spill = 0;
-                               if (val < -1) {
-                                       /* the register gets spilled after this 
inst */
-                                       spill = -val -1;
+                               if (!(rs->ifree_mask & (1 << dest_sreg1))) {
+                                       DEBUG (g_print ("\tforced spill of 
R%d\n", rs->isymbolic [dest_sreg1]));
+                                       get_register_force_spilling (cfg, tmp, 
ins, rs->isymbolic [dest_sreg1], FALSE);
+                                       mono_regstate_free_int (rs, dest_sreg1);
                                }
+                               if (is_global_ireg (ins->sreg1)) {
+                                       /* The argument is already in a hard 
reg, need to copy */
+                                       MonoInst *copy = create_copy_ins (cfg, 
dest_sreg1, ins->sreg1, NULL, FALSE);
+                                       insert_before_ins (ins, tmp, copy);
+                                       ins->sreg1 = dest_sreg1;
+                               }
+                       }
 
-                               val = alloc_reg (cfg, tmp, ins, fp ? 
AMD64_CALLEE_FREGS : src1_mask, ins->sreg1, reginfo [ins->sreg1].flags, fp);
-                               assign_reg (rs, ins->sreg1, val, fp);
-                               DEBUG (g_print ("\tassigned sreg1 %s to R%d\n", 
mono_amd64_regname (val, fp), ins->sreg1));
+                       if (is_soft_reg (ins->sreg1, fp)) {
+                               val = rassign (cfg, ins->sreg1, fp);
+                               prev_sreg1 = ins->sreg1;
+                               if (val < 0) {
+                                       int spill = 0;
+                                       if (val < -1) {
+                                               /* the register gets spilled 
after this inst */
+                                               spill = -val -1;
+                                       }
 
-                               if (spill) {
-                                       MonoInst *store = create_spilled_store 
(cfg, spill, val, prev_sreg1, NULL, fp);
-                                       /*
-                                        * Need to insert before the 
instruction since it can
-                                        * overwrite sreg1.
-                                        */
-                                       insert_before_ins (ins, tmp, store);
+                                       val = alloc_reg (cfg, tmp, ins, 
sreg1_mask, ins->sreg1, reginfo [ins->sreg1].flags, fp);
+                                       assign_reg (rs, ins->sreg1, val, fp);
+                                       DEBUG (g_print ("\tassigned sreg1 %s to 
R%d\n", mono_amd64_regname (val, fp), ins->sreg1));
+
+                                       if (spill) {
+                                               MonoInst *store = 
create_spilled_store (cfg, spill, val, prev_sreg1, NULL, fp);
+                                               /*
+                                                * Need to insert before the 
instruction since it can
+                                                * overwrite sreg1.
+                                                */
+                                               insert_before_ins (ins, tmp, 
store);
+                                       }
                                }
+                               else if ((dest_sreg1 != -1) && (dest_sreg1 != 
val)) {
+                                       g_assert_not_reached ();
+                               }
+                               
+                               ins->sreg1 = val;
                        }
-
-                       ins->sreg1 = val;
+                       else {
+                               prev_sreg1 = -1;
+                       }
+                       sreg2_mask &= ~(1 << ins->sreg1);
                }
-               else {
-                       prev_sreg1 = -1;
-               }
 
                /* handle clobbering of sreg1 */
                if (((spec [MONO_INST_DEST] == 'f' && spec [MONO_INST_SRC1] == 
'f' && use_sse2) || spec [MONO_INST_CLOB] == '1' || spec [MONO_INST_CLOB] == 
's') && ins->dreg != ins->sreg1) {
@@ -2854,7 +2815,7 @@
                                 * copying sreg1 to dreg could clobber sreg2, 
so allocate a new
                                 * register for it.
                                 */
-                               int reg2 = alloc_reg (cfg, tmp, ins, fp ? 
MONO_ARCH_CALLEE_FREGS : dest_mask, ins->sreg2, 0, fp);
+                               int reg2 = alloc_reg (cfg, tmp, ins, dreg_mask, 
ins->sreg2, 0, fp);
 
                                DEBUG (g_print ("\tneed to copy sreg2 %s to reg 
%s\n", mono_amd64_regname (ins->sreg2, fp), mono_amd64_regname (reg2, fp)));
                                sreg2_copy = create_copy_ins (cfg, reg2, 
ins->sreg2, NULL, fp);
@@ -2877,10 +2838,10 @@
                         * Need to prevent sreg2 to be allocated to sreg1, 
since that
                         * would screw up the previous copy.
                         */
-                       src2_mask &= ~ (1 << ins->sreg1);
+                       sreg2_mask &= ~ (1 << ins->sreg1);
                        /* we set sreg1 to dest as well */
                        prev_sreg1 = ins->sreg1 = ins->dreg;
-                       src2_mask &= ~ (1 << ins->dreg);
+                       sreg2_mask &= ~ (1 << ins->dreg);
                }
 
                /*
@@ -2896,16 +2857,13 @@
                                        /* the register gets spilled after this 
inst */
                                        spill = -val -1;
                                }
-                               val = alloc_reg (cfg, tmp, ins, fp ? 
MONO_ARCH_CALLEE_FREGS : src2_mask, ins->sreg2, reginfo [ins->sreg2].flags, fp);
+                               val = alloc_reg (cfg, tmp, ins, sreg2_mask, 
ins->sreg2, reginfo [ins->sreg2].flags, fp);
                                assign_reg (rs, ins->sreg2, val, fp);
                                DEBUG (g_print ("\tassigned sreg2 %s to R%d\n", 
mono_amd64_regname (val, fp), ins->sreg2));
                                if (spill)
                                        create_spilled_store (cfg, spill, val, 
prev_sreg2, ins, fp);
                        }
                        ins->sreg2 = val;
-                       if (spec [MONO_INST_CLOB] == 's' && ins->sreg2 != 
AMD64_RCX) {
-                               DEBUG (g_print ("\tassigned sreg2 %s to R%d, 
but ECX is needed (R%d)\n", mono_arch_regname (val), ins->sreg2, rs->iassign 
[AMD64_RCX]));
-                       }
                }
                else {
                        prev_sreg2 = -1;
@@ -3061,8 +3019,7 @@
        case OP_LCALL:
        case OP_LCALL_REG:
        case OP_LCALL_MEMBASE:
-               if (ins->dreg != AMD64_RAX)
-                       amd64_mov_reg_reg (code, ins->dreg, AMD64_RAX, 8);
+               g_assert (ins->dreg == AMD64_RAX);
                break;
        case OP_FCALL:
        case OP_FCALL_REG:
@@ -3292,12 +3249,8 @@
                        break;
                case OP_STORE_MEMBASE_IMM:
                case OP_STOREI8_MEMBASE_IMM:
-                       if (amd64_is_imm32 (ins->inst_imm))
-                               amd64_mov_membase_imm (code, 
ins->inst_destbasereg, ins->inst_offset, ins->inst_imm, 8);
-                       else {
-                               amd64_mov_reg_imm (code, GP_SCRATCH_REG, 
ins->inst_imm);
-                               amd64_mov_membase_reg (code, 
ins->inst_destbasereg, ins->inst_offset, GP_SCRATCH_REG, 8);
-                       }
+                       g_assert (amd64_is_imm32 (ins->inst_imm));
+                       amd64_mov_membase_imm (code, ins->inst_destbasereg, 
ins->inst_offset, ins->inst_imm, 8);
                        break;
                case CEE_LDIND_I:
                        amd64_mov_reg_mem (code, ins->dreg, 
(gssize)ins->inst_p0, sizeof (gpointer));
@@ -3314,13 +3267,8 @@
                        break;
                case OP_LOAD_MEMBASE:
                case OP_LOADI8_MEMBASE:
-                       if (amd64_is_imm32 (ins->inst_offset)) {
-                               amd64_mov_reg_membase (code, ins->dreg, 
ins->inst_basereg, ins->inst_offset, sizeof (gpointer));
-                       }
-                       else {
-                               amd64_mov_reg_imm_size (code, GP_SCRATCH_REG, 
ins->inst_offset, 8);
-                               amd64_mov_reg_memindex_size (code, ins->dreg, 
ins->inst_basereg, 0, GP_SCRATCH_REG, 0, 8);
-                       }
+                       g_assert (amd64_is_imm32 (ins->inst_offset));
+                       amd64_mov_reg_membase (code, ins->dreg, 
ins->inst_basereg, ins->inst_offset, sizeof (gpointer));
                        break;
                case OP_LOADI4_MEMBASE:
                        amd64_movsxd_reg_membase (code, ins->dreg, 
ins->inst_basereg, ins->inst_offset);
@@ -3340,6 +3288,9 @@
                case OP_LOADI2_MEMBASE:
                        amd64_widen_membase (code, ins->dreg, 
ins->inst_basereg, ins->inst_offset, TRUE, TRUE);
                        break;
+               case OP_AMD64_LOADI8_MEMINDEX:
+                       amd64_mov_reg_memindex_size (code, ins->dreg, 
ins->inst_basereg, 0, ins->inst_indexreg, 0, 8);
+                       break;
                case CEE_CONV_I1:
                        amd64_widen_reg (code, ins->dreg, ins->sreg1, TRUE, 
FALSE);
                        break;
@@ -3366,12 +3317,8 @@
                        amd64_alu_reg_reg (code, X86_CMP, ins->sreg1, 
ins->sreg2);
                        break;
                case OP_COMPARE_IMM:
-                       if (!amd64_is_imm32 (ins->inst_imm)) {
-                               amd64_mov_reg_imm (code, AMD64_R11, 
ins->inst_imm);
-                               amd64_alu_reg_reg (code, X86_CMP, ins->sreg1, 
AMD64_R11);
-                       } else {
-                               amd64_alu_reg_imm (code, X86_CMP, ins->sreg1, 
ins->inst_imm);
-                       }
+                       g_assert (amd64_is_imm32 (ins->inst_imm));
+                       amd64_alu_reg_imm (code, X86_CMP, ins->sreg1, 
ins->inst_imm);
                        break;
                case OP_X86_COMPARE_REG_MEMBASE:
                        amd64_alu_reg_membase (code, X86_CMP, ins->sreg1, 
ins->sreg2, ins->inst_offset);
@@ -3478,12 +3425,6 @@
                        amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        amd64_div_reg (code, ins->sreg2, FALSE);
                        break;
-               case OP_DIV_IMM:
-                       g_assert (amd64_is_imm32 (ins->inst_imm));
-                       amd64_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       amd64_cdq (code);
-                       amd64_div_reg (code, ins->sreg2, TRUE);
-                       break;
                case CEE_REM:
                case OP_LREM:
                        amd64_cdq (code);
@@ -3494,12 +3435,6 @@
                        amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        amd64_div_reg (code, ins->sreg2, FALSE);
                        break;
-               case OP_REM_IMM:
-                       g_assert (amd64_is_imm32 (ins->inst_imm));
-                       amd64_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       amd64_cdq (code);
-                       amd64_div_reg (code, ins->sreg2, TRUE);
-                       break;
                case OP_LMUL_OVF:
                        amd64_imul_reg_reg (code, ins->sreg1, ins->sreg2);
                        EMIT_COND_SYSTEM_EXCEPTION (X86_CC_O, FALSE, 
"OverflowException");
@@ -3690,11 +3625,6 @@
                        amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        amd64_div_reg_size (code, ins->sreg2, 4, FALSE);
                        break;
-               case OP_IDIV_IMM:
-                       amd64_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       amd64_cdq_size (code, 4);
-                       amd64_div_reg_size (code, ins->sreg2, 4, TRUE);
-                       break;
                case OP_IREM:
                        amd64_cdq_size (code, 4);
                        amd64_div_reg_size (code, ins->sreg2, 4, TRUE);
@@ -3703,19 +3633,12 @@
                        amd64_alu_reg_reg (code, X86_XOR, AMD64_RDX, AMD64_RDX);
                        amd64_div_reg_size (code, ins->sreg2, 4, FALSE);
                        break;
-               case OP_IREM_IMM:
-                       amd64_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       amd64_cdq_size (code, 4);
-                       amd64_div_reg_size (code, ins->sreg2, 4, TRUE);
-                       break;
-
                case OP_ICOMPARE:
                        amd64_alu_reg_reg_size (code, X86_CMP, ins->sreg1, 
ins->sreg2, 4);
                        break;
                case OP_ICOMPARE_IMM:
                        amd64_alu_reg_imm_size (code, X86_CMP, ins->sreg1, 
ins->inst_imm, 4);
                        break;
-
                case OP_IBEQ:
                case OP_IBLT:
                case OP_IBGT:

Modified: branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-ops.h
===================================================================
--- branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-ops.h    
2005-03-21 18:11:45 UTC (rev 42051)
+++ branches/vargaz/mini-xp-local-regalloc/mono/mono/mini/mini-ops.h    
2005-03-21 18:12:45 UTC (rev 42052)
@@ -480,6 +480,7 @@
 MINI_OP(OP_AMD64_ICOMPARE_MEMBASE_IMM,   "amd64_icompare_membase_imm")
 MINI_OP(OP_AMD64_ICOMPARE_REG_MEMBASE,   "amd64_icompare_reg_membase")
 MINI_OP(OP_AMD64_OUTARG_ALIGN_STACK,     "amd64_outarg_align_stack")
+MINI_OP(OP_AMD64_LOADI8_MEMINDEX,        "amd64_loadi8_memindex")
        
 MINI_OP(OP_PPC_SUBFIC,             "ppc_subfic")
 MINI_OP(OP_PPC_SUBFZE,             "ppc_subfze")

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

Reply via email to