#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
* 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;
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;
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,
#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 {
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)
#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);
* 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;
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:
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;
}
/*
- if (!debug_count ())
+ if (!mono_debug_count ())
res = FALSE;
*/
}
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);
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);
while (cfg->code_len + max_epilog_size > (cfg->code_size - 16)) {
cfg->code_size *= 2;
cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- mono_jit_stats.code_reallocs++;
+ cfg->stat_code_reallocs++;
}
/*
while (cfg->code_len + max_epilog_size > (cfg->code_size - 16)) {
cfg->code_size *= 2;
cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- mono_jit_stats.code_reallocs++;
+ cfg->stat_code_reallocs++;
}
code = cfg->native_code + cfg->code_len;
mono_domain_get_tls_offset returning -1) then use keyed access. */
if (monodomain_key == -1) {
ptk = mono_domain_get_tls_key ();
- if (ptk < 1024) {
- ptk = mono_pthread_key_for_tls (ptk);
- if (ptk < 1024) {
- monodomain_key = ptk;
- }
- }
+ if (ptk < 1024)
+ monodomain_key = ptk;
}
if ((lmf_pthread_key == -1) && (tls_mode == TLS_MODE_NPTL)) {
lmf_pthread_key = mono_get_lmf_addr_tls_offset();
}
+
+#if 0
/* 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_pthread_key_for_tls (mono_jit_tls_id);
+ ptk = mono_jit_tls_id;
if (ptk < 1024) {
/*g_print ("MonoLMF at: %d\n", ptk);*/
/*if (!try_offset_access (mono_get_lmf_addr (), ptk)) {
}
}
#endif
+
+#endif
}
void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
{
setup_tls_access ();
}
return FALSE;
}
-/*
- * mono_arch_get_ip_for_breakpoint:
- *
- * See mini-amd64.c for docs.
- */
-guint8*
-mono_arch_get_ip_for_breakpoint (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- /* ip points at the ldptr instruction */
- ip -= PPC_LOAD_SEQUENCE_LENGTH;
-
- return ip;
-}
-
/*
* mono_arch_skip_breakpoint:
*
* See mini-amd64.c for docs.
*/
void
-mono_arch_skip_breakpoint (MonoContext *ctx)
+mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
{
/* skip the ldptr */
MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4);
return FALSE;
}
-/*
- * mono_arch_get_ip_for_single_step:
- *
- * See mini-amd64.c for docs.
- */
-guint8*
-mono_arch_get_ip_for_single_step (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- /* ip points after the ldptr instruction */
- return ip;
-}
-
/*
* mono_arch_skip_single_step:
*
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