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