* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
-#include "mini.h"
+#include "config.h"
+
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/debug-mono-symfile.h>
#include <mono/metadata/mempool-internals.h>
#include "aot-compiler.h"
#include "mini-llvm.h"
+#ifndef DISABLE_JIT
+
#ifdef __MINGW32__
#include <stddef.h>
return LLVMVectorType (LLVMInt8Type (), 16);
} else if (!strcmp (klass->name, "Vector16b")) {
return LLVMVectorType (LLVMInt8Type (), 16);
+ } else if (!strcmp (klass->name, "Vector2")) {
+ /* System.Numerics */
+ return LLVMVectorType (LLVMFloatType (), 4);
+ } else if (!strcmp (klass->name, "Vector3")) {
+ return LLVMVectorType (LLVMFloatType (), 4);
+ } else if (!strcmp (klass->name, "Vector4")) {
+ return LLVMVectorType (LLVMFloatType (), 4);
+ } else if (!strcmp (klass->name, "Vector`1")) {
+ MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
+ switch (etype->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ return LLVMVectorType (LLVMInt8Type (), 16);
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ return LLVMVectorType (LLVMInt16Type (), 8);
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ return LLVMVectorType (LLVMInt32Type (), 4);
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return LLVMVectorType (LLVMInt64Type (), 2);
+ case MONO_TYPE_R4:
+ return LLVMVectorType (LLVMFloatType (), 4);
+ case MONO_TYPE_R8:
+ return LLVMVectorType (LLVMDoubleType (), 2);
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
} else {
printf ("%s\n", klass->name);
NOT_IMPLEMENTED;
return "llvm.x86.sse2.pmulh.w";
case OP_PMULW_HIGH_UN:
return "llvm.x86.sse2.pmulhu.w";
+ case OP_DPPS:
+ return "llvm.x86.sse41.dpps";
#endif
default:
g_assert_not_reached ();
lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
+ if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
+ mono_llvm_set_call_notail (lcall);
+
/*
* Modify cconv and parameter attributes to pass rgctx/imt correctly.
*/
LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
// else move to that target bb
- for (int i=0; i < group_size; i++) {
+ for (int i = 0; i < group_size; i++) {
MonoExceptionClause *clause = group_start + i;
int clause_index = clause - cfg->header->clauses;
MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
const char *name = (const char*)ins->inst_p0;
LLVMValueRef var;
- if (!ctx->module->objc_selector_to_var)
+ if (!ctx->module->objc_selector_to_var) {
ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
+ int32_t objc_imageinfo [] = { 0, 16 };
+ LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
+ LLVMSetLinkage (info_var, LLVMPrivateLinkage);
+ LLVMSetExternallyInitialized (info_var, TRUE);
+ LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
+ LLVMSetAlignment (info_var, sizeof (mgreg_t));
+ mark_as_used (ctx->module, info_var);
+ }
+
var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
if (!var) {
LLVMValueRef indexes [16];
break;
}
+ case OP_DPPS: {
+ LLVMValueRef args [3];
+
+ args [0] = lhs;
+ args [1] = rhs;
+ /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
+ args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
+
+ values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
+ break;
+ }
+
#endif /* SIMD */
case OP_DUMMY_USE:
LLVMValueRef switch_ins = (LLVMValueRef)l->data;
GSList *bb_list = info->call_handler_return_bbs;
- for (i = 0; i < g_slist_length (bb_list); ++i)
- LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
+ GSList *bb_list_iter;
+ i = 0;
+ for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
+ LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
+ i ++;
+ }
}
}
INTRINS_SSE_PSUBUSB,
INTRINS_SSE_PAVGB,
INTRINS_SSE_PAUSE,
+ INTRINS_SSE_DPPS,
#endif
INTRINS_NUM
} IntrinsicId;
{INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
{INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
{INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
- {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
+ {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
+ {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
#endif
};
case INTRINS_SSE_PAUSE:
AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
break;
+ case INTRINS_SSE_DPPS:
+ ret_type = type_to_simd_type (MONO_TYPE_R4);
+ arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
+ arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
+ arg_types [2] = LLVMInt32Type ();
+ AddFunc (module, name, ret_type, arg_types, 3);
+ break;
#endif
default:
g_assert_not_reached ();
module->llvm_only = llvm_only;
/* The first few entries are reserved */
module->max_got_offset = 16;
- module->context = LLVMContextCreate ();
+ module->context = LLVMGetGlobalContext ();
if (llvm_only)
/* clang ignores our debug info because it has an invalid version */
* code.
* - use pointer types to help optimizations.
*/
+
+#else /* DISABLE_JIT */
+
+void
+mono_llvm_cleanup (void)
+{
+}
+
+void
+mono_llvm_free_domain_info (MonoDomain *domain)
+{
+}
+
+void
+mono_llvm_init (void)
+{
+}
+
+void
+default_mono_llvm_unhandled_exception (void)
+{
+}
+
+#endif /* DISABLE_JIT */