Initialize LLVM's ARM target when compiling for it.
[mono.git] / mono / mini / mini-amd64.c
index 11631bab7f095ec7c3b4b4e70f5ac1ff69440d39..f4945b9459f1c78a2db5ee1fcdbcc8bbb693437a 100644 (file)
@@ -171,36 +171,11 @@ mono_arch_xregname (int reg)
                return "unknown";
 }
 
-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
@@ -1202,7 +1177,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
  * Returns the size of the argument area on the stack.
  */
 int
-mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
 {
        int k;
        CallInfo *cinfo = get_call_info (NULL, NULL, csig);
@@ -1345,7 +1320,7 @@ mono_arch_cleanup (void)
  * This function returns the optimizations supported on this cpu.
  */
 guint32
-mono_arch_cpu_optimizazions (guint32 *exclude_mask)
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
 {
        int eax, ebx, ecx, edx;
        guint32 opts = 0;
@@ -1784,7 +1759,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        } else {
                if (cfg->arch.omit_fp)
                        cfg->arch.reg_save_area_offset = offset;
-               /* Reserve space for caller saved registers */
+               /* Reserve space for callee saved registers */
                for (i = 0; i < AMD64_NREG; ++i)
                        if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
                                offset += sizeof(mgreg_t);
@@ -2139,9 +2114,6 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
        if (call->tail_call)
                NOT_IMPLEMENTED;
 
-       /* FIXME: Add support for signature tokens to AOT */
-       //cfg->disable_aot = TRUE;
-
        g_assert (cinfo->sig_cookie.storage == ArgOnStack);
                        
        /*
@@ -3616,11 +3588,12 @@ mono_amd64_have_tls_get (void)
 #ifdef __APPLE__
        static gboolean have_tls_get = FALSE;
        static gboolean inited = FALSE;
+       guint8 *ins;
 
        if (inited)
                return have_tls_get;
 
-       guint8 *ins = (guint8*)pthread_getspecific;
+       ins = (guint8*)pthread_getspecific;
 
        /*
         * We're looking for these two instructions:
@@ -4324,6 +4297,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                for (i = 0; i < breakpoint_size; ++i)
                                        x86_nop (code);
                        }
+                       /*
+                        * Add an additional nop so skipping the bp doesn't cause the ip to point
+                        * to another IL offset.
+                        */
+                       x86_nop (code);
                        break;
                }
                case OP_ADDCC:
@@ -6816,6 +6794,9 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                (cfg->rgctx_var->inst_basereg == AMD64_RBP || cfg->rgctx_var->inst_basereg == AMD64_RSP));
 
                amd64_mov_membase_reg (code, cfg->rgctx_var->inst_basereg, cfg->rgctx_var->inst_offset, MONO_ARCH_RGCTX_REG, sizeof(gpointer));
+
+               mono_add_var_location (cfg, cfg->rgctx_var, TRUE, MONO_ARCH_RGCTX_REG, 0, 0, code - cfg->native_code);
+               mono_add_var_location (cfg, cfg->rgctx_var, FALSE, cfg->rgctx_var->inst_basereg, cfg->rgctx_var->inst_offset, code - cfg->native_code, 0);
        }
 
        /* compute max_length in order to use short forward jumps */
@@ -6937,6 +6918,16 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                        size = 8;
                                */
                                amd64_mov_membase_reg (code, ins->inst_basereg, ins->inst_offset, ainfo->reg, size);
+
+                               /*
+                                * Save the original location of 'this',
+                                * get_generic_info_from_stack_frame () needs this to properly look up
+                                * the argument value during the handling of async exceptions.
+                                */
+                               if (ins == cfg->args [0]) {
+                                       mono_add_var_location (cfg, ins, TRUE, ainfo->reg, 0, 0, code - cfg->native_code);
+                                       mono_add_var_location (cfg, ins, FALSE, ins->inst_basereg, ins->inst_offset, code - cfg->native_code, 0);
+                               }
                                break;
                        }
                        case ArgInFloatSSEReg:
@@ -6983,61 +6974,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        default:
                                g_assert_not_reached ();
                        }
-               }
-       }
-
-       /* Might need to attach the thread to the JIT  or change the domain for the callback */
-       if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
-               guint64 domain = (guint64)cfg->domain;
 
-               args_clobbered = TRUE;
-
-               /* 
-                * The call might clobber argument registers, but they are already
-                * saved to the stack/global regs.
-                */
-               if (appdomain_tls_offset != -1 && lmf_tls_offset != -1) {
-                       guint8 *buf, *no_domain_branch;
-
-                       code = mono_amd64_emit_tls_get (code, AMD64_RAX, appdomain_tls_offset);
-                       if (cfg->compile_aot) {
-                               /* AOT code is only used in the root domain */
-                               amd64_mov_reg_imm (code, AMD64_ARG_REG1, 0);
-                       } else {
-                               if ((domain >> 32) == 0)
-                                       amd64_mov_reg_imm_size (code, AMD64_ARG_REG1, domain, 4);
-                               else
-                                       amd64_mov_reg_imm_size (code, AMD64_ARG_REG1, domain, 8);
+                       if (ins == cfg->args [0]) {
+                               mono_add_var_location (cfg, ins, TRUE, ainfo->reg, 0, 0, code - cfg->native_code);
+                               mono_add_var_location (cfg, ins, TRUE, ins->dreg, 0, code - cfg->native_code, 0);
                        }
-                       amd64_alu_reg_reg (code, X86_CMP, AMD64_RAX, AMD64_ARG_REG1);
-                       no_domain_branch = code;
-                       x86_branch8 (code, X86_CC_NE, 0, 0);
-                       code = mono_amd64_emit_tls_get ( code, AMD64_RAX, lmf_addr_tls_offset);
-                       amd64_test_reg_reg (code, AMD64_RAX, AMD64_RAX);
-                       buf = code;
-                       x86_branch8 (code, X86_CC_NE, 0, 0);
-                       amd64_patch (no_domain_branch, code);
-                       code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, 
-                                         (gpointer)"mono_jit_thread_attach", TRUE);
-                       amd64_patch (buf, code);
-#ifdef HOST_WIN32
-                       /* The TLS key actually contains a pointer to the MonoJitTlsData structure */
-                       /* FIXME: Add a separate key for LMF to avoid this */
-                       amd64_alu_reg_imm (code, X86_ADD, AMD64_RAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
-#endif
-               } else {
-                       g_assert (!cfg->compile_aot);
-                       if (cfg->compile_aot) {
-                               /* AOT code is only used in the root domain */
-                               amd64_mov_reg_imm (code, AMD64_ARG_REG1, 0);
-                       } else {
-                               if ((domain >> 32) == 0)
-                                       amd64_mov_reg_imm_size (code, AMD64_ARG_REG1, domain, 4);
-                               else
-                                       amd64_mov_reg_imm_size (code, AMD64_ARG_REG1, domain, 8);
-                       }
-                       code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD,
-                                         (gpointer)"mono_jit_thread_attach", TRUE);
                }
        }
 
@@ -8030,42 +7971,33 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
 
        return start;
 }
-
-/*
- * Support for fast access to the thread-local lmf structure using the GS
- * segment register on NPTL + kernel 2.6.x.
- */
-
-static gboolean tls_offset_inited = FALSE;
-
 void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
 {
-       if (!tls_offset_inited) {
 #ifdef HOST_WIN32
-               /* 
-                * We need to init this multiple times, since when we are first called, the key might not
-                * be initialized yet.
-                */
-               appdomain_tls_offset = mono_domain_get_tls_key ();
-               lmf_tls_offset = mono_get_jit_tls_key ();
-               lmf_addr_tls_offset = mono_get_jit_tls_key ();
-
-               /* Only 64 tls entries can be accessed using inline code */
-               if (appdomain_tls_offset >= 64)
-                       appdomain_tls_offset = -1;
-               if (lmf_tls_offset >= 64)
-                       lmf_tls_offset = -1;
+       /* 
+        * We need to init this multiple times, since when we are first called, the key might not
+        * be initialized yet.
+        */
+       appdomain_tls_offset = mono_domain_get_tls_key ();
+       lmf_tls_offset = mono_get_jit_tls_key ();
+       lmf_addr_tls_offset = mono_get_jit_tls_key ();
+
+       /* Only 64 tls entries can be accessed using inline code */
+       if (appdomain_tls_offset >= 64)
+               appdomain_tls_offset = -1;
+       if (lmf_tls_offset >= 64)
+               lmf_tls_offset = -1;
+       if (lmf_addr_tls_offset >= 64)
+               lmf_addr_tls_offset = -1;
 #else
-               tls_offset_inited = TRUE;
 #ifdef MONO_XEN_OPT
-               optimize_for_xen = access ("/proc/xen", F_OK) == 0;
+       optimize_for_xen = access ("/proc/xen", F_OK) == 0;
 #endif
-               appdomain_tls_offset = mono_domain_get_tls_offset ();
-               lmf_tls_offset = mono_get_lmf_tls_offset ();
-               lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
+       appdomain_tls_offset = mono_domain_get_tls_offset ();
+       lmf_tls_offset = mono_get_lmf_tls_offset ();
+       lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
 #endif
-       }               
 }
 
 void