Author: zoltan
Date: 2005-12-03 20:46:37 -0500 (Sat, 03 Dec 2005)
New Revision: 53895

Modified:
   branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md
   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-ops.h
Log:
Ongoing work.


Modified: branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md  2005-12-03 
20:55:21 UTC (rev 53894)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/cpu-amd64.md  2005-12-04 
01:46:37 UTC (rev 53895)
@@ -54,6 +54,7 @@
 # See the code in mini-x86.c for more details on how the specifiers are used.
 #
 nop: len:0
+dummy_store: len:0
 break: len:2
 jmp: len:42
 br: len:6

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        
2005-12-03 20:55:21 UTC (rev 53894)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/method-to-ir.c        
2005-12-04 01:46:37 UTC (rev 53895)
@@ -195,9 +195,9 @@
                        type = type->data.klass->enum_basetype;
                        goto handle_enum;
                }
-               NOT_IMPLEMENTED;
+               return CEE_STOBJ;
        case MONO_TYPE_TYPEDBYREF:
-               NOT_IMPLEMENTED;
+               return CEE_STOBJ;
        case MONO_TYPE_GENERICINST:
                type = &type->data.generic_class->container_class->byval_arg;
                goto handle_enum;
@@ -295,6 +295,13 @@
                }       \
        } while (0)
 
+/*
+ * IR Emission Macros
+ */
+
+/*
+ * Variants which take a dest argument and do not do an emit
+ */
 #define NEW_ICONST(cfg,dest,val) do {  \
         MONO_INST_NEW ((cfg), (dest), OP_ICONST); \
                (dest)->inst_c0 = (val);        \
@@ -330,152 +337,8 @@
         (dest)->inst_p1 = (gpointer)(gssize)(imm); \
        } while (0)
 
-#define        MONO_EMIT_NEW_ICONST(cfg,dr,imm) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), OP_ICONST); \
-        inst->dreg = dr; \
-        inst->inst_c0 = imm; \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define MONO_EMIT_NEW_PCONST(cfg,dr,val) do {  \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), OP_PCONST); \
-        inst->dreg = dr; \
-               (inst)->inst_p0 = (val);        \
-               (inst)->type = STACK_PTR;       \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define        MONO_EMIT_NEW_I8CONST(cfg,dr,imm) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), OP_I8CONST); \
-        inst->dreg = dr; \
-        inst->inst_l = imm; \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
 #ifdef MONO_ARCH_NEED_GOT_VAR
 
-#define MONO_EMIT_NEW_AOTCONST(cfg,dr,cons,patch_type) do { \
-               mini_emit_aotconst ((cfg), (dr), (patch_type), (cons)); \
-    } while (0)
-
-#else
-
-#define        MONO_EMIT_NEW_AOTCONST(cfg,dr,imm,type) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), OP_AOTCONST); \
-        inst->dreg = dr; \
-        inst->inst_p0 = imm; \
-        inst->inst_c1 = type; \
-               MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#endif
-
-#define        MONO_EMIT_NEW_CLASSCONST(cfg,dr,imm) 
MONO_EMIT_NEW_AOTCONST(cfg,dr,imm,MONO_PATCH_INFO_CLASS)
-#define MONO_EMIT_NEW_VTABLECONST(cfg,dest,vtable) MONO_EMIT_NEW_AOTCONST 
((cfg), (dest), (cfg)->compile_aot ? (gpointer)((vtable)->klass) : (vtable), 
MONO_PATCH_INFO_VTABLE)
-
-#define MONO_EMIT_NEW_UNALU(cfg,op,dr,sr1) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-        inst->opcode = op; \
-        inst->dreg = dr; \
-        inst->sreg1 = sr1; \
-           MONO_ADD_INS (cfg->cbb, inst); \
-       } while (0)
-
-#define MONO_EMIT_NEW_BIALU(cfg,op,dr,sr1,sr2) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-        inst->dreg = dr; \
-        inst->sreg1 = sr1; \
-        inst->sreg2 = sr2; \
-           MONO_ADD_INS (cfg->cbb, inst); \
-       } while (0)
-
-#define MONO_EMIT_NEW_BIALU_IMM(cfg,op,dr,sr,imm) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-        inst->dreg = dr; \
-        inst->sreg1 = sr; \
-        inst->inst_p1 = (gpointer)(gssize)(imm); \
-           MONO_ADD_INS (cfg->cbb, inst); \
-       } while (0)
-
-#define        MONO_EMIT_NEW_COMPARE_IMM(cfg,sr1,imm) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (OP_COMPARE_IMM)); \
-        inst->sreg1 = sr1; \
-        inst->inst_p1 = (gpointer)imm; \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define        MONO_EMIT_NEW_ICOMPARE_IMM(cfg,sr1,imm) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), sizeof (void*) == 8 ? OP_ICOMPARE_IMM : 
OP_COMPARE_IMM); \
-        inst->sreg1 = sr1; \
-        inst->inst_p1 = (gpointer)imm; \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg,op,dr,base,offset) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-        inst->dreg = dr; \
-        inst->inst_basereg = base; \
-        inst->inst_offset = offset; \
-           MONO_ADD_INS (cfg->cbb, inst); \
-    } while (0)
-
-#define MONO_EMIT_NEW_LOAD_MEMBASE(cfg,dr,base,offset) 
MONO_EMIT_NEW_LOAD_MEMBASE_OP ((cfg), (OP_LOAD_MEMBASE), (dr), (base), (offset))
-
-#define MONO_EMIT_NEW_STORE_MEMBASE(cfg,op,base,offset,sr) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-        (inst)->sreg1 = sr; \
-        (inst)->inst_destbasereg = base; \
-        (inst)->inst_offset = offset; \
-           MONO_ADD_INS (cfg->cbb, inst); \
-       } while (0)
-
-#define        MONO_EMIT_NEW_COND_EXC(cfg,cond,name) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (OP_COND_EXC_##cond)); \
-        inst->inst_p1 = (char*)name; \
-           MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define MONO_NEW_LABEL(cfg,inst) do { \
-        MONO_INST_NEW ((cfg), (inst), OP_LABEL); \
-       } while (0)
-
-/* FIXME: Why is this label thing needed ? */
-#define        MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,targetbb) do { \
-        MonoInst *inst; \
-        MonoInst *target_label; \
-        MONO_INST_NEW ((cfg), (target_label), OP_LABEL); \
-               target_label->next = (targetbb)->code; \
-               target_label->inst_c0 = (targetbb)->native_offset; \
-        if (!(targetbb)->last_ins) (targetbb)->last_ins = target_label; \
-               (targetbb)->code = target_label; \
-        MONO_INST_NEW ((cfg), inst, (op)); \
-               inst->inst_i0 = target_label;   \
-               inst->flags = MONO_INST_BRLABEL;        \
-        MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#define        MONO_EMIT_NEW_BRANCH_LABEL(cfg,op,label) do { \
-        MonoInst *inst; \
-        MONO_INST_NEW ((cfg), (inst), (op)); \
-               inst->inst_i0 = label;  \
-               inst->flags = MONO_INST_BRLABEL;        \
-        MONO_ADD_INS ((cfg)->cbb, inst); \
-       } while (0)
-
-#ifdef MONO_ARCH_NEED_GOT_VAR
-
 #define NEW_PATCH_INFO(cfg,dest,el1,el2) do {  \
         MONO_INST_NEW ((cfg), (dest), OP_PATCH_INFO); \
                (dest)->inst_left = (gpointer)(el1);    \
@@ -639,13 +502,13 @@
        } while (0)
 
 #define NEW_TEMPLOADA(cfg,dest,num) do {       \
-        NOT_IMPLEMENTED; \
         MONO_INST_NEW ((cfg), (dest), OP_LDADDR); \
                (dest)->ssa_op = MONO_SSA_ADDRESS_TAKEN;        \
-               (dest)->inst_i0 = (cfg)->varinfo [(num)];       \
-               (dest)->inst_i0->flags |= MONO_INST_INDIRECT;   \
+               (dest)->inst_c0 = (num); \
+               (cfg)->varinfo [(num)]->flags |= MONO_INST_INDIRECT;    \
                (dest)->type = STACK_MP;        \
-               (dest)->klass = (dest)->inst_i0->klass; \
+               (dest)->klass = (cfg)->varinfo [(num)]->klass;  \
+        (dest)->dreg = alloc_dreg ((cfg), STACK_MP); \
         if (!MONO_TYPE_ISSTRUCT (cfg->varinfo [(num)]->inst_vtype)) \
            (cfg)->disable_ssa = TRUE; \
        } while (0)
@@ -706,13 +569,167 @@
     } while (0)
 
 #define NEW_DUMMY_STORE(cfg,dest,num) do { \
-        NOT_IMPLEMENTED; \
         MONO_INST_NEW ((cfg), (dest), OP_DUMMY_STORE); \
                (dest)->inst_i0 = (cfg)->varinfo [(num)];       \
                (dest)->opcode = OP_DUMMY_STORE; \
                (dest)->klass = (dest)->inst_i0->klass; \
        } while (0)
 
+/*
+ * Variants which do an emit as well.
+ */
+#define EMIT_NEW_ICONST(cfg,dest,val) do { \
+        NEW_ICONST ((cfg), (dest), (val)); \
+        MONO_ADD_INS ((cfg)->cbb, (dest)); \
+    } while (0)
+
+/*
+ * Variants which do not take an dest argument, but take a dreg argument.
+ */
+#define        MONO_EMIT_NEW_ICONST(cfg,dr,imm) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), OP_ICONST); \
+        inst->dreg = dr; \
+        inst->inst_c0 = imm; \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define MONO_EMIT_NEW_PCONST(cfg,dr,val) do {  \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), OP_PCONST); \
+        inst->dreg = dr; \
+               (inst)->inst_p0 = (val);        \
+               (inst)->type = STACK_PTR;       \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define        MONO_EMIT_NEW_I8CONST(cfg,dr,imm) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), OP_I8CONST); \
+        inst->dreg = dr; \
+        inst->inst_l = imm; \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#ifdef MONO_ARCH_NEED_GOT_VAR
+
+#define MONO_EMIT_NEW_AOTCONST(cfg,dr,cons,patch_type) do { \
+               mini_emit_aotconst ((cfg), (dr), (patch_type), (cons)); \
+    } while (0)
+
+#else
+
+#define        MONO_EMIT_NEW_AOTCONST(cfg,dr,imm,type) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), OP_AOTCONST); \
+        inst->dreg = dr; \
+        inst->inst_p0 = imm; \
+        inst->inst_c1 = type; \
+               MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#endif
+
+#define        MONO_EMIT_NEW_CLASSCONST(cfg,dr,imm) 
MONO_EMIT_NEW_AOTCONST(cfg,dr,imm,MONO_PATCH_INFO_CLASS)
+#define MONO_EMIT_NEW_VTABLECONST(cfg,dest,vtable) MONO_EMIT_NEW_AOTCONST 
((cfg), (dest), (cfg)->compile_aot ? (gpointer)((vtable)->klass) : (vtable), 
MONO_PATCH_INFO_VTABLE)
+
+#define MONO_EMIT_NEW_UNALU(cfg,op,dr,sr1) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+        inst->opcode = op; \
+        inst->dreg = dr; \
+        inst->sreg1 = sr1; \
+           MONO_ADD_INS (cfg->cbb, inst); \
+       } while (0)
+
+#define MONO_EMIT_NEW_BIALU(cfg,op,dr,sr1,sr2) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+        inst->dreg = dr; \
+        inst->sreg1 = sr1; \
+        inst->sreg2 = sr2; \
+           MONO_ADD_INS (cfg->cbb, inst); \
+       } while (0)
+
+#define MONO_EMIT_NEW_BIALU_IMM(cfg,op,dr,sr,imm) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+        inst->dreg = dr; \
+        inst->sreg1 = sr; \
+        inst->inst_p1 = (gpointer)(gssize)(imm); \
+           MONO_ADD_INS (cfg->cbb, inst); \
+       } while (0)
+
+#define        MONO_EMIT_NEW_COMPARE_IMM(cfg,sr1,imm) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (OP_COMPARE_IMM)); \
+        inst->sreg1 = sr1; \
+        inst->inst_p1 = (gpointer)imm; \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define        MONO_EMIT_NEW_ICOMPARE_IMM(cfg,sr1,imm) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), sizeof (void*) == 8 ? OP_ICOMPARE_IMM : 
OP_COMPARE_IMM); \
+        inst->sreg1 = sr1; \
+        inst->inst_p1 = (gpointer)imm; \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg,op,dr,base,offset) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+        inst->dreg = dr; \
+        inst->inst_basereg = base; \
+        inst->inst_offset = offset; \
+           MONO_ADD_INS (cfg->cbb, inst); \
+    } while (0)
+
+#define MONO_EMIT_NEW_LOAD_MEMBASE(cfg,dr,base,offset) 
MONO_EMIT_NEW_LOAD_MEMBASE_OP ((cfg), (OP_LOAD_MEMBASE), (dr), (base), (offset))
+
+#define MONO_EMIT_NEW_STORE_MEMBASE(cfg,op,base,offset,sr) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+        (inst)->sreg1 = sr; \
+        (inst)->inst_destbasereg = base; \
+        (inst)->inst_offset = offset; \
+           MONO_ADD_INS (cfg->cbb, inst); \
+       } while (0)
+
+#define        MONO_EMIT_NEW_COND_EXC(cfg,cond,name) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (OP_COND_EXC_##cond)); \
+        inst->inst_p1 = (char*)name; \
+           MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define MONO_NEW_LABEL(cfg,inst) do { \
+        MONO_INST_NEW ((cfg), (inst), OP_LABEL); \
+       } while (0)
+
+/* FIXME: Why is this label thing needed ? */
+#define        MONO_EMIT_NEW_BRANCH_BLOCK(cfg,op,targetbb) do { \
+        MonoInst *inst; \
+        MonoInst *target_label; \
+        MONO_INST_NEW ((cfg), (target_label), OP_LABEL); \
+               target_label->next = (targetbb)->code; \
+               target_label->inst_c0 = (targetbb)->native_offset; \
+        if (!(targetbb)->last_ins) (targetbb)->last_ins = target_label; \
+               (targetbb)->code = target_label; \
+        MONO_INST_NEW ((cfg), inst, (op)); \
+               inst->inst_i0 = target_label;   \
+               inst->flags = MONO_INST_BRLABEL;        \
+        MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
+#define        MONO_EMIT_NEW_BRANCH_LABEL(cfg,op,label) do { \
+        MonoInst *inst; \
+        MONO_INST_NEW ((cfg), (inst), (op)); \
+               inst->inst_i0 = label;  \
+               inst->flags = MONO_INST_BRLABEL;        \
+        MONO_ADD_INS ((cfg)->cbb, inst); \
+       } while (0)
+
 #define ADD_BINOP(op) do {     \
                MONO_INST_NEW (cfg, ins, (op)); \
                ins->cil_code = ip;     \
@@ -1978,6 +1995,51 @@
        }
 }
 
+static void 
+mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int 
soffset, int size, int align)
+{
+       int cur_reg;
+
+       /* FIXME: consider alignment for archs that need it. */
+#if !NO_UNALIGNED_ACCESS
+       if (sizeof (gpointer) == 8) {
+               while (size >= 8) {
+                       cur_reg = alloc_dreg (cfg, STACK_PTR);
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI8_MEMBASE, 
cur_reg, srcreg, soffset);
+                       MONO_EMIT_NEW_STORE_MEMBASE (cfg, 
OP_STOREI8_MEMBASE_REG, destreg, doffset, cur_reg);
+                       doffset += 8;
+                       soffset += 8;
+                       size -= 8;
+               }
+       }       
+#endif
+
+       while (size >= 4) {
+               cur_reg = alloc_dreg (cfg, STACK_PTR);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, cur_reg, 
srcreg, soffset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, 
destreg, doffset, cur_reg);
+               doffset += 4;
+               soffset += 4;
+               size -= 4;
+       }
+       while (size >= 2) {
+               cur_reg = alloc_dreg (cfg, STACK_PTR);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, cur_reg, 
srcreg, soffset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, 
destreg, doffset, cur_reg);
+               doffset += 2;
+               soffset += 2;
+               size -= 2;
+       }
+       while (size >= 1) {
+               cur_reg = alloc_dreg (cfg, STACK_PTR);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, cur_reg, 
srcreg, soffset);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, 
destreg, doffset, cur_reg);
+               doffset += 1;
+               soffset += 1;
+               size -= 1;
+       }
+}
+
 static int
 ret_type_to_call_opcode (MonoType *type, int calli, int virt)
 {
@@ -2282,7 +2344,29 @@
        call->signature = sig;
        call = mono_arch_call_opcode2 (cfg, call, virtual);
        type_to_eval_stack_type (sig->ret, &call->inst);
-       if (call->inst.opcode != OP_VOIDCALL)
+
+       if (MONO_TYPE_ISSTRUCT (sig->ret)) {
+               MonoInst *temp = mono_compile_create_var (cfg, sig->ret, 
OP_LOCAL);
+               MonoInst *loada, *dummy_store;
+
+               temp->flags |= MONO_INST_IS_TEMP;
+
+               /* 
+                * Emit a dummy store to the local holding the result so the
+                * liveness info remains correct.
+                */
+               NEW_DUMMY_STORE (cfg, dummy_store, temp->inst_c0);
+               MONO_ADD_INS (cfg->cbb, dummy_store);
+
+               /* FIXME: What is this ? */
+               /* we use this to allocate native sized structs */
+               temp->unused = sig->pinvoke;
+
+               NEW_TEMPLOADA (cfg, loada, temp->inst_c0);
+               MONO_ADD_INS (cfg->cbb, loada);
+
+               call->inst.dreg = loada->dreg;
+       } else if (call->inst.opcode != OP_VOIDCALL)
                call->inst.dreg = alloc_dreg (cfg, call->inst.type);
        
        if (to_end)
@@ -2407,7 +2491,7 @@
        return mono_spill_call (cfg, call, signature, ret_object, ip, to_end);
 }
 
-inline static int
+inline static MonoInst*
 mono_emit_native_call (MonoCompile *cfg, gconstpointer func, 
MonoMethodSignature *sig,
                       MonoInst **args, const guint8 *ip, gboolean ret_object, 
gboolean to_end)
 {
@@ -2422,10 +2506,10 @@
 
        mono_get_got_var (cfg);
 
-       return mono_spill_call (cfg, call, sig, ret_object, ip, to_end);
+       return call;
 }
 
-inline static int
+inline static MonoInst*
 mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args, 
const guint8 *ip)
 {
        MonoJitICallInfo *info = mono_find_jit_icall_by_addr (func);
@@ -2523,6 +2607,10 @@
        return memcpy_method;
 }
 
+/*
+ * Emit code to copy a valuetype of type @klass whose address is stored in
+ * @src->dreg to memory whose address is stored at @dest->dreg.
+ */
 static void
 handle_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, const unsigned 
char *ip, MonoClass *klass, gboolean to_end, gboolean native) {
        MonoInst *iargs [3];
@@ -2536,32 +2624,24 @@
         * g_assert (klass && klass == src->klass && klass == dest->klass);
         */
 
+       g_assert (!to_end);
+
        if (native)
                n = mono_class_native_size (klass, &align);
        else
                n = mono_class_value_size (klass, &align);
 
        if ((cfg->opt & MONO_OPT_INTRINS) && !to_end && n <= sizeof (gpointer) 
* 5) {
-               MonoInst *inst;
-               if (dest->opcode == OP_LDADDR) {
-                       /* Keep liveness info correct */
-                       NEW_DUMMY_STORE (cfg, inst, dest->inst_i0->inst_c0);
-                       MONO_ADD_INS (cfg->cbb, inst);
-               }
-               MONO_INST_NEW (cfg, inst, OP_MEMCPY);
-               inst->inst_left = dest;
-               inst->inst_right = src;
-               inst->cil_code = ip;
-               inst->unused = n;
-               MONO_ADD_INS (cfg->cbb, inst);
-               return;
+               /* FIXME: Optimize the case when src/dest is OP_LDADDR */
+               mini_emit_memcpy (cfg, dest->dreg, 0, src->dreg, 0, n, 0);
+       } else {
+               iargs [0] = dest;
+               iargs [1] = src;
+               EMIT_NEW_ICONST (cfg, iargs [2], n);
+               
+               memcpy_method = get_memcpy_method ();
+               mono_emit_method_call_spilled_full (cfg, memcpy_method, 
memcpy_method->signature, iargs, ip, NULL, FALSE, to_end);
        }
-       iargs [0] = dest;
-       iargs [1] = src;
-       NEW_ICONST (cfg, iargs [2], n);
-
-       memcpy_method = get_memcpy_method ();
-       mono_emit_method_call_spilled_full (cfg, memcpy_method, 
memcpy_method->signature, iargs, ip, NULL, FALSE, to_end);
 }
 
 static MonoMethod*
@@ -2611,7 +2691,7 @@
        }
 }
 
-static int
+static MonoInst*
 handle_alloc (MonoCompile *cfg, MonoClass *klass, gboolean for_box, const 
guchar *ip)
 {
        MonoInst *iargs [2];
@@ -2632,8 +2712,7 @@
                if (pass_lw) {
                        guint32 lw = vtable->klass->instance_size;
                        lw = ((lw + (sizeof (gpointer) - 1)) & ~(sizeof 
(gpointer) - 1)) / sizeof (gpointer);
-                       NEW_ICONST (cfg, iargs [0], lw);
-                       MONO_ADD_INS (cfg->cbb, iargs [0]);
+                       EMIT_NEW_ICONST (cfg, iargs [0], lw);
                        NEW_VTABLECONST (cfg, iargs [1], vtable);
                        MONO_ADD_INS (cfg->cbb, iargs [1]);
                }
@@ -2646,30 +2725,24 @@
        return mono_emit_jit_icall (cfg, alloc_ftn, iargs, ip);
 }
        
-static MonoInst *
+static MonoInst*
 handle_box (MonoCompile *cfg, MonoInst *val, const guchar *ip, MonoClass 
*klass)
 {
-       MonoInst *dest, *vstore;
-       int temp;
+       MonoInst *alloc, *dest, *vstore;
 
-       temp = handle_alloc (cfg, klass, TRUE, ip);
-       NEW_TEMPLOAD (cfg, dest, temp);
-       MONO_ADD_INS (cfg->cbb, dest);
+       alloc = handle_alloc (cfg, klass, TRUE, ip);
 
-       NEW_STORE_MEMBASE (cfg, vstore, mono_type_to_store_membase 
(&klass->byval_arg), dest->dreg, sizeof (MonoObject), val->dreg);
+       NEW_STORE_MEMBASE (cfg, vstore, mono_type_to_store_membase 
(&klass->byval_arg), alloc->dreg, sizeof (MonoObject), val->dreg);
 
        if (vstore->opcode == CEE_STOBJ)
                NOT_IMPLEMENTED;
        else
                MONO_ADD_INS (cfg->cbb, vstore);
 
-       NEW_TEMPLOAD (cfg, dest, temp);
-       MONO_ADD_INS (cfg->cbb, dest);
-
-       return dest;
+       return alloc;
 }
 
-static int
+static MonoInst*
 handle_array_new (MonoCompile *cfg, int rank, MonoInst **sp, unsigned char *ip)
 {
        MonoMethodSignature *esig;
@@ -4469,13 +4542,13 @@
                        } else {
                                NEW_LOCSTORE (cfg, ins, n, *sp);
                                ins->cil_code = ip;
-                               MONO_ADD_INS (bblock, ins);
 
                                if (ins->opcode == CEE_STOBJ) {
-                                       NOT_IMPLEMENTED;
                                        NEW_LOCLOADA (cfg, ins, n);
+                                       MONO_ADD_INS (cfg->cbb, ins);
                                        handle_stobj (cfg, ins, *sp, ip, 
ins->klass, FALSE, FALSE);
-                               }
+                               } else
+                                       MONO_ADD_INS (bblock, ins);
                        }
                        ++ip;
                        inline_costs += 1;
@@ -5821,6 +5894,7 @@
                case CEE_NEWOBJ: {
                        MonoInst *iargs [2];
                        MonoMethodSignature *fsig;
+                       MonoInst *alloc;
                        int temp;
                        
                        CHECK_OPSIZE (5);
@@ -5880,9 +5954,8 @@
                                         */
                                        mono_get_got_var (cfg);
                                } else {
-                                       temp = handle_alloc (cfg, 
cmethod->klass, FALSE, ip);
-                                       NEW_TEMPLOAD (cfg, *sp, temp);
-                                       MONO_ADD_INS (bblock, *sp);
+                                       alloc = handle_alloc (cfg, 
cmethod->klass, FALSE, ip);
+                                       *sp = alloc;
                                }
 
                                /* Avoid virtual calls to ctors if possible */
@@ -5924,8 +5997,7 @@
                                }
                        }
 
-                       NEW_TEMPLOAD (cfg, *sp, temp);
-                       MONO_ADD_INS (bblock, *sp);
+                       *sp = alloc;
                        sp++;
                        
                        ip += 5;
@@ -8086,8 +8158,9 @@
  * - clean up/automatize setting of ins->cil_code
  * - clean up usage of OP_P/OP_ opcodes
  * - allocate dregs automatically in MONO_EMIT_NEW macros
- * - cleanup calls
+ * - cleanup calls. especially the spill stuff
  * - handle the emit ins + need it/its dreg pattern
+ * - cleanup usage of DUMMY_USE
  * - COMPARE/BEQ as separate instructions or unify them ?
  *   - keeping them separate allows specialized compare instructions like
  *     compare_imm, compare_membase

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2005-12-03 
20:55:21 UTC (rev 53894)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-amd64.c  2005-12-04 
01:46:37 UTC (rev 53895)
@@ -1431,7 +1431,7 @@
                        call->out_args = arg;
                }
 
-               if (is_virtual && i == 0) {
+               if (0 && is_virtual && i == 0) {
                        /* the argument will be attached to the call 
instruction */
                        in = call->args [i];
                } else {
@@ -2613,6 +2613,7 @@
                        amd64_breakpoint (code);
                        break;
                case CEE_NOP:
+               case OP_DUMMY_STORE:
                        break;
                case OP_ADDCC:
                case CEE_ADD:

Modified: branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h
===================================================================
--- branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h    2005-12-03 
20:55:21 UTC (rev 53894)
+++ branches/vargaz/mini-linear-il/mono/mono/mini/mini-ops.h    2005-12-04 
01:46:37 UTC (rev 53895)
@@ -45,10 +45,13 @@
 MINI_OP(OP_LCALLVIRT,  "lcallvirt", LREG, NONE, NONE)
 MINI_OP(OP_LCALL_REG,  "lcall_reg", LREG, IREG, NONE)
 MINI_OP(OP_LCALL_MEMBASE,      "lcall_membase", LREG, IREG, NONE)
-MINI_OP(OP_VCALL,      "vcall", NONE, NONE, NONE)
-MINI_OP(OP_VCALLVIRT,  "vcallvirt", NONE, NONE, NONE)
-MINI_OP(OP_VCALL_REG,  "vcall_reg", NONE, IREG, NONE)
-MINI_OP(OP_VCALL_MEMBASE,      "vcall_membase", NONE, IREG, NONE)
+
+/* ins->dreg is the vreg holding the address where the return value is stored 
*/
+MINI_OP(OP_VCALL,      "vcall", IREG, NONE, NONE)
+MINI_OP(OP_VCALLVIRT,  "vcallvirt", IREG, NONE, NONE)
+MINI_OP(OP_VCALL_REG,  "vcall_reg", IREG, IREG, NONE)
+MINI_OP(OP_VCALL_MEMBASE,      "vcall_membase", IREG, IREG, NONE)
+
 MINI_OP(OP_CALL,        "call", IREG, NONE, NONE)
 MINI_OP(OP_CALL_REG,   "call_reg", IREG, IREG, NONE)
 MINI_OP(OP_CALL_MEMBASE,       "call_membase", IREG, IREG, NONE)

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

Reply via email to