Merge pull request #2003 from esdrubal/seq_test_fix2
[mono.git] / mono / mini / mini-amd64.c
index 536e19087f053035c26b245ff1e8d3070607876f..f0ca62d8d97a358f1e46b44e832fc73b5abcffb9 100644 (file)
@@ -65,9 +65,6 @@ static gboolean optimize_for_xen = TRUE;
 #define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
 static mono_mutex_t mini_arch_mutex;
 
-MonoBreakpointInfo
-mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
 /*
  * The code generated for sequence points reads from this location, which is
  * made read-only when single stepping is enabled.
@@ -182,6 +179,15 @@ amd64_is_near_call (guint8 *code)
        return code [0] == 0xe8;
 }
 
+static inline gboolean
+amd64_use_imm32 (gint64 val)
+{
+       if (mini_get_debug_options()->single_imm_size)
+               return FALSE;
+
+       return amd64_is_imm32 (val);
+}
+
 #ifdef __native_client_codegen__
 
 /* Keep track of instruction "depth", that is, the level of sub-instruction */
@@ -641,7 +647,7 @@ merge_argument_class_from_type (MonoType *type, ArgumentClass class1)
 
                for (i = 0; i < info->num_fields; ++i) {
                        class2 = class1;
-                       class2 = merge_argument_class_from_type (gsctx, info->fields [i].field->type, class2);
+                       class2 = merge_argument_class_from_type (info->fields [i].field->type, class2);
                }
                break;
        }
@@ -727,7 +733,7 @@ collect_field_info_nested (MonoClass *klass, MonoMarshalField *fields, int index
 }
 
 static void
-add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
+add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type,
                           gboolean is_return,
                           guint32 *gr, guint32 *fr, guint32 *stack_size)
 {
@@ -739,16 +745,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
        MonoMarshalType *info = NULL;
        MonoMarshalField *fields = NULL;
        MonoClass *klass;
-       MonoGenericSharingContext tmp_gsctx;
        gboolean pass_on_stack = FALSE;
-       
-       /* 
-        * The gsctx currently contains no data, it is only used for checking whenever
-        * open types are allowed, some callers like mono_arch_get_argument_info ()
-        * don't pass it to us, so work around that.
-        */
-       if (!gsctx)
-               gsctx = &tmp_gsctx;
 
        klass = mono_class_from_mono_type (type);
        size = mini_type_stack_size_full (&klass->byval_arg, NULL, sig->pinvoke);
@@ -916,7 +913,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
                                /* (8 is size of quad) */
                                quadsize [quad] = fields [i].offset + size - (quad * 8);
 
-                               class1 = merge_argument_class_from_type (gsctx, fields [i].field->type, class1);
+                               class1 = merge_argument_class_from_type (fields [i].field->type, class1);
                        }
                        g_assert (class1 != ARG_CLASS_NO_CLASS);
                        args [quad] = class1;
@@ -1001,7 +998,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
  * Draft Version 0.23" document for more information.
  */
 static CallInfo*
-get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig)
+get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
 {
        guint32 i, gr, fr, pstart;
        MonoType *ret_type;
@@ -1072,7 +1069,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
        case MONO_TYPE_VALUETYPE: {
                guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
 
-               add_valuetype (gsctx, sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+               add_valuetype (sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
                if (cinfo->ret.storage == ArgOnStack) {
                        cinfo->vtype_retaddr = TRUE;
                        /* The caller passes the address where the value is stored */
@@ -1183,7 +1180,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                        /* fall through */
                case MONO_TYPE_VALUETYPE:
                case MONO_TYPE_TYPEDBYREF:
-                       add_valuetype (gsctx, sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
+                       add_valuetype (sig, ainfo, sig->params [i], FALSE, &gr, &fr, &stack_size);
                        break;
                case MONO_TYPE_U8:
 
@@ -1227,10 +1224,10 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
  * Returns the size of the argument area on the stack.
  */
 int
-mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
 {
        int k;
-       CallInfo *cinfo = get_call_info (NULL, NULL, csig);
+       CallInfo *cinfo = get_call_info (NULL, csig);
        guint32 args_size = cinfo->stack_usage;
 
        /* The arguments are saved to a stack area in mono_arch_instrument_prolog */
@@ -1256,8 +1253,8 @@ mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig
        gboolean res;
        MonoType *callee_ret;
 
-       c1 = get_call_info (NULL, NULL, caller_sig);
-       c2 = get_call_info (NULL, NULL, callee_sig);
+       c1 = get_call_info (NULL, caller_sig);
+       c2 = get_call_info (NULL, callee_sig);
        res = c1->stack_usage >= c2->stack_usage;
        callee_ret = mini_get_underlying_type (callee_sig->ret);
        if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
@@ -1459,7 +1456,7 @@ mono_arch_compute_omit_fp (MonoCompile *cfg)
        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;
 
        /*
@@ -1943,7 +1940,7 @@ mono_arch_create_vars (MonoCompile *cfg)
        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;
 
        if (cinfo->ret.storage == ArgValuetypeInReg)
@@ -2100,7 +2097,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
        n = sig->param_count + sig->hasthis;
        sig_ret = mini_get_underlying_type (sig->ret);
 
-       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+       cinfo = get_call_info (cfg->mempool, sig);
 
        linfo = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
 
@@ -2194,7 +2191,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
 
-       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+       cinfo = get_call_info (cfg->mempool, sig);
 
        sig_ret = sig->ret;
 
@@ -2565,7 +2562,7 @@ mono_arch_dyn_call_prepare (MonoMethodSignature *sig)
        ArchDynCallInfo *info;
        CallInfo *cinfo;
 
-       cinfo = get_call_info (NULL, NULL, sig);
+       cinfo = get_call_info (NULL, sig);
 
        if (!dyn_call_supported (sig, cinfo)) {
                g_free (cinfo);
@@ -3194,7 +3191,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_COMPARE_IMM:
                case OP_LCOMPARE_IMM:
-                       if (!amd64_is_imm32 (ins->inst_imm)) {
+                       if (!amd64_use_imm32 (ins->inst_imm)) {
                                NEW_INS (cfg, ins, temp, OP_I8CONST);
                                temp->inst_c0 = ins->inst_imm;
                                temp->dreg = mono_alloc_ireg (cfg);
@@ -3209,7 +3206,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
 #ifndef __native_client_codegen__
                /*  Don't generate memindex opcodes (to simplify */
                /*  read sandboxing) */
-                       if (!amd64_is_imm32 (ins->inst_offset)) {
+                       if (!amd64_use_imm32 (ins->inst_offset)) {
                                NEW_INS (cfg, ins, temp, OP_I8CONST);
                                temp->inst_c0 = ins->inst_offset;
                                temp->dreg = mono_alloc_ireg (cfg);
@@ -3222,7 +3219,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_STORE_MEMBASE_IMM:
 #endif
                case OP_STOREI8_MEMBASE_IMM:
-                       if (!amd64_is_imm32 (ins->inst_imm)) {
+                       if (!amd64_use_imm32 (ins->inst_imm)) {
                                NEW_INS (cfg, ins, temp, OP_I8CONST);
                                temp->inst_c0 = ins->inst_imm;
                                temp->dreg = mono_alloc_ireg (cfg);
@@ -3444,7 +3441,7 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
        case OP_VCALL2:
        case OP_VCALL2_REG:
        case OP_VCALL2_MEMBASE:
-               cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, ((MonoCallInst*)ins)->signature);
+               cinfo = get_call_info (cfg->mempool, ((MonoCallInst*)ins)->signature);
                if (cinfo->ret.storage == ArgValuetypeInReg) {
                        MonoInst *loc = cfg->arch.vret_addr_loc;
 
@@ -3855,10 +3852,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 #endif
                case OP_LOADI8_MEM:
                        // FIXME: Decompose this earlier
-                       if (amd64_is_imm32 (ins->inst_imm))
+                       if (amd64_use_imm32 (ins->inst_imm))
                                amd64_mov_reg_mem (code, ins->dreg, ins->inst_imm, 8);
                        else {
-                               amd64_mov_reg_imm (code, ins->dreg, ins->inst_imm);
+                               amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_imm, sizeof(gpointer));
                                amd64_mov_reg_membase (code, ins->dreg, ins->dreg, 0, 8);
                        }
                        break;
@@ -3868,10 +3865,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_LOADU4_MEM:
                        // FIXME: Decompose this earlier
-                       if (amd64_is_imm32 (ins->inst_imm))
+                       if (amd64_use_imm32 (ins->inst_imm))
                                amd64_mov_reg_mem (code, ins->dreg, ins->inst_imm, 4);
                        else {
-                               amd64_mov_reg_imm (code, ins->dreg, ins->inst_imm);
+                               amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_imm, sizeof(gpointer));
                                amd64_mov_reg_membase (code, ins->dreg, ins->dreg, 0, 4);
                        }
                        break;
@@ -4602,7 +4599,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                case OP_ICONST:
                case OP_I8CONST:
-                       if ((((guint64)ins->inst_c0) >> 32) == 0)
+                       if ((((guint64)ins->inst_c0) >> 32) == 0 && !mini_get_debug_options()->single_imm_size)
                                amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_c0, 4);
                        else
                                amd64_mov_reg_imm_size (code, ins->dreg, ins->inst_c0, 8);
@@ -7688,7 +7685,7 @@ mono_arch_flush_register_windows (void)
 gboolean 
 mono_arch_is_inst_imm (gint64 imm)
 {
-       return amd64_is_imm32 (imm);
+       return amd64_use_imm32 (imm);
 }
 
 /*
@@ -7815,11 +7812,14 @@ mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code)
 #define MAX_ARCH_DELEGATE_PARAMS 10
 
 static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count)
 {
        guint8 *code, *start;
+       GSList *unwind_ops = NULL;
        int i;
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        if (has_target) {
                start = code = mono_global_codeman_reserve (64);
 
@@ -7856,8 +7856,13 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
        nacl_global_codeman_validate (&start, 64, &code);
        mono_arch_flush_icache (start, code - start);
 
-       if (code_len)
-               *code_len = code - start;
+       if (has_target) {
+               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+       } else {
+               char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+               g_free (name);
+       }
 
        if (mono_jit_map_is_enabled ()) {
                char *buff;
@@ -7877,16 +7882,20 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod
 #define MAX_VIRTUAL_DELEGATE_OFFSET 32
 
 static gpointer
-get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_len)
+get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, int offset)
 {
        guint8 *code, *start;
        int size = 20;
+       char *tramp_name;
+       GSList *unwind_ops;
 
-       if (offset / sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+       if (offset / (int)sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
                return NULL;
 
        start = code = mono_global_codeman_reserve (size);
 
+       unwind_ops = mono_arch_get_cie_program ();
+
        /* Replace the this argument with the target */
        amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
        amd64_mov_reg_membase (code, AMD64_ARG_REG1, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 8);
@@ -7901,8 +7910,12 @@ get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *co
        amd64_jump_membase (code, AMD64_RAX, offset);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
 
-       if (code_len)
-               *code_len = code - start;
+       if (load_imt_reg)
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
+       else
+               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+       *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
+       g_free (tramp_name);
 
        return start;
 }
@@ -7917,31 +7930,23 @@ GSList*
 mono_arch_get_delegate_invoke_impls (void)
 {
        GSList *res = NULL;
-       guint8 *code;
-       guint32 code_len;
+       MonoTrampInfo *info;
        int i;
-       char *tramp_name;
 
-       code = get_delegate_invoke_impl (TRUE, 0, &code_len);
-       res = g_slist_prepend (res, mono_tramp_info_create ("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);
-               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);
+       for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+               get_delegate_invoke_impl (&info, FALSE, i);
+               res = g_slist_prepend (res, info);
        }
 
-       for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
-               code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+       for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+               get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
 
-               code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
-               tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
-               res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
-               g_free (tramp_name);
+               get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
+               res = g_slist_prepend (res, info);
        }
 
        return res;
@@ -7957,7 +7962,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                return NULL;
 
        /* FIXME: Support more cases */
-       if (MONO_TYPE_ISSTRUCT (mini_replace_type (sig->ret)))
+       if (MONO_TYPE_ISSTRUCT (mini_get_underlying_type (sig->ret)))
                return NULL;
 
        if (has_target) {
@@ -7966,10 +7971,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                if (cached)
                        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);
+               }
 
                mono_memory_barrier ();
 
@@ -7991,7 +7999,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                        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);
                }
 
                mono_memory_barrier ();
@@ -8005,7 +8015,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 gpointer
 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
 {
-       return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
+       MonoTrampInfo *info;
+       gpointer code;
+
+       code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
+       if (code)
+               mono_tramp_info_register (info, NULL);
+       return code;
 }
 
 void
@@ -8064,13 +8080,14 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        int size = 0;
        guint8 *code, *start;
        gboolean vtable_is_32bit = ((gsize)(vtable) == (gsize)(int)(gsize)(vtable));
+       GSList *unwind_ops;
 
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                if (item->is_equals) {
                        if (item->check_target_idx) {
                                if (!item->compare_done) {
-                                       if (amd64_is_imm32 (item->key))
+                                       if (amd64_use_imm32 ((gint64)item->key))
                                                item->chunk_size += CMP_SIZE;
                                        else
                                                item->chunk_size += MOV_REG_IMM_SIZE + CMP_REG_REG_SIZE;
@@ -8106,7 +8123,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                }
                        }
                } else {
-                       if (amd64_is_imm32 (item->key))
+                       if (amd64_use_imm32 ((gint64)item->key))
                                item->chunk_size += CMP_SIZE;
                        else
                                item->chunk_size += MOV_REG_IMM_SIZE + CMP_REG_REG_SIZE;
@@ -8126,6 +8143,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                code = mono_domain_code_reserve (domain, size);
 #endif
        start = code;
+
+       unwind_ops = mono_arch_get_cie_program ();
+
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                item->code_target = code;
@@ -8134,10 +8154,10 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 
                        if (item->check_target_idx || fail_case) {
                                if (!item->compare_done || fail_case) {
-                                       if (amd64_is_imm32 (item->key))
+                                       if (amd64_use_imm32 ((gint64)item->key))
                                                amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof(gpointer));
                                        else {
-                                               amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key);
+                                               amd64_mov_reg_imm_size (code, MONO_ARCH_IMT_SCRATCH_REG, item->key, sizeof(gpointer));
                                                amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG);
                                        }
                                }
@@ -8185,10 +8205,10 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 #endif
                        }
                } else {
-                       if (amd64_is_imm32 (item->key))
+                       if (amd64_use_imm32 ((gint64)item->key))
                                amd64_alu_reg_imm_size (code, X86_CMP, MONO_ARCH_IMT_REG, (guint32)(gssize)item->key, sizeof (gpointer));
                        else {
-                               amd64_mov_reg_imm (code, MONO_ARCH_IMT_SCRATCH_REG, item->key);
+                               amd64_mov_reg_imm_size (code, MONO_ARCH_IMT_SCRATCH_REG, item->key, sizeof (gpointer));
                                amd64_alu_reg_reg (code, X86_CMP, MONO_ARCH_IMT_REG, MONO_ARCH_IMT_SCRATCH_REG);
                        }
                        item->jmp_code = code;
@@ -8216,6 +8236,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        nacl_domain_code_validate(domain, &start, size, &code);
        mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
 
+       mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
        return start;
 }