2002-07-19 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 19 Jul 2002 16:56:36 +0000 (16:56 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Fri, 19 Jul 2002 16:56:36 +0000 (16:56 -0000)
* x86.brg: correctly align valuetype arguments on the stack

* jit.c (mono_analyze_stack): do not compute frame size here.

* x86.brg: use macros to avoid code duplication for CALL opcodes,
compute frame size in x86.brg

svn path=/trunk/mono/; revision=5929

mono/jit/ChangeLog
mono/jit/jit.c
mono/jit/jit.h
mono/jit/x86.brg
mono/tests/marshal2.cs

index 2fd348f19f8cad5e54bd0a70caea2d7704f303e9..dddb372fbfa3d49762bd1f82e2feefdb764eeb3f 100644 (file)
@@ -1,3 +1,12 @@
+2002-07-19  Dietmar Maurer  <dietmar@ximian.com>
+
+       * x86.brg: correctly align valuetype arguments on the stack
+
+       * jit.c (mono_analyze_stack): do not compute frame size here.
+
+       * x86.brg: use macros to avoid code duplication for CALL opcodes,
+       compute frame size in x86.brg
+
 2002-07-18  Dietmar Maurer  <dietmar@ximian.com>
 
        * x86.brg (ARG_OBJ): allow zero sized ARG_OBJ
index 2acba1483835b64572f854eba156596f23a6c12c..609cc6c764199379b173bd68d63298573e59e819 100644 (file)
@@ -1924,7 +1924,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        MonoMethod *cm;
                        MBTree *this = NULL;
                        guint32 token;
-                       int k, align, size, args_size = 0;
+                       int k, size, align;
                        int newarr = FALSE;
                        int newstr = FALSE;
 
@@ -1981,14 +1981,12 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                ADD_TREE (t1, cli_addr);
                        }
                        
-                       args_size += sizeof (gpointer); /* this argument */             
-
                        for (k = csig->param_count - 1; k >= 0; k--) {
                                MonoType *type = mono_get_param_info (cm->signature, k, &size, &align);
                                t1 = mono_ctree_new (mp, mono_map_arg_type (type), arg_sp [k], NULL);   
-                               t1->data.i = size;
+                               t1->data.size_info.size = size;
+                               t1->data.size_info.align = align;
                                ADD_TREE (t1, cli_addr);
-                               args_size += size;
                        }
 
 
@@ -2002,9 +2000,6 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                }
 
                                t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, this, t2);
-                               t1->data.ci.args_size = args_size;
-                               t1->data.ci.vtype_num = 0;
-                               
                                t1->svt = VAL_POINTER;
 
                                t1 = mono_store_tree (cfg, -1, t1, &t2);
@@ -2018,8 +2013,6 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                t2->data.p = arch_create_jit_trampoline (cm);
 
                                t1 = mono_ctree_new (mp, mono_map_call_type (csig->ret, &svt), this, t2);
-                               t1->data.ci.args_size = args_size;
-                               t1->data.ci.vtype_num = 0;
                                t1->svt = svt;
 
                                ADD_TREE (t1, cli_addr);
@@ -2042,7 +2035,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        MonoMethod *cm;
                        MBTree *ftn, *this = NULL;
                        guint32 token;
-                       int k, align, size, args_size = 0;
+                       int k, align, size;
                        int virtual = *ip == CEE_CALLVIRT;
                        int calli = *ip == CEE_CALLI;
                        gboolean array_set = FALSE;
@@ -2155,28 +2148,21 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                        }
 
                        for (k = nargs - 1; k >= 0; k--) {
-                               MonoType *type = mono_get_param_info (csig, k, &size, NULL);
+                               MonoType *type = mono_get_param_info (csig, k, &size, &align);
                                t1 = mono_ctree_new (mp, mono_map_arg_type (type), arg_sp [k], NULL);
-                               t1->data.i = size;
+                               t1->data.size_info.size = size;
+                               t1->data.size_info.align = align;
                                ADD_TREE (t1, cli_addr);
-                               args_size += size;
-                               // fixme: align value type arguments  to 8 byte boundary on the stack
                        }
 
-                       if (csig->hasthis) {
+                       if (csig->hasthis)
                                this = *(--sp);         
-                               args_size += sizeof (gpointer);
-                       } else
+                       else
                                this = mono_ctree_new_leaf (mp, MB_TERM_NOP);
 
                        if (MONO_TYPE_ISSTRUCT (csig->ret)) {
-                               size = mono_type_size (csig->ret, &align);
-                               if (csig->pinvoke && MONO_TYPE_ISSTRUCT ((csig->ret)))
-                                       mono_class_native_size (csig->ret->data.klass);
-
+                               mono_get_param_info (csig, -1, &size, &align);
                                vtype_num = arch_allocate_var (cfg, size, align, MONO_TEMPVAR, VAL_UNKNOWN);
-                               /* we push a pointer to the vtype as argument */
-                               args_size += sizeof (gpointer);
                        }
 
                        if (array_get) {
@@ -2186,8 +2172,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                t2->data.p = ves_array_element_address;
 
                                t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, this, t2);
-                               t1->data.ci.args_size = args_size;
-                               t1->data.ci.vtype_num = vtype_num;
+                               t1->data.i = vtype_num;
  
                                t1 = mono_ctree_new (mp, mono_map_ldind_type (csig->ret, &svt), t1, NULL);
                                t1->svt = svt;          
@@ -2210,8 +2195,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                t2->data.p = ves_array_element_address;
 
                                t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, this, t2);
-                               t1->data.ci.args_size = args_size;
-                               t1->data.ci.vtype_num = vtype_num;
+                               t1->data.i = vtype_num;
 
                                t1 = ctree_create_store (cfg, csig->params [nargs], t1, arg_sp [nargs], FALSE);
                                ADD_TREE (t1, cli_addr);
@@ -2239,8 +2223,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                }
 
                                t1 = mono_ctree_new (mp, mono_map_call_type (csig->ret, &svt), this, t2);
-                               t1->data.ci.args_size = args_size;
-                               t1->data.ci.vtype_num = vtype_num;
+                               t1->data.i = vtype_num;
                                t1->svt = svt;
 
                                if (csig->ret->type != MONO_TYPE_VOID) {
index f1e84813ae227ee27cbeb56a7a7a2a06ffa8a3fd..3b75bb202e28ef61ef947b3467574ca7ca101ab6 100644 (file)
@@ -152,6 +152,7 @@ typedef struct {
        MonoBytecodeInfo *bcinfo;
        MonoBBlock       *bblocks;
        int               block_count;
+
        GArray           *varinfo;
        gint32            locals_size;
        gint32            args_size;
@@ -172,12 +173,9 @@ typedef struct {
        gint             *spillvars; 
        gint              spillcount;
        MonoJumpInfo     *jump_info;
-} MonoFlowGraph;
 
-typedef struct {
-       gint16 args_size;
-       gint16 vtype_num;
-} MonoJitCallInfo;
+       guint             frame_size;
+} MonoFlowGraph;
 
 typedef struct {
        MonoClass *klass;
index 23be36952d67aeb522527d33d93beee111f38ec8..d9d5d3a4ac4309ca42e3fe33b1647c4efb5c034d 100644 (file)
@@ -91,9 +91,12 @@ struct _MBTree {
                MonoClass *klass;
                MonoClassField *field;
                X86AddressInfo ainfo;
-               MonoJitCallInfo ci;
                MonoJitFieldInfo fi;
                MonoJitBranchInfo bi;
+               union {
+                       gint32 size;
+                       gint32 align;
+               } size_info;
        } data;
 };
 
@@ -191,6 +194,26 @@ debug_memcopy (void *dest, const void *src, size_t n);
                x86_call_code (s->code, 0);                    \
        } while (0); 
 
+#define X86_CALL_END                                                        \
+       if (s->frame_size) {                                                \
+               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, s->frame_size); \
+               s->frame_size = 0;                                          \
+       }
+
+#define X86_CALL_BEGIN                                                      \
+       if (tree->left->op != MB_TERM_NOP) {                                \
+               s->frame_size += 4;                                         \
+               mono_assert (lreg >= 0);                                    \
+               x86_push_reg (s->code, lreg);                               \
+               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);         \
+       }                                                                   \
+       if (tree->data.i) {                                                 \
+               int offset = VARINFO (s, tree->data.i).offset;              \
+               s->frame_size += 4;                                         \
+               x86_lea_membase (s->code, treg, X86_EBP, offset);           \
+               x86_push_reg (s->code, treg);                               \
+       }
+
 /* we use this macro to move one lreg to another - source and
    destination may overlap, but the register allocator has to
    make sure that ((d1 < d2) && (s1 < s2))
@@ -2639,6 +2662,8 @@ stmt: RET_VOID {
 stmt: ARG_I4 (LDIND_I4 (addr)) {
        MBTree *at = tree->left->left;
 
+       s->frame_size += 4;
+
        switch (at->data.ainfo.amode) {
 
        case AMImmediate:
@@ -2662,6 +2687,7 @@ stmt: ARG_I4 (LDIND_I4 (addr)) {
 
 stmt: ARG_I4 (LDIND_I4 (ADDR_L)) {
        int treg = VARINFO (s, tree->left->left->data.i).reg;
+       s->frame_size += 4;
        x86_push_reg (s->code, treg);
 } cost {
        MBCOND ((VARINFO (data, tree->left->left->data.i).reg >= 0));
@@ -2669,15 +2695,18 @@ stmt: ARG_I4 (LDIND_I4 (ADDR_L)) {
 }
 
 stmt: ARG_I4 (reg) {
+       s->frame_size += 4;
        x86_push_reg (s->code, tree->left->reg1);
        PRINT_REG ("ARG_I4",  tree->left->reg1);
 }
 
 stmt: ARG_I4 (ADDR_G) {
+       s->frame_size += 4;
        x86_push_imm (s->code, tree->left->data.p);
 }
 
 stmt: ARG_I4 (CONST_I4) "MB_USE_OPT1(0)" {
+       s->frame_size += 4;
        x86_push_imm (s->code, tree->left->data.i);
 }
 
@@ -2736,24 +2765,11 @@ reg: CALL_I4 (this, reg) {
        if (lreg == treg || rreg == treg) 
                mono_assert_not_reached ();
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_call_reg (s->code, rreg);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-       
-       PRINT_REG ("CALL_I4", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
 }
@@ -2765,25 +2781,12 @@ reg: CALL_I4 (this, ADDR_G) {
        if (lreg == treg) 
                treg = X86_EDX;
        
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, tree->right->data.p);
        x86_call_code (s->code, 0);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-
-       PRINT_REG ("CALL_I4", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
 }
@@ -2818,16 +2821,7 @@ reg: CALL_I4 (this, INTF_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_mov_reg_membase (s->code, lreg, lreg, 
@@ -2835,10 +2829,7 @@ reg: CALL_I4 (this, INTF_ADDR) {
        x86_mov_reg_membase (s->code, lreg, lreg, tree->right->data.m->klass->interface_id << 2, 4);
        x86_call_virtual (s->code, lreg, tree->right->data.m->slot << 2);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-
-       PRINT_REG ("CALL_I4(INTERFACE)", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
 }
@@ -2893,25 +2884,13 @@ reg: CALL_I4 (this, VFUNC_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);        
        x86_call_virtual (s->code, lreg, 
                G_STRUCT_OFFSET (MonoVTable, vtable) + (tree->right->data.m->slot << 2));
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-
-       PRINT_REG ("CALL_I4(VIRTUAL)", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
 }
@@ -2923,23 +2902,12 @@ stmt: CALL_VOID (this, ADDR_G) {
        if (lreg == treg) 
                treg = X86_EDX;
        
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, tree->right->data.p);
        x86_call_code (s->code, 0);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 stmt: CALL_VOID (this, reg) {
@@ -2954,22 +2922,11 @@ stmt: CALL_VOID (this, reg) {
        if (lreg == treg || rreg == treg) 
                mono_assert_not_reached ();
        
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_call_reg (s->code, tree->right->reg1);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 stmt: CALL_VOID (this, INTF_ADDR) {
@@ -2979,16 +2936,7 @@ stmt: CALL_VOID (this, INTF_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_mov_reg_membase (s->code, lreg, lreg, 
@@ -2996,8 +2944,7 @@ stmt: CALL_VOID (this, INTF_ADDR) {
        x86_mov_reg_membase (s->code, lreg, lreg, tree->right->data.m->klass->interface_id << 2, 4);
        x86_call_virtual (s->code, lreg, tree->right->data.m->slot << 2);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 stmt: CALL_VOID (this, VFUNC_ADDR) {
@@ -3007,23 +2954,13 @@ stmt: CALL_VOID (this, VFUNC_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_call_virtual (s->code, lreg, 
                G_STRUCT_OFFSET (MonoVTable, vtable) + (tree->right->data.m->slot << 2));
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 stmt: SWITCH (reg) {
@@ -3692,24 +3629,11 @@ lreg: CALL_I8 (this, reg) {
        if (lreg == treg || rreg == treg) 
                mono_assert_not_reached ();
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_call_reg (s->code, rreg);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-       
-       PRINT_REG ("CALL_I8", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
        mono_assert (tree->reg2 == X86_EDX);
@@ -3722,23 +3646,12 @@ lreg: CALL_I8 (this, ADDR_G) {
        if (lreg == treg) 
                treg = X86_EDX;
        
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, tree->right->data.p);
        x86_call_code (s->code, 0);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
        mono_assert (tree->reg2 == X86_EDX);
@@ -3751,26 +3664,13 @@ lreg: CALL_I8 (this, VFUNC_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_call_virtual (s->code, lreg, 
                G_STRUCT_OFFSET (MonoVTable, vtable) + (tree->right->data.m->slot << 2));
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-
-       PRINT_REG ("CALL0_I8(VIRTUAL)", tree->reg1);
-       PRINT_REG ("CALL1_I8(VIRTUAL)", tree->reg2);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
        mono_assert (tree->reg2 == X86_EDX);
@@ -3783,16 +3683,7 @@ lreg: CALL_I8 (this, INTF_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_mov_reg_membase (s->code, lreg, lreg, 
@@ -3800,10 +3691,7 @@ lreg: CALL_I8 (this, INTF_ADDR) {
        x86_mov_reg_membase (s->code, lreg, lreg, tree->right->data.m->klass->interface_id << 2, 4);
        x86_call_virtual (s->code, lreg, tree->right->data.m->slot << 2);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
-
-       PRINT_REG ("CALL_I8(INTERFACE)", tree->reg1);
+       X86_CALL_END
 
        mono_assert (tree->reg1 == X86_EAX);
        mono_assert (tree->reg2 == X86_EDX);
@@ -3832,6 +3720,7 @@ stmt: RET (lreg) {
 
 
 stmt: ARG_I8 (lreg) {
+       s->frame_size += 8;
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
 }
@@ -4546,11 +4435,13 @@ stmt: REMOTE_STIND_R8 (reg, freg) {
 }
 
 stmt: ARG_R4 (freg) {
+       s->frame_size += 4;
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
        x86_fst_membase (s->code, X86_ESP, 0, FALSE, TRUE);
 }
 
 stmt: ARG_R8 (freg) {
+       s->frame_size += 8;
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 8);
        x86_fst_membase (s->code, X86_ESP, 0, TRUE, TRUE);
 }
@@ -4627,22 +4518,11 @@ freg: CALL_R8 (this, reg) {
        if (lreg == treg || rreg == treg) 
                mono_assert_not_reached ();
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_call_reg (s->code, rreg);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);   
+       X86_CALL_END
 }
 
 freg: CALL_R8 (this, ADDR_G) {
@@ -4652,23 +4532,12 @@ freg: CALL_R8 (this, ADDR_G) {
        if (lreg == treg) 
                treg = X86_EDX;
        
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-               x86_alu_membase_imm (s->code, X86_CMP, lreg, 0, 0);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        mono_add_jump_info (s, s->code, MONO_JUMP_INFO_ABS, tree->right->data.p);
        x86_call_code (s->code, 0);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 freg: CALL_R8 (this, INTF_ADDR) {
@@ -4678,16 +4547,7 @@ freg: CALL_R8 (this, INTF_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_mov_reg_membase (s->code, lreg, lreg, 
@@ -4695,8 +4555,7 @@ freg: CALL_R8 (this, INTF_ADDR) {
        x86_mov_reg_membase (s->code, lreg, lreg, tree->right->data.m->klass->interface_id << 2, 4);
        x86_call_virtual (s->code, lreg, tree->right->data.m->slot << 2);
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 freg: CALL_R8 (this, VFUNC_ADDR) {
@@ -4706,23 +4565,13 @@ freg: CALL_R8 (this, VFUNC_ADDR) {
        if (lreg == treg) 
                treg = X86_EDX;
 
-       if (tree->left->op != MB_TERM_NOP) {
-               mono_assert (lreg >= 0);
-               x86_push_reg (s->code, lreg);
-       }
-
-       if (tree->data.ci.vtype_num) {
-               int offset = VARINFO (s, tree->data.ci.vtype_num).offset;
-               x86_lea_membase (s->code, treg, X86_EBP, offset);
-               x86_push_reg (s->code, treg);
-       }
+       X86_CALL_BEGIN
 
        x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
        x86_call_virtual (s->code, lreg, 
                G_STRUCT_OFFSET (MonoVTable, vtable) + (tree->right->data.m->slot << 2));
 
-       if (tree->data.ci.args_size)
-               x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.ci.args_size);
+       X86_CALL_END
 }
 
 stmt: RET (freg) {
@@ -4809,18 +4658,28 @@ stmt: REMOTE_STIND_OBJ (reg, reg) {
 }
 
 stmt: ARG_OBJ (CONST_I4) {
+       s->frame_size += 4;
        x86_push_imm (s->code, tree->left->data.i);     
 }
 
 stmt: ARG_OBJ (reg) {
-       int size = tree->data.i;
+       int pad;
+       int size = tree->data.size_info.size;
+       int align = tree->data.size_info.align;
        int sa;
        
        if (!size)
                return;
 
-       sa = size + 3;
-       sa &= ~3;
+       g_assert ((align & 3) == 0);
+
+       pad = (align - ((s->frame_size + size) & (align -1))) & (align - 1);
+
+       sa = size + pad;
+
+       s->frame_size += sa;
+
+       g_assert ((s->frame_size & (align - 1)) == 0);
 
        /* reserve space for the argument */
        x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, sa);
index 27058edcdf0a4d9aade27b6270f3a94b438a26ef..a94b707f271f17459e6cc5016be2ec6773a33d3d 100755 (executable)
@@ -29,6 +29,7 @@ public class Test {
                public SimpleStruct2 emb1;
                public SimpleObj emb2;
                public string s2;
+               public double x;
        }
        
        public unsafe static int Main () {
@@ -36,7 +37,7 @@ public class Test {
                int size = Marshal.SizeOf (typeof (SimpleStruct));
                
                Console.WriteLine ("SimpleStruct:" + size);
-               if (size != 44)
+               if (size != 56)
                        return 1;
                
                IntPtr p = Marshal.AllocHGlobal (size);
@@ -55,6 +56,7 @@ public class Test {
                ss.emb2.a = 10;
                ss.emb2.b = 11;
                ss.s2 = "just a test";
+               ss.x = 1.5;
                
                Marshal.StructureToPtr (ss, p, false);
                Type t = ss.GetType ();
@@ -123,6 +125,9 @@ public class Test {
 
                if (cp.s2 != "just a test")
                        return 2;
+
+               if (cp.x != 1.5)
+                       return 2;
                
                return 0;
        }