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 || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
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 > 5000 && 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);
3683 case OP_GENERIC_CLASS_INIT: {
3684 static int byte_offset = -1;
3685 static guint8 bitmask;
3686 LLVMValueRef flags_load, cmp;
3687 MonoMethodSignature *sig;
3688 const char *icall_name;
3689 LLVMValueRef callee;
3690 LLVMBasicBlockRef init_bb, noinit_bb;
3692 if (byte_offset < 0)
3693 mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
3695 flags_load = emit_load (ctx, bb, &builder, 1, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type(), 0)), "", FALSE);
3696 set_metadata_flag (flags_load, "mono.nofail.load");
3697 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, flags_load, LLVMConstInt (LLVMInt8Type (), bitmask, 0), ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
3699 callee = ctx->lmodule->generic_class_init_tramp;
3701 icall_name = "specific_trampoline_generic_class_init";
3702 sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3703 sig->ret = &mono_get_void_class ()->byval_arg;
3704 sig->params [0] = &mono_get_int64_class ()->byval_arg;
3705 if (cfg->compile_aot) {
3706 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3708 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, sig));
3709 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3711 mono_memory_barrier ();
3712 ctx->lmodule->generic_class_init_tramp = callee;
3715 init_bb = gen_bb (ctx, "INIT_BB");
3716 noinit_bb = gen_bb (ctx, "NOINIT_BB");
3718 LLVMBuildCondBr (ctx->builder, cmp, noinit_bb, init_bb);
3720 builder = create_builder (ctx);
3721 ctx->builder = builder;
3722 LLVMPositionBuilderAtEnd (builder, init_bb);
3723 emit_call (ctx, bb, &builder, callee, &lhs, 1);
3724 LLVMBuildBr (builder, noinit_bb);
3726 builder = create_builder (ctx);
3727 ctx->builder = builder;
3728 LLVMPositionBuilderAtEnd (builder, noinit_bb);
3733 LLVMValueRef indexes [2];
3735 LLVMValueRef got_entry_addr;
3738 * FIXME: Can't allocate from the cfg mempool since that is freed if
3739 * the LLVM compile fails.
3741 ji = g_new0 (MonoJumpInfo, 1);
3742 ji->type = (MonoJumpInfoType)ins->inst_i1;
3743 ji->data.target = ins->inst_p0;
3745 ji = mono_aot_patch_info_dup (ji);
3747 ji->next = cfg->patch_info;
3748 cfg->patch_info = ji;
3750 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3751 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3752 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3754 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3755 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3756 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3758 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3759 set_invariant_load_flag (values [ins->dreg]);
3762 case OP_NOT_REACHED:
3763 LLVMBuildUnreachable (builder);
3764 has_terminator = TRUE;
3765 g_assert (bb->block_num < cfg->max_block_num);
3766 ctx->unreachable [bb->block_num] = TRUE;
3767 /* Might have instructions after this */
3769 MonoInst *next = ins->next;
3771 * FIXME: If later code uses the regs defined by these instructions,
3772 * compilation will fail.
3774 MONO_DELETE_INS (bb, next);
3778 MonoInst *var = ins->inst_p0;
3780 values [ins->dreg] = addresses [var->dreg];
3784 LLVMValueRef args [1];
3786 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3787 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3791 LLVMValueRef args [1];
3793 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3794 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3798 LLVMValueRef args [1];
3801 /* This no longer seems to happen */
3803 * LLVM optimizes sqrt(nan) into undefined in
3804 * lib/Analysis/ConstantFolding.cpp
3805 * Also, sqrt(NegativeInfinity) is optimized into 0.
3807 LLVM_FAILURE (ctx, "sqrt");
3809 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3810 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3814 LLVMValueRef args [1];
3816 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3817 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3831 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3832 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3834 switch (ins->opcode) {
3837 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3841 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3845 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3849 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3852 g_assert_not_reached ();
3855 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3858 case OP_ATOMIC_EXCHANGE_I4:
3859 case OP_ATOMIC_EXCHANGE_I8: {
3860 LLVMValueRef args [2];
3863 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3864 t = LLVMInt32Type ();
3866 t = LLVMInt64Type ();
3868 g_assert (ins->inst_offset == 0);
3870 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3871 args [1] = convert (ctx, rhs, t);
3873 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3876 case OP_ATOMIC_ADD_I4:
3877 case OP_ATOMIC_ADD_I8: {
3878 LLVMValueRef args [2];
3881 if (ins->opcode == OP_ATOMIC_ADD_I4)
3882 t = LLVMInt32Type ();
3884 t = LLVMInt64Type ();
3886 g_assert (ins->inst_offset == 0);
3888 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3889 args [1] = convert (ctx, rhs, t);
3890 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3893 case OP_ATOMIC_CAS_I4:
3894 case OP_ATOMIC_CAS_I8: {
3895 LLVMValueRef args [3], val;
3898 if (ins->opcode == OP_ATOMIC_CAS_I4)
3899 t = LLVMInt32Type ();
3901 t = LLVMInt64Type ();
3903 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3905 args [1] = convert (ctx, values [ins->sreg3], t);
3907 args [2] = convert (ctx, values [ins->sreg2], t);
3908 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3909 /* cmpxchg returns a pair */
3910 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3913 case OP_MEMORY_BARRIER: {
3914 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3917 case OP_ATOMIC_LOAD_I1:
3918 case OP_ATOMIC_LOAD_I2:
3919 case OP_ATOMIC_LOAD_I4:
3920 case OP_ATOMIC_LOAD_I8:
3921 case OP_ATOMIC_LOAD_U1:
3922 case OP_ATOMIC_LOAD_U2:
3923 case OP_ATOMIC_LOAD_U4:
3924 case OP_ATOMIC_LOAD_U8:
3925 case OP_ATOMIC_LOAD_R4:
3926 case OP_ATOMIC_LOAD_R8: {
3927 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3930 gboolean sext, zext;
3932 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3933 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3934 LLVMValueRef index, addr;
3936 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3941 if (ins->inst_offset != 0) {
3942 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3943 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3948 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3950 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3953 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3955 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3958 case OP_ATOMIC_STORE_I1:
3959 case OP_ATOMIC_STORE_I2:
3960 case OP_ATOMIC_STORE_I4:
3961 case OP_ATOMIC_STORE_I8:
3962 case OP_ATOMIC_STORE_U1:
3963 case OP_ATOMIC_STORE_U2:
3964 case OP_ATOMIC_STORE_U4:
3965 case OP_ATOMIC_STORE_U8:
3966 case OP_ATOMIC_STORE_R4:
3967 case OP_ATOMIC_STORE_R8: {
3968 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3971 gboolean sext, zext;
3973 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3974 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3975 LLVMValueRef index, addr, value;
3977 if (!values [ins->inst_destbasereg])
3978 LLVM_FAILURE (ctx, "inst_destbasereg");
3980 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3982 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3983 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3984 value = convert (ctx, values [ins->sreg1], t);
3986 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3989 case OP_RELAXED_NOP: {
3990 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3991 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3998 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
4000 // 257 == FS segment register
4001 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
4003 // 256 == GS segment register
4004 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4007 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
4008 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
4009 /* See mono_amd64_emit_tls_get () */
4010 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
4012 // 256 == GS segment register
4013 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4014 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
4016 LLVM_FAILURE (ctx, "opcode tls-get");
4021 case OP_TLS_GET_REG: {
4022 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
4023 /* See emit_tls_get_reg () */
4024 // 256 == GS segment register
4025 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
4026 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
4028 LLVM_FAILURE (ctx, "opcode tls-get");
4037 case OP_IADD_OVF_UN:
4039 case OP_ISUB_OVF_UN:
4041 case OP_IMUL_OVF_UN:
4042 #if SIZEOF_VOID_P == 8
4044 case OP_LADD_OVF_UN:
4046 case OP_LSUB_OVF_UN:
4048 case OP_LMUL_OVF_UN:
4051 LLVMValueRef args [2], val, ovf, func;
4053 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4054 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4055 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4057 val = LLVMBuildCall (builder, func, args, 2, "");
4058 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4059 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4060 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4061 CHECK_FAILURE (ctx);
4062 builder = ctx->builder;
4068 * We currently model them using arrays. Promotion to local vregs is
4069 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4070 * so we always have an entry in cfg->varinfo for them.
4071 * FIXME: Is this needed ?
4074 MonoClass *klass = ins->klass;
4075 LLVMValueRef args [5];
4079 LLVM_FAILURE (ctx, "!klass");
4083 if (!addresses [ins->dreg])
4084 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4085 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4086 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4087 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4089 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4090 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4091 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4094 case OP_DUMMY_VZERO:
4097 case OP_STOREV_MEMBASE:
4098 case OP_LOADV_MEMBASE:
4100 MonoClass *klass = ins->klass;
4101 LLVMValueRef src = NULL, dst, args [5];
4102 gboolean done = FALSE;
4106 LLVM_FAILURE (ctx, "!klass");
4110 if (mini_is_gsharedvt_klass (cfg, klass)) {
4112 LLVM_FAILURE (ctx, "gsharedvt");
4116 switch (ins->opcode) {
4117 case OP_STOREV_MEMBASE:
4118 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4119 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4120 /* Decomposed earlier */
4121 g_assert_not_reached ();
4124 if (!addresses [ins->sreg1]) {
4126 g_assert (values [ins->sreg1]);
4127 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));
4128 LLVMBuildStore (builder, values [ins->sreg1], dst);
4131 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4132 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4135 case OP_LOADV_MEMBASE:
4136 if (!addresses [ins->dreg])
4137 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4138 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4139 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4142 if (!addresses [ins->sreg1])
4143 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4144 if (!addresses [ins->dreg])
4145 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4146 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4147 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4150 g_assert_not_reached ();
4152 CHECK_FAILURE (ctx);
4159 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4160 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4162 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4163 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4164 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4167 case OP_LLVM_OUTARG_VT:
4168 if (!addresses [ins->sreg1]) {
4169 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4170 g_assert (values [ins->sreg1]);
4171 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4173 addresses [ins->dreg] = addresses [ins->sreg1];
4179 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4181 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4184 case OP_LOADX_MEMBASE: {
4185 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4188 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4189 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4192 case OP_STOREX_MEMBASE: {
4193 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4196 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4197 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4204 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4208 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4214 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4218 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4222 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4226 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4229 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4232 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4235 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4239 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4250 LLVMValueRef v = NULL;
4252 switch (ins->opcode) {
4257 t = LLVMVectorType (LLVMInt32Type (), 4);
4258 rt = LLVMVectorType (LLVMFloatType (), 4);
4264 t = LLVMVectorType (LLVMInt64Type (), 2);
4265 rt = LLVMVectorType (LLVMDoubleType (), 2);
4268 t = LLVMInt32Type ();
4269 rt = LLVMInt32Type ();
4270 g_assert_not_reached ();
4273 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4274 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4275 switch (ins->opcode) {
4278 v = LLVMBuildAnd (builder, lhs, rhs, "");
4282 v = LLVMBuildOr (builder, lhs, rhs, "");
4286 v = LLVMBuildXor (builder, lhs, rhs, "");
4290 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4293 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4317 case OP_PADDB_SAT_UN:
4318 case OP_PADDW_SAT_UN:
4319 case OP_PSUBB_SAT_UN:
4320 case OP_PSUBW_SAT_UN:
4328 case OP_PMULW_HIGH_UN: {
4329 LLVMValueRef args [2];
4334 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4341 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4345 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4353 case OP_EXTRACTX_U2:
4355 case OP_EXTRACT_U1: {
4357 gboolean zext = FALSE;
4359 t = simd_op_to_llvm_type (ins->opcode);
4361 switch (ins->opcode) {
4369 case OP_EXTRACTX_U2:
4374 t = LLVMInt32Type ();
4375 g_assert_not_reached ();
4378 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4379 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4381 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4390 case OP_EXPAND_R8: {
4391 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4392 LLVMValueRef mask [16], v;
4395 for (i = 0; i < 16; ++i)
4396 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4398 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4400 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4401 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4406 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4409 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4412 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4415 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4418 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4421 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4432 case OP_EXTRACT_MASK:
4439 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4441 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4447 LLVMValueRef args [3];
4451 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4453 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4458 /* This is only used for implementing shifts by non-immediate */
4459 values [ins->dreg] = lhs;
4470 LLVMValueRef args [3];
4473 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4475 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4486 case OP_PSHLQ_REG: {
4487 LLVMValueRef args [3];
4490 args [1] = values [ins->sreg2];
4492 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4499 case OP_PSHUFLEW_LOW:
4500 case OP_PSHUFLEW_HIGH: {
4502 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4503 int i, mask_size = 0;
4504 int imask = ins->inst_c0;
4506 /* Convert the x86 shuffle mask to LLVM's */
4507 switch (ins->opcode) {
4510 mask [0] = ((imask >> 0) & 3);
4511 mask [1] = ((imask >> 2) & 3);
4512 mask [2] = ((imask >> 4) & 3) + 4;
4513 mask [3] = ((imask >> 6) & 3) + 4;
4514 v1 = values [ins->sreg1];
4515 v2 = values [ins->sreg2];
4519 mask [0] = ((imask >> 0) & 1);
4520 mask [1] = ((imask >> 1) & 1) + 2;
4521 v1 = values [ins->sreg1];
4522 v2 = values [ins->sreg2];
4524 case OP_PSHUFLEW_LOW:
4526 mask [0] = ((imask >> 0) & 3);
4527 mask [1] = ((imask >> 2) & 3);
4528 mask [2] = ((imask >> 4) & 3);
4529 mask [3] = ((imask >> 6) & 3);
4534 v1 = values [ins->sreg1];
4535 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4537 case OP_PSHUFLEW_HIGH:
4543 mask [4] = 4 + ((imask >> 0) & 3);
4544 mask [5] = 4 + ((imask >> 2) & 3);
4545 mask [6] = 4 + ((imask >> 4) & 3);
4546 mask [7] = 4 + ((imask >> 6) & 3);
4547 v1 = values [ins->sreg1];
4548 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4552 mask [0] = ((imask >> 0) & 3);
4553 mask [1] = ((imask >> 2) & 3);
4554 mask [2] = ((imask >> 4) & 3);
4555 mask [3] = ((imask >> 6) & 3);
4556 v1 = values [ins->sreg1];
4557 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4560 g_assert_not_reached ();
4562 for (i = 0; i < mask_size; ++i)
4563 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4565 values [ins->dreg] =
4566 LLVMBuildShuffleVector (builder, v1, v2,
4567 LLVMConstVector (mask_values, mask_size), dname);
4571 case OP_UNPACK_LOWB:
4572 case OP_UNPACK_LOWW:
4573 case OP_UNPACK_LOWD:
4574 case OP_UNPACK_LOWQ:
4575 case OP_UNPACK_LOWPS:
4576 case OP_UNPACK_LOWPD:
4577 case OP_UNPACK_HIGHB:
4578 case OP_UNPACK_HIGHW:
4579 case OP_UNPACK_HIGHD:
4580 case OP_UNPACK_HIGHQ:
4581 case OP_UNPACK_HIGHPS:
4582 case OP_UNPACK_HIGHPD: {
4584 LLVMValueRef mask_values [16];
4585 int i, mask_size = 0;
4586 gboolean low = FALSE;
4588 switch (ins->opcode) {
4589 case OP_UNPACK_LOWB:
4593 case OP_UNPACK_LOWW:
4597 case OP_UNPACK_LOWD:
4598 case OP_UNPACK_LOWPS:
4602 case OP_UNPACK_LOWQ:
4603 case OP_UNPACK_LOWPD:
4607 case OP_UNPACK_HIGHB:
4610 case OP_UNPACK_HIGHW:
4613 case OP_UNPACK_HIGHD:
4614 case OP_UNPACK_HIGHPS:
4617 case OP_UNPACK_HIGHQ:
4618 case OP_UNPACK_HIGHPD:
4622 g_assert_not_reached ();
4626 for (i = 0; i < (mask_size / 2); ++i) {
4628 mask [(i * 2) + 1] = mask_size + i;
4631 for (i = 0; i < (mask_size / 2); ++i) {
4632 mask [(i * 2)] = (mask_size / 2) + i;
4633 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4637 for (i = 0; i < mask_size; ++i)
4638 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4640 values [ins->dreg] =
4641 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4642 LLVMConstVector (mask_values, mask_size), dname);
4647 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4648 LLVMValueRef v, val;
4650 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4651 val = LLVMConstNull (t);
4652 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4653 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4655 values [ins->dreg] = val;
4659 case OP_DUPPS_HIGH: {
4660 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4661 LLVMValueRef v1, v2, val;
4664 if (ins->opcode == OP_DUPPS_LOW) {
4665 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4666 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4668 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4669 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4671 val = LLVMConstNull (t);
4672 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4673 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4674 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4675 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4677 values [ins->dreg] = val;
4687 * EXCEPTION HANDLING
4689 case OP_IMPLICIT_EXCEPTION:
4690 /* This marks a place where an implicit exception can happen */
4691 if (bb->region != -1)
4692 LLVM_FAILURE (ctx, "implicit-exception");
4696 MonoMethodSignature *throw_sig;
4697 LLVMValueRef callee, arg;
4698 gboolean rethrow = (ins->opcode == OP_RETHROW);
4699 const char *icall_name;
4701 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4702 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4705 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4706 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4707 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4708 if (cfg->compile_aot) {
4709 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4711 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4715 * LLVM doesn't push the exception argument, so we need a different
4718 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4720 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4724 mono_memory_barrier ();
4726 ctx->lmodule->rethrow = callee;
4728 ctx->lmodule->throw = callee;
4730 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4731 emit_call (ctx, bb, &builder, callee, &arg, 1);
4734 case OP_CALL_HANDLER: {
4736 * We don't 'call' handlers, but instead simply branch to them.
4737 * The code generated by ENDFINALLY will branch back to us.
4739 LLVMBasicBlockRef noex_bb;
4741 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4743 bb_list = info->call_handler_return_bbs;
4746 * Set the indicator variable for the finally clause.
4748 lhs = info->finally_ind;
4750 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4752 /* Branch to the finally clause */
4753 LLVMBuildBr (builder, info->call_handler_target_bb);
4755 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4756 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4758 builder = ctx->builder = create_builder (ctx);
4759 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4761 bblocks [bb->block_num].end_bblock = noex_bb;
4764 case OP_START_HANDLER: {
4767 case OP_ENDFINALLY: {
4768 LLVMBasicBlockRef resume_bb;
4769 MonoBasicBlock *handler_bb;
4770 LLVMValueRef val, switch_ins, callee;
4774 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4775 g_assert (handler_bb);
4776 info = &bblocks [handler_bb->block_num];
4777 lhs = info->finally_ind;
4780 bb_list = info->call_handler_return_bbs;
4782 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4784 /* Load the finally variable */
4785 val = LLVMBuildLoad (builder, lhs, "");
4787 /* Reset the variable */
4788 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4790 /* Branch to either resume_bb, or to the bblocks in bb_list */
4791 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4793 * The other targets are added at the end to handle OP_CALL_HANDLER
4794 * opcodes processed later.
4796 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4798 builder = ctx->builder = create_builder (ctx);
4799 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4801 if (ctx->cfg->compile_aot) {
4802 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4804 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4806 LLVMBuildCall (builder, callee, NULL, 0, "");
4808 LLVMBuildUnreachable (builder);
4809 has_terminator = TRUE;
4815 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4816 LLVM_FAILURE (ctx, reason);
4821 /* Convert the value to the type required by phi nodes */
4822 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4823 if (!values [ins->dreg])
4825 values [ins->dreg] = addresses [ins->dreg];
4827 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4830 /* Add stores for volatile variables */
4831 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4832 emit_volatile_store (ctx, ins->dreg);
4835 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4836 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4838 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4839 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4840 LLVMBuildRetVoid (builder);
4843 if (bb == cfg->bb_entry)
4844 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4853 * mono_llvm_check_method_supported:
4855 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4856 * compiling a method twice.
4859 mono_llvm_check_method_supported (MonoCompile *cfg)
4863 if (cfg->method->save_lmf) {
4864 cfg->exception_message = g_strdup ("lmf");
4865 cfg->disable_llvm = TRUE;
4867 if (cfg->disable_llvm)
4871 * Nested clauses where one of the clauses is a finally clause is
4872 * not supported, because LLVM can't figure out the control flow,
4873 * probably because we resume exception handling by calling our
4874 * own function instead of using the 'resume' llvm instruction.
4876 for (i = 0; i < cfg->header->num_clauses; ++i) {
4877 for (j = 0; j < cfg->header->num_clauses; ++j) {
4878 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4879 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4881 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4882 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4883 cfg->exception_message = g_strdup ("nested clauses");
4884 cfg->disable_llvm = TRUE;
4889 if (cfg->disable_llvm)
4893 if (cfg->method->dynamic) {
4894 cfg->exception_message = g_strdup ("dynamic.");
4895 cfg->disable_llvm = TRUE;
4897 if (cfg->disable_llvm)
4902 * mono_llvm_emit_method:
4904 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4907 mono_llvm_emit_method (MonoCompile *cfg)
4910 MonoMethodSignature *sig;
4912 LLVMTypeRef method_type;
4913 LLVMValueRef method = NULL;
4915 LLVMValueRef *values;
4916 int i, max_block_num, bb_index;
4917 gboolean last = FALSE;
4918 GPtrArray *phi_values;
4919 LLVMCallInfo *linfo;
4921 LLVMModuleRef module;
4923 GPtrArray *bblock_list;
4924 MonoMethodHeader *header;
4925 MonoExceptionClause *clause;
4929 /* The code below might acquire the loader lock, so use it for global locking */
4930 mono_loader_lock ();
4932 /* Used to communicate with the callbacks */
4933 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4935 ctx = g_new0 (EmitContext, 1);
4937 ctx->mempool = cfg->mempool;
4940 * This maps vregs to the LLVM instruction defining them
4942 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4944 * This maps vregs for volatile variables to the LLVM instruction defining their
4947 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4948 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4949 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4950 phi_values = g_ptr_array_sized_new (256);
4952 * This signals whenever the vreg was defined by a phi node with no input vars
4953 * (i.e. all its input bblocks end with NOT_REACHABLE).
4955 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4956 /* Whenever the bblock is unreachable */
4957 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4959 bblock_list = g_ptr_array_sized_new (256);
4961 ctx->values = values;
4962 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4963 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4965 if (cfg->compile_aot) {
4966 ctx->lmodule = &aot_module;
4967 method_name = mono_aot_get_method_name (cfg);
4968 cfg->llvm_method_name = g_strdup (method_name);
4970 init_jit_module (cfg->domain);
4971 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4972 method_name = mono_method_full_name (cfg->method, TRUE);
4975 module = ctx->module = ctx->lmodule->module;
4978 LLVM_FAILURE (ctx, "gsharedvt");
4982 static int count = 0;
4985 if (g_getenv ("LLVM_COUNT")) {
4986 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4987 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4991 if (count > atoi (g_getenv ("LLVM_COUNT")))
4992 LLVM_FAILURE (ctx, "");
4997 sig = mono_method_signature (cfg->method);
5000 linfo = mono_arch_get_llvm_call_info (cfg, sig);
5002 CHECK_FAILURE (ctx);
5005 linfo->rgctx_arg = TRUE;
5006 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
5007 CHECK_FAILURE (ctx);
5010 * This maps parameter indexes in the original signature to the indexes in
5011 * the LLVM signature.
5013 ctx->pindexes = sinfo.pindexes;
5015 method = LLVMAddFunction (module, method_name, method_type);
5016 ctx->lmethod = method;
5018 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
5019 LLVMSetLinkage (method, LLVMPrivateLinkage);
5021 LLVMAddFunctionAttr (method, LLVMUWTable);
5023 if (cfg->compile_aot) {
5024 LLVMSetLinkage (method, LLVMInternalLinkage);
5025 if (ctx->lmodule->external_symbols) {
5026 LLVMSetLinkage (method, LLVMExternalLinkage);
5027 LLVMSetVisibility (method, LLVMHiddenVisibility);
5030 LLVMSetLinkage (method, LLVMPrivateLinkage);
5033 if (cfg->method->save_lmf)
5034 LLVM_FAILURE (ctx, "lmf");
5036 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
5037 LLVM_FAILURE (ctx, "pinvoke signature");
5039 header = cfg->header;
5040 for (i = 0; i < header->num_clauses; ++i) {
5041 clause = &header->clauses [i];
5042 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5043 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5045 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5046 /* We can't handle inlined methods with clauses */
5047 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5049 if (linfo->rgctx_arg) {
5050 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5052 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5053 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5054 * CC_X86_64_Mono in X86CallingConv.td.
5056 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5057 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5059 if (cfg->vret_addr) {
5060 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5061 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5064 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5065 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5068 names = g_new (char *, sig->param_count);
5069 mono_method_get_param_names (cfg->method, (const char **) names);
5071 for (i = 0; i < sig->param_count; ++i) {
5074 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5075 if (names [i] && names [i][0] != '\0')
5076 name = g_strdup_printf ("arg_%s", names [i]);
5078 name = g_strdup_printf ("arg_%d", i);
5079 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5081 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5082 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5086 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5087 ctx->minfo = mono_debug_lookup_method (cfg->method);
5088 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5093 max_block_num = MAX (max_block_num, bb->block_num);
5094 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5096 /* Add branches between non-consecutive bblocks */
5097 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5098 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5099 bb->next_bb != bb->last_ins->inst_false_bb) {
5101 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5102 inst->opcode = OP_BR;
5103 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5104 mono_bblock_add_inst (bb, inst);
5109 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5110 * was later optimized away, so clear these flags, and add them back for the still
5111 * present OP_LDADDR instructions.
5113 for (i = 0; i < cfg->next_vreg; ++i) {
5116 ins = get_vreg_to_inst (cfg, i);
5117 if (ins && ins != cfg->rgctx_var)
5118 ins->flags &= ~MONO_INST_INDIRECT;
5122 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5124 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5126 LLVMBuilderRef builder;
5128 char dname_buf[128];
5130 builder = create_builder (ctx);
5132 for (ins = bb->code; ins; ins = ins->next) {
5133 switch (ins->opcode) {
5138 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5140 CHECK_FAILURE (ctx);
5142 if (ins->opcode == OP_VPHI) {
5143 /* Treat valuetype PHI nodes as operating on the address itself */
5144 g_assert (ins->klass);
5145 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5149 * Have to precreate these, as they can be referenced by
5150 * earlier instructions.
5152 sprintf (dname_buf, "t%d", ins->dreg);
5154 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5156 if (ins->opcode == OP_VPHI)
5157 ctx->addresses [ins->dreg] = values [ins->dreg];
5159 g_ptr_array_add (phi_values, values [ins->dreg]);
5162 * Set the expected type of the incoming arguments since these have
5163 * to have the same type.
5165 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5166 int sreg1 = ins->inst_phi_args [i + 1];
5169 ctx->vreg_types [sreg1] = phi_type;
5174 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5183 * Create an ordering for bblocks, use the depth first order first, then
5184 * put the exception handling bblocks last.
5186 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5187 bb = cfg->bblocks [bb_index];
5188 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5189 g_ptr_array_add (bblock_list, bb);
5190 bblocks [bb->block_num].added = TRUE;
5194 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5195 if (!bblocks [bb->block_num].added)
5196 g_ptr_array_add (bblock_list, bb);
5200 * Second pass: generate code.
5202 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5203 bb = g_ptr_array_index (bblock_list, bb_index);
5205 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5208 process_bb (ctx, bb);
5209 CHECK_FAILURE (ctx);
5212 /* Add incoming phi values */
5213 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5214 GSList *l, *ins_list;
5216 ins_list = bblocks [bb->block_num].phi_nodes;
5218 for (l = ins_list; l; l = l->next) {
5219 PhiNode *node = l->data;
5220 MonoInst *phi = node->phi;
5221 int sreg1 = node->sreg;
5222 LLVMBasicBlockRef in_bb;
5227 in_bb = get_end_bb (ctx, node->in_bb);
5229 if (ctx->unreachable [node->in_bb->block_num])
5232 if (!values [sreg1])
5233 /* Can happen with values in EH clauses */
5234 LLVM_FAILURE (ctx, "incoming phi sreg1");
5236 if (phi->opcode == OP_VPHI) {
5237 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5238 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5240 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5242 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5243 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5244 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5249 /* Create the SWITCH statements for ENDFINALLY instructions */
5250 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5251 BBInfo *info = &bblocks [bb->block_num];
5253 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5254 LLVMValueRef switch_ins = l->data;
5255 GSList *bb_list = info->call_handler_return_bbs;
5257 for (i = 0; i < g_slist_length (bb_list); ++i)
5258 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5262 if (cfg->verbose_level > 1)
5263 mono_llvm_dump_value (method);
5265 if (cfg->compile_aot)
5266 mark_as_used (ctx->lmodule, method);
5268 if (cfg->compile_aot) {
5269 LLVMValueRef md_args [16];
5270 LLVMValueRef md_node;
5273 method_index = mono_aot_get_method_index (cfg->orig_method);
5274 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5275 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5276 md_node = LLVMMDNode (md_args, 2);
5277 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5278 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5281 if (cfg->compile_aot) {
5282 /* Don't generate native code, keep the LLVM IR */
5283 if (cfg->compile_aot && cfg->verbose_level)
5284 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5286 //LLVMVerifyFunction(method, 0);
5288 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5290 if (cfg->verbose_level > 1)
5291 mono_llvm_dump_value (method);
5293 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5295 /* Set by emit_cb */
5296 g_assert (cfg->code_len);
5298 /* FIXME: Free the LLVM IL for the function */
5301 if (ctx->lmodule->method_to_lmethod)
5302 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5309 /* Need to add unused phi nodes as they can be referenced by other values */
5310 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5311 LLVMBuilderRef builder;
5313 builder = create_builder (ctx);
5314 LLVMPositionBuilderAtEnd (builder, phi_bb);
5316 for (i = 0; i < phi_values->len; ++i) {
5317 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5318 if (LLVMGetInstructionParent (v) == NULL)
5319 LLVMInsertIntoBuilder (builder, v);
5322 LLVMDeleteFunction (method);
5327 g_free (ctx->addresses);
5328 g_free (ctx->vreg_types);
5329 g_free (ctx->vreg_cli_types);
5330 g_free (ctx->pindexes);
5331 g_free (ctx->is_dead);
5332 g_free (ctx->unreachable);
5333 g_ptr_array_free (phi_values, TRUE);
5334 g_free (ctx->bblocks);
5335 g_hash_table_destroy (ctx->region_to_handler);
5336 g_hash_table_destroy (ctx->clause_to_handler);
5337 g_free (method_name);
5338 g_ptr_array_free (bblock_list, TRUE);
5340 for (l = ctx->builders; l; l = l->next) {
5341 LLVMBuilderRef builder = l->data;
5342 LLVMDisposeBuilder (builder);
5347 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5349 mono_loader_unlock ();
5353 * mono_llvm_emit_call:
5355 * Same as mono_arch_emit_call () for LLVM.
5358 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5361 MonoMethodSignature *sig;
5362 int i, n, stack_size;
5367 sig = call->signature;
5368 n = sig->param_count + sig->hasthis;
5370 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5372 if (cfg->disable_llvm)
5375 if (sig->call_convention == MONO_CALL_VARARG) {
5376 cfg->exception_message = g_strdup ("varargs");
5377 cfg->disable_llvm = TRUE;
5380 for (i = 0; i < n; ++i) {
5383 ainfo = call->cinfo->args + i;
5385 in = call->args [i];
5387 /* Simply remember the arguments */
5388 switch (ainfo->storage) {
5390 case LLVMArgInFPReg: {
5391 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5394 opcode = mono_type_to_regmove (cfg, t);
5395 if (opcode == OP_FMOVE) {
5396 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5397 ins->dreg = mono_alloc_freg (cfg);
5398 } else if (opcode == OP_LMOVE) {
5399 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5400 ins->dreg = mono_alloc_lreg (cfg);
5402 MONO_INST_NEW (cfg, ins, OP_MOVE);
5403 ins->dreg = mono_alloc_ireg (cfg);
5405 ins->sreg1 = in->dreg;
5408 case LLVMArgVtypeByVal:
5409 case LLVMArgVtypeInReg:
5410 case LLVMArgAsIArgs:
5411 case LLVMArgAsFpArgs:
5412 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5413 ins->dreg = mono_alloc_ireg (cfg);
5414 ins->sreg1 = in->dreg;
5415 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5418 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5419 cfg->exception_message = g_strdup ("ainfo->storage");
5420 cfg->disable_llvm = TRUE;
5424 if (!cfg->disable_llvm) {
5425 MONO_ADD_INS (cfg->cbb, ins);
5426 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5431 static unsigned char*
5432 alloc_cb (LLVMValueRef function, int size)
5436 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5440 return mono_domain_code_reserve (cfg->domain, size);
5442 return mono_domain_code_reserve (mono_domain_get (), size);
5447 emitted_cb (LLVMValueRef function, void *start, void *end)
5451 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5453 cfg->code_len = (guint8*)end - (guint8*)start;
5457 exception_cb (void *data)
5460 MonoJitExceptionInfo *ei;
5461 guint32 ei_len, i, j, nested_len, nindex;
5462 gpointer *type_info;
5463 int this_reg, this_offset;
5465 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5469 * data points to a DWARF FDE structure, convert it to our unwind format and
5471 * An alternative would be to save it directly, and modify our unwinder to work
5474 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);
5475 if (cfg->verbose_level > 1)
5476 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5478 /* Count nested clauses */
5480 for (i = 0; i < ei_len; ++i) {
5481 for (j = 0; j < ei_len; ++j) {
5482 gint32 cindex1 = *(gint32*)type_info [i];
5483 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5484 gint32 cindex2 = *(gint32*)type_info [j];
5485 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5487 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5493 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5494 cfg->llvm_ex_info_len = ei_len + nested_len;
5495 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5496 /* Fill the rest of the information from the type info */
5497 for (i = 0; i < ei_len; ++i) {
5498 gint32 clause_index = *(gint32*)type_info [i];
5499 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5501 cfg->llvm_ex_info [i].flags = clause->flags;
5502 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5503 cfg->llvm_ex_info [i].clause_index = clause_index;
5507 * For nested clauses, the LLVM produced exception info associates the try interval with
5508 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5509 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5510 * and everything else from the nested clause.
5513 for (i = 0; i < ei_len; ++i) {
5514 for (j = 0; j < ei_len; ++j) {
5515 gint32 cindex1 = *(gint32*)type_info [i];
5516 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5517 gint32 cindex2 = *(gint32*)type_info [j];
5518 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5520 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5521 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5522 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5523 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5524 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5525 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5530 g_assert (nindex == ei_len + nested_len);
5531 cfg->llvm_this_reg = this_reg;
5532 cfg->llvm_this_offset = this_offset;
5534 /* type_info [i] is cfg mempool allocated, no need to free it */
5541 dlsym_cb (const char *name, void **symbol)
5547 if (!strcmp (name, "__bzero")) {
5548 *symbol = (void*)bzero;
5550 current = mono_dl_open (NULL, 0, NULL);
5553 err = mono_dl_symbol (current, name, symbol);
5555 mono_dl_close (current);
5557 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5558 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5564 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5566 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5570 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5572 LLVMTypeRef param_types [4];
5574 param_types [0] = param_type1;
5575 param_types [1] = param_type2;
5577 AddFunc (module, name, ret_type, param_types, 2);
5581 add_intrinsics (LLVMModuleRef module)
5583 /* Emit declarations of instrinsics */
5585 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5586 * type doesn't seem to do any locking.
5589 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5591 memset_param_count = 5;
5592 memset_func_name = "llvm.memset.p0i8.i32";
5594 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
5598 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5600 memcpy_param_count = 5;
5601 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5603 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
5607 LLVMTypeRef params [] = { LLVMDoubleType () };
5609 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
5610 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
5611 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
5613 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5614 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
5618 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5619 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
5620 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
5622 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5623 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
5624 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
5625 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
5626 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
5627 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
5628 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
5632 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5633 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
5634 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
5636 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
5637 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
5638 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
5639 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
5640 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
5641 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
5646 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
5648 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
5651 /* SSE intrinsics */
5652 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5654 LLVMTypeRef ret_type, arg_types [16];
5657 ret_type = type_to_simd_type (MONO_TYPE_I4);
5658 arg_types [0] = ret_type;
5659 arg_types [1] = ret_type;
5660 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5661 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5663 ret_type = type_to_simd_type (MONO_TYPE_I2);
5664 arg_types [0] = ret_type;
5665 arg_types [1] = ret_type;
5666 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5667 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5668 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5669 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5670 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5671 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5672 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5673 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5674 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5675 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5677 ret_type = type_to_simd_type (MONO_TYPE_I1);
5678 arg_types [0] = ret_type;
5679 arg_types [1] = ret_type;
5680 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5681 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5682 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5683 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5684 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5685 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5686 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5688 ret_type = type_to_simd_type (MONO_TYPE_R8);
5689 arg_types [0] = ret_type;
5690 arg_types [1] = ret_type;
5691 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5692 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5693 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5694 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5695 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5697 ret_type = type_to_simd_type (MONO_TYPE_R4);
5698 arg_types [0] = ret_type;
5699 arg_types [1] = ret_type;
5700 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5701 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5702 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5703 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5704 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5707 ret_type = type_to_simd_type (MONO_TYPE_I1);
5708 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5709 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5710 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5711 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5712 ret_type = type_to_simd_type (MONO_TYPE_I2);
5713 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5714 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5715 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5716 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5719 ret_type = type_to_simd_type (MONO_TYPE_R8);
5720 arg_types [0] = ret_type;
5721 arg_types [1] = ret_type;
5722 arg_types [2] = LLVMInt8Type ();
5723 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5724 ret_type = type_to_simd_type (MONO_TYPE_R4);
5725 arg_types [0] = ret_type;
5726 arg_types [1] = ret_type;
5727 arg_types [2] = LLVMInt8Type ();
5728 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5730 /* Conversion ops */
5731 ret_type = type_to_simd_type (MONO_TYPE_R8);
5732 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5733 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5734 ret_type = type_to_simd_type (MONO_TYPE_R4);
5735 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5736 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5737 ret_type = type_to_simd_type (MONO_TYPE_I4);
5738 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5739 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5740 ret_type = type_to_simd_type (MONO_TYPE_I4);
5741 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5742 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5743 ret_type = type_to_simd_type (MONO_TYPE_R4);
5744 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5745 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5746 ret_type = type_to_simd_type (MONO_TYPE_R8);
5747 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5748 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5750 ret_type = type_to_simd_type (MONO_TYPE_I4);
5751 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5752 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5753 ret_type = type_to_simd_type (MONO_TYPE_I4);
5754 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5755 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5758 ret_type = type_to_simd_type (MONO_TYPE_R8);
5759 arg_types [0] = ret_type;
5760 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5761 ret_type = type_to_simd_type (MONO_TYPE_R4);
5762 arg_types [0] = ret_type;
5763 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5764 ret_type = type_to_simd_type (MONO_TYPE_R4);
5765 arg_types [0] = ret_type;
5766 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5767 ret_type = type_to_simd_type (MONO_TYPE_R4);
5768 arg_types [0] = ret_type;
5769 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5772 ret_type = type_to_simd_type (MONO_TYPE_I2);
5773 arg_types [0] = ret_type;
5774 arg_types [1] = LLVMInt32Type ();
5775 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5776 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5777 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5778 ret_type = type_to_simd_type (MONO_TYPE_I4);
5779 arg_types [0] = ret_type;
5780 arg_types [1] = LLVMInt32Type ();
5781 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5782 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5783 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5784 ret_type = type_to_simd_type (MONO_TYPE_I8);
5785 arg_types [0] = ret_type;
5786 arg_types [1] = LLVMInt32Type ();
5787 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5788 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5791 ret_type = LLVMInt32Type ();
5792 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5793 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5796 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5799 /* Load/Store intrinsics */
5801 LLVMTypeRef arg_types [5];
5805 for (i = 1; i <= 8; i *= 2) {
5806 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5807 arg_types [1] = LLVMInt32Type ();
5808 arg_types [2] = LLVMInt1Type ();
5809 arg_types [3] = LLVMInt32Type ();
5810 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5811 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
5813 arg_types [0] = LLVMIntType (i * 8);
5814 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5815 arg_types [2] = LLVMInt32Type ();
5816 arg_types [3] = LLVMInt1Type ();
5817 arg_types [4] = LLVMInt32Type ();
5818 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5819 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
5825 add_types (MonoLLVMModule *lmodule)
5827 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5831 mono_llvm_init (void)
5833 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5837 init_jit_module (MonoDomain *domain)
5839 MonoJitICallInfo *info;
5840 MonoJitDomainInfo *dinfo;
5841 MonoLLVMModule *module;
5844 dinfo = domain_jit_info (domain);
5845 if (dinfo->llvm_module)
5848 mono_loader_lock ();
5850 if (dinfo->llvm_module) {
5851 mono_loader_unlock ();
5855 module = g_new0 (MonoLLVMModule, 1);
5857 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5858 module->module = LLVMModuleCreateWithName (name);
5860 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5862 add_intrinsics (module->module);
5865 module->llvm_types = g_hash_table_new (NULL, NULL);
5867 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5869 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5871 mono_memory_barrier ();
5873 dinfo->llvm_module = module;
5875 mono_loader_unlock ();
5879 mono_llvm_cleanup (void)
5881 if (aot_module.module)
5882 LLVMDisposeModule (aot_module.module);
5884 LLVMContextDispose (LLVMGetGlobalContext ());
5888 mono_llvm_free_domain_info (MonoDomain *domain)
5890 MonoJitDomainInfo *info = domain_jit_info (domain);
5891 MonoLLVMModule *module = info->llvm_module;
5897 if (module->llvm_types)
5898 g_hash_table_destroy (module->llvm_types);
5900 mono_llvm_dispose_ee (module->mono_ee);
5902 if (module->bb_names) {
5903 for (i = 0; i < module->bb_names_len; ++i)
5904 g_free (module->bb_names [i]);
5905 g_free (module->bb_names);
5907 //LLVMDisposeModule (module->module);
5911 info->llvm_module = NULL;
5915 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5917 /* Delete previous module */
5918 if (aot_module.plt_entries)
5919 g_hash_table_destroy (aot_module.plt_entries);
5920 if (aot_module.module)
5921 LLVMDisposeModule (aot_module.module);
5923 memset (&aot_module, 0, sizeof (aot_module));
5925 aot_module.module = LLVMModuleCreateWithName ("aot");
5926 aot_module.got_symbol = got_symbol;
5927 aot_module.external_symbols = external_symbols;
5928 aot_module.emit_dwarf = emit_dwarf;
5929 /* The first few entries are reserved */
5930 aot_module.max_got_offset = 16;
5932 add_intrinsics (aot_module.module);
5933 add_types (&aot_module);
5937 * We couldn't compute the type of the LLVM global representing the got because
5938 * its size is only known after all the methods have been emitted. So create
5939 * a dummy variable, and replace all uses it with the real got variable when
5940 * its size is known in mono_llvm_emit_aot_module ().
5943 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5945 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5946 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5949 /* Add a dummy personality function */
5951 LLVMBasicBlockRef lbb;
5952 LLVMBuilderRef lbuilder;
5953 LLVMValueRef personality;
5955 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5956 LLVMSetLinkage (personality, LLVMInternalLinkage);
5957 lbb = LLVMAppendBasicBlock (personality, "BB0");
5958 lbuilder = LLVMCreateBuilder ();
5959 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5960 LLVMBuildRetVoid (lbuilder);
5961 mark_as_used (&aot_module, personality);
5964 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5965 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5966 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5967 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5971 * Emit the aot module into the LLVM bitcode file FILENAME.
5974 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5976 LLVMTypeRef got_type;
5977 LLVMValueRef real_got;
5978 MonoLLVMModule *module = &aot_module;
5981 * Create the real got variable and replace all uses of the dummy variable with
5984 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5985 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5986 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5987 if (module->external_symbols) {
5988 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5989 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5991 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5993 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5995 mark_as_used (&aot_module, real_got);
5997 /* Delete the dummy got so it doesn't become a global */
5998 LLVMDeleteGlobal (aot_module.got_var);
6000 emit_llvm_used (&aot_module);
6001 emit_dbg_info (&aot_module, filename, cu_name);
6003 /* Replace PLT entries for directly callable methods with the methods themselves */
6005 GHashTableIter iter;
6007 LLVMValueRef callee;
6009 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
6010 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
6011 if (mono_aot_is_direct_callable (ji)) {
6012 LLVMValueRef lmethod;
6014 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
6015 /* The types might not match because the caller might pass an rgctx */
6016 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
6017 mono_llvm_replace_uses_of (callee, lmethod);
6018 mono_aot_mark_unused_llvm_plt_entry (ji);
6028 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
6029 g_assert_not_reached ();
6034 LLVMWriteBitcodeToFile (aot_module.module, filename);
6039 md_string (const char *s)
6041 return LLVMMDString (s, strlen (s));
6044 /* Debugging support */
6047 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6049 LLVMModuleRef module = lmodule->module;
6050 LLVMValueRef args [16], cu_args [16], cu, ver;
6052 char *build_info, *s, *dir;
6055 * This can only be enabled when LLVM code is emitted into a separate object
6056 * file, since the AOT compiler also emits dwarf info,
6057 * and the abbrev indexes will not be correct since llvm has added its own
6060 if (!lmodule->emit_dwarf)
6064 * Emit dwarf info in the form of LLVM metadata. There is some
6065 * out-of-date documentation at:
6066 * http://llvm.org/docs/SourceLevelDebugging.html
6067 * but most of this was gathered from the llvm and
6072 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6073 /* CU name/compilation dir */
6074 dir = g_path_get_dirname (filename);
6075 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6076 args [1] = LLVMMDString (dir, strlen (dir));
6077 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6080 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6082 build_info = mono_get_runtime_build_info ();
6083 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6084 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6085 g_free (build_info);
6087 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6089 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6090 /* Runtime version */
6091 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6093 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6094 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6096 if (lmodule->subprogram_mds) {
6100 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6101 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6102 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6103 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6105 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6108 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6109 /* Imported modules */
6110 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6112 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6113 /* DebugEmissionKind = FullDebug */
6114 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6115 cu = LLVMMDNode (cu_args, n_cuargs);
6116 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6118 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6119 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6120 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6121 ver = LLVMMDNode (args, 3);
6122 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6124 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6125 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6126 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6127 ver = LLVMMDNode (args, 3);
6128 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6132 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6134 MonoLLVMModule *module = ctx->lmodule;
6135 MonoDebugMethodInfo *minfo = ctx->minfo;
6136 char *source_file, *dir, *filename;
6137 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6138 MonoSymSeqPoint *sym_seq_points;
6144 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
6146 source_file = g_strdup ("<unknown>");
6147 dir = g_path_get_dirname (source_file);
6148 filename = g_path_get_basename (source_file);
6150 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6151 args [0] = md_string (filename);
6152 args [1] = md_string (dir);
6153 ctx_args [1] = LLVMMDNode (args, 2);
6154 ctx_md = LLVMMDNode (ctx_args, 2);
6156 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6157 type_args [1] = NULL;
6158 type_args [2] = NULL;
6159 type_args [3] = LLVMMDString ("", 0);
6160 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6161 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6162 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6163 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6164 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6165 type_args [9] = NULL;
6166 type_args [10] = NULL;
6167 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6168 type_args [12] = NULL;
6169 type_args [13] = NULL;
6170 type_args [14] = NULL;
6171 type_md = LLVMMDNode (type_args, 14);
6173 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6174 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6175 /* Source directory + file pair */
6176 args [0] = md_string (filename);
6177 args [1] = md_string (dir);
6178 md_args [1] = LLVMMDNode (args ,2);
6179 md_args [2] = ctx_md;
6180 md_args [3] = md_string (cfg->method->name);
6181 md_args [4] = md_string (name);
6182 md_args [5] = md_string (name);
6185 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
6187 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6189 md_args [7] = type_md;
6191 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6193 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6195 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6196 /* Index into a virtual function */
6197 md_args [11] = NULL;
6198 md_args [12] = NULL;
6200 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6202 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6203 /* Pointer to LLVM function */
6204 md_args [15] = method;
6205 /* Function template parameter */
6206 md_args [16] = NULL;
6207 /* Function declaration descriptor */
6208 md_args [17] = NULL;
6209 /* List of function variables */
6210 md_args [18] = LLVMMDNode (args, 0);
6212 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6213 md = LLVMMDNode (md_args, 20);
6215 if (!module->subprogram_mds)
6216 module->subprogram_mds = g_ptr_array_new ();
6217 g_ptr_array_add (module->subprogram_mds, md);
6221 g_free (source_file);
6222 g_free (sym_seq_points);
6228 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6230 MonoCompile *cfg = ctx->cfg;
6232 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6233 MonoDebugSourceLocation *loc;
6234 LLVMValueRef loc_md, md_args [16];
6237 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6241 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6242 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6243 md_args [nmd_args ++] = ctx->dbg_md;
6244 md_args [nmd_args ++] = NULL;
6245 loc_md = LLVMMDNode (md_args, nmd_args);
6246 LLVMSetCurrentDebugLocation (builder, loc_md);
6247 mono_debug_symfile_free_location (loc);
6254 - Emit LLVM IR from the mono IR using the LLVM C API.
6255 - The original arch specific code remains, so we can fall back to it if we run
6256 into something we can't handle.
6260 A partial list of issues:
6261 - Handling of opcodes which can throw exceptions.
6263 In the mono JIT, these are implemented using code like this:
6270 push throw_pos - method
6271 call <exception trampoline>
6273 The problematic part is push throw_pos - method, which cannot be represented
6274 in the LLVM IR, since it does not support label values.
6275 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6276 be implemented in JIT mode ?
6277 -> a possible but slower implementation would use the normal exception
6278 throwing code but it would need to control the placement of the throw code
6279 (it needs to be exactly after the compare+branch).
6280 -> perhaps add a PC offset intrinsics ?
6282 - efficient implementation of .ovf opcodes.
6284 These are currently implemented as:
6285 <ins which sets the condition codes>
6288 Some overflow opcodes are now supported by LLVM SVN.
6290 - exception handling, unwinding.
6291 - SSA is disabled for methods with exception handlers
6292 - How to obtain unwind info for LLVM compiled methods ?
6293 -> this is now solved by converting the unwind info generated by LLVM
6295 - LLVM uses the c++ exception handling framework, while we use our home grown
6296 code, and couldn't use the c++ one:
6297 - its not supported under VC++, other exotic platforms.
6298 - it might be impossible to support filter clauses with it.
6302 The trampolines need a predictable call sequence, since they need to disasm
6303 the calling code to obtain register numbers / offsets.
6305 LLVM currently generates this code in non-JIT mode:
6306 mov -0x98(%rax),%eax
6308 Here, the vtable pointer is lost.
6309 -> solution: use one vtable trampoline per class.
6311 - passing/receiving the IMT pointer/RGCTX.
6312 -> solution: pass them as normal arguments ?
6316 LLVM does not allow the specification of argument registers etc. This means
6317 that all calls are made according to the platform ABI.
6319 - passing/receiving vtypes.
6321 Vtypes passed/received in registers are handled by the front end by using
6322 a signature with scalar arguments, and loading the parts of the vtype into those
6325 Vtypes passed on the stack are handled using the 'byval' attribute.
6329 Supported though alloca, we need to emit the load/store code.
6333 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6334 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6335 This is made easier because the IR is already in SSA form.
6336 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6337 types are frequently used incorrectly.
6342 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6343 it with the file containing the methods emitted by the JIT and the AOT data
6347 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6348 * - each bblock should end with a branch
6349 * - setting the return value, making cfg->ret non-volatile
6350 * - avoid some transformations in the JIT which make it harder for us to generate
6352 * - use pointer types to help optimizations.