Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / decompose.c
index 9546009e724697247abc5e7e3e11ff1f67c8e685..93668ac852457377081ddd806f9b8f65ad75b32a 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * decompose.c: Functions to decompose complex IR instructions into simpler ones.
+/**
+ * \file
+ * Functions to decompose complex IR instructions into simpler ones.
  *
  * Author:
  *   Zoltan Varga (vargaz@gmail.com)
 
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/abi-details.h>
+#include <mono/utils/mono-compiler.h>
 
 #ifndef DISABLE_JIT
 
-/* FIXME: This conflicts with the definition in mini.c, so it cannot be moved to mini.h */
-MONO_API MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
-void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native);
-void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass *klass);
-
 /*
  * Decompose complex long opcodes on 64 bit machines.
  * This is also used on 32 bit machines when using LLVM, so it needs to handle I/U correctly.
@@ -1230,8 +1227,8 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
 
                                        EMIT_NEW_VARLOADA ((cfg), (src), src_var, src_var->inst_vtype);
                                        EMIT_NEW_VARLOADA ((cfg), (dest), dest_var, dest_var->inst_vtype);
+                                       mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, 0);
 
-                                       mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
                                        break;
                                }
                                case OP_VZERO:
@@ -1264,6 +1261,9 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
                                case OP_STOREV_MEMBASE: {
                                        src_var = get_vreg_to_inst (cfg, ins->sreg1);
 
+                                       if (COMPILE_LLVM (cfg) && !mini_is_gsharedvt_klass (ins->klass) && !cfg->gen_write_barriers)
+                                               break;
+
                                        if (!src_var) {
                                                g_assert (ins->klass);
                                                src_var = mono_compile_create_var_for_vreg (cfg, &ins->klass->byval_arg, OP_LOCAL, ins->sreg1);
@@ -1273,7 +1273,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
 
                                        dreg = alloc_preg (cfg);
                                        EMIT_NEW_BIALU_IMM (cfg, dest, OP_ADD_IMM, dreg, ins->inst_destbasereg, ins->inst_offset);
-                                       mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
+                                       mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, 0);
                                        break;
                                }
                                case OP_LOADV_MEMBASE: {
@@ -1290,7 +1290,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
                                        dreg = alloc_preg (cfg);
                                        EMIT_NEW_BIALU_IMM (cfg, src, OP_ADD_IMM, dreg, ins->inst_basereg, ins->inst_offset);
                                        EMIT_NEW_VARLOADA (cfg, dest, dest_var, dest_var->inst_vtype);
-                                       mini_emit_stobj (cfg, dest, src, dest_var->klass, dest_var->backend.is_pinvoke);
+                                       mini_emit_memory_copy (cfg, dest, src, dest_var->klass, dest_var->backend.is_pinvoke, 0);
                                        break;
                                }
                                case OP_OUTARG_VT: {
@@ -1508,10 +1508,13 @@ mono_decompose_array_access_opts (MonoCompile *cfg)
                                        break;
                                case OP_BOUNDS_CHECK:
                                        MONO_EMIT_NULL_CHECK (cfg, ins->sreg1);
-                                       if (COMPILE_LLVM (cfg))
-                                               MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->flags & MONO_INST_FAULT);
-                                       else
+                                       if (COMPILE_LLVM (cfg)) {
+                                               int index2_reg = alloc_preg (cfg);
+                                               MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2);
+                                               MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, index2_reg, ins->flags & MONO_INST_FAULT);
+                                       } else {
                                                MONO_ARCH_EMIT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2);
+                                       }
                                        break;
                                case OP_NEWARR:
                                        if (cfg->opt & MONO_OPT_SHARED) {
@@ -1520,7 +1523,7 @@ mono_decompose_array_access_opts (MonoCompile *cfg)
                                                MONO_INST_NEW (cfg, iargs [2], OP_MOVE);
                                                iargs [2]->dreg = ins->sreg1;
 
-                                               dest = mono_emit_jit_icall (cfg, mono_array_new, iargs);
+                                               dest = mono_emit_jit_icall (cfg, ves_icall_array_new, iargs);
                                                dest->dreg = ins->dreg;
                                        } else {
                                                MonoClass *array_class = mono_array_class_get (ins->inst_newa_class, 1);
@@ -1886,6 +1889,13 @@ mono_local_emulate_ops (MonoCompile *cfg)
                        int op_noimm = mono_op_imm_to_op (ins->opcode);
                        MonoJitICallInfo *info;
 
+                       /*
+                        * These opcodes don't have logical equivalence to the emulating native
+                        * function. They are decomposed in specific fashion in mono_decompose_soft_float.
+                        */
+                       if (MONO_HAS_CUSTOM_EMULATION (ins))
+                               continue;
+
                        /*
                         * Emulation can't handle _IMM ops. If this is an imm opcode we need
                         * to check whether its non-imm counterpart is emulated and, if so,
@@ -1922,9 +1932,9 @@ mono_local_emulate_ops (MonoCompile *cfg)
 
                                /* We emit the call on a separate dummy basic block */
                                cfg->cbb = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
-                               first_bb = cfg->cbb;
+                               first_bb = cfg->cbb;
 
-                               call = mono_emit_jit_icall_by_info (cfg, info, args);
+                               call = mono_emit_jit_icall_by_info (cfg, bb->real_offset, info, args);
                                call->dreg = ins->dreg;
 
                                /* Replace ins with the emitted code and do the necessary bb linking */
@@ -1958,4 +1968,8 @@ mono_local_emulate_ops (MonoCompile *cfg)
        }
 }
 
-#endif /* DISABLE_JIT */
+#else /* !DISABLE_JIT */
+
+MONO_EMPTY_SOURCE_FILE (decompose);
+
+#endif /* !DISABLE_JIT */