Merge pull request #2003 from esdrubal/seq_test_fix2
[mono.git] / mono / mini / mini-amd64.c
index 06ba12665998d00a6ad1381b8d7df378b7e2ea54..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 */
@@ -3185,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);
@@ -3200,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);
@@ -3213,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);
@@ -3846,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;
@@ -3859,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;
@@ -4593,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);
@@ -7679,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);
 }
 
 /*
@@ -7809,8 +7815,11 @@ static gpointer
 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);
 
@@ -7848,10 +7857,10 @@ get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 par
        mono_arch_flush_icache (start, code - start);
 
        if (has_target) {
-               *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+               *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, NULL);
+               *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
                g_free (name);
        }
 
@@ -7878,12 +7887,15 @@ get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, i
        guint8 *code, *start;
        int size = 20;
        char *tramp_name;
+       GSList *unwind_ops;
 
        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);
@@ -7902,7 +7914,7 @@ get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, i
                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, NULL);
+       *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
        g_free (tramp_name);
 
        return start;
@@ -7964,7 +7976,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                } else {
                        MonoTrampInfo *info;
                        start = get_delegate_invoke_impl (&info, TRUE, 0);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -7989,7 +8001,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                } else {
                        MonoTrampInfo *info;
                        start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
-                       mono_tramp_info_register (info);
+                       mono_tramp_info_register (info, NULL);
                }
 
                mono_memory_barrier ();
@@ -8008,7 +8020,7 @@ mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod
 
        code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
        if (code)
-               mono_tramp_info_register (info);
+               mono_tramp_info_register (info, NULL);
        return code;
 }
 
@@ -8068,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;
@@ -8110,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;
@@ -8130,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;
@@ -8138,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);
                                        }
                                }
@@ -8189,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;
@@ -8220,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;
 }