#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
case MONO_TYPE_SZARRAY:
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
- return LLVMPointerType (IntPtrType (), 0);
+ return IntPtrType ();
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
/* Because of generic sharing */
- return IntPtrType ();
+ if (mini_type_var_is_vt (ctx->cfg, t))
+ return type_to_llvm_type (ctx, mini_get_gsharedvt_alloc_type_for_type (ctx->cfg, t));
+ else
+ return IntPtrType ();
case MONO_TYPE_GENERICINST:
if (!mono_type_generic_inst_is_valuetype (t))
return IntPtrType ();
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:
} else {
g_assert_not_reached ();
}
- } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
+ } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
vretaddr = TRUE;
ret_type = LLVMVoidType ();
ctx->ex_index ++;
return;
-
- FAILURE:
- return;
}
/*
MonoInst *var = cfg->varinfo [i];
LLVMTypeRef vtype;
- if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
+ if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
vtype = type_to_llvm_type (ctx, var->inst_vtype);
CHECK_FAILURE (ctx);
/* Could be already created by an OP_VPHI */
if (sig->hasthis)
emit_volatile_store (ctx, cfg->args [0]->dreg);
for (i = 0; i < sig->param_count; ++i)
- if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
+ if (!mini_type_is_vtype (cfg, sig->params [i]))
emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
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 (), "");
}
BBInfo *bblocks = ctx->bblocks;
MonoInst *ins;
LLVMBasicBlockRef cbb;
- LLVMBuilderRef builder;
+ LLVMBuilderRef builder, starting_builder;
gboolean has_terminator;
LLVMValueRef v;
LLVMValueRef lhs, rhs;
+ int nins = 0;
cbb = get_bb (ctx, bb);
builder = create_builder (ctx);
type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
- LLVMSetLinkage (type_info, LLVMPrivateLinkage);
- LLVMSetVisibility (type_info, LLVMHiddenVisibility);
+ /*
+ * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
+ */
+ LLVMSetLinkage (type_info, LLVMInternalLinkage);
/*
* Enabling this causes llc to crash:
* 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,
}
has_terminator = FALSE;
+ starting_builder = builder;
for (ins = bb->code; ins; ins = ins->next) {
const char *spec = LLVM_INS_INFO (ins->opcode);
char *dname = NULL;
char dname_buf [128];
+ nins ++;
+ if (nins > 5000 && builder == starting_builder) {
+ /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
+ LLVM_FAILURE (ctx, "basic block too long");
+ }
+
if (has_terminator)
/* There could be instructions after a terminator, skip them */
break;
break;
case OP_INOT: {
guint32 v = 0xffffffff;
- values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
+ values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
break;
}
case OP_LNOT: {
}
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;
*/
LLVM_FAILURE (ctx, "sqrt");
#endif
- args [0] = lhs;
+ args [0] = convert (ctx, lhs, LLVMDoubleType ());
values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
break;
}
case OP_ABS: {
LLVMValueRef args [1];
- args [0] = lhs;
+ args [0] = convert (ctx, lhs, LLVMDoubleType ());
values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
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);
break;
}
+ if (mini_is_gsharedvt_klass (cfg, klass)) {
+ // FIXME:
+ LLVM_FAILURE (ctx, "gsharedvt");
+ break;
+ }
+
switch (ins->opcode) {
case OP_STOREV_MEMBASE:
if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
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;
else
ctx->lmodule->throw = callee;
}
- arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
+ arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
emit_call (ctx, bb, &builder, callee, &arg, 1);
break;
}
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]));
switch (ainfo->storage) {
case LLVMArgInIReg:
case LLVMArgInFPReg: {
- MonoType *t = (sig->hasthis && i == 0) ? &mono_defaults.int_class->byval_arg : sig->params [i - sig->hasthis];
+ MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
MONO_INST_NEW (cfg, ins, OP_FMOVE);
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);