[sdb] Keep the exception object alive during debugger suspensions. Fixes #12494.
[mono.git] / mono / mini / mini-llvm.c
old mode 100755 (executable)
new mode 100644 (file)
index cbf206e..fd82248
@@ -9,6 +9,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/mempool-internals.h>
 #include <mono/utils/mono-tls.h>
+#include <mono/utils/mono-dl.h>
 
 #ifndef __STDC_LIMIT_MACROS
 #define __STDC_LIMIT_MACROS
@@ -329,7 +330,10 @@ type_to_llvm_type (EmitContext *ctx, MonoType *t)
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                /* Because of generic sharing */
-               return IntPtrType ();
+               if (mini_type_var_is_vt (ctx->cfg, t))
+                       return type_to_llvm_type (ctx, mini_get_gsharedvt_alloc_type_for_type (ctx->cfg, t));
+               else
+                       return IntPtrType ();
        case MONO_TYPE_GENERICINST:
                if (!mono_type_generic_inst_is_valuetype (t))
                        return IntPtrType ();
@@ -729,16 +733,6 @@ simd_op_to_intrins (int opcode)
                return "llvm.x86.sse.rsqrt.ps";
        case OP_RCPPS:
                return "llvm.x86.sse.rcp.ps";
-       case OP_PCMPEQB:
-               return "llvm.x86.sse2.pcmpeq.b";
-       case OP_PCMPEQW:
-               return "llvm.x86.sse2.pcmpeq.w";
-       case OP_PCMPEQD:
-               return "llvm.x86.sse2.pcmpeq.d";
-       case OP_PCMPEQQ:
-               return "llvm.x86.sse41.pcmpeqq";
-       case OP_PCMPGTB:
-               return "llvm.x86.sse2.pcmpgt.b";
        case OP_CVTDQ2PD:
                return "llvm.x86.sse2.cvtdq2pd";
        case OP_CVTDQ2PS:
@@ -1053,7 +1047,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
                } else {
                        g_assert_not_reached ();
                }
-       } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
+       } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
                g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
                vretaddr = TRUE;
                ret_type = LLVMVoidType ();
@@ -1689,7 +1683,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
                MonoInst *var = cfg->varinfo [i];
                LLVMTypeRef vtype;
 
-               if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
+               if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
                        vtype = type_to_llvm_type (ctx, var->inst_vtype);
                        CHECK_FAILURE (ctx);
                        /* Could be already created by an OP_VPHI */
@@ -1742,7 +1736,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
        if (sig->hasthis)
                emit_volatile_store (ctx, cfg->args [0]->dreg);
        for (i = 0; i < sig->param_count; ++i)
-               if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
+               if (!mini_type_is_vtype (cfg, sig->params [i]))
                        emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
 
        if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
@@ -1830,7 +1824,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
        LLVMValueRef *args;
        LLVMCallInfo *cinfo;
        GSList *l;
-       int i, len;
+       int i, len, nargs;
        gboolean vretaddr;
        LLVMTypeRef llvm_sig;
        gpointer target;
@@ -1952,23 +1946,27 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
        /* 
         * Collect and convert arguments
         */
-       len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
+       nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
+       len = sizeof (LLVMValueRef) * nargs;
        args = alloca (len);
        memset (args, 0, len);
        l = call->out_ireg_args;
 
        if (call->rgctx_arg_reg) {
                g_assert (values [call->rgctx_arg_reg]);
+               g_assert (sinfo.rgctx_arg_pindex < nargs);
                args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
        }
        if (call->imt_arg_reg) {
                g_assert (values [call->imt_arg_reg]);
+               g_assert (sinfo.imt_arg_pindex < nargs);
                args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
        }
 
        if (vretaddr) {
                if (!addresses [call->inst.dreg])
                        addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
+               g_assert (sinfo.vret_arg_pindex < nargs);
                args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
        }
 
@@ -2159,14 +2157,20 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
                        LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
 
-                       LLVMSetLinkage (type_info, LLVMPrivateLinkage);
-                       LLVMSetVisibility (type_info, LLVMHiddenVisibility);
+                       /*
+                        * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
+                        */
+                       LLVMSetLinkage (type_info, LLVMInternalLinkage);
 
                        /* 
                         * Enabling this causes llc to crash:
                         * http://llvm.org/bugs/show_bug.cgi?id=6102
                         */
                        //LLVM_FAILURE (ctx, "aot+clauses");
+#ifdef TARGET_ARM
+                       // test_0_invalid_unbox_arrays () fails
+                       LLVM_FAILURE (ctx, "aot+clauses");
+#endif
                } else {
                        /*
                         * After the cfg mempool is freed, the type info will point to stale memory,
@@ -2775,7 +2779,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        break;
                case OP_INOT: {
                        guint32 v = 0xffffffff;
-                       values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
+                       values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
                        break;
                }
                case OP_LNOT: {
@@ -3041,7 +3045,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                }
 
                case OP_CHECK_THIS:
-                       emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
+                       emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
                        break;
                case OP_OUTARG_VTRETADDR:
                        break;
@@ -3278,7 +3282,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 #endif
                }
                case OP_TLS_GET: {
-#if defined(TARGET_AMD64) || defined(TARGET_X86)
+#if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
 #ifdef TARGET_AMD64
                        // 257 == FS segment register
                        LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
@@ -3371,6 +3375,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                break;
                        }
 
+                       if (mini_is_gsharedvt_klass (cfg, klass)) {
+                               // FIXME:
+                               LLVM_FAILURE (ctx, "gsharedvt");
+                               break;
+                       }
+
                        switch (ins->opcode) {
                        case OP_STOREV_MEMBASE:
                                if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
@@ -3577,11 +3587,6 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_PSUBW_SAT_UN:
                case OP_PAVGB_UN:
                case OP_PAVGW_UN:
-               case OP_PCMPEQB:
-               case OP_PCMPEQW:
-               case OP_PCMPEQD:
-               case OP_PCMPEQQ:
-               case OP_PCMPGTB:
                case OP_PACKW:
                case OP_PACKD:
                case OP_PACKW_UN:
@@ -3596,6 +3601,17 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
                        break;
                }
+               case OP_PCMPEQB:
+               case OP_PCMPEQW:
+               case OP_PCMPEQD:
+               case OP_PCMPEQQ: {
+                       values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
+                       break;
+               }
+               case OP_PCMPGTB: {
+                       values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
+                       break;
+               }
                case OP_EXTRACT_R8:
                case OP_EXTRACT_I8:
                case OP_EXTRACT_I4:
@@ -3754,7 +3770,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_PSHUFLEW_LOW:
                case OP_PSHUFLEW_HIGH: {
                        int mask [16];
-                       LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
+                       LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
                        int i, mask_size = 0;
                        int imask = ins->inst_c0;
        
@@ -3982,7 +3998,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                else
                                        ctx->lmodule->throw = callee;
                        }
-                       arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
+                       arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
                        emit_call (ctx, bb, &builder, callee, &arg, 1);
                        break;
                }
@@ -4111,18 +4127,16 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 void
 mono_llvm_check_method_supported (MonoCompile *cfg)
 {
-       /*
        MonoMethodHeader *header = cfg->header;
        MonoExceptionClause *clause;
        int i;
-       */
 
        if (cfg->method->save_lmf) {
                cfg->exception_message = g_strdup ("lmf");
                cfg->disable_llvm = TRUE;
        }
 
-#if 0
+#if 1
        for (i = 0; i < header->num_clauses; ++i) {
                clause = &header->clauses [i];
                
@@ -4461,7 +4475,9 @@ mono_llvm_emit_method (MonoCompile *cfg)
                        if (ctx->unreachable [node->in_bb->block_num])
                                continue;
 
-                       g_assert (values [sreg1]);
+                       if (!values [sreg1])
+                               /* Can happen with values in EH clauses */
+                               LLVM_FAILURE (ctx, "incoming phi sreg1");
 
                        if (phi->opcode == OP_VPHI) {
                                g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
@@ -4737,6 +4753,27 @@ exception_cb (void *data)
        g_free (type_info);
 }
 
+static char*
+dlsym_cb (const char *name, void **symbol)
+{
+       MonoDl *current;
+       char *err;
+
+       err = NULL;
+       if (!strcmp (name, "__bzero")) {
+               *symbol = (void*)bzero;
+       } else {
+               current = mono_dl_open (NULL, 0, NULL);
+               g_assert (current);
+
+               err = mono_dl_symbol (current, name, symbol);
+       }
+#ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
+       *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
+#endif
+       return err;
+}
+
 static inline void
 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
 {
@@ -4849,7 +4886,6 @@ add_intrinsics (LLVMModuleRef module)
                arg_types [1] = ret_type;
                AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
-               AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
 
                ret_type = type_to_simd_type (MONO_TYPE_I2);
                arg_types [0] = ret_type;
@@ -4857,7 +4893,6 @@ add_intrinsics (LLVMModuleRef module)
                AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
-               AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
@@ -4871,19 +4906,12 @@ add_intrinsics (LLVMModuleRef module)
                arg_types [1] = ret_type;
                AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
-               AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
-               AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
                AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
 
-               ret_type = type_to_simd_type (MONO_TYPE_I8);
-               arg_types [0] = ret_type;
-               arg_types [1] = ret_type;
-               AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
-
                ret_type = type_to_simd_type (MONO_TYPE_R8);
                arg_types [0] = ret_type;
                arg_types [1] = ret_type;
@@ -5040,7 +5068,7 @@ init_jit_module (void)
 
        jit_module.module = LLVMModuleCreateWithName ("mono");
 
-       ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
+       ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
 
        add_intrinsics (jit_module.module);