Author: zoltan
Date: 2006-04-18 11:14:55 -0400 (Tue, 18 Apr 2006)
New Revision: 59595

Modified:
   branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
   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-ia64.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-sparc.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.c
   branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.h
   branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
Log:
2006-04-18  Zoltan Varga  <[EMAIL PROTECTED]>

        * mini.h method-to-ir.c mini-<ARCH>.c: Put back the 'is_virtual' 
argument to
        mono_arch_emit_call () as it is needed on x86.

        * method-to-ir.c (mono_spill_global_vars): Reenable the lvreg 
optimization.

        * mini-x86.c mini-x86.h: Enable the second argument of div/rem opcodes 
to be
        allocated to %edx, and handle this case in the opcodes themselves.


Modified: branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog     2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/ChangeLog     2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1,5 +1,13 @@
 2006-04-18  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * mini.h method-to-ir.c mini-<ARCH>.c: Put back the 'is_virtual' 
argument to
+       mono_arch_emit_call () as it is needed on x86.
+
+       * method-to-ir.c (mono_spill_global_vars): Reenable the lvreg 
optimization.
+
+       * mini-x86.c mini-x86.h: Enable the second argument of div/rem opcodes 
to be
+       allocated to %edx, and handle this case in the opcodes themselves.
+
        * method-to-ir.c (mono_spill_global_vars): Disable the lvreg 
optimization for
        now since it leads to unsolvable situations in the local register 
allocator.
 

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        
2006-04-18 14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c        
2006-04-18 15:14:55 UTC (rev 59595)
@@ -2536,7 +2536,7 @@
        } else if (!MONO_TYPE_IS_VOID (sig->ret))
                call->inst.dreg = alloc_dreg (cfg, call->inst.type);
 
-       mono_arch_emit_call (cfg, call);
+       mono_arch_emit_call (cfg, call, virtual);
        
        return call;
 }
@@ -9763,24 +9763,9 @@
                                                                         */
                                                                        sreg = 
ins->dreg;
                                                                }
-                                                               /* 
-                                                                * FIXME: This 
causes assertions in the local allocator.
-                                                                * Specially, 
in Mono.Globalization.Unicode.SimpleCollator:.ctor:
-                                                                * there is a 
instruction of the form:
-                                                                * int_div R112 
<- R250 R111 clobbers: d
-                                                                * Here, R112 
is assigned to RDX, R250 is assigned to
-                                                                * RCX. int_div 
has the following spec:
-                                                                * int_div: 
dest:a src1:a src2:i len:15 clob:d
-                                                                * So we need 
to copy from RCX to RAX, and the
-                                                                * instruction 
clobbers RDX before accessing SREG1
-                                                                * and SREG2, 
so there are no registers left for
-                                                                * SREG2. Not 
sure how this can be fixed.
-                                                                */
-#if 0
                                                                vreg_to_lvreg 
[var->dreg] = sreg;
                                                                g_assert 
(lvregs_len < 1024);
                                                                lvregs 
[lvregs_len ++] = var->dreg;
-#endif
                                                        }
                                                }
 
@@ -9807,13 +9792,10 @@
                        }
 
                        if (dest_has_lvreg) {
-                               /* FIXME: This causes assertions in the local 
allocator */
-#if 0
                                vreg_to_lvreg [prev_dreg] = ins->dreg;
                                g_assert (lvregs_len < 1024);
                                lvregs [lvregs_len ++] = prev_dreg;
                                dest_has_lvreg = FALSE;
-#endif
                        }
 
                        if (store) {

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1467,7 +1467,7 @@
 #define EMIT_NEW_VARLOADA(cfg,dest,var,vartype) do { NEW_VARLOADA ((cfg), 
(dest), (var), (vartype)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0)
 
 void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
+mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call, gboolean is_virtual)
 {
        MonoInst *arg, *in;
        MonoMethodSignature *sig;

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-ia64.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-ia64.c   2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-ia64.c   2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1295,7 +1295,7 @@
 }
 
 void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
+mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call, gboolean is_virtual)
 {
        MonoInst *in;
        MonoMethodSignature *sig;

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-sparc.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-sparc.c  2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-sparc.c  2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1486,7 +1486,7 @@
 }
 
 void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
+mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call, gboolean is_virtual)
 {
        MonoInst *in;
        MonoMethodSignature *sig;

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.c    2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.c    2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1070,7 +1070,7 @@
 #define EMIT_NEW_VARLOADA(cfg,dest,var,vartype) do { NEW_VARLOADA ((cfg), 
(dest), (var), (vartype)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0)
 
 void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
+mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call, gboolean is_virtual)
 {
        MonoInst *arg, *in;
        MonoMethodSignature *sig;
@@ -1545,9 +1545,13 @@
                        } else if ((ins->inst_imm == 1) && (ins->dreg == 
ins->sreg1))
                                ins->opcode = OP_X86_INC_REG;
                        break;
+               case OP_SUB_IMM:
                case OP_ISUB_IMM:
-               case OP_SUB_IMM:
-                       if ((ins->inst_imm == 1) && (ins->dreg == ins->sreg1))
+                       if ((ins->sreg1 < MONO_MAX_IREGS) && (ins->dreg >= 
MONO_MAX_IREGS)) {
+                               ins->opcode = OP_X86_LEA_MEMBASE;
+                               ins->inst_basereg = ins->sreg1;
+                               ins->inst_imm = -ins->inst_imm;
+                       } else if ((ins->inst_imm == 1) && (ins->dreg == 
ins->sreg1))
                                ins->opcode = OP_X86_DEC_REG;
                        break;
                case OP_COMPARE_IMM:
@@ -2522,35 +2526,51 @@
                        break;
                case CEE_DIV:
                case OP_IDIV:
-                       x86_cdq (code);
-                       x86_div_reg (code, ins->sreg2, TRUE);
+               case CEE_REM:
+               case OP_IREM:
+                       /* 
+                        * The code is the same for div/rem, the allocator will 
allocate dreg
+                        * to RAX/RDX as appropriate.
+                        */
+                       if (ins->sreg2 == X86_EDX) {
+                               /* cdq clobbers this */
+                               x86_push_reg (code, ins->sreg2);
+                               x86_cdq (code);
+                               x86_div_membase (code, X86_ESP, 0, TRUE);
+                               x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);    
                        
+                       } else {
+                               x86_cdq (code);
+                               x86_div_reg (code, ins->sreg2, TRUE);
+                       }
                        break;
                case CEE_DIV_UN:
                case OP_IDIV_UN:
-                       x86_alu_reg_reg (code, X86_XOR, X86_EDX, X86_EDX);
-                       x86_div_reg (code, ins->sreg2, FALSE);
+               case CEE_REM_UN:
+               case OP_IREM_UN:
+                       if (ins->sreg2 == X86_EDX) {
+                               x86_push_reg (code, ins->sreg2);
+                               x86_alu_reg_reg (code, X86_XOR, X86_EDX, 
X86_EDX);
+                               x86_div_membase (code, X86_ESP, 0, FALSE);
+                               x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);    
                        
+                       } else {
+                               x86_alu_reg_reg (code, X86_XOR, X86_EDX, 
X86_EDX);
+                               x86_div_reg (code, ins->sreg2, FALSE);
+                       }
                        break;
                case OP_DIV_IMM:
                case OP_IDIV_IMM:
-                       x86_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       x86_cdq (code);
-                       x86_div_reg (code, ins->sreg2, TRUE);
-                       break;
-               case CEE_REM:
-               case OP_IREM:
-                       x86_cdq (code);
-                       x86_div_reg (code, ins->sreg2, TRUE);
-                       break;
-               case CEE_REM_UN:
-               case OP_IREM_UN:
-                       x86_alu_reg_reg (code, X86_XOR, X86_EDX, X86_EDX);
-                       x86_div_reg (code, ins->sreg2, FALSE);
-                       break;
                case OP_REM_IMM:
                case OP_IREM_IMM:
-                       x86_mov_reg_imm (code, ins->sreg2, ins->inst_imm);
-                       x86_cdq (code);
-                       x86_div_reg (code, ins->sreg2, TRUE);
+                       if (ins->sreg2 == X86_EDX) {
+                               x86_push_imm (code, ins->sreg2);
+                               x86_cdq (code);
+                               x86_div_membase (code, X86_ESP, 0, TRUE);       
+                               x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
+                       } else {
+                               x86_mov_reg_imm (code, ins->sreg2, 
ins->inst_imm);
+                               x86_cdq (code);
+                               x86_div_reg (code, ins->sreg2, TRUE);
+                       }
                        break;
                case CEE_OR:
                case OP_IOR:

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.h    2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-x86.h    2006-04-18 
15:14:55 UTC (rev 59595)
@@ -88,7 +88,12 @@
 #define MONO_ARCH_INST_FIXED_MASK(desc) ((desc == 'y') ? (X86_BYTE_REGS) : 0)
 
 /* RDX is clobbered by the opcode implementation before accessing sreg2 */
-#define MONO_ARCH_INST_SREG2_MASK(ins) (((ins [MONO_INST_CLOB] == 'a') || (ins 
[MONO_INST_CLOB] == 'd')) ? (1 << X86_EDX) : 0)
+/* 
+ * Originally this contained X86_EDX for div/rem opcodes, but that led to 
unsolvable 
+ * situations since there are only 3 usable registers for local register 
allocation.
+ * Instead, we handle the sreg2==edx case in the opcodes.
+ */
+#define MONO_ARCH_INST_SREG2_MASK(ins) 0
 
 /*
  * L is a generic register pair, while l means eax:rdx

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini.h        2006-04-18 
14:35:54 UTC (rev 59594)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini.h        2006-04-18 
15:14:55 UTC (rev 59595)
@@ -1066,7 +1066,7 @@
 void     *mono_arch_instrument_prolog           (MonoCompile *cfg, void *func, 
void *p, gboolean enable_arguments);
 void     *mono_arch_instrument_epilog           (MonoCompile *cfg, void *func, 
void *p, gboolean enable_arguments);
 MonoCallInst *mono_arch_call_opcode             (MonoCompile *cfg, 
MonoBasicBlock* bb, MonoCallInst *call, int is_virtual);
-void      mono_arch_emit_call                   (MonoCompile *cfg, 
MonoCallInst *call);
+void      mono_arch_emit_call                   (MonoCompile *cfg, 
MonoCallInst *call, gboolean is_virtual);
 void      mono_arch_emit_outarg_vt              (MonoCompile *cfg, MonoInst 
*ins);
 void      mono_arch_emit_setret                 (MonoCompile *cfg, MonoMethod 
*method, MonoInst *val);
 MonoInst *mono_arch_get_inst_for_method         (MonoCompile *cfg, MonoMethod 
*cmethod, MonoMethodSignature *fsig, MonoInst **args);

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

Reply via email to