X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fir-emit.h;h=b46d21e07fb56d7243c3a573cfbabba053212bb9;hb=290ea77a902579c0322767e30790382969bfed1e;hp=50d1616e221c2b73016c5c3f698cb5bde16d0c51;hpb=3f1e9f525b5bfc922950b1026c90376e5181c573;p=mono.git diff --git a/mono/mini/ir-emit.h b/mono/mini/ir-emit.h index 50d1616e221..b46d21e07fb 100644 --- a/mono/mini/ir-emit.h +++ b/mono/mini/ir-emit.h @@ -29,7 +29,7 @@ alloc_preg (MonoCompile *cfg) static inline guint32 alloc_lreg (MonoCompile *cfg) { -#if SIZEOF_VOID_P == 8 +#if SIZEOF_REGISTER == 8 return cfg->next_vreg ++; #else /* Use a pair of consecutive vregs */ @@ -69,6 +69,7 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) case STACK_VTYPE: return alloc_ireg (cfg); default: + g_warning ("Unknown stack type %x\n", stack_type); g_assert_not_reached (); } } @@ -80,11 +81,13 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) */ #define MONO_INST_NEW(cfg,dest,op) do { \ (dest) = mono_mempool_alloc ((cfg)->mempool, sizeof (MonoInst)); \ - (dest)->inst_p0 = (dest)->inst_p1 = (dest)->next = (dest)->prev = NULL; \ + (dest)->inst_c0 = (dest)->inst_c1 = 0; \ + (dest)->next = (dest)->prev = NULL; \ (dest)->opcode = (op); \ (dest)->flags = 0; \ (dest)->type = 0; \ - (dest)->dreg = (dest)->sreg1 = (dest)->sreg2 = -1; \ + (dest)->dreg = -1; \ + MONO_INST_NULLIFY_SREGS ((dest)); \ (dest)->cil_code = (cfg)->ip; \ } while (0) @@ -98,6 +101,10 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) (dest)->dreg = alloc_dreg ((cfg), STACK_I4); \ } while (0) +/* + * Avoid using this with a non-NULL val if possible as it is not AOT + * compatible. Use one of the NEW_xxxCONST variants instead. + */ #define NEW_PCONST(cfg,dest,val) do { \ MONO_INST_NEW ((cfg), (dest), OP_PCONST); \ (dest)->inst_p0 = (val); \ @@ -179,12 +186,12 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) (dest)->dreg = alloc_dreg ((cfg), STACK_PTR); \ } while (0) -#define NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,stack_type,stack_class) do { \ +#define NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,generic_context,stack_type,stack_class) do { \ MonoInst *group, *got_loc; \ MONO_INST_NEW ((cfg), (dest), OP_GOT_ENTRY); \ got_loc = mono_get_got_var (cfg); \ NEW_PATCH_INFO ((cfg), group, NULL, patch_type); \ - group->inst_p0 = mono_jump_info_token_new ((cfg)->mempool, (image), (token)); \ + group->inst_p0 = mono_jump_info_token_new2 ((cfg)->mempool, (image), (token), (generic_context)); \ (dest)->inst_basereg = got_loc->dreg; \ (dest)->inst_p1 = group; \ (dest)->type = (stack_type); \ @@ -202,9 +209,9 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) (dest)->dreg = alloc_dreg ((cfg), STACK_PTR); \ } while (0) -#define NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,stack_type,stack_class) do { \ +#define NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,generic_context,stack_type,stack_class) do { \ MONO_INST_NEW ((cfg), (dest), OP_AOTCONST); \ - (dest)->inst_p0 = mono_jump_info_token_new ((cfg)->mempool, (image), (token)); \ + (dest)->inst_p0 = mono_jump_info_token_new2 ((cfg)->mempool, (image), (token), (generic_context)); \ (dest)->inst_p1 = (gpointer)(patch_type); \ (dest)->type = (stack_type); \ (dest)->klass = (stack_class); \ @@ -225,15 +232,15 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) #define NEW_SFLDACONST(cfg,dest,val) NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_SFLDA, (val)) -#define NEW_LDSTRCONST(cfg,dest,image,token) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDSTR, (image), (token), STACK_OBJ, mono_defaults.string_class) +#define NEW_LDSTRCONST(cfg,dest,image,token) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDSTR, (image), (token), NULL, STACK_OBJ, mono_defaults.string_class) -#define NEW_TYPE_FROM_HANDLE_CONST(cfg,dest,image,token) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_TYPE_FROM_HANDLE, (image), (token), STACK_OBJ, mono_defaults.monotype_class) +#define NEW_TYPE_FROM_HANDLE_CONST(cfg,dest,image,token,generic_context) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_TYPE_FROM_HANDLE, (image), (token), (generic_context), STACK_OBJ, mono_defaults.monotype_class) -#define NEW_LDTOKENCONST(cfg,dest,image,token) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDTOKEN, (image), (token), STACK_PTR, NULL) +#define NEW_LDTOKENCONST(cfg,dest,image,token) NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDTOKEN, (image), (token), NULL, STACK_PTR, NULL) #define NEW_DECLSECCONST(cfg,dest,image,entry) do { \ if (cfg->compile_aot) { \ - NEW_AOTCONST_TOKEN (cfg, dest, MONO_PATCH_INFO_DECLSEC, image, (entry).index, STACK_OBJ, NULL); \ + NEW_AOTCONST_TOKEN (cfg, dest, MONO_PATCH_INFO_DECLSEC, image, (entry).index, NULL, STACK_OBJ, NULL); \ } else { \ NEW_PCONST (cfg, args [0], (entry).blob); \ } \ @@ -250,7 +257,7 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) } while (0) #define NEW_DOMAINCONST(cfg,dest) do { \ - if (cfg->opt & MONO_OPT_SHARED) { \ + if ((cfg->opt & MONO_OPT_SHARED) || cfg->compile_aot) { \ /* avoid depending on undefined C behavior in sequence points */ \ MonoInst* __domain_var = mono_get_domainvar (cfg); \ NEW_TEMPLOAD (cfg, dest, __domain_var->inst_c0); \ @@ -284,7 +291,7 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) (dest)->type = STACK_MP; \ (dest)->klass = (var)->klass; \ (dest)->dreg = alloc_dreg ((cfg), STACK_MP); \ - if (SIZEOF_VOID_P == 4 && DECOMPOSE_INTO_REGPAIR ((var)->type)) { MonoInst *var1 = get_vreg_to_inst (cfg, (var)->dreg + 1); MonoInst *var2 = get_vreg_to_inst (cfg, (var)->dreg + 2); g_assert (var1); g_assert (var2); var1->flags |= MONO_INST_INDIRECT; var2->flags |= MONO_INST_INDIRECT; } \ + if (SIZEOF_REGISTER == 4 && DECOMPOSE_INTO_REGPAIR ((var)->type)) { MonoInst *var1 = get_vreg_to_inst (cfg, (var)->dreg + 1); MonoInst *var2 = get_vreg_to_inst (cfg, (var)->dreg + 2); g_assert (var1); g_assert (var2); var1->flags |= MONO_INST_INDIRECT; var2->flags |= MONO_INST_INDIRECT; } \ } while (0) #define NEW_VARSTORE(cfg,dest,var,vartype,inst) do { \ @@ -362,25 +369,25 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) #define EMIT_NEW_AOTCONST(cfg,dest,patch_type,cons) do { NEW_AOTCONST ((cfg), (dest), (patch_type), (cons)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,stack_type,stack_class) do { NEW_AOTCONST_TOKEN ((cfg), (dest), (patch_type), (image), (token), (stack_type), (stack_class)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) +#define EMIT_NEW_AOTCONST_TOKEN(cfg,dest,patch_type,image,token,stack_type,stack_class) do { NEW_AOTCONST_TOKEN ((cfg), (dest), (patch_type), (image), (token), NULL, (stack_type), (stack_class)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_CLASSCONST(cfg,dest,val) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_CLASS, (val)) +#define EMIT_NEW_CLASSCONST(cfg,dest,val) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_CLASS, (val)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_IMAGECONST(cfg,dest,val) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_IMAGE, (val)) +#define EMIT_NEW_IMAGECONST(cfg,dest,val) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_IMAGE, (val)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_FIELDCONST(cfg,dest,val) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_FIELD, (val)) +#define EMIT_NEW_FIELDCONST(cfg,dest,val) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_FIELD, (val)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_METHODCONST(cfg,dest,val) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_METHODCONST, (val)) +#define EMIT_NEW_METHODCONST(cfg,dest,val) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_METHODCONST, (val)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_VTABLECONST(cfg,dest,vtable) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_VTABLE, cfg->compile_aot ? (gpointer)((vtable)->klass) : (vtable)) +#define EMIT_NEW_VTABLECONST(cfg,dest,vtable) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_VTABLE, cfg->compile_aot ? (gpointer)((vtable)->klass) : (vtable)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_SFLDACONST(cfg,dest,val) EMIT_NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_SFLDA, (val)) +#define EMIT_NEW_SFLDACONST(cfg,dest,val) do { NEW_AOTCONST ((cfg), (dest), MONO_PATCH_INFO_SFLDA, (val)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_LDSTRCONST(cfg,dest,image,token) EMIT_NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDSTR, (image), (token), STACK_OBJ, mono_defaults.string_class) +#define EMIT_NEW_LDSTRCONST(cfg,dest,image,token) do { NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDSTR, (image), (token), NULL, STACK_OBJ, mono_defaults.string_class); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_TYPE_FROM_HANDLE_CONST(cfg,dest,image,token) EMIT_NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_TYPE_FROM_HANDLE, (image), (token), STACK_OBJ, mono_defaults.monotype_class) +#define EMIT_NEW_TYPE_FROM_HANDLE_CONST(cfg,dest,image,token,generic_context) do { NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_TYPE_FROM_HANDLE, (image), (token), (generic_context), STACK_OBJ, mono_defaults.monotype_class); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) -#define EMIT_NEW_LDTOKENCONST(cfg,dest,image,token) EMIT_NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDTOKEN, (image), (token), STACK_PTR, NULL) +#define EMIT_NEW_LDTOKENCONST(cfg,dest,image,token) do { NEW_AOTCONST_TOKEN ((cfg), (dest), MONO_PATCH_INFO_LDTOKEN, (image), (token), NULL, STACK_PTR, NULL); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) #define EMIT_NEW_DOMAINCONST(cfg,dest) do { NEW_DOMAINCONST ((cfg), (dest)); MONO_ADD_INS ((cfg)->cbb, (dest)); } while (0) @@ -528,7 +535,7 @@ alloc_dreg (MonoCompile *cfg, MonoStackType stack_type) #define MONO_EMIT_NEW_VZERO(cfg,dr,kl) do { \ MonoInst *inst; \ - MONO_INST_NEW ((cfg), (inst), OP_VZERO); \ + MONO_INST_NEW ((cfg), (inst), MONO_CLASS_IS_SIMD (cfg, kl) ? OP_XZERO : OP_VZERO); \ inst->dreg = dr; \ (inst)->type = STACK_VTYPE; \ (inst)->klass = (kl); \ @@ -711,6 +718,38 @@ static int ccount = 0; (cfg)->cbb = (bblock); \ } while (0) +/*Object Model related macros*/ + +#ifndef MONO_ARCH_EMIT_BOUNDS_CHECK +#define MONO_ARCH_EMIT_BOUNDS_CHECK(cfg, array_reg, offset, index_reg) do { \ + int _length_reg = alloc_ireg (cfg); \ + MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, offset); \ + MONO_EMIT_NEW_BIALU (cfg, OP_COMPARE, -1, _length_reg, index_reg); \ + MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \ + } while (0) +#endif + +/* cfg is the MonoCompile been used + * array_reg is the vreg holding the array object + * array_type is a struct (usually MonoArray or MonoString) + * array_length_field is the field in the previous struct with the length + * index_reg is the vreg holding the index + */ +#define MONO_EMIT_BOUNDS_CHECK(cfg, array_reg, array_type, array_length_field, index_reg) do { \ + if (!(cfg->opt & MONO_OPT_ABCREM)) { \ + MONO_ARCH_EMIT_BOUNDS_CHECK ((cfg), (array_reg), G_STRUCT_OFFSET (array_type, array_length_field), (index_reg)); \ + } else { \ + MonoInst *ins; \ + MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK); \ + ins->sreg1 = array_reg; \ + ins->sreg2 = index_reg; \ + ins->inst_imm = G_STRUCT_OFFSET (array_type, array_length_field); \ + MONO_ADD_INS ((cfg)->cbb, ins); \ + (cfg)->flags |= MONO_CFG_HAS_ARRAY_ACCESS; \ + (cfg)->cbb->has_array_access = TRUE; \ + } \ + } while (0) + G_END_DECLS #endif