#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
simd_op_to_intrins (int opcode)
{
switch (opcode) {
-#if defined(TARGET_X86) || defined(TARGET_AMD64)
+#ifdef MONO_ARCH_SIMD_INTRINSICS
case OP_MINPD:
return "llvm.x86.sse2.min.pd";
case OP_MINPS:
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:
static LLVMTypeRef
simd_op_to_llvm_type (int opcode)
{
-#if defined(TARGET_X86) || defined(TARGET_AMD64)
+#ifdef MONO_ARCH_SIMD_INTRINSICS
switch (opcode) {
case OP_EXTRACT_R8:
case OP_EXPAND_R8:
LLVMValueRef *args;
LLVMCallInfo *cinfo;
GSList *l;
- int i, len;
+ int i, len, nargs;
gboolean vretaddr;
LLVMTypeRef llvm_sig;
gpointer target;
/*
* 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 (), "");
}
* 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,
}
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;
#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);
/*
* SIMD
*/
-#if defined(TARGET_X86) || defined(TARGET_AMD64)
+#ifdef MONO_ARCH_SIMD_INTRINSICS
case OP_XZERO: {
values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
break;
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:
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:
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;
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];
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]));
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)
{
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;
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);
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;
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);