2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
11 #define __STDC_LIMIT_MACROS
12 #define __STDC_CONSTANT_MACROS
14 #include "llvm-c/Core.h"
15 #include "llvm-c/ExecutionEngine.h"
17 #include "mini-llvm-cpp.h"
20 * Information associated by mono with LLVM modules.
24 LLVMValueRef throw, throw_corlib_exception;
25 GHashTable *llvm_types;
30 * Structure containing emit state
35 /* Maps method names to the corresponding LLVMValueRef */
36 GHashTable *emitted_method_decls;
40 MonoLLVMModule *lmodule;
42 LLVMBasicBlockRef *bblocks, *end_bblocks;
43 int sindex, default_index, ex_index;
44 LLVMBuilderRef builder;
45 LLVMValueRef *values, *addresses;
47 MonoMethodSignature *sig;
60 * Instruction metadata
61 * This is the same as ins_info, but LREG != IREG.
69 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
70 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
77 /* keep in sync with the enum in mini.h */
85 #if SIZEOF_VOID_P == 4
86 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
88 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
91 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
93 #define LLVM_FAILURE(ctx, reason) do { \
94 (ctx)->cfg->exception_message = g_strdup (reason); \
95 (ctx)->cfg->disable_llvm = TRUE; \
99 #define CHECK_FAILURE(ctx) do { \
100 if ((ctx)->cfg->disable_llvm) \
104 static LLVMIntPredicate cond_to_llvm_cond [] = {
117 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
130 static LLVMExecutionEngineRef ee;
131 static guint32 current_cfg_tls_id;
133 static MonoLLVMModule jit_module, aot_module;
134 static GHashTable *plt_entries;
139 * The LLVM type with width == sizeof (gpointer)
144 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
150 * Return the size of the LLVM representation of the vtype T.
153 get_vtype_size (MonoType *t)
157 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
159 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
168 * Return the LLVM type corresponding to T.
171 type_to_llvm_type (EmitContext *ctx, MonoType *t)
174 return LLVMPointerType (LLVMInt8Type (), 0);
177 return LLVMVoidType ();
179 return LLVMInt8Type ();
181 return LLVMInt16Type ();
183 return LLVMInt32Type ();
185 return LLVMInt8Type ();
187 return LLVMInt16Type ();
189 return LLVMInt32Type ();
190 case MONO_TYPE_BOOLEAN:
191 return LLVMInt8Type ();
194 return LLVMInt64Type ();
196 return LLVMInt16Type ();
198 return LLVMFloatType ();
200 return LLVMDoubleType ();
203 return IntPtrType ();
204 case MONO_TYPE_OBJECT:
205 case MONO_TYPE_CLASS:
206 case MONO_TYPE_ARRAY:
207 case MONO_TYPE_SZARRAY:
208 case MONO_TYPE_STRING:
210 return LLVMPointerType (IntPtrType (), 0);
213 /* Because of generic sharing */
214 return IntPtrType ();
215 case MONO_TYPE_GENERICINST:
216 if (!mono_type_generic_inst_is_valuetype (t))
217 return IntPtrType ();
219 case MONO_TYPE_VALUETYPE: {
223 klass = mono_class_from_mono_type (t);
226 return type_to_llvm_type (ctx, mono_class_enum_basetype (t->data.klass));
227 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
230 LLVMTypeRef *eltypes;
232 size = get_vtype_size (t);
234 eltypes = g_new (LLVMTypeRef, size);
235 for (i = 0; i < size; ++i)
236 eltypes [i] = LLVMInt8Type ();
238 ltype = LLVMStructType (eltypes, size, FALSE);
239 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
246 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
247 ctx->cfg->disable_llvm = TRUE;
253 * type_to_llvm_arg_type:
255 * Same as type_to_llvm_type, but treat i8/i16 as i32.
258 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
260 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
262 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
264 * LLVM generates code which only sets the lower bits, while JITted
265 * code expects all the bits to be set.
267 ptype = LLVMInt32Type ();
274 * llvm_type_to_stack_type:
276 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
279 static G_GNUC_UNUSED LLVMTypeRef
280 llvm_type_to_stack_type (LLVMTypeRef type)
284 if (type == LLVMInt8Type ())
285 return LLVMInt32Type ();
286 else if (type == LLVMInt16Type ())
287 return LLVMInt32Type ();
288 else if (type == LLVMFloatType ())
289 return LLVMDoubleType ();
295 * regtype_to_llvm_type:
297 * Return the LLVM type corresponding to the regtype C used in instruction
301 regtype_to_llvm_type (char c)
305 return LLVMInt32Type ();
307 return LLVMInt64Type ();
309 return LLVMDoubleType ();
318 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
321 op_to_llvm_type (int opcode)
326 return LLVMInt8Type ();
329 return LLVMInt8Type ();
332 return LLVMInt16Type ();
335 return LLVMInt16Type ();
338 return LLVMInt32Type ();
341 return LLVMInt32Type ();
343 return LLVMInt64Type ();
345 return LLVMFloatType ();
347 return LLVMDoubleType ();
349 return LLVMInt64Type ();
351 return LLVMInt32Type ();
353 return LLVMInt64Type ();
356 return LLVMInt8Type ();
359 return LLVMInt16Type ();
362 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
369 return LLVMInt32Type ();
375 return LLVMInt64Type ();
377 printf ("%s\n", mono_inst_name (opcode));
378 g_assert_not_reached ();
384 * load_store_to_llvm_type:
386 * Return the size/sign/zero extension corresponding to the load/store opcode
390 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
396 case OP_LOADI1_MEMBASE:
397 case OP_STOREI1_MEMBASE_REG:
398 case OP_STOREI1_MEMBASE_IMM:
401 return LLVMInt8Type ();
402 case OP_LOADU1_MEMBASE:
406 return LLVMInt8Type ();
407 case OP_LOADI2_MEMBASE:
408 case OP_STOREI2_MEMBASE_REG:
409 case OP_STOREI2_MEMBASE_IMM:
412 return LLVMInt16Type ();
413 case OP_LOADU2_MEMBASE:
417 return LLVMInt16Type ();
418 case OP_LOADI4_MEMBASE:
419 case OP_LOADU4_MEMBASE:
422 case OP_STOREI4_MEMBASE_REG:
423 case OP_STOREI4_MEMBASE_IMM:
425 return LLVMInt32Type ();
426 case OP_LOADI8_MEMBASE:
428 case OP_STOREI8_MEMBASE_REG:
429 case OP_STOREI8_MEMBASE_IMM:
431 return LLVMInt64Type ();
432 case OP_LOADR4_MEMBASE:
433 case OP_STORER4_MEMBASE_REG:
435 return LLVMFloatType ();
436 case OP_LOADR8_MEMBASE:
437 case OP_STORER8_MEMBASE_REG:
439 return LLVMDoubleType ();
440 case OP_LOAD_MEMBASE:
442 case OP_STORE_MEMBASE_REG:
443 case OP_STORE_MEMBASE_IMM:
444 *size = sizeof (gpointer);
445 return IntPtrType ();
447 g_assert_not_reached ();
455 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
458 ovf_op_to_intrins (int opcode)
462 return "llvm.sadd.with.overflow.i32";
464 return "llvm.uadd.with.overflow.i32";
466 return "llvm.ssub.with.overflow.i32";
468 return "llvm.usub.with.overflow.i32";
470 return "llvm.smul.with.overflow.i32";
472 return "llvm.umul.with.overflow.i32";
474 return "llvm.sadd.with.overflow.i64";
476 return "llvm.uadd.with.overflow.i64";
478 return "llvm.ssub.with.overflow.i64";
480 return "llvm.usub.with.overflow.i64";
482 return "llvm.smul.with.overflow.i64";
484 return "llvm.umul.with.overflow.i64";
486 g_assert_not_reached ();
494 * Return the LLVM basic block corresponding to BB.
496 static LLVMBasicBlockRef
497 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
501 if (ctx->bblocks [bb->block_num] == NULL) {
502 sprintf (bb_name, "BB%d", bb->block_num);
504 ctx->bblocks [bb->block_num] = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
505 ctx->end_bblocks [bb->block_num] = ctx->bblocks [bb->block_num];
508 return ctx->bblocks [bb->block_num];
514 * Return the last LLVM bblock corresponding to BB.
515 * This might not be equal to the bb returned by get_bb () since we need to generate
516 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
518 static LLVMBasicBlockRef
519 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
522 return ctx->end_bblocks [bb->block_num];
528 * Return the target of the patch identified by TYPE and TARGET.
531 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
535 memset (&ji, 0, sizeof (ji));
537 ji.data.target = target;
539 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
545 * Emit code to convert the LLVM value V to DTYPE.
548 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
550 LLVMTypeRef stype = LLVMTypeOf (v);
552 if (stype != dtype) {
554 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
555 return LLVMBuildSExt (ctx->builder, v, dtype, "");
556 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
557 return LLVMBuildSExt (ctx->builder, v, dtype, "");
558 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
559 return LLVMBuildSExt (ctx->builder, v, dtype, "");
560 else if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
561 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
564 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
565 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
566 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
567 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
568 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
569 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
571 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
572 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
573 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
574 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
575 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
576 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
579 LLVMDumpValue (LLVMConstNull (dtype));
580 g_assert_not_reached ();
588 * emit_volatile_store:
590 * If VREG is volatile, emit a store from its value to its address.
593 emit_volatile_store (EmitContext *ctx, int vreg)
595 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
597 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
598 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
605 * Return the LLVM signature corresponding to the mono signature SIG using the
606 * calling convention information in CINFO.
609 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
611 LLVMTypeRef ret_type;
612 LLVMTypeRef *param_types = NULL;
615 gboolean vretaddr = FALSE;
617 ret_type = type_to_llvm_type (ctx, sig->ret);
620 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
621 /* LLVM models this by returning an aggregate value */
622 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
623 LLVMTypeRef members [2];
625 members [0] = IntPtrType ();
626 ret_type = LLVMStructType (members, 1, FALSE);
628 g_assert_not_reached ();
630 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
631 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
635 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 2);
638 ret_type = LLVMVoidType ();
639 param_types [pindex ++] = IntPtrType ();
642 param_types [pindex ++] = IntPtrType ();
643 for (i = 0; i < sig->param_count; ++i) {
644 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
645 for (j = 0; j < 2; ++j) {
646 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
648 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
653 g_assert_not_reached ();
656 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
657 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
659 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
662 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
667 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
668 g_free (param_types);
673 g_free (param_types);
681 * Create an LLVM function type from the arguments.
683 static G_GNUC_UNUSED LLVMTypeRef
684 LLVMFunctionType1(LLVMTypeRef ReturnType,
685 LLVMTypeRef ParamType1,
688 LLVMTypeRef param_types [1];
690 param_types [0] = ParamType1;
692 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
698 * Create an LLVM function type from the arguments.
701 LLVMFunctionType2(LLVMTypeRef ReturnType,
702 LLVMTypeRef ParamType1,
703 LLVMTypeRef ParamType2,
706 LLVMTypeRef param_types [2];
708 param_types [0] = ParamType1;
709 param_types [1] = ParamType2;
711 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
717 * Create an LLVM function type from the arguments.
720 LLVMFunctionType3(LLVMTypeRef ReturnType,
721 LLVMTypeRef ParamType1,
722 LLVMTypeRef ParamType2,
723 LLVMTypeRef ParamType3,
726 LLVMTypeRef param_types [3];
728 param_types [0] = ParamType1;
729 param_types [1] = ParamType2;
730 param_types [2] = ParamType3;
732 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
738 * Create an LLVM builder and remember it so it can be freed later.
740 static LLVMBuilderRef
741 create_builder (EmitContext *ctx)
743 LLVMBuilderRef builder = LLVMCreateBuilder ();
745 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
751 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
758 emit_cond_throw_pos (EmitContext *ctx)
763 * emit_cond_system_exception:
765 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
768 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
771 LLVMBasicBlockRef ex_bb, noex_bb;
772 LLVMBuilderRef builder;
773 MonoClass *exc_class;
774 LLVMValueRef args [2];
776 sprintf (bb_name, "EX_BB%d", ctx->ex_index);
777 ex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
779 sprintf (bb_name, "NOEX_BB%d", ctx->ex_index);
780 noex_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
782 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
784 ctx->builder = create_builder (ctx);
785 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
787 ctx->end_bblocks [bb->block_num] = noex_bb;
789 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
790 g_assert (exc_class);
792 /* Emit exception throwing code */
793 builder = create_builder (ctx);
794 LLVMPositionBuilderAtEnd (builder, ex_bb);
796 if (!ctx->lmodule->throw_corlib_exception) {
800 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
801 throw_sig->ret = &mono_defaults.void_class->byval_arg;
802 throw_sig->params [0] = &mono_defaults.int32_class->byval_arg;
803 throw_sig->params [1] = &mono_defaults.int32_class->byval_arg;
804 sig = sig_to_llvm_sig (ctx, throw_sig, NULL);
806 if (ctx->cfg->compile_aot) {
807 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception");
809 callee = LLVMAddFunction (ctx->module, "throw_corlib_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
811 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception"));
814 mono_memory_barrier ();
815 ctx->lmodule->throw_corlib_exception = callee;
818 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
820 * FIXME: The offset is 0, this is not a problem for exception handling
821 * in general, because we don't llvm compile methods with handlers, its only
822 * a problem for line numbers in stack traces.
824 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
825 LLVMBuildCall (builder, ctx->lmodule->throw_corlib_exception, args, 2, "");
827 LLVMBuildUnreachable (builder);
835 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
838 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
842 size = get_vtype_size (t);
844 for (j = 0; j < 2; ++j) {
845 LLVMValueRef index [2], addr;
846 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
847 LLVMTypeRef part_type;
849 if (ainfo->pair_storage [j] == LLVMArgNone)
852 part_type = LLVMIntType (part_size * 8);
853 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
854 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
855 addr = LLVMBuildGEP (builder, address, index, 2, "");
856 switch (ainfo->pair_storage [j]) {
858 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
863 g_assert_not_reached ();
866 size -= sizeof (gpointer);
873 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
874 * into REGS, and the number of registers into NREGS.
877 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
882 size = get_vtype_size (t);
884 for (j = 0; j < 2; ++j) {
885 LLVMValueRef index [2], addr;
886 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
888 if (ainfo->pair_storage [j] == LLVMArgNone)
891 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
892 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
893 addr = LLVMBuildGEP (builder, address, index, 2, "");
894 switch (ainfo->pair_storage [j]) {
896 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
901 g_assert_not_reached ();
903 size -= sizeof (gpointer);
912 * Emit code to load/convert arguments.
915 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
918 MonoCompile *cfg = ctx->cfg;
919 MonoMethodSignature *sig = ctx->sig;
920 LLVMCallInfo *linfo = ctx->linfo;
923 * Handle indirect/volatile variables by allocating memory for them
924 * using 'alloca', and storing their address in a temporary.
926 for (i = 0; i < cfg->num_varinfo; ++i) {
927 MonoInst *var = cfg->varinfo [i];
930 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
931 vtype = type_to_llvm_type (ctx, var->inst_vtype);
933 ctx->addresses [var->dreg] = LLVMBuildAlloca (builder, vtype, "");
937 for (i = 0; i < sig->param_count; ++i) {
938 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
939 int reg = cfg->args [i + sig->hasthis]->dreg;
941 if (ainfo->storage == LLVMArgVtypeInReg) {
942 LLVMValueRef regs [2];
945 * Emit code to save the argument from the registers to
948 pindex = pindexes [i];
949 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
950 if (ainfo->pair_storage [1] != LLVMArgNone)
951 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
955 ctx->addresses [reg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->params [i])->byval_arg)), "");
957 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
958 } else if (ainfo->storage == LLVMArgVtypeByVal) {
959 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindexes [i]);
961 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
965 for (i = 0; i < sig->param_count; ++i)
966 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
967 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
974 * mono_llvm_emit_method:
976 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
979 mono_llvm_emit_method (MonoCompile *cfg)
982 MonoMethodSignature *sig;
984 LLVMTypeRef method_type;
985 LLVMValueRef method = NULL;
986 char *method_name, *debug_name;
987 LLVMValueRef *values, *addresses;
988 LLVMTypeRef *vreg_types;
989 int i, max_block_num, pindex;
990 int *pindexes = NULL;
991 GHashTable *phi_nodes;
992 gboolean last = FALSE;
993 GPtrArray *phi_values;
996 LLVMModuleRef module;
998 /* The code below might acquire the loader lock, so use it for global locking */
1001 /* Used to communicate with the callbacks */
1002 TlsSetValue (current_cfg_tls_id, cfg);
1004 ctx = g_new0 (EmitContext, 1);
1006 ctx->mempool = cfg->mempool;
1009 * This maps vregs to the LLVM instruction defining them
1011 values = g_new0 (LLVMValueRef, cfg->next_vreg);
1013 * This maps vregs for volatile variables to the LLVM instruction defining their
1016 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
1017 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
1018 phi_nodes = g_hash_table_new (NULL, NULL);
1019 phi_values = g_ptr_array_new ();
1021 ctx->values = values;
1022 ctx->addresses = addresses;
1024 if (cfg->compile_aot) {
1025 ctx->lmodule = &aot_module;
1028 ctx->lmodule = &jit_module;
1029 method_name = mono_method_full_name (cfg->method, TRUE);
1033 module = ctx->module = ctx->lmodule->module;
1037 static int count = 0;
1040 if (getenv ("LLVM_COUNT")) {
1041 if (count == atoi (getenv ("LLVM_COUNT"))) {
1042 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
1045 if (count > atoi (getenv ("LLVM_COUNT")))
1046 LLVM_FAILURE (ctx, "");
1051 sig = mono_method_signature (cfg->method);
1054 linfo = mono_arch_get_llvm_call_info (cfg, sig);
1056 CHECK_FAILURE (ctx);
1058 method_type = sig_to_llvm_sig (ctx, sig, linfo);
1059 CHECK_FAILURE (ctx);
1061 method = LLVMAddFunction (module, method_name, method_type);
1062 ctx->lmethod = method;
1063 g_free (method_name);
1065 LLVMSetLinkage (method, LLVMPrivateLinkage);
1067 if (cfg->method->save_lmf)
1068 LLVM_FAILURE (ctx, "lmf");
1071 LLVM_FAILURE (ctx, "pinvoke signature");
1074 * This maps parameter indexes in the original signature to the indexes in
1075 * the LLVM signature.
1077 pindexes = g_new0 (int, sig->param_count);
1079 if (cfg->vret_addr) {
1080 values [cfg->vret_addr->dreg] = LLVMGetParam (method, pindex);
1084 values [cfg->args [0]->dreg] = LLVMGetParam (method, pindex);
1087 for (i = 0; i < sig->param_count; ++i) {
1088 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
1089 pindexes [i] = pindex;
1090 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1091 if (linfo->args [i + sig->hasthis].pair_storage [0] != LLVMArgNone)
1093 if (linfo->args [i + sig->hasthis].pair_storage [1] != LLVMArgNone)
1095 } else if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1096 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
1104 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
1105 max_block_num = MAX (max_block_num, bb->block_num);
1106 ctx->bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
1107 ctx->end_bblocks = g_new0 (LLVMBasicBlockRef, max_block_num + 1);
1109 /* Add branches between non-consecutive bblocks */
1110 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1111 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
1112 bb->next_bb != bb->last_ins->inst_false_bb) {
1114 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
1115 inst->opcode = OP_BR;
1116 inst->inst_target_bb = bb->last_ins->inst_false_bb;
1117 mono_bblock_add_inst (bb, inst);
1122 * Make a first pass over the code to precreate PHI nodes.
1124 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1126 LLVMBuilderRef builder;
1128 char dname_buf[128];
1130 builder = create_builder (ctx);
1132 for (ins = bb->code; ins; ins = ins->next) {
1133 switch (ins->opcode) {
1136 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
1138 CHECK_FAILURE (ctx);
1141 * Have to precreate these, as they can be referenced by
1142 * earlier instructions.
1144 sprintf (dname_buf, "t%d", ins->dreg);
1146 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
1148 g_ptr_array_add (phi_values, values [ins->dreg]);
1151 * Set the expected type of the incoming arguments since these have
1152 * to have the same type.
1154 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1155 int sreg1 = ins->inst_phi_args [i + 1];
1158 vreg_types [sreg1] = phi_type;
1169 * Second pass: generate code.
1171 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1173 LLVMBasicBlockRef cbb;
1174 LLVMBuilderRef builder;
1175 gboolean has_terminator;
1177 LLVMValueRef lhs, rhs;
1179 if (!(bb == cfg->bb_entry || bb->in_count > 0))
1182 cbb = get_bb (ctx, bb);
1183 builder = create_builder (ctx);
1184 ctx->builder = builder;
1185 LLVMPositionBuilderAtEnd (builder, cbb);
1187 if (bb == cfg->bb_entry)
1188 emit_entry_bb (ctx, builder, pindexes);
1189 CHECK_FAILURE (ctx);
1191 has_terminator = FALSE;
1192 for (ins = bb->code; ins; ins = ins->next) {
1193 const char *spec = LLVM_INS_INFO (ins->opcode);
1195 char dname_buf [128];
1198 /* There could be instructions after a terminator, skip them */
1201 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
1202 sprintf (dname_buf, "t%d", ins->dreg);
1206 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
1207 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
1209 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1210 lhs = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
1212 /* It is ok for SETRET to have an uninitialized argument */
1213 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
1214 LLVM_FAILURE (ctx, "sreg1");
1215 lhs = values [ins->sreg1];
1221 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
1222 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
1223 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1224 rhs = LLVMBuildLoad (builder, addresses [ins->sreg2], "");
1226 if (!values [ins->sreg2])
1227 LLVM_FAILURE (ctx, "sreg2");
1228 rhs = values [ins->sreg2];
1234 //mono_print_ins (ins);
1235 switch (ins->opcode) {
1238 case OP_LIVERANGE_START:
1239 case OP_LIVERANGE_END:
1242 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
1245 #if SIZEOF_VOID_P == 4
1246 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1248 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
1252 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
1255 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
1258 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
1259 has_terminator = TRUE;
1265 LLVMBasicBlockRef new_bb;
1266 LLVMBuilderRef new_builder;
1268 // The default branch is already handled
1269 // FIXME: Handle it here
1271 /* Start new bblock */
1272 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
1273 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1275 lhs = convert (ctx, lhs, LLVMInt32Type ());
1276 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
1277 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
1278 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
1280 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
1283 new_builder = create_builder (ctx);
1284 LLVMPositionBuilderAtEnd (new_builder, new_bb);
1285 LLVMBuildUnreachable (new_builder);
1287 has_terminator = TRUE;
1288 g_assert (!ins->next);
1294 if (linfo->ret.storage == LLVMArgVtypeInReg) {
1295 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
1296 LLVMValueRef part1, retval;
1299 size = get_vtype_size (sig->ret);
1301 g_assert (addresses [ins->sreg1]);
1303 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
1304 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
1306 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
1308 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
1310 LLVMBuildRet (builder, retval);
1316 * The method did not set its return value, probably because it
1317 * ends with a throw.
1320 LLVMBuildRetVoid (builder);
1322 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
1324 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
1326 has_terminator = TRUE;
1332 case OP_ICOMPARE_IMM:
1333 case OP_LCOMPARE_IMM:
1334 case OP_COMPARE_IMM:
1336 case OP_AMD64_ICOMPARE_MEMBASE_REG:
1337 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
1340 case OP_X86_COMPARE_MEMBASE_REG:
1341 case OP_X86_COMPARE_MEMBASE_IMM:
1347 if (ins->next->opcode == OP_NOP)
1350 if (ins->next->opcode == OP_BR)
1351 /* The comparison result is not needed */
1354 rel = mono_opcode_to_cond (ins->next->opcode);
1356 /* Used for implementing bound checks */
1358 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
1363 t = LLVMInt32Type ();
1365 g_assert (ins->inst_offset % size == 0);
1366 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1368 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1370 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
1371 lhs = convert (ctx, lhs, LLVMInt32Type ());
1372 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1374 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
1375 rhs = convert (ctx, rhs, LLVMInt32Type ());
1379 if ((ins->opcode == OP_X86_COMPARE_MEMBASE_REG) || (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM)) {
1384 t = LLVMInt32Type ();
1386 g_assert (ins->inst_offset % size == 0);
1387 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1389 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1391 if (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM) {
1392 lhs = convert (ctx, lhs, LLVMInt32Type ());
1393 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1395 if (ins->opcode == OP_X86_COMPARE_MEMBASE_REG)
1396 rhs = convert (ctx, rhs, LLVMInt32Type ());
1399 if (ins->opcode == OP_ICOMPARE_IMM) {
1400 lhs = convert (ctx, lhs, LLVMInt32Type ());
1401 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1403 if (ins->opcode == OP_LCOMPARE_IMM) {
1404 lhs = convert (ctx, lhs, LLVMInt64Type ());
1405 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1407 if (ins->opcode == OP_LCOMPARE) {
1408 lhs = convert (ctx, lhs, LLVMInt64Type ());
1409 rhs = convert (ctx, rhs, LLVMInt64Type ());
1411 if (ins->opcode == OP_ICOMPARE) {
1412 lhs = convert (ctx, lhs, LLVMInt32Type ());
1413 rhs = convert (ctx, rhs, LLVMInt32Type ());
1417 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1418 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
1419 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
1420 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
1423 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
1424 if (ins->opcode == OP_FCOMPARE)
1425 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1426 else if (ins->opcode == OP_COMPARE_IMM)
1427 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
1428 else if (ins->opcode == OP_COMPARE)
1429 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
1431 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
1433 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
1434 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
1435 has_terminator = TRUE;
1436 } else if (MONO_IS_SETCC (ins->next)) {
1437 sprintf (dname_buf, "t%d", ins->next->dreg);
1439 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1441 /* Add stores for volatile variables */
1442 emit_volatile_store (ctx, ins->next->dreg);
1443 } else if (MONO_IS_COND_EXC (ins->next)) {
1444 //emit_cond_throw_pos (ctx);
1445 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
1446 builder = ctx->builder;
1448 LLVM_FAILURE (ctx, "next");
1462 rel = mono_opcode_to_cond (ins->opcode);
1464 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1465 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1472 /* Created earlier, insert it now */
1473 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
1475 /* Check that all input bblocks really branch to us */
1476 for (i = 0; i < bb->in_count; ++i) {
1477 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
1478 ins->inst_phi_args [i + 1] = -1;
1481 // FIXME: If a SWITCH statement branches to the same bblock in more
1482 // than once case, the PHI should reference the bblock multiple times
1483 for (i = 0; i < bb->in_count; ++i)
1484 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
1485 LLVM_FAILURE (ctx, "switch + phi");
1489 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1490 int sreg1 = ins->inst_phi_args [i + 1];
1491 LLVMBasicBlockRef in_bb;
1496 /* Add incoming values which are already defined */
1497 if (FALSE && values [sreg1]) {
1498 in_bb = get_end_bb (ctx, bb->in_bb [i]);
1500 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [ins->dreg]));
1501 LLVMAddIncoming (values [ins->dreg], &values [sreg1], &in_bb, 1);
1503 /* Remember for later */
1504 //LLVM_FAILURE (ctx, "phi incoming value");
1505 GSList *node_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]));
1506 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
1510 node_list = g_slist_prepend_mempool (ctx->mempool, node_list, node);
1511 g_hash_table_insert (phi_nodes, GUINT_TO_POINTER (bb->in_bb [i]), node_list);
1519 values [ins->dreg] = lhs;
1522 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
1525 values [ins->dreg] = lhs;
1527 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
1529 * This is added by the spilling pass in case of the JIT,
1530 * but we have to do it ourselves.
1532 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
1566 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1567 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
1569 switch (ins->opcode) {
1573 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
1578 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
1583 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
1587 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
1591 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
1595 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
1599 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
1602 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
1606 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
1610 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
1614 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
1618 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
1622 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
1626 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
1629 g_assert_not_reached ();
1636 case OP_IREM_UN_IMM:
1638 case OP_IDIV_UN_IMM:
1644 case OP_ISHR_UN_IMM:
1653 case OP_LSHR_UN_IMM:
1660 if (spec [MONO_INST_SRC1] == 'l') {
1661 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1663 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1666 #if SIZEOF_VOID_P == 4
1667 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
1668 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1671 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1672 lhs = convert (ctx, lhs, IntPtrType ());
1673 imm = convert (ctx, imm, LLVMTypeOf (lhs));
1674 switch (ins->opcode) {
1678 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
1682 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
1686 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
1690 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
1692 case OP_IDIV_UN_IMM:
1693 case OP_LDIV_UN_IMM:
1694 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
1698 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
1700 case OP_IREM_UN_IMM:
1701 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
1706 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
1710 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
1714 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
1719 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
1723 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
1725 case OP_ISHR_UN_IMM:
1726 /* This is used to implement conv.u4, so the lhs could be an i8 */
1727 lhs = convert (ctx, lhs, LLVMInt32Type ());
1728 imm = convert (ctx, imm, LLVMInt32Type ());
1729 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
1731 case OP_LSHR_UN_IMM:
1732 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
1735 g_assert_not_reached ();
1740 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
1743 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
1746 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
1749 guint32 v = 0xffffffff;
1750 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
1754 guint64 v = 0xffffffffffffffffLL;
1755 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
1759 LLVMValueRef v1, v2;
1761 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
1762 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
1763 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
1767 case OP_ICONV_TO_I1:
1768 case OP_ICONV_TO_I2:
1769 case OP_ICONV_TO_I4:
1770 case OP_ICONV_TO_U1:
1771 case OP_ICONV_TO_U2:
1772 case OP_ICONV_TO_U4:
1773 case OP_LCONV_TO_I1:
1774 case OP_LCONV_TO_I2:
1775 case OP_LCONV_TO_U1:
1776 case OP_LCONV_TO_U2:
1777 case OP_LCONV_TO_U4: {
1780 sign = (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_ICONV_TO_I4) || (ins->opcode == OP_LCONV_TO_I1) || (ins->opcode == OP_LCONV_TO_I2);
1782 /* Have to do two casts since our vregs have type int */
1783 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
1785 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
1787 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
1790 case OP_ICONV_TO_I8:
1791 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1793 case OP_ICONV_TO_U8:
1794 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1796 case OP_FCONV_TO_I4:
1797 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
1799 case OP_FCONV_TO_I1:
1800 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
1802 case OP_FCONV_TO_U1:
1803 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
1805 case OP_FCONV_TO_I2:
1806 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
1808 case OP_FCONV_TO_U2:
1809 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
1811 case OP_FCONV_TO_I8:
1812 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
1815 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
1817 case OP_ICONV_TO_R8:
1818 case OP_LCONV_TO_R8:
1819 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
1821 case OP_LCONV_TO_R_UN:
1822 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
1824 #if SIZEOF_VOID_P == 4
1827 case OP_LCONV_TO_I4:
1828 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1830 case OP_ICONV_TO_R4:
1831 case OP_LCONV_TO_R4:
1832 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
1833 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1835 case OP_FCONV_TO_R4:
1836 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
1837 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
1840 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
1843 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
1846 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
1848 case OP_LOCALLOC_IMM: {
1851 guint32 size = ins->inst_imm;
1852 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
1854 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
1856 if (ins->flags & MONO_INST_INIT) {
1857 LLVMValueRef args [4];
1860 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
1861 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
1862 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
1863 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
1866 values [ins->dreg] = v;
1869 case OP_LOADI1_MEMBASE:
1870 case OP_LOADU1_MEMBASE:
1871 case OP_LOADI2_MEMBASE:
1872 case OP_LOADU2_MEMBASE:
1873 case OP_LOADI4_MEMBASE:
1874 case OP_LOADU4_MEMBASE:
1875 case OP_LOADI8_MEMBASE:
1876 case OP_LOADR4_MEMBASE:
1877 case OP_LOADR8_MEMBASE:
1878 case OP_LOAD_MEMBASE:
1888 gboolean sext = FALSE, zext = FALSE;
1890 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1896 * We emit volatile loads because otherwise LLVM will
1897 * generate invalid code when encountering a load from a
1899 * FIXME: Avoid this somehow.
1901 g_assert (ins->inst_offset % size == 0);
1902 if ((ins->opcode == OP_LOADI8_MEM) || (ins->opcode == OP_LOAD_MEM) || (ins->opcode == OP_LOADI4_MEM) || (ins->opcode == OP_LOADU4_MEM) || (ins->opcode == OP_LOADU1_MEM) || (ins->opcode == OP_LOADU2_MEM)) {
1903 values [ins->dreg] = mono_llvm_build_volatile_load (builder, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), LLVMPointerType (t, 0)), dname);
1904 } else if (ins->inst_offset == 0) {
1905 values [ins->dreg] = mono_llvm_build_volatile_load (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), dname);
1907 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1908 values [ins->dreg] = mono_llvm_build_volatile_load (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), dname);
1911 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1913 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
1914 else if (ins->opcode == OP_LOADR4_MEMBASE)
1915 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
1919 case OP_STOREI1_MEMBASE_REG:
1920 case OP_STOREI2_MEMBASE_REG:
1921 case OP_STOREI4_MEMBASE_REG:
1922 case OP_STOREI8_MEMBASE_REG:
1923 case OP_STORER4_MEMBASE_REG:
1924 case OP_STORER8_MEMBASE_REG:
1925 case OP_STORE_MEMBASE_REG: {
1929 gboolean sext = FALSE, zext = FALSE;
1931 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1933 g_assert (ins->inst_offset % size == 0);
1934 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1935 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, ""));
1939 case OP_STOREI1_MEMBASE_IMM:
1940 case OP_STOREI2_MEMBASE_IMM:
1941 case OP_STOREI4_MEMBASE_IMM:
1942 case OP_STOREI8_MEMBASE_IMM:
1943 case OP_STORE_MEMBASE_IMM: {
1947 gboolean sext = FALSE, zext = FALSE;
1949 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
1951 g_assert (ins->inst_offset % size == 0);
1952 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1953 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE), t), LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, ""));
1958 mono_llvm_build_volatile_load (builder, convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "");
1960 case OP_OUTARG_VTRETADDR:
1967 case OP_VOIDCALL_MEMBASE:
1968 case OP_CALL_MEMBASE:
1969 case OP_LCALL_MEMBASE:
1970 case OP_FCALL_MEMBASE:
1971 case OP_VCALL_MEMBASE: {
1972 MonoCallInst *call = (MonoCallInst*)ins;
1973 MonoMethodSignature *sig = call->signature;
1974 LLVMValueRef callee, lcall;
1976 LLVMCallInfo *cinfo;
1980 LLVMTypeRef llvm_sig;
1984 cinfo = call->cinfo;
1986 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1988 llvm_sig = sig_to_llvm_sig (ctx, sig, cinfo);
1989 CHECK_FAILURE (ctx);
1991 if (call->rgctx_reg) {
1992 LLVM_FAILURE (ctx, "rgctx reg");
1995 pindexes = mono_mempool_alloc0 (cfg->mempool, sig->param_count + 2);
1997 /* FIXME: Avoid creating duplicate methods */
1999 if (ins->flags & MONO_INST_HAS_METHOD) {
2000 if (cfg->compile_aot) {
2001 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2003 callee = LLVMAddFunction (module, "", llvm_sig);
2006 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2008 LLVMAddGlobalMapping (ee, callee, target);
2011 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2017 memset (&ji, 0, sizeof (ji));
2018 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2019 ji.data.target = info->name;
2021 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2023 if (cfg->compile_aot) {
2024 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2026 callee = LLVMAddFunction (module, "", llvm_sig);
2027 target = (gpointer)mono_icall_get_wrapper (info);
2028 LLVMAddGlobalMapping (ee, callee, target);
2031 if (cfg->compile_aot) {
2033 if (cfg->abs_patches) {
2034 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2036 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2040 LLVM_FAILURE (ctx, "aot");
2042 callee = LLVMAddFunction (module, "", llvm_sig);
2044 if (cfg->abs_patches) {
2045 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2047 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2048 LLVMAddGlobalMapping (ee, callee, target);
2052 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
2057 if (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE) {
2058 int size = sizeof (gpointer);
2061 g_assert (ins->inst_offset % size == 0);
2062 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2064 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2066 // FIXME: mono_arch_get_vcall_slot () can't decode the code
2067 // generated by LLVM
2068 //LLVM_FAILURE (ctx, "virtual call");
2070 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
2071 /* No support for passing the IMT argument */
2072 LLVM_FAILURE (ctx, "imt");
2074 if (ins->flags & MONO_INST_HAS_METHOD) {
2079 * Collect and convert arguments
2082 args = alloca (sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr));
2083 l = call->out_ireg_args;
2086 if (!addresses [call->inst.dreg])
2087 addresses [call->inst.dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->ret)->byval_arg)), "");
2088 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2091 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2094 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2096 regpair = (guint32)(gssize)(l->data);
2097 reg = regpair & 0xffffff;
2098 args [pindex] = values [reg];
2099 if (ainfo->storage == LLVMArgVtypeInReg) {
2101 LLVMValueRef regs [2];
2106 g_assert (addresses [reg]);
2108 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2109 for (j = 0; j < nregs; ++j)
2110 args [pindex ++] = regs [j];
2113 // FIXME: Get rid of the VMOVE
2114 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2115 g_assert (addresses [reg]);
2116 args [pindex] = addresses [reg];
2117 pindexes [i] = pindex;
2120 g_assert (args [pindex]);
2121 if (i == 0 && sig->hasthis)
2122 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2124 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2131 // FIXME: Align call sites
2136 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
2138 /* Add byval attributes if needed */
2139 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2140 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2142 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2143 LLVMAddInstrAttribute (lcall, pindexes [i] + 1, LLVMByValAttribute);
2148 * Convert the result
2150 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2151 LLVMValueRef regs [2];
2153 if (!addresses [ins->dreg])
2154 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &(mono_class_from_mono_type (sig->ret)->byval_arg)), "");
2156 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2157 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2158 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2160 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2161 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2162 values [ins->dreg] = convert (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)));
2166 case OP_GOT_ENTRY: {
2167 LLVMValueRef indexes [2];
2169 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2170 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)ins->inst_p0, FALSE);
2171 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, ""), dname);
2175 MonoMethodSignature *throw_sig;
2176 LLVMValueRef callee, arg;
2178 if (!ctx->lmodule->throw) {
2179 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
2180 throw_sig->ret = &mono_defaults.void_class->byval_arg;
2181 throw_sig->params [0] = &mono_defaults.object_class->byval_arg;
2182 if (cfg->compile_aot) {
2183 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig, NULL), MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception");
2185 callee = LLVMAddFunction (module, "mono_arch_throw_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
2186 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception"));
2189 mono_memory_barrier ();
2190 ctx->lmodule->throw = callee;
2192 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_defaults.object_class->byval_arg));
2193 LLVMBuildCall (builder, ctx->lmodule->throw, &arg, 1, "");
2196 case OP_NOT_REACHED:
2197 LLVMBuildUnreachable (builder);
2198 has_terminator = TRUE;
2199 /* Might have instructions after this */
2201 MonoInst *next = ins->next;
2202 MONO_DELETE_INS (bb, next);
2206 MonoInst *var = ins->inst_p0;
2208 values [ins->dreg] = addresses [var->dreg];
2212 LLVMValueRef args [1];
2215 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
2219 LLVMValueRef args [1];
2222 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
2225 /* test_0_sqrt_nan fails with LLVM */
2228 LLVMValueRef args [1];
2231 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
2238 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
2239 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2244 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
2245 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2250 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
2251 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2256 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
2257 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2260 case OP_ATOMIC_EXCHANGE_I4: {
2261 LLVMValueRef args [2];
2263 g_assert (ins->inst_offset == 0);
2265 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2267 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
2270 case OP_ATOMIC_EXCHANGE_I8: {
2271 LLVMValueRef args [2];
2273 g_assert (ins->inst_offset == 0);
2275 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2277 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
2280 case OP_ATOMIC_ADD_NEW_I4: {
2281 LLVMValueRef args [2];
2283 g_assert (ins->inst_offset == 0);
2285 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2287 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
2290 case OP_ATOMIC_ADD_NEW_I8: {
2291 LLVMValueRef args [2];
2293 g_assert (ins->inst_offset == 0);
2295 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2296 args [1] = convert (ctx, rhs, LLVMInt64Type ());
2297 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
2300 case OP_ATOMIC_CAS_I4:
2301 case OP_ATOMIC_CAS_I8: {
2302 LLVMValueRef args [3];
2304 const char *intrins;
2306 if (ins->opcode == OP_ATOMIC_CAS_I4) {
2307 t = LLVMInt32Type ();
2308 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
2310 t = LLVMInt64Type ();
2311 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
2314 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
2316 args [1] = convert (ctx, values [ins->sreg3], t);
2318 args [2] = convert (ctx, values [ins->sreg2], t);
2319 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
2322 case OP_MEMORY_BARRIER: {
2323 LLVMValueRef args [5];
2325 for (i = 0; i < 5; ++i)
2326 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
2328 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
2333 #if defined(TARGET_AMD64) || defined(TARGET_X86)
2335 // 257 == FS segment register
2336 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
2338 // 256 == GS segment register
2339 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
2343 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
2345 LLVM_FAILURE (ctx, "opcode tls-get");
2355 case OP_IADD_OVF_UN:
2357 case OP_ISUB_OVF_UN:
2359 case OP_IMUL_OVF_UN:
2360 #if SIZEOF_VOID_P == 8
2363 case OP_LSUB_OVF_UN:
2365 case OP_LMUL_OVF_UN:
2368 LLVMValueRef args [2], val, ovf, func;
2370 emit_cond_throw_pos (ctx);
2372 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
2373 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
2374 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
2376 val = LLVMBuildCall (builder, func, args, 2, "");
2377 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
2378 ovf = LLVMBuildExtractValue (builder, val, 1, "");
2379 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
2380 builder = ctx->builder;
2386 * We currently model them using arrays. Promotion to local vregs is
2387 * disabled for them in mono_handle_global_vregs () in the LLVM case,
2388 * so we always have an entry in cfg->varinfo for them.
2389 * FIXME: Is this needed ?
2392 MonoClass *klass = ins->klass;
2393 LLVMValueRef args [4];
2397 LLVM_FAILURE (ctx, "!klass");
2401 if (!addresses [ins->dreg])
2402 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2403 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2404 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2405 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
2407 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2408 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
2412 case OP_STOREV_MEMBASE:
2413 case OP_LOADV_MEMBASE:
2415 MonoClass *klass = ins->klass;
2416 LLVMValueRef src, dst, args [4];
2420 LLVM_FAILURE (ctx, "!klass");
2424 switch (ins->opcode) {
2425 case OP_STOREV_MEMBASE:
2426 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
2427 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
2429 case OP_LOADV_MEMBASE:
2430 if (!addresses [ins->dreg])
2431 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2432 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
2433 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2436 if (!addresses [ins->sreg1])
2437 addresses [ins->sreg1] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2438 if (!addresses [ins->dreg])
2439 addresses [ins->dreg] = LLVMBuildAlloca (builder, type_to_llvm_type (ctx, &klass->byval_arg), "");
2440 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
2441 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
2444 g_assert_not_reached ();
2449 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
2450 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2452 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2453 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memcpy.i32"), args, 4, "");
2456 case OP_LLVM_OUTARG_VT:
2457 g_assert (addresses [ins->sreg1]);
2458 addresses [ins->dreg] = addresses [ins->sreg1];
2464 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
2465 LLVM_FAILURE (ctx, reason);
2470 /* Convert the value to the type required by phi nodes */
2471 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg])
2472 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
2474 /* Add stores for volatile variables */
2475 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
2476 emit_volatile_store (ctx, ins->dreg);
2479 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
2480 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
2482 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
2483 LLVMBuildRetVoid (builder);
2486 /* Add incoming phi values */
2487 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2488 GSList *ins_list = g_hash_table_lookup (phi_nodes, GUINT_TO_POINTER (bb));
2491 PhiNode *node = ins_list->data;
2492 MonoInst *phi = node->phi;
2493 int sreg1 = phi->inst_phi_args [node->index + 1];
2494 LLVMBasicBlockRef in_bb;
2496 in_bb = get_end_bb (ctx, node->bb->in_bb [node->index]);
2498 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
2499 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
2501 ins_list = ins_list->next;
2505 if (cfg->verbose_level > 1)
2506 mono_llvm_dump_value (method);
2508 if (cfg->compile_aot) {
2509 /* Don't generate native code, keep the LLVM IR */
2512 mono_llvm_optimize_method (method);
2514 if (cfg->verbose_level > 1)
2515 mono_llvm_dump_value (method);
2517 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
2519 /* Set by emit_cb */
2520 g_assert (cfg->code_len);
2522 /* FIXME: Free the LLVM IL for the function */
2530 /* Need to add unused phi nodes as they can be referenced by other values */
2531 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
2532 LLVMBuilderRef builder;
2534 builder = create_builder (ctx);
2535 LLVMPositionBuilderAtEnd (builder, phi_bb);
2537 for (i = 0; i < phi_values->len; ++i) {
2538 LLVMValueRef v = g_ptr_array_index (phi_values, i);
2539 if (LLVMGetInstructionParent (v) == NULL)
2540 LLVMInsertIntoBuilder (builder, v);
2543 LLVMDeleteFunction (method);
2549 g_free (vreg_types);
2551 g_hash_table_destroy (phi_nodes);
2552 g_ptr_array_free (phi_values, TRUE);
2553 g_free (ctx->bblocks);
2554 g_free (ctx->end_bblocks);
2556 for (l = ctx->builders; l; l = l->next) {
2557 LLVMBuilderRef builder = l->data;
2558 LLVMDisposeBuilder (builder);
2563 TlsSetValue (current_cfg_tls_id, NULL);
2565 mono_loader_unlock ();
2569 * mono_llvm_emit_call:
2571 * Same as mono_arch_emit_call () for LLVM.
2574 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
2577 MonoMethodSignature *sig;
2578 int i, n, stack_size;
2583 sig = call->signature;
2584 n = sig->param_count + sig->hasthis;
2586 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
2588 if (sig->call_convention == MONO_CALL_VARARG) {
2589 cfg->exception_message = g_strdup ("varargs");
2590 cfg->disable_llvm = TRUE;
2593 for (i = 0; i < n; ++i) {
2596 ainfo = call->cinfo->args + i;
2598 in = call->args [i];
2600 /* Simply remember the arguments */
2601 switch (ainfo->storage) {
2603 MONO_INST_NEW (cfg, ins, OP_MOVE);
2604 ins->dreg = mono_alloc_ireg (cfg);
2605 ins->sreg1 = in->dreg;
2607 case LLVMArgInFPReg:
2608 MONO_INST_NEW (cfg, ins, OP_FMOVE);
2609 ins->dreg = mono_alloc_freg (cfg);
2610 ins->sreg1 = in->dreg;
2612 case LLVMArgVtypeByVal:
2613 case LLVMArgVtypeInReg:
2614 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
2615 ins->dreg = mono_alloc_ireg (cfg);
2616 ins->sreg1 = in->dreg;
2617 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
2620 cfg->exception_message = g_strdup ("ainfo->storage");
2621 cfg->disable_llvm = TRUE;
2625 if (!cfg->disable_llvm) {
2626 MONO_ADD_INS (cfg->cbb, ins);
2627 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
2632 static unsigned char*
2633 alloc_cb (LLVMValueRef function, int size)
2637 cfg = TlsGetValue (current_cfg_tls_id);
2641 return mono_domain_code_reserve (cfg->domain, size);
2643 return mono_domain_code_reserve (mono_domain_get (), size);
2648 emitted_cb (LLVMValueRef function, void *start, void *end)
2652 cfg = TlsGetValue (current_cfg_tls_id);
2654 cfg->code_len = (guint8*)end - (guint8*)start;
2658 exception_cb (void *data)
2662 cfg = TlsGetValue (current_cfg_tls_id);
2666 * data points to a DWARF FDE structure, convert it to our unwind format and
2668 * An alternative would be to save it directly, and modify our unwinder to work
2671 cfg->encoded_unwind_ops = mono_unwind_get_ops_from_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL);
2675 add_intrinsics (LLVMModuleRef module)
2677 /* Emit declarations of instrinsics */
2679 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type () };
2681 LLVMAddFunction (module, "llvm.memset.i32", LLVMFunctionType (LLVMVoidType (), memset_params, 4, FALSE));
2685 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type () };
2687 LLVMAddFunction (module, "llvm.memcpy.i32", LLVMFunctionType (LLVMVoidType (), memcpy_params, 4, FALSE));
2691 LLVMTypeRef params [] = { LLVMDoubleType () };
2693 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2694 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2695 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
2699 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
2701 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
2702 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
2703 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
2704 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
2705 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
2706 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
2707 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
2711 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
2712 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
2714 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2715 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2716 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2717 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2718 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2719 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
2723 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
2724 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
2726 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2727 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2728 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2729 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2730 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2731 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
2736 mono_llvm_init (void)
2738 current_cfg_tls_id = TlsAlloc ();
2740 jit_module.module = LLVMModuleCreateWithName ("mono");
2742 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
2744 add_intrinsics (jit_module.module);
2746 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
2750 mono_llvm_cleanup (void)
2752 mono_llvm_dispose_ee (ee);
2754 g_hash_table_destroy (jit_module.llvm_types);
2759 - Emit LLVM IR from the mono IR using the LLVM C API.
2760 - The original arch specific code remains, so we can fall back to it if we run
2761 into something we can't handle.
2763 - llvm's PrettyStackTrace class seems to register a signal handler which screws
2764 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
2768 A partial list of issues:
2769 - Handling of opcodes which can throw exceptions.
2771 In the mono JIT, these are implemented using code like this:
2778 push throw_pos - method
2779 call <exception trampoline>
2781 The problematic part is push throw_pos - method, which cannot be represented
2782 in the LLVM IR, since it does not support label values.
2783 -> this can be implemented in AOT mode using inline asm + labels, but cannot
2784 be implemented in JIT mode ?
2785 -> a possible but slower implementation would use the normal exception
2786 throwing code but it would need to control the placement of the throw code
2787 (it needs to be exactly after the compare+branch).
2788 -> perhaps add a PC offset intrinsics ?
2790 - efficient implementation of .ovf opcodes.
2792 These are currently implemented as:
2793 <ins which sets the condition codes>
2796 Some overflow opcodes are now supported by LLVM SVN.
2798 - exception handling, unwinding.
2799 - SSA is disabled for methods with exception handlers
2800 - How to obtain unwind info for LLVM compiled methods ?
2801 -> this is now solved by converting the unwind info generated by LLVM
2803 - LLVM uses the c++ exception handling framework, while we use our home grown
2804 code, and couldn't use the c++ one:
2805 - its not supported under VC++, other exotic platforms.
2806 - it might be impossible to support filter clauses with it.
2810 The trampolines need a predictable call sequence, since they need to disasm
2811 the calling code to obtain register numbers / offsets.
2813 LLVM currently generates this code in non-JIT mode:
2814 mov -0x98(%rax),%eax
2816 Here, the vtable pointer is lost.
2817 -> solution: use one vtable trampoline per class.
2819 - passing/receiving the IMT pointer/RGCTX.
2820 -> solution: pass them as normal arguments ?
2824 LLVM does not allow the specification of argument registers etc. This means
2825 that all calls are made according to the platform ABI.
2827 - passing/receiving vtypes.
2829 Vtypes passed/received in registers are handled by the front end by using
2830 a signature with scalar arguments, and loading the parts of the vtype into those
2833 Vtypes passed on the stack are handled using the 'byval' attribute.
2837 Supported though alloca, we need to emit the load/store code.
2841 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
2842 typed registers, so we have to keep track of the precise LLVM type of each vreg.
2843 This is made easier because the IR is already in SSA form.
2844 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
2845 types are frequently used incorrectly.
2848 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
2849 * - each bblock should end with a branch
2850 * - setting the return value, making cfg->ret non-volatile
2851 * - merge some changes back to HEAD, to reduce the differences.
2852 * - avoid some transformations in the JIT which make it harder for us to generate
2854 * - fix memory leaks.
2855 * - use pointer types to help optimizations.