2008-09-07 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Sun, 7 Sep 2008 10:25:11 +0000 (10:25 -0000)
committerMark Probst <mark.probst@gmail.com>
Sun, 7 Sep 2008 10:25:11 +0000 (10:25 -0000)
* marshal.c (mono_type_native_stack_size): Treat
MONO_TYPE_TYPEDBYREF like MONO_TYPE_VALUETYPE.

2008-09-07  Mark Probst  <mark.probst@gmail.com>

* method-to-ir.c (mono_method_to_ir2): Disable tail calls for PPC
until they're implemented properly.

* exceptions-ppc.c: Use arch-independent exception-handling code
instead of custom one.

* exceptions-ppc.c, mini-ppc.c, mini-ppc.h: Bug fixes and changes
for Linear IR.

* tramp-ppc.c, mini-ppc.c: Fixed warnings.

* decompose.c, aot-runtime.c, aot-compiler.c: PPC code also
applies when __powerpc__ is defined.

2008-09-07  Mark Probst  <mark.probst@gmail.com>

* libtest.c: Darwin structure alignment also applies to PPC.

2008-09-07  Mark Probst  <mark.probst@gmail.com>

* ppc/ppc-codegen.h (ppc_load): Inserted cast to fix some
warnings.

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

15 files changed:
mono/arch/ChangeLog
mono/arch/ppc/ppc-codegen.h
mono/metadata/ChangeLog
mono/metadata/marshal.c
mono/mini/ChangeLog
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/decompose.c
mono/mini/exceptions-ppc.c
mono/mini/method-to-ir.c
mono/mini/mini-ppc.c
mono/mini/mini-ppc.h
mono/mini/tramp-ppc.c
mono/tests/ChangeLog
mono/tests/libtest.c

index b286a8f70dc504fddeec1e0c70193aa2811ab794..e4956c32e79aa300d35c195f5e0ee2fd44966a3a 100644 (file)
@@ -1,3 +1,8 @@
+2008-09-07  Mark Probst  <mark.probst@gmail.com>
+
+       * ppc/ppc-codegen.h (ppc_load): Inserted cast to fix some
+       warnings.
+
 2008-06-16  Mark Probst  <mark.probst@gmail.com>
 
        * amd64/amd64-codegen.h: Removed extraneous parenthesis in a macro
index c3181e7bf236f736369a239abf70dcb30fa0848e..ebcc21e3ad1bdab23184bfe74756e8c9fa6b9ae4 100644 (file)
@@ -123,7 +123,7 @@ enum {
 #define ppc_is_uimm16(val) ((gint)(val) >= 0 && (gint)(val) <= 65535)
 
 #define ppc_load(c,D,v) do {   \
-               if (ppc_is_imm16 ((v))) {       \
+               if (ppc_is_imm16 ((guint32)(v)))        {       \
                        ppc_li ((c), (D), (guint16)(v));        \
                } else {        \
                        ppc_lis ((c), (D), (guint32)(v) >> 16); \
index b245437ccb371915cc1fd72a8b8232d86ca2f3a1..2aa37514383336b1805a561950747b7f30d9facf 100644 (file)
@@ -1,3 +1,8 @@
+2008-09-07  Mark Probst  <mark.probst@gmail.com>
+
+       * marshal.c (mono_type_native_stack_size): Treat
+       MONO_TYPE_TYPEDBYREF like MONO_TYPE_VALUETYPE.
+
 2008-09-04  Jb Evain  <jbevain@novell.com>
 
        * class.c (mono_class_is_assignable_from): fix assignability of nullables
index 0c176cd588667d2e4d98e30822d39143c0d74bda..cf716c61d2321af93f114f0314ed9158aa7185b8 100644 (file)
@@ -11209,7 +11209,6 @@ mono_type_native_stack_size (MonoType *t, guint32 *align)
        case MONO_TYPE_PTR:
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_ARRAY:
-       case MONO_TYPE_TYPEDBYREF:
                *align = 4;
                return 4;
        case MONO_TYPE_R4:
@@ -11220,6 +11219,7 @@ mono_type_native_stack_size (MonoType *t, guint32 *align)
        case MONO_TYPE_R8:
                *align = 4;
                return 8;
+       case MONO_TYPE_TYPEDBYREF:
        case MONO_TYPE_VALUETYPE: {
                guint32 size;
 
index 8e574a29ee909dff6db6a6150acc65b33fcfdead..827cb5ae5d5c677222d4a9ea3b104e437d1f64e8 100644 (file)
@@ -1,3 +1,19 @@
+2008-09-07  Mark Probst  <mark.probst@gmail.com>
+
+       * method-to-ir.c (mono_method_to_ir2): Disable tail calls for PPC
+       until they're implemented properly.
+
+       * exceptions-ppc.c: Use arch-independent exception-handling code
+       instead of custom one.
+
+       * exceptions-ppc.c, mini-ppc.c, mini-ppc.h: Bug fixes and changes
+       for Linear IR.
+
+       * tramp-ppc.c, mini-ppc.c: Fixed warnings.
+
+       * decompose.c, aot-runtime.c, aot-compiler.c: PPC code also
+       applies when __powerpc__ is defined.
+
 2008-09-06  Zoltan Varga  <vargaz@gmail.com>
 
        * aot-runtime.c (mono_aot_get_method): Add another cache mapping wrapper
index a7059a946e83dd96f50137ec127c84521c3e5e89..fcf1ef9088069a7c3ca5d69f3d0b99e269172a61 100644 (file)
@@ -72,7 +72,7 @@
 #define SHARED_EXT ".so"
 #endif
 
-#if defined(sparc) || defined(__ppc__) || defined(__MACH__)
+#if defined(sparc) || defined(__ppc__) || defined(__powerpc__) || defined(__MACH__)
 #define AS_STRING_DIRECTIVE ".asciz"
 #else
 /* GNU as */
index e7e1463320bd0a929ab9809254048bad88f04750..b34b45530a9169c625319c038fc39437b86b04da 100644 (file)
@@ -57,7 +57,7 @@
 
 #ifdef PLATFORM_WIN32
 #define SHARED_EXT ".dll"
-#elif (defined(__ppc__) || defined(__ppc64__)) || defined(__MACH__)
+#elif (defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) || defined(__MACH__)
 #define SHARED_EXT ".dylib"
 #else
 #define SHARED_EXT ".so"
index 359163009e0214921bc77ea8fd455b44ee9a65f7..ded99802dd628304eb006c470ecbc150fcb453b3 100644 (file)
@@ -164,7 +164,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins)
                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, ins->dreg, ins->sreg1, 0);
                ins->opcode = OP_NOP;
                break;
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__powerpc__)
        case OP_LADD_OVF:
                /* ADC sets the condition code */
                MONO_EMIT_NEW_BIALU (cfg, OP_ADDCC, ins->dreg + 1, ins->sreg1 + 1, ins->sreg2 + 1);
@@ -666,7 +666,7 @@ mono_decompose_long_opts (MonoCompile *cfg)
                                MONO_EMIT_NEW_BIALU (cfg, OP_ISBB, tree->dreg + 2, tree->sreg1 + 2, tree->sreg2 + 2);
                                break;
 
-#if defined(__ppc__)
+#if defined(__ppc__) || defined(__powerpc__)
                        case OP_LADD_OVF:
                                /* ADC sets the condition code */
                                MONO_EMIT_NEW_BIALU (cfg, OP_ADDCC, tree->dreg + 1, tree->sreg1 + 1, tree->sreg2 + 1);
@@ -745,7 +745,7 @@ mono_decompose_long_opts (MonoCompile *cfg)
 #elif defined(__arm__)
                                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ARM_RSBS_IMM, tree->dreg + 1, tree->sreg1 + 1, 0);
                                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ARM_RSC_IMM, tree->dreg + 2, tree->sreg1 + 2, 0);
-#elif defined(__ppc__)
+#elif defined(__ppc__) || defined(__powerpc__)
                                /* This is the old version from inssel-long32.brg */
                                MONO_EMIT_NEW_UNALU (cfg, OP_INOT, tree->dreg + 1, tree->sreg1 + 1);
                                MONO_EMIT_NEW_UNALU (cfg, OP_INOT, tree->dreg + 2, tree->sreg1 + 2);
index 4350716f42dd4c58de893410e5b5bae819594a0b..c79ffa27c6118a5ba7b490236aeb3a0717e7ef88 100644 (file)
@@ -26,8 +26,6 @@
 #include "mini.h"
 #include "mini-ppc.h"
 
-static gboolean arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only);
-
 /*
 
 struct sigcontext {
@@ -295,7 +293,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gulong *
                if (!rethrow)
                        mono_ex->stack_trace = NULL;
        }
-       arch_handle_exception (&ctx, exc, FALSE);
+       mono_handle_exception (&ctx, exc, (gpointer)eip, FALSE);
        restore_context (&ctx);
 
        g_assert_not_reached ();
@@ -341,7 +339,7 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo
        //ppc_break (code);
        if (by_name) {
                ppc_mr (code, ppc_r5, ppc_r3);
-               ppc_load (code, ppc_r3, mono_defaults.corlib);
+               ppc_load (code, ppc_r3, (guint32)mono_defaults.corlib);
                ppc_load (code, ppc_r4, "System");
                ppc_load (code, ppc_r0, mono_exception_from_name);
                ppc_mtctr (code, ppc_r0);
@@ -499,7 +497,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                *new_ctx = *ctx;
                setup_context (new_ctx);
 
-               if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
+               if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) {
                        /* remove any unused lmf */
                        *lmf = (*lmf)->previous_lmf;
                }
@@ -510,7 +508,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                        if (!ji->method->wrapper_type)
                                *managed = TRUE;
 
-               sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_BP (ctx);
+               sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
                MONO_CONTEXT_SET_BP (new_ctx, sframe->sp);
                if (ji->method->save_lmf) {
                        memcpy (&new_ctx->fregs, (char*)sframe->sp - sizeof (double) * MONO_SAVED_FREGS, sizeof (double) * MONO_SAVED_FREGS);
@@ -543,22 +541,25 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInf
                *new_ctx = *ctx;
                setup_context (new_ctx);
 
-               if (!(*lmf)->method)
-                       return (gpointer)-1;
-
                if ((ji = mono_jit_info_table_find (domain, (gpointer)(*lmf)->eip))) {
                } else {
+                       if (!(*lmf)->method)
+                               return (gpointer)-1;
+
                        memset (res, 0, sizeof (MonoJitInfo));
                        res->method = (*lmf)->method;
                }
 
-               /*sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_BP (ctx);
+               /*sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
                MONO_CONTEXT_SET_BP (new_ctx, sframe->sp);
                MONO_CONTEXT_SET_IP (new_ctx, sframe->lr);*/
                MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp);
                MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip);
                memcpy (&new_ctx->regs, (*lmf)->iregs, sizeof (gulong) * MONO_SAVED_GREGS);
                memcpy (&new_ctx->fregs, (*lmf)->fregs, sizeof (double) * MONO_SAVED_FREGS);
+
+               /* FIXME: what about trampoline LMF frames?  see exceptions-x86.c */
+
                *lmf = (*lmf)->previous_lmf;
 
                return ji ? ji : res;
@@ -608,7 +609,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean test_only)
 
        restore_context = mono_arch_get_restore_context ();
        mono_arch_sigctx_to_monoctx (sigctx, &mctx);
-       arch_handle_exception (&mctx, obj, test_only);
+       mono_handle_exception (&mctx, obj, (gpointer)mctx.sc_ir, test_only);
        restore_context (&mctx);
 }
 
@@ -651,8 +652,9 @@ mono_arch_handle_altstack_exception (void *sigctx, gpointer fault_addr, gboolean
        uc_copy = (ucontext_t*)(sp + 16);
        memcpy (uc_copy, uc, sizeof (os_ucontext));
 #ifdef __linux__
-       uc_copy->uc_mcontext.uc_regs = (char*)uc_copy + offsetof(ucontext_t, uc_mcontext.uc_regs);
+       uc_copy->uc_mcontext.uc_regs = (gpointer)((char*)uc_copy + ((char*)uc->uc_mcontext.uc_regs - (char*)uc));
 #endif
+       g_assert (mono_arch_ip_from_context (uc) == mono_arch_ip_from_context (uc_copy));
        /* at the return form the signal handler execution starts in altstack_handle_and_restore() */
        UCONTEXT_REG_LNK(uc) = UCONTEXT_REG_NIP(uc);
        UCONTEXT_REG_NIP(uc) = (unsigned long)altstack_handle_and_restore;
@@ -673,7 +675,7 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
 
        mono_arch_sigctx_to_monoctx (ctx, &mctx);
 
-       result = arch_handle_exception (&mctx, obj, test_only);
+       result = mono_handle_exception (&mctx, obj, (gpointer)mctx.sc_ir, test_only);
        /* restore the context so that returning from the signal handler will invoke
         * the catch clause 
         */
@@ -681,181 +683,6 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
        return result;
 }
 
-/**
- * arch_handle_exception:
- * @ctx: saved processor state
- * @obj: the exception object
- * @test_only: only test if the exception is caught, but dont call handlers
- *
- *
- */
-static gboolean
-arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
-{
-       MonoDomain *domain = mono_domain_get ();
-       MonoJitInfo *ji, rji;
-       static int (*call_filter) (MonoContext *, gpointer, gpointer) = NULL;
-       MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
-       MonoLMF *lmf = jit_tls->lmf;            
-       GList *trace_ips = NULL;
-       MonoException *mono_ex;
-       MonoArray *initial_trace_ips = NULL;
-       int frame_count = 0;
-       gboolean has_dynamic_methods = FALSE;
-
-       g_assert (ctx != NULL);
-       if (!obj) {
-               MonoException *ex = mono_get_exception_null_reference ();
-               ex->message = mono_string_new (domain, 
-                       "Object reference not set to an instance of an object");
-               obj = (MonoObject *)ex;
-       } 
-
-       if (mono_object_isinst (obj, mono_defaults.exception_class)) {
-               mono_ex = (MonoException*)obj;
-               initial_trace_ips = mono_ex->trace_ips;
-       } else {
-               mono_ex = NULL;
-       }
-
-
-       if (!call_filter)
-               call_filter = mono_arch_get_call_filter ();
-
-       g_assert (jit_tls->end_of_stack);
-       g_assert (jit_tls->abort_func);
-
-       if (!test_only) {
-               MonoContext ctx_cp = *ctx;
-               setup_context (&ctx_cp);
-               if (mono_jit_trace_calls != NULL)
-                       g_print ("EXCEPTION handling: %s\n", mono_object_class (obj)->name);
-               if (!arch_handle_exception (&ctx_cp, obj, TRUE)) {
-                       if (mono_break_on_exc)
-                               G_BREAKPOINT ();
-                       mono_unhandled_exception (obj);
-               }
-       }
-
-       memset (&rji, 0, sizeof (rji));
-
-       while (1) {
-               MonoContext new_ctx;
-
-               setup_context (&new_ctx);
-               ji = mono_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx, 
-                                             NULL, &lmf, NULL, NULL);
-               if (!ji) {
-                       g_warning ("Exception inside function without unwind info");
-                       g_assert_not_reached ();
-               }
-
-               if (ji != (gpointer)-1) {
-                       frame_count ++;
-                       
-                       if (test_only && ji->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && mono_ex) {
-                               /* 
-                                * Avoid overwriting the stack trace if the exception is
-                                * rethrown. Also avoid giant stack traces during a stack
-                                * overflow.
-                                */
-                               if (!initial_trace_ips && (frame_count < 1000)) {
-                                       trace_ips = g_list_prepend (trace_ips, MONO_CONTEXT_GET_IP (ctx));
-
-                               }
-                       }
-
-                       if (ji->method->dynamic)
-                               has_dynamic_methods = TRUE;
-
-                       if (ji->num_clauses) {
-                               int i;
-                               
-                               g_assert (ji->clauses);
-                       
-                               for (i = 0; i < ji->num_clauses; i++) {
-                                       MonoJitExceptionInfo *ei = &ji->clauses [i];
-                                       gboolean filtered = FALSE;
-
-                                       if (ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
-                                           MONO_CONTEXT_GET_IP (ctx) <= ei->try_end) { 
-                                               /* catch block */
-
-                                               if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE) || (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)) {
-                                                       /* store the exception object int cfg->excvar */
-                                                       g_assert (ei->exvar_offset);
-                                                       /* need to use the frame pointer (ppc_r31), not r1 (regs start from register r13): methods with clauses always have r31 */
-                                                       *((gpointer *)((char *)(ctx->regs [ppc_r31-13]) + ei->exvar_offset)) = obj;
-                                               }
-
-                                               if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER)
-                                                       filtered = call_filter (ctx, ei->data.filter, mono_ex);
-
-                                               if ((ei->flags == MONO_EXCEPTION_CLAUSE_NONE && 
-                                                    mono_object_isinst (obj, ei->data.catch_class)) || filtered) {
-                                                       if (test_only) {
-                                                               if (mono_ex && !initial_trace_ips) {
-                                                                       trace_ips = g_list_reverse (trace_ips);
-                                                                       mono_ex->trace_ips = glist_to_array (trace_ips, mono_defaults.int_class);
-                                                                       if (has_dynamic_methods)
-                                                                               /* These methods could go away anytime, so compute the stack trace now */
-                                                                               mono_ex->stack_trace = ves_icall_System_Exception_get_trace (mono_ex);
-                                                               }
-                                                               g_list_free (trace_ips);
-                                                               return TRUE;
-                                                       }
-                                                       if (mono_jit_trace_calls != NULL)
-                                                               g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
-                                                       /*printf ("stack for catch: %p\n", MONO_CONTEXT_GET_BP (ctx));*/
-                                                       MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
-                                                       jit_tls->lmf = lmf;
-                                                       return 0;
-                                               }
-                                               if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
-                                                   MONO_CONTEXT_GET_IP (ctx) < ei->try_end &&
-                                                   (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT)) {
-                                                       if (mono_jit_trace_calls != NULL)
-                                                               g_print ("EXCEPTION: fault clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
-                                                       call_filter (ctx, ei->handler_start, NULL);
-                                               }
-                                               if (!test_only && ei->try_start <= MONO_CONTEXT_GET_IP (ctx) && 
-                                                   MONO_CONTEXT_GET_IP (ctx) < ei->try_end &&
-                                                   (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
-                                                       if (mono_jit_trace_calls != NULL)
-                                                               g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
-                                                       call_filter (ctx, ei->handler_start, NULL);
-                                               }
-                                               
-                                       }
-                               }
-                       }
-               }
-
-               *ctx = new_ctx;
-               setup_context (ctx);
-
-               if ((ji == (gpointer)-1) || MONO_CONTEXT_GET_BP (ctx) >= jit_tls->end_of_stack) {
-                       if (!test_only) {
-                               jit_tls->lmf = lmf;
-                               jit_tls->abort_func (obj);
-                               g_assert_not_reached ();
-                       } else {
-                               if (mono_ex && !initial_trace_ips) {
-                                       trace_ips = g_list_reverse (trace_ips);
-                                       mono_ex->trace_ips = glist_to_array (trace_ips, mono_defaults.int_class);
-                                       if (has_dynamic_methods)
-                                               /* These methods could go away anytime, so compute the stack trace now */
-                                               mono_ex->stack_trace = ves_icall_System_Exception_get_trace (mono_ex);
-                               }
-                               g_list_free (trace_ips);
-                               return FALSE;
-                       }
-               }
-       }
-
-       g_assert_not_reached ();
-}
-
 gboolean
 mono_arch_has_unwind_info (gconstpointer addr)
 {
index ac9493a3aefa03471dd3ce5b890a063da1e86bbc..488aa8d740536e7be7e106cc8113deba9c3b807f 100644 (file)
@@ -8998,10 +8998,12 @@ mono_method_to_ir2 (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_
                                ip += 2;
                                break;
                        case CEE_TAIL_:
+#if !defined(__ppc__) && !defined(__powerpc)
                                ins_flag   |= MONO_INST_TAILCALL;
                                cfg->flags |= MONO_CFG_HAS_TAIL;
                                /* Can't inline tail calls at this time */
                                inline_costs += 100000;
+#endif
                                ip += 2;
                                break;
                        case CEE_INITOBJ:
index d0799f2461d4718912dd04e3760a56740dadeda4..baa20014712d00ffc3c1062ce7f1c511789c7f16 100644 (file)
 #include <sys/sysctl.h>
 #endif
 
+/* From ir-emit.h */
+static inline guint32
+alloc_ireg (MonoCompile *cfg)
+{
+       return cfg->next_vreg ++;
+}
+
+static inline guint32
+alloc_lreg (MonoCompile *cfg)
+{
+#if SIZEOF_VOID_P == 8
+       return cfg->next_vreg ++;
+#else
+       /* Use a pair of consecutive vregs */
+       guint32 res = cfg->next_vreg;
+
+       cfg->next_vreg += 3;
+
+       return res;
+#endif
+}
+
+static inline guint32
+alloc_freg (MonoCompile *cfg)
+{
+#ifdef MONO_ARCH_SOFT_FLOAT
+       /* Allocate an lvreg so float ops can be decomposed into long ops */
+       return alloc_lreg (cfg);
+#else
+       /* Allocate these from the same pool as the int regs */
+       return cfg->next_vreg ++;
+#endif
+}
+
+static inline guint32
+alloc_dreg (MonoCompile *cfg, MonoStackType stack_type)
+{
+       switch (stack_type) {
+       case STACK_I4:
+       case STACK_PTR:
+       case STACK_MP:
+       case STACK_OBJ:
+               return alloc_ireg (cfg);
+       case STACK_R8:
+               return alloc_freg (cfg);
+       case STACK_I8:
+               return alloc_lreg (cfg);
+       case STACK_VTYPE:
+               return alloc_ireg (cfg);
+       default:
+               g_assert_not_reached ();
+       }
+}
+
+#ifdef MONO_ARCH_SOFT_FLOAT
+#define DECOMPOSE_INTO_REGPAIR(stack_type) ((stack_type) == STACK_I8 || (stack_type) == STACK_R8)
+#else
+#define DECOMPOSE_INTO_REGPAIR(stack_type) ((stack_type) == STACK_I8)
+#endif
+
+#define NEW_VARLOADA(cfg,dest,var,vartype) do {        \
+        MONO_INST_NEW ((cfg), (dest), OP_LDADDR); \
+               (dest)->inst_p0 = (var); \
+               (var)->flags |= MONO_INST_INDIRECT;     \
+               (dest)->type = STACK_MP;        \
+               (dest)->klass = (var)->klass;   \
+        (dest)->dreg = alloc_dreg ((cfg), STACK_MP); \
+               if (SIZEOF_VOID_P == 4 && DECOMPOSE_INTO_REGPAIR ((var)->type)) { MonoInst *var1 = get_vreg_to_inst (cfg, (var)->dreg + 1); MonoInst *var2 = get_vreg_to_inst (cfg, (var)->dreg + 2); g_assert (var1); g_assert (var2); var1->flags |= MONO_INST_INDIRECT; var2->flags |= MONO_INST_INDIRECT; } \
+       } while (0)
+
+#define EMIT_NEW_VARLOADA(cfg,dest,var,vartype) do { NEW_VARLOADA ((cfg), (dest), (var), (vartype)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0)
+
 #define FORCE_INDIR_CALL 1
 
 enum {
@@ -635,21 +707,24 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple)
 }
 
 #if __APPLE__
-/* size == 4 is checked already */
 static gboolean
-has_only_a_r4_field (MonoClass *klass)
+has_only_a_r48_field (MonoClass *klass)
 {
        gpointer iter;
        MonoClassField *f;
+       gboolean have_field = FALSE;
        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;
+                       if (have_field)
+                               return FALSE;
+                       if (!f->type->byref && (f->type->type == MONO_TYPE_R4 || f->type->type == MONO_TYPE_R8))
+                               have_field = TRUE;
+                       else
+                               return FALSE;
                }
        }
-       return FALSE;
+       return have_field;
 }
 #endif
 
@@ -745,8 +820,8 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                        else
                            size = mono_class_value_size (klass, NULL);
 #if __APPLE__
-                       if (size == 4 && has_only_a_r4_field (klass)) {
-                               cinfo->args [n].size = 4;
+                       if ((size == 4 || size == 8) && has_only_a_r48_field (klass)) {
+                               cinfo->args [n].size = size;
 
                                /* It was 7, now it is 8 in LinuxPPC */
                                if (fr <= PPC_LAST_FPARG_REG) {
@@ -754,12 +829,14 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                                        cinfo->args [n].reg = fr;
                                        fr ++;
                                        FP_ALSO_IN_REG (gr ++);
-                                       ALWAYS_ON_STACK (stack_size += 4);
+                                       if (size == 8)
+                                               FP_ALSO_IN_REG (gr ++);
+                                       ALWAYS_ON_STACK (stack_size += size);
                                } 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;
+                                       stack_size += 8;
                                }
                                n++;
                                break;
@@ -771,21 +848,22 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke)
                        {
                                int align_size = size;
                                int nwords = 0;
+                               int rest = PPC_LAST_ARG_REG - gr + 1;
+                               int n_in_regs;
                                align_size += (sizeof (gpointer) - 1);
                                align_size &= ~(sizeof (gpointer) - 1);
                                nwords = (align_size + sizeof (gpointer) -1 ) / sizeof (gpointer);
+                               n_in_regs = rest >= nwords? nwords: rest;
                                cinfo->args [n].regtype = RegTypeStructByVal;
                                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;
                                }
+                               gr += n_in_regs;
                                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);*/
                                stack_size += nwords * sizeof (gpointer);
@@ -992,15 +1070,20 @@ mono_arch_allocate_vars (MonoCompile *m)
        curinst = 0;
        if (MONO_TYPE_ISSTRUCT (sig->ret)) {
                m->ret->opcode = OP_REGVAR;
-               m->ret->inst_c0 = ppc_r3;
+               m->ret->inst_c0 = m->ret->dreg = ppc_r3;
        } else {
-               /* FIXME: handle long and FP values */
+               /* FIXME: handle long values? */
                switch (mono_type_get_underlying_type (sig->ret)->type) {
                case MONO_TYPE_VOID:
                        break;
+               case MONO_TYPE_R4:
+               case MONO_TYPE_R8:
+                       m->ret->opcode = OP_REGVAR;
+                       m->ret->inst_c0 = m->ret->dreg = ppc_f1;
+                       break;
                default:
                        m->ret->opcode = OP_REGVAR;
-                       m->ret->inst_c0 = ppc_r3;
+                       m->ret->inst_c0 = m->ret->dreg = ppc_r3;
                        break;
                }
        }
@@ -1109,7 +1192,12 @@ mono_arch_allocate_vars (MonoCompile *m)
                if (inst->opcode != OP_REGVAR) {
                        inst->opcode = OP_REGOFFSET;
                        inst->inst_basereg = frame_reg;
-                       size = mono_type_size (sig->params [i], &align);
+                       if (sig->pinvoke) {
+                               size = mono_type_native_stack_size (sig->params [i], &align);
+                               inst->backend.is_pinvoke = 1;
+                       } else {
+                               size = mono_type_size (sig->params [i], &align);
+                       }
                        offset += align - 1;
                        offset &= ~(align - 1);
                        inst->inst_offset = offset;
@@ -1127,6 +1215,13 @@ mono_arch_allocate_vars (MonoCompile *m)
        /* change sign? */
        m->stack_offset = offset;
 
+       if (m->new_ir && sig->call_convention == MONO_CALL_VARARG) {
+               CallInfo *cinfo = calculate_sizes (m->method->signature, m->method->signature->pinvoke);
+
+               m->sig_cookie = cinfo->sig_cookie.offset;
+
+               g_free(cinfo);
+        }
 }
 
 void
@@ -1336,16 +1431,14 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                                mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE);
                        }
                } else if (ainfo->regtype == RegTypeStructByAddr) {
-                       if (ainfo->offset) {
-                               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ppc_r1, ainfo->offset, in->dreg);
-                       } else {
-                               MONO_INST_NEW (cfg, ins, OP_MOVE);
-                               ins->dreg = mono_alloc_ireg (cfg);
-                               ins->sreg1 = in->dreg;
-                               MONO_ADD_INS (cfg->cbb, ins);
-
-                               mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE);
-                       }
+                       MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
+                       ins->opcode = OP_OUTARG_VT;
+                       ins->sreg1 = in->dreg;
+                       ins->klass = in->klass;
+                       ins->inst_p0 = call;
+                       ins->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
+                       memcpy (ins->inst_p1, ainfo, sizeof (ArgInfo));
+                       MONO_ADD_INS (cfg->cbb, ins);
                } else if (ainfo->regtype == RegTypeStructByVal) {
                        /* this is further handled in mono_arch_emit_outarg_vt () */
                        MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
@@ -1368,13 +1461,27 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ppc_r1, ainfo->offset, in->dreg);
                        }
                } else if (ainfo->regtype == RegTypeFP) {
-                       MONO_INST_NEW (cfg, ins, OP_FMOVE);
-                       ins->dreg = mono_alloc_freg (cfg);
-                       ins->sreg1 = in->dreg;
-                       MONO_ADD_INS (cfg->cbb, ins);
+                       if (t->type == MONO_TYPE_VALUETYPE) {
+                               /* this is further handled in mono_arch_emit_outarg_vt () */
+                               MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
+                               ins->opcode = OP_OUTARG_VT;
+                               ins->sreg1 = in->dreg;
+                               ins->klass = in->klass;
+                               ins->inst_p0 = call;
+                               ins->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
+                               memcpy (ins->inst_p1, ainfo, sizeof (ArgInfo));
+                               MONO_ADD_INS (cfg->cbb, ins);
+
+                               cfg->flags |= MONO_CFG_HAS_FPOUT;
+                       } else {
+                               MONO_INST_NEW (cfg, ins, OP_FMOVE);
+                               ins->dreg = mono_alloc_freg (cfg);
+                               ins->sreg1 = in->dreg;
+                               MONO_ADD_INS (cfg->cbb, ins);
 
-                       mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, TRUE);
-                       cfg->flags |= MONO_CFG_HAS_FPOUT;
+                               mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, TRUE);
+                               cfg->flags |= MONO_CFG_HAS_FPOUT;
+                       }
                } else {
                        g_assert_not_reached ();
                }
@@ -1413,33 +1520,65 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
        int i, soffset, dreg;
        int size = 0;
 
-       soffset = 0;
-       /*
-         Darwin needs some special handling for 1 and 2 byte arguments
-       */
+       if (ainfo->regtype == RegTypeStructByVal) {
+               soffset = 0;
+               /*
+                 Darwin needs some special handling for 1 and 2 byte arguments
+               */
 #ifdef __APPLE__
-       g_assert (ins->klass);
-       size =  mono_class_native_size (ins->klass, NULL);
-       if (size == 2 || size == 1) {
-               int tmpr = mono_alloc_ireg (cfg);
-               if (size == 1)
-                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, tmpr, src->dreg, soffset);
-               else
-                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, tmpr, src->dreg, soffset);
-               dreg = mono_alloc_ireg (cfg);
-               MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, dreg, tmpr);
-               mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, FALSE);
-       } else
+               g_assert (ins->klass);
+               size =  mono_class_native_size (ins->klass, NULL);
+               if (size == 2 || size == 1) {
+                       int tmpr = mono_alloc_ireg (cfg);
+                       if (size == 1)
+                               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI1_MEMBASE, tmpr, src->dreg, soffset);
+                       else
+                               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI2_MEMBASE, tmpr, src->dreg, soffset);
+                       dreg = mono_alloc_ireg (cfg);
+                       MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, dreg, tmpr);
+                       mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, FALSE);
+               } else
 #endif
-       for (i = 0; i < ainfo->size; ++i) {
-               dreg = mono_alloc_ireg (cfg);
-               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, soffset);
-               mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg + i, FALSE);
-               soffset += sizeof (gpointer);
+                       for (i = 0; i < ainfo->size; ++i) {
+                               dreg = mono_alloc_ireg (cfg);
+                               MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, soffset);
+                               mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg + i, FALSE);
+                               soffset += sizeof (gpointer);
+                       }
+               if (ovf_size != 0)
+                       mini_emit_memcpy2 (cfg, ppc_r1, doffset + soffset, src->dreg, soffset, ovf_size * sizeof (gpointer), 0);
+       } else if (ainfo->regtype == RegTypeFP) {
+               int tmpr = mono_alloc_freg (cfg);
+               if (ainfo->size == 4)
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR4_MEMBASE, tmpr, src->dreg, 0);
+               else
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmpr, src->dreg, 0);
+               dreg = mono_alloc_freg (cfg);
+               MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, dreg, tmpr);
+               mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, TRUE);
+       } else {
+               MonoInst *vtcopy = mono_compile_create_var (cfg, &src->klass->byval_arg, OP_LOCAL);
+               MonoInst *load;
+               guint32 size;
+
+               /* FIXME: alignment? */
+               if (call->signature->pinvoke) {
+                       size = mono_type_native_stack_size (&src->klass->byval_arg, NULL);
+                       vtcopy->backend.is_pinvoke = 1;
+               } else {
+                       size = mini_type_stack_size (cfg->generic_sharing_context, &src->klass->byval_arg, NULL);
+               }
+               if (size > 0)
+                       g_assert (ovf_size > 0);
+
+               EMIT_NEW_VARLOADA (cfg, load, vtcopy, vtcopy->inst_vtype);
+               mini_emit_memcpy2 (cfg, load->dreg, 0, src->dreg, 0, size, 0);
+
+               if (ainfo->offset)
+                       MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ppc_r1, ainfo->offset, load->dreg);
+               else
+                       mono_call_inst_add_outarg_reg (cfg, call, load->dreg, ainfo->reg, FALSE);
        }
-       //g_print ("vt size: %d at R%d + %d\n", doffset, vt->inst_basereg, vt->inst_offset);
-       if (ovf_size != 0)
-               mini_emit_memcpy2 (cfg, ppc_r1, doffset + soffset, src->dreg, soffset, ovf_size * sizeof (gpointer), 0);
 }
 
 void
@@ -1841,7 +1980,7 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -8, msw_reg);
                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_XOR_IMM, xored, ins->sreg1, 0x80000000);
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -4, xored);
-               MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, &adjust_val);
+               MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, (gpointer)&adjust_val);
                MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, ppc_sp, -8);
                MONO_EMIT_NEW_BIALU (cfg, OP_FSUB, ins->dreg, tmp_reg, adj_reg);
                ins->opcode = OP_NOP;
@@ -2190,7 +2329,7 @@ loop_start:
                case OP_R8CONST:
                case OP_R4CONST:
                        NEW_INS (cfg, temp, OP_ICONST);
-                       temp->inst_c0 = ins->inst_p0;
+                       temp->inst_c0 = (guint32)ins->inst_p0;
                        temp->dreg = mono_regstate_next_int (cfg->rs);
                        ins->inst_basereg = temp->dreg;
                        ins->inst_offset = 0;
@@ -2273,7 +2412,7 @@ mono_emit_stack_alloc (guchar *code, MonoInst* tree)
 
 typedef struct {
        guchar *code;
-       guchar *target;
+       const guchar *target;
        int absolute;
        int found;
 } PatchData;
@@ -2288,7 +2427,7 @@ search_thunk_slot (void *data, int csize, int bsize, void *user_data) {
        guint32 *endthunks = (guint32*)(code + bsize);
        guint32 load [2];
        guchar *templ;
-       int i, count = 0;
+       int count = 0;
        int difflow, diffhigh;
 
        /* always ensure a call from pdata->code can reach to the thunks without further thunks */
@@ -2346,7 +2485,7 @@ search_thunk_slot (void *data, int csize, int bsize, void *user_data) {
 }
 
 static void
-handle_thunk (int absolute, guchar *code, guchar *target) {
+handle_thunk (int absolute, guchar *code, const guchar *target) {
        MonoDomain *domain = mono_domain_get ();
        PatchData pdata;
 
@@ -2371,7 +2510,7 @@ handle_thunk (int absolute, guchar *code, guchar *target) {
 }
 
 void
-ppc_patch (guchar *code, guchar *target)
+ppc_patch (guchar *code, const guchar *target)
 {
        guint32 ins = *(guint32*)code;
        guint32 prim = ins >> 26;
@@ -2809,7 +2948,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                        break;
                case OP_IDIV: {
-                       guint32 *divisor_is_m1;
+                       guint8 *divisor_is_m1;
                          /* XER format: SO, OV, CA, reserved [21 bits], count [8 bits]
                          */
                        ppc_cmpi (code, 0, 0, ins->sreg2, -1);
@@ -3064,7 +3203,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;
+                       guint8 * zero_loop_jump, * zero_loop_start;
                        /* keep alignment */
                        int alloca_waste = PPC_STACK_PARAM_OFFSET + cfg->param_area + 31;
                        int area_offset = alloca_waste;
@@ -3353,7 +3492,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_LCONV_TO_OVF_I4_2:
                case OP_LCONV_TO_OVF_I: {
-                       guint32 *negative_branch, *msword_positive_branch, *msword_negative_branch, *ovf_ex_target;
+                       guint8 *negative_branch, *msword_positive_branch, *msword_negative_branch, *ovf_ex_target;
                        // Check if its negative
                        ppc_cmpi (code, 0, 0, ins->sreg1, 0);
                        negative_branch = code;
@@ -3521,7 +3660,7 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, Mono
 
        for (patch_info = ji; patch_info; patch_info = patch_info->next) {
                unsigned char *ip = patch_info->ip.i + code;
-               const unsigned char *target;
+               unsigned char *target;
 
                target = mono_resolve_patch_target (method, domain, code, patch_info, run_cctors);
 
@@ -3819,6 +3958,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                int size = 0;
                                g_assert (ppc_is_imm16 (inst->inst_offset));
                                g_assert (ppc_is_imm16 (inst->inst_offset + ainfo->size * sizeof (gpointer)));
+                               /* FIXME: what if there is no class? */
                                if (mono_class_from_mono_type (inst->inst_vtype))
                                        size = mono_class_native_size (mono_class_from_mono_type (inst->inst_vtype), NULL);
                                for (cur_reg = 0; cur_reg < ainfo->size; ++cur_reg) {
@@ -4060,12 +4200,10 @@ void
 mono_arch_emit_exceptions (MonoCompile *cfg)
 {
        MonoJumpInfo *patch_info;
-       int nthrows, i;
+       int i;
        guint8 *code;
        const guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM] = {NULL};
        guint8 exc_throw_found [MONO_EXC_INTRINS_NUM] = {0};
-       guint32 code_size;
-       int exc_count = 0;
        int max_epilog_size = 50;
 
        /* count the number of exception infos */
@@ -4084,7 +4222,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                } else if (patch_info->type == MONO_PATCH_INFO_BB_OVF)
                        max_epilog_size += 12;
                else if (patch_info->type == MONO_PATCH_INFO_EXC_OVF) {
-                       MonoOvfJump *ovfj = patch_info->data.target;
+                       MonoOvfJump *ovfj = (MonoOvfJump*)patch_info->data.target;
                        i = exception_id_by_name (ovfj->data.exception);
                        if (!exc_throw_found [i]) {
                                max_epilog_size += 24;
@@ -4106,7 +4244,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
        for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
                switch (patch_info->type) {
                case MONO_PATCH_INFO_BB_OVF: {
-                       MonoOvfJump *ovfj = patch_info->data.target;
+                       MonoOvfJump *ovfj = (MonoOvfJump*)patch_info->data.target;
                        unsigned char *ip = patch_info->ip.i + cfg->native_code;
                        /* patch the initial jump */
                        ppc_patch (ip, code);
@@ -4120,7 +4258,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                        break;
                }
                case MONO_PATCH_INFO_EXC_OVF: {
-                       MonoOvfJump *ovfj = patch_info->data.target;
+                       MonoOvfJump *ovfj = (MonoOvfJump*)patch_info->data.target;
                        MonoJumpInfo *newji;
                        unsigned char *ip = patch_info->ip.i + cfg->native_code;
                        unsigned char *bcl = code;
@@ -4255,14 +4393,14 @@ setup_tls_access (void)
                                } else {
                                        ins = (guint32*) ((char*)ins + val);
                                }
-                               code = &val;
+                               code = (guint32*)&val;
                                ppc_li (code, ppc_r0, 0x7FF2);
                                if (ins [1] == val) {
                                        /* Darwin on G4, implement */
                                        tls_mode = TLS_MODE_FAILED;
                                        return;
                                } else {
-                                       code = &val;
+                                       code = (guint32*)&val;
                                        ppc_mfspr (code, ppc_r3, 104);
                                        if (ins [1] != val) {
                                                tls_mode = TLS_MODE_FAILED;
index 7bbe9cd6452b1addbbb32dd644e9864d2ce65b86..f0dad8fa80816a973bfdd2af56e20f6b9b4d54c0 100644 (file)
@@ -18,7 +18,7 @@
  * reproduceable results for benchmarks */
 #define MONO_ARCH_CODE_ALIGNMENT 32
 
-void ppc_patch (guchar *code, guchar *target);
+void ppc_patch (guchar *code, const guchar *target);
 
 struct MonoLMF {
        gpointer    previous_lmf;
@@ -126,10 +126,11 @@ typedef struct MonoCompileArch {
 
 /* we have the stack pointer, not the base pointer in sigcontext */
 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_ir = (int)ip; } while (0); 
+/* FIXME: should be called SET_SP */
 #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_sp = (int)bp; } while (0); 
 
 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
-#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->sc_sp))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
 
 #ifdef __APPLE__
@@ -141,11 +142,10 @@ typedef struct {
 } MonoPPCStackFrame;
 
 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {       \
-               MonoPPCStackFrame *sframe;      \
-               __asm__ volatile("lwz   %0,0(r1)" : "=r" (sframe));     \
-               MONO_CONTEXT_SET_BP ((ctx), sframe->sp);        \
-               sframe = (MonoPPCStackFrame*)sframe->sp;        \
-               MONO_CONTEXT_SET_IP ((ctx), sframe->lr);        \
+               gpointer r1;                                    \
+               __asm__ volatile("mr   %0,r1" : "=r" (r1));     \
+               MONO_CONTEXT_SET_BP ((ctx), r1);                \
+               MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
        } while (0)
 
 #else
@@ -155,20 +155,15 @@ typedef struct {
        unsigned long lr;
 } MonoPPCStackFrame;
 
-#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do {     \
-               MonoPPCStackFrame *sframe;      \
-               __asm__ volatile("lwz   %0,0(1)" : "=r" (sframe));      \
-               MONO_CONTEXT_SET_BP ((ctx), sframe->sp);        \
-               sframe = (MonoPPCStackFrame*)sframe->sp;        \
-               MONO_CONTEXT_SET_IP ((ctx), sframe->lr);        \
+#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {       \
+               gpointer r1;                                    \
+               __asm__ volatile("mr   %0,1" : "=r" (r1));      \
+               MONO_CONTEXT_SET_BP ((ctx), r1);                \
+               MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
        } while (0)
 
 #endif
 
-#define MONO_INIT_CONTEXT_FROM_CURRENT(ctx) MONO_INIT_CONTEXT_FROM_FUNC ((ctx), NULL)
-
-#define CUSTOM_EXCEPTION_HANDLING 1
-
 typedef struct {
        gint8 reg;
        gint8 size;
index f7cc6363da9685b5190e852922fb496da4d8af38..2b6c6b493527cb54040468e689360e2b4b3f81f0 100644 (file)
@@ -97,8 +97,8 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
         */
        if (((*code) >> 26) == 18) {
                /*g_print ("direct patching\n");*/
-               ppc_patch ((char*)code, addr);
-               mono_arch_flush_icache ((char*)code, 4);
+               ppc_patch ((guint8*)code, addr);
+               mono_arch_flush_icache ((guint8*)code, 4);
                return;
        }
        
@@ -107,7 +107,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
 
        /* the thunk-less direct call sequence: lis/ori/mtlr/blrl */
        if ((code [-1] >> 26) == 31 && (code [-2] >> 26) == 24 && (code [-3] >> 26) == 15) {
-               ppc_patch ((char*)code, addr);
+               ppc_patch ((guint8*)code, addr);
                return;
        }
        g_assert_not_reached ();
@@ -165,7 +165,7 @@ mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
 {
        guint8 *buf, *code = NULL;
        int i, offset;
-       gpointer tramp_handler;
+       gconstpointer tramp_handler;
 
        if(!code) {
                /* Now we'll create in 'buf' the PowerPC trampoline code. This
index 9e104ba8b9f37ac2117b53ad89a7142c93c08622..98d8b585601931d712b5c20a2d080a8fd8b5bbed 100644 (file)
@@ -1,3 +1,7 @@
+2008-09-07  Mark Probst  <mark.probst@gmail.com>
+
+       * libtest.c: Darwin structure alignment also applies to PPC.
+
 2008-09-06  Zoltan Varga  <vargaz@gmail.com>
 
        * libtest.c pinvoke2.cs: Add float tests.
index f3cd623b5c8ff0c11d468188e796bca6d6db269f..70d1f718e478802741f718524dde9487fbdfb594 100644 (file)
@@ -2956,7 +2956,7 @@ mono_test_marshal_ccw_itest (MonoComObject *pUnk)
  * mono_method_get_unmanaged_thunk tests
  */
 
-#if defined(__GNUC__) && defined(__i386__) && (defined(__linux__) || defined (__APPLE__))
+#if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__))) || (defined(__ppc__) && defined(__APPLE__)))
 #define ALIGN(size) __attribute__ ((aligned(size)))
 #else
 #define ALIGN(size)