#include <string.h>
#include <asm/cachectl.h>
+#include <mono/metadata/abi-details.h>
#include <mono/metadata/appdomain.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/utils/mono-mmap.h>
+#include <mono/utils/mono-hwcap-mips.h>
#include <mono/arch/mips/mips-codegen.h>
#include "ir-emit.h"
#define SAVE_FP_REGS 0
-#define EXTRA_STACK_SPACE 0 /* suppresses some s-reg corruption issues */
-#define ALWAYS_USE_FP 1
#define ALWAYS_SAVE_RA 1 /* call-handler & switch currently clobber ra */
#define PROMOTE_R4_TO_R8 1 /* promote single values in registers to doubles */
-#define USE_MUL 1 /* use mul instead of mult/mflo for multiply */
+#define USE_MUL 0 /* use mul instead of mult/mflo for multiply
+ remember to update cpu-mips.md if you change this */
/* Emit a call sequence to 'v', using 'D' as a scratch register if necessary */
#define mips_call(c,D,v) do { \
};
/* 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 monothread_key = -1;
-static int monodomain_key = -1;
/* Whenever the host is little-endian */
static int little_endian;
arg_info [0].size = frame_size;
for (k = 0; k < param_count; k++) {
- size = mini_type_stack_size_full (NULL, csig->params [k], &align, csig->pinvoke);
+ size = mini_type_stack_size_full (csig->params [k], &align, csig->pinvoke);
/* ignore alignment for now */
align = 1;
#define MAX_ARCH_DELEGATE_PARAMS (4 - 1)
static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
{
guint8 *code, *start;
start = code = mono_global_codeman_reserve (16);
/* Replace the this argument with the target */
- mips_lw (code, mips_temp, mips_a0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
- mips_lw (code, mips_a0, mips_a0, G_STRUCT_OFFSET (MonoDelegate, target));
+ mips_lw (code, mips_temp, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
+ mips_lw (code, mips_a0, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, target));
mips_jr (code, mips_temp);
mips_nop (code);
size = 16 + param_count * 4;
start = code = mono_global_codeman_reserve (size);
- mips_lw (code, mips_temp, mips_a0, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
+ mips_lw (code, mips_temp, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
/* slide down the arguments */
for (i = 0; i < param_count; ++i) {
mips_move (code, mips_a0 + i, mips_a0 + i + 1);
mono_arch_flush_icache (start, size);
}
- if (code_size)
- *code_size = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+ g_free (name);
+ }
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0);
+ res = g_slist_prepend (res, info);
for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, FALSE, i);
+ res = g_slist_prepend (res, info);
}
return res;
return cached;
}
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0);
+ mono_tramp_info_register (info, NULL);
+ }
cached = start;
mono_mini_arch_unlock ();
return cached;
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+ mono_tramp_info_register (info, NULL);
}
cache [sig->param_count] = start;
mono_mini_arch_unlock ();
return NULL;
}
+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)
{
void
mono_arch_init (void)
{
- 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);
}
/*
* 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;
+}
+
GList *
mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
{
#endif
static CallInfo*
-get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig)
+get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
{
guint i;
int n = sig->hasthis + sig->param_count;
* are sometimes made using calli without sig->hasthis set, like in the delegate
* invoke wrappers.
*/
- if (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (gsctx, sig->params [0]))))) {
+ if (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) {
if (sig->hasthis) {
add_int32_arg (cinfo, cinfo->args + n);
n ++;
add_int32_arg (cinfo, &cinfo->sig_cookie);
}
DEBUG(printf("param %d: ", i));
- simpletype = mini_type_get_underlying_type (gsctx, sig->params [i]);
+ simpletype = mini_get_underlying_type (sig->params [i]);
switch (simpletype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
}
{
- simpletype = mini_type_get_underlying_type (gsctx, sig->ret);
+ simpletype = mini_get_underlying_type (sig->ret);
switch (simpletype->type) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
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;
-}
-
static gboolean
debug_omit_fp (void)
{
#if 0
- return debug_count ();
+ return mono_debug_count ();
#else
return TRUE;
#endif
sig = mono_method_signature (cfg->method);
if (!cfg->arch.cinfo)
- cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+ cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
cinfo = cfg->arch.cinfo;
/*
sig = mono_method_signature (cfg->method);
if (!cfg->arch.cinfo)
- cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+ cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
cinfo = cfg->arch.cinfo;
mono_arch_compute_omit_fp (cfg);
curinst = 0;
if (!MONO_TYPE_ISSTRUCT (sig->ret)) {
/* FIXME: handle long and FP values */
- switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) {
+ switch (mini_get_underlying_type (sig->ret)->type) {
case MONO_TYPE_VOID:
break;
case MONO_TYPE_R4:
offset += size;
}
- /*
- * FIXME: - Saved S-regs seem to be getting clobbered by some calls with struct
- * args or return vals. Extra stack space avoids this in a lot of cases.
- */
- offset += EXTRA_STACK_SPACE;
offset += SIZEOF_REGISTER - 1;
offset &= ~(SIZEOF_REGISTER - 1);
sig = call->signature;
n = sig->param_count + sig->hasthis;
- cinfo = get_call_info (NULL, cfg->mempool, sig);
+ cinfo = get_call_info (cfg->mempool, sig);
if (cinfo->struct_ret)
call->used_iregs |= 1 << cinfo->struct_ret;
t = sig->params [i - sig->hasthis];
else
t = &mono_defaults.int_class->byval_arg;
- t = mini_type_get_underlying_type (cfg->generic_sharing_context, t);
+ t = mini_get_underlying_type (t);
if ((sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) {
/* Emit the signature cookie just before the implicit arguments */
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);
+ size = mini_type_stack_size (&src->klass->byval_arg, NULL);
}
if (size > 0)
g_assert (ovf_size > 0);
void
mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
{
- MonoType *ret = mini_type_get_underlying_type (cfg->generic_sharing_context,
- mono_method_signature (method)->ret);
+ MonoType *ret = mini_get_underlying_type (mono_method_signature (method)->ret);
if (!ret->byref) {
#if (SIZEOF_REGISTER == 4)
sig = mono_method_signature (method);
if (!cfg->arch.cinfo)
- cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+ cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
cinfo = cfg->arch.cinfo;
if (cinfo->struct_ret) {
if (ppc_is_imm16 (-size)) {
ppc_stwu (code, ppc_r0, -size, ppc_sp);
} else {
- ppc_load (code, ppc_r11, -size);
- ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
+ ppc_load (code, ppc_r12, -size);
+ ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
}
#endif
return code;
if (ppc_is_imm16 (size)) {
ppc_stwu (code, ppc_r0, size, ppc_sp);
} else {
- ppc_load (code, ppc_r11, size);
- ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
+ ppc_load (code, ppc_r12, size);
+ ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
}
#endif
return code;
case OP_NOT_REACHED:
case OP_NOT_NULL:
break;
+ case OP_IL_SEQ_POINT:
+ mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+ break;
case OP_SEQ_POINT: {
if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
guint32 addr = (guint32)ss_trigger_page;
mips_mfhi (code, ins->dreg+1);
break;
case OP_MEMORY_BARRIER:
-#if 0
- ppc_sync (code);
-#endif
+ mips_sync (code, 0);
break;
case OP_STOREI1_MEMBASE_IMM:
mips_load_const (code, mips_temp, ins->inst_imm);
case OP_DIV_IMM:
g_assert_not_reached ();
#if 0
- ppc_load (code, ppc_r11, ins->inst_imm);
- ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r11);
+ ppc_load (code, ppc_r12, ins->inst_imm);
+ ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r12);
ppc_mfspr (code, ppc_r0, ppc_xer);
ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
/* FIXME: use OverflowException for 0x80000000/-1 */
mips_fmovd (code, ins->dreg, ins->sreg1);
}
break;
+ case OP_MOVE_F_TO_I4:
+ mips_cvtsd (code, mips_ftemp, ins->sreg1);
+ mips_mfc1 (code, ins->dreg, mips_ftemp);
+ break;
+ case OP_MOVE_I4_TO_F:
+ mips_mtc1 (code, ins->dreg, ins->sreg1);
+ mips_cvtds (code, ins->dreg, ins->dreg);
+ break;
case OP_MIPS_CVTSD:
/* Convert from double to float and leave it there */
mips_cvtsd (code, ins->dreg, ins->sreg1);
mips_addiu (code, ins->dreg, mips_sp, area_offset);
if (ins->flags & MONO_INST_INIT) {
+ guint32 *buf;
+
+ buf = (guint32*)(void*)code;
+ mips_beq (code, mips_at, mips_zero, 0);
+ mips_nop (code);
+
mips_move (code, mips_temp, ins->dreg);
mips_sb (code, mips_zero, mips_temp, 0);
mips_addiu (code, mips_at, mips_at, -1);
mips_bne (code, mips_at, mips_zero, -3);
mips_addiu (code, mips_temp, mips_temp, 1);
+
+ mips_patch (buf, (guint32)code);
}
break;
}
}
void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
+mono_arch_patch_code (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors)
{
MonoJumpInfo *patch_info;
}
}
-#if 0
-static
-void
-mono_trace_lmf_prolog (MonoLMF *new_lmf)
-{
-}
-
-static
-void
-mono_trace_lmf_epilog (MonoLMF *old_lmf)
-{
-}
-#endif
-
/*
* Allow tracing to work with this interface (with an optional argument)
*
mips_nop (code);
mips_nop (code);
- /* For N32, need to know for each stack slot if it's an integer
- * or float argument, and save/restore the appropriate register
- */
MIPS_SW (code, mips_a0, mips_sp, offset + 0*SIZEOF_REGISTER);
MIPS_SW (code, mips_a1, mips_sp, offset + 1*SIZEOF_REGISTER);
MIPS_SW (code, mips_a2, mips_sp, offset + 2*SIZEOF_REGISTER);
MIPS_SW (code, mips_a3, mips_sp, offset + 3*SIZEOF_REGISTER);
#if _MIPS_SIM == _ABIN32
+ NOT_IMPLEMENTED;
+ /* FIXME: Need a separate region for these */
MIPS_SW (code, mips_a4, mips_sp, offset + 4*SIZEOF_REGISTER);
MIPS_SW (code, mips_a5, mips_sp, offset + 5*SIZEOF_REGISTER);
MIPS_SW (code, mips_a6, mips_sp, offset + 6*SIZEOF_REGISTER);
MIPS_SW (code, mips_a7, mips_sp, offset + 7*SIZEOF_REGISTER);
+ */
#endif
mips_load_const (code, mips_a0, cfg->method);
mips_addiu (code, mips_a1, mips_sp, offset);
mips_call (code, mips_t9, func);
+ mips_nop (code);
MIPS_LW (code, mips_a0, mips_sp, offset + 0*SIZEOF_REGISTER);
MIPS_LW (code, mips_a1, mips_sp, offset + 1*SIZEOF_REGISTER);
MIPS_LW (code, mips_a2, mips_sp, offset + 2*SIZEOF_REGISTER);
MIPS_LW (code, mips_a3, mips_sp, offset + 3*SIZEOF_REGISTER);
#if _MIPS_SIM == _ABIN32
+ NOT_IMPLEMENTED;
+ /*
MIPS_LW (code, mips_a4, mips_sp, offset + 4*SIZEOF_REGISTER);
MIPS_LW (code, mips_a5, mips_sp, offset + 5*SIZEOF_REGISTER);
MIPS_LW (code, mips_a6, mips_sp, offset + 6*SIZEOF_REGISTER);
MIPS_LW (code, mips_a7, mips_sp, offset + 7*SIZEOF_REGISTER);
+ */
#endif
mips_nop (code);
if (max_offset > 0xffff)
cfg->arch.long_branch = TRUE;
- if (tracing) {
-#if _MIPS_SIM == _ABIO32
- cfg->arch.tracing_offset = cfg->stack_offset;
-#elif _MIPS_SIM == _ABIN32
- /* no stack slots by default for argument regs, reserve a special block */
- cfg->arch.tracing_offset = cfg->stack_offset;
- cfg->stack_offset += 8 * SIZEOF_REGISTER;
-#endif
- }
-
/*
* Currently, fp points to the bottom of the frame on MIPS, unlike other platforms.
* This means that we have to adjust the offsets inside instructions which reference
}
}
- /* Do instrumentation before assigning regvars to registers. Because they may be assigned
- * to the t* registers, which would be clobbered by the instrumentation calls.
- */
- if (tracing) {
- code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
- }
-
/* store runtime generic context */
if (cfg->rgctx_var) {
MonoInst *ins = cfg->rgctx_var;
pos = 0;
if (!cfg->arch.cinfo)
- cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+ cfg->arch.cinfo = get_call_info (cfg->mempool, sig);
cinfo = cfg->arch.cinfo;
if (MONO_TYPE_ISSTRUCT (sig->ret)) {
pos++;
}
- if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
- mips_load_const (code, mips_a0, cfg->domain);
- mips_call (code, mips_t9, (gpointer)mono_jit_thread_attach);
- }
-
if (method->save_lmf) {
mips_load_const (code, mips_at, MIPS_LMF_MAGIC1);
mips_sw (code, mips_at, mips_sp, lmf_offset + G_STRUCT_OFFSET(MonoLMF, magic));
mono_emit_unwind_op_def_cfa_offset (cfg, code, cfa_offset);
}
+ if (tracing) {
+#if _MIPS_SIM == _ABIO32
+ cfg->arch.tracing_offset = cfg->stack_offset;
+#elif _MIPS_SIM == _ABIN32
+ /* no stack slots by default for argument regs, reserve a special block */
+ g_assert_not_reached ();
+#endif
+ code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
+ }
+
cfg->code_len = code - cfg->native_code;
g_assert (cfg->code_len < cfg->code_size);
int save_mode = SAVE_NONE;
int offset;
MonoMethod *method = cfg->method;
- int rtype = mini_type_get_underlying_type (cfg->generic_sharing_context, mono_method_signature (method)->ret)->type;
+ int rtype = mini_get_underlying_type (mono_method_signature (method)->ret)->type;
int save_offset = MIPS_STACK_PARAM_OFFSET;
g_assert ((save_offset & (MIPS_STACK_ALIGNMENT-1)) == 0);
}
#endif
}
- if (monodomain_key == -1) {
- ptk = mono_domain_get_tls_key ();
- if (ptk < 1024)
- monodomain_key = ptk;
- }
if (lmf_pthread_key == -1) {
ptk = mono_jit_tls_id;
if (ptk < 1024) {
}
void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
{
setup_tls_access ();
}
/* add the this argument */
if (this_reg != -1) {
- MonoInst *this;
- MONO_INST_NEW (cfg, this, OP_MOVE);
- this->type = this_type;
- this->sreg1 = this_reg;
- this->dreg = mono_alloc_ireg (cfg);
- mono_bblock_add_inst (cfg->cbb, this);
- mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, this_dreg, FALSE);
+ MonoInst *this_ins;
+ MONO_INST_NEW (cfg, this_ins, OP_MOVE);
+ this_ins->type = this_type;
+ this_ins->sreg1 = this_reg;
+ this_ins->dreg = mono_alloc_ireg (cfg);
+ mono_bblock_add_inst (cfg->cbb, this_ins);
+ mono_call_inst_add_outarg_reg (cfg, inst, this_ins->dreg, this_dreg, FALSE);
}
if (vt_reg != -1) {
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)
{
return ctx->sc_regs [reg];
}
-#ifdef MONO_ARCH_HAVE_IMT
-
#define ENABLE_WRONG_METHOD_CHECK 0
#define MIPS_LOAD_SEQUENCE_LENGTH 8
mono_stats.imt_thunks_size += code - start;
g_assert (code - start <= size);
mono_arch_flush_icache (start, size);
+
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
{
return (MonoMethod*) regs [MONO_ARCH_IMT_REG];
}
-#endif
MonoVTable*
mono_arch_find_static_call_vtable (mgreg_t *regs, 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.iregs [mips_sp] = (gssize)ext;
+}
+
#endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */
+
+gboolean
+mono_arch_opcode_supported (int opcode)
+{
+ return FALSE;
+}