Mon Jan 30 12:51:10 CET 2006 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / mini / mini-ppc.c
index 5fda64c243021122ae15adf4adf2ce95bb0f8b72..1435de5ee9864ae92fbbcc3fce236e93917fc347 100644 (file)
@@ -214,7 +214,7 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
        guint32 opts = 0;
 
        /* no ppc-specific optimizations yet */
-       *exclude_mask = MONO_OPT_INLINE;
+       *exclude_mask = 0;
        return opts;
 }
 
@@ -407,6 +407,25 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple)
        (*gr) ++;
 }
 
+#if __APPLE__
+/* size == 4 is checked already */
+static gboolean
+has_only_a_r4_field (MonoClass *klass)
+{
+       gpointer iter;
+       MonoClassField *f;
+       iter = NULL;
+       while ((f = mono_class_get_fields (klass, &iter))) {
+               if (!(f->type->attrs & FIELD_ATTRIBUTE_STATIC)) {
+                       if (!f->type->byref && f->type->type == MONO_TYPE_R4)
+                               return TRUE;
+                       return FALSE;
+               }
+       }
+       return FALSE;
+}
+#endif
+
 static CallInfo*
 calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
 {
@@ -490,6 +509,27 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                            size = mono_class_native_size (klass, NULL);
                        else
                            size = mono_class_value_size (klass, NULL);
+#if __APPLE__
+                       if (size == 4 && has_only_a_r4_field (klass)) {
+                               cinfo->args [n].size = 4;
+
+                               /* It was 7, now it is 8 in LinuxPPC */
+                               if (fr <= PPC_LAST_FPARG_REG) {
+                                       cinfo->args [n].regtype = RegTypeFP;
+                                       cinfo->args [n].reg = fr;
+                                       fr ++;
+                                       FP_ALSO_IN_REG (gr ++);
+                                       ALWAYS_ON_STACK (stack_size += 4);
+                               } else {
+                                       cinfo->args [n].offset = PPC_STACK_PARAM_OFFSET + stack_size;
+                                       cinfo->args [n].regtype = RegTypeBase;
+                                       cinfo->args [n].reg = ppc_sp; /* in the caller*/
+                                       stack_size += 4;
+                               }
+                               n++;
+                               break;
+                       }
+#endif
                        DEBUG(printf ("load %d bytes struct\n",
                                      mono_class_native_size (sig->params [i]->data.klass, NULL)));
 #if PPC_PASS_STRUCTS_BY_VALUE
@@ -2422,6 +2462,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ppc_mullw (code, ppc_r4, ins->sreg1, ins->sreg2);
                        ppc_mulhwu (code, ppc_r3, ins->sreg1, ins->sreg2);
                        break;
+               case OP_MEMORY_BARRIER:
+                       ppc_sync (code);
+                       break;
                case OP_STOREI1_MEMBASE_IMM:
                        ppc_li (code, ppc_r0, ins->inst_imm);
                        if (ppc_is_imm16 (ins->inst_offset)) {
@@ -2991,7 +3034,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_assert_not_reached ();
                        break;
                case OP_LOCALLOC: {
-                       guint32 * zero_loop_jump, zero_loop_start;
+                       guint32 * zero_loop_jump, zero_loop_start;
                        /* keep alignment */
                        int alloca_waste = PPC_STACK_PARAM_OFFSET + cfg->param_area + 31;
                        int area_offset = alloca_waste;
@@ -3197,6 +3240,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                        break;
                case OP_STORER4_MEMBASE_REG:
+                       ppc_frsp (code, ins->sreg1, ins->sreg1);
                        if (ppc_is_imm16 (ins->inst_offset)) {
                                ppc_stfs (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
                        } else {
@@ -3942,6 +3986,7 @@ exception_id_by_name (const char *name)
        if (strcmp (name, "ArrayTypeMismatchException") == 0)
                return MONO_EXC_ARRAY_TYPE_MISMATCH;
        g_error ("Unknown intrinsic exception %s\n", name);
+       return 0;
 }
 
 void
@@ -4223,18 +4268,19 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_re
 MonoInst*
 mono_arch_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
 {
-       /*
        MonoInst *ins = NULL;
 
-       if (cmethod->klass == mono_defaults.math_class) {
+       if (cmethod->klass == mono_defaults.thread_class &&
+                       strcmp (cmethod->name, "MemoryBarrier") == 0) {
+               MONO_INST_NEW (cfg, ins, OP_MEMORY_BARRIER);
+       }
+       /*if (cmethod->klass == mono_defaults.math_class) {
                if (strcmp (cmethod->name, "Sqrt") == 0) {
                        MONO_INST_NEW (cfg, ins, OP_SQRT);
                        ins->inst_i0 = args [0];
                }
-       }
+       }*/
        return ins;
-       */
-       return NULL;
 }
 
 gboolean