}
}
+ if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) {
+ if (!strcmp (cmethod->name, "Memmove") && fsig->param_count == 3 && fsig->params [0]->type == MONO_TYPE_PTR && fsig->params [1]->type == MONO_TYPE_PTR) {
+ opcode = OP_MEMMOVE;
+ MONO_INST_NEW (cfg, ins, opcode);
+ ins->sreg1 = args [0]->dreg; // i1* dst
+ ins->sreg2 = args [1]->dreg; // i1* src
+ ins->sreg3 = args [2]->dreg; // i32/i64 len
+ MONO_ADD_INS (cfg->cbb, ins);
+ }
+ }
+
return ins;
}
typedef enum {
INTRINS_MEMSET,
INTRINS_MEMCPY,
+ INTRINS_MEMMOVE,
INTRINS_SADD_OVF_I32,
INTRINS_UADD_OVF_I32,
INTRINS_SSUB_OVF_I32,
set_nonnull_load_flag (values [ins->dreg]);
break;
}
+ case OP_MEMMOVE: {
+ int argn = 0;
+ LLVMValueRef args [5];
+ args [argn++] = convert (ctx, values [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0));
+ args [argn++] = convert (ctx, values [ins->sreg2], LLVMPointerType (LLVMInt8Type (), 0));
+ args [argn++] = convert (ctx, values [ins->sreg3], LLVMInt64Type ());
+#if LLVM_API_VERSION < 900
+ args [argn++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE); // alignment
+#endif
+ args [argn++] = LLVMConstInt (LLVMInt1Type (), 0, FALSE); // is_volatile
+
+ LLVMBuildCall (builder, get_intrins (ctx, INTRINS_MEMMOVE), args, argn, "");
+ break;
+ }
case OP_NOT_REACHED:
LLVMBuildUnreachable (builder);
has_terminator = TRUE;
static IntrinsicDesc intrinsics[] = {
{INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
{INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
+ {INTRINS_MEMMOVE, "llvm.memmove.p0i8.p0i8.i64"},
{INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
{INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
{INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
#endif
break;
}
+ case INTRINS_MEMMOVE: {
+#if LLVM_API_VERSION >= 900
+ /* No alignment argument */
+ LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt64Type (), LLVMInt1Type () };
+ AddFunc (module, name, LLVMVoidType (), params, 4);
+#else
+ LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt64Type (), LLVMInt32Type (), LLVMInt1Type () };
+ AddFunc (module, name, LLVMVoidType (), params, 5);
+#endif
+ break;
+ }
case INTRINS_SADD_OVF_I32:
case INTRINS_UADD_OVF_I32:
case INTRINS_SSUB_OVF_I32:
MINI_OP(OP_SAVE_LMF, "save_lmf", NONE, NONE, NONE)
MINI_OP(OP_RESTORE_LMF, "restore_lmf", NONE, NONE, NONE)
+MINI_OP3(OP_MEMMOVE, "memmove", NONE, IREG, IREG, IREG)
+
/* write barrier */
MINI_OP(OP_CARD_TABLE_WBARRIER, "card_table_wbarrier", NONE, IREG, IREG)