#define JUMP_SIZE 6
#define ENABLE_WRONG_METHOD_CHECK 0
+#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
+#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
+
/*========================= End of Defines =========================*/
/*------------------------------------------------------------------*/
static inline void add_general (guint *, size_data *, ArgInfo *);
static inline void add_stackParm (guint *, size_data *, ArgInfo *, gint);
static inline void add_float (guint *, size_data *, ArgInfo *);
-static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *, gboolean);
+static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *);
static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
static guint8 * emit_load_volatile_arguments (guint8 *, MonoCompile *);
static void catch_SIGILL(int, siginfo_t *, void *);
breakpoint_t breakpointCode;
+/*
+ * This mutex protects architecture specific caches
+ */
+static CRITICAL_SECTION mini_arch_mutex;
+
/*====================== End of Global Variables ===================*/
/*------------------------------------------------------------------*/
/*------------------------------------------------------------------*/
int
-mono_arch_get_argument_info (MonoMethodSignature *csig,
+mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig,
int param_count,
MonoJitArgumentInfo *arg_info)
{
sig = mono_method_signature (method);
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
+ cinfo = get_call_info (NULL, NULL, sig);
if (cinfo->struct_ret) {
printf ("[STRUCTRET:%p], ", (gpointer) rParm->gr[0]);
/*------------------------------------------------------------------*/
/* */
-/* Name - mono_arch_cpu_optimizazions */
+/* Name - mono_arch_cpu_optimizations */
/* */
/* 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;
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_cpu_enumerate_simd_versions */
+/* */
+/* Function - Returns the SIMD instruction sets on this CPU */
+/* */
+/*------------------------------------------------------------------*/
+guint32
+mono_arch_cpu_enumerate_simd_versions (void)
+{
+ /* SIMD is currently unimplemented */
+ return 0;
+}
+/*========================= End of Function ========================*/
+
/*------------------------------------------------------------------*/
/* */
/* Name - */
/*------------------------------------------------------------------*/
static CallInfo *
-get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig)
{
guint i, fr, gr, size, pstart;
int nParm = sig->hasthis + sig->param_count;
MonoType *ret_type;
- guint32 simpletype, align;
+ guint32 simpleType, align;
+ gboolean is_pinvoke = sig->pinvoke;
CallInfo *cinfo;
size_data *sz;
MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
/* area that the callee will use. */
/*----------------------------------------------------------*/
- ret_type = mono_type_get_underlying_type (sig->ret);
+ ret_type = mini_type_get_underlying_type (gsctx, sig->ret);
ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
- simpletype = ret_type->type;
+ simpleType = ret_type->type;
enum_retvalue:
- switch (simpletype) {
+ switch (simpleType) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
case MONO_TYPE_VALUETYPE: {
MonoClass *klass = mono_class_from_mono_type (sig->ret);
if (klass->enumtype) {
- simpletype = mono_class_enum_basetype (klass)->type;
+ simpleType = mono_class_enum_basetype (klass)->type;
goto enum_retvalue;
}
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
+ size = mini_type_stack_size_full (gsctx, &klass->byval_arg, NULL, sig->pinvoke);
cinfo->struct_ret = 1;
cinfo->ret.size = size;
continue;
}
- ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (gsctx, ptype);
- simpletype = ptype->type;
- cinfo->args[nParm].type = simpletype;
- switch (simpletype) {
+ ptype = mini_type_get_underlying_type (gsctx, sig->params [i]);
+// ptype = mini_get_basic_type_from_generic (gsctx, ptype);
+ simpleType = ptype->type;
+ cinfo->args[nParm].type = simpleType;
+ switch (simpleType) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
nParm++;
break;
case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (sig->params [i])) {
+ if (!mono_type_generic_inst_is_valuetype (ptype)) {
cinfo->args[nParm].size = sizeof(gpointer);
add_general (&gr, sz, cinfo->args+nParm);
nParm++;
/* Fall through */
case MONO_TYPE_VALUETYPE: {
MonoMarshalType *info;
- MonoClass *klass = mono_class_from_mono_type (sig->params [i]);
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- info = mono_marshal_load_type_info (klass);
+ MonoClass *klass = mono_class_from_mono_type (ptype);
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- cinfo->args[nParm].size = sizeof(float);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
+ size = mini_type_stack_size_full(gsctx, &klass->byval_arg, NULL, sig->pinvoke);
+ if (simpleType != MONO_TYPE_GENERICINST) {
+ info = mono_marshal_load_type_info(klass);
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- cinfo->args[nParm].size = sizeof(double);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
+ if ((info->native_size == sizeof(float)) &&
+ (info->num_fields == 1) &&
+ (info->fields[0].field->type->type == MONO_TYPE_R4)) {
+ cinfo->args[nParm].size = sizeof(float);
+ add_float(&fr, sz, cinfo->args+nParm);
+ nParm ++;
+ break;
+ }
+
+ if ((info->native_size == sizeof(double)) &&
+ (info->num_fields == 1) &&
+ (info->fields[0].field->type->type == MONO_TYPE_R8)) {
+ cinfo->args[nParm].size = sizeof(double);
+ add_float(&fr, sz, cinfo->args+nParm);
+ nParm ++;
+ break;
+ }
}
cinfo->args[nParm].vtsize = 0;
}
break;
default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
+ g_error ("Can't trampoline 0x%x", ptype);
}
}
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (!cinfo->struct_ret) {
switch (mono_type_get_underlying_type (sig->ret)->type) {
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (cinfo->struct_ret) {
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
n = sig->param_count + sig->hasthis;
DEBUG (g_print ("Call requires: %d parameters\n",n));
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
stackSize = cinfo->sz.stack_size + cinfo->sz.local_size +
cinfo->sz.parm_size + cinfo->sz.offset;
/* ensure ins->sreg1 is not NULL */
s390_lg (code, s390_r0, 0, ins->sreg1, 0);
s390_ltgr (code, s390_r0, s390_r0);
+ EMIT_COND_SYSTEM_EXCEPTION (S390_CC_ZR, "NullReferenceException");
}
break;
case OP_ARGLIST: {
/* floating point opcodes */
case OP_R8CONST: {
- if (*((float *) ins->inst_p0) == 0) {
+ if (*((double *) ins->inst_p0) == 0) {
s390_lzdr (code, ins->dreg);
} else {
s390_basr (code, s390_r13, 0);
case MONO_PATCH_INFO_EXC:
case MONO_PATCH_INFO_ABS:
case MONO_PATCH_INFO_METHOD:
+ case MONO_PATCH_INFO_RGCTX_FETCH:
case MONO_PATCH_INFO_INTERNAL_METHOD:
case MONO_PATCH_INFO_CLASS_INIT:
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
s390_patch_addr (ip, (guint64) target);
continue;
case MONO_PATCH_INFO_SWITCH:
int pos = 0, i;
CallInfo *cinfo;
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
+ cinfo = get_call_info (NULL, NULL, sig);
if (cinfo->struct_ret) {
ArgInfo *ainfo = &cinfo->ret;
mono_emit_unwind_op_def_cfa_reg (cfg, code, cfg->frame_reg);
+ /* store runtime generic context */
+ if (cfg->rgctx_var) {
+ g_assert (cfg->rgctx_var->opcode == OP_REGOFFSET);
+
+ s390_stg (code, MONO_ARCH_RGCTX_REG, 0,
+ cfg->rgctx_var->inst_basereg,
+ cfg->rgctx_var->inst_offset);
+ }
+
/* compute max_offset in order to use short forward jumps
* we always do it on s390 because the immediate displacement
* for jumps is too small
sig = mono_method_signature (method);
pos = 0;
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (cinfo->struct_ret) {
ArgInfo *ainfo = &cinfo->ret;
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_find_static_call_vtable */
+/* */
+/* Function - Find the static call vtable. */
+/* */
+/*------------------------------------------------------------------*/
+
+MonoVTable*
+mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
+{
+ mgreg_t *r = (mgreg_t*)regs;
+
+ return (MonoVTable*)(gsize) r [MONO_ARCH_RGCTX_REG];
+}
+
+/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_get_cie_program */
+/* */
+/* Function - Find the static call vtable. */
+/* */
+/*------------------------------------------------------------------*/
+
+GSList*
+mono_arch_get_cie_program (void)
+{
+ GSList *l = NULL;
+
+ mono_add_unwind_op_def_cfa (l, NULL, NULL, STK_BASE, 0);
+
+ return(l);
+}
+
+/*========================= End of Function ========================*/
+
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
/*------------------------------------------------------------------*/