2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 LLVMValueRef generic_class_init_tramp;
50 GHashTable *llvm_types;
52 const char *got_symbol;
53 GHashTable *plt_entries;
54 GHashTable *plt_entries_ji;
55 GHashTable *method_to_lmethod;
60 GPtrArray *subprogram_mds;
62 LLVMExecutionEngineRef ee;
63 gboolean external_symbols;
69 * Information associated by the backend with mono basic blocks.
72 LLVMBasicBlockRef bblock, end_bblock;
73 LLVMValueRef finally_ind;
74 gboolean added, invoke_target;
76 * If this bblock is the start of a finally clause, this is a list of bblocks it
77 * needs to branch to in ENDFINALLY.
79 GSList *call_handler_return_bbs;
81 * If this bblock is the start of a finally clause, this is the bblock that
82 * CALL_HANDLER needs to branch to.
84 LLVMBasicBlockRef call_handler_target_bb;
85 /* The list of switch statements generated by ENDFINALLY instructions */
86 GSList *endfinally_switch_ins_list;
91 * Structure containing emit state
96 /* Maps method names to the corresponding LLVMValueRef */
97 GHashTable *emitted_method_decls;
100 LLVMValueRef lmethod;
101 MonoLLVMModule *lmodule;
102 LLVMModuleRef module;
104 int sindex, default_index, ex_index;
105 LLVMBuilderRef builder;
106 LLVMValueRef *values, *addresses;
107 MonoType **vreg_cli_types;
109 MonoMethodSignature *sig;
111 GHashTable *region_to_handler;
112 GHashTable *clause_to_handler;
113 LLVMBuilderRef alloca_builder;
114 LLVMValueRef last_alloca;
115 LLVMValueRef rgctx_arg;
116 LLVMTypeRef *vreg_types;
118 gboolean *unreachable;
120 LLVMValueRef imt_rgctx_loc;
121 GHashTable *llvm_types;
123 MonoDebugMethodInfo *minfo;
125 /* For every clause, the clauses it is nested in */
133 MonoBasicBlock *in_bb;
138 * Instruction metadata
139 * This is the same as ins_info, but LREG != IREG.
147 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
148 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
155 /* keep in sync with the enum in mini.h */
158 #include "mini-ops.h"
163 #if SIZEOF_VOID_P == 4
164 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
166 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
169 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
172 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
174 #define TRACE_FAILURE(msg)
178 #define IS_TARGET_X86 1
180 #define IS_TARGET_X86 0
184 #define IS_TARGET_AMD64 1
186 #define IS_TARGET_AMD64 0
189 #define LLVM_FAILURE(ctx, reason) do { \
190 TRACE_FAILURE (reason); \
191 (ctx)->cfg->exception_message = g_strdup (reason); \
192 (ctx)->cfg->disable_llvm = TRUE; \
196 #define CHECK_FAILURE(ctx) do { \
197 if ((ctx)->cfg->disable_llvm) \
201 static LLVMIntPredicate cond_to_llvm_cond [] = {
214 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
227 static MonoNativeTlsKey current_cfg_tls_id;
229 static MonoLLVMModule aot_module;
230 static int memset_param_count, memcpy_param_count;
231 static const char *memset_func_name;
232 static const char *memcpy_func_name;
234 static void init_jit_module (MonoDomain *domain);
236 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
237 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
238 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
243 * The LLVM type with width == sizeof (gpointer)
248 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
254 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
260 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
266 * Return the size of the LLVM representation of the vtype T.
269 get_vtype_size (MonoType *t)
273 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
275 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
282 * simd_class_to_llvm_type:
284 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
287 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
289 if (!strcmp (klass->name, "Vector2d")) {
290 return LLVMVectorType (LLVMDoubleType (), 2);
291 } else if (!strcmp (klass->name, "Vector2l")) {
292 return LLVMVectorType (LLVMInt64Type (), 2);
293 } else if (!strcmp (klass->name, "Vector2ul")) {
294 return LLVMVectorType (LLVMInt64Type (), 2);
295 } else if (!strcmp (klass->name, "Vector4i")) {
296 return LLVMVectorType (LLVMInt32Type (), 4);
297 } else if (!strcmp (klass->name, "Vector4ui")) {
298 return LLVMVectorType (LLVMInt32Type (), 4);
299 } else if (!strcmp (klass->name, "Vector4f")) {
300 return LLVMVectorType (LLVMFloatType (), 4);
301 } else if (!strcmp (klass->name, "Vector8s")) {
302 return LLVMVectorType (LLVMInt16Type (), 8);
303 } else if (!strcmp (klass->name, "Vector8us")) {
304 return LLVMVectorType (LLVMInt16Type (), 8);
305 } else if (!strcmp (klass->name, "Vector16sb")) {
306 return LLVMVectorType (LLVMInt8Type (), 16);
307 } else if (!strcmp (klass->name, "Vector16b")) {
308 return LLVMVectorType (LLVMInt8Type (), 16);
310 printf ("%s\n", klass->name);
316 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
317 static inline G_GNUC_UNUSED LLVMTypeRef
318 type_to_simd_type (int type)
322 return LLVMVectorType (LLVMInt8Type (), 16);
324 return LLVMVectorType (LLVMInt16Type (), 8);
326 return LLVMVectorType (LLVMInt32Type (), 4);
328 return LLVMVectorType (LLVMInt64Type (), 2);
330 return LLVMVectorType (LLVMDoubleType (), 2);
332 return LLVMVectorType (LLVMFloatType (), 4);
334 g_assert_not_reached ();
340 create_llvm_type_for_type (MonoClass *klass)
342 int i, size, nfields, esize;
343 LLVMTypeRef *eltypes;
348 t = &klass->byval_arg;
350 if (mini_type_is_hfa (t, &nfields, &esize)) {
352 * This is needed on arm64 where HFAs are returned in
356 eltypes = g_new (LLVMTypeRef, size);
357 for (i = 0; i < size; ++i)
358 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
360 size = get_vtype_size (t);
362 eltypes = g_new (LLVMTypeRef, size);
363 for (i = 0; i < size; ++i)
364 eltypes [i] = LLVMInt8Type ();
367 name = mono_type_full_name (&klass->byval_arg);
368 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
369 LLVMStructSetBody (ltype, eltypes, size, FALSE);
379 * Return the LLVM type corresponding to T.
382 type_to_llvm_type (EmitContext *ctx, MonoType *t)
385 return LLVMPointerType (LLVMInt8Type (), 0);
387 t = mini_get_underlying_type (ctx->cfg, t);
390 return LLVMVoidType ();
392 return LLVMInt8Type ();
394 return LLVMInt16Type ();
396 return LLVMInt32Type ();
398 return LLVMInt8Type ();
400 return LLVMInt16Type ();
402 return LLVMInt32Type ();
403 case MONO_TYPE_BOOLEAN:
404 return LLVMInt8Type ();
407 return LLVMInt64Type ();
409 return LLVMInt16Type ();
411 return LLVMFloatType ();
413 return LLVMDoubleType ();
416 return IntPtrType ();
417 case MONO_TYPE_OBJECT:
418 case MONO_TYPE_CLASS:
419 case MONO_TYPE_ARRAY:
420 case MONO_TYPE_SZARRAY:
421 case MONO_TYPE_STRING:
423 return ObjRefType ();
426 /* Because of generic sharing */
427 return ObjRefType ();
428 case MONO_TYPE_GENERICINST:
429 if (!mono_type_generic_inst_is_valuetype (t))
430 return ObjRefType ();
432 case MONO_TYPE_VALUETYPE:
433 case MONO_TYPE_TYPEDBYREF: {
437 klass = mono_class_from_mono_type (t);
439 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
440 return simd_class_to_llvm_type (ctx, klass);
443 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
445 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
447 ltype = create_llvm_type_for_type (klass);
448 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
454 printf ("X: %d\n", t->type);
455 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
456 ctx->cfg->disable_llvm = TRUE;
464 * Return whenever T is an unsigned int type.
467 type_is_unsigned (EmitContext *ctx, MonoType *t)
484 * type_to_llvm_arg_type:
486 * Same as type_to_llvm_type, but treat i8/i16 as i32.
489 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
491 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
494 * This works on all abis except arm64/ios which passes multiple
495 * arguments in one stack slot.
498 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
500 * LLVM generates code which only sets the lower bits, while JITted
501 * code expects all the bits to be set.
503 ptype = LLVMInt32Type ();
511 * llvm_type_to_stack_type:
513 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
516 static G_GNUC_UNUSED LLVMTypeRef
517 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
521 if (type == LLVMInt8Type ())
522 return LLVMInt32Type ();
523 else if (type == LLVMInt16Type ())
524 return LLVMInt32Type ();
525 else if (!cfg->r4fp && type == LLVMFloatType ())
526 return LLVMDoubleType ();
532 * regtype_to_llvm_type:
534 * Return the LLVM type corresponding to the regtype C used in instruction
538 regtype_to_llvm_type (char c)
542 return LLVMInt32Type ();
544 return LLVMInt64Type ();
546 return LLVMDoubleType ();
555 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
558 op_to_llvm_type (int opcode)
563 return LLVMInt8Type ();
566 return LLVMInt8Type ();
569 return LLVMInt16Type ();
572 return LLVMInt16Type ();
575 return LLVMInt32Type ();
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMFloatType ();
584 return LLVMDoubleType ();
586 return LLVMInt64Type ();
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
595 return LLVMInt8Type ();
600 return LLVMInt16Type ();
603 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
610 return LLVMInt32Type ();
617 return LLVMInt64Type ();
619 printf ("%s\n", mono_inst_name (opcode));
620 g_assert_not_reached ();
626 * load_store_to_llvm_type:
628 * Return the size/sign/zero extension corresponding to the load/store opcode
632 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
638 case OP_LOADI1_MEMBASE:
639 case OP_STOREI1_MEMBASE_REG:
640 case OP_STOREI1_MEMBASE_IMM:
641 case OP_ATOMIC_LOAD_I1:
642 case OP_ATOMIC_STORE_I1:
645 return LLVMInt8Type ();
646 case OP_LOADU1_MEMBASE:
648 case OP_ATOMIC_LOAD_U1:
649 case OP_ATOMIC_STORE_U1:
652 return LLVMInt8Type ();
653 case OP_LOADI2_MEMBASE:
654 case OP_STOREI2_MEMBASE_REG:
655 case OP_STOREI2_MEMBASE_IMM:
656 case OP_ATOMIC_LOAD_I2:
657 case OP_ATOMIC_STORE_I2:
660 return LLVMInt16Type ();
661 case OP_LOADU2_MEMBASE:
663 case OP_ATOMIC_LOAD_U2:
664 case OP_ATOMIC_STORE_U2:
667 return LLVMInt16Type ();
668 case OP_LOADI4_MEMBASE:
669 case OP_LOADU4_MEMBASE:
672 case OP_STOREI4_MEMBASE_REG:
673 case OP_STOREI4_MEMBASE_IMM:
674 case OP_ATOMIC_LOAD_I4:
675 case OP_ATOMIC_STORE_I4:
676 case OP_ATOMIC_LOAD_U4:
677 case OP_ATOMIC_STORE_U4:
679 return LLVMInt32Type ();
680 case OP_LOADI8_MEMBASE:
682 case OP_STOREI8_MEMBASE_REG:
683 case OP_STOREI8_MEMBASE_IMM:
684 case OP_ATOMIC_LOAD_I8:
685 case OP_ATOMIC_STORE_I8:
686 case OP_ATOMIC_LOAD_U8:
687 case OP_ATOMIC_STORE_U8:
689 return LLVMInt64Type ();
690 case OP_LOADR4_MEMBASE:
691 case OP_STORER4_MEMBASE_REG:
692 case OP_ATOMIC_LOAD_R4:
693 case OP_ATOMIC_STORE_R4:
695 return LLVMFloatType ();
696 case OP_LOADR8_MEMBASE:
697 case OP_STORER8_MEMBASE_REG:
698 case OP_ATOMIC_LOAD_R8:
699 case OP_ATOMIC_STORE_R8:
701 return LLVMDoubleType ();
702 case OP_LOAD_MEMBASE:
704 case OP_STORE_MEMBASE_REG:
705 case OP_STORE_MEMBASE_IMM:
706 *size = sizeof (gpointer);
707 return IntPtrType ();
709 g_assert_not_reached ();
717 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
720 ovf_op_to_intrins (int opcode)
724 return "llvm.sadd.with.overflow.i32";
726 return "llvm.uadd.with.overflow.i32";
728 return "llvm.ssub.with.overflow.i32";
730 return "llvm.usub.with.overflow.i32";
732 return "llvm.smul.with.overflow.i32";
734 return "llvm.umul.with.overflow.i32";
736 return "llvm.sadd.with.overflow.i64";
738 return "llvm.uadd.with.overflow.i64";
740 return "llvm.ssub.with.overflow.i64";
742 return "llvm.usub.with.overflow.i64";
744 return "llvm.smul.with.overflow.i64";
746 return "llvm.umul.with.overflow.i64";
748 g_assert_not_reached ();
754 simd_op_to_intrins (int opcode)
757 #if defined(TARGET_X86) || defined(TARGET_AMD64)
759 return "llvm.x86.sse2.min.pd";
761 return "llvm.x86.sse.min.ps";
763 return "llvm.x86.sse41.pminud";
765 return "llvm.x86.sse41.pminuw";
767 return "llvm.x86.sse2.pminu.b";
769 return "llvm.x86.sse2.pmins.w";
771 return "llvm.x86.sse2.max.pd";
773 return "llvm.x86.sse.max.ps";
775 return "llvm.x86.sse3.hadd.pd";
777 return "llvm.x86.sse3.hadd.ps";
779 return "llvm.x86.sse3.hsub.pd";
781 return "llvm.x86.sse3.hsub.ps";
783 return "llvm.x86.sse41.pmaxud";
785 return "llvm.x86.sse41.pmaxuw";
787 return "llvm.x86.sse2.pmaxu.b";
789 return "llvm.x86.sse3.addsub.ps";
791 return "llvm.x86.sse3.addsub.pd";
792 case OP_EXTRACT_MASK:
793 return "llvm.x86.sse2.pmovmskb.128";
796 return "llvm.x86.sse2.psrli.w";
799 return "llvm.x86.sse2.psrli.d";
802 return "llvm.x86.sse2.psrli.q";
805 return "llvm.x86.sse2.pslli.w";
808 return "llvm.x86.sse2.pslli.d";
811 return "llvm.x86.sse2.pslli.q";
814 return "llvm.x86.sse2.psrai.w";
817 return "llvm.x86.sse2.psrai.d";
819 return "llvm.x86.sse2.padds.b";
821 return "llvm.x86.sse2.padds.w";
823 return "llvm.x86.sse2.psubs.b";
825 return "llvm.x86.sse2.psubs.w";
826 case OP_PADDB_SAT_UN:
827 return "llvm.x86.sse2.paddus.b";
828 case OP_PADDW_SAT_UN:
829 return "llvm.x86.sse2.paddus.w";
830 case OP_PSUBB_SAT_UN:
831 return "llvm.x86.sse2.psubus.b";
832 case OP_PSUBW_SAT_UN:
833 return "llvm.x86.sse2.psubus.w";
835 return "llvm.x86.sse2.pavg.b";
837 return "llvm.x86.sse2.pavg.w";
839 return "llvm.x86.sse.sqrt.ps";
841 return "llvm.x86.sse2.sqrt.pd";
843 return "llvm.x86.sse.rsqrt.ps";
845 return "llvm.x86.sse.rcp.ps";
847 return "llvm.x86.sse2.cvtdq2pd";
849 return "llvm.x86.sse2.cvtdq2ps";
851 return "llvm.x86.sse2.cvtpd2dq";
853 return "llvm.x86.sse2.cvtps2dq";
855 return "llvm.x86.sse2.cvtpd2ps";
857 return "llvm.x86.sse2.cvtps2pd";
859 return "llvm.x86.sse2.cvttpd2dq";
861 return "llvm.x86.sse2.cvttps2dq";
863 return "llvm.x86.sse.cmp.ps";
865 return "llvm.x86.sse2.cmp.pd";
867 return "llvm.x86.sse2.packsswb.128";
869 return "llvm.x86.sse2.packssdw.128";
871 return "llvm.x86.sse2.packuswb.128";
873 return "llvm.x86.sse41.packusdw";
875 return "llvm.x86.sse2.pmulh.w";
876 case OP_PMULW_HIGH_UN:
877 return "llvm.x86.sse2.pmulhu.w";
880 g_assert_not_reached ();
886 simd_op_to_llvm_type (int opcode)
888 #if defined(TARGET_X86) || defined(TARGET_AMD64)
892 return type_to_simd_type (MONO_TYPE_R8);
895 return type_to_simd_type (MONO_TYPE_I8);
898 return type_to_simd_type (MONO_TYPE_I4);
903 return type_to_simd_type (MONO_TYPE_I2);
907 return type_to_simd_type (MONO_TYPE_I1);
909 return type_to_simd_type (MONO_TYPE_R4);
912 return type_to_simd_type (MONO_TYPE_I4);
916 return type_to_simd_type (MONO_TYPE_R8);
920 return type_to_simd_type (MONO_TYPE_R4);
921 case OP_EXTRACT_MASK:
922 return type_to_simd_type (MONO_TYPE_I1);
928 return type_to_simd_type (MONO_TYPE_R4);
931 return type_to_simd_type (MONO_TYPE_R8);
933 g_assert_not_reached ();
944 * Return the LLVM basic block corresponding to BB.
946 static LLVMBasicBlockRef
947 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
949 char bb_name_buf [128];
952 if (ctx->bblocks [bb->block_num].bblock == NULL) {
953 if (bb->flags & BB_EXCEPTION_HANDLER) {
954 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
955 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
956 bb_name = bb_name_buf;
957 } else if (bb->block_num < 256) {
958 if (!ctx->lmodule->bb_names) {
959 ctx->lmodule->bb_names_len = 256;
960 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
962 if (!ctx->lmodule->bb_names [bb->block_num]) {
965 n = g_strdup_printf ("BB%d", bb->block_num);
966 mono_memory_barrier ();
967 ctx->lmodule->bb_names [bb->block_num] = n;
969 bb_name = ctx->lmodule->bb_names [bb->block_num];
971 sprintf (bb_name_buf, "BB%d", bb->block_num);
972 bb_name = bb_name_buf;
975 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
976 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
979 return ctx->bblocks [bb->block_num].bblock;
985 * Return the last LLVM bblock corresponding to BB.
986 * This might not be equal to the bb returned by get_bb () since we need to generate
987 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
989 static LLVMBasicBlockRef
990 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
993 return ctx->bblocks [bb->block_num].end_bblock;
996 static LLVMBasicBlockRef
997 gen_bb (EmitContext *ctx, const char *prefix)
1001 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1002 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1008 * Return the target of the patch identified by TYPE and TARGET.
1011 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1015 memset (&ji, 0, sizeof (ji));
1017 ji.data.target = target;
1019 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1025 * Emit code to convert the LLVM value V to DTYPE.
1028 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1030 LLVMTypeRef stype = LLVMTypeOf (v);
1032 if (stype != dtype) {
1033 gboolean ext = FALSE;
1036 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1038 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1040 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1044 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1046 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1047 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1050 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1051 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1052 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1053 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1054 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1055 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1056 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1057 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1059 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1060 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1061 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1062 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1063 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1064 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1066 if (mono_arch_is_soft_float ()) {
1067 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1068 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1069 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1070 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1073 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1074 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1077 LLVMDumpValue (LLVMConstNull (dtype));
1078 g_assert_not_reached ();
1086 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1088 return convert_full (ctx, v, dtype, FALSE);
1092 * emit_volatile_load:
1094 * If vreg is volatile, emit a load from its address.
1097 emit_volatile_load (EmitContext *ctx, int vreg)
1101 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1102 t = ctx->vreg_cli_types [vreg];
1103 if (t && !t->byref) {
1105 * Might have to zero extend since llvm doesn't have
1108 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1109 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1110 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1111 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1112 else if (t->type == MONO_TYPE_U8)
1113 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1120 * emit_volatile_store:
1122 * If VREG is volatile, emit a store from its value to its address.
1125 emit_volatile_store (EmitContext *ctx, int vreg)
1127 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1129 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1130 g_assert (ctx->addresses [vreg]);
1131 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1137 * Maps parameter indexes in the original signature to parameter indexes
1138 * in the LLVM signature.
1141 /* The indexes of various special arguments in the LLVM signature */
1142 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1146 * sig_to_llvm_sig_full:
1148 * Return the LLVM signature corresponding to the mono signature SIG using the
1149 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1152 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1155 LLVMTypeRef ret_type;
1156 LLVMTypeRef *param_types = NULL;
1158 int i, j, pindex, vret_arg_pindex = 0;
1160 gboolean vretaddr = FALSE;
1164 memset (sinfo, 0, sizeof (LLVMSigInfo));
1166 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1167 ret_type = type_to_llvm_type (ctx, rtype);
1168 CHECK_FAILURE (ctx);
1171 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1172 /* LLVM models this by returning an aggregate value */
1173 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1174 LLVMTypeRef members [2];
1176 members [0] = IntPtrType ();
1177 ret_type = LLVMStructType (members, 1, FALSE);
1179 g_assert_not_reached ();
1181 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1182 /* Vtype returned normally by val */
1183 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1184 /* Vtype returned as a fp struct */
1185 LLVMTypeRef members [16];
1187 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1188 for (i = 0; i < cinfo->ret.nslots; ++i)
1189 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1190 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1191 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1192 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1194 ret_type = LLVMVoidType ();
1198 pindexes = g_new0 (int, sig->param_count);
1199 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1201 if (cinfo && cinfo->rgctx_arg) {
1203 sinfo->rgctx_arg_pindex = pindex;
1204 param_types [pindex] = ctx->lmodule->ptr_type;
1207 if (cinfo && cinfo->imt_arg) {
1209 sinfo->imt_arg_pindex = pindex;
1210 param_types [pindex] = ctx->lmodule->ptr_type;
1214 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1215 vret_arg_pindex = pindex;
1216 if (cinfo->vret_arg_index == 1) {
1217 /* Add the slots consumed by the first argument */
1218 LLVMArgInfo *ainfo = &cinfo->args [0];
1219 switch (ainfo->storage) {
1220 case LLVMArgVtypeInReg:
1221 for (j = 0; j < 2; ++j) {
1222 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1232 sinfo->vret_arg_pindex = vret_arg_pindex;
1235 if (vretaddr && vret_arg_pindex == pindex)
1236 param_types [pindex ++] = IntPtrType ();
1239 sinfo->this_arg_pindex = pindex;
1240 param_types [pindex ++] = ThisType ();
1242 if (vretaddr && vret_arg_pindex == pindex)
1243 param_types [pindex ++] = IntPtrType ();
1244 for (i = 0; i < sig->param_count; ++i) {
1245 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1247 if (vretaddr && vret_arg_pindex == pindex)
1248 param_types [pindex ++] = IntPtrType ();
1249 pindexes [i] = pindex;
1252 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1256 switch (ainfo->storage) {
1257 case LLVMArgVtypeInReg:
1258 for (j = 0; j < 2; ++j) {
1259 switch (ainfo->pair_storage [j]) {
1261 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1266 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1272 CHECK_FAILURE (ctx);
1273 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1276 case LLVMArgAsIArgs:
1277 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1280 case LLVMArgAsFpArgs: {
1283 for (j = 0; j < ainfo->nslots; ++j)
1284 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1285 pindex += ainfo->nslots;
1289 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1293 if (vretaddr && vret_arg_pindex == pindex)
1294 param_types [pindex ++] = IntPtrType ();
1296 CHECK_FAILURE (ctx);
1298 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1299 g_free (param_types);
1302 sinfo->pindexes = pindexes;
1310 g_free (param_types);
1316 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1318 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1322 * LLVMFunctionType1:
1324 * Create an LLVM function type from the arguments.
1326 static G_GNUC_UNUSED LLVMTypeRef
1327 LLVMFunctionType1(LLVMTypeRef ReturnType,
1328 LLVMTypeRef ParamType1,
1331 LLVMTypeRef param_types [1];
1333 param_types [0] = ParamType1;
1335 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1339 * LLVMFunctionType2:
1341 * Create an LLVM function type from the arguments.
1343 static G_GNUC_UNUSED LLVMTypeRef
1344 LLVMFunctionType2(LLVMTypeRef ReturnType,
1345 LLVMTypeRef ParamType1,
1346 LLVMTypeRef ParamType2,
1349 LLVMTypeRef param_types [2];
1351 param_types [0] = ParamType1;
1352 param_types [1] = ParamType2;
1354 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1358 * LLVMFunctionType3:
1360 * Create an LLVM function type from the arguments.
1362 static G_GNUC_UNUSED LLVMTypeRef
1363 LLVMFunctionType3(LLVMTypeRef ReturnType,
1364 LLVMTypeRef ParamType1,
1365 LLVMTypeRef ParamType2,
1366 LLVMTypeRef ParamType3,
1369 LLVMTypeRef param_types [3];
1371 param_types [0] = ParamType1;
1372 param_types [1] = ParamType2;
1373 param_types [2] = ParamType3;
1375 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1381 * Create an LLVM builder and remember it so it can be freed later.
1383 static LLVMBuilderRef
1384 create_builder (EmitContext *ctx)
1386 LLVMBuilderRef builder = LLVMCreateBuilder ();
1388 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1394 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1396 char *callee_name = mono_aot_get_plt_symbol (type, data);
1397 LLVMValueRef callee;
1398 MonoJumpInfo *ji = NULL;
1403 if (ctx->cfg->compile_aot)
1404 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1405 mono_add_patch_info (ctx->cfg, 0, type, data);
1408 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1410 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1412 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1414 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1417 if (ctx->cfg->compile_aot) {
1418 ji = g_new0 (MonoJumpInfo, 1);
1420 ji->data.target = data;
1422 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1429 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1431 MonoMethodHeader *header = cfg->header;
1432 MonoExceptionClause *clause;
1436 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1437 return (bb->region >> 8) - 1;
1440 for (i = 0; i < header->num_clauses; ++i) {
1441 clause = &header->clauses [i];
1443 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1451 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1453 LLVMValueRef md_arg;
1456 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1457 md_arg = LLVMMDString ("mono", 4);
1458 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1462 set_invariant_load_flag (LLVMValueRef v)
1464 LLVMValueRef md_arg;
1466 const char *flag_name;
1468 // FIXME: Cache this
1469 flag_name = "invariant.load";
1470 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1471 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1472 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1478 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1482 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1484 MonoCompile *cfg = ctx->cfg;
1486 LLVMBuilderRef builder = *builder_ref;
1489 clause_index = get_handler_clause (cfg, bb);
1491 if (clause_index != -1) {
1492 MonoMethodHeader *header = cfg->header;
1493 MonoExceptionClause *ec = &header->clauses [clause_index];
1494 MonoBasicBlock *tblock;
1495 LLVMBasicBlockRef ex_bb, noex_bb;
1498 * Have to use an invoke instead of a call, branching to the
1499 * handler bblock of the clause containing this bblock.
1502 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1504 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1507 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1509 ex_bb = get_bb (ctx, tblock);
1511 noex_bb = gen_bb (ctx, "NOEX_BB");
1514 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1516 builder = ctx->builder = create_builder (ctx);
1517 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1519 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1521 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1522 ctx->builder = builder;
1525 *builder_ref = ctx->builder;
1531 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1533 const char *intrins_name;
1534 LLVMValueRef args [16], res;
1535 LLVMTypeRef addr_type;
1537 if (is_faulting && bb->region != -1) {
1538 LLVMAtomicOrdering ordering;
1541 case LLVM_BARRIER_NONE:
1542 ordering = LLVMAtomicOrderingNotAtomic;
1544 case LLVM_BARRIER_ACQ:
1545 ordering = LLVMAtomicOrderingAcquire;
1547 case LLVM_BARRIER_SEQ:
1548 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1551 g_assert_not_reached ();
1556 * We handle loads which can fault by calling a mono specific intrinsic
1557 * using an invoke, so they are handled properly inside try blocks.
1558 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1559 * are marked with IntrReadArgMem.
1563 intrins_name = "llvm.mono.load.i8.p0i8";
1566 intrins_name = "llvm.mono.load.i16.p0i16";
1569 intrins_name = "llvm.mono.load.i32.p0i32";
1572 intrins_name = "llvm.mono.load.i64.p0i64";
1575 g_assert_not_reached ();
1578 addr_type = LLVMTypeOf (addr);
1579 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1580 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1583 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1584 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1585 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1586 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1588 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1589 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1590 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1591 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1598 * We emit volatile loads for loads which can fault, because otherwise
1599 * LLVM will generate invalid code when encountering a load from a
1602 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1604 /* Mark it with a custom metadata */
1607 set_metadata_flag (res, "mono.faulting.load");
1615 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1617 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1621 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1623 const char *intrins_name;
1624 LLVMValueRef args [16];
1626 if (is_faulting && bb->region != -1) {
1627 LLVMAtomicOrdering ordering;
1630 case LLVM_BARRIER_NONE:
1631 ordering = LLVMAtomicOrderingNotAtomic;
1633 case LLVM_BARRIER_REL:
1634 ordering = LLVMAtomicOrderingRelease;
1636 case LLVM_BARRIER_SEQ:
1637 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1640 g_assert_not_reached ();
1646 intrins_name = "llvm.mono.store.i8.p0i8";
1649 intrins_name = "llvm.mono.store.i16.p0i16";
1652 intrins_name = "llvm.mono.store.i32.p0i32";
1655 intrins_name = "llvm.mono.store.i64.p0i64";
1658 g_assert_not_reached ();
1661 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1662 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1663 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1668 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1669 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1670 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1671 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1673 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1678 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1680 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1684 * emit_cond_system_exception:
1686 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1687 * Might set the ctx exception.
1690 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1692 LLVMBasicBlockRef ex_bb, noex_bb;
1693 LLVMBuilderRef builder;
1694 MonoClass *exc_class;
1695 LLVMValueRef args [2];
1697 ex_bb = gen_bb (ctx, "EX_BB");
1698 noex_bb = gen_bb (ctx, "NOEX_BB");
1700 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1702 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1703 g_assert (exc_class);
1705 /* Emit exception throwing code */
1706 builder = create_builder (ctx);
1707 LLVMPositionBuilderAtEnd (builder, ex_bb);
1709 if (!ctx->lmodule->throw_corlib_exception) {
1710 LLVMValueRef callee;
1712 const char *icall_name;
1714 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1715 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1716 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1717 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1718 /* This will become i8* */
1719 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1720 sig = sig_to_llvm_sig (ctx, throw_sig);
1722 if (ctx->cfg->compile_aot) {
1723 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1725 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1728 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1729 * - On x86, LLVM generated code doesn't push the arguments
1730 * - The trampoline takes the throw address as an arguments, not a pc offset.
1732 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1735 mono_memory_barrier ();
1736 ctx->lmodule->throw_corlib_exception = callee;
1739 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1740 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1742 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1745 * The LLVM mono branch contains changes so a block address can be passed as an
1746 * argument to a call.
1748 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1749 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1751 LLVMBuildUnreachable (builder);
1753 ctx->builder = create_builder (ctx);
1754 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1756 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1763 * emit_args_to_vtype:
1765 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1768 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1770 int j, size, nslots;
1772 size = get_vtype_size (t);
1774 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1775 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1778 if (ainfo->storage == LLVMArgAsFpArgs)
1779 nslots = ainfo->nslots;
1783 for (j = 0; j < nslots; ++j) {
1784 LLVMValueRef index [2], addr, daddr;
1785 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1786 LLVMTypeRef part_type;
1788 if (ainfo->pair_storage [j] == LLVMArgNone)
1791 switch (ainfo->pair_storage [j]) {
1792 case LLVMArgInIReg: {
1793 part_type = LLVMIntType (part_size * 8);
1794 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1795 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1796 addr = LLVMBuildGEP (builder, address, index, 1, "");
1798 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1799 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1800 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1802 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1805 case LLVMArgInFPReg: {
1806 LLVMTypeRef arg_type;
1808 if (ainfo->esize == 8)
1809 arg_type = LLVMDoubleType ();
1811 arg_type = LLVMFloatType ();
1813 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1814 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1815 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1816 LLVMBuildStore (builder, args [j], addr);
1822 g_assert_not_reached ();
1825 size -= sizeof (gpointer);
1830 * emit_vtype_to_args:
1832 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1833 * into ARGS, and the number of arguments into NARGS.
1836 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1839 int j, size, nslots;
1840 LLVMTypeRef arg_type;
1842 size = get_vtype_size (t);
1844 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1845 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1847 if (ainfo->storage == LLVMArgAsFpArgs)
1848 nslots = ainfo->nslots;
1851 for (j = 0; j < nslots; ++j) {
1852 LLVMValueRef index [2], addr, daddr;
1853 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1855 if (ainfo->pair_storage [j] == LLVMArgNone)
1858 switch (ainfo->pair_storage [j]) {
1860 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1861 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1862 addr = LLVMBuildGEP (builder, address, index, 1, "");
1864 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1865 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1866 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1868 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1870 case LLVMArgInFPReg:
1871 if (ainfo->esize == 8)
1872 arg_type = LLVMDoubleType ();
1874 arg_type = LLVMFloatType ();
1875 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1876 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1877 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1878 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1883 g_assert_not_reached ();
1885 size -= sizeof (gpointer);
1892 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1895 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1896 * get executed every time control reaches them.
1898 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1900 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1901 return ctx->last_alloca;
1905 build_alloca (EmitContext *ctx, MonoType *t)
1907 MonoClass *k = mono_class_from_mono_type (t);
1910 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1913 align = mono_class_min_align (k);
1915 /* Sometimes align is not a power of 2 */
1916 while (mono_is_power_of_two (align) == -1)
1919 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1923 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1926 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1929 lmodule->used = g_ptr_array_sized_new (16);
1930 g_ptr_array_add (lmodule->used, global);
1934 emit_llvm_used (MonoLLVMModule *lmodule)
1936 LLVMModuleRef module = lmodule->module;
1937 LLVMTypeRef used_type;
1938 LLVMValueRef used, *used_elem;
1944 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1945 used = LLVMAddGlobal (module, used_type, "llvm.used");
1946 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1947 for (i = 0; i < lmodule->used->len; ++i)
1948 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1949 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1950 LLVMSetLinkage (used, LLVMAppendingLinkage);
1951 LLVMSetSection (used, "llvm.metadata");
1955 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1957 gboolean need_div_check = FALSE;
1959 #ifdef MONO_ARCH_NEED_DIV_CHECK
1960 need_div_check = TRUE;
1963 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1964 need_div_check = TRUE;
1966 if (!need_div_check)
1969 switch (ins->opcode) {
1982 case OP_IDIV_UN_IMM:
1983 case OP_LDIV_UN_IMM:
1984 case OP_IREM_UN_IMM:
1985 case OP_LREM_UN_IMM: {
1987 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1988 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
1990 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
1991 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
1992 CHECK_FAILURE (ctx);
1993 builder = ctx->builder;
1995 /* b == -1 && a == 0x80000000 */
1997 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
1998 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
1999 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2001 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2002 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2003 CHECK_FAILURE (ctx);
2004 builder = ctx->builder;
2019 * Emit code to load/convert arguments.
2022 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2025 MonoCompile *cfg = ctx->cfg;
2026 MonoMethodSignature *sig = ctx->sig;
2027 LLVMCallInfo *linfo = ctx->linfo;
2030 ctx->alloca_builder = create_builder (ctx);
2033 * Handle indirect/volatile variables by allocating memory for them
2034 * using 'alloca', and storing their address in a temporary.
2036 for (i = 0; i < cfg->num_varinfo; ++i) {
2037 MonoInst *var = cfg->varinfo [i];
2040 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2041 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2042 CHECK_FAILURE (ctx);
2043 /* Could be already created by an OP_VPHI */
2044 if (!ctx->addresses [var->dreg])
2045 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2046 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2050 for (i = 0; i < sig->param_count; ++i) {
2051 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2052 int reg = cfg->args [i + sig->hasthis]->dreg;
2054 switch (ainfo->storage) {
2055 case LLVMArgVtypeInReg:
2056 case LLVMArgAsFpArgs: {
2057 LLVMValueRef args [8];
2060 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2061 memset (args, 0, sizeof (args));
2062 pindex = ctx->pindexes [i];
2063 if (ainfo->storage == LLVMArgVtypeInReg) {
2064 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2065 if (ainfo->pair_storage [1] != LLVMArgNone)
2066 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2068 g_assert (ainfo->nslots <= 8);
2069 for (j = 0; j < ainfo->nslots; ++j)
2070 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2072 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2074 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2076 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2077 /* Treat these as normal values */
2078 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2082 case LLVMArgVtypeByVal: {
2083 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2085 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2086 /* Treat these as normal values */
2087 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2091 case LLVMArgAsIArgs: {
2092 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2094 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2096 /* The argument is received as an array of ints, store it into the real argument */
2097 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2101 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->params [i])), type_is_unsigned (ctx, sig->params [i]));
2107 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2109 emit_volatile_store (ctx, cfg->args [0]->dreg);
2110 for (i = 0; i < sig->param_count; ++i)
2111 if (!mini_type_is_vtype (cfg, sig->params [i]))
2112 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2114 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2115 LLVMValueRef this_alloc;
2118 * The exception handling code needs the location where the this argument was
2119 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2120 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2121 * location into the LSDA.
2123 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2124 /* This volatile store will keep the alloca alive */
2125 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2127 set_metadata_flag (this_alloc, "mono.this");
2130 if (cfg->rgctx_var) {
2131 LLVMValueRef rgctx_alloc, store;
2134 * We handle the rgctx arg similarly to the this pointer.
2136 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2137 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2138 /* This volatile store will keep the alloca alive */
2139 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2141 set_metadata_flag (rgctx_alloc, "mono.this");
2144 /* Compute nesting between clauses */
2145 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2146 for (i = 0; i < cfg->header->num_clauses; ++i) {
2147 for (j = 0; j < cfg->header->num_clauses; ++j) {
2148 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2149 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2151 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2152 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2157 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2158 * it needs to continue normally, or return back to the exception handling system.
2160 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2164 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2167 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2168 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2169 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2171 if (bb->in_scount == 0) {
2174 sprintf (name, "finally_ind_bb%d", bb->block_num);
2175 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2176 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2178 ctx->bblocks [bb->block_num].finally_ind = val;
2180 /* Create a variable to hold the exception var */
2182 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2186 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2187 * LLVM bblock containing a landing pad causes problems for the
2188 * LLVM optimizer passes.
2190 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2191 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2198 /* Have to export this for AOT */
2200 mono_personality (void)
2203 g_assert_not_reached ();
2207 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2209 MonoCompile *cfg = ctx->cfg;
2210 LLVMModuleRef module = ctx->module;
2211 LLVMValueRef *values = ctx->values;
2212 LLVMValueRef *addresses = ctx->addresses;
2213 MonoCallInst *call = (MonoCallInst*)ins;
2214 MonoMethodSignature *sig = call->signature;
2215 LLVMValueRef callee = NULL, lcall;
2217 LLVMCallInfo *cinfo;
2221 LLVMTypeRef llvm_sig;
2223 gboolean virtual, calli;
2224 LLVMBuilderRef builder = *builder_ref;
2227 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2228 LLVM_FAILURE (ctx, "non-default callconv");
2230 cinfo = call->cinfo;
2231 if (call->rgctx_arg_reg)
2232 cinfo->rgctx_arg = TRUE;
2233 if (call->imt_arg_reg)
2234 cinfo->imt_arg = TRUE;
2236 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2238 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2239 CHECK_FAILURE (ctx);
2241 virtual = (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 || ins->opcode == OP_RCALL_MEMBASE);
2242 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
2244 /* FIXME: Avoid creating duplicate methods */
2246 if (ins->flags & MONO_INST_HAS_METHOD) {
2250 if (cfg->compile_aot) {
2251 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2253 LLVM_FAILURE (ctx, "can't encode patch");
2255 callee = LLVMAddFunction (module, "", llvm_sig);
2258 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2260 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2264 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2265 /* LLVM miscompiles async methods */
2266 LLVM_FAILURE (ctx, "#13734");
2269 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2275 memset (&ji, 0, sizeof (ji));
2276 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2277 ji.data.target = info->name;
2279 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2281 if (cfg->compile_aot) {
2282 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2284 LLVM_FAILURE (ctx, "can't encode patch");
2286 callee = LLVMAddFunction (module, "", llvm_sig);
2287 target = (gpointer)mono_icall_get_wrapper (info);
2288 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2291 if (cfg->compile_aot) {
2293 if (cfg->abs_patches) {
2294 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2296 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2298 LLVM_FAILURE (ctx, "can't encode patch");
2302 LLVM_FAILURE (ctx, "aot");
2304 callee = LLVMAddFunction (module, "", llvm_sig);
2306 if (cfg->abs_patches) {
2307 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2310 * FIXME: Some trampolines might have
2311 * their own calling convention on some platforms.
2313 #ifndef TARGET_AMD64
2314 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2315 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2316 LLVM_FAILURE (ctx, "trampoline with own cconv");
2318 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2319 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2323 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2329 int size = sizeof (gpointer);
2332 g_assert (ins->inst_offset % size == 0);
2333 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2335 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2337 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2339 if (ins->flags & MONO_INST_HAS_METHOD) {
2344 * Collect and convert arguments
2346 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2347 len = sizeof (LLVMValueRef) * nargs;
2348 args = alloca (len);
2349 memset (args, 0, len);
2350 l = call->out_ireg_args;
2352 if (call->rgctx_arg_reg) {
2353 g_assert (values [call->rgctx_arg_reg]);
2354 g_assert (sinfo.rgctx_arg_pindex < nargs);
2356 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2357 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2358 * it using a volatile load.
2361 if (!ctx->imt_rgctx_loc)
2362 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2363 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2364 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2366 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2369 if (call->imt_arg_reg) {
2370 g_assert (values [call->imt_arg_reg]);
2371 g_assert (sinfo.imt_arg_pindex < nargs);
2373 if (!ctx->imt_rgctx_loc)
2374 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2375 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2376 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2378 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2383 if (!addresses [call->inst.dreg])
2384 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2385 g_assert (sinfo.vret_arg_pindex < nargs);
2386 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2389 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2392 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2396 pindex = sinfo.this_arg_pindex;
2398 pindex = sinfo.pindexes [i - 1];
2400 pindex = sinfo.pindexes [i];
2403 regpair = (guint32)(gssize)(l->data);
2404 reg = regpair & 0xffffff;
2405 args [pindex] = values [reg];
2406 switch (ainfo->storage) {
2407 case LLVMArgVtypeInReg:
2408 case LLVMArgAsFpArgs: {
2411 g_assert (addresses [reg]);
2412 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2416 // FIXME: Get rid of the VMOVE
2419 case LLVMArgVtypeByVal:
2420 g_assert (addresses [reg]);
2421 args [pindex] = addresses [reg];
2423 case LLVMArgAsIArgs:
2424 g_assert (addresses [reg]);
2425 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2428 g_assert (args [pindex]);
2429 if (i == 0 && sig->hasthis)
2430 args [pindex] = convert (ctx, args [pindex], ThisType ());
2432 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2435 g_assert (pindex <= nargs);
2440 // FIXME: Align call sites
2446 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2449 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2451 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2452 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2454 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2455 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2457 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2459 if (call->rgctx_arg_reg)
2460 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2461 if (call->imt_arg_reg)
2462 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2464 /* Add byval attributes if needed */
2465 for (i = 0; i < sig->param_count; ++i) {
2466 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2468 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2469 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2474 * Convert the result
2477 switch (cinfo->ret.storage) {
2478 case LLVMArgVtypeInReg: {
2479 LLVMValueRef regs [2];
2481 if (!addresses [ins->dreg])
2482 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2484 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2485 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2486 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2487 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2490 case LLVMArgVtypeByVal:
2491 if (!addresses [call->inst.dreg])
2492 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2493 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2495 case LLVMArgFpStruct:
2496 if (!addresses [call->inst.dreg])
2497 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2498 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2501 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2502 /* If the method returns an unsigned value, need to zext it */
2503 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2507 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2508 /* If the method returns an unsigned value, need to zext it */
2509 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2513 if (!addresses [call->inst.dreg])
2514 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2515 g_assert (sinfo.vret_arg_pindex < nargs);
2516 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2519 *builder_ref = ctx->builder;
2521 g_free (sinfo.pindexes);
2529 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2531 MonoCompile *cfg = ctx->cfg;
2532 LLVMValueRef *values = ctx->values;
2533 LLVMModuleRef module = ctx->module;
2534 BBInfo *bblocks = ctx->bblocks;
2536 LLVMValueRef personality;
2537 LLVMValueRef landing_pad;
2538 LLVMBasicBlockRef target_bb;
2540 static gint32 mapping_inited;
2541 static int ti_generator;
2544 LLVMValueRef type_info;
2548 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2550 if (cfg->compile_aot) {
2551 /* Use a dummy personality function */
2552 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2553 g_assert (personality);
2555 personality = LLVMGetNamedFunction (module, "mono_personality");
2556 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2557 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2560 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2562 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2565 * Create the type info
2567 sprintf (ti_name, "type_info_%d", ti_generator);
2570 if (cfg->compile_aot) {
2571 /* decode_eh_frame () in aot-runtime.c will decode this */
2572 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2573 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2576 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2578 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2581 * After the cfg mempool is freed, the type info will point to stale memory,
2582 * but this is not a problem, since we decode it once in exception_cb during
2585 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2586 *(gint32*)ti = clause_index;
2588 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2590 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2594 LLVMTypeRef members [2], ret_type;
2596 members [0] = i8ptr;
2597 members [1] = LLVMInt32Type ();
2598 ret_type = LLVMStructType (members, 2, FALSE);
2600 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2601 LLVMAddClause (landing_pad, type_info);
2603 /* Store the exception into the exvar */
2605 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2609 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2610 * code expects control to be transferred to this landing pad even in the
2611 * presence of nested clauses. The landing pad needs to branch to the landing
2612 * pads belonging to nested clauses based on the selector value returned by
2613 * the landing pad instruction, which is passed to the landing pad in a
2614 * register by the EH code.
2616 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2617 g_assert (target_bb);
2620 * Branch to the correct landing pad
2622 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2623 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2625 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2626 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2627 MonoBasicBlock *handler_bb;
2629 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2630 g_assert (handler_bb);
2632 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2633 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2636 /* Start a new bblock which CALL_HANDLER can branch to */
2637 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2639 ctx->builder = builder = create_builder (ctx);
2640 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2642 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2644 /* Store the exception into the IL level exvar */
2645 if (bb->in_scount == 1) {
2646 g_assert (bb->in_scount == 1);
2647 exvar = bb->in_stack [0];
2649 // FIXME: This is shared with filter clauses ?
2650 g_assert (!values [exvar->dreg]);
2652 g_assert (ctx->ex_var);
2653 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2654 emit_volatile_store (ctx, exvar->dreg);
2660 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2662 MonoCompile *cfg = ctx->cfg;
2663 MonoMethodSignature *sig = ctx->sig;
2664 LLVMValueRef method = ctx->lmethod;
2665 LLVMValueRef *values = ctx->values;
2666 LLVMValueRef *addresses = ctx->addresses;
2667 LLVMCallInfo *linfo = ctx->linfo;
2668 LLVMModuleRef module = ctx->module;
2669 BBInfo *bblocks = ctx->bblocks;
2671 LLVMBasicBlockRef cbb;
2672 LLVMBuilderRef builder, starting_builder;
2673 gboolean has_terminator;
2675 LLVMValueRef lhs, rhs;
2678 cbb = get_bb (ctx, bb);
2679 builder = create_builder (ctx);
2680 ctx->builder = builder;
2681 LLVMPositionBuilderAtEnd (builder, cbb);
2683 if (bb == cfg->bb_entry)
2684 emit_entry_bb (ctx, builder);
2685 CHECK_FAILURE (ctx);
2687 if (bb->flags & BB_EXCEPTION_HANDLER) {
2688 if (!bblocks [bb->block_num].invoke_target) {
2690 * LLVM asserts if llvm.eh.selector is called from a bblock which
2691 * doesn't have an invoke pointing at it.
2692 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2694 LLVM_FAILURE (ctx, "handler without invokes");
2697 emit_handler_start (ctx, bb, builder);
2698 CHECK_FAILURE (ctx);
2699 builder = ctx->builder;
2702 has_terminator = FALSE;
2703 starting_builder = builder;
2704 for (ins = bb->code; ins; ins = ins->next) {
2705 const char *spec = LLVM_INS_INFO (ins->opcode);
2707 char dname_buf [128];
2709 emit_dbg_loc (ctx, builder, ins->cil_code);
2712 if (nins > 3000 && builder == starting_builder) {
2713 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2714 LLVM_FAILURE (ctx, "basic block too long");
2718 /* There could be instructions after a terminator, skip them */
2721 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2722 sprintf (dname_buf, "t%d", ins->dreg);
2726 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2727 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2729 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2730 lhs = emit_volatile_load (ctx, ins->sreg1);
2732 /* It is ok for SETRET to have an uninitialized argument */
2733 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2734 LLVM_FAILURE (ctx, "sreg1");
2735 lhs = values [ins->sreg1];
2741 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2742 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2743 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2744 rhs = emit_volatile_load (ctx, ins->sreg2);
2746 if (!values [ins->sreg2])
2747 LLVM_FAILURE (ctx, "sreg2");
2748 rhs = values [ins->sreg2];
2754 //mono_print_ins (ins);
2755 switch (ins->opcode) {
2758 case OP_LIVERANGE_START:
2759 case OP_LIVERANGE_END:
2762 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2765 #if SIZEOF_VOID_P == 4
2766 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2768 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2772 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2776 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2778 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2780 case OP_DUMMY_ICONST:
2781 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2783 case OP_DUMMY_I8CONST:
2784 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2786 case OP_DUMMY_R8CONST:
2787 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2790 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2791 has_terminator = TRUE;
2797 LLVMBasicBlockRef new_bb;
2798 LLVMBuilderRef new_builder;
2800 // The default branch is already handled
2801 // FIXME: Handle it here
2803 /* Start new bblock */
2804 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2805 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2807 lhs = convert (ctx, lhs, LLVMInt32Type ());
2808 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2809 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2810 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2812 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2815 new_builder = create_builder (ctx);
2816 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2817 LLVMBuildUnreachable (new_builder);
2819 has_terminator = TRUE;
2820 g_assert (!ins->next);
2826 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2827 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2828 LLVMValueRef part1, retval;
2831 size = get_vtype_size (sig->ret);
2833 g_assert (addresses [ins->sreg1]);
2835 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2836 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2838 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2840 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2842 LLVMBuildRet (builder, retval);
2846 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2847 LLVMValueRef retval;
2849 g_assert (addresses [ins->sreg1]);
2850 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2851 LLVMBuildRet (builder, retval);
2855 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2856 LLVMBuildRetVoid (builder);
2860 if (linfo->ret.storage == LLVMArgFpStruct) {
2861 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2862 LLVMValueRef retval;
2864 g_assert (addresses [ins->sreg1]);
2865 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2866 LLVMBuildRet (builder, retval);
2870 if (!lhs || ctx->is_dead [ins->sreg1]) {
2872 * The method did not set its return value, probably because it
2873 * ends with a throw.
2876 LLVMBuildRetVoid (builder);
2878 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2880 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2882 has_terminator = TRUE;
2889 case OP_ICOMPARE_IMM:
2890 case OP_LCOMPARE_IMM:
2891 case OP_COMPARE_IMM: {
2895 if (ins->next->opcode == OP_NOP)
2898 if (ins->next->opcode == OP_BR)
2899 /* The comparison result is not needed */
2902 rel = mono_opcode_to_cond (ins->next->opcode);
2904 if (ins->opcode == OP_ICOMPARE_IMM) {
2905 lhs = convert (ctx, lhs, LLVMInt32Type ());
2906 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2908 if (ins->opcode == OP_LCOMPARE_IMM) {
2909 lhs = convert (ctx, lhs, LLVMInt64Type ());
2910 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2912 if (ins->opcode == OP_LCOMPARE) {
2913 lhs = convert (ctx, lhs, LLVMInt64Type ());
2914 rhs = convert (ctx, rhs, LLVMInt64Type ());
2916 if (ins->opcode == OP_ICOMPARE) {
2917 lhs = convert (ctx, lhs, LLVMInt32Type ());
2918 rhs = convert (ctx, rhs, LLVMInt32Type ());
2922 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2923 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2924 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2925 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2928 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2929 if (ins->opcode == OP_FCOMPARE) {
2930 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2931 } else if (ins->opcode == OP_RCOMPARE) {
2932 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2933 } else if (ins->opcode == OP_COMPARE_IMM) {
2934 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2935 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2937 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2938 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2939 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2940 /* The immediate is encoded in two fields */
2941 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2942 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2944 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2947 else if (ins->opcode == OP_COMPARE) {
2948 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2949 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2951 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2953 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2955 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2956 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2958 * If the target bb contains PHI instructions, LLVM requires
2959 * two PHI entries for this bblock, while we only generate one.
2960 * So convert this to an unconditional bblock. (bxc #171).
2962 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2964 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2966 has_terminator = TRUE;
2967 } else if (MONO_IS_SETCC (ins->next)) {
2968 sprintf (dname_buf, "t%d", ins->next->dreg);
2970 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2972 /* Add stores for volatile variables */
2973 emit_volatile_store (ctx, ins->next->dreg);
2974 } else if (MONO_IS_COND_EXC (ins->next)) {
2975 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2976 CHECK_FAILURE (ctx);
2977 builder = ctx->builder;
2979 LLVM_FAILURE (ctx, "next");
2993 rel = mono_opcode_to_cond (ins->opcode);
2995 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2996 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3007 rel = mono_opcode_to_cond (ins->opcode);
3009 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3010 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3018 gboolean empty = TRUE;
3020 /* Check that all input bblocks really branch to us */
3021 for (i = 0; i < bb->in_count; ++i) {
3022 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3023 ins->inst_phi_args [i + 1] = -1;
3029 /* LLVM doesn't like phi instructions with zero operands */
3030 ctx->is_dead [ins->dreg] = TRUE;
3034 /* Created earlier, insert it now */
3035 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3037 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3038 int sreg1 = ins->inst_phi_args [i + 1];
3042 * Count the number of times the incoming bblock branches to us,
3043 * since llvm requires a separate entry for each.
3045 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3046 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3049 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3050 if (switch_ins->inst_many_bb [j] == bb)
3057 /* Remember for later */
3058 for (j = 0; j < count; ++j) {
3059 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3062 node->in_bb = bb->in_bb [i];
3064 bblocks [bb->in_bb [i]->block_num].phi_nodes = g_slist_prepend_mempool (ctx->mempool, bblocks [bb->in_bb [i]->block_num].phi_nodes, node);
3074 values [ins->dreg] = lhs;
3078 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3081 values [ins->dreg] = lhs;
3083 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3085 * This is added by the spilling pass in case of the JIT,
3086 * but we have to do it ourselves.
3088 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3092 case OP_MOVE_F_TO_I4: {
3093 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3096 case OP_MOVE_I4_TO_F: {
3097 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3100 case OP_MOVE_F_TO_I8: {
3101 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3104 case OP_MOVE_I8_TO_F: {
3105 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3138 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3139 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3141 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3142 CHECK_FAILURE (ctx);
3143 builder = ctx->builder;
3145 switch (ins->opcode) {
3148 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3152 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3156 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3160 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3164 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3168 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3172 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3176 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3180 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3184 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3188 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3192 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3196 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3200 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3204 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3207 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3210 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3214 g_assert_not_reached ();
3221 lhs = convert (ctx, lhs, LLVMFloatType ());
3222 rhs = convert (ctx, rhs, LLVMFloatType ());
3223 switch (ins->opcode) {
3225 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3228 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3231 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3234 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3237 g_assert_not_reached ();
3246 case OP_IREM_UN_IMM:
3248 case OP_IDIV_UN_IMM:
3254 case OP_ISHR_UN_IMM:
3263 case OP_LSHR_UN_IMM:
3269 case OP_SHR_UN_IMM: {
3272 if (spec [MONO_INST_SRC1] == 'l') {
3273 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3275 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3278 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3279 CHECK_FAILURE (ctx);
3280 builder = ctx->builder;
3282 #if SIZEOF_VOID_P == 4
3283 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3284 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3287 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3288 lhs = convert (ctx, lhs, IntPtrType ());
3289 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3290 switch (ins->opcode) {
3294 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3298 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3302 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3306 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3308 case OP_IDIV_UN_IMM:
3309 case OP_LDIV_UN_IMM:
3310 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3314 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3316 case OP_IREM_UN_IMM:
3317 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3322 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3326 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3330 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3335 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3340 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3342 case OP_ISHR_UN_IMM:
3343 /* This is used to implement conv.u4, so the lhs could be an i8 */
3344 lhs = convert (ctx, lhs, LLVMInt32Type ());
3345 imm = convert (ctx, imm, LLVMInt32Type ());
3346 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3348 case OP_LSHR_UN_IMM:
3350 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3353 g_assert_not_reached ();
3358 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3361 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3364 lhs = convert (ctx, lhs, LLVMDoubleType ());
3365 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3368 lhs = convert (ctx, lhs, LLVMFloatType ());
3369 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3372 guint32 v = 0xffffffff;
3373 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3377 guint64 v = 0xffffffffffffffffLL;
3378 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3381 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3383 LLVMValueRef v1, v2;
3385 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3386 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3387 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3392 case OP_ICONV_TO_I1:
3393 case OP_ICONV_TO_I2:
3394 case OP_ICONV_TO_I4:
3395 case OP_ICONV_TO_U1:
3396 case OP_ICONV_TO_U2:
3397 case OP_ICONV_TO_U4:
3398 case OP_LCONV_TO_I1:
3399 case OP_LCONV_TO_I2:
3400 case OP_LCONV_TO_U1:
3401 case OP_LCONV_TO_U2:
3402 case OP_LCONV_TO_U4: {
3405 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);
3407 /* Have to do two casts since our vregs have type int */
3408 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3410 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3412 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3415 case OP_ICONV_TO_I8:
3416 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3418 case OP_ICONV_TO_U8:
3419 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3421 case OP_FCONV_TO_I4:
3422 case OP_RCONV_TO_I4:
3423 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3425 case OP_FCONV_TO_I1:
3426 case OP_RCONV_TO_I1:
3427 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3429 case OP_FCONV_TO_U1:
3430 case OP_RCONV_TO_U1:
3431 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3433 case OP_FCONV_TO_I2:
3434 case OP_RCONV_TO_I2:
3435 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3437 case OP_FCONV_TO_U2:
3438 case OP_RCONV_TO_U2:
3439 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3441 case OP_FCONV_TO_I8:
3442 case OP_RCONV_TO_I8:
3443 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3446 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3448 case OP_ICONV_TO_R8:
3449 case OP_LCONV_TO_R8:
3450 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3452 case OP_LCONV_TO_R_UN:
3453 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3455 #if SIZEOF_VOID_P == 4
3458 case OP_LCONV_TO_I4:
3459 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3461 case OP_ICONV_TO_R4:
3462 case OP_LCONV_TO_R4:
3463 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3465 values [ins->dreg] = v;
3467 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3469 case OP_FCONV_TO_R4:
3470 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3472 values [ins->dreg] = v;
3474 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3476 case OP_RCONV_TO_R8:
3477 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3479 case OP_RCONV_TO_R4:
3480 values [ins->dreg] = lhs;
3483 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3486 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3489 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3491 case OP_LOCALLOC_IMM: {
3494 guint32 size = ins->inst_imm;
3495 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3497 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3499 if (ins->flags & MONO_INST_INIT) {
3500 LLVMValueRef args [5];
3503 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3504 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3505 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3506 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3507 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3510 values [ins->dreg] = v;
3514 LLVMValueRef v, size;
3516 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
3518 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3520 if (ins->flags & MONO_INST_INIT) {
3521 LLVMValueRef args [5];
3524 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3526 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3527 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3528 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3530 values [ins->dreg] = v;
3534 case OP_LOADI1_MEMBASE:
3535 case OP_LOADU1_MEMBASE:
3536 case OP_LOADI2_MEMBASE:
3537 case OP_LOADU2_MEMBASE:
3538 case OP_LOADI4_MEMBASE:
3539 case OP_LOADU4_MEMBASE:
3540 case OP_LOADI8_MEMBASE:
3541 case OP_LOADR4_MEMBASE:
3542 case OP_LOADR8_MEMBASE:
3543 case OP_LOAD_MEMBASE:
3551 LLVMValueRef base, index, addr;
3553 gboolean sext = FALSE, zext = FALSE;
3554 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3556 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3561 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)) {
3562 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3567 if (ins->inst_offset == 0) {
3569 } else if (ins->inst_offset % size != 0) {
3570 /* Unaligned load */
3571 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3572 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3574 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3575 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3579 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3581 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3583 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3585 * These will signal LLVM that these loads do not alias any stores, and
3586 * they can't fail, allowing them to be hoisted out of loops.
3588 set_invariant_load_flag (values [ins->dreg]);
3589 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3593 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3595 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3596 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3597 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3601 case OP_STOREI1_MEMBASE_REG:
3602 case OP_STOREI2_MEMBASE_REG:
3603 case OP_STOREI4_MEMBASE_REG:
3604 case OP_STOREI8_MEMBASE_REG:
3605 case OP_STORER4_MEMBASE_REG:
3606 case OP_STORER8_MEMBASE_REG:
3607 case OP_STORE_MEMBASE_REG: {
3609 LLVMValueRef index, addr;
3611 gboolean sext = FALSE, zext = FALSE;
3612 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3614 if (!values [ins->inst_destbasereg])
3615 LLVM_FAILURE (ctx, "inst_destbasereg");
3617 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3619 if (ins->inst_offset % size != 0) {
3620 /* Unaligned store */
3621 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3622 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3624 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3625 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3627 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3631 case OP_STOREI1_MEMBASE_IMM:
3632 case OP_STOREI2_MEMBASE_IMM:
3633 case OP_STOREI4_MEMBASE_IMM:
3634 case OP_STOREI8_MEMBASE_IMM:
3635 case OP_STORE_MEMBASE_IMM: {
3637 LLVMValueRef index, addr;
3639 gboolean sext = FALSE, zext = FALSE;
3640 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3642 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3644 if (ins->inst_offset % size != 0) {
3645 /* Unaligned store */
3646 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3647 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3649 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3650 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3652 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3657 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3659 case OP_OUTARG_VTRETADDR:
3667 case OP_VOIDCALL_MEMBASE:
3668 case OP_CALL_MEMBASE:
3669 case OP_LCALL_MEMBASE:
3670 case OP_FCALL_MEMBASE:
3671 case OP_RCALL_MEMBASE:
3672 case OP_VCALL_MEMBASE:
3673 case OP_VOIDCALL_REG:
3678 case OP_VCALL_REG: {
3679 process_call (ctx, bb, &builder, ins);
3680 CHECK_FAILURE (ctx);
3685 LLVMValueRef indexes [2];
3687 LLVMValueRef got_entry_addr;
3690 * FIXME: Can't allocate from the cfg mempool since that is freed if
3691 * the LLVM compile fails.
3693 ji = g_new0 (MonoJumpInfo, 1);
3694 ji->type = (MonoJumpInfoType)ins->inst_i1;
3695 ji->data.target = ins->inst_p0;
3697 ji = mono_aot_patch_info_dup (ji);
3699 ji->next = cfg->patch_info;
3700 cfg->patch_info = ji;
3702 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3703 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3704 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3706 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3707 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3708 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3710 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3711 set_invariant_load_flag (values [ins->dreg]);
3714 case OP_NOT_REACHED:
3715 LLVMBuildUnreachable (builder);
3716 has_terminator = TRUE;
3717 g_assert (bb->block_num < cfg->max_block_num);
3718 ctx->unreachable [bb->block_num] = TRUE;
3719 /* Might have instructions after this */
3721 MonoInst *next = ins->next;
3723 * FIXME: If later code uses the regs defined by these instructions,
3724 * compilation will fail.
3726 MONO_DELETE_INS (bb, next);
3730 MonoInst *var = ins->inst_p0;
3732 values [ins->dreg] = addresses [var->dreg];
3736 LLVMValueRef args [1];
3738 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3739 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3743 LLVMValueRef args [1];
3745 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3746 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3750 LLVMValueRef args [1];
3753 /* This no longer seems to happen */
3755 * LLVM optimizes sqrt(nan) into undefined in
3756 * lib/Analysis/ConstantFolding.cpp
3757 * Also, sqrt(NegativeInfinity) is optimized into 0.
3759 LLVM_FAILURE (ctx, "sqrt");
3761 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3762 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3766 LLVMValueRef args [1];
3768 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3769 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3783 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3784 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3786 switch (ins->opcode) {
3789 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3793 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3797 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3801 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3804 g_assert_not_reached ();
3807 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3810 case OP_ATOMIC_EXCHANGE_I4:
3811 case OP_ATOMIC_EXCHANGE_I8: {
3812 LLVMValueRef args [2];
3815 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3816 t = LLVMInt32Type ();
3818 t = LLVMInt64Type ();
3820 g_assert (ins->inst_offset == 0);
3822 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3823 args [1] = convert (ctx, rhs, t);
3825 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3828 case OP_ATOMIC_ADD_I4:
3829 case OP_ATOMIC_ADD_I8: {
3830 LLVMValueRef args [2];
3833 if (ins->opcode == OP_ATOMIC_ADD_I4)
3834 t = LLVMInt32Type ();
3836 t = LLVMInt64Type ();
3838 g_assert (ins->inst_offset == 0);
3840 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3841 args [1] = convert (ctx, rhs, t);
3842 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3845 case OP_ATOMIC_CAS_I4:
3846 case OP_ATOMIC_CAS_I8: {
3847 LLVMValueRef args [3], val;
3850 if (ins->opcode == OP_ATOMIC_CAS_I4)
3851 t = LLVMInt32Type ();
3853 t = LLVMInt64Type ();
3855 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3857 args [1] = convert (ctx, values [ins->sreg3], t);
3859 args [2] = convert (ctx, values [ins->sreg2], t);
3860 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3861 /* cmpxchg returns a pair */
3862 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3865 case OP_MEMORY_BARRIER: {
3866 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3869 case OP_ATOMIC_LOAD_I1:
3870 case OP_ATOMIC_LOAD_I2:
3871 case OP_ATOMIC_LOAD_I4:
3872 case OP_ATOMIC_LOAD_I8:
3873 case OP_ATOMIC_LOAD_U1:
3874 case OP_ATOMIC_LOAD_U2:
3875 case OP_ATOMIC_LOAD_U4:
3876 case OP_ATOMIC_LOAD_U8:
3877 case OP_ATOMIC_LOAD_R4:
3878 case OP_ATOMIC_LOAD_R8: {
3879 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3882 gboolean sext, zext;
3884 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3885 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3886 LLVMValueRef index, addr;
3888 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3893 if (ins->inst_offset != 0) {
3894 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3895 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3900 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3902 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3905 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3907 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3910 case OP_ATOMIC_STORE_I1:
3911 case OP_ATOMIC_STORE_I2:
3912 case OP_ATOMIC_STORE_I4:
3913 case OP_ATOMIC_STORE_I8:
3914 case OP_ATOMIC_STORE_U1:
3915 case OP_ATOMIC_STORE_U2:
3916 case OP_ATOMIC_STORE_U4:
3917 case OP_ATOMIC_STORE_U8:
3918 case OP_ATOMIC_STORE_R4:
3919 case OP_ATOMIC_STORE_R8: {
3920 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3923 gboolean sext, zext;
3925 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3926 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3927 LLVMValueRef index, addr, value;
3929 if (!values [ins->inst_destbasereg])
3930 LLVM_FAILURE (ctx, "inst_destbasereg");
3932 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3934 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3935 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3936 value = convert (ctx, values [ins->sreg1], t);
3938 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3941 case OP_RELAXED_NOP: {
3942 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3943 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3950 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3952 // 257 == FS segment register
3953 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3955 // 256 == GS segment register
3956 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3959 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3960 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3961 /* See mono_amd64_emit_tls_get () */
3962 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3964 // 256 == GS segment register
3965 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3966 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3968 LLVM_FAILURE (ctx, "opcode tls-get");
3973 case OP_TLS_GET_REG: {
3974 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3975 /* See emit_tls_get_reg () */
3976 // 256 == GS segment register
3977 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3978 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3980 LLVM_FAILURE (ctx, "opcode tls-get");
3989 case OP_IADD_OVF_UN:
3991 case OP_ISUB_OVF_UN:
3993 case OP_IMUL_OVF_UN:
3994 #if SIZEOF_VOID_P == 8
3996 case OP_LADD_OVF_UN:
3998 case OP_LSUB_OVF_UN:
4000 case OP_LMUL_OVF_UN:
4003 LLVMValueRef args [2], val, ovf, func;
4005 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4006 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4007 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4009 val = LLVMBuildCall (builder, func, args, 2, "");
4010 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4011 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4012 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4013 CHECK_FAILURE (ctx);
4014 builder = ctx->builder;
4020 * We currently model them using arrays. Promotion to local vregs is
4021 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4022 * so we always have an entry in cfg->varinfo for them.
4023 * FIXME: Is this needed ?
4026 MonoClass *klass = ins->klass;
4027 LLVMValueRef args [5];
4031 LLVM_FAILURE (ctx, "!klass");
4035 if (!addresses [ins->dreg])
4036 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4037 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4038 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4039 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4041 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4042 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4043 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4046 case OP_DUMMY_VZERO:
4049 case OP_STOREV_MEMBASE:
4050 case OP_LOADV_MEMBASE:
4052 MonoClass *klass = ins->klass;
4053 LLVMValueRef src = NULL, dst, args [5];
4054 gboolean done = FALSE;
4058 LLVM_FAILURE (ctx, "!klass");
4062 if (mini_is_gsharedvt_klass (cfg, klass)) {
4064 LLVM_FAILURE (ctx, "gsharedvt");
4068 switch (ins->opcode) {
4069 case OP_STOREV_MEMBASE:
4070 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4071 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4072 /* Decomposed earlier */
4073 g_assert_not_reached ();
4076 if (!addresses [ins->sreg1]) {
4078 g_assert (values [ins->sreg1]);
4079 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (type_to_llvm_type (ctx, &klass->byval_arg), 0));
4080 LLVMBuildStore (builder, values [ins->sreg1], dst);
4083 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4084 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4087 case OP_LOADV_MEMBASE:
4088 if (!addresses [ins->dreg])
4089 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4090 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4091 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4094 if (!addresses [ins->sreg1])
4095 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4096 if (!addresses [ins->dreg])
4097 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4098 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4099 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4102 g_assert_not_reached ();
4104 CHECK_FAILURE (ctx);
4111 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4112 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4114 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4115 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4116 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4119 case OP_LLVM_OUTARG_VT:
4120 if (!addresses [ins->sreg1]) {
4121 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4122 g_assert (values [ins->sreg1]);
4123 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4125 addresses [ins->dreg] = addresses [ins->sreg1];
4131 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4133 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4136 case OP_LOADX_MEMBASE: {
4137 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4140 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4141 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4144 case OP_STOREX_MEMBASE: {
4145 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4148 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4149 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4156 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4160 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4166 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4170 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4174 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4178 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4181 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4184 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4187 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4191 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4202 LLVMValueRef v = NULL;
4204 switch (ins->opcode) {
4209 t = LLVMVectorType (LLVMInt32Type (), 4);
4210 rt = LLVMVectorType (LLVMFloatType (), 4);
4216 t = LLVMVectorType (LLVMInt64Type (), 2);
4217 rt = LLVMVectorType (LLVMDoubleType (), 2);
4220 t = LLVMInt32Type ();
4221 rt = LLVMInt32Type ();
4222 g_assert_not_reached ();
4225 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4226 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4227 switch (ins->opcode) {
4230 v = LLVMBuildAnd (builder, lhs, rhs, "");
4234 v = LLVMBuildOr (builder, lhs, rhs, "");
4238 v = LLVMBuildXor (builder, lhs, rhs, "");
4242 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4245 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4269 case OP_PADDB_SAT_UN:
4270 case OP_PADDW_SAT_UN:
4271 case OP_PSUBB_SAT_UN:
4272 case OP_PSUBW_SAT_UN:
4280 case OP_PMULW_HIGH_UN: {
4281 LLVMValueRef args [2];
4286 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4293 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4297 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4305 case OP_EXTRACTX_U2:
4307 case OP_EXTRACT_U1: {
4309 gboolean zext = FALSE;
4311 t = simd_op_to_llvm_type (ins->opcode);
4313 switch (ins->opcode) {
4321 case OP_EXTRACTX_U2:
4326 t = LLVMInt32Type ();
4327 g_assert_not_reached ();
4330 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4331 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4333 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4342 case OP_EXPAND_R8: {
4343 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4344 LLVMValueRef mask [16], v;
4347 for (i = 0; i < 16; ++i)
4348 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4350 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4352 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4353 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4358 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4361 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4364 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4367 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4370 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4373 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4384 case OP_EXTRACT_MASK:
4391 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4393 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4399 LLVMValueRef args [3];
4403 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4405 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4410 /* This is only used for implementing shifts by non-immediate */
4411 values [ins->dreg] = lhs;
4422 LLVMValueRef args [3];
4425 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4427 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4438 case OP_PSHLQ_REG: {
4439 LLVMValueRef args [3];
4442 args [1] = values [ins->sreg2];
4444 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4451 case OP_PSHUFLEW_LOW:
4452 case OP_PSHUFLEW_HIGH: {
4454 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4455 int i, mask_size = 0;
4456 int imask = ins->inst_c0;
4458 /* Convert the x86 shuffle mask to LLVM's */
4459 switch (ins->opcode) {
4462 mask [0] = ((imask >> 0) & 3);
4463 mask [1] = ((imask >> 2) & 3);
4464 mask [2] = ((imask >> 4) & 3) + 4;
4465 mask [3] = ((imask >> 6) & 3) + 4;
4466 v1 = values [ins->sreg1];
4467 v2 = values [ins->sreg2];
4471 mask [0] = ((imask >> 0) & 1);
4472 mask [1] = ((imask >> 1) & 1) + 2;
4473 v1 = values [ins->sreg1];
4474 v2 = values [ins->sreg2];
4476 case OP_PSHUFLEW_LOW:
4478 mask [0] = ((imask >> 0) & 3);
4479 mask [1] = ((imask >> 2) & 3);
4480 mask [2] = ((imask >> 4) & 3);
4481 mask [3] = ((imask >> 6) & 3);
4486 v1 = values [ins->sreg1];
4487 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4489 case OP_PSHUFLEW_HIGH:
4495 mask [4] = 4 + ((imask >> 0) & 3);
4496 mask [5] = 4 + ((imask >> 2) & 3);
4497 mask [6] = 4 + ((imask >> 4) & 3);
4498 mask [7] = 4 + ((imask >> 6) & 3);
4499 v1 = values [ins->sreg1];
4500 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4504 mask [0] = ((imask >> 0) & 3);
4505 mask [1] = ((imask >> 2) & 3);
4506 mask [2] = ((imask >> 4) & 3);
4507 mask [3] = ((imask >> 6) & 3);
4508 v1 = values [ins->sreg1];
4509 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4512 g_assert_not_reached ();
4514 for (i = 0; i < mask_size; ++i)
4515 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4517 values [ins->dreg] =
4518 LLVMBuildShuffleVector (builder, v1, v2,
4519 LLVMConstVector (mask_values, mask_size), dname);
4523 case OP_UNPACK_LOWB:
4524 case OP_UNPACK_LOWW:
4525 case OP_UNPACK_LOWD:
4526 case OP_UNPACK_LOWQ:
4527 case OP_UNPACK_LOWPS:
4528 case OP_UNPACK_LOWPD:
4529 case OP_UNPACK_HIGHB:
4530 case OP_UNPACK_HIGHW:
4531 case OP_UNPACK_HIGHD:
4532 case OP_UNPACK_HIGHQ:
4533 case OP_UNPACK_HIGHPS:
4534 case OP_UNPACK_HIGHPD: {
4536 LLVMValueRef mask_values [16];
4537 int i, mask_size = 0;
4538 gboolean low = FALSE;
4540 switch (ins->opcode) {
4541 case OP_UNPACK_LOWB:
4545 case OP_UNPACK_LOWW:
4549 case OP_UNPACK_LOWD:
4550 case OP_UNPACK_LOWPS:
4554 case OP_UNPACK_LOWQ:
4555 case OP_UNPACK_LOWPD:
4559 case OP_UNPACK_HIGHB:
4562 case OP_UNPACK_HIGHW:
4565 case OP_UNPACK_HIGHD:
4566 case OP_UNPACK_HIGHPS:
4569 case OP_UNPACK_HIGHQ:
4570 case OP_UNPACK_HIGHPD:
4574 g_assert_not_reached ();
4578 for (i = 0; i < (mask_size / 2); ++i) {
4580 mask [(i * 2) + 1] = mask_size + i;
4583 for (i = 0; i < (mask_size / 2); ++i) {
4584 mask [(i * 2)] = (mask_size / 2) + i;
4585 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4589 for (i = 0; i < mask_size; ++i)
4590 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4592 values [ins->dreg] =
4593 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4594 LLVMConstVector (mask_values, mask_size), dname);
4599 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4600 LLVMValueRef v, val;
4602 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4603 val = LLVMConstNull (t);
4604 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4605 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4607 values [ins->dreg] = val;
4611 case OP_DUPPS_HIGH: {
4612 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4613 LLVMValueRef v1, v2, val;
4616 if (ins->opcode == OP_DUPPS_LOW) {
4617 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4618 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4620 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4621 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4623 val = LLVMConstNull (t);
4624 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4625 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4626 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4627 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4629 values [ins->dreg] = val;
4639 * EXCEPTION HANDLING
4641 case OP_IMPLICIT_EXCEPTION:
4642 /* This marks a place where an implicit exception can happen */
4643 if (bb->region != -1)
4644 LLVM_FAILURE (ctx, "implicit-exception");
4648 MonoMethodSignature *throw_sig;
4649 LLVMValueRef callee, arg;
4650 gboolean rethrow = (ins->opcode == OP_RETHROW);
4651 const char *icall_name;
4653 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4654 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4657 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4658 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4659 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4660 if (cfg->compile_aot) {
4661 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4663 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4667 * LLVM doesn't push the exception argument, so we need a different
4670 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4672 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4676 mono_memory_barrier ();
4678 ctx->lmodule->rethrow = callee;
4680 ctx->lmodule->throw = callee;
4682 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4683 emit_call (ctx, bb, &builder, callee, &arg, 1);
4686 case OP_CALL_HANDLER: {
4688 * We don't 'call' handlers, but instead simply branch to them.
4689 * The code generated by ENDFINALLY will branch back to us.
4691 LLVMBasicBlockRef noex_bb;
4693 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4695 bb_list = info->call_handler_return_bbs;
4698 * Set the indicator variable for the finally clause.
4700 lhs = info->finally_ind;
4702 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4704 /* Branch to the finally clause */
4705 LLVMBuildBr (builder, info->call_handler_target_bb);
4707 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4708 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4710 builder = ctx->builder = create_builder (ctx);
4711 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4713 bblocks [bb->block_num].end_bblock = noex_bb;
4716 case OP_START_HANDLER: {
4719 case OP_ENDFINALLY: {
4720 LLVMBasicBlockRef resume_bb;
4721 MonoBasicBlock *handler_bb;
4722 LLVMValueRef val, switch_ins, callee;
4726 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4727 g_assert (handler_bb);
4728 info = &bblocks [handler_bb->block_num];
4729 lhs = info->finally_ind;
4732 bb_list = info->call_handler_return_bbs;
4734 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4736 /* Load the finally variable */
4737 val = LLVMBuildLoad (builder, lhs, "");
4739 /* Reset the variable */
4740 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4742 /* Branch to either resume_bb, or to the bblocks in bb_list */
4743 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4745 * The other targets are added at the end to handle OP_CALL_HANDLER
4746 * opcodes processed later.
4748 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4750 builder = ctx->builder = create_builder (ctx);
4751 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4753 if (ctx->cfg->compile_aot) {
4754 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4756 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4758 LLVMBuildCall (builder, callee, NULL, 0, "");
4760 LLVMBuildUnreachable (builder);
4761 has_terminator = TRUE;
4767 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4768 LLVM_FAILURE (ctx, reason);
4773 /* Convert the value to the type required by phi nodes */
4774 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4775 if (!values [ins->dreg])
4777 values [ins->dreg] = addresses [ins->dreg];
4779 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4782 /* Add stores for volatile variables */
4783 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4784 emit_volatile_store (ctx, ins->dreg);
4787 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4788 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4790 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4791 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4792 LLVMBuildRetVoid (builder);
4795 if (bb == cfg->bb_entry)
4796 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4805 * mono_llvm_check_method_supported:
4807 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4808 * compiling a method twice.
4811 mono_llvm_check_method_supported (MonoCompile *cfg)
4815 if (cfg->method->save_lmf) {
4816 cfg->exception_message = g_strdup ("lmf");
4817 cfg->disable_llvm = TRUE;
4819 if (cfg->disable_llvm)
4823 * Nested clauses where one of the clauses is a finally clause is
4824 * not supported, because LLVM can't figure out the control flow,
4825 * probably because we resume exception handling by calling our
4826 * own function instead of using the 'resume' llvm instruction.
4828 for (i = 0; i < cfg->header->num_clauses; ++i) {
4829 for (j = 0; j < cfg->header->num_clauses; ++j) {
4830 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4831 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4833 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4834 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4835 cfg->exception_message = g_strdup ("nested clauses");
4836 cfg->disable_llvm = TRUE;
4841 if (cfg->disable_llvm)
4845 if (cfg->method->dynamic) {
4846 cfg->exception_message = g_strdup ("dynamic.");
4847 cfg->disable_llvm = TRUE;
4849 if (cfg->disable_llvm)
4854 * mono_llvm_emit_method:
4856 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4859 mono_llvm_emit_method (MonoCompile *cfg)
4862 MonoMethodSignature *sig;
4864 LLVMTypeRef method_type;
4865 LLVMValueRef method = NULL;
4867 LLVMValueRef *values;
4868 int i, max_block_num, bb_index;
4869 gboolean last = FALSE;
4870 GPtrArray *phi_values;
4871 LLVMCallInfo *linfo;
4873 LLVMModuleRef module;
4875 GPtrArray *bblock_list;
4876 MonoMethodHeader *header;
4877 MonoExceptionClause *clause;
4881 /* The code below might acquire the loader lock, so use it for global locking */
4882 mono_loader_lock ();
4884 /* Used to communicate with the callbacks */
4885 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4887 ctx = g_new0 (EmitContext, 1);
4889 ctx->mempool = cfg->mempool;
4892 * This maps vregs to the LLVM instruction defining them
4894 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4896 * This maps vregs for volatile variables to the LLVM instruction defining their
4899 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4900 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4901 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4902 phi_values = g_ptr_array_sized_new (256);
4904 * This signals whenever the vreg was defined by a phi node with no input vars
4905 * (i.e. all its input bblocks end with NOT_REACHABLE).
4907 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4908 /* Whenever the bblock is unreachable */
4909 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4911 bblock_list = g_ptr_array_sized_new (256);
4913 ctx->values = values;
4914 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4915 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4917 if (cfg->compile_aot) {
4918 ctx->lmodule = &aot_module;
4919 method_name = mono_aot_get_method_name (cfg);
4920 cfg->llvm_method_name = g_strdup (method_name);
4922 init_jit_module (cfg->domain);
4923 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4924 method_name = mono_method_full_name (cfg->method, TRUE);
4927 module = ctx->module = ctx->lmodule->module;
4930 LLVM_FAILURE (ctx, "gsharedvt");
4934 static int count = 0;
4937 if (g_getenv ("LLVM_COUNT")) {
4938 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4939 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4943 if (count > atoi (g_getenv ("LLVM_COUNT")))
4944 LLVM_FAILURE (ctx, "");
4949 sig = mono_method_signature (cfg->method);
4952 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4954 CHECK_FAILURE (ctx);
4957 linfo->rgctx_arg = TRUE;
4958 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4959 CHECK_FAILURE (ctx);
4962 * This maps parameter indexes in the original signature to the indexes in
4963 * the LLVM signature.
4965 ctx->pindexes = sinfo.pindexes;
4967 method = LLVMAddFunction (module, method_name, method_type);
4968 ctx->lmethod = method;
4970 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4971 LLVMSetLinkage (method, LLVMPrivateLinkage);
4973 LLVMAddFunctionAttr (method, LLVMUWTable);
4975 if (cfg->compile_aot) {
4976 LLVMSetLinkage (method, LLVMInternalLinkage);
4977 if (ctx->lmodule->external_symbols) {
4978 LLVMSetLinkage (method, LLVMExternalLinkage);
4979 LLVMSetVisibility (method, LLVMHiddenVisibility);
4982 LLVMSetLinkage (method, LLVMPrivateLinkage);
4985 if (cfg->method->save_lmf)
4986 LLVM_FAILURE (ctx, "lmf");
4988 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4989 LLVM_FAILURE (ctx, "pinvoke signature");
4991 header = cfg->header;
4992 for (i = 0; i < header->num_clauses; ++i) {
4993 clause = &header->clauses [i];
4994 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4995 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4997 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
4998 /* We can't handle inlined methods with clauses */
4999 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5001 if (linfo->rgctx_arg) {
5002 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5004 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5005 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5006 * CC_X86_64_Mono in X86CallingConv.td.
5008 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5009 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5011 if (cfg->vret_addr) {
5012 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5013 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5016 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5017 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5020 names = g_new (char *, sig->param_count);
5021 mono_method_get_param_names (cfg->method, (const char **) names);
5023 for (i = 0; i < sig->param_count; ++i) {
5026 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5027 if (names [i] && names [i][0] != '\0')
5028 name = g_strdup_printf ("arg_%s", names [i]);
5030 name = g_strdup_printf ("arg_%d", i);
5031 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5033 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5034 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5038 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5039 ctx->minfo = mono_debug_lookup_method (cfg->method);
5040 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5044 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5045 max_block_num = MAX (max_block_num, bb->block_num);
5046 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5048 /* Add branches between non-consecutive bblocks */
5049 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5050 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5051 bb->next_bb != bb->last_ins->inst_false_bb) {
5053 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5054 inst->opcode = OP_BR;
5055 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5056 mono_bblock_add_inst (bb, inst);
5061 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5062 * was later optimized away, so clear these flags, and add them back for the still
5063 * present OP_LDADDR instructions.
5065 for (i = 0; i < cfg->next_vreg; ++i) {
5068 ins = get_vreg_to_inst (cfg, i);
5069 if (ins && ins != cfg->rgctx_var)
5070 ins->flags &= ~MONO_INST_INDIRECT;
5074 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5076 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5078 LLVMBuilderRef builder;
5080 char dname_buf[128];
5082 builder = create_builder (ctx);
5084 for (ins = bb->code; ins; ins = ins->next) {
5085 switch (ins->opcode) {
5090 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5092 CHECK_FAILURE (ctx);
5094 if (ins->opcode == OP_VPHI) {
5095 /* Treat valuetype PHI nodes as operating on the address itself */
5096 g_assert (ins->klass);
5097 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5101 * Have to precreate these, as they can be referenced by
5102 * earlier instructions.
5104 sprintf (dname_buf, "t%d", ins->dreg);
5106 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5108 if (ins->opcode == OP_VPHI)
5109 ctx->addresses [ins->dreg] = values [ins->dreg];
5111 g_ptr_array_add (phi_values, values [ins->dreg]);
5114 * Set the expected type of the incoming arguments since these have
5115 * to have the same type.
5117 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5118 int sreg1 = ins->inst_phi_args [i + 1];
5121 ctx->vreg_types [sreg1] = phi_type;
5126 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5135 * Create an ordering for bblocks, use the depth first order first, then
5136 * put the exception handling bblocks last.
5138 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5139 bb = cfg->bblocks [bb_index];
5140 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5141 g_ptr_array_add (bblock_list, bb);
5142 bblocks [bb->block_num].added = TRUE;
5146 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5147 if (!bblocks [bb->block_num].added)
5148 g_ptr_array_add (bblock_list, bb);
5152 * Second pass: generate code.
5154 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5155 bb = g_ptr_array_index (bblock_list, bb_index);
5157 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5160 process_bb (ctx, bb);
5161 CHECK_FAILURE (ctx);
5164 /* Add incoming phi values */
5165 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5166 GSList *l, *ins_list;
5168 ins_list = bblocks [bb->block_num].phi_nodes;
5170 for (l = ins_list; l; l = l->next) {
5171 PhiNode *node = l->data;
5172 MonoInst *phi = node->phi;
5173 int sreg1 = node->sreg;
5174 LLVMBasicBlockRef in_bb;
5179 in_bb = get_end_bb (ctx, node->in_bb);
5181 if (ctx->unreachable [node->in_bb->block_num])
5184 if (!values [sreg1])
5185 /* Can happen with values in EH clauses */
5186 LLVM_FAILURE (ctx, "incoming phi sreg1");
5188 if (phi->opcode == OP_VPHI) {
5189 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5190 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5192 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5194 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5195 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5196 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5201 /* Create the SWITCH statements for ENDFINALLY instructions */
5202 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5203 BBInfo *info = &bblocks [bb->block_num];
5205 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5206 LLVMValueRef switch_ins = l->data;
5207 GSList *bb_list = info->call_handler_return_bbs;
5209 for (i = 0; i < g_slist_length (bb_list); ++i)
5210 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5214 if (cfg->verbose_level > 1)
5215 mono_llvm_dump_value (method);
5217 if (cfg->compile_aot)
5218 mark_as_used (ctx->lmodule, method);
5220 if (cfg->compile_aot) {
5221 LLVMValueRef md_args [16];
5222 LLVMValueRef md_node;
5225 method_index = mono_aot_get_method_index (cfg->orig_method);
5226 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5227 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5228 md_node = LLVMMDNode (md_args, 2);
5229 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5230 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5233 if (cfg->compile_aot) {
5234 /* Don't generate native code, keep the LLVM IR */
5235 if (cfg->compile_aot && cfg->verbose_level)
5236 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5238 //LLVMVerifyFunction(method, 0);
5240 //LLVMVerifyFunction(method, 0);
5241 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5243 if (cfg->verbose_level > 1)
5244 mono_llvm_dump_value (method);
5246 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5248 /* Set by emit_cb */
5249 g_assert (cfg->code_len);
5251 /* FIXME: Free the LLVM IL for the function */
5254 if (ctx->lmodule->method_to_lmethod)
5255 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5262 /* Need to add unused phi nodes as they can be referenced by other values */
5263 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5264 LLVMBuilderRef builder;
5266 builder = create_builder (ctx);
5267 LLVMPositionBuilderAtEnd (builder, phi_bb);
5269 for (i = 0; i < phi_values->len; ++i) {
5270 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5271 if (LLVMGetInstructionParent (v) == NULL)
5272 LLVMInsertIntoBuilder (builder, v);
5275 LLVMDeleteFunction (method);
5280 g_free (ctx->addresses);
5281 g_free (ctx->vreg_types);
5282 g_free (ctx->vreg_cli_types);
5283 g_free (ctx->pindexes);
5284 g_free (ctx->is_dead);
5285 g_free (ctx->unreachable);
5286 g_ptr_array_free (phi_values, TRUE);
5287 g_free (ctx->bblocks);
5288 g_hash_table_destroy (ctx->region_to_handler);
5289 g_hash_table_destroy (ctx->clause_to_handler);
5290 g_free (method_name);
5291 g_ptr_array_free (bblock_list, TRUE);
5293 for (l = ctx->builders; l; l = l->next) {
5294 LLVMBuilderRef builder = l->data;
5295 LLVMDisposeBuilder (builder);
5300 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5302 mono_loader_unlock ();
5306 * mono_llvm_emit_call:
5308 * Same as mono_arch_emit_call () for LLVM.
5311 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5314 MonoMethodSignature *sig;
5315 int i, n, stack_size;
5320 sig = call->signature;
5321 n = sig->param_count + sig->hasthis;
5323 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5325 if (cfg->disable_llvm)
5328 if (sig->call_convention == MONO_CALL_VARARG) {
5329 cfg->exception_message = g_strdup ("varargs");
5330 cfg->disable_llvm = TRUE;
5333 for (i = 0; i < n; ++i) {
5336 ainfo = call->cinfo->args + i;
5338 in = call->args [i];
5340 /* Simply remember the arguments */
5341 switch (ainfo->storage) {
5343 case LLVMArgInFPReg: {
5344 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5347 opcode = mono_type_to_regmove (cfg, t);
5348 if (opcode == OP_FMOVE) {
5349 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5350 ins->dreg = mono_alloc_freg (cfg);
5351 } else if (opcode == OP_LMOVE) {
5352 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5353 ins->dreg = mono_alloc_lreg (cfg);
5355 MONO_INST_NEW (cfg, ins, OP_MOVE);
5356 ins->dreg = mono_alloc_ireg (cfg);
5358 ins->sreg1 = in->dreg;
5361 case LLVMArgVtypeByVal:
5362 case LLVMArgVtypeInReg:
5363 case LLVMArgAsIArgs:
5364 case LLVMArgAsFpArgs:
5365 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5366 ins->dreg = mono_alloc_ireg (cfg);
5367 ins->sreg1 = in->dreg;
5368 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5371 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5372 cfg->exception_message = g_strdup ("ainfo->storage");
5373 cfg->disable_llvm = TRUE;
5377 if (!cfg->disable_llvm) {
5378 MONO_ADD_INS (cfg->cbb, ins);
5379 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5384 static unsigned char*
5385 alloc_cb (LLVMValueRef function, int size)
5389 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5393 return mono_domain_code_reserve (cfg->domain, size);
5395 return mono_domain_code_reserve (mono_domain_get (), size);
5400 emitted_cb (LLVMValueRef function, void *start, void *end)
5404 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5406 cfg->code_len = (guint8*)end - (guint8*)start;
5410 exception_cb (void *data)
5413 MonoJitExceptionInfo *ei;
5414 guint32 ei_len, i, j, nested_len, nindex;
5415 gpointer *type_info;
5416 int this_reg, this_offset;
5418 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5422 * data points to a DWARF FDE structure, convert it to our unwind format and
5424 * An alternative would be to save it directly, and modify our unwinder to work
5427 cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info, &this_reg, &this_offset);
5428 if (cfg->verbose_level > 1)
5429 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5431 /* Count nested clauses */
5433 for (i = 0; i < ei_len; ++i) {
5434 for (j = 0; j < ei_len; ++j) {
5435 gint32 cindex1 = *(gint32*)type_info [i];
5436 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5437 gint32 cindex2 = *(gint32*)type_info [j];
5438 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5440 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5446 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5447 cfg->llvm_ex_info_len = ei_len + nested_len;
5448 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5449 /* Fill the rest of the information from the type info */
5450 for (i = 0; i < ei_len; ++i) {
5451 gint32 clause_index = *(gint32*)type_info [i];
5452 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5454 cfg->llvm_ex_info [i].flags = clause->flags;
5455 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5456 cfg->llvm_ex_info [i].clause_index = clause_index;
5460 * For nested clauses, the LLVM produced exception info associates the try interval with
5461 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5462 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5463 * and everything else from the nested clause.
5466 for (i = 0; i < ei_len; ++i) {
5467 for (j = 0; j < ei_len; ++j) {
5468 gint32 cindex1 = *(gint32*)type_info [i];
5469 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5470 gint32 cindex2 = *(gint32*)type_info [j];
5471 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5473 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5474 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5475 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5476 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5477 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5478 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5483 g_assert (nindex == ei_len + nested_len);
5484 cfg->llvm_this_reg = this_reg;
5485 cfg->llvm_this_offset = this_offset;
5487 /* type_info [i] is cfg mempool allocated, no need to free it */
5494 dlsym_cb (const char *name, void **symbol)
5500 if (!strcmp (name, "__bzero")) {
5501 *symbol = (void*)bzero;
5503 current = mono_dl_open (NULL, 0, NULL);
5506 err = mono_dl_symbol (current, name, symbol);
5508 mono_dl_close (current);
5510 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5511 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5517 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5519 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5523 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5525 LLVMTypeRef param_types [4];
5527 param_types [0] = param_type1;
5528 param_types [1] = param_type2;
5530 AddFunc (module, name, ret_type, param_types, 2);
5534 add_intrinsics (LLVMModuleRef module)
5536 /* Emit declarations of instrinsics */
5538 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5539 * type doesn't seem to do any locking.
5542 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5544 memset_param_count = 5;
5545 memset_func_name = "llvm.memset.p0i8.i32";
5547 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5551 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5553 memcpy_param_count = 5;
5554 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5556 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5560 LLVMTypeRef params [] = { LLVMDoubleType () };
5562 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5563 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5564 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5566 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5567 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5571 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5572 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5573 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5575 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5576 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5577 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5578 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5579 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5580 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5581 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5585 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5586 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5587 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5589 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5590 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5591 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5592 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5593 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5594 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5599 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5601 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5604 /* SSE intrinsics */
5605 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5607 LLVMTypeRef ret_type, arg_types [16];
5610 ret_type = type_to_simd_type (MONO_TYPE_I4);
5611 arg_types [0] = ret_type;
5612 arg_types [1] = ret_type;
5613 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5614 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5616 ret_type = type_to_simd_type (MONO_TYPE_I2);
5617 arg_types [0] = ret_type;
5618 arg_types [1] = ret_type;
5619 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5620 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5621 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5622 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5623 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5624 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5625 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5626 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5627 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5628 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5630 ret_type = type_to_simd_type (MONO_TYPE_I1);
5631 arg_types [0] = ret_type;
5632 arg_types [1] = ret_type;
5633 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5639 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5641 ret_type = type_to_simd_type (MONO_TYPE_R8);
5642 arg_types [0] = ret_type;
5643 arg_types [1] = ret_type;
5644 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5645 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5647 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5648 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5650 ret_type = type_to_simd_type (MONO_TYPE_R4);
5651 arg_types [0] = ret_type;
5652 arg_types [1] = ret_type;
5653 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5654 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5655 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5656 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5657 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5660 ret_type = type_to_simd_type (MONO_TYPE_I1);
5661 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5662 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5663 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5664 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5665 ret_type = type_to_simd_type (MONO_TYPE_I2);
5666 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5667 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5668 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5669 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5672 ret_type = type_to_simd_type (MONO_TYPE_R8);
5673 arg_types [0] = ret_type;
5674 arg_types [1] = ret_type;
5675 arg_types [2] = LLVMInt8Type ();
5676 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5677 ret_type = type_to_simd_type (MONO_TYPE_R4);
5678 arg_types [0] = ret_type;
5679 arg_types [1] = ret_type;
5680 arg_types [2] = LLVMInt8Type ();
5681 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5683 /* Conversion ops */
5684 ret_type = type_to_simd_type (MONO_TYPE_R8);
5685 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5686 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5687 ret_type = type_to_simd_type (MONO_TYPE_R4);
5688 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5689 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5690 ret_type = type_to_simd_type (MONO_TYPE_I4);
5691 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5692 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5693 ret_type = type_to_simd_type (MONO_TYPE_I4);
5694 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5695 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5696 ret_type = type_to_simd_type (MONO_TYPE_R4);
5697 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5698 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5699 ret_type = type_to_simd_type (MONO_TYPE_R8);
5700 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5701 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5703 ret_type = type_to_simd_type (MONO_TYPE_I4);
5704 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5705 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5706 ret_type = type_to_simd_type (MONO_TYPE_I4);
5707 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5708 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5711 ret_type = type_to_simd_type (MONO_TYPE_R8);
5712 arg_types [0] = ret_type;
5713 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5714 ret_type = type_to_simd_type (MONO_TYPE_R4);
5715 arg_types [0] = ret_type;
5716 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5717 ret_type = type_to_simd_type (MONO_TYPE_R4);
5718 arg_types [0] = ret_type;
5719 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5720 ret_type = type_to_simd_type (MONO_TYPE_R4);
5721 arg_types [0] = ret_type;
5722 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5725 ret_type = type_to_simd_type (MONO_TYPE_I2);
5726 arg_types [0] = ret_type;
5727 arg_types [1] = LLVMInt32Type ();
5728 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5729 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5730 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5731 ret_type = type_to_simd_type (MONO_TYPE_I4);
5732 arg_types [0] = ret_type;
5733 arg_types [1] = LLVMInt32Type ();
5734 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5735 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5736 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5737 ret_type = type_to_simd_type (MONO_TYPE_I8);
5738 arg_types [0] = ret_type;
5739 arg_types [1] = LLVMInt32Type ();
5740 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5741 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5744 ret_type = LLVMInt32Type ();
5745 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5746 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5749 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5752 /* Load/Store intrinsics */
5754 LLVMTypeRef arg_types [5];
5758 for (i = 1; i <= 8; i *= 2) {
5759 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5760 arg_types [1] = LLVMInt32Type ();
5761 arg_types [2] = LLVMInt1Type ();
5762 arg_types [3] = LLVMInt32Type ();
5763 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5764 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5766 arg_types [0] = LLVMIntType (i * 8);
5767 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5768 arg_types [2] = LLVMInt32Type ();
5769 arg_types [3] = LLVMInt1Type ();
5770 arg_types [4] = LLVMInt32Type ();
5771 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5772 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5778 add_types (MonoLLVMModule *lmodule)
5780 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5784 mono_llvm_init (void)
5786 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5790 init_jit_module (MonoDomain *domain)
5792 MonoJitICallInfo *info;
5793 MonoJitDomainInfo *dinfo;
5794 MonoLLVMModule *module;
5797 dinfo = domain_jit_info (domain);
5798 if (dinfo->llvm_module)
5801 mono_loader_lock ();
5803 if (dinfo->llvm_module) {
5804 mono_loader_unlock ();
5808 module = g_new0 (MonoLLVMModule, 1);
5810 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5811 module->module = LLVMModuleCreateWithName (name);
5813 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5815 add_intrinsics (module->module);
5818 module->llvm_types = g_hash_table_new (NULL, NULL);
5820 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5822 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5824 mono_memory_barrier ();
5826 dinfo->llvm_module = module;
5828 mono_loader_unlock ();
5832 mono_llvm_cleanup (void)
5834 if (aot_module.module)
5835 LLVMDisposeModule (aot_module.module);
5837 LLVMContextDispose (LLVMGetGlobalContext ());
5841 mono_llvm_free_domain_info (MonoDomain *domain)
5843 MonoJitDomainInfo *info = domain_jit_info (domain);
5844 MonoLLVMModule *module = info->llvm_module;
5850 if (module->llvm_types)
5851 g_hash_table_destroy (module->llvm_types);
5853 mono_llvm_dispose_ee (module->mono_ee);
5855 if (module->bb_names) {
5856 for (i = 0; i < module->bb_names_len; ++i)
5857 g_free (module->bb_names [i]);
5858 g_free (module->bb_names);
5860 //LLVMDisposeModule (module->module);
5864 info->llvm_module = NULL;
5868 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5870 /* Delete previous module */
5871 if (aot_module.plt_entries)
5872 g_hash_table_destroy (aot_module.plt_entries);
5873 if (aot_module.module)
5874 LLVMDisposeModule (aot_module.module);
5876 memset (&aot_module, 0, sizeof (aot_module));
5878 aot_module.module = LLVMModuleCreateWithName ("aot");
5879 aot_module.got_symbol = got_symbol;
5880 aot_module.external_symbols = external_symbols;
5881 aot_module.emit_dwarf = emit_dwarf;
5882 /* The first few entries are reserved */
5883 aot_module.max_got_offset = 16;
5885 add_intrinsics (aot_module.module);
5886 add_types (&aot_module);
5890 * We couldn't compute the type of the LLVM global representing the got because
5891 * its size is only known after all the methods have been emitted. So create
5892 * a dummy variable, and replace all uses it with the real got variable when
5893 * its size is known in mono_llvm_emit_aot_module ().
5896 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5898 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5899 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5902 /* Add a dummy personality function */
5904 LLVMBasicBlockRef lbb;
5905 LLVMBuilderRef lbuilder;
5906 LLVMValueRef personality;
5908 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5909 LLVMSetLinkage (personality, LLVMInternalLinkage);
5910 lbb = LLVMAppendBasicBlock (personality, "BB0");
5911 lbuilder = LLVMCreateBuilder ();
5912 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5913 LLVMBuildRetVoid (lbuilder);
5914 mark_as_used (&aot_module, personality);
5917 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5918 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5919 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5920 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5924 * Emit the aot module into the LLVM bitcode file FILENAME.
5927 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5929 LLVMTypeRef got_type;
5930 LLVMValueRef real_got;
5931 MonoLLVMModule *module = &aot_module;
5934 * Create the real got variable and replace all uses of the dummy variable with
5937 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5938 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5939 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5940 if (module->external_symbols) {
5941 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5942 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5944 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5946 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5948 mark_as_used (&aot_module, real_got);
5950 /* Delete the dummy got so it doesn't become a global */
5951 LLVMDeleteGlobal (aot_module.got_var);
5953 emit_llvm_used (&aot_module);
5954 emit_dbg_info (&aot_module, filename, cu_name);
5956 /* Replace PLT entries for directly callable methods with the methods themselves */
5958 GHashTableIter iter;
5960 LLVMValueRef callee;
5962 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5963 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5964 if (mono_aot_is_direct_callable (ji)) {
5965 LLVMValueRef lmethod;
5967 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5968 /* The types might not match because the caller might pass an rgctx */
5969 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
5970 mono_llvm_replace_uses_of (callee, lmethod);
5971 mono_aot_mark_unused_llvm_plt_entry (ji);
5981 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5982 g_assert_not_reached ();
5987 LLVMWriteBitcodeToFile (aot_module.module, filename);
5992 md_string (const char *s)
5994 return LLVMMDString (s, strlen (s));
5997 /* Debugging support */
6000 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6002 LLVMModuleRef module = lmodule->module;
6003 LLVMValueRef args [16], cu_args [16], cu, ver;
6005 char *build_info, *s, *dir;
6008 * This can only be enabled when LLVM code is emitted into a separate object
6009 * file, since the AOT compiler also emits dwarf info,
6010 * and the abbrev indexes will not be correct since llvm has added its own
6013 if (!lmodule->emit_dwarf)
6017 * Emit dwarf info in the form of LLVM metadata. There is some
6018 * out-of-date documentation at:
6019 * http://llvm.org/docs/SourceLevelDebugging.html
6020 * but most of this was gathered from the llvm and
6025 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6026 /* CU name/compilation dir */
6027 dir = g_path_get_dirname (filename);
6028 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6029 args [1] = LLVMMDString (dir, strlen (dir));
6030 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6033 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6035 build_info = mono_get_runtime_build_info ();
6036 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6037 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6038 g_free (build_info);
6040 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6042 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6043 /* Runtime version */
6044 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6046 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6047 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6049 if (lmodule->subprogram_mds) {
6053 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6054 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6055 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6056 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6058 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6061 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6062 /* Imported modules */
6063 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6065 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6066 /* DebugEmissionKind = FullDebug */
6067 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6068 cu = LLVMMDNode (cu_args, n_cuargs);
6069 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6071 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6072 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6073 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6074 ver = LLVMMDNode (args, 3);
6075 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6077 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6078 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6079 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6080 ver = LLVMMDNode (args, 3);
6081 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6085 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6087 MonoLLVMModule *module = ctx->lmodule;
6088 MonoDebugMethodInfo *minfo = ctx->minfo;
6089 char *source_file, *dir, *filename;
6090 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6091 MonoSymSeqPoint *sym_seq_points;
6097 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6099 source_file = g_strdup ("<unknown>");
6100 dir = g_path_get_dirname (source_file);
6101 filename = g_path_get_basename (source_file);
6103 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6104 args [0] = md_string (filename);
6105 args [1] = md_string (dir);
6106 ctx_args [1] = LLVMMDNode (args, 2);
6107 ctx_md = LLVMMDNode (ctx_args, 2);
6109 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6110 type_args [1] = NULL;
6111 type_args [2] = NULL;
6112 type_args [3] = LLVMMDString ("", 0);
6113 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6114 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6115 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6116 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6117 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6118 type_args [9] = NULL;
6119 type_args [10] = NULL;
6120 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6121 type_args [12] = NULL;
6122 type_args [13] = NULL;
6123 type_args [14] = NULL;
6124 type_md = LLVMMDNode (type_args, 14);
6126 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6127 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6128 /* Source directory + file pair */
6129 args [0] = md_string (filename);
6130 args [1] = md_string (dir);
6131 md_args [1] = LLVMMDNode (args ,2);
6132 md_args [2] = ctx_md;
6133 md_args [3] = md_string (cfg->method->name);
6134 md_args [4] = md_string (name);
6135 md_args [5] = md_string (name);
6138 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6140 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6142 md_args [7] = type_md;
6144 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6146 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6148 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6149 /* Index into a virtual function */
6150 md_args [11] = NULL;
6151 md_args [12] = NULL;
6153 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6155 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6156 /* Pointer to LLVM function */
6157 md_args [15] = method;
6158 /* Function template parameter */
6159 md_args [16] = NULL;
6160 /* Function declaration descriptor */
6161 md_args [17] = NULL;
6162 /* List of function variables */
6163 md_args [18] = LLVMMDNode (args, 0);
6165 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6166 md = LLVMMDNode (md_args, 20);
6168 if (!module->subprogram_mds)
6169 module->subprogram_mds = g_ptr_array_new ();
6170 g_ptr_array_add (module->subprogram_mds, md);
6174 g_free (source_file);
6175 g_free (sym_seq_points);
6181 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6183 MonoCompile *cfg = ctx->cfg;
6185 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6186 MonoDebugSourceLocation *loc;
6187 LLVMValueRef loc_md, md_args [16];
6190 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6194 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6195 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6196 md_args [nmd_args ++] = ctx->dbg_md;
6197 md_args [nmd_args ++] = NULL;
6198 loc_md = LLVMMDNode (md_args, nmd_args);
6199 LLVMSetCurrentDebugLocation (builder, loc_md);
6200 mono_debug_symfile_free_location (loc);
6207 - Emit LLVM IR from the mono IR using the LLVM C API.
6208 - The original arch specific code remains, so we can fall back to it if we run
6209 into something we can't handle.
6213 A partial list of issues:
6214 - Handling of opcodes which can throw exceptions.
6216 In the mono JIT, these are implemented using code like this:
6223 push throw_pos - method
6224 call <exception trampoline>
6226 The problematic part is push throw_pos - method, which cannot be represented
6227 in the LLVM IR, since it does not support label values.
6228 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6229 be implemented in JIT mode ?
6230 -> a possible but slower implementation would use the normal exception
6231 throwing code but it would need to control the placement of the throw code
6232 (it needs to be exactly after the compare+branch).
6233 -> perhaps add a PC offset intrinsics ?
6235 - efficient implementation of .ovf opcodes.
6237 These are currently implemented as:
6238 <ins which sets the condition codes>
6241 Some overflow opcodes are now supported by LLVM SVN.
6243 - exception handling, unwinding.
6244 - SSA is disabled for methods with exception handlers
6245 - How to obtain unwind info for LLVM compiled methods ?
6246 -> this is now solved by converting the unwind info generated by LLVM
6248 - LLVM uses the c++ exception handling framework, while we use our home grown
6249 code, and couldn't use the c++ one:
6250 - its not supported under VC++, other exotic platforms.
6251 - it might be impossible to support filter clauses with it.
6255 The trampolines need a predictable call sequence, since they need to disasm
6256 the calling code to obtain register numbers / offsets.
6258 LLVM currently generates this code in non-JIT mode:
6259 mov -0x98(%rax),%eax
6261 Here, the vtable pointer is lost.
6262 -> solution: use one vtable trampoline per class.
6264 - passing/receiving the IMT pointer/RGCTX.
6265 -> solution: pass them as normal arguments ?
6269 LLVM does not allow the specification of argument registers etc. This means
6270 that all calls are made according to the platform ABI.
6272 - passing/receiving vtypes.
6274 Vtypes passed/received in registers are handled by the front end by using
6275 a signature with scalar arguments, and loading the parts of the vtype into those
6278 Vtypes passed on the stack are handled using the 'byval' attribute.
6282 Supported though alloca, we need to emit the load/store code.
6286 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6287 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6288 This is made easier because the IR is already in SSA form.
6289 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6290 types are frequently used incorrectly.
6295 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6296 it with the file containing the methods emitted by the JIT and the AOT data
6300 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6301 * - each bblock should end with a branch
6302 * - setting the return value, making cfg->ret non-volatile
6303 * - avoid some transformations in the JIT which make it harder for us to generate
6305 * - use pointer types to help optimizations.