2004-11-2 Geoff Norton <gnorton@customerdna.com>
authorGeoff Norton <grompf@sublimeintervention.com>
Tue, 2 Nov 2004 16:34:03 +0000 (16:34 -0000)
committerGeoff Norton <grompf@sublimeintervention.com>
Tue, 2 Nov 2004 16:34:03 +0000 (16:34 -0000)
        * inssel-ppc.brg (OP_OUTARG_VT (CEE_LDOBJ (base))):
        The darwin ABI needs some special handling for 1 and 2 byte structs
        Lets use lbz/lhz instead of lwz everywhere.
        * mini-ppc.c (calculate_sizes):  The Darwin ABI needs from special handling
        for 1 and 2 byte structs and struct which are size >= 3 || size % 4 != 0.
        Use stb/sth for the former, and put the latter always on stack instead of in
        argument registers.

svn path=/branches/mono-1-0/mono/; revision=35565

mono/mini/ChangeLog
mono/mini/inssel-ppc.brg
mono/mini/mini-ppc.c

index a0356fba2af765063d04afc6f42f2f66e7b0ecf1..d8738cd1b22a76fb0858eeb7a4c69f71fb7b8c50 100644 (file)
@@ -1,3 +1,13 @@
+2004-11-2  Geoff Norton  <gnorton@customerdna.com>
+
+        * inssel-ppc.brg (OP_OUTARG_VT (CEE_LDOBJ (base))):
+        The darwin ABI needs some special handling for 1 and 2 byte structs
+        Lets use lbz/lhz instead of lwz everywhere.
+        * mini-ppc.c (calculate_sizes):  The Darwin ABI needs from special handling
+        for 1 and 2 byte structs and struct which are size >= 3 || size % 4 != 0.
+        Use stb/sth for the former, and put the latter always on stack instead of in
+        argument registers.
+
 2004-10-30  Zoltan Varga  <vargaz@freemail.hu>
 
        * trace.c (is_filenamechar): Add '_'.
index 38eced8c0dc73db531fb418fb775a9485d5608bd..96b18cc98c8cf4db62cc00713d2b6a5828c11701 100644 (file)
@@ -260,7 +260,23 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
        int nregs = (tree->unused >> 8) & 0xff;
        int ovf_size = (tree->unused >> 16) & 0xffff;
        int i, tmpr, soffset;
+       int size = 0;
        soffset = vt->inst_offset;
+/*
+  Darwin needs some special handling for 1 and 2 byte arguments
+*/
+#ifdef __APPLE__
+       if (vt->inst_vtype && MONO_TYPE_ISSTRUCT (vt->inst_vtype) && vt->inst_vtype->type != MONO_TYPE_TYPEDBYREF)
+           size =  mono_class_native_size (vt->inst_vtype->data.klass, NULL);
+       if (size == 2 || size == 1) {
+               tmpr = mono_regstate_next_int (s->rs);
+               if (size == 1)
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI1_MEMBASE, tmpr, vt->inst_basereg, soffset);
+               else
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI2_MEMBASE, tmpr, vt->inst_basereg, soffset);
+               MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg, tmpr);
+       } else
+#endif
        for (i = 0; i < nregs; ++i) {
                tmpr = mono_regstate_next_int (s->rs);
                MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset);
index 967c253c648a4b7c8a666fd8a1fb6242a690f2ba..cebf7d9afb646acceb3a894ed3dd4b32d74e06a8 100644 (file)
@@ -408,18 +408,22 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                                      mono_class_native_size (sig->params [i]->data.klass, NULL)));
 #if PPC_PASS_STRUCTS_BY_VALUE
                        {
-                               int nwords = (size + sizeof (gpointer) -1 ) / sizeof (gpointer);
+                               int align_size = size;
+                               int nwords = 0;
+                               align_size += (sizeof (gpointer) - 1);
+                               align_size &= ~(sizeof (gpointer) - 1);
+                               nwords = (align_size + sizeof (gpointer) -1 ) / sizeof (gpointer);
                                cinfo->args [n].regtype = RegTypeStructByVal;
-                               if (gr <= PPC_LAST_ARG_REG) {
+                               if (gr > PPC_LAST_ARG_REG || (size >= 3 && size % 4 != 0)) {
+                                       cinfo->args [n].size = 0;
+                                       cinfo->args [n].vtsize = nwords;
+                               } else {
                                        int rest = PPC_LAST_ARG_REG - gr + 1;
                                        int n_in_regs = rest >= nwords? nwords: rest;
                                        cinfo->args [n].size = n_in_regs;
                                        cinfo->args [n].vtsize = nwords - n_in_regs;
                                        cinfo->args [n].reg = gr;
                                        gr += n_in_regs;
-                               } else {
-                                       cinfo->args [n].size = 0;
-                                       cinfo->args [n].vtsize = nwords;
                                }
                                cinfo->args [n].offset = PPC_STACK_PARAM_OFFSET + stack_size;
                                /*g_print ("offset for arg %d at %d\n", n, PPC_STACK_PARAM_OFFSET + stack_size);*/
@@ -3536,10 +3540,24 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                int doffset = inst->inst_offset;
                                int soffset = 0;
                                int cur_reg;
+                               int size = 0;
                                g_assert (ppc_is_imm16 (inst->inst_offset));
                                g_assert (ppc_is_imm16 (inst->inst_offset + ainfo->size * sizeof (gpointer)));
+                               if (inst->inst_vtype->data.klass)
+                                       size = mono_class_native_size (inst->inst_vtype->data.klass, NULL);
                                for (cur_reg = 0; cur_reg < ainfo->size; ++cur_reg) {
-                                       ppc_stw (code, ainfo->reg + cur_reg, doffset, inst->inst_basereg);
+/*
+Darwin handles 1 and 2 byte structs specially by loading h/b into the arg
+register.  Should this case include linux/ppc?
+*/
+#if __APPLE__
+                                       if (size == 2)
+                                               ppc_sth (code, ainfo->reg + cur_reg, doffset, inst->inst_basereg);
+                                       else if (size == 1)
+                                               ppc_stb (code, ainfo->reg + cur_reg, doffset, inst->inst_basereg);
+                                       else 
+#endif
+                                               ppc_stw (code, ainfo->reg + cur_reg, doffset, inst->inst_basereg);
                                        soffset += sizeof (gpointer);
                                        doffset += sizeof (gpointer);
                                }