Add support for OP_SETFRET to the llvm backend.
[mono.git] / mono / mini / mini-llvm.c
index cb068ea37e369ea0417993220d8a6b71c55b036c..c459b388e1b0a424e0c605266d8d8cae7cb1acf2 100644 (file)
@@ -1083,6 +1083,10 @@ get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gc
        if (!callee_name)
                return NULL;
 
+       if (ctx->cfg->compile_aot)
+               /* Add a patch so referenced wrappers can be compiled in full aot mode */
+               mono_add_patch_info (ctx->cfg, 0, type, data);
+
        // FIXME: Locking
        callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
        if (!callee) {
@@ -1937,7 +1941,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
 #endif
        /* The two can't be used together, so use only one LLVM calling conv to pass them */
        g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
-       if (call->rgctx_arg_reg || call->imt_arg_reg)
+       if (!sig->pinvoke)
                LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
 
        if (call->rgctx_arg_reg)
@@ -2301,6 +2305,15 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
                        else if (ins->opcode == OP_COMPARE_IMM)
                                cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
+                       else if (ins->opcode == OP_LCOMPARE_IMM) {
+                               if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg))  {
+                                       /* The immediate is encoded in two fields */
+                                       guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
+                               } else {
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
+                               }
+                       }
                        else if (ins->opcode == OP_COMPARE)
                                cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
                        else
@@ -2400,6 +2413,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_MOVE:
                case OP_LMOVE:
                case OP_XMOVE:
+               case OP_SETFRET:
                        g_assert (lhs);
                        values [ins->dreg] = lhs;
                        break;
@@ -2768,7 +2782,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_LOCALLOC: {
                        LLVMValueRef v, size;
                                
-                       size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, lhs, LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
+                       size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
 
                        v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
 
@@ -3245,6 +3259,11 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        switch (ins->opcode) {
                        case OP_STOREV_MEMBASE:
+                               if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
+                                       /* FIXME: Emit write barriers like in mini_emit_stobj () */
+                                       LLVM_FAILURE (ctx, "storev_membase + write barriers");
+                                       break;
+                               }
                                if (!addresses [ins->sreg1]) {
                                        /* SIMD */
                                        g_assert (values [ins->sreg1]);
@@ -3273,6 +3292,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        default:
                                g_assert_not_reached ();
                        }
+                       CHECK_FAILURE (ctx);
 
                        if (done)
                                break;
@@ -3825,8 +3845,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
        ctx->lmethod = method;
 
 #ifdef LLVM_MONO_BRANCH
-       if (linfo->rgctx_arg)
-               LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
+       LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
 #endif
        LLVMSetLinkage (method, LLVMPrivateLinkage);