-/*
- * 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.
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:
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);
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: {
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: {
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) {
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);
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,
/* 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 */
}
}
-#endif /* DISABLE_JIT */
+#else /* !DISABLE_JIT */
+
+MONO_EMPTY_SOURCE_FILE (decompose);
+
+#endif /* !DISABLE_JIT */