[sdb] Move the setup of the sdb invoke LMF structure to an arch-specific function...
[mono.git] / mono / mini / mini-ppc.c
index 994edf96a07c42943525a87bb9e2fb3b4dcf4851..6a1d7187a856c3280769e32593130ceafb7c1559 100644 (file)
@@ -16,6 +16,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-proclib.h>
 #include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-hwcap-ppc.h>
 
 #include "mini-ppc.h"
 #ifdef TARGET_POWERPC64
@@ -274,7 +275,7 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse
  * Returns the size of the activation frame.
  */
 int
-mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
 {
 #ifdef __mono_ppc64__
        NOT_IMPLEMENTED;
@@ -442,13 +443,16 @@ mono_arch_get_delegate_invoke_impls (void)
        guint8 *code;
        guint32 code_len;
        int i;
+       char *tramp_name;
 
        code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
-       res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
+       res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
 
        for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
                code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
-               res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
+               tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
+               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
+               g_free (tramp_name);
        }
 
        return res;
@@ -520,32 +524,6 @@ typedef struct {
        long int value;
 } AuxVec;
 
-#ifdef USE_ENVIRON_HACK
-static AuxVec*
-linux_find_auxv (int *count)
-{
-       AuxVec *vec;
-       int c = 0;
-       char **result = __environ;
-       /* Scan over the env vector looking for the ending NULL */
-       for (; *result != NULL; ++result) {
-       }
-       /* Bump the pointer one more step, which should be the auxv. */
-       ++result;
-       vec = (AuxVec *)result;
-       if (vec->type != 22 /*AT_IGNOREPPC*/) {
-               *count = 0;
-               return NULL;
-       }
-       while (vec->type != 0 /*AT_NULL*/) {
-               vec++;
-               c++;
-       }
-       *count = c;
-       return (AuxVec *)result;
-}
-#endif
-
 #define MAX_AUX_ENTRIES 128
 /* 
  * PPC_FEATURE_POWER4, PPC_FEATURE_POWER5, PPC_FEATURE_POWER5_PLUS, PPC_FEATURE_CELL,
@@ -575,11 +553,12 @@ mono_arch_init (void)
 #if defined(MONO_CROSS_COMPILE)
 #elif defined(__APPLE__)
        int mib [3];
-       size_t len;
+       size_t len = sizeof (cachelinesize);
+
        mib [0] = CTL_HW;
        mib [1] = HW_CACHELINE;
-       len = sizeof (cachelinesize);
-       if (sysctl (mib, 2, &cachelinesize, (size_t*)&len, NULL, 0) == -1) {
+
+       if (sysctl (mib, 2, &cachelinesize, &len, NULL, 0) == -1) {
                perror ("sysctl");
                cachelinesize = 128;
        } else {
@@ -590,38 +569,18 @@ mono_arch_init (void)
        int i, vec_entries = 0;
        /* sadly this will work only with 2.6 kernels... */
        FILE* f = fopen ("/proc/self/auxv", "rb");
+
        if (f) {
                vec_entries = fread (&vec, sizeof (AuxVec), MAX_AUX_ENTRIES, f);
                fclose (f);
-#ifdef USE_ENVIRON_HACK
-       } else {
-               AuxVec *evec = linux_find_auxv (&vec_entries);
-               if (vec_entries)
-                       memcpy (&vec, evec, sizeof (AuxVec) * MIN (vec_entries, MAX_AUX_ENTRIES));
-#endif
        }
+
        for (i = 0; i < vec_entries; i++) {
                int type = vec [i].type;
+
                if (type == 19) { /* AT_DCACHEBSIZE */
                        cachelinesize = vec [i].value;
                        continue;
-               } else if (type == 16) { /* AT_HWCAP */
-                       if (vec [i].value & 0x00002000 /*PPC_FEATURE_ICACHE_SNOOP*/)
-                               cpu_hw_caps |= PPC_ICACHE_SNOOP;
-                       if (vec [i].value & ISA_2X)
-                               cpu_hw_caps |= PPC_ISA_2X;
-                       if (vec [i].value & ISA_64)
-                               cpu_hw_caps |= PPC_ISA_64;
-                       if (vec [i].value & ISA_MOVE_FPR_GPR)
-                               cpu_hw_caps |= PPC_MOVE_FPR_GPR;
-                       continue;
-               } else if (type == 15) { /* AT_PLATFORM */
-                       const char *arch = (char*)vec [i].value;
-                       if (strcmp (arch, "ppc970") == 0 ||
-                                       (strncmp (arch, "power", 5) == 0 && arch [5] >= '4' && arch [5] <= '7'))
-                               cpu_hw_caps |= PPC_MULTIPLE_LS_UNITS;
-                       /*printf ("cpu: %s\n", (char*)vec [i].value);*/
-                       continue;
                }
        }
 #elif defined(G_COMPILER_CODEWARRIOR)
@@ -630,13 +589,31 @@ mono_arch_init (void)
 #else
 //#error Need a way to get cache line size
 #endif
+
+       if (mono_hwcap_ppc_has_icache_snoop)
+               cpu_hw_caps |= PPC_ICACHE_SNOOP;
+
+       if (mono_hwcap_ppc_is_isa_2x)
+               cpu_hw_caps |= PPC_ISA_2X;
+
+       if (mono_hwcap_ppc_is_isa_64)
+               cpu_hw_caps |= PPC_ISA_64;
+
+       if (mono_hwcap_ppc_has_move_fpr_gpr)
+               cpu_hw_caps |= PPC_MOVE_FPR_GPR;
+
+       if (mono_hwcap_ppc_has_multiple_ls_units)
+               cpu_hw_caps |= PPC_MULTIPLE_LS_UNITS;
+
        if (!cachelinesize)
                cachelinesize = 32;
+
        if (!cachelineinc)
                cachelineinc = cachelinesize;
 
        if (mono_cpu_count () > 1)
                cpu_hw_caps |= PPC_SMP_CAPABLE;
+
        InitializeCriticalSection (&mini_arch_mutex);
 
        ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
@@ -659,7 +636,7 @@ mono_arch_cleanup (void)
  * This function returns the optimizations supported on this cpu.
  */
 guint32
-mono_arch_cpu_optimizazions (guint32 *exclude_mask)
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
 {
        guint32 opts = 0;
 
@@ -668,6 +645,19 @@ mono_arch_cpu_optimizazions (guint32 *exclude_mask)
        return opts;
 }
 
+/*
+ * This function test for all SIMD functions supported.
+ *
+ * Returns a bitmask corresponding to all supported versions.
+ *
+ */
+guint32
+mono_arch_cpu_enumerate_simd_versions (void)
+{
+       /* SIMD is currently unimplemented */
+       return 0;
+}
+
 #ifdef __mono_ppc64__
 #define CASE_PPC32(c)
 #define CASE_PPC64(c)  case c:
@@ -1264,33 +1254,8 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig)
        return cinfo;
 }
 
-G_GNUC_UNUSED static void
-break_count (void)
-{
-}
-
-G_GNUC_UNUSED static gboolean
-debug_count (void)
-{
-       static int count = 0;
-       count ++;
-
-       if (!getenv ("COUNT"))
-               return TRUE;
-
-       if (count == atoi (getenv ("COUNT"))) {
-               break_count ();
-       }
-
-       if (count > atoi (getenv ("COUNT"))) {
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
 gboolean
-mono_ppc_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
+mono_arch_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
 {
        CallInfo *c1, *c2;
        gboolean res;
@@ -1309,7 +1274,7 @@ mono_ppc_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignatu
        }
 
        /*
-       if (!debug_count ())
+       if (!mono_debug_count ())
                res = FALSE;
        */
 
@@ -3800,7 +3765,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
 
                        ppc_mr (code, ppc_sp, ppc_r11);
-                       mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
+                       mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method);
                        if (cfg->compile_aot) {
                                /* arch_emit_got_access () patches this */
                                ppc_load32 (code, ppc_r0, 0);
@@ -5069,22 +5034,6 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                pos++;
        }
 
-       if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
-               if (cfg->compile_aot)
-                       /* AOT code is only used in the root domain */
-                       ppc_load_ptr (code, ppc_r3, 0);
-               else
-                       ppc_load_ptr (code, ppc_r3, cfg->domain);
-               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach");
-               if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
-                       ppc_load_func (code, ppc_r0, 0);
-                       ppc_mtlr (code, ppc_r0);
-                       ppc_blrl (code);
-               } else {
-                       ppc_bl (code, 0);
-               }
-       }
-
        if (method->save_lmf) {
                if (lmf_pthread_key != -1) {
                        emit_tls_access (code, ppc_r3, lmf_pthread_key);
@@ -6007,4 +5956,13 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return NULL;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.ebp = (gssize)ext;
+}
+
 #endif