#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>
#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;
static int lmf_pthread_key = -1;
-static int monodomain_key = -1;
/*
* The code generated for sequence points reads from this location, which is
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);
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);
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)
{
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);
void
mono_arch_cleanup (void)
{
- DeleteCriticalSection (&mini_arch_mutex);
+ mono_mutex_destroy (&mini_arch_mutex);
}
/*
}
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;
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);
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)
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;
}
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__
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;
}
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
static void
setup_tls_access (void)
{
- guint32 ptk;
-
#if defined(__linux__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
size_t conf_size = 0;
char confbuf[128];
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)
tls_mode = TLS_MODE_FAILED;
if (tls_mode == TLS_MODE_FAILED)
return;
- if ((monodomain_key == -1) && (tls_mode == TLS_MODE_NPTL)) {
- monodomain_key = mono_domain_get_tls_offset();
- }
- /* if not TLS_MODE_NPTL or local dynamic (as indicated by
- mono_domain_get_tls_offset returning -1) then use keyed access. */
- if (monodomain_key == -1) {
- ptk = mono_domain_get_tls_key ();
- 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 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)) {
{
}
-#ifdef MONO_ARCH_HAVE_IMT
-
#define CMP_SIZE (PPC_LOAD_SEQUENCE_LENGTH + 4)
#define BR_SIZE 4
#define LOADSTORE_SIZE 4
return (MonoMethod*)(gsize) r [MONO_ARCH_IMT_REG];
}
-#endif
MonoVTable*
mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
return 0;
}
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
- MonoInst* ins;
-
- setup_tls_access ();
- if (monodomain_key == -1)
- return NULL;
-
- MONO_INST_NEW (cfg, ins, OP_TLS_GET);
- ins->inst_offset = monodomain_key;
- return ins;
-}
-
mgreg_t
mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
{
}
#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;
+ }
+}