[runtime] Fix a problem introduced by 522663cdfad5860ffbb84b2827b9d0156c4ed623.
[mono.git] / mono / mini / mini-ppc.c
index 6970aa0fd1f758ac07d084d11668417e2bfea9a5..a7c83988da6bcf9b664fd42f7329e01923d9c913 100644 (file)
@@ -12,6 +12,7 @@
 #include "mini.h"
 #include <string.h>
 
+#include <mono/metadata/abi-details.h>
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-proclib.h>
@@ -61,9 +62,9 @@ enum {
 #define BREAKPOINT_SIZE (PPC_LOAD_SEQUENCE_LENGTH + 4)
 
 /* This mutex protects architecture specific caches */
-#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
-#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
-static CRITICAL_SECTION mini_arch_mutex;
+#define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex)
+#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
+static mono_mutex_t mini_arch_mutex;
 
 int mono_exc_esp_offset = 0;
 static int tls_mode = TLS_MODE_DETECT;
@@ -391,14 +392,14 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                        code = mono_ppc_create_pre_code_ftnptr (code);
 
                /* Replace the this argument with the target */
-               ppc_ldptr (code, ppc_r0, G_STRUCT_OFFSET (MonoDelegate, method_ptr), ppc_r3);
+               ppc_ldptr (code, ppc_r0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr), ppc_r3);
 #ifdef PPC_USES_FUNCTION_DESCRIPTOR
                /* it's a function descriptor */
                /* Can't use ldptr as it doesn't work with r0 */
                ppc_ldptr_indexed (code, ppc_r0, 0, ppc_r0);
 #endif
                ppc_mtctr (code, ppc_r0);
-               ppc_ldptr (code, ppc_r3, G_STRUCT_OFFSET (MonoDelegate, target), ppc_r3);
+               ppc_ldptr (code, ppc_r3, MONO_STRUCT_OFFSET (MonoDelegate, target), ppc_r3);
                ppc_bcctr (code, PPC_BR_ALWAYS, 0);
 
                g_assert ((code - start) <= size);
@@ -412,7 +413,7 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
                if (!aot)
                        code = mono_ppc_create_pre_code_ftnptr (code);
 
-               ppc_ldptr (code, ppc_r0, G_STRUCT_OFFSET (MonoDelegate, method_ptr), ppc_r3);
+               ppc_ldptr (code, ppc_r0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr), ppc_r3);
 #ifdef PPC_USES_FUNCTION_DESCRIPTOR
                /* it's a function descriptor */
                ppc_ldptr_indexed (code, ppc_r0, 0, ppc_r0);
@@ -510,6 +511,12 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
        return start;
 }
 
+gpointer
+mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
+{
+       return NULL;
+}
+
 gpointer
 mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
 {
@@ -613,7 +620,7 @@ mono_arch_init (void)
        if (mono_cpu_count () > 1)
                cpu_hw_caps |= PPC_SMP_CAPABLE;
 
-       InitializeCriticalSection (&mini_arch_mutex);
+       mono_mutex_init_recursive (&mini_arch_mutex);
 
        ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
        bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
@@ -628,7 +635,7 @@ mono_arch_init (void)
 void
 mono_arch_cleanup (void)
 {
-       DeleteCriticalSection (&mini_arch_mutex);
+       mono_mutex_destroy (&mini_arch_mutex);
 }
 
 /*
@@ -1254,7 +1261,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig)
 }
 
 gboolean
-mono_arch_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
+mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
 {
        CallInfo *c1, *c2;
        gboolean res;
@@ -2429,6 +2436,7 @@ loop_start:
                case OP_IDIV_IMM:
                case OP_IREM_IMM:
                case OP_IREM_UN_IMM:
+               CASE_PPC64 (OP_LREM_IMM) {
                        NEW_INS (cfg, temp, OP_ICONST);
                        temp->inst_c0 = ins->inst_imm;
                        temp->dreg = mono_alloc_ireg (cfg);
@@ -2441,9 +2449,12 @@ loop_start:
                                ins->opcode = OP_IDIV_UN;
                        else if (ins->opcode == OP_IREM_UN_IMM)
                                ins->opcode = OP_IREM_UN;
+                       else if (ins->opcode == OP_LREM_IMM)
+                               ins->opcode = OP_LREM;
                        last_ins = temp;
                        /* handle rem separately */
                        goto loop_start;
+               }
                case OP_IREM:
                case OP_IREM_UN:
                CASE_PPC64 (OP_LREM)
@@ -4384,22 +4395,36 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        else
                                ppc_mr (code, ins->dreg, ins->sreg1);
                        break;
-               case OP_ATOMIC_ADD_NEW_I4:
-               case OP_ATOMIC_ADD_NEW_I8: {
-                       guint8 *loop = code, *branch;
+               case OP_ATOMIC_ADD_I4:
+               CASE_PPC64 (OP_ATOMIC_ADD_I8) {
+                       int location = ins->inst_basereg;
+                       int addend = ins->sreg2;
+                       guint8 *loop, *branch;
                        g_assert (ins->inst_offset == 0);
-                       if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
-                               ppc_lwarx (code, ppc_r0, 0, ins->inst_basereg);
+
+                       loop = code;
+                       ppc_sync (code);
+                       if (ins->opcode == OP_ATOMIC_ADD_I4)
+                               ppc_lwarx (code, ppc_r0, 0, location);
+#ifdef __mono_ppc64__
                        else
-                               ppc_ldarx (code, ppc_r0, 0, ins->inst_basereg);
-                       ppc_add (code, ppc_r0, ppc_r0, ins->sreg2);
-                       if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
-                               ppc_stwcxd (code, ppc_r0, 0, ins->inst_basereg);
+                               ppc_ldarx (code, ppc_r0, 0, location);
+#endif
+
+                       ppc_add (code, ppc_r0, ppc_r0, addend);
+
+                       if (ins->opcode == OP_ATOMIC_ADD_I4)
+                               ppc_stwcxd (code, ppc_r0, 0, location);
+#ifdef __mono_ppc64__
                        else
-                               ppc_stdcxd (code, ppc_r0, 0, ins->inst_basereg);
+                               ppc_stdcxd (code, ppc_r0, 0, location);
+#endif
+
                        branch = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
                        ppc_patch (branch, loop);
+
+                       ppc_sync (code);
                        ppc_mr (code, ins->dreg, ppc_r0);
                        break;
                }
@@ -4426,16 +4451,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        guint8 *start, *not_equal, *lost_reservation;
 
                        start = code;
+                       ppc_sync (code);
                        if (ins->opcode == OP_ATOMIC_CAS_I4)
                                ppc_lwarx (code, ppc_r0, 0, location);
 #ifdef __mono_ppc64__
                        else
                                ppc_ldarx (code, ppc_r0, 0, location);
 #endif
-                       ppc_cmp (code, 0, ins->opcode == OP_ATOMIC_CAS_I4 ? 0 : 1, ppc_r0, comparand);
 
+                       ppc_cmp (code, 0, ins->opcode == OP_ATOMIC_CAS_I4 ? 0 : 1, ppc_r0, comparand);
                        not_equal = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
+
                        if (ins->opcode == OP_ATOMIC_CAS_I4)
                                ppc_stwcxd (code, value, 0, location);
 #ifdef __mono_ppc64__
@@ -4446,8 +4473,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        lost_reservation = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
                        ppc_patch (lost_reservation, start);
-
                        ppc_patch (not_equal, code);
+
+                       ppc_sync (code);
                        ppc_mr (code, ins->dreg, ppc_r0);
                        break;
                }
@@ -4574,6 +4602,7 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, Mono
                case MONO_PATCH_INFO_ABS:
                case MONO_PATCH_INFO_CLASS_INIT:
                case MONO_PATCH_INFO_RGCTX_FETCH:
+               case MONO_PATCH_INFO_JIT_ICALL_ADDR:
                        is_fd = TRUE;
                        break;
 #endif
@@ -5395,8 +5424,6 @@ try_offset_access (void *value, guint32 idx)
 static void
 setup_tls_access (void)
 {
-       guint32 ptk;
-
 #if defined(__linux__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
        size_t conf_size = 0;
        char confbuf[128];
@@ -5446,6 +5473,7 @@ setup_tls_access (void)
                ppc_blr (code);
                if (*ins == cmplwi_1023) {
                        int found_lwz_284 = 0;
+                       guint32 ptk;
                        for (ptk = 0; ptk < 20; ++ptk) {
                                ++ins;
                                if (!*ins || *ins == blr_ins)
@@ -5511,7 +5539,7 @@ setup_tls_access (void)
        /* if not TLS_MODE_NPTL or local dynamic (as indicated by
           mono_get_lmf_addr_tls_offset returning -1) then use keyed access. */
        if (lmf_pthread_key == -1) {
-               ptk = mono_jit_tls_id;
+               guint32 ptk = mono_jit_tls_id;
                if (ptk < 1024) {
                        /*g_print ("MonoLMF at: %d\n", ptk);*/
                        /*if (!try_offset_access (mono_get_lmf_addr (), ptk)) {
@@ -5537,8 +5565,6 @@ mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
 {
 }
 
-#ifdef MONO_ARCH_HAVE_IMT
-
 #define CMP_SIZE (PPC_LOAD_SEQUENCE_LENGTH + 4)
 #define BR_SIZE 4
 #define LOADSTORE_SIZE 4
@@ -5694,7 +5720,6 @@ mono_arch_find_imt_method (mgreg_t *regs, guint8 *code)
 
        return (MonoMethod*)(gsize) r [MONO_ARCH_IMT_REG];
 }
-#endif
 
 MonoVTable*
 mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
@@ -5941,3 +5966,19 @@ mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
 }
 
 #endif
+
+gboolean
+mono_arch_opcode_supported (int opcode)
+{
+       switch (opcode) {
+       case OP_ATOMIC_ADD_I4:
+       case OP_ATOMIC_CAS_I4:
+#ifdef TARGET_POWERPC64
+       case OP_ATOMIC_ADD_I8:
+       case OP_ATOMIC_CAS_I8:
+#endif
+               return TRUE;
+       default:
+               return FALSE;
+       }
+}