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); }
40 * Information associated by mono with LLVM modules.
44 LLVMValueRef throw, rethrow, throw_corlib_exception;
45 GHashTable *llvm_types;
47 const char *got_symbol;
48 GHashTable *plt_entries;
49 GHashTable *plt_entries_ji;
50 GHashTable *method_to_lmethod;
55 GPtrArray *subprogram_mds;
57 LLVMExecutionEngineRef ee;
58 gboolean external_symbols;
64 * Information associated by the backend with mono basic blocks.
67 LLVMBasicBlockRef bblock, end_bblock;
68 LLVMValueRef finally_ind;
69 gboolean added, invoke_target;
71 * If this bblock is the start of a finally clause, this is a list of bblocks it
72 * needs to branch to in ENDFINALLY.
74 GSList *call_handler_return_bbs;
76 * If this bblock is the start of a finally clause, this is the bblock that
77 * CALL_HANDLER needs to branch to.
79 LLVMBasicBlockRef call_handler_target_bb;
80 /* The list of switch statements generated by ENDFINALLY instructions */
81 GSList *endfinally_switch_ins_list;
86 * Structure containing emit state
91 /* Maps method names to the corresponding LLVMValueRef */
92 GHashTable *emitted_method_decls;
96 MonoLLVMModule *lmodule;
99 int sindex, default_index, ex_index;
100 LLVMBuilderRef builder;
101 LLVMValueRef *values, *addresses;
102 MonoType **vreg_cli_types;
104 MonoMethodSignature *sig;
106 GHashTable *region_to_handler;
107 LLVMBuilderRef alloca_builder;
108 LLVMValueRef last_alloca;
109 LLVMValueRef rgctx_arg;
110 LLVMTypeRef *vreg_types;
112 gboolean *unreachable;
114 LLVMValueRef imt_rgctx_loc;
115 GHashTable *llvm_types;
117 MonoDebugMethodInfo *minfo;
124 MonoBasicBlock *in_bb;
129 * Instruction metadata
130 * This is the same as ins_info, but LREG != IREG.
138 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
139 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
146 /* keep in sync with the enum in mini.h */
149 #include "mini-ops.h"
154 #if SIZEOF_VOID_P == 4
155 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
157 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
160 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
163 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
165 #define TRACE_FAILURE(msg)
169 #define IS_TARGET_X86 1
171 #define IS_TARGET_X86 0
175 #define IS_TARGET_AMD64 1
177 #define IS_TARGET_AMD64 0
180 #define LLVM_FAILURE(ctx, reason) do { \
181 TRACE_FAILURE (reason); \
182 (ctx)->cfg->exception_message = g_strdup (reason); \
183 (ctx)->cfg->disable_llvm = TRUE; \
187 #define CHECK_FAILURE(ctx) do { \
188 if ((ctx)->cfg->disable_llvm) \
192 static LLVMIntPredicate cond_to_llvm_cond [] = {
205 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
218 static MonoNativeTlsKey current_cfg_tls_id;
220 static MonoLLVMModule aot_module;
221 static int memset_param_count, memcpy_param_count;
222 static const char *memset_func_name;
223 static const char *memcpy_func_name;
225 static void init_jit_module (MonoDomain *domain);
227 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
228 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
229 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
234 * The LLVM type with width == sizeof (gpointer)
239 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
245 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
251 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
257 * Return the size of the LLVM representation of the vtype T.
260 get_vtype_size (MonoType *t)
264 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
266 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
273 * simd_class_to_llvm_type:
275 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
278 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
280 if (!strcmp (klass->name, "Vector2d")) {
281 return LLVMVectorType (LLVMDoubleType (), 2);
282 } else if (!strcmp (klass->name, "Vector2l")) {
283 return LLVMVectorType (LLVMInt64Type (), 2);
284 } else if (!strcmp (klass->name, "Vector2ul")) {
285 return LLVMVectorType (LLVMInt64Type (), 2);
286 } else if (!strcmp (klass->name, "Vector4i")) {
287 return LLVMVectorType (LLVMInt32Type (), 4);
288 } else if (!strcmp (klass->name, "Vector4ui")) {
289 return LLVMVectorType (LLVMInt32Type (), 4);
290 } else if (!strcmp (klass->name, "Vector4f")) {
291 return LLVMVectorType (LLVMFloatType (), 4);
292 } else if (!strcmp (klass->name, "Vector8s")) {
293 return LLVMVectorType (LLVMInt16Type (), 8);
294 } else if (!strcmp (klass->name, "Vector8us")) {
295 return LLVMVectorType (LLVMInt16Type (), 8);
296 } else if (!strcmp (klass->name, "Vector16sb")) {
297 return LLVMVectorType (LLVMInt8Type (), 16);
298 } else if (!strcmp (klass->name, "Vector16b")) {
299 return LLVMVectorType (LLVMInt8Type (), 16);
301 printf ("%s\n", klass->name);
307 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
308 static inline G_GNUC_UNUSED LLVMTypeRef
309 type_to_simd_type (int type)
313 return LLVMVectorType (LLVMInt8Type (), 16);
315 return LLVMVectorType (LLVMInt16Type (), 8);
317 return LLVMVectorType (LLVMInt32Type (), 4);
319 return LLVMVectorType (LLVMInt64Type (), 2);
321 return LLVMVectorType (LLVMDoubleType (), 2);
323 return LLVMVectorType (LLVMFloatType (), 4);
325 g_assert_not_reached ();
331 create_llvm_type_for_type (MonoClass *klass)
333 int i, size, nfields, esize;
334 LLVMTypeRef *eltypes;
339 t = &klass->byval_arg;
341 if (mini_type_is_hfa (t, &nfields, &esize)) {
343 * This is needed on arm64 where HFAs are returned in
347 eltypes = g_new (LLVMTypeRef, size);
348 for (i = 0; i < size; ++i)
349 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
351 size = get_vtype_size (t);
353 eltypes = g_new (LLVMTypeRef, size);
354 for (i = 0; i < size; ++i)
355 eltypes [i] = LLVMInt8Type ();
358 name = mono_type_full_name (&klass->byval_arg);
359 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
360 LLVMStructSetBody (ltype, eltypes, size, FALSE);
370 * Return the LLVM type corresponding to T.
373 type_to_llvm_type (EmitContext *ctx, MonoType *t)
376 return LLVMPointerType (LLVMInt8Type (), 0);
378 t = mini_get_underlying_type (ctx->cfg, t);
381 return LLVMVoidType ();
383 return LLVMInt8Type ();
385 return LLVMInt16Type ();
387 return LLVMInt32Type ();
389 return LLVMInt8Type ();
391 return LLVMInt16Type ();
393 return LLVMInt32Type ();
394 case MONO_TYPE_BOOLEAN:
395 return LLVMInt8Type ();
398 return LLVMInt64Type ();
400 return LLVMInt16Type ();
402 return LLVMFloatType ();
404 return LLVMDoubleType ();
407 return IntPtrType ();
408 case MONO_TYPE_OBJECT:
409 case MONO_TYPE_CLASS:
410 case MONO_TYPE_ARRAY:
411 case MONO_TYPE_SZARRAY:
412 case MONO_TYPE_STRING:
414 return ObjRefType ();
417 /* Because of generic sharing */
418 return ObjRefType ();
419 case MONO_TYPE_GENERICINST:
420 if (!mono_type_generic_inst_is_valuetype (t))
421 return ObjRefType ();
423 case MONO_TYPE_VALUETYPE:
424 case MONO_TYPE_TYPEDBYREF: {
428 klass = mono_class_from_mono_type (t);
430 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
431 return simd_class_to_llvm_type (ctx, klass);
434 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
436 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
438 ltype = create_llvm_type_for_type (klass);
439 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
445 printf ("X: %d\n", t->type);
446 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
447 ctx->cfg->disable_llvm = TRUE;
455 * Return whenever T is an unsigned int type.
458 type_is_unsigned (EmitContext *ctx, MonoType *t)
475 * type_to_llvm_arg_type:
477 * Same as type_to_llvm_type, but treat i8/i16 as i32.
480 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
482 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
485 * This works on all abis except arm64/ios which passes multiple
486 * arguments in one stack slot.
489 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
491 * LLVM generates code which only sets the lower bits, while JITted
492 * code expects all the bits to be set.
494 ptype = LLVMInt32Type ();
502 * llvm_type_to_stack_type:
504 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
507 static G_GNUC_UNUSED LLVMTypeRef
508 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
512 if (type == LLVMInt8Type ())
513 return LLVMInt32Type ();
514 else if (type == LLVMInt16Type ())
515 return LLVMInt32Type ();
516 else if (!cfg->r4fp && type == LLVMFloatType ())
517 return LLVMDoubleType ();
523 * regtype_to_llvm_type:
525 * Return the LLVM type corresponding to the regtype C used in instruction
529 regtype_to_llvm_type (char c)
533 return LLVMInt32Type ();
535 return LLVMInt64Type ();
537 return LLVMDoubleType ();
546 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
549 op_to_llvm_type (int opcode)
554 return LLVMInt8Type ();
557 return LLVMInt8Type ();
560 return LLVMInt16Type ();
563 return LLVMInt16Type ();
566 return LLVMInt32Type ();
569 return LLVMInt32Type ();
571 return LLVMInt64Type ();
573 return LLVMFloatType ();
575 return LLVMDoubleType ();
577 return LLVMInt64Type ();
579 return LLVMInt32Type ();
581 return LLVMInt64Type ();
586 return LLVMInt8Type ();
591 return LLVMInt16Type ();
594 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
601 return LLVMInt32Type ();
608 return LLVMInt64Type ();
610 printf ("%s\n", mono_inst_name (opcode));
611 g_assert_not_reached ();
617 * load_store_to_llvm_type:
619 * Return the size/sign/zero extension corresponding to the load/store opcode
623 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
629 case OP_LOADI1_MEMBASE:
630 case OP_STOREI1_MEMBASE_REG:
631 case OP_STOREI1_MEMBASE_IMM:
632 case OP_ATOMIC_LOAD_I1:
633 case OP_ATOMIC_STORE_I1:
636 return LLVMInt8Type ();
637 case OP_LOADU1_MEMBASE:
639 case OP_ATOMIC_LOAD_U1:
640 case OP_ATOMIC_STORE_U1:
643 return LLVMInt8Type ();
644 case OP_LOADI2_MEMBASE:
645 case OP_STOREI2_MEMBASE_REG:
646 case OP_STOREI2_MEMBASE_IMM:
647 case OP_ATOMIC_LOAD_I2:
648 case OP_ATOMIC_STORE_I2:
651 return LLVMInt16Type ();
652 case OP_LOADU2_MEMBASE:
654 case OP_ATOMIC_LOAD_U2:
655 case OP_ATOMIC_STORE_U2:
658 return LLVMInt16Type ();
659 case OP_LOADI4_MEMBASE:
660 case OP_LOADU4_MEMBASE:
663 case OP_STOREI4_MEMBASE_REG:
664 case OP_STOREI4_MEMBASE_IMM:
665 case OP_ATOMIC_LOAD_I4:
666 case OP_ATOMIC_STORE_I4:
667 case OP_ATOMIC_LOAD_U4:
668 case OP_ATOMIC_STORE_U4:
670 return LLVMInt32Type ();
671 case OP_LOADI8_MEMBASE:
673 case OP_STOREI8_MEMBASE_REG:
674 case OP_STOREI8_MEMBASE_IMM:
675 case OP_ATOMIC_LOAD_I8:
676 case OP_ATOMIC_STORE_I8:
677 case OP_ATOMIC_LOAD_U8:
678 case OP_ATOMIC_STORE_U8:
680 return LLVMInt64Type ();
681 case OP_LOADR4_MEMBASE:
682 case OP_STORER4_MEMBASE_REG:
683 case OP_ATOMIC_LOAD_R4:
684 case OP_ATOMIC_STORE_R4:
686 return LLVMFloatType ();
687 case OP_LOADR8_MEMBASE:
688 case OP_STORER8_MEMBASE_REG:
689 case OP_ATOMIC_LOAD_R8:
690 case OP_ATOMIC_STORE_R8:
692 return LLVMDoubleType ();
693 case OP_LOAD_MEMBASE:
695 case OP_STORE_MEMBASE_REG:
696 case OP_STORE_MEMBASE_IMM:
697 *size = sizeof (gpointer);
698 return IntPtrType ();
700 g_assert_not_reached ();
708 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
711 ovf_op_to_intrins (int opcode)
715 return "llvm.sadd.with.overflow.i32";
717 return "llvm.uadd.with.overflow.i32";
719 return "llvm.ssub.with.overflow.i32";
721 return "llvm.usub.with.overflow.i32";
723 return "llvm.smul.with.overflow.i32";
725 return "llvm.umul.with.overflow.i32";
727 return "llvm.sadd.with.overflow.i64";
729 return "llvm.uadd.with.overflow.i64";
731 return "llvm.ssub.with.overflow.i64";
733 return "llvm.usub.with.overflow.i64";
735 return "llvm.smul.with.overflow.i64";
737 return "llvm.umul.with.overflow.i64";
739 g_assert_not_reached ();
745 simd_op_to_intrins (int opcode)
748 #if defined(TARGET_X86) || defined(TARGET_AMD64)
750 return "llvm.x86.sse2.min.pd";
752 return "llvm.x86.sse.min.ps";
754 return "llvm.x86.sse41.pminud";
756 return "llvm.x86.sse41.pminuw";
758 return "llvm.x86.sse2.pminu.b";
760 return "llvm.x86.sse2.pmins.w";
762 return "llvm.x86.sse2.max.pd";
764 return "llvm.x86.sse.max.ps";
766 return "llvm.x86.sse3.hadd.pd";
768 return "llvm.x86.sse3.hadd.ps";
770 return "llvm.x86.sse3.hsub.pd";
772 return "llvm.x86.sse3.hsub.ps";
774 return "llvm.x86.sse41.pmaxud";
776 return "llvm.x86.sse41.pmaxuw";
778 return "llvm.x86.sse2.pmaxu.b";
780 return "llvm.x86.sse3.addsub.ps";
782 return "llvm.x86.sse3.addsub.pd";
783 case OP_EXTRACT_MASK:
784 return "llvm.x86.sse2.pmovmskb.128";
787 return "llvm.x86.sse2.psrli.w";
790 return "llvm.x86.sse2.psrli.d";
793 return "llvm.x86.sse2.psrli.q";
796 return "llvm.x86.sse2.pslli.w";
799 return "llvm.x86.sse2.pslli.d";
802 return "llvm.x86.sse2.pslli.q";
805 return "llvm.x86.sse2.psrai.w";
808 return "llvm.x86.sse2.psrai.d";
810 return "llvm.x86.sse2.padds.b";
812 return "llvm.x86.sse2.padds.w";
814 return "llvm.x86.sse2.psubs.b";
816 return "llvm.x86.sse2.psubs.w";
817 case OP_PADDB_SAT_UN:
818 return "llvm.x86.sse2.paddus.b";
819 case OP_PADDW_SAT_UN:
820 return "llvm.x86.sse2.paddus.w";
821 case OP_PSUBB_SAT_UN:
822 return "llvm.x86.sse2.psubus.b";
823 case OP_PSUBW_SAT_UN:
824 return "llvm.x86.sse2.psubus.w";
826 return "llvm.x86.sse2.pavg.b";
828 return "llvm.x86.sse2.pavg.w";
830 return "llvm.x86.sse.sqrt.ps";
832 return "llvm.x86.sse2.sqrt.pd";
834 return "llvm.x86.sse.rsqrt.ps";
836 return "llvm.x86.sse.rcp.ps";
838 return "llvm.x86.sse2.cvtdq2pd";
840 return "llvm.x86.sse2.cvtdq2ps";
842 return "llvm.x86.sse2.cvtpd2dq";
844 return "llvm.x86.sse2.cvtps2dq";
846 return "llvm.x86.sse2.cvtpd2ps";
848 return "llvm.x86.sse2.cvtps2pd";
850 return "llvm.x86.sse2.cvttpd2dq";
852 return "llvm.x86.sse2.cvttps2dq";
854 return "llvm.x86.sse.cmp.ps";
856 return "llvm.x86.sse2.cmp.pd";
858 return "llvm.x86.sse2.packsswb.128";
860 return "llvm.x86.sse2.packssdw.128";
862 return "llvm.x86.sse2.packuswb.128";
864 return "llvm.x86.sse41.packusdw";
866 return "llvm.x86.sse2.pmulh.w";
867 case OP_PMULW_HIGH_UN:
868 return "llvm.x86.sse2.pmulhu.w";
871 g_assert_not_reached ();
877 simd_op_to_llvm_type (int opcode)
879 #if defined(TARGET_X86) || defined(TARGET_AMD64)
883 return type_to_simd_type (MONO_TYPE_R8);
886 return type_to_simd_type (MONO_TYPE_I8);
889 return type_to_simd_type (MONO_TYPE_I4);
894 return type_to_simd_type (MONO_TYPE_I2);
898 return type_to_simd_type (MONO_TYPE_I1);
900 return type_to_simd_type (MONO_TYPE_R4);
903 return type_to_simd_type (MONO_TYPE_I4);
907 return type_to_simd_type (MONO_TYPE_R8);
911 return type_to_simd_type (MONO_TYPE_R4);
912 case OP_EXTRACT_MASK:
913 return type_to_simd_type (MONO_TYPE_I1);
919 return type_to_simd_type (MONO_TYPE_R4);
922 return type_to_simd_type (MONO_TYPE_R8);
924 g_assert_not_reached ();
935 * Return the LLVM basic block corresponding to BB.
937 static LLVMBasicBlockRef
938 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
940 char bb_name_buf [128];
943 if (ctx->bblocks [bb->block_num].bblock == NULL) {
944 if (bb->flags & BB_EXCEPTION_HANDLER) {
945 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
946 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
947 bb_name = bb_name_buf;
948 } else if (bb->block_num < 256) {
949 if (!ctx->lmodule->bb_names) {
950 ctx->lmodule->bb_names_len = 256;
951 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
953 if (!ctx->lmodule->bb_names [bb->block_num]) {
956 n = g_strdup_printf ("BB%d", bb->block_num);
957 mono_memory_barrier ();
958 ctx->lmodule->bb_names [bb->block_num] = n;
960 bb_name = ctx->lmodule->bb_names [bb->block_num];
962 sprintf (bb_name_buf, "BB%d", bb->block_num);
963 bb_name = bb_name_buf;
966 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
967 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
970 return ctx->bblocks [bb->block_num].bblock;
976 * Return the last LLVM bblock corresponding to BB.
977 * This might not be equal to the bb returned by get_bb () since we need to generate
978 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
980 static LLVMBasicBlockRef
981 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
984 return ctx->bblocks [bb->block_num].end_bblock;
987 static LLVMBasicBlockRef
988 gen_bb (EmitContext *ctx, const char *prefix)
992 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
993 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
999 * Return the target of the patch identified by TYPE and TARGET.
1002 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1006 memset (&ji, 0, sizeof (ji));
1008 ji.data.target = target;
1010 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1016 * Emit code to convert the LLVM value V to DTYPE.
1019 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1021 LLVMTypeRef stype = LLVMTypeOf (v);
1023 if (stype != dtype) {
1024 gboolean ext = FALSE;
1027 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1029 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1031 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1035 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1037 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1038 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1041 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1042 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1043 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1044 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1045 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1046 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1047 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1048 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1050 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1051 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1052 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1053 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1054 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1055 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1057 if (mono_arch_is_soft_float ()) {
1058 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1059 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1060 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1061 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1064 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1065 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1068 LLVMDumpValue (LLVMConstNull (dtype));
1069 g_assert_not_reached ();
1077 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1079 return convert_full (ctx, v, dtype, FALSE);
1083 * emit_volatile_load:
1085 * If vreg is volatile, emit a load from its address.
1088 emit_volatile_load (EmitContext *ctx, int vreg)
1092 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1093 t = ctx->vreg_cli_types [vreg];
1094 if (t && !t->byref) {
1096 * Might have to zero extend since llvm doesn't have
1099 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1100 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1101 else if (t->type == MONO_TYPE_U8)
1102 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1109 * emit_volatile_store:
1111 * If VREG is volatile, emit a store from its value to its address.
1114 emit_volatile_store (EmitContext *ctx, int vreg)
1116 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1118 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1119 g_assert (ctx->addresses [vreg]);
1120 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1126 * Maps parameter indexes in the original signature to parameter indexes
1127 * in the LLVM signature.
1130 /* The indexes of various special arguments in the LLVM signature */
1131 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1135 * sig_to_llvm_sig_full:
1137 * Return the LLVM signature corresponding to the mono signature SIG using the
1138 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1141 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1144 LLVMTypeRef ret_type;
1145 LLVMTypeRef *param_types = NULL;
1147 int i, j, pindex, vret_arg_pindex = 0;
1149 gboolean vretaddr = FALSE;
1153 memset (sinfo, 0, sizeof (LLVMSigInfo));
1155 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1156 ret_type = type_to_llvm_type (ctx, rtype);
1157 CHECK_FAILURE (ctx);
1160 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1161 /* LLVM models this by returning an aggregate value */
1162 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1163 LLVMTypeRef members [2];
1165 members [0] = IntPtrType ();
1166 ret_type = LLVMStructType (members, 1, FALSE);
1168 g_assert_not_reached ();
1170 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1171 /* Vtype returned normally by val */
1172 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1173 /* Vtype returned as a fp struct */
1174 LLVMTypeRef members [16];
1176 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1177 for (i = 0; i < cinfo->ret.nslots; ++i)
1178 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1179 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1180 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1181 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1183 ret_type = LLVMVoidType ();
1187 pindexes = g_new0 (int, sig->param_count);
1188 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1190 if (cinfo && cinfo->rgctx_arg) {
1192 sinfo->rgctx_arg_pindex = pindex;
1193 param_types [pindex] = ctx->lmodule->ptr_type;
1196 if (cinfo && cinfo->imt_arg) {
1198 sinfo->imt_arg_pindex = pindex;
1199 param_types [pindex] = ctx->lmodule->ptr_type;
1203 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1204 vret_arg_pindex = pindex;
1205 if (cinfo->vret_arg_index == 1) {
1206 /* Add the slots consumed by the first argument */
1207 LLVMArgInfo *ainfo = &cinfo->args [0];
1208 switch (ainfo->storage) {
1209 case LLVMArgVtypeInReg:
1210 for (j = 0; j < 2; ++j) {
1211 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1221 sinfo->vret_arg_pindex = vret_arg_pindex;
1224 if (vretaddr && vret_arg_pindex == pindex)
1225 param_types [pindex ++] = IntPtrType ();
1228 sinfo->this_arg_pindex = pindex;
1229 param_types [pindex ++] = ThisType ();
1231 if (vretaddr && vret_arg_pindex == pindex)
1232 param_types [pindex ++] = IntPtrType ();
1233 for (i = 0; i < sig->param_count; ++i) {
1234 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1236 if (vretaddr && vret_arg_pindex == pindex)
1237 param_types [pindex ++] = IntPtrType ();
1238 pindexes [i] = pindex;
1241 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1245 switch (ainfo->storage) {
1246 case LLVMArgVtypeInReg:
1247 for (j = 0; j < 2; ++j) {
1248 switch (ainfo->pair_storage [j]) {
1250 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1255 g_assert_not_reached ();
1259 case LLVMArgVtypeByVal:
1260 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1261 CHECK_FAILURE (ctx);
1262 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1265 case LLVMArgAsIArgs:
1266 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1269 case LLVMArgAsFpArgs: {
1272 for (j = 0; j < ainfo->nslots; ++j)
1273 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1274 pindex += ainfo->nslots;
1278 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1282 if (vretaddr && vret_arg_pindex == pindex)
1283 param_types [pindex ++] = IntPtrType ();
1285 CHECK_FAILURE (ctx);
1287 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1288 g_free (param_types);
1291 sinfo->pindexes = pindexes;
1299 g_free (param_types);
1305 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1307 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1311 * LLVMFunctionType1:
1313 * Create an LLVM function type from the arguments.
1315 static G_GNUC_UNUSED LLVMTypeRef
1316 LLVMFunctionType1(LLVMTypeRef ReturnType,
1317 LLVMTypeRef ParamType1,
1320 LLVMTypeRef param_types [1];
1322 param_types [0] = ParamType1;
1324 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1328 * LLVMFunctionType2:
1330 * Create an LLVM function type from the arguments.
1332 static G_GNUC_UNUSED LLVMTypeRef
1333 LLVMFunctionType2(LLVMTypeRef ReturnType,
1334 LLVMTypeRef ParamType1,
1335 LLVMTypeRef ParamType2,
1338 LLVMTypeRef param_types [2];
1340 param_types [0] = ParamType1;
1341 param_types [1] = ParamType2;
1343 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1347 * LLVMFunctionType3:
1349 * Create an LLVM function type from the arguments.
1351 static G_GNUC_UNUSED LLVMTypeRef
1352 LLVMFunctionType3(LLVMTypeRef ReturnType,
1353 LLVMTypeRef ParamType1,
1354 LLVMTypeRef ParamType2,
1355 LLVMTypeRef ParamType3,
1358 LLVMTypeRef param_types [3];
1360 param_types [0] = ParamType1;
1361 param_types [1] = ParamType2;
1362 param_types [2] = ParamType3;
1364 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1370 * Create an LLVM builder and remember it so it can be freed later.
1372 static LLVMBuilderRef
1373 create_builder (EmitContext *ctx)
1375 LLVMBuilderRef builder = LLVMCreateBuilder ();
1377 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1383 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1385 char *callee_name = mono_aot_get_plt_symbol (type, data);
1386 LLVMValueRef callee;
1387 MonoJumpInfo *ji = NULL;
1392 if (ctx->cfg->compile_aot)
1393 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1394 mono_add_patch_info (ctx->cfg, 0, type, data);
1397 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1399 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1401 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1403 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1406 if (ctx->cfg->compile_aot) {
1407 ji = g_new0 (MonoJumpInfo, 1);
1409 ji->data.target = data;
1411 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1418 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1420 MonoMethodHeader *header = cfg->header;
1421 MonoExceptionClause *clause;
1425 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1426 return (bb->region >> 8) - 1;
1429 for (i = 0; i < header->num_clauses; ++i) {
1430 clause = &header->clauses [i];
1432 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1440 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1442 LLVMValueRef md_arg;
1445 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1446 md_arg = LLVMMDString ("mono", 4);
1447 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1451 set_invariant_load_flag (LLVMValueRef v)
1453 LLVMValueRef md_arg;
1455 const char *flag_name;
1457 // FIXME: Cache this
1458 flag_name = "invariant.load";
1459 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1460 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1461 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1467 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1471 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1473 MonoCompile *cfg = ctx->cfg;
1475 LLVMBuilderRef builder = *builder_ref;
1478 clause_index = get_handler_clause (cfg, bb);
1480 if (clause_index != -1) {
1481 MonoMethodHeader *header = cfg->header;
1482 MonoExceptionClause *ec = &header->clauses [clause_index];
1483 MonoBasicBlock *tblock;
1484 LLVMBasicBlockRef ex_bb, noex_bb;
1487 * Have to use an invoke instead of a call, branching to the
1488 * handler bblock of the clause containing this bblock.
1491 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1493 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1496 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1498 ex_bb = get_bb (ctx, tblock);
1500 noex_bb = gen_bb (ctx, "NOEX_BB");
1503 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1505 builder = ctx->builder = create_builder (ctx);
1506 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1508 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1510 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1511 ctx->builder = builder;
1514 *builder_ref = ctx->builder;
1519 #if LLVM_API_VERSION >= 4
1520 #define EXTRA_MONO_LOAD_STORE_ARGS 1
1522 #define EXTRA_MONO_LOAD_STORE_ARGS 0
1526 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1528 const char *intrins_name;
1529 LLVMValueRef args [16], res;
1530 LLVMTypeRef addr_type;
1532 if (is_faulting && bb->region != -1) {
1533 #if LLVM_API_VERSION >= 4
1534 LLVMAtomicOrdering ordering;
1537 case LLVM_BARRIER_NONE:
1538 ordering = LLVMAtomicOrderingNotAtomic;
1540 case LLVM_BARRIER_ACQ:
1541 ordering = LLVMAtomicOrderingAcquire;
1543 case LLVM_BARRIER_SEQ:
1544 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1547 g_assert_not_reached ();
1553 * We handle loads which can fault by calling a mono specific intrinsic
1554 * using an invoke, so they are handled properly inside try blocks.
1555 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1556 * are marked with IntrReadArgMem.
1560 intrins_name = "llvm.mono.load.i8.p0i8";
1563 intrins_name = "llvm.mono.load.i16.p0i16";
1566 intrins_name = "llvm.mono.load.i32.p0i32";
1569 intrins_name = "llvm.mono.load.i64.p0i64";
1572 g_assert_not_reached ();
1575 addr_type = LLVMTypeOf (addr);
1576 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1577 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1580 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1581 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1582 #if LLVM_API_VERSION >= 4
1583 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1585 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3 + EXTRA_MONO_LOAD_STORE_ARGS);
1587 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1588 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1589 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1590 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1597 * We emit volatile loads for loads which can fault, because otherwise
1598 * LLVM will generate invalid code when encountering a load from a
1601 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1603 /* Mark it with a custom metadata */
1606 set_metadata_flag (res, "mono.faulting.load");
1614 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1616 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1620 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1622 const char *intrins_name;
1623 LLVMValueRef args [16];
1625 if (is_faulting && bb->region != -1) {
1626 #if LLVM_API_VERSION >= 4
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 ();
1647 intrins_name = "llvm.mono.store.i8.p0i8";
1650 intrins_name = "llvm.mono.store.i16.p0i16";
1653 intrins_name = "llvm.mono.store.i32.p0i32";
1656 intrins_name = "llvm.mono.store.i64.p0i64";
1659 g_assert_not_reached ();
1662 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1663 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1664 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1669 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1670 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1671 #if LLVM_API_VERSION >= 4
1672 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1674 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4 + EXTRA_MONO_LOAD_STORE_ARGS);
1676 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1681 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1683 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1687 * emit_cond_system_exception:
1689 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1690 * Might set the ctx exception.
1693 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1695 LLVMBasicBlockRef ex_bb, noex_bb;
1696 LLVMBuilderRef builder;
1697 MonoClass *exc_class;
1698 LLVMValueRef args [2];
1700 ex_bb = gen_bb (ctx, "EX_BB");
1701 noex_bb = gen_bb (ctx, "NOEX_BB");
1703 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1705 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1706 g_assert (exc_class);
1708 /* Emit exception throwing code */
1709 builder = create_builder (ctx);
1710 LLVMPositionBuilderAtEnd (builder, ex_bb);
1712 if (!ctx->lmodule->throw_corlib_exception) {
1713 LLVMValueRef callee;
1715 const char *icall_name;
1717 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1718 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1719 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1720 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1721 /* This will become i8* */
1722 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1723 sig = sig_to_llvm_sig (ctx, throw_sig);
1725 if (ctx->cfg->compile_aot) {
1726 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1728 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1731 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1732 * - On x86, LLVM generated code doesn't push the arguments
1733 * - The trampoline takes the throw address as an arguments, not a pc offset.
1735 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1738 mono_memory_barrier ();
1739 ctx->lmodule->throw_corlib_exception = callee;
1742 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1743 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1745 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1748 * The LLVM mono branch contains changes so a block address can be passed as an
1749 * argument to a call.
1751 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1752 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1754 LLVMBuildUnreachable (builder);
1756 ctx->builder = create_builder (ctx);
1757 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1759 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1766 * emit_args_to_vtype:
1768 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1771 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1773 int j, size, nslots;
1775 size = get_vtype_size (t);
1777 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1778 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1781 if (ainfo->storage == LLVMArgAsFpArgs)
1782 nslots = ainfo->nslots;
1786 for (j = 0; j < nslots; ++j) {
1787 LLVMValueRef index [2], addr, daddr;
1788 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1789 LLVMTypeRef part_type;
1791 if (ainfo->pair_storage [j] == LLVMArgNone)
1794 switch (ainfo->pair_storage [j]) {
1795 case LLVMArgInIReg: {
1796 part_type = LLVMIntType (part_size * 8);
1797 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1798 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1799 addr = LLVMBuildGEP (builder, address, index, 1, "");
1801 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1802 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1803 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1805 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1808 case LLVMArgInFPReg: {
1809 LLVMTypeRef arg_type;
1811 if (ainfo->esize == 8)
1812 arg_type = LLVMDoubleType ();
1814 arg_type = LLVMFloatType ();
1816 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1817 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1818 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1819 LLVMBuildStore (builder, args [j], addr);
1825 g_assert_not_reached ();
1828 size -= sizeof (gpointer);
1833 * emit_vtype_to_args:
1835 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1836 * into ARGS, and the number of arguments into NARGS.
1839 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1842 int j, size, nslots;
1843 LLVMTypeRef arg_type;
1845 size = get_vtype_size (t);
1847 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1848 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1850 if (ainfo->storage == LLVMArgAsFpArgs)
1851 nslots = ainfo->nslots;
1854 for (j = 0; j < nslots; ++j) {
1855 LLVMValueRef index [2], addr, daddr;
1856 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1858 if (ainfo->pair_storage [j] == LLVMArgNone)
1861 switch (ainfo->pair_storage [j]) {
1863 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1864 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1865 addr = LLVMBuildGEP (builder, address, index, 1, "");
1867 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1868 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1869 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1871 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1873 case LLVMArgInFPReg:
1874 if (ainfo->esize == 8)
1875 arg_type = LLVMDoubleType ();
1877 arg_type = LLVMFloatType ();
1878 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1879 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1880 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1881 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1886 g_assert_not_reached ();
1888 size -= sizeof (gpointer);
1895 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1898 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1899 * get executed every time control reaches them.
1901 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1903 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1904 return ctx->last_alloca;
1908 build_alloca (EmitContext *ctx, MonoType *t)
1910 MonoClass *k = mono_class_from_mono_type (t);
1913 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1916 align = mono_class_min_align (k);
1918 /* Sometimes align is not a power of 2 */
1919 while (mono_is_power_of_two (align) == -1)
1922 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1926 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1929 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1932 lmodule->used = g_ptr_array_sized_new (16);
1933 g_ptr_array_add (lmodule->used, global);
1937 emit_llvm_used (MonoLLVMModule *lmodule)
1939 LLVMModuleRef module = lmodule->module;
1940 LLVMTypeRef used_type;
1941 LLVMValueRef used, *used_elem;
1947 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1948 used = LLVMAddGlobal (module, used_type, "llvm.used");
1949 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1950 for (i = 0; i < lmodule->used->len; ++i)
1951 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1952 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1953 LLVMSetLinkage (used, LLVMAppendingLinkage);
1954 LLVMSetSection (used, "llvm.metadata");
1960 * Emit code to load/convert arguments.
1963 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1966 MonoCompile *cfg = ctx->cfg;
1967 MonoMethodSignature *sig = ctx->sig;
1968 LLVMCallInfo *linfo = ctx->linfo;
1971 ctx->alloca_builder = create_builder (ctx);
1974 * Handle indirect/volatile variables by allocating memory for them
1975 * using 'alloca', and storing their address in a temporary.
1977 for (i = 0; i < cfg->num_varinfo; ++i) {
1978 MonoInst *var = cfg->varinfo [i];
1981 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1982 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1983 CHECK_FAILURE (ctx);
1984 /* Could be already created by an OP_VPHI */
1985 if (!ctx->addresses [var->dreg])
1986 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1987 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1991 for (i = 0; i < sig->param_count; ++i) {
1992 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1993 int reg = cfg->args [i + sig->hasthis]->dreg;
1995 switch (ainfo->storage) {
1996 case LLVMArgVtypeInReg:
1997 case LLVMArgAsFpArgs: {
1998 LLVMValueRef args [8];
2001 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2002 memset (args, 0, sizeof (args));
2003 pindex = ctx->pindexes [i];
2004 if (ainfo->storage == LLVMArgVtypeInReg) {
2005 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2006 if (ainfo->pair_storage [1] != LLVMArgNone)
2007 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2009 g_assert (ainfo->nslots <= 8);
2010 for (j = 0; j < ainfo->nslots; ++j)
2011 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2013 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2015 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2017 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2018 /* Treat these as normal values */
2019 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2023 case LLVMArgVtypeByVal: {
2024 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2026 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2027 /* Treat these as normal values */
2028 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2032 case LLVMArgAsIArgs: {
2033 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2035 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2037 /* The argument is received as an array of ints, store it into the real argument */
2038 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2042 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]));
2048 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2050 emit_volatile_store (ctx, cfg->args [0]->dreg);
2051 for (i = 0; i < sig->param_count; ++i)
2052 if (!mini_type_is_vtype (cfg, sig->params [i]))
2053 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2055 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2056 LLVMValueRef this_alloc;
2059 * The exception handling code needs the location where the this argument was
2060 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2061 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2062 * location into the LSDA.
2064 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2065 /* This volatile store will keep the alloca alive */
2066 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2068 set_metadata_flag (this_alloc, "mono.this");
2071 if (cfg->rgctx_var) {
2072 LLVMValueRef rgctx_alloc, store;
2075 * We handle the rgctx arg similarly to the this pointer.
2077 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2078 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2079 /* This volatile store will keep the alloca alive */
2080 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2082 set_metadata_flag (rgctx_alloc, "mono.this");
2086 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2087 * it needs to continue normally, or return back to the exception handling system.
2089 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2090 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
2091 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2092 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
2096 sprintf (name, "finally_ind_bb%d", bb->block_num);
2097 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2098 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2100 ctx->bblocks [bb->block_num].finally_ind = val;
2103 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
2104 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
2105 * LLVM optimizer passes.
2107 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2108 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2116 /* Have to export this for AOT */
2118 mono_personality (void)
2121 g_assert_not_reached ();
2125 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2127 MonoCompile *cfg = ctx->cfg;
2128 LLVMModuleRef module = ctx->module;
2129 LLVMValueRef *values = ctx->values;
2130 LLVMValueRef *addresses = ctx->addresses;
2131 MonoCallInst *call = (MonoCallInst*)ins;
2132 MonoMethodSignature *sig = call->signature;
2133 LLVMValueRef callee = NULL, lcall;
2135 LLVMCallInfo *cinfo;
2139 LLVMTypeRef llvm_sig;
2141 gboolean virtual, calli;
2142 LLVMBuilderRef builder = *builder_ref;
2145 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2146 LLVM_FAILURE (ctx, "non-default callconv");
2148 cinfo = call->cinfo;
2149 if (call->rgctx_arg_reg)
2150 cinfo->rgctx_arg = TRUE;
2151 if (call->imt_arg_reg)
2152 cinfo->imt_arg = TRUE;
2154 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2156 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2157 CHECK_FAILURE (ctx);
2159 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);
2160 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);
2162 /* FIXME: Avoid creating duplicate methods */
2164 if (ins->flags & MONO_INST_HAS_METHOD) {
2168 if (cfg->compile_aot) {
2169 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2171 LLVM_FAILURE (ctx, "can't encode patch");
2173 callee = LLVMAddFunction (module, "", llvm_sig);
2176 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2178 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2182 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2183 /* LLVM miscompiles async methods */
2184 LLVM_FAILURE (ctx, "#13734");
2187 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2193 memset (&ji, 0, sizeof (ji));
2194 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2195 ji.data.target = info->name;
2197 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2199 if (cfg->compile_aot) {
2200 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2202 LLVM_FAILURE (ctx, "can't encode patch");
2204 callee = LLVMAddFunction (module, "", llvm_sig);
2205 target = (gpointer)mono_icall_get_wrapper (info);
2206 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2209 if (cfg->compile_aot) {
2211 if (cfg->abs_patches) {
2212 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2214 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2216 LLVM_FAILURE (ctx, "can't encode patch");
2220 LLVM_FAILURE (ctx, "aot");
2222 callee = LLVMAddFunction (module, "", llvm_sig);
2224 if (cfg->abs_patches) {
2225 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2228 * FIXME: Some trampolines might have
2229 * their own calling convention on some platforms.
2231 #ifndef TARGET_AMD64
2232 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2233 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
2234 LLVM_FAILURE (ctx, "trampoline with own cconv");
2236 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2237 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2241 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2247 int size = sizeof (gpointer);
2250 g_assert (ins->inst_offset % size == 0);
2251 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2253 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2255 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2257 if (ins->flags & MONO_INST_HAS_METHOD) {
2262 * Collect and convert arguments
2264 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2265 len = sizeof (LLVMValueRef) * nargs;
2266 args = alloca (len);
2267 memset (args, 0, len);
2268 l = call->out_ireg_args;
2270 if (call->rgctx_arg_reg) {
2271 g_assert (values [call->rgctx_arg_reg]);
2272 g_assert (sinfo.rgctx_arg_pindex < nargs);
2274 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2275 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2276 * it using a volatile load.
2279 if (!ctx->imt_rgctx_loc)
2280 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2281 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2282 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2284 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2287 if (call->imt_arg_reg) {
2288 g_assert (values [call->imt_arg_reg]);
2289 g_assert (sinfo.imt_arg_pindex < nargs);
2291 if (!ctx->imt_rgctx_loc)
2292 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2293 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2294 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2296 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2301 if (!addresses [call->inst.dreg])
2302 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2303 g_assert (sinfo.vret_arg_pindex < nargs);
2304 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2307 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2310 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2314 pindex = sinfo.this_arg_pindex;
2316 pindex = sinfo.pindexes [i - 1];
2318 pindex = sinfo.pindexes [i];
2321 regpair = (guint32)(gssize)(l->data);
2322 reg = regpair & 0xffffff;
2323 args [pindex] = values [reg];
2324 switch (ainfo->storage) {
2325 case LLVMArgVtypeInReg:
2326 case LLVMArgAsFpArgs: {
2329 g_assert (addresses [reg]);
2330 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2334 // FIXME: Get rid of the VMOVE
2337 case LLVMArgVtypeByVal:
2338 g_assert (addresses [reg]);
2339 args [pindex] = addresses [reg];
2341 case LLVMArgAsIArgs:
2342 g_assert (addresses [reg]);
2343 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2346 g_assert (args [pindex]);
2347 if (i == 0 && sig->hasthis)
2348 args [pindex] = convert (ctx, args [pindex], ThisType ());
2350 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2353 g_assert (pindex <= nargs);
2358 // FIXME: Align call sites
2364 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2367 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2369 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2370 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2372 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2373 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2375 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2377 if (call->rgctx_arg_reg)
2378 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2379 if (call->imt_arg_reg)
2380 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2382 /* Add byval attributes if needed */
2383 for (i = 0; i < sig->param_count; ++i) {
2384 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2386 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2387 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2392 * Convert the result
2395 switch (cinfo->ret.storage) {
2396 case LLVMArgVtypeInReg: {
2397 LLVMValueRef regs [2];
2399 if (!addresses [ins->dreg])
2400 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2402 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2403 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2404 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2405 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2408 case LLVMArgVtypeByVal:
2409 if (!addresses [call->inst.dreg])
2410 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2411 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2413 case LLVMArgFpStruct:
2414 if (!addresses [call->inst.dreg])
2415 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2416 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2419 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2420 /* If the method returns an unsigned value, need to zext it */
2421 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));
2425 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2426 /* If the method returns an unsigned value, need to zext it */
2427 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));
2431 if (!addresses [call->inst.dreg])
2432 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2433 g_assert (sinfo.vret_arg_pindex < nargs);
2434 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2437 *builder_ref = ctx->builder;
2439 g_free (sinfo.pindexes);
2447 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2449 MonoCompile *cfg = ctx->cfg;
2450 MonoMethodSignature *sig = ctx->sig;
2451 LLVMValueRef method = ctx->lmethod;
2452 LLVMValueRef *values = ctx->values;
2453 LLVMValueRef *addresses = ctx->addresses;
2454 LLVMCallInfo *linfo = ctx->linfo;
2455 LLVMModuleRef module = ctx->module;
2456 BBInfo *bblocks = ctx->bblocks;
2458 LLVMBasicBlockRef cbb;
2459 LLVMBuilderRef builder, starting_builder;
2460 gboolean has_terminator;
2462 LLVMValueRef lhs, rhs;
2465 cbb = get_bb (ctx, bb);
2466 builder = create_builder (ctx);
2467 ctx->builder = builder;
2468 LLVMPositionBuilderAtEnd (builder, cbb);
2470 if (bb == cfg->bb_entry)
2471 emit_entry_bb (ctx, builder);
2472 CHECK_FAILURE (ctx);
2474 if (bb->flags & BB_EXCEPTION_HANDLER) {
2476 LLVMValueRef personality;
2477 LLVMBasicBlockRef target_bb;
2479 static gint32 mapping_inited;
2480 static int ti_generator;
2483 LLVMValueRef type_info;
2486 if (!bblocks [bb->block_num].invoke_target) {
2488 * LLVM asserts if llvm.eh.selector is called from a bblock which
2489 * doesn't have an invoke pointing at it.
2490 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2492 LLVM_FAILURE (ctx, "handler without invokes");
2495 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2497 if (cfg->compile_aot) {
2498 /* Use a dummy personality function */
2499 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2500 g_assert (personality);
2502 personality = LLVMGetNamedFunction (module, "mono_personality");
2503 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2504 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2507 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2509 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2512 * Create the type info
2514 sprintf (ti_name, "type_info_%d", ti_generator);
2517 if (cfg->compile_aot) {
2518 /* decode_eh_frame () in aot-runtime.c will decode this */
2519 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2520 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2523 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2525 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2528 * Enabling this causes llc to crash:
2529 * http://llvm.org/bugs/show_bug.cgi?id=6102
2531 //LLVM_FAILURE (ctx, "aot+clauses");
2533 // test_0_invalid_unbox_arrays () fails
2534 LLVM_FAILURE (ctx, "aot+clauses");
2538 * After the cfg mempool is freed, the type info will point to stale memory,
2539 * but this is not a problem, since we decode it once in exception_cb during
2542 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2543 *(gint32*)ti = clause_index;
2545 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2547 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2551 LLVMTypeRef members [2], ret_type;
2552 LLVMValueRef landing_pad;
2554 members [0] = i8ptr;
2555 members [1] = LLVMInt32Type ();
2556 ret_type = LLVMStructType (members, 2, FALSE);
2558 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2559 LLVMAddClause (landing_pad, type_info);
2561 /* Store the exception into the exvar */
2562 if (bb->in_scount == 1) {
2563 g_assert (bb->in_scount == 1);
2564 exvar = bb->in_stack [0];
2566 // FIXME: This is shared with filter clauses ?
2567 g_assert (!values [exvar->dreg]);
2569 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2570 emit_volatile_store (ctx, exvar->dreg);
2574 /* Start a new bblock which CALL_HANDLER can branch to */
2575 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2577 LLVMBuildBr (builder, target_bb);
2579 ctx->builder = builder = create_builder (ctx);
2580 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2582 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2586 has_terminator = FALSE;
2587 starting_builder = builder;
2588 for (ins = bb->code; ins; ins = ins->next) {
2589 const char *spec = LLVM_INS_INFO (ins->opcode);
2591 char dname_buf [128];
2593 emit_dbg_loc (ctx, builder, ins->cil_code);
2596 if (nins > 5000 && builder == starting_builder) {
2597 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2598 LLVM_FAILURE (ctx, "basic block too long");
2602 /* There could be instructions after a terminator, skip them */
2605 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2606 sprintf (dname_buf, "t%d", ins->dreg);
2610 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2611 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2613 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2614 lhs = emit_volatile_load (ctx, ins->sreg1);
2616 /* It is ok for SETRET to have an uninitialized argument */
2617 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2618 LLVM_FAILURE (ctx, "sreg1");
2619 lhs = values [ins->sreg1];
2625 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2626 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2627 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2628 rhs = emit_volatile_load (ctx, ins->sreg2);
2630 if (!values [ins->sreg2])
2631 LLVM_FAILURE (ctx, "sreg2");
2632 rhs = values [ins->sreg2];
2638 //mono_print_ins (ins);
2639 switch (ins->opcode) {
2642 case OP_LIVERANGE_START:
2643 case OP_LIVERANGE_END:
2646 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2649 #if SIZEOF_VOID_P == 4
2650 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2652 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2656 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2660 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2662 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2664 case OP_DUMMY_ICONST:
2665 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2667 case OP_DUMMY_I8CONST:
2668 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2670 case OP_DUMMY_R8CONST:
2671 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2674 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2675 has_terminator = TRUE;
2681 LLVMBasicBlockRef new_bb;
2682 LLVMBuilderRef new_builder;
2684 // The default branch is already handled
2685 // FIXME: Handle it here
2687 /* Start new bblock */
2688 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2689 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2691 lhs = convert (ctx, lhs, LLVMInt32Type ());
2692 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2693 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2694 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2696 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2699 new_builder = create_builder (ctx);
2700 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2701 LLVMBuildUnreachable (new_builder);
2703 has_terminator = TRUE;
2704 g_assert (!ins->next);
2710 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2711 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2712 LLVMValueRef part1, retval;
2715 size = get_vtype_size (sig->ret);
2717 g_assert (addresses [ins->sreg1]);
2719 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2720 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2722 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2724 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2726 LLVMBuildRet (builder, retval);
2730 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2731 LLVMValueRef retval;
2733 g_assert (addresses [ins->sreg1]);
2734 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2735 LLVMBuildRet (builder, retval);
2739 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2740 LLVMBuildRetVoid (builder);
2744 if (linfo->ret.storage == LLVMArgFpStruct) {
2745 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2746 LLVMValueRef retval;
2748 g_assert (addresses [ins->sreg1]);
2749 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2750 LLVMBuildRet (builder, retval);
2754 if (!lhs || ctx->is_dead [ins->sreg1]) {
2756 * The method did not set its return value, probably because it
2757 * ends with a throw.
2760 LLVMBuildRetVoid (builder);
2762 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2764 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2766 has_terminator = TRUE;
2773 case OP_ICOMPARE_IMM:
2774 case OP_LCOMPARE_IMM:
2775 case OP_COMPARE_IMM: {
2779 if (ins->next->opcode == OP_NOP)
2782 if (ins->next->opcode == OP_BR)
2783 /* The comparison result is not needed */
2786 rel = mono_opcode_to_cond (ins->next->opcode);
2788 if (ins->opcode == OP_ICOMPARE_IMM) {
2789 lhs = convert (ctx, lhs, LLVMInt32Type ());
2790 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2792 if (ins->opcode == OP_LCOMPARE_IMM) {
2793 lhs = convert (ctx, lhs, LLVMInt64Type ());
2794 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2796 if (ins->opcode == OP_LCOMPARE) {
2797 lhs = convert (ctx, lhs, LLVMInt64Type ());
2798 rhs = convert (ctx, rhs, LLVMInt64Type ());
2800 if (ins->opcode == OP_ICOMPARE) {
2801 lhs = convert (ctx, lhs, LLVMInt32Type ());
2802 rhs = convert (ctx, rhs, LLVMInt32Type ());
2806 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2807 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2808 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2809 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2812 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2813 if (ins->opcode == OP_FCOMPARE) {
2814 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2815 } else if (ins->opcode == OP_RCOMPARE) {
2816 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2817 } else if (ins->opcode == OP_COMPARE_IMM) {
2818 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2819 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2821 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2822 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2823 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2824 /* The immediate is encoded in two fields */
2825 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2826 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2828 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2831 else if (ins->opcode == OP_COMPARE) {
2832 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2833 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2835 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2837 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2839 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2840 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2842 * If the target bb contains PHI instructions, LLVM requires
2843 * two PHI entries for this bblock, while we only generate one.
2844 * So convert this to an unconditional bblock. (bxc #171).
2846 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2848 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2850 has_terminator = TRUE;
2851 } else if (MONO_IS_SETCC (ins->next)) {
2852 sprintf (dname_buf, "t%d", ins->next->dreg);
2854 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2856 /* Add stores for volatile variables */
2857 emit_volatile_store (ctx, ins->next->dreg);
2858 } else if (MONO_IS_COND_EXC (ins->next)) {
2859 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2860 CHECK_FAILURE (ctx);
2861 builder = ctx->builder;
2863 LLVM_FAILURE (ctx, "next");
2877 rel = mono_opcode_to_cond (ins->opcode);
2879 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2880 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2891 rel = mono_opcode_to_cond (ins->opcode);
2893 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2894 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2902 gboolean empty = TRUE;
2904 /* Check that all input bblocks really branch to us */
2905 for (i = 0; i < bb->in_count; ++i) {
2906 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2907 ins->inst_phi_args [i + 1] = -1;
2913 /* LLVM doesn't like phi instructions with zero operands */
2914 ctx->is_dead [ins->dreg] = TRUE;
2918 /* Created earlier, insert it now */
2919 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2921 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2922 int sreg1 = ins->inst_phi_args [i + 1];
2926 * Count the number of times the incoming bblock branches to us,
2927 * since llvm requires a separate entry for each.
2929 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2930 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2933 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2934 if (switch_ins->inst_many_bb [j] == bb)
2941 /* Remember for later */
2942 for (j = 0; j < count; ++j) {
2943 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2946 node->in_bb = bb->in_bb [i];
2948 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);
2958 values [ins->dreg] = lhs;
2962 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2965 values [ins->dreg] = lhs;
2967 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2969 * This is added by the spilling pass in case of the JIT,
2970 * but we have to do it ourselves.
2972 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2976 case OP_MOVE_F_TO_I4: {
2977 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
2980 case OP_MOVE_I4_TO_F: {
2981 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
2984 case OP_MOVE_F_TO_I8: {
2985 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
2988 case OP_MOVE_I8_TO_F: {
2989 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3022 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3023 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3025 #ifdef MONO_ARCH_NEED_DIV_CHECK
3026 switch (ins->opcode) {
3037 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
3038 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
3039 CHECK_FAILURE (ctx);
3040 builder = ctx->builder;
3048 switch (ins->opcode) {
3051 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3055 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3059 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3063 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3067 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3071 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3075 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3079 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3083 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3087 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3091 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3095 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3099 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3103 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3107 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3110 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3113 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3117 g_assert_not_reached ();
3124 lhs = convert (ctx, lhs, LLVMFloatType ());
3125 rhs = convert (ctx, rhs, LLVMFloatType ());
3126 switch (ins->opcode) {
3128 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3131 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3134 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3137 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3140 g_assert_not_reached ();
3149 case OP_IREM_UN_IMM:
3151 case OP_IDIV_UN_IMM:
3157 case OP_ISHR_UN_IMM:
3166 case OP_LSHR_UN_IMM:
3172 case OP_SHR_UN_IMM: {
3175 if (spec [MONO_INST_SRC1] == 'l') {
3176 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3178 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3181 #if SIZEOF_VOID_P == 4
3182 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3183 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3186 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3187 lhs = convert (ctx, lhs, IntPtrType ());
3188 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3189 switch (ins->opcode) {
3193 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3197 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3201 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3205 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3207 case OP_IDIV_UN_IMM:
3208 case OP_LDIV_UN_IMM:
3209 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3213 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3215 case OP_IREM_UN_IMM:
3216 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3221 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3225 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3229 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3234 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3239 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3241 case OP_ISHR_UN_IMM:
3242 /* This is used to implement conv.u4, so the lhs could be an i8 */
3243 lhs = convert (ctx, lhs, LLVMInt32Type ());
3244 imm = convert (ctx, imm, LLVMInt32Type ());
3245 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3247 case OP_LSHR_UN_IMM:
3249 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3252 g_assert_not_reached ();
3257 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3260 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3263 lhs = convert (ctx, lhs, LLVMDoubleType ());
3264 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3267 lhs = convert (ctx, lhs, LLVMFloatType ());
3268 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3271 guint32 v = 0xffffffff;
3272 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3276 guint64 v = 0xffffffffffffffffLL;
3277 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3280 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3282 LLVMValueRef v1, v2;
3284 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3285 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3286 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3291 case OP_ICONV_TO_I1:
3292 case OP_ICONV_TO_I2:
3293 case OP_ICONV_TO_I4:
3294 case OP_ICONV_TO_U1:
3295 case OP_ICONV_TO_U2:
3296 case OP_ICONV_TO_U4:
3297 case OP_LCONV_TO_I1:
3298 case OP_LCONV_TO_I2:
3299 case OP_LCONV_TO_U1:
3300 case OP_LCONV_TO_U2:
3301 case OP_LCONV_TO_U4: {
3304 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);
3306 /* Have to do two casts since our vregs have type int */
3307 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3309 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3311 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3314 case OP_ICONV_TO_I8:
3315 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3317 case OP_ICONV_TO_U8:
3318 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3320 case OP_FCONV_TO_I4:
3321 case OP_RCONV_TO_I4:
3322 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3324 case OP_FCONV_TO_I1:
3325 case OP_RCONV_TO_I1:
3326 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3328 case OP_FCONV_TO_U1:
3329 case OP_RCONV_TO_U1:
3330 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3332 case OP_FCONV_TO_I2:
3333 case OP_RCONV_TO_I2:
3334 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3336 case OP_FCONV_TO_U2:
3337 case OP_RCONV_TO_U2:
3338 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3340 case OP_FCONV_TO_I8:
3341 case OP_RCONV_TO_I8:
3342 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3345 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3347 case OP_ICONV_TO_R8:
3348 case OP_LCONV_TO_R8:
3349 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3351 case OP_LCONV_TO_R_UN:
3352 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3354 #if SIZEOF_VOID_P == 4
3357 case OP_LCONV_TO_I4:
3358 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3360 case OP_ICONV_TO_R4:
3361 case OP_LCONV_TO_R4:
3362 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3364 values [ins->dreg] = v;
3366 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3368 case OP_FCONV_TO_R4:
3369 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3371 values [ins->dreg] = v;
3373 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3375 case OP_RCONV_TO_R8:
3376 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3378 case OP_RCONV_TO_R4:
3379 values [ins->dreg] = lhs;
3382 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3385 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3388 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3390 case OP_LOCALLOC_IMM: {
3393 guint32 size = ins->inst_imm;
3394 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3396 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3398 if (ins->flags & MONO_INST_INIT) {
3399 LLVMValueRef args [5];
3402 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3403 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3404 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3405 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3406 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3409 values [ins->dreg] = v;
3413 LLVMValueRef v, size;
3415 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), "");
3417 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3419 if (ins->flags & MONO_INST_INIT) {
3420 LLVMValueRef args [5];
3423 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3425 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3426 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3427 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3429 values [ins->dreg] = v;
3433 case OP_LOADI1_MEMBASE:
3434 case OP_LOADU1_MEMBASE:
3435 case OP_LOADI2_MEMBASE:
3436 case OP_LOADU2_MEMBASE:
3437 case OP_LOADI4_MEMBASE:
3438 case OP_LOADU4_MEMBASE:
3439 case OP_LOADI8_MEMBASE:
3440 case OP_LOADR4_MEMBASE:
3441 case OP_LOADR8_MEMBASE:
3442 case OP_LOAD_MEMBASE:
3450 LLVMValueRef base, index, addr;
3452 gboolean sext = FALSE, zext = FALSE;
3453 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3455 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3460 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)) {
3461 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3466 if (ins->inst_offset == 0) {
3468 } else if (ins->inst_offset % size != 0) {
3469 /* Unaligned load */
3470 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3471 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3473 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3474 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3478 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3480 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3482 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3484 * These will signal LLVM that these loads do not alias any stores, and
3485 * they can't fail, allowing them to be hoisted out of loops.
3487 set_invariant_load_flag (values [ins->dreg]);
3488 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3492 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3494 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3495 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3496 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3500 case OP_STOREI1_MEMBASE_REG:
3501 case OP_STOREI2_MEMBASE_REG:
3502 case OP_STOREI4_MEMBASE_REG:
3503 case OP_STOREI8_MEMBASE_REG:
3504 case OP_STORER4_MEMBASE_REG:
3505 case OP_STORER8_MEMBASE_REG:
3506 case OP_STORE_MEMBASE_REG: {
3508 LLVMValueRef index, addr;
3510 gboolean sext = FALSE, zext = FALSE;
3511 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3513 if (!values [ins->inst_destbasereg])
3514 LLVM_FAILURE (ctx, "inst_destbasereg");
3516 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3518 if (ins->inst_offset % size != 0) {
3519 /* Unaligned store */
3520 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3521 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3523 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3524 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3526 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3530 case OP_STOREI1_MEMBASE_IMM:
3531 case OP_STOREI2_MEMBASE_IMM:
3532 case OP_STOREI4_MEMBASE_IMM:
3533 case OP_STOREI8_MEMBASE_IMM:
3534 case OP_STORE_MEMBASE_IMM: {
3536 LLVMValueRef index, addr;
3538 gboolean sext = FALSE, zext = FALSE;
3539 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3541 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3543 if (ins->inst_offset % size != 0) {
3544 /* Unaligned store */
3545 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3546 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3548 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3549 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3551 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3556 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3558 case OP_OUTARG_VTRETADDR:
3566 case OP_VOIDCALL_MEMBASE:
3567 case OP_CALL_MEMBASE:
3568 case OP_LCALL_MEMBASE:
3569 case OP_FCALL_MEMBASE:
3570 case OP_RCALL_MEMBASE:
3571 case OP_VCALL_MEMBASE:
3572 case OP_VOIDCALL_REG:
3577 case OP_VCALL_REG: {
3578 process_call (ctx, bb, &builder, ins);
3579 CHECK_FAILURE (ctx);
3584 LLVMValueRef indexes [2];
3586 LLVMValueRef got_entry_addr;
3589 * FIXME: Can't allocate from the cfg mempool since that is freed if
3590 * the LLVM compile fails.
3592 ji = g_new0 (MonoJumpInfo, 1);
3593 ji->type = (MonoJumpInfoType)ins->inst_i1;
3594 ji->data.target = ins->inst_p0;
3596 ji = mono_aot_patch_info_dup (ji);
3598 ji->next = cfg->patch_info;
3599 cfg->patch_info = ji;
3601 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3602 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3603 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3605 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3606 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3607 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3609 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3610 set_invariant_load_flag (values [ins->dreg]);
3613 case OP_NOT_REACHED:
3614 LLVMBuildUnreachable (builder);
3615 has_terminator = TRUE;
3616 g_assert (bb->block_num < cfg->max_block_num);
3617 ctx->unreachable [bb->block_num] = TRUE;
3618 /* Might have instructions after this */
3620 MonoInst *next = ins->next;
3622 * FIXME: If later code uses the regs defined by these instructions,
3623 * compilation will fail.
3625 MONO_DELETE_INS (bb, next);
3629 MonoInst *var = ins->inst_p0;
3631 values [ins->dreg] = addresses [var->dreg];
3635 LLVMValueRef args [1];
3637 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3638 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3642 LLVMValueRef args [1];
3644 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3645 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3649 LLVMValueRef args [1];
3652 /* This no longer seems to happen */
3654 * LLVM optimizes sqrt(nan) into undefined in
3655 * lib/Analysis/ConstantFolding.cpp
3656 * Also, sqrt(NegativeInfinity) is optimized into 0.
3658 LLVM_FAILURE (ctx, "sqrt");
3660 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3661 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3665 LLVMValueRef args [1];
3667 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3668 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3682 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3683 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3685 switch (ins->opcode) {
3688 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3692 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3696 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3700 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3703 g_assert_not_reached ();
3706 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3709 case OP_ATOMIC_EXCHANGE_I4:
3710 case OP_ATOMIC_EXCHANGE_I8: {
3711 LLVMValueRef args [2];
3714 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3715 t = LLVMInt32Type ();
3717 t = LLVMInt64Type ();
3719 g_assert (ins->inst_offset == 0);
3721 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3722 args [1] = convert (ctx, rhs, t);
3724 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3727 case OP_ATOMIC_ADD_I4:
3728 case OP_ATOMIC_ADD_I8: {
3729 LLVMValueRef args [2];
3732 if (ins->opcode == OP_ATOMIC_ADD_I4)
3733 t = LLVMInt32Type ();
3735 t = LLVMInt64Type ();
3737 g_assert (ins->inst_offset == 0);
3739 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3740 args [1] = convert (ctx, rhs, t);
3741 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3744 case OP_ATOMIC_CAS_I4:
3745 case OP_ATOMIC_CAS_I8: {
3746 LLVMValueRef args [3], val;
3749 if (ins->opcode == OP_ATOMIC_CAS_I4)
3750 t = LLVMInt32Type ();
3752 t = LLVMInt64Type ();
3754 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3756 args [1] = convert (ctx, values [ins->sreg3], t);
3758 args [2] = convert (ctx, values [ins->sreg2], t);
3759 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3760 #if LLVM_API_VERSION >= 1
3761 /* cmpxchg returns a pair */
3762 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3764 values [ins->dreg] = val;
3768 case OP_MEMORY_BARRIER: {
3769 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3772 case OP_ATOMIC_LOAD_I1:
3773 case OP_ATOMIC_LOAD_I2:
3774 case OP_ATOMIC_LOAD_I4:
3775 case OP_ATOMIC_LOAD_I8:
3776 case OP_ATOMIC_LOAD_U1:
3777 case OP_ATOMIC_LOAD_U2:
3778 case OP_ATOMIC_LOAD_U4:
3779 case OP_ATOMIC_LOAD_U8:
3780 case OP_ATOMIC_LOAD_R4:
3781 case OP_ATOMIC_LOAD_R8: {
3782 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3783 #if LLVM_API_VERSION >= 4
3785 gboolean sext, zext;
3787 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3788 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3789 LLVMValueRef index, addr;
3791 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3796 if (ins->inst_offset != 0) {
3797 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3798 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3803 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3805 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3808 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3810 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3812 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3816 case OP_ATOMIC_STORE_I1:
3817 case OP_ATOMIC_STORE_I2:
3818 case OP_ATOMIC_STORE_I4:
3819 case OP_ATOMIC_STORE_I8:
3820 case OP_ATOMIC_STORE_U1:
3821 case OP_ATOMIC_STORE_U2:
3822 case OP_ATOMIC_STORE_U4:
3823 case OP_ATOMIC_STORE_U8:
3824 case OP_ATOMIC_STORE_R4:
3825 case OP_ATOMIC_STORE_R8: {
3826 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3827 #if LLVM_API_VERSION >= 4
3829 gboolean sext, zext;
3831 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3832 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3833 LLVMValueRef index, addr, value;
3835 if (!values [ins->inst_destbasereg])
3836 LLVM_FAILURE (ctx, "inst_destbasereg");
3838 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3840 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3841 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3842 value = convert (ctx, values [ins->sreg1], t);
3844 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3847 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
3851 case OP_RELAXED_NOP: {
3852 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3853 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3860 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3862 // 257 == FS segment register
3863 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3865 // 256 == GS segment register
3866 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3869 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3870 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3871 /* See mono_amd64_emit_tls_get () */
3872 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3874 // 256 == GS segment register
3875 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3876 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3878 LLVM_FAILURE (ctx, "opcode tls-get");
3883 case OP_TLS_GET_REG: {
3884 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3885 /* See emit_tls_get_reg () */
3886 // 256 == GS segment register
3887 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3888 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3890 LLVM_FAILURE (ctx, "opcode tls-get");
3899 case OP_IADD_OVF_UN:
3901 case OP_ISUB_OVF_UN:
3903 case OP_IMUL_OVF_UN:
3904 #if SIZEOF_VOID_P == 8
3906 case OP_LADD_OVF_UN:
3908 case OP_LSUB_OVF_UN:
3910 case OP_LMUL_OVF_UN:
3913 LLVMValueRef args [2], val, ovf, func;
3915 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3916 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3917 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3919 val = LLVMBuildCall (builder, func, args, 2, "");
3920 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3921 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3922 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3923 CHECK_FAILURE (ctx);
3924 builder = ctx->builder;
3930 * We currently model them using arrays. Promotion to local vregs is
3931 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3932 * so we always have an entry in cfg->varinfo for them.
3933 * FIXME: Is this needed ?
3936 MonoClass *klass = ins->klass;
3937 LLVMValueRef args [5];
3941 LLVM_FAILURE (ctx, "!klass");
3945 if (!addresses [ins->dreg])
3946 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3947 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3948 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3949 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3951 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3952 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3953 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3956 case OP_DUMMY_VZERO:
3959 case OP_STOREV_MEMBASE:
3960 case OP_LOADV_MEMBASE:
3962 MonoClass *klass = ins->klass;
3963 LLVMValueRef src = NULL, dst, args [5];
3964 gboolean done = FALSE;
3968 LLVM_FAILURE (ctx, "!klass");
3972 if (mini_is_gsharedvt_klass (cfg, klass)) {
3974 LLVM_FAILURE (ctx, "gsharedvt");
3978 switch (ins->opcode) {
3979 case OP_STOREV_MEMBASE:
3980 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3981 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3982 /* Decomposed earlier */
3983 g_assert_not_reached ();
3986 if (!addresses [ins->sreg1]) {
3988 g_assert (values [ins->sreg1]);
3989 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));
3990 LLVMBuildStore (builder, values [ins->sreg1], dst);
3993 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3994 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3997 case OP_LOADV_MEMBASE:
3998 if (!addresses [ins->dreg])
3999 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4000 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4001 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4004 if (!addresses [ins->sreg1])
4005 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4006 if (!addresses [ins->dreg])
4007 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4008 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4009 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4012 g_assert_not_reached ();
4014 CHECK_FAILURE (ctx);
4021 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4022 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4024 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4025 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4026 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4029 case OP_LLVM_OUTARG_VT:
4030 if (!addresses [ins->sreg1]) {
4031 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4032 g_assert (values [ins->sreg1]);
4033 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4035 addresses [ins->dreg] = addresses [ins->sreg1];
4041 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4043 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4046 case OP_LOADX_MEMBASE: {
4047 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4050 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4051 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4054 case OP_STOREX_MEMBASE: {
4055 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4058 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4059 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4066 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4070 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4076 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4080 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4084 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4088 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4091 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4094 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4097 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4101 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4112 LLVMValueRef v = NULL;
4114 switch (ins->opcode) {
4119 t = LLVMVectorType (LLVMInt32Type (), 4);
4120 rt = LLVMVectorType (LLVMFloatType (), 4);
4126 t = LLVMVectorType (LLVMInt64Type (), 2);
4127 rt = LLVMVectorType (LLVMDoubleType (), 2);
4130 t = LLVMInt32Type ();
4131 rt = LLVMInt32Type ();
4132 g_assert_not_reached ();
4135 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4136 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4137 switch (ins->opcode) {
4140 v = LLVMBuildAnd (builder, lhs, rhs, "");
4144 v = LLVMBuildOr (builder, lhs, rhs, "");
4148 v = LLVMBuildXor (builder, lhs, rhs, "");
4152 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4155 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4179 case OP_PADDB_SAT_UN:
4180 case OP_PADDW_SAT_UN:
4181 case OP_PSUBB_SAT_UN:
4182 case OP_PSUBW_SAT_UN:
4190 case OP_PMULW_HIGH_UN: {
4191 LLVMValueRef args [2];
4196 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4203 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4207 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4215 case OP_EXTRACTX_U2:
4217 case OP_EXTRACT_U1: {
4219 gboolean zext = FALSE;
4221 t = simd_op_to_llvm_type (ins->opcode);
4223 switch (ins->opcode) {
4231 case OP_EXTRACTX_U2:
4236 t = LLVMInt32Type ();
4237 g_assert_not_reached ();
4240 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4241 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4243 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4252 case OP_EXPAND_R8: {
4253 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4254 LLVMValueRef mask [16], v;
4257 for (i = 0; i < 16; ++i)
4258 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4260 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4262 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4263 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4268 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4271 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4274 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4277 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4280 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4283 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4294 case OP_EXTRACT_MASK:
4301 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4303 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4309 LLVMValueRef args [3];
4313 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4315 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4320 /* This is only used for implementing shifts by non-immediate */
4321 values [ins->dreg] = lhs;
4332 LLVMValueRef args [3];
4335 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4337 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4348 case OP_PSHLQ_REG: {
4349 LLVMValueRef args [3];
4352 args [1] = values [ins->sreg2];
4354 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4361 case OP_PSHUFLEW_LOW:
4362 case OP_PSHUFLEW_HIGH: {
4364 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4365 int i, mask_size = 0;
4366 int imask = ins->inst_c0;
4368 /* Convert the x86 shuffle mask to LLVM's */
4369 switch (ins->opcode) {
4372 mask [0] = ((imask >> 0) & 3);
4373 mask [1] = ((imask >> 2) & 3);
4374 mask [2] = ((imask >> 4) & 3) + 4;
4375 mask [3] = ((imask >> 6) & 3) + 4;
4376 v1 = values [ins->sreg1];
4377 v2 = values [ins->sreg2];
4381 mask [0] = ((imask >> 0) & 1);
4382 mask [1] = ((imask >> 1) & 1) + 2;
4383 v1 = values [ins->sreg1];
4384 v2 = values [ins->sreg2];
4386 case OP_PSHUFLEW_LOW:
4388 mask [0] = ((imask >> 0) & 3);
4389 mask [1] = ((imask >> 2) & 3);
4390 mask [2] = ((imask >> 4) & 3);
4391 mask [3] = ((imask >> 6) & 3);
4396 v1 = values [ins->sreg1];
4397 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4399 case OP_PSHUFLEW_HIGH:
4405 mask [4] = 4 + ((imask >> 0) & 3);
4406 mask [5] = 4 + ((imask >> 2) & 3);
4407 mask [6] = 4 + ((imask >> 4) & 3);
4408 mask [7] = 4 + ((imask >> 6) & 3);
4409 v1 = values [ins->sreg1];
4410 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4414 mask [0] = ((imask >> 0) & 3);
4415 mask [1] = ((imask >> 2) & 3);
4416 mask [2] = ((imask >> 4) & 3);
4417 mask [3] = ((imask >> 6) & 3);
4418 v1 = values [ins->sreg1];
4419 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4422 g_assert_not_reached ();
4424 for (i = 0; i < mask_size; ++i)
4425 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4427 values [ins->dreg] =
4428 LLVMBuildShuffleVector (builder, v1, v2,
4429 LLVMConstVector (mask_values, mask_size), dname);
4433 case OP_UNPACK_LOWB:
4434 case OP_UNPACK_LOWW:
4435 case OP_UNPACK_LOWD:
4436 case OP_UNPACK_LOWQ:
4437 case OP_UNPACK_LOWPS:
4438 case OP_UNPACK_LOWPD:
4439 case OP_UNPACK_HIGHB:
4440 case OP_UNPACK_HIGHW:
4441 case OP_UNPACK_HIGHD:
4442 case OP_UNPACK_HIGHQ:
4443 case OP_UNPACK_HIGHPS:
4444 case OP_UNPACK_HIGHPD: {
4446 LLVMValueRef mask_values [16];
4447 int i, mask_size = 0;
4448 gboolean low = FALSE;
4450 switch (ins->opcode) {
4451 case OP_UNPACK_LOWB:
4455 case OP_UNPACK_LOWW:
4459 case OP_UNPACK_LOWD:
4460 case OP_UNPACK_LOWPS:
4464 case OP_UNPACK_LOWQ:
4465 case OP_UNPACK_LOWPD:
4469 case OP_UNPACK_HIGHB:
4472 case OP_UNPACK_HIGHW:
4475 case OP_UNPACK_HIGHD:
4476 case OP_UNPACK_HIGHPS:
4479 case OP_UNPACK_HIGHQ:
4480 case OP_UNPACK_HIGHPD:
4484 g_assert_not_reached ();
4488 for (i = 0; i < (mask_size / 2); ++i) {
4490 mask [(i * 2) + 1] = mask_size + i;
4493 for (i = 0; i < (mask_size / 2); ++i) {
4494 mask [(i * 2)] = (mask_size / 2) + i;
4495 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4499 for (i = 0; i < mask_size; ++i)
4500 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4502 values [ins->dreg] =
4503 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4504 LLVMConstVector (mask_values, mask_size), dname);
4509 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4510 LLVMValueRef v, val;
4512 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4513 val = LLVMConstNull (t);
4514 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4515 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4517 values [ins->dreg] = val;
4521 case OP_DUPPS_HIGH: {
4522 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4523 LLVMValueRef v1, v2, val;
4526 if (ins->opcode == OP_DUPPS_LOW) {
4527 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4528 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4530 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4531 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4533 val = LLVMConstNull (t);
4534 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4535 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4536 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4537 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4539 values [ins->dreg] = val;
4549 * EXCEPTION HANDLING
4551 case OP_IMPLICIT_EXCEPTION:
4552 /* This marks a place where an implicit exception can happen */
4553 if (bb->region != -1)
4554 LLVM_FAILURE (ctx, "implicit-exception");
4558 MonoMethodSignature *throw_sig;
4559 LLVMValueRef callee, arg;
4560 gboolean rethrow = (ins->opcode == OP_RETHROW);
4561 const char *icall_name;
4563 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4564 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4567 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4568 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4569 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4570 if (cfg->compile_aot) {
4571 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4573 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4577 * LLVM doesn't push the exception argument, so we need a different
4580 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4582 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4586 mono_memory_barrier ();
4588 ctx->lmodule->rethrow = callee;
4590 ctx->lmodule->throw = callee;
4592 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4593 emit_call (ctx, bb, &builder, callee, &arg, 1);
4596 case OP_CALL_HANDLER: {
4598 * We don't 'call' handlers, but instead simply branch to them.
4599 * The code generated by ENDFINALLY will branch back to us.
4601 LLVMBasicBlockRef noex_bb;
4603 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4605 bb_list = info->call_handler_return_bbs;
4608 * Set the indicator variable for the finally clause.
4610 lhs = info->finally_ind;
4612 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4614 /* Branch to the finally clause */
4615 LLVMBuildBr (builder, info->call_handler_target_bb);
4617 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4618 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4620 builder = ctx->builder = create_builder (ctx);
4621 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4623 bblocks [bb->block_num].end_bblock = noex_bb;
4626 case OP_START_HANDLER: {
4629 case OP_ENDFINALLY: {
4630 LLVMBasicBlockRef resume_bb;
4631 MonoBasicBlock *handler_bb;
4632 LLVMValueRef val, switch_ins, callee;
4636 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4637 g_assert (handler_bb);
4638 info = &bblocks [handler_bb->block_num];
4639 lhs = info->finally_ind;
4642 bb_list = info->call_handler_return_bbs;
4644 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4646 /* Load the finally variable */
4647 val = LLVMBuildLoad (builder, lhs, "");
4649 /* Reset the variable */
4650 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4652 /* Branch to either resume_bb, or to the bblocks in bb_list */
4653 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4655 * The other targets are added at the end to handle OP_CALL_HANDLER
4656 * opcodes processed later.
4658 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4660 builder = ctx->builder = create_builder (ctx);
4661 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4663 if (ctx->cfg->compile_aot) {
4664 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4666 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4668 LLVMBuildCall (builder, callee, NULL, 0, "");
4670 LLVMBuildUnreachable (builder);
4671 has_terminator = TRUE;
4677 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4678 LLVM_FAILURE (ctx, reason);
4683 /* Convert the value to the type required by phi nodes */
4684 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4685 if (!values [ins->dreg])
4687 values [ins->dreg] = addresses [ins->dreg];
4689 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4692 /* Add stores for volatile variables */
4693 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4694 emit_volatile_store (ctx, ins->dreg);
4697 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4698 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4700 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4701 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4702 LLVMBuildRetVoid (builder);
4705 if (bb == cfg->bb_entry)
4706 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4715 * mono_llvm_check_method_supported:
4717 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4718 * compiling a method twice.
4721 mono_llvm_check_method_supported (MonoCompile *cfg)
4723 MonoMethodHeader *header = cfg->header;
4724 MonoExceptionClause *clause;
4727 if (cfg->method->save_lmf) {
4728 cfg->exception_message = g_strdup ("lmf");
4729 cfg->disable_llvm = TRUE;
4731 if (cfg->disable_llvm)
4735 for (i = 0; i < header->num_clauses; ++i) {
4736 clause = &header->clauses [i];
4738 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4740 * FIXME: Some tests still fail with nested clauses.
4742 cfg->exception_message = g_strdup ("nested clauses");
4743 cfg->disable_llvm = TRUE;
4747 if (cfg->disable_llvm)
4752 if (cfg->method->dynamic) {
4753 cfg->exception_message = g_strdup ("dynamic.");
4754 cfg->disable_llvm = TRUE;
4756 if (cfg->disable_llvm)
4761 * mono_llvm_emit_method:
4763 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4766 mono_llvm_emit_method (MonoCompile *cfg)
4769 MonoMethodSignature *sig;
4771 LLVMTypeRef method_type;
4772 LLVMValueRef method = NULL;
4774 LLVMValueRef *values;
4775 int i, max_block_num, bb_index;
4776 gboolean last = FALSE;
4777 GPtrArray *phi_values;
4778 LLVMCallInfo *linfo;
4780 LLVMModuleRef module;
4782 GPtrArray *bblock_list;
4783 MonoMethodHeader *header;
4784 MonoExceptionClause *clause;
4788 /* The code below might acquire the loader lock, so use it for global locking */
4789 mono_loader_lock ();
4791 /* Used to communicate with the callbacks */
4792 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4794 ctx = g_new0 (EmitContext, 1);
4796 ctx->mempool = cfg->mempool;
4799 * This maps vregs to the LLVM instruction defining them
4801 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4803 * This maps vregs for volatile variables to the LLVM instruction defining their
4806 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4807 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4808 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4809 phi_values = g_ptr_array_sized_new (256);
4811 * This signals whenever the vreg was defined by a phi node with no input vars
4812 * (i.e. all its input bblocks end with NOT_REACHABLE).
4814 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4815 /* Whenever the bblock is unreachable */
4816 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4818 bblock_list = g_ptr_array_sized_new (256);
4820 ctx->values = values;
4821 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4823 if (cfg->compile_aot) {
4824 ctx->lmodule = &aot_module;
4825 method_name = mono_aot_get_method_name (cfg);
4826 cfg->llvm_method_name = g_strdup (method_name);
4828 init_jit_module (cfg->domain);
4829 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4830 method_name = mono_method_full_name (cfg->method, TRUE);
4833 module = ctx->module = ctx->lmodule->module;
4836 LLVM_FAILURE (ctx, "gsharedvt");
4840 static int count = 0;
4843 if (g_getenv ("LLVM_COUNT")) {
4844 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4845 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4849 if (count > atoi (g_getenv ("LLVM_COUNT")))
4850 LLVM_FAILURE (ctx, "");
4855 sig = mono_method_signature (cfg->method);
4858 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4860 CHECK_FAILURE (ctx);
4863 linfo->rgctx_arg = TRUE;
4864 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4865 CHECK_FAILURE (ctx);
4868 * This maps parameter indexes in the original signature to the indexes in
4869 * the LLVM signature.
4871 ctx->pindexes = sinfo.pindexes;
4873 method = LLVMAddFunction (module, method_name, method_type);
4874 ctx->lmethod = method;
4876 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4877 LLVMSetLinkage (method, LLVMPrivateLinkage);
4879 LLVMAddFunctionAttr (method, LLVMUWTable);
4881 if (cfg->compile_aot) {
4882 LLVMSetLinkage (method, LLVMInternalLinkage);
4883 #if LLVM_API_VERSION == 0
4884 /* This causes an assertion in later LLVM versions */
4885 LLVMSetVisibility (method, LLVMHiddenVisibility);
4887 if (ctx->lmodule->external_symbols) {
4888 LLVMSetLinkage (method, LLVMExternalLinkage);
4889 LLVMSetVisibility (method, LLVMHiddenVisibility);
4892 LLVMSetLinkage (method, LLVMPrivateLinkage);
4895 if (cfg->method->save_lmf)
4896 LLVM_FAILURE (ctx, "lmf");
4898 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4899 LLVM_FAILURE (ctx, "pinvoke signature");
4901 header = cfg->header;
4902 for (i = 0; i < header->num_clauses; ++i) {
4903 clause = &header->clauses [i];
4904 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4905 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4907 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
4908 /* We can't handle inlined methods with clauses */
4909 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
4911 if (linfo->rgctx_arg) {
4912 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4914 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4915 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4916 * CC_X86_64_Mono in X86CallingConv.td.
4918 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4919 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4921 if (cfg->vret_addr) {
4922 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4923 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4926 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4927 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4930 names = g_new (char *, sig->param_count);
4931 mono_method_get_param_names (cfg->method, (const char **) names);
4933 for (i = 0; i < sig->param_count; ++i) {
4936 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4937 if (names [i] && names [i][0] != '\0')
4938 name = g_strdup_printf ("arg_%s", names [i]);
4940 name = g_strdup_printf ("arg_%d", i);
4941 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4943 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4944 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4948 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
4949 ctx->minfo = mono_debug_lookup_method (cfg->method);
4950 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
4954 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4955 max_block_num = MAX (max_block_num, bb->block_num);
4956 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4958 /* Add branches between non-consecutive bblocks */
4959 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4960 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4961 bb->next_bb != bb->last_ins->inst_false_bb) {
4963 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4964 inst->opcode = OP_BR;
4965 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4966 mono_bblock_add_inst (bb, inst);
4971 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4972 * was later optimized away, so clear these flags, and add them back for the still
4973 * present OP_LDADDR instructions.
4975 for (i = 0; i < cfg->next_vreg; ++i) {
4978 ins = get_vreg_to_inst (cfg, i);
4979 if (ins && ins != cfg->rgctx_var)
4980 ins->flags &= ~MONO_INST_INDIRECT;
4984 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4986 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4988 LLVMBuilderRef builder;
4990 char dname_buf[128];
4992 builder = create_builder (ctx);
4994 for (ins = bb->code; ins; ins = ins->next) {
4995 switch (ins->opcode) {
5000 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5002 CHECK_FAILURE (ctx);
5004 if (ins->opcode == OP_VPHI) {
5005 /* Treat valuetype PHI nodes as operating on the address itself */
5006 g_assert (ins->klass);
5007 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5011 * Have to precreate these, as they can be referenced by
5012 * earlier instructions.
5014 sprintf (dname_buf, "t%d", ins->dreg);
5016 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5018 if (ins->opcode == OP_VPHI)
5019 ctx->addresses [ins->dreg] = values [ins->dreg];
5021 g_ptr_array_add (phi_values, values [ins->dreg]);
5024 * Set the expected type of the incoming arguments since these have
5025 * to have the same type.
5027 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5028 int sreg1 = ins->inst_phi_args [i + 1];
5031 ctx->vreg_types [sreg1] = phi_type;
5036 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5045 * Create an ordering for bblocks, use the depth first order first, then
5046 * put the exception handling bblocks last.
5048 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5049 bb = cfg->bblocks [bb_index];
5050 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5051 g_ptr_array_add (bblock_list, bb);
5052 bblocks [bb->block_num].added = TRUE;
5056 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5057 if (!bblocks [bb->block_num].added)
5058 g_ptr_array_add (bblock_list, bb);
5062 * Second pass: generate code.
5064 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5065 bb = g_ptr_array_index (bblock_list, bb_index);
5067 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5070 process_bb (ctx, bb);
5071 CHECK_FAILURE (ctx);
5074 /* Add incoming phi values */
5075 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5076 GSList *l, *ins_list;
5078 ins_list = bblocks [bb->block_num].phi_nodes;
5080 for (l = ins_list; l; l = l->next) {
5081 PhiNode *node = l->data;
5082 MonoInst *phi = node->phi;
5083 int sreg1 = node->sreg;
5084 LLVMBasicBlockRef in_bb;
5089 in_bb = get_end_bb (ctx, node->in_bb);
5091 if (ctx->unreachable [node->in_bb->block_num])
5094 if (!values [sreg1])
5095 /* Can happen with values in EH clauses */
5096 LLVM_FAILURE (ctx, "incoming phi sreg1");
5098 if (phi->opcode == OP_VPHI) {
5099 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5100 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5102 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5104 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5105 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5106 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5111 /* Create the SWITCH statements for ENDFINALLY instructions */
5112 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5113 BBInfo *info = &bblocks [bb->block_num];
5115 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5116 LLVMValueRef switch_ins = l->data;
5117 GSList *bb_list = info->call_handler_return_bbs;
5119 for (i = 0; i < g_slist_length (bb_list); ++i)
5120 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5124 if (cfg->verbose_level > 1)
5125 mono_llvm_dump_value (method);
5127 if (cfg->compile_aot)
5128 mark_as_used (ctx->lmodule, method);
5130 if (cfg->compile_aot) {
5131 LLVMValueRef md_args [16];
5132 LLVMValueRef md_node;
5135 method_index = mono_aot_get_method_index (cfg->orig_method);
5136 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5137 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5138 md_node = LLVMMDNode (md_args, 2);
5139 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5140 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5143 if (cfg->compile_aot) {
5144 /* Don't generate native code, keep the LLVM IR */
5145 if (cfg->compile_aot && cfg->verbose_level)
5146 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5148 //LLVMVerifyFunction(method, 0);
5150 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5152 if (cfg->verbose_level > 1)
5153 mono_llvm_dump_value (method);
5155 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5157 /* Set by emit_cb */
5158 g_assert (cfg->code_len);
5160 /* FIXME: Free the LLVM IL for the function */
5163 if (ctx->lmodule->method_to_lmethod)
5164 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5171 /* Need to add unused phi nodes as they can be referenced by other values */
5172 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5173 LLVMBuilderRef builder;
5175 builder = create_builder (ctx);
5176 LLVMPositionBuilderAtEnd (builder, phi_bb);
5178 for (i = 0; i < phi_values->len; ++i) {
5179 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5180 if (LLVMGetInstructionParent (v) == NULL)
5181 LLVMInsertIntoBuilder (builder, v);
5184 LLVMDeleteFunction (method);
5189 g_free (ctx->addresses);
5190 g_free (ctx->vreg_types);
5191 g_free (ctx->vreg_cli_types);
5192 g_free (ctx->pindexes);
5193 g_free (ctx->is_dead);
5194 g_free (ctx->unreachable);
5195 g_ptr_array_free (phi_values, TRUE);
5196 g_free (ctx->bblocks);
5197 g_hash_table_destroy (ctx->region_to_handler);
5198 g_free (method_name);
5199 g_ptr_array_free (bblock_list, TRUE);
5201 for (l = ctx->builders; l; l = l->next) {
5202 LLVMBuilderRef builder = l->data;
5203 LLVMDisposeBuilder (builder);
5208 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5210 mono_loader_unlock ();
5214 * mono_llvm_emit_call:
5216 * Same as mono_arch_emit_call () for LLVM.
5219 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5222 MonoMethodSignature *sig;
5223 int i, n, stack_size;
5228 sig = call->signature;
5229 n = sig->param_count + sig->hasthis;
5231 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5233 if (cfg->disable_llvm)
5236 if (sig->call_convention == MONO_CALL_VARARG) {
5237 cfg->exception_message = g_strdup ("varargs");
5238 cfg->disable_llvm = TRUE;
5241 for (i = 0; i < n; ++i) {
5244 ainfo = call->cinfo->args + i;
5246 in = call->args [i];
5248 /* Simply remember the arguments */
5249 switch (ainfo->storage) {
5251 case LLVMArgInFPReg: {
5252 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5255 opcode = mono_type_to_regmove (cfg, t);
5256 if (opcode == OP_FMOVE) {
5257 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5258 ins->dreg = mono_alloc_freg (cfg);
5259 } else if (opcode == OP_LMOVE) {
5260 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5261 ins->dreg = mono_alloc_lreg (cfg);
5263 MONO_INST_NEW (cfg, ins, OP_MOVE);
5264 ins->dreg = mono_alloc_ireg (cfg);
5266 ins->sreg1 = in->dreg;
5269 case LLVMArgVtypeByVal:
5270 case LLVMArgVtypeInReg:
5271 case LLVMArgAsIArgs:
5272 case LLVMArgAsFpArgs:
5273 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5274 ins->dreg = mono_alloc_ireg (cfg);
5275 ins->sreg1 = in->dreg;
5276 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5279 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5280 cfg->exception_message = g_strdup ("ainfo->storage");
5281 cfg->disable_llvm = TRUE;
5285 if (!cfg->disable_llvm) {
5286 MONO_ADD_INS (cfg->cbb, ins);
5287 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5292 static unsigned char*
5293 alloc_cb (LLVMValueRef function, int size)
5297 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5301 return mono_domain_code_reserve (cfg->domain, size);
5303 return mono_domain_code_reserve (mono_domain_get (), size);
5308 emitted_cb (LLVMValueRef function, void *start, void *end)
5312 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5314 cfg->code_len = (guint8*)end - (guint8*)start;
5318 exception_cb (void *data)
5321 MonoJitExceptionInfo *ei;
5322 guint32 ei_len, i, j, nested_len, nindex;
5323 gpointer *type_info;
5324 int this_reg, this_offset;
5326 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5330 * data points to a DWARF FDE structure, convert it to our unwind format and
5332 * An alternative would be to save it directly, and modify our unwinder to work
5335 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);
5336 if (cfg->verbose_level > 1)
5337 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5339 /* Count nested clauses */
5341 for (i = 0; i < ei_len; ++i) {
5342 for (j = 0; j < ei_len; ++j) {
5343 gint32 cindex1 = *(gint32*)type_info [i];
5344 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5345 gint32 cindex2 = *(gint32*)type_info [j];
5346 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5348 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5354 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5355 cfg->llvm_ex_info_len = ei_len + nested_len;
5356 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5357 /* Fill the rest of the information from the type info */
5358 for (i = 0; i < ei_len; ++i) {
5359 gint32 clause_index = *(gint32*)type_info [i];
5360 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5362 cfg->llvm_ex_info [i].flags = clause->flags;
5363 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5367 * For nested clauses, the LLVM produced exception info associates the try interval with
5368 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5370 /* FIXME: These should be order with the normal clauses */
5372 for (i = 0; i < ei_len; ++i) {
5373 for (j = 0; j < ei_len; ++j) {
5374 gint32 cindex1 = *(gint32*)type_info [i];
5375 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5376 gint32 cindex2 = *(gint32*)type_info [j];
5377 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5379 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5381 * The try interval comes from the nested clause, everything else from the
5384 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5385 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5386 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5391 g_assert (nindex == ei_len + nested_len);
5392 cfg->llvm_this_reg = this_reg;
5393 cfg->llvm_this_offset = this_offset;
5395 /* type_info [i] is cfg mempool allocated, no need to free it */
5402 dlsym_cb (const char *name, void **symbol)
5408 if (!strcmp (name, "__bzero")) {
5409 *symbol = (void*)bzero;
5411 current = mono_dl_open (NULL, 0, NULL);
5414 err = mono_dl_symbol (current, name, symbol);
5416 mono_dl_close (current);
5418 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5419 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5425 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5427 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5431 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5433 LLVMTypeRef param_types [4];
5435 param_types [0] = param_type1;
5436 param_types [1] = param_type2;
5438 AddFunc (module, name, ret_type, param_types, 2);
5442 add_intrinsics (LLVMModuleRef module)
5444 /* Emit declarations of instrinsics */
5446 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5447 * type doesn't seem to do any locking.
5450 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5452 memset_param_count = 5;
5453 memset_func_name = "llvm.memset.p0i8.i32";
5455 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
5459 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5461 memcpy_param_count = 5;
5462 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5464 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
5468 LLVMTypeRef params [] = { LLVMDoubleType () };
5470 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5471 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5472 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5474 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5475 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5479 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5480 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
5482 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5483 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5484 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5485 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5486 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5487 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5491 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5492 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
5494 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5495 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5496 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5497 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5498 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5499 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5504 LLVMTypeRef arg_types [2];
5505 LLVMTypeRef ret_type;
5507 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5508 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5509 ret_type = LLVMInt32Type ();
5511 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5513 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5516 /* SSE intrinsics */
5517 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5519 LLVMTypeRef ret_type, arg_types [16];
5522 ret_type = type_to_simd_type (MONO_TYPE_I4);
5523 arg_types [0] = ret_type;
5524 arg_types [1] = ret_type;
5525 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5526 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5528 ret_type = type_to_simd_type (MONO_TYPE_I2);
5529 arg_types [0] = ret_type;
5530 arg_types [1] = ret_type;
5531 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5532 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5533 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5534 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5535 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5536 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5537 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5538 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5539 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5540 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5542 ret_type = type_to_simd_type (MONO_TYPE_I1);
5543 arg_types [0] = ret_type;
5544 arg_types [1] = ret_type;
5545 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5546 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5547 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5548 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5549 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5550 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5551 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5553 ret_type = type_to_simd_type (MONO_TYPE_R8);
5554 arg_types [0] = ret_type;
5555 arg_types [1] = ret_type;
5556 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5557 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5558 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5559 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5560 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5562 ret_type = type_to_simd_type (MONO_TYPE_R4);
5563 arg_types [0] = ret_type;
5564 arg_types [1] = ret_type;
5565 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5566 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5567 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5568 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5569 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5572 ret_type = type_to_simd_type (MONO_TYPE_I1);
5573 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5574 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5575 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5576 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5577 ret_type = type_to_simd_type (MONO_TYPE_I2);
5578 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5579 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5580 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5581 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5584 ret_type = type_to_simd_type (MONO_TYPE_R8);
5585 arg_types [0] = ret_type;
5586 arg_types [1] = ret_type;
5587 arg_types [2] = LLVMInt8Type ();
5588 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5589 ret_type = type_to_simd_type (MONO_TYPE_R4);
5590 arg_types [0] = ret_type;
5591 arg_types [1] = ret_type;
5592 arg_types [2] = LLVMInt8Type ();
5593 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5595 /* Conversion ops */
5596 ret_type = type_to_simd_type (MONO_TYPE_R8);
5597 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5598 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5599 ret_type = type_to_simd_type (MONO_TYPE_R4);
5600 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5601 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5602 ret_type = type_to_simd_type (MONO_TYPE_I4);
5603 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5604 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5605 ret_type = type_to_simd_type (MONO_TYPE_I4);
5606 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5607 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5608 ret_type = type_to_simd_type (MONO_TYPE_R4);
5609 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5610 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5611 ret_type = type_to_simd_type (MONO_TYPE_R8);
5612 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5613 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5615 ret_type = type_to_simd_type (MONO_TYPE_I4);
5616 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5617 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5618 ret_type = type_to_simd_type (MONO_TYPE_I4);
5619 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5620 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5623 ret_type = type_to_simd_type (MONO_TYPE_R8);
5624 arg_types [0] = ret_type;
5625 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5626 ret_type = type_to_simd_type (MONO_TYPE_R4);
5627 arg_types [0] = ret_type;
5628 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5629 ret_type = type_to_simd_type (MONO_TYPE_R4);
5630 arg_types [0] = ret_type;
5631 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5632 ret_type = type_to_simd_type (MONO_TYPE_R4);
5633 arg_types [0] = ret_type;
5634 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5637 ret_type = type_to_simd_type (MONO_TYPE_I2);
5638 arg_types [0] = ret_type;
5639 arg_types [1] = LLVMInt32Type ();
5640 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5641 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5642 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5643 ret_type = type_to_simd_type (MONO_TYPE_I4);
5644 arg_types [0] = ret_type;
5645 arg_types [1] = LLVMInt32Type ();
5646 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5647 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5648 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5649 ret_type = type_to_simd_type (MONO_TYPE_I8);
5650 arg_types [0] = ret_type;
5651 arg_types [1] = LLVMInt32Type ();
5652 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5653 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5656 ret_type = LLVMInt32Type ();
5657 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5658 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5661 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5664 /* Load/Store intrinsics */
5666 LLVMTypeRef arg_types [5];
5670 for (i = 1; i <= 8; i *= 2) {
5671 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5672 arg_types [1] = LLVMInt32Type ();
5673 arg_types [2] = LLVMInt1Type ();
5674 #if LLVM_API_VERSION >= 4
5675 arg_types [3] = LLVMInt32Type ();
5677 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5678 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3 + EXTRA_MONO_LOAD_STORE_ARGS, FALSE));
5680 arg_types [0] = LLVMIntType (i * 8);
5681 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5682 arg_types [2] = LLVMInt32Type ();
5683 arg_types [3] = LLVMInt1Type ();
5684 #if LLVM_API_VERSION >= 4
5685 arg_types [4] = LLVMInt32Type ();
5687 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5688 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4 + EXTRA_MONO_LOAD_STORE_ARGS, FALSE));
5694 add_types (MonoLLVMModule *lmodule)
5696 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5700 mono_llvm_init (void)
5702 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5706 init_jit_module (MonoDomain *domain)
5708 MonoJitICallInfo *info;
5709 MonoJitDomainInfo *dinfo;
5710 MonoLLVMModule *module;
5713 dinfo = domain_jit_info (domain);
5714 if (dinfo->llvm_module)
5717 mono_loader_lock ();
5719 if (dinfo->llvm_module) {
5720 mono_loader_unlock ();
5724 module = g_new0 (MonoLLVMModule, 1);
5726 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5727 module->module = LLVMModuleCreateWithName (name);
5729 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5731 add_intrinsics (module->module);
5734 module->llvm_types = g_hash_table_new (NULL, NULL);
5736 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5738 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5740 mono_memory_barrier ();
5742 dinfo->llvm_module = module;
5744 mono_loader_unlock ();
5748 mono_llvm_cleanup (void)
5750 if (aot_module.module)
5751 LLVMDisposeModule (aot_module.module);
5753 LLVMContextDispose (LLVMGetGlobalContext ());
5757 mono_llvm_free_domain_info (MonoDomain *domain)
5759 MonoJitDomainInfo *info = domain_jit_info (domain);
5760 MonoLLVMModule *module = info->llvm_module;
5766 if (module->llvm_types)
5767 g_hash_table_destroy (module->llvm_types);
5769 mono_llvm_dispose_ee (module->mono_ee);
5771 if (module->bb_names) {
5772 for (i = 0; i < module->bb_names_len; ++i)
5773 g_free (module->bb_names [i]);
5774 g_free (module->bb_names);
5776 //LLVMDisposeModule (module->module);
5780 info->llvm_module = NULL;
5784 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5786 /* Delete previous module */
5787 if (aot_module.plt_entries)
5788 g_hash_table_destroy (aot_module.plt_entries);
5789 if (aot_module.module)
5790 LLVMDisposeModule (aot_module.module);
5792 memset (&aot_module, 0, sizeof (aot_module));
5794 aot_module.module = LLVMModuleCreateWithName ("aot");
5795 aot_module.got_symbol = got_symbol;
5796 aot_module.external_symbols = external_symbols;
5797 aot_module.emit_dwarf = emit_dwarf;
5798 /* The first few entries are reserved */
5799 aot_module.max_got_offset = 16;
5801 add_intrinsics (aot_module.module);
5802 add_types (&aot_module);
5806 * We couldn't compute the type of the LLVM global representing the got because
5807 * its size is only known after all the methods have been emitted. So create
5808 * a dummy variable, and replace all uses it with the real got variable when
5809 * its size is known in mono_llvm_emit_aot_module ().
5812 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5814 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5815 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5818 /* Add a dummy personality function */
5820 LLVMBasicBlockRef lbb;
5821 LLVMBuilderRef lbuilder;
5822 LLVMValueRef personality;
5824 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5825 LLVMSetLinkage (personality, LLVMInternalLinkage);
5826 lbb = LLVMAppendBasicBlock (personality, "BB0");
5827 lbuilder = LLVMCreateBuilder ();
5828 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5829 LLVMBuildRetVoid (lbuilder);
5830 mark_as_used (&aot_module, personality);
5833 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5834 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5835 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5836 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5840 * Emit the aot module into the LLVM bitcode file FILENAME.
5843 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5845 LLVMTypeRef got_type;
5846 LLVMValueRef real_got;
5847 MonoLLVMModule *module = &aot_module;
5850 * Create the real got variable and replace all uses of the dummy variable with
5853 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5854 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5855 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5856 if (module->external_symbols) {
5857 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5858 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5860 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5862 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5864 mark_as_used (&aot_module, real_got);
5866 /* Delete the dummy got so it doesn't become a global */
5867 LLVMDeleteGlobal (aot_module.got_var);
5869 emit_llvm_used (&aot_module);
5870 emit_dbg_info (&aot_module, filename, cu_name);
5872 /* Replace PLT entries for directly callable methods with the methods themselves */
5874 GHashTableIter iter;
5876 LLVMValueRef callee;
5878 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5879 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5880 if (mono_aot_is_direct_callable (ji)) {
5881 LLVMValueRef lmethod;
5883 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5884 /* The types might not match because the caller might pass an rgctx */
5885 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
5886 mono_llvm_replace_uses_of (callee, lmethod);
5887 mono_aot_mark_unused_llvm_plt_entry (ji);
5897 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5898 g_assert_not_reached ();
5903 LLVMWriteBitcodeToFile (aot_module.module, filename);
5908 md_string (const char *s)
5910 return LLVMMDString (s, strlen (s));
5913 /* Debugging support */
5916 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
5918 LLVMModuleRef module = lmodule->module;
5919 LLVMValueRef args [16], cu_args [16], cu, ver;
5921 char *build_info, *s, *dir;
5924 * This can only be enabled when LLVM code is emitted into a separate object
5925 * file, since the AOT compiler also emits dwarf info,
5926 * and the abbrev indexes will not be correct since llvm has added its own
5929 if (!lmodule->emit_dwarf)
5933 * Emit dwarf info in the form of LLVM metadata. There is some
5934 * out-of-date documentation at:
5935 * http://llvm.org/docs/SourceLevelDebugging.html
5936 * but most of this was gathered from the llvm and
5941 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
5942 /* CU name/compilation dir */
5943 dir = g_path_get_dirname (filename);
5944 args [0] = LLVMMDString (cu_name, strlen (cu_name));
5945 args [1] = LLVMMDString (dir, strlen (dir));
5946 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
5949 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
5951 build_info = mono_get_runtime_build_info ();
5952 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
5953 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
5954 g_free (build_info);
5956 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
5958 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
5959 /* Runtime version */
5960 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5962 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
5963 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
5965 if (lmodule->subprogram_mds) {
5969 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
5970 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
5971 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
5972 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
5974 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
5977 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
5978 /* Imported modules */
5979 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
5981 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
5982 /* DebugEmissionKind = FullDebug */
5983 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
5984 cu = LLVMMDNode (cu_args, n_cuargs);
5985 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
5987 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
5988 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
5989 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
5990 ver = LLVMMDNode (args, 3);
5991 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
5993 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
5994 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
5995 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
5996 ver = LLVMMDNode (args, 3);
5997 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6001 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6003 MonoLLVMModule *module = ctx->lmodule;
6004 MonoDebugMethodInfo *minfo = ctx->minfo;
6005 char *source_file, *dir, *filename;
6006 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6014 mono_debug_symfile_get_line_numbers_full (minfo, &source_file, NULL, &n_il_offsets, &il_offsets, &line_numbers, NULL, NULL, NULL, NULL);
6016 source_file = g_strdup ("<unknown>");
6017 dir = g_path_get_dirname (source_file);
6018 filename = g_path_get_basename (source_file);
6020 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6021 args [0] = md_string (filename);
6022 args [1] = md_string (dir);
6023 ctx_args [1] = LLVMMDNode (args, 2);
6024 ctx_md = LLVMMDNode (ctx_args, 2);
6026 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6027 type_args [1] = NULL;
6028 type_args [2] = NULL;
6029 type_args [3] = LLVMMDString ("", 0);
6030 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6031 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6032 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6033 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6034 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6035 type_args [9] = NULL;
6036 type_args [10] = NULL;
6037 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6038 type_args [12] = NULL;
6039 type_args [13] = NULL;
6040 type_args [14] = NULL;
6041 type_md = LLVMMDNode (type_args, 14);
6043 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6044 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6045 /* Source directory + file pair */
6046 args [0] = md_string (filename);
6047 args [1] = md_string (dir);
6048 md_args [1] = LLVMMDNode (args ,2);
6049 md_args [2] = ctx_md;
6050 md_args [3] = md_string (cfg->method->name);
6051 md_args [4] = md_string (name);
6052 md_args [5] = md_string (name);
6055 md_args [6] = LLVMConstInt (LLVMInt32Type (), line_numbers [0], FALSE);
6057 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6059 md_args [7] = type_md;
6061 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6063 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6065 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6066 /* Index into a virtual function */
6067 md_args [11] = NULL;
6068 md_args [12] = NULL;
6070 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6072 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6073 /* Pointer to LLVM function */
6074 md_args [15] = method;
6075 /* Function template parameter */
6076 md_args [16] = NULL;
6077 /* Function declaration descriptor */
6078 md_args [17] = NULL;
6079 /* List of function variables */
6080 md_args [18] = LLVMMDNode (args, 0);
6082 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6083 md = LLVMMDNode (md_args, 20);
6085 if (!module->subprogram_mds)
6086 module->subprogram_mds = g_ptr_array_new ();
6087 g_ptr_array_add (module->subprogram_mds, md);
6091 g_free (source_file);
6092 g_free (il_offsets);
6093 g_free (line_numbers);
6099 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6101 MonoCompile *cfg = ctx->cfg;
6103 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6104 MonoDebugSourceLocation *loc;
6105 LLVMValueRef loc_md, md_args [16];
6108 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6112 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6113 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6114 md_args [nmd_args ++] = ctx->dbg_md;
6115 md_args [nmd_args ++] = NULL;
6116 loc_md = LLVMMDNode (md_args, nmd_args);
6117 LLVMSetCurrentDebugLocation (builder, loc_md);
6118 mono_debug_symfile_free_location (loc);
6125 - Emit LLVM IR from the mono IR using the LLVM C API.
6126 - The original arch specific code remains, so we can fall back to it if we run
6127 into something we can't handle.
6131 A partial list of issues:
6132 - Handling of opcodes which can throw exceptions.
6134 In the mono JIT, these are implemented using code like this:
6141 push throw_pos - method
6142 call <exception trampoline>
6144 The problematic part is push throw_pos - method, which cannot be represented
6145 in the LLVM IR, since it does not support label values.
6146 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6147 be implemented in JIT mode ?
6148 -> a possible but slower implementation would use the normal exception
6149 throwing code but it would need to control the placement of the throw code
6150 (it needs to be exactly after the compare+branch).
6151 -> perhaps add a PC offset intrinsics ?
6153 - efficient implementation of .ovf opcodes.
6155 These are currently implemented as:
6156 <ins which sets the condition codes>
6159 Some overflow opcodes are now supported by LLVM SVN.
6161 - exception handling, unwinding.
6162 - SSA is disabled for methods with exception handlers
6163 - How to obtain unwind info for LLVM compiled methods ?
6164 -> this is now solved by converting the unwind info generated by LLVM
6166 - LLVM uses the c++ exception handling framework, while we use our home grown
6167 code, and couldn't use the c++ one:
6168 - its not supported under VC++, other exotic platforms.
6169 - it might be impossible to support filter clauses with it.
6173 The trampolines need a predictable call sequence, since they need to disasm
6174 the calling code to obtain register numbers / offsets.
6176 LLVM currently generates this code in non-JIT mode:
6177 mov -0x98(%rax),%eax
6179 Here, the vtable pointer is lost.
6180 -> solution: use one vtable trampoline per class.
6182 - passing/receiving the IMT pointer/RGCTX.
6183 -> solution: pass them as normal arguments ?
6187 LLVM does not allow the specification of argument registers etc. This means
6188 that all calls are made according to the platform ABI.
6190 - passing/receiving vtypes.
6192 Vtypes passed/received in registers are handled by the front end by using
6193 a signature with scalar arguments, and loading the parts of the vtype into those
6196 Vtypes passed on the stack are handled using the 'byval' attribute.
6200 Supported though alloca, we need to emit the load/store code.
6204 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6205 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6206 This is made easier because the IR is already in SSA form.
6207 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6208 types are frequently used incorrectly.
6213 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
6214 append the AOT data structures to that file. For methods which cannot be
6215 handled by LLVM, the normal JIT compiled versions are used.
6218 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6219 * - each bblock should end with a branch
6220 * - setting the return value, making cfg->ret non-volatile
6221 * - avoid some transformations in the JIT which make it harder for us to generate
6223 * - use pointer types to help optimizations.