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/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
13 #ifndef __STDC_LIMIT_MACROS
14 #define __STDC_LIMIT_MACROS
16 #ifndef __STDC_CONSTANT_MACROS
17 #define __STDC_CONSTANT_MACROS
20 #include "llvm-c/Core.h"
21 #include "llvm-c/ExecutionEngine.h"
22 #include "llvm-c/BitWriter.h"
23 #include "llvm-c/Analysis.h"
25 #include "mini-llvm-cpp.h"
28 * Information associated by mono with LLVM modules.
32 LLVMValueRef throw, rethrow, throw_corlib_exception;
33 GHashTable *llvm_types;
35 const char *got_symbol;
36 GHashTable *plt_entries;
40 * Information associated by the backend with mono basic blocks.
43 LLVMBasicBlockRef bblock, end_bblock;
44 LLVMValueRef finally_ind;
45 gboolean added, invoke_target;
47 * If this bblock is the start of a finally clause, this is a list of bblocks it
48 * needs to branch to in ENDFINALLY.
50 GSList *call_handler_return_bbs;
52 * If this bblock is the start of a finally clause, this is the bblock that
53 * CALL_HANDLER needs to branch to.
55 LLVMBasicBlockRef call_handler_target_bb;
56 /* The list of switch statements generated by ENDFINALLY instructions */
57 GSList *endfinally_switch_ins_list;
62 * Structure containing emit state
67 /* Maps method names to the corresponding LLVMValueRef */
68 GHashTable *emitted_method_decls;
72 MonoLLVMModule *lmodule;
75 int sindex, default_index, ex_index;
76 LLVMBuilderRef builder;
77 LLVMValueRef *values, *addresses;
78 MonoType **vreg_cli_types;
80 MonoMethodSignature *sig;
82 GHashTable *region_to_handler;
83 LLVMBuilderRef alloca_builder;
84 LLVMValueRef last_alloca;
85 LLVMValueRef rgctx_arg;
86 LLVMTypeRef *vreg_types;
88 gboolean *unreachable;
97 MonoBasicBlock *in_bb;
102 * Instruction metadata
103 * This is the same as ins_info, but LREG != IREG.
111 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
112 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
119 /* keep in sync with the enum in mini.h */
122 #include "mini-ops.h"
127 #if SIZEOF_VOID_P == 4
128 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
130 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
133 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
136 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
138 #define TRACE_FAILURE(msg)
142 #define IS_TARGET_X86 1
144 #define IS_TARGET_X86 0
147 #define LLVM_FAILURE(ctx, reason) do { \
148 TRACE_FAILURE (reason); \
149 (ctx)->cfg->exception_message = g_strdup (reason); \
150 (ctx)->cfg->disable_llvm = TRUE; \
154 #define CHECK_FAILURE(ctx) do { \
155 if ((ctx)->cfg->disable_llvm) \
159 static LLVMIntPredicate cond_to_llvm_cond [] = {
172 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
185 static LLVMExecutionEngineRef ee;
186 static MonoNativeTlsKey current_cfg_tls_id;
188 static MonoLLVMModule jit_module, aot_module;
189 static gboolean jit_module_inited;
190 static int memset_param_count, memcpy_param_count;
191 static const char *memset_func_name;
192 static const char *memcpy_func_name;
193 static const char *eh_selector_name;
195 static void init_jit_module (void);
200 * The LLVM type with width == sizeof (gpointer)
205 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
211 * Return the size of the LLVM representation of the vtype T.
214 get_vtype_size (MonoType *t)
218 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
220 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
227 * simd_class_to_llvm_type:
229 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
232 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
234 if (!strcmp (klass->name, "Vector2d")) {
235 return LLVMVectorType (LLVMDoubleType (), 2);
236 } else if (!strcmp (klass->name, "Vector2l")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector2ul")) {
239 return LLVMVectorType (LLVMInt64Type (), 2);
240 } else if (!strcmp (klass->name, "Vector4i")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4ui")) {
243 return LLVMVectorType (LLVMInt32Type (), 4);
244 } else if (!strcmp (klass->name, "Vector4f")) {
245 return LLVMVectorType (LLVMFloatType (), 4);
246 } else if (!strcmp (klass->name, "Vector8s")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector8us")) {
249 return LLVMVectorType (LLVMInt16Type (), 8);
250 } else if (!strcmp (klass->name, "Vector16sb")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else if (!strcmp (klass->name, "Vector16b")) {
253 return LLVMVectorType (LLVMInt8Type (), 16);
255 printf ("%s\n", klass->name);
261 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
262 static inline G_GNUC_UNUSED LLVMTypeRef
263 type_to_simd_type (int type)
267 return LLVMVectorType (LLVMInt8Type (), 16);
269 return LLVMVectorType (LLVMInt16Type (), 8);
271 return LLVMVectorType (LLVMInt32Type (), 4);
273 return LLVMVectorType (LLVMInt64Type (), 2);
275 return LLVMVectorType (LLVMDoubleType (), 2);
277 return LLVMVectorType (LLVMFloatType (), 4);
279 g_assert_not_reached ();
287 * Return the LLVM type corresponding to T.
290 type_to_llvm_type (EmitContext *ctx, MonoType *t)
293 return LLVMPointerType (LLVMInt8Type (), 0);
296 return LLVMVoidType ();
298 return LLVMInt8Type ();
300 return LLVMInt16Type ();
302 return LLVMInt32Type ();
304 return LLVMInt8Type ();
306 return LLVMInt16Type ();
308 return LLVMInt32Type ();
309 case MONO_TYPE_BOOLEAN:
310 return LLVMInt8Type ();
313 return LLVMInt64Type ();
315 return LLVMInt16Type ();
317 return LLVMFloatType ();
319 return LLVMDoubleType ();
322 return IntPtrType ();
323 case MONO_TYPE_OBJECT:
324 case MONO_TYPE_CLASS:
325 case MONO_TYPE_ARRAY:
326 case MONO_TYPE_SZARRAY:
327 case MONO_TYPE_STRING:
329 return LLVMPointerType (IntPtrType (), 0);
332 /* Because of generic sharing */
333 return IntPtrType ();
334 case MONO_TYPE_GENERICINST:
335 if (!mono_type_generic_inst_is_valuetype (t))
336 return IntPtrType ();
338 case MONO_TYPE_VALUETYPE:
339 case MONO_TYPE_TYPEDBYREF: {
343 klass = mono_class_from_mono_type (t);
345 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
346 return simd_class_to_llvm_type (ctx, klass);
349 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
350 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
353 LLVMTypeRef *eltypes;
356 size = get_vtype_size (t);
358 eltypes = g_new (LLVMTypeRef, size);
359 for (i = 0; i < size; ++i)
360 eltypes [i] = LLVMInt8Type ();
362 name = mono_type_full_name (&klass->byval_arg);
363 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
364 LLVMStructSetBody (ltype, eltypes, size, FALSE);
365 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
372 printf ("X: %d\n", t->type);
373 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
374 ctx->cfg->disable_llvm = TRUE;
382 * Return whenever T is an unsigned int type.
385 type_is_unsigned (EmitContext *ctx, MonoType *t)
401 * type_to_llvm_arg_type:
403 * Same as type_to_llvm_type, but treat i8/i16 as i32.
406 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
408 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
410 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
412 * LLVM generates code which only sets the lower bits, while JITted
413 * code expects all the bits to be set.
415 ptype = LLVMInt32Type ();
422 * llvm_type_to_stack_type:
424 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
427 static G_GNUC_UNUSED LLVMTypeRef
428 llvm_type_to_stack_type (LLVMTypeRef type)
432 if (type == LLVMInt8Type ())
433 return LLVMInt32Type ();
434 else if (type == LLVMInt16Type ())
435 return LLVMInt32Type ();
436 else if (type == LLVMFloatType ())
437 return LLVMDoubleType ();
443 * regtype_to_llvm_type:
445 * Return the LLVM type corresponding to the regtype C used in instruction
449 regtype_to_llvm_type (char c)
453 return LLVMInt32Type ();
455 return LLVMInt64Type ();
457 return LLVMDoubleType ();
466 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
469 op_to_llvm_type (int opcode)
474 return LLVMInt8Type ();
477 return LLVMInt8Type ();
480 return LLVMInt16Type ();
483 return LLVMInt16Type ();
486 return LLVMInt32Type ();
489 return LLVMInt32Type ();
491 return LLVMInt64Type ();
493 return LLVMFloatType ();
495 return LLVMDoubleType ();
497 return LLVMInt64Type ();
499 return LLVMInt32Type ();
501 return LLVMInt64Type ();
504 return LLVMInt8Type ();
507 return LLVMInt16Type ();
510 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
517 return LLVMInt32Type ();
524 return LLVMInt64Type ();
526 printf ("%s\n", mono_inst_name (opcode));
527 g_assert_not_reached ();
533 * load_store_to_llvm_type:
535 * Return the size/sign/zero extension corresponding to the load/store opcode
539 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
545 case OP_LOADI1_MEMBASE:
546 case OP_STOREI1_MEMBASE_REG:
547 case OP_STOREI1_MEMBASE_IMM:
550 return LLVMInt8Type ();
551 case OP_LOADU1_MEMBASE:
555 return LLVMInt8Type ();
556 case OP_LOADI2_MEMBASE:
557 case OP_STOREI2_MEMBASE_REG:
558 case OP_STOREI2_MEMBASE_IMM:
561 return LLVMInt16Type ();
562 case OP_LOADU2_MEMBASE:
566 return LLVMInt16Type ();
567 case OP_LOADI4_MEMBASE:
568 case OP_LOADU4_MEMBASE:
571 case OP_STOREI4_MEMBASE_REG:
572 case OP_STOREI4_MEMBASE_IMM:
574 return LLVMInt32Type ();
575 case OP_LOADI8_MEMBASE:
577 case OP_STOREI8_MEMBASE_REG:
578 case OP_STOREI8_MEMBASE_IMM:
580 return LLVMInt64Type ();
581 case OP_LOADR4_MEMBASE:
582 case OP_STORER4_MEMBASE_REG:
584 return LLVMFloatType ();
585 case OP_LOADR8_MEMBASE:
586 case OP_STORER8_MEMBASE_REG:
588 return LLVMDoubleType ();
589 case OP_LOAD_MEMBASE:
591 case OP_STORE_MEMBASE_REG:
592 case OP_STORE_MEMBASE_IMM:
593 *size = sizeof (gpointer);
594 return IntPtrType ();
596 g_assert_not_reached ();
604 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
607 ovf_op_to_intrins (int opcode)
611 return "llvm.sadd.with.overflow.i32";
613 return "llvm.uadd.with.overflow.i32";
615 return "llvm.ssub.with.overflow.i32";
617 return "llvm.usub.with.overflow.i32";
619 return "llvm.smul.with.overflow.i32";
621 return "llvm.umul.with.overflow.i32";
623 return "llvm.sadd.with.overflow.i64";
625 return "llvm.uadd.with.overflow.i64";
627 return "llvm.ssub.with.overflow.i64";
629 return "llvm.usub.with.overflow.i64";
631 return "llvm.smul.with.overflow.i64";
633 return "llvm.umul.with.overflow.i64";
635 g_assert_not_reached ();
641 simd_op_to_intrins (int opcode)
644 #if defined(TARGET_X86) || defined(TARGET_AMD64)
646 return "llvm.x86.sse2.min.pd";
648 return "llvm.x86.sse.min.ps";
650 return "llvm.x86.sse41.pminud";
652 return "llvm.x86.sse41.pminuw";
654 return "llvm.x86.sse2.pminu.b";
656 return "llvm.x86.sse2.pmins.w";
658 return "llvm.x86.sse2.max.pd";
660 return "llvm.x86.sse.max.ps";
662 return "llvm.x86.sse3.hadd.pd";
664 return "llvm.x86.sse3.hadd.ps";
666 return "llvm.x86.sse3.hsub.pd";
668 return "llvm.x86.sse3.hsub.ps";
670 return "llvm.x86.sse41.pmaxud";
672 return "llvm.x86.sse41.pmaxuw";
674 return "llvm.x86.sse2.pmaxu.b";
676 return "llvm.x86.sse3.addsub.ps";
678 return "llvm.x86.sse3.addsub.pd";
679 case OP_EXTRACT_MASK:
680 return "llvm.x86.sse2.pmovmskb.128";
683 return "llvm.x86.sse2.psrli.w";
686 return "llvm.x86.sse2.psrli.d";
689 return "llvm.x86.sse2.psrli.q";
692 return "llvm.x86.sse2.pslli.w";
695 return "llvm.x86.sse2.pslli.d";
698 return "llvm.x86.sse2.pslli.q";
701 return "llvm.x86.sse2.psrai.w";
704 return "llvm.x86.sse2.psrai.d";
706 return "llvm.x86.sse2.padds.b";
708 return "llvm.x86.sse2.padds.w";
710 return "llvm.x86.sse2.psubs.b";
712 return "llvm.x86.sse2.psubs.w";
713 case OP_PADDB_SAT_UN:
714 return "llvm.x86.sse2.paddus.b";
715 case OP_PADDW_SAT_UN:
716 return "llvm.x86.sse2.paddus.w";
717 case OP_PSUBB_SAT_UN:
718 return "llvm.x86.sse2.psubus.b";
719 case OP_PSUBW_SAT_UN:
720 return "llvm.x86.sse2.psubus.w";
722 return "llvm.x86.sse2.pavg.b";
724 return "llvm.x86.sse2.pavg.w";
726 return "llvm.x86.sse.sqrt.ps";
728 return "llvm.x86.sse2.sqrt.pd";
730 return "llvm.x86.sse.rsqrt.ps";
732 return "llvm.x86.sse.rcp.ps";
734 return "llvm.x86.sse2.pcmpeq.b";
736 return "llvm.x86.sse2.pcmpeq.w";
738 return "llvm.x86.sse2.pcmpeq.d";
740 return "llvm.x86.sse41.pcmpeqq";
742 return "llvm.x86.sse2.pcmpgt.b";
744 return "llvm.x86.sse2.cvtdq2pd";
746 return "llvm.x86.sse2.cvtdq2ps";
748 return "llvm.x86.sse2.cvtpd2dq";
750 return "llvm.x86.sse2.cvtps2dq";
752 return "llvm.x86.sse2.cvtpd2ps";
754 return "llvm.x86.sse2.cvtps2pd";
756 return "llvm.x86.sse2.cvttpd2dq";
758 return "llvm.x86.sse2.cvttps2dq";
760 return "llvm.x86.sse.cmp.ps";
762 return "llvm.x86.sse2.cmp.pd";
764 return "llvm.x86.sse2.packsswb.128";
766 return "llvm.x86.sse2.packssdw.128";
768 return "llvm.x86.sse2.packuswb.128";
770 return "llvm.x86.sse41.packusdw";
772 return "llvm.x86.sse2.pmulh.w";
773 case OP_PMULW_HIGH_UN:
774 return "llvm.x86.sse2.pmulhu.w";
777 g_assert_not_reached ();
783 simd_op_to_llvm_type (int opcode)
785 #if defined(TARGET_X86) || defined(TARGET_AMD64)
789 return type_to_simd_type (MONO_TYPE_R8);
792 return type_to_simd_type (MONO_TYPE_I8);
795 return type_to_simd_type (MONO_TYPE_I4);
800 return type_to_simd_type (MONO_TYPE_I2);
804 return type_to_simd_type (MONO_TYPE_I1);
806 return type_to_simd_type (MONO_TYPE_R4);
809 return type_to_simd_type (MONO_TYPE_I4);
813 return type_to_simd_type (MONO_TYPE_R8);
817 return type_to_simd_type (MONO_TYPE_R4);
818 case OP_EXTRACT_MASK:
819 return type_to_simd_type (MONO_TYPE_I1);
825 return type_to_simd_type (MONO_TYPE_R4);
828 return type_to_simd_type (MONO_TYPE_R8);
830 g_assert_not_reached ();
841 * Return the LLVM basic block corresponding to BB.
843 static LLVMBasicBlockRef
844 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
848 if (ctx->bblocks [bb->block_num].bblock == NULL) {
849 sprintf (bb_name, "BB%d", bb->block_num);
851 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
852 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
855 return ctx->bblocks [bb->block_num].bblock;
861 * Return the last LLVM bblock corresponding to BB.
862 * This might not be equal to the bb returned by get_bb () since we need to generate
863 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
865 static LLVMBasicBlockRef
866 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
869 return ctx->bblocks [bb->block_num].end_bblock;
872 static LLVMBasicBlockRef
873 gen_bb (EmitContext *ctx, const char *prefix)
877 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
878 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
884 * Return the target of the patch identified by TYPE and TARGET.
887 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
891 memset (&ji, 0, sizeof (ji));
893 ji.data.target = target;
895 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
901 * Emit code to convert the LLVM value V to DTYPE.
904 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
906 LLVMTypeRef stype = LLVMTypeOf (v);
908 if (stype != dtype) {
909 gboolean ext = FALSE;
912 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
914 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
916 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
920 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
922 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
923 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
926 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
927 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
928 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
929 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
930 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
931 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
932 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
933 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
935 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
936 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
937 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
938 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
939 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
940 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
942 #ifdef MONO_ARCH_SOFT_FLOAT
943 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
944 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
945 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
946 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
949 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
950 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
953 LLVMDumpValue (LLVMConstNull (dtype));
954 g_assert_not_reached ();
962 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
964 return convert_full (ctx, v, dtype, FALSE);
968 * emit_volatile_load:
970 * If vreg is volatile, emit a load from its address.
973 emit_volatile_load (EmitContext *ctx, int vreg)
977 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
978 t = ctx->vreg_cli_types [vreg];
979 if (t && !t->byref) {
981 * Might have to zero extend since llvm doesn't have
984 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
985 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
986 else if (t->type == MONO_TYPE_U8)
987 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
994 * emit_volatile_store:
996 * If VREG is volatile, emit a store from its value to its address.
999 emit_volatile_store (EmitContext *ctx, int vreg)
1001 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1003 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1004 g_assert (ctx->addresses [vreg]);
1005 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1011 * Maps parameter indexes in the original signature to parameter indexes
1012 * in the LLVM signature.
1015 /* The indexes of various special arguments in the LLVM signature */
1016 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1020 * sig_to_llvm_sig_full:
1022 * Return the LLVM signature corresponding to the mono signature SIG using the
1023 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1026 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1029 LLVMTypeRef ret_type;
1030 LLVMTypeRef *param_types = NULL;
1032 int i, j, pindex, vret_arg_pindex = 0;
1034 gboolean vretaddr = FALSE;
1037 memset (sinfo, 0, sizeof (LLVMSigInfo));
1039 ret_type = type_to_llvm_type (ctx, sig->ret);
1040 CHECK_FAILURE (ctx);
1042 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1043 /* LLVM models this by returning an aggregate value */
1044 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1045 LLVMTypeRef members [2];
1047 members [0] = IntPtrType ();
1048 ret_type = LLVMStructType (members, 1, FALSE);
1050 g_assert_not_reached ();
1052 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1053 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1055 ret_type = LLVMVoidType ();
1058 pindexes = g_new0 (int, sig->param_count);
1059 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1061 if (cinfo && cinfo->rgctx_arg) {
1063 sinfo->rgctx_arg_pindex = pindex;
1064 param_types [pindex] = IntPtrType ();
1067 if (cinfo && cinfo->imt_arg && IS_LLVM_MONO_BRANCH) {
1069 sinfo->imt_arg_pindex = pindex;
1070 param_types [pindex] = IntPtrType ();
1074 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1075 vret_arg_pindex = pindex;
1076 if (cinfo->vret_arg_index == 1) {
1077 /* Add the slots consumed by the first argument */
1078 LLVMArgInfo *ainfo = &cinfo->args [0];
1079 switch (ainfo->storage) {
1080 case LLVMArgVtypeInReg:
1081 for (j = 0; j < 2; ++j) {
1082 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1092 sinfo->vret_arg_pindex = vret_arg_pindex;
1095 if (vretaddr && vret_arg_pindex == pindex)
1096 param_types [pindex ++] = IntPtrType ();
1099 sinfo->this_arg_pindex = pindex;
1100 param_types [pindex ++] = IntPtrType ();
1102 if (vretaddr && vret_arg_pindex == pindex)
1103 param_types [pindex ++] = IntPtrType ();
1104 for (i = 0; i < sig->param_count; ++i) {
1105 if (vretaddr && vret_arg_pindex == pindex)
1106 param_types [pindex ++] = IntPtrType ();
1107 pindexes [i] = pindex;
1108 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1109 for (j = 0; j < 2; ++j) {
1110 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1112 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1117 g_assert_not_reached ();
1120 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1121 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1122 CHECK_FAILURE (ctx);
1123 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1126 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1129 if (vretaddr && vret_arg_pindex == pindex)
1130 param_types [pindex ++] = IntPtrType ();
1132 CHECK_FAILURE (ctx);
1134 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1135 g_free (param_types);
1138 sinfo->pindexes = pindexes;
1146 g_free (param_types);
1152 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1154 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1158 * LLVMFunctionType1:
1160 * Create an LLVM function type from the arguments.
1162 static G_GNUC_UNUSED LLVMTypeRef
1163 LLVMFunctionType1(LLVMTypeRef ReturnType,
1164 LLVMTypeRef ParamType1,
1167 LLVMTypeRef param_types [1];
1169 param_types [0] = ParamType1;
1171 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1175 * LLVMFunctionType2:
1177 * Create an LLVM function type from the arguments.
1179 static G_GNUC_UNUSED LLVMTypeRef
1180 LLVMFunctionType2(LLVMTypeRef ReturnType,
1181 LLVMTypeRef ParamType1,
1182 LLVMTypeRef ParamType2,
1185 LLVMTypeRef param_types [2];
1187 param_types [0] = ParamType1;
1188 param_types [1] = ParamType2;
1190 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1194 * LLVMFunctionType3:
1196 * Create an LLVM function type from the arguments.
1198 static G_GNUC_UNUSED LLVMTypeRef
1199 LLVMFunctionType3(LLVMTypeRef ReturnType,
1200 LLVMTypeRef ParamType1,
1201 LLVMTypeRef ParamType2,
1202 LLVMTypeRef ParamType3,
1205 LLVMTypeRef param_types [3];
1207 param_types [0] = ParamType1;
1208 param_types [1] = ParamType2;
1209 param_types [2] = ParamType3;
1211 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1217 * Create an LLVM builder and remember it so it can be freed later.
1219 static LLVMBuilderRef
1220 create_builder (EmitContext *ctx)
1222 LLVMBuilderRef builder = LLVMCreateBuilder ();
1224 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1230 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1232 char *callee_name = mono_aot_get_plt_symbol (type, data);
1233 LLVMValueRef callee;
1238 if (ctx->cfg->compile_aot)
1239 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1240 mono_add_patch_info (ctx->cfg, 0, type, data);
1243 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1245 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1247 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1249 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1256 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1258 MonoMethodHeader *header = cfg->header;
1259 MonoExceptionClause *clause;
1263 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1264 return (bb->region >> 8) - 1;
1267 for (i = 0; i < header->num_clauses; ++i) {
1268 clause = &header->clauses [i];
1270 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1278 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1280 LLVMValueRef md_arg;
1283 if (!IS_LLVM_MONO_BRANCH)
1286 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1287 md_arg = LLVMMDString ("mono", 4);
1288 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1294 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1298 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1300 MonoCompile *cfg = ctx->cfg;
1302 LLVMBuilderRef builder = *builder_ref;
1305 clause_index = get_handler_clause (cfg, bb);
1307 if (clause_index != -1) {
1308 MonoMethodHeader *header = cfg->header;
1309 MonoExceptionClause *ec = &header->clauses [clause_index];
1310 MonoBasicBlock *tblock;
1311 LLVMBasicBlockRef ex_bb, noex_bb;
1314 * Have to use an invoke instead of a call, branching to the
1315 * handler bblock of the clause containing this bblock.
1318 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1320 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1323 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1325 ex_bb = get_bb (ctx, tblock);
1327 noex_bb = gen_bb (ctx, "NOEX_BB");
1330 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1332 builder = ctx->builder = create_builder (ctx);
1333 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1335 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1337 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1338 ctx->builder = builder;
1341 *builder_ref = ctx->builder;
1347 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1349 const char *intrins_name;
1350 LLVMValueRef args [16], res;
1351 LLVMTypeRef addr_type;
1353 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1355 * We handle loads which can fault by calling a mono specific intrinsic
1356 * using an invoke, so they are handled properly inside try blocks.
1357 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1358 * are marked with IntrReadArgMem.
1362 intrins_name = "llvm.mono.load.i8.p0i8";
1365 intrins_name = "llvm.mono.load.i16.p0i16";
1368 intrins_name = "llvm.mono.load.i32.p0i32";
1371 intrins_name = "llvm.mono.load.i64.p0i64";
1374 g_assert_not_reached ();
1377 addr_type = LLVMTypeOf (addr);
1378 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1379 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1382 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1383 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1384 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1386 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1387 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1388 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1389 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1396 * We emit volatile loads for loads which can fault, because otherwise
1397 * LLVM will generate invalid code when encountering a load from a
1400 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1402 /* Mark it with a custom metadata */
1405 set_metadata_flag (res, "mono.faulting.load");
1413 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1415 const char *intrins_name;
1416 LLVMValueRef args [16];
1418 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1421 intrins_name = "llvm.mono.store.i8.p0i8";
1424 intrins_name = "llvm.mono.store.i16.p0i16";
1427 intrins_name = "llvm.mono.store.i32.p0i32";
1430 intrins_name = "llvm.mono.store.i64.p0i64";
1433 g_assert_not_reached ();
1436 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1437 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1438 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1443 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1444 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1445 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1447 LLVMBuildStore (*builder_ref, value, addr);
1452 * emit_cond_system_exception:
1454 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1455 * Might set the ctx exception.
1458 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1460 LLVMBasicBlockRef ex_bb, noex_bb;
1461 LLVMBuilderRef builder;
1462 MonoClass *exc_class;
1463 LLVMValueRef args [2];
1465 ex_bb = gen_bb (ctx, "EX_BB");
1466 noex_bb = gen_bb (ctx, "NOEX_BB");
1468 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1470 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1471 g_assert (exc_class);
1473 /* Emit exception throwing code */
1474 builder = create_builder (ctx);
1475 LLVMPositionBuilderAtEnd (builder, ex_bb);
1477 if (!ctx->lmodule->throw_corlib_exception) {
1478 LLVMValueRef callee;
1480 const char *icall_name;
1482 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1483 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1484 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1485 if (IS_LLVM_MONO_BRANCH) {
1486 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1487 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1489 icall_name = "llvm_throw_corlib_exception_trampoline";
1490 throw_sig->params [1] = &mono_get_int32_class ()->byval_arg;
1492 sig = sig_to_llvm_sig (ctx, throw_sig);
1494 if (ctx->cfg->compile_aot) {
1495 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1497 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1500 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1501 * - On x86, LLVM generated code doesn't push the arguments
1502 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1503 * arguments, not a pc offset.
1505 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1508 mono_memory_barrier ();
1509 ctx->lmodule->throw_corlib_exception = callee;
1513 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1515 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1517 if (IS_LLVM_MONO_BRANCH) {
1519 * The LLVM mono branch contains changes so a block address can be passed as an
1520 * argument to a call.
1522 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1523 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1526 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1527 * otherwise only the line numbers in stack traces are incorrect.
1529 if (bb->region != -1 && !IS_LLVM_MONO_BRANCH)
1530 LLVM_FAILURE (ctx, "system-ex-in-region");
1532 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1533 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1536 LLVMBuildUnreachable (builder);
1538 ctx->builder = create_builder (ctx);
1539 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1541 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1551 * emit_reg_to_vtype:
1553 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1556 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1560 size = get_vtype_size (t);
1562 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1563 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1566 for (j = 0; j < 2; ++j) {
1567 LLVMValueRef index [2], addr;
1568 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1569 LLVMTypeRef part_type;
1571 if (ainfo->pair_storage [j] == LLVMArgNone)
1574 part_type = LLVMIntType (part_size * 8);
1575 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1576 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1577 addr = LLVMBuildGEP (builder, address, index, 1, "");
1579 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1580 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1581 addr = LLVMBuildGEP (builder, address, index, 2, "");
1583 switch (ainfo->pair_storage [j]) {
1585 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1590 g_assert_not_reached ();
1593 size -= sizeof (gpointer);
1598 * emit_vtype_to_reg:
1600 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1601 * into REGS, and the number of registers into NREGS.
1604 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1609 size = get_vtype_size (t);
1611 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1612 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1615 for (j = 0; j < 2; ++j) {
1616 LLVMValueRef index [2], addr;
1617 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1619 if (ainfo->pair_storage [j] == LLVMArgNone)
1622 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1623 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1624 addr = LLVMBuildGEP (builder, address, index, 1, "");
1626 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1627 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1628 addr = LLVMBuildGEP (builder, address, index, 2, "");
1630 switch (ainfo->pair_storage [j]) {
1632 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1637 g_assert_not_reached ();
1639 size -= sizeof (gpointer);
1646 build_alloca (EmitContext *ctx, MonoType *t)
1648 MonoClass *k = mono_class_from_mono_type (t);
1651 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1654 align = mono_class_min_align (k);
1656 /* Sometimes align is not a power of 2 */
1657 while (mono_is_power_of_two (align) == -1)
1661 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1662 * get executed every time control reaches them.
1664 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1666 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1667 return ctx->last_alloca;
1671 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1674 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1676 LLVMTypeRef used_type;
1677 LLVMValueRef used, used_elem;
1679 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1680 used = LLVMAddGlobal (module, used_type, "llvm.used");
1681 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1682 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1683 LLVMSetLinkage (used, LLVMAppendingLinkage);
1684 LLVMSetSection (used, "llvm.metadata");
1690 * Emit code to load/convert arguments.
1693 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1696 MonoCompile *cfg = ctx->cfg;
1697 MonoMethodSignature *sig = ctx->sig;
1698 LLVMCallInfo *linfo = ctx->linfo;
1701 ctx->alloca_builder = create_builder (ctx);
1704 * Handle indirect/volatile variables by allocating memory for them
1705 * using 'alloca', and storing their address in a temporary.
1707 for (i = 0; i < cfg->num_varinfo; ++i) {
1708 MonoInst *var = cfg->varinfo [i];
1711 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1712 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1713 CHECK_FAILURE (ctx);
1714 /* Could be already created by an OP_VPHI */
1715 if (!ctx->addresses [var->dreg])
1716 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1717 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1721 for (i = 0; i < sig->param_count; ++i) {
1722 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1723 int reg = cfg->args [i + sig->hasthis]->dreg;
1725 if (ainfo->storage == LLVMArgVtypeInReg) {
1726 LLVMValueRef regs [2];
1729 * Emit code to save the argument from the registers to
1730 * the real argument.
1732 pindex = ctx->pindexes [i];
1733 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1734 if (ainfo->pair_storage [1] != LLVMArgNone)
1735 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1739 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1741 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1743 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1744 /* Treat these as normal values */
1745 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1747 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1748 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1750 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1751 /* Treat these as normal values */
1752 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1755 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1760 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1762 emit_volatile_store (ctx, cfg->args [0]->dreg);
1763 for (i = 0; i < sig->param_count; ++i)
1764 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1765 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1767 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1768 LLVMValueRef this_alloc;
1771 * The exception handling code needs the location where the this argument was
1772 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1773 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1774 * location into the LSDA.
1776 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1777 /* This volatile store will keep the alloca alive */
1778 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1780 set_metadata_flag (this_alloc, "mono.this");
1783 if (cfg->rgctx_var) {
1784 LLVMValueRef rgctx_alloc, store;
1787 * We handle the rgctx arg similarly to the this pointer.
1789 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1790 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1791 /* This volatile store will keep the alloca alive */
1792 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1794 set_metadata_flag (rgctx_alloc, "mono.this");
1798 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1799 * it needs to continue normally, or return back to the exception handling system.
1801 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1802 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1803 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1804 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1808 sprintf (name, "finally_ind_bb%d", bb->block_num);
1809 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1810 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1812 ctx->bblocks [bb->block_num].finally_ind = val;
1815 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1816 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1817 * LLVM optimizer passes.
1819 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1820 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1828 /* Have to export this for AOT */
1830 mono_personality (void);
1833 mono_personality (void)
1836 g_assert_not_reached ();
1840 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1842 MonoCompile *cfg = ctx->cfg;
1843 LLVMModuleRef module = ctx->module;
1844 LLVMValueRef *values = ctx->values;
1845 LLVMValueRef *addresses = ctx->addresses;
1846 MonoCallInst *call = (MonoCallInst*)ins;
1847 MonoMethodSignature *sig = call->signature;
1848 LLVMValueRef callee = NULL, lcall;
1850 LLVMCallInfo *cinfo;
1854 LLVMTypeRef llvm_sig;
1856 gboolean virtual, calli;
1857 LLVMBuilderRef builder = *builder_ref;
1860 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1861 LLVM_FAILURE (ctx, "non-default callconv");
1863 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
1864 LLVM_FAILURE (ctx, "rgctx reg in call");
1866 if (call->rgctx_reg && !IS_LLVM_MONO_BRANCH) {
1868 * It might be possible to support this by creating a static rgctx trampoline, but
1869 * common_call_trampoline () would patch callsites to call the trampoline, which
1870 * would be incorrect if the rgctx arg is computed dynamically.
1872 LLVM_FAILURE (ctx, "rgctx reg");
1875 cinfo = call->cinfo;
1876 if (call->rgctx_arg_reg)
1877 cinfo->rgctx_arg = TRUE;
1878 if (call->imt_arg_reg)
1879 cinfo->imt_arg = TRUE;
1881 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1883 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1884 CHECK_FAILURE (ctx);
1886 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);
1887 calli = (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);
1889 /* FIXME: Avoid creating duplicate methods */
1891 if (ins->flags & MONO_INST_HAS_METHOD) {
1895 if (cfg->compile_aot) {
1896 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1898 LLVM_FAILURE (ctx, "can't encode patch");
1900 callee = LLVMAddFunction (module, "", llvm_sig);
1903 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1905 LLVMAddGlobalMapping (ee, callee, target);
1910 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1916 memset (&ji, 0, sizeof (ji));
1917 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1918 ji.data.target = info->name;
1920 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1922 if (cfg->compile_aot) {
1923 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1925 LLVM_FAILURE (ctx, "can't encode patch");
1927 callee = LLVMAddFunction (module, "", llvm_sig);
1928 target = (gpointer)mono_icall_get_wrapper (info);
1929 LLVMAddGlobalMapping (ee, callee, target);
1932 if (cfg->compile_aot) {
1934 if (cfg->abs_patches) {
1935 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1937 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1939 LLVM_FAILURE (ctx, "can't encode patch");
1943 LLVM_FAILURE (ctx, "aot");
1945 callee = LLVMAddFunction (module, "", llvm_sig);
1947 if (cfg->abs_patches) {
1948 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1951 * FIXME: Some trampolines might have
1952 * their own calling convention on some platforms.
1954 #ifndef TARGET_AMD64
1955 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
1956 LLVM_FAILURE (ctx, "trampoline with own cconv");
1958 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1959 LLVMAddGlobalMapping (ee, callee, target);
1963 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1969 int size = sizeof (gpointer);
1972 g_assert (ins->inst_offset % size == 0);
1973 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1976 * When using the llvm mono branch, we can support IMT directly, otherwise
1977 * we need to call a trampoline.
1979 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
1980 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1981 if (cfg->compile_aot) {
1982 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
1983 imt_tramp->method = call->method;
1984 imt_tramp->vt_offset = call->inst.inst_offset;
1986 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
1988 callee = LLVMAddFunction (module, "", llvm_sig);
1989 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
1990 LLVMAddGlobalMapping (ee, callee, target);
1993 /* No support for passing the IMT argument */
1994 LLVM_FAILURE (ctx, "imt");
1997 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2000 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2002 if (ins->flags & MONO_INST_HAS_METHOD) {
2007 * Collect and convert arguments
2009 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
2010 args = alloca (len);
2011 memset (args, 0, len);
2012 l = call->out_ireg_args;
2014 if (IS_LLVM_MONO_BRANCH) {
2015 if (call->rgctx_arg_reg) {
2016 g_assert (values [call->rgctx_arg_reg]);
2017 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
2019 if (call->imt_arg_reg) {
2020 g_assert (values [call->imt_arg_reg]);
2021 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
2026 if (!addresses [call->inst.dreg])
2027 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2028 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2031 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2034 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2038 pindex = sinfo.this_arg_pindex;
2040 pindex = sinfo.pindexes [i - 1];
2042 pindex = sinfo.pindexes [i];
2045 regpair = (guint32)(gssize)(l->data);
2046 reg = regpair & 0xffffff;
2047 args [pindex] = values [reg];
2048 if (ainfo->storage == LLVMArgVtypeInReg) {
2050 LLVMValueRef regs [2];
2055 g_assert (addresses [reg]);
2057 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2058 for (j = 0; j < nregs; ++j)
2059 args [pindex ++] = regs [j];
2062 // FIXME: Get rid of the VMOVE
2063 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2064 g_assert (addresses [reg]);
2065 args [pindex] = addresses [reg];
2067 g_assert (args [pindex]);
2068 if (i == 0 && sig->hasthis)
2069 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2071 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2077 // FIXME: Align call sites
2083 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2085 #ifdef LLVM_MONO_BRANCH
2087 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2089 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2090 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2092 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2093 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2095 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2097 if (call->rgctx_arg_reg)
2098 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2099 if (call->imt_arg_reg)
2100 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2103 /* Add byval attributes if needed */
2104 for (i = 0; i < sig->param_count; ++i) {
2105 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2107 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2108 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2113 * Convert the result
2115 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2116 LLVMValueRef regs [2];
2118 if (!addresses [ins->dreg])
2119 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2121 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2122 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2123 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2125 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2126 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2127 /* If the method returns an unsigned value, need to zext it */
2129 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2132 *builder_ref = ctx->builder;
2134 g_free (sinfo.pindexes);
2142 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2144 MonoCompile *cfg = ctx->cfg;
2145 MonoMethodSignature *sig = ctx->sig;
2146 LLVMValueRef method = ctx->lmethod;
2147 LLVMValueRef *values = ctx->values;
2148 LLVMValueRef *addresses = ctx->addresses;
2150 LLVMCallInfo *linfo = ctx->linfo;
2151 LLVMModuleRef module = ctx->module;
2152 BBInfo *bblocks = ctx->bblocks;
2154 LLVMBasicBlockRef cbb;
2155 LLVMBuilderRef builder;
2156 gboolean has_terminator;
2158 LLVMValueRef lhs, rhs;
2160 cbb = get_bb (ctx, bb);
2161 builder = create_builder (ctx);
2162 ctx->builder = builder;
2163 LLVMPositionBuilderAtEnd (builder, cbb);
2165 if (bb == cfg->bb_entry)
2166 emit_entry_bb (ctx, builder);
2167 CHECK_FAILURE (ctx);
2169 if (bb->flags & BB_EXCEPTION_HANDLER) {
2171 LLVMValueRef eh_selector, eh_exception, personality, args [4];
2172 LLVMBasicBlockRef target_bb;
2174 static gint32 mapping_inited;
2175 static int ti_generator;
2178 LLVMValueRef type_info;
2181 if (!bblocks [bb->block_num].invoke_target) {
2183 * LLVM asserts if llvm.eh.selector is called from a bblock which
2184 * doesn't have an invoke pointing at it.
2185 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2187 LLVM_FAILURE (ctx, "handler without invokes");
2190 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2193 LandingPadInst *LPadInst =
2194 Builder.CreateLandingPad(StructType::get(Int8PtrTy, Int32Ty, NULL),
2197 Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
2198 Builder.CreateStore(LPadExn, getExceptionSlot());
2200 Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
2201 Builder.CreateStore(LPadSel, getEHSelectorSlot());
2204 eh_selector = LLVMGetNamedFunction (module, eh_selector_name);
2206 if (cfg->compile_aot) {
2207 /* Use a dummy personality function */
2208 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2209 g_assert (personality);
2211 personality = LLVMGetNamedFunction (module, "mono_personality");
2212 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2213 LLVMAddGlobalMapping (ee, personality, mono_personality);
2216 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2218 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2221 * Create the type info
2223 sprintf (ti_name, "type_info_%d", ti_generator);
2226 if (cfg->compile_aot) {
2227 /* decode_eh_frame () in aot-runtime.c will decode this */
2228 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2229 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2231 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2232 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2235 * Enabling this causes llc to crash:
2236 * http://llvm.org/bugs/show_bug.cgi?id=6102
2238 //LLVM_FAILURE (ctx, "aot+clauses");
2241 * After the cfg mempool is freed, the type info will point to stale memory,
2242 * but this is not a problem, since we decode it once in exception_cb during
2245 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2246 *(gint32*)ti = clause_index;
2248 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2250 LLVMAddGlobalMapping (ee, type_info, ti);
2254 LLVMTypeRef members [2], ret_type;
2255 LLVMValueRef landing_pad;
2257 members [0] = i8ptr;
2258 members [1] = LLVMInt32Type ();
2259 ret_type = LLVMStructType (members, 2, FALSE);
2261 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2262 LLVMAddClause (landing_pad, type_info);
2266 args [0] = LLVMConstNull (i8ptr);
2267 args [1] = LLVMConstBitCast (personality, i8ptr);
2268 args [2] = type_info;
2269 LLVMBuildCall (builder, eh_selector, args, 3, "");
2271 /* Store the exception into the exvar */
2272 if (bb->in_scount == 1) {
2273 g_assert (bb->in_scount == 1);
2274 exvar = bb->in_stack [0];
2276 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
2278 // FIXME: This is shared with filter clauses ?
2279 g_assert (!values [exvar->dreg]);
2280 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
2281 emit_volatile_store (ctx, exvar->dreg);
2285 /* Start a new bblock which CALL_HANDLER can branch to */
2286 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2288 LLVMBuildBr (builder, target_bb);
2290 ctx->builder = builder = create_builder (ctx);
2291 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2293 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2297 has_terminator = FALSE;
2298 for (ins = bb->code; ins; ins = ins->next) {
2299 const char *spec = LLVM_INS_INFO (ins->opcode);
2301 char dname_buf [128];
2304 /* There could be instructions after a terminator, skip them */
2307 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2308 sprintf (dname_buf, "t%d", ins->dreg);
2312 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2313 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2315 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2316 lhs = emit_volatile_load (ctx, ins->sreg1);
2318 /* It is ok for SETRET to have an uninitialized argument */
2319 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2320 LLVM_FAILURE (ctx, "sreg1");
2321 lhs = values [ins->sreg1];
2327 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2328 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2329 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2330 rhs = emit_volatile_load (ctx, ins->sreg2);
2332 if (!values [ins->sreg2])
2333 LLVM_FAILURE (ctx, "sreg2");
2334 rhs = values [ins->sreg2];
2340 //mono_print_ins (ins);
2341 switch (ins->opcode) {
2344 case OP_LIVERANGE_START:
2345 case OP_LIVERANGE_END:
2348 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2351 #if SIZEOF_VOID_P == 4
2352 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2354 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2358 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2361 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2364 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2365 has_terminator = TRUE;
2371 LLVMBasicBlockRef new_bb;
2372 LLVMBuilderRef new_builder;
2374 // The default branch is already handled
2375 // FIXME: Handle it here
2377 /* Start new bblock */
2378 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2379 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2381 lhs = convert (ctx, lhs, LLVMInt32Type ());
2382 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2383 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2384 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2386 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2389 new_builder = create_builder (ctx);
2390 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2391 LLVMBuildUnreachable (new_builder);
2393 has_terminator = TRUE;
2394 g_assert (!ins->next);
2400 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2401 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2402 LLVMValueRef part1, retval;
2405 size = get_vtype_size (sig->ret);
2407 g_assert (addresses [ins->sreg1]);
2409 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2410 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2412 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2414 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2416 LLVMBuildRet (builder, retval);
2420 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2421 LLVMBuildRetVoid (builder);
2425 if (!lhs || ctx->is_dead [ins->sreg1]) {
2427 * The method did not set its return value, probably because it
2428 * ends with a throw.
2431 LLVMBuildRetVoid (builder);
2433 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2435 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2437 has_terminator = TRUE;
2443 case OP_ICOMPARE_IMM:
2444 case OP_LCOMPARE_IMM:
2445 case OP_COMPARE_IMM: {
2449 if (ins->next->opcode == OP_NOP)
2452 if (ins->next->opcode == OP_BR)
2453 /* The comparison result is not needed */
2456 rel = mono_opcode_to_cond (ins->next->opcode);
2458 if (ins->opcode == OP_ICOMPARE_IMM) {
2459 lhs = convert (ctx, lhs, LLVMInt32Type ());
2460 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2462 if (ins->opcode == OP_LCOMPARE_IMM) {
2463 lhs = convert (ctx, lhs, LLVMInt64Type ());
2464 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2466 if (ins->opcode == OP_LCOMPARE) {
2467 lhs = convert (ctx, lhs, LLVMInt64Type ());
2468 rhs = convert (ctx, rhs, LLVMInt64Type ());
2470 if (ins->opcode == OP_ICOMPARE) {
2471 lhs = convert (ctx, lhs, LLVMInt32Type ());
2472 rhs = convert (ctx, rhs, LLVMInt32Type ());
2476 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2477 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2478 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2479 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2482 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2483 if (ins->opcode == OP_FCOMPARE)
2484 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2485 else if (ins->opcode == OP_COMPARE_IMM)
2486 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2487 else if (ins->opcode == OP_LCOMPARE_IMM) {
2488 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2489 /* The immediate is encoded in two fields */
2490 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2491 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2493 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2496 else if (ins->opcode == OP_COMPARE)
2497 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2499 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2501 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2502 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2504 * If the target bb contains PHI instructions, LLVM requires
2505 * two PHI entries for this bblock, while we only generate one.
2506 * So convert this to an unconditional bblock. (bxc #171).
2508 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2510 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2512 has_terminator = TRUE;
2513 } else if (MONO_IS_SETCC (ins->next)) {
2514 sprintf (dname_buf, "t%d", ins->next->dreg);
2516 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2518 /* Add stores for volatile variables */
2519 emit_volatile_store (ctx, ins->next->dreg);
2520 } else if (MONO_IS_COND_EXC (ins->next)) {
2521 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2522 CHECK_FAILURE (ctx);
2523 builder = ctx->builder;
2525 LLVM_FAILURE (ctx, "next");
2539 rel = mono_opcode_to_cond (ins->opcode);
2541 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2542 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2550 gboolean empty = TRUE;
2552 /* Check that all input bblocks really branch to us */
2553 for (i = 0; i < bb->in_count; ++i) {
2554 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2555 ins->inst_phi_args [i + 1] = -1;
2561 /* LLVM doesn't like phi instructions with zero operands */
2562 ctx->is_dead [ins->dreg] = TRUE;
2566 /* Created earlier, insert it now */
2567 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2569 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2570 int sreg1 = ins->inst_phi_args [i + 1];
2574 * Count the number of times the incoming bblock branches to us,
2575 * since llvm requires a separate entry for each.
2577 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2578 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2581 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2582 if (switch_ins->inst_many_bb [j] == bb)
2589 /* Remember for later */
2590 for (j = 0; j < count; ++j) {
2591 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2594 node->in_bb = bb->in_bb [i];
2596 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);
2606 values [ins->dreg] = lhs;
2609 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2612 values [ins->dreg] = lhs;
2614 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2616 * This is added by the spilling pass in case of the JIT,
2617 * but we have to do it ourselves.
2619 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2653 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2654 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2656 switch (ins->opcode) {
2659 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2663 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2667 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2671 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2675 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2679 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2683 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2686 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2690 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2694 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2698 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2702 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2706 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2710 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2714 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2717 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2720 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2724 g_assert_not_reached ();
2731 case OP_IREM_UN_IMM:
2733 case OP_IDIV_UN_IMM:
2739 case OP_ISHR_UN_IMM:
2748 case OP_LSHR_UN_IMM:
2756 if (spec [MONO_INST_SRC1] == 'l') {
2757 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2759 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2762 #if SIZEOF_VOID_P == 4
2763 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2764 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2767 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2768 lhs = convert (ctx, lhs, IntPtrType ());
2769 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2770 switch (ins->opcode) {
2774 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2778 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2782 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2786 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2788 case OP_IDIV_UN_IMM:
2789 case OP_LDIV_UN_IMM:
2790 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2794 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2796 case OP_IREM_UN_IMM:
2797 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2802 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2806 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2810 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2815 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2820 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2822 case OP_ISHR_UN_IMM:
2823 /* This is used to implement conv.u4, so the lhs could be an i8 */
2824 lhs = convert (ctx, lhs, LLVMInt32Type ());
2825 imm = convert (ctx, imm, LLVMInt32Type ());
2826 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2828 case OP_LSHR_UN_IMM:
2829 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2832 g_assert_not_reached ();
2837 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2840 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2843 lhs = convert (ctx, lhs, LLVMDoubleType ());
2844 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2847 guint32 v = 0xffffffff;
2848 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2852 guint64 v = 0xffffffffffffffffLL;
2853 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2856 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2858 LLVMValueRef v1, v2;
2860 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2861 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2862 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2867 case OP_ICONV_TO_I1:
2868 case OP_ICONV_TO_I2:
2869 case OP_ICONV_TO_I4:
2870 case OP_ICONV_TO_U1:
2871 case OP_ICONV_TO_U2:
2872 case OP_ICONV_TO_U4:
2873 case OP_LCONV_TO_I1:
2874 case OP_LCONV_TO_I2:
2875 case OP_LCONV_TO_U1:
2876 case OP_LCONV_TO_U2:
2877 case OP_LCONV_TO_U4: {
2880 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);
2882 /* Have to do two casts since our vregs have type int */
2883 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2885 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2887 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2890 case OP_ICONV_TO_I8:
2891 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2893 case OP_ICONV_TO_U8:
2894 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2896 case OP_FCONV_TO_I4:
2897 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2899 case OP_FCONV_TO_I1:
2900 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2902 case OP_FCONV_TO_U1:
2903 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2905 case OP_FCONV_TO_I2:
2906 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2908 case OP_FCONV_TO_U2:
2909 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2911 case OP_FCONV_TO_I8:
2912 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2915 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2917 case OP_ICONV_TO_R8:
2918 case OP_LCONV_TO_R8:
2919 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2921 case OP_LCONV_TO_R_UN:
2922 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2924 #if SIZEOF_VOID_P == 4
2927 case OP_LCONV_TO_I4:
2928 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2930 case OP_ICONV_TO_R4:
2931 case OP_LCONV_TO_R4:
2932 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2933 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2935 case OP_FCONV_TO_R4:
2936 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2937 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2940 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2943 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2946 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2948 case OP_LOCALLOC_IMM: {
2951 guint32 size = ins->inst_imm;
2952 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2954 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2956 if (ins->flags & MONO_INST_INIT) {
2957 LLVMValueRef args [5];
2960 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2961 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2962 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2963 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2964 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2967 values [ins->dreg] = v;
2971 LLVMValueRef v, size;
2973 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), "");
2975 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2977 if (ins->flags & MONO_INST_INIT) {
2978 LLVMValueRef args [5];
2981 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2983 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2984 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2985 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2987 values [ins->dreg] = v;
2991 case OP_LOADI1_MEMBASE:
2992 case OP_LOADU1_MEMBASE:
2993 case OP_LOADI2_MEMBASE:
2994 case OP_LOADU2_MEMBASE:
2995 case OP_LOADI4_MEMBASE:
2996 case OP_LOADU4_MEMBASE:
2997 case OP_LOADI8_MEMBASE:
2998 case OP_LOADR4_MEMBASE:
2999 case OP_LOADR8_MEMBASE:
3000 case OP_LOAD_MEMBASE:
3008 LLVMValueRef base, index, addr;
3010 gboolean sext = FALSE, zext = FALSE;
3011 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3013 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3018 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)) {
3019 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3024 if (ins->inst_offset == 0) {
3026 } else if (ins->inst_offset % size != 0) {
3027 /* Unaligned load */
3028 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3029 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3031 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3032 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3036 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3038 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3040 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
3042 * These will signal LLVM that these loads do not alias any stores, and
3043 * they can't fail, allowing them to be hoisted out of loops.
3045 set_metadata_flag (values [ins->dreg], "mono.noalias");
3046 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3050 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3052 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3053 else if (ins->opcode == OP_LOADR4_MEMBASE)
3054 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3058 case OP_STOREI1_MEMBASE_REG:
3059 case OP_STOREI2_MEMBASE_REG:
3060 case OP_STOREI4_MEMBASE_REG:
3061 case OP_STOREI8_MEMBASE_REG:
3062 case OP_STORER4_MEMBASE_REG:
3063 case OP_STORER8_MEMBASE_REG:
3064 case OP_STORE_MEMBASE_REG: {
3066 LLVMValueRef index, addr;
3068 gboolean sext = FALSE, zext = FALSE;
3069 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3071 if (!values [ins->inst_destbasereg])
3072 LLVM_FAILURE (ctx, "inst_destbasereg");
3074 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3076 if (ins->inst_offset % size != 0) {
3077 /* Unaligned store */
3078 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3079 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3081 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3082 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3084 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3088 case OP_STOREI1_MEMBASE_IMM:
3089 case OP_STOREI2_MEMBASE_IMM:
3090 case OP_STOREI4_MEMBASE_IMM:
3091 case OP_STOREI8_MEMBASE_IMM:
3092 case OP_STORE_MEMBASE_IMM: {
3094 LLVMValueRef index, addr;
3096 gboolean sext = FALSE, zext = FALSE;
3097 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3099 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3101 if (ins->inst_offset % size != 0) {
3102 /* Unaligned store */
3103 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3104 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3106 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3107 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3109 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3114 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3116 case OP_OUTARG_VTRETADDR:
3123 case OP_VOIDCALL_MEMBASE:
3124 case OP_CALL_MEMBASE:
3125 case OP_LCALL_MEMBASE:
3126 case OP_FCALL_MEMBASE:
3127 case OP_VCALL_MEMBASE:
3128 case OP_VOIDCALL_REG:
3132 case OP_VCALL_REG: {
3133 process_call (ctx, bb, &builder, ins);
3134 CHECK_FAILURE (ctx);
3139 LLVMValueRef indexes [2];
3141 LLVMValueRef got_entry_addr;
3144 * FIXME: Can't allocate from the cfg mempool since that is freed if
3145 * the LLVM compile fails.
3147 ji = g_new0 (MonoJumpInfo, 1);
3148 ji->type = (MonoJumpInfoType)ins->inst_i1;
3149 ji->data.target = ins->inst_p0;
3151 ji = mono_aot_patch_info_dup (ji);
3153 ji->next = cfg->patch_info;
3154 cfg->patch_info = ji;
3156 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3157 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3159 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3160 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3161 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3163 // FIXME: This doesn't work right now, because it must be
3164 // paired with an invariant.end, and even then, its only in effect
3165 // inside its basic block
3168 LLVMValueRef args [3];
3169 LLVMValueRef ptr, val;
3171 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3173 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3175 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3179 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3182 case OP_NOT_REACHED:
3183 LLVMBuildUnreachable (builder);
3184 has_terminator = TRUE;
3185 g_assert (bb->block_num < cfg->max_block_num);
3186 ctx->unreachable [bb->block_num] = TRUE;
3187 /* Might have instructions after this */
3189 MonoInst *next = ins->next;
3191 * FIXME: If later code uses the regs defined by these instructions,
3192 * compilation will fail.
3194 MONO_DELETE_INS (bb, next);
3198 MonoInst *var = ins->inst_p0;
3200 values [ins->dreg] = addresses [var->dreg];
3204 LLVMValueRef args [1];
3206 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3207 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3211 LLVMValueRef args [1];
3213 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3214 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3218 LLVMValueRef args [1];
3221 /* This no longer seems to happen */
3223 * LLVM optimizes sqrt(nan) into undefined in
3224 * lib/Analysis/ConstantFolding.cpp
3225 * Also, sqrt(NegativeInfinity) is optimized into 0.
3227 LLVM_FAILURE (ctx, "sqrt");
3230 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3234 LLVMValueRef args [1];
3237 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3251 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3252 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3254 switch (ins->opcode) {
3257 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3261 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3265 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3269 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3272 g_assert_not_reached ();
3275 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3278 case OP_ATOMIC_EXCHANGE_I4: {
3279 LLVMValueRef args [2];
3281 g_assert (ins->inst_offset == 0);
3283 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3286 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3289 case OP_ATOMIC_EXCHANGE_I8: {
3290 LLVMValueRef args [2];
3292 g_assert (ins->inst_offset == 0);
3294 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3295 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3296 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3299 case OP_ATOMIC_ADD_NEW_I4: {
3300 LLVMValueRef args [2];
3302 g_assert (ins->inst_offset == 0);
3304 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3306 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3309 case OP_ATOMIC_ADD_NEW_I8: {
3310 LLVMValueRef args [2];
3312 g_assert (ins->inst_offset == 0);
3314 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3315 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3316 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3319 case OP_ATOMIC_CAS_I4:
3320 case OP_ATOMIC_CAS_I8: {
3321 LLVMValueRef args [3];
3324 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3325 t = LLVMInt32Type ();
3327 t = LLVMInt64Type ();
3330 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3332 args [1] = convert (ctx, values [ins->sreg3], t);
3334 args [2] = convert (ctx, values [ins->sreg2], t);
3335 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3338 case OP_MEMORY_BARRIER: {
3340 /* Not yet supported by llc on arm */
3341 LLVM_FAILURE (ctx, "memory-barrier+arm");
3343 mono_llvm_build_fence (builder);
3346 case OP_RELAXED_NOP: {
3347 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3348 if (IS_LLVM_MONO_BRANCH)
3349 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3351 /* No way to get LLVM to emit this */
3352 LLVM_FAILURE (ctx, "relaxed_nop");
3359 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3361 // 257 == FS segment register
3362 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3364 // 256 == GS segment register
3365 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3369 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3371 LLVM_FAILURE (ctx, "opcode tls-get");
3381 case OP_IADD_OVF_UN:
3383 case OP_ISUB_OVF_UN:
3385 case OP_IMUL_OVF_UN:
3386 #if SIZEOF_VOID_P == 8
3388 case OP_LADD_OVF_UN:
3390 case OP_LSUB_OVF_UN:
3392 case OP_LMUL_OVF_UN:
3395 LLVMValueRef args [2], val, ovf, func;
3397 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3398 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3399 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3401 val = LLVMBuildCall (builder, func, args, 2, "");
3402 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3403 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3404 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3405 CHECK_FAILURE (ctx);
3406 builder = ctx->builder;
3412 * We currently model them using arrays. Promotion to local vregs is
3413 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3414 * so we always have an entry in cfg->varinfo for them.
3415 * FIXME: Is this needed ?
3418 MonoClass *klass = ins->klass;
3419 LLVMValueRef args [5];
3423 LLVM_FAILURE (ctx, "!klass");
3427 if (!addresses [ins->dreg])
3428 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3429 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3430 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3431 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3433 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3434 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3435 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3439 case OP_STOREV_MEMBASE:
3440 case OP_LOADV_MEMBASE:
3442 MonoClass *klass = ins->klass;
3443 LLVMValueRef src = NULL, dst, args [5];
3444 gboolean done = FALSE;
3448 LLVM_FAILURE (ctx, "!klass");
3452 switch (ins->opcode) {
3453 case OP_STOREV_MEMBASE:
3454 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3455 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3456 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3459 if (!addresses [ins->sreg1]) {
3461 g_assert (values [ins->sreg1]);
3462 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));
3463 LLVMBuildStore (builder, values [ins->sreg1], dst);
3466 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3467 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3470 case OP_LOADV_MEMBASE:
3471 if (!addresses [ins->dreg])
3472 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3473 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3474 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3477 if (!addresses [ins->sreg1])
3478 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3479 if (!addresses [ins->dreg])
3480 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3481 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3482 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3485 g_assert_not_reached ();
3487 CHECK_FAILURE (ctx);
3494 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3495 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3497 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3498 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3499 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3502 case OP_LLVM_OUTARG_VT:
3503 if (!addresses [ins->sreg1]) {
3504 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3505 g_assert (values [ins->sreg1]);
3506 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3508 addresses [ins->dreg] = addresses [ins->sreg1];
3514 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3516 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3519 case OP_LOADX_MEMBASE: {
3520 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3523 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3524 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3527 case OP_STOREX_MEMBASE: {
3528 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3531 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3532 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3539 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3543 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3549 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3553 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3557 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3561 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3564 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3567 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3570 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3574 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3585 LLVMValueRef v = NULL;
3587 switch (ins->opcode) {
3592 t = LLVMVectorType (LLVMInt32Type (), 4);
3593 rt = LLVMVectorType (LLVMFloatType (), 4);
3599 t = LLVMVectorType (LLVMInt64Type (), 2);
3600 rt = LLVMVectorType (LLVMDoubleType (), 2);
3603 t = LLVMInt32Type ();
3604 rt = LLVMInt32Type ();
3605 g_assert_not_reached ();
3608 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3609 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3610 switch (ins->opcode) {
3613 v = LLVMBuildAnd (builder, lhs, rhs, "");
3617 v = LLVMBuildOr (builder, lhs, rhs, "");
3621 v = LLVMBuildXor (builder, lhs, rhs, "");
3625 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3628 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3652 case OP_PADDB_SAT_UN:
3653 case OP_PADDW_SAT_UN:
3654 case OP_PSUBB_SAT_UN:
3655 case OP_PSUBW_SAT_UN:
3668 case OP_PMULW_HIGH_UN: {
3669 LLVMValueRef args [2];
3674 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3682 case OP_EXTRACTX_U2:
3684 case OP_EXTRACT_U1: {
3686 gboolean zext = FALSE;
3688 t = simd_op_to_llvm_type (ins->opcode);
3690 switch (ins->opcode) {
3698 case OP_EXTRACTX_U2:
3703 t = LLVMInt32Type ();
3704 g_assert_not_reached ();
3707 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3708 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3710 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3719 case OP_EXPAND_R8: {
3720 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3721 LLVMValueRef mask [16], v;
3723 for (i = 0; i < 16; ++i)
3724 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3726 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3728 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3729 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3734 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3737 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3740 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3743 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3746 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3749 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3760 case OP_EXTRACT_MASK:
3767 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3769 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3773 case OP_ICONV_TO_R8_RAW:
3774 /* Same as OP_ICONV_TO_R8 */
3775 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3780 LLVMValueRef args [3];
3784 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3786 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3791 /* This is only used for implementing shifts by non-immediate */
3792 values [ins->dreg] = lhs;
3803 LLVMValueRef args [3];
3806 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3808 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3819 case OP_PSHLQ_REG: {
3820 LLVMValueRef args [3];
3823 args [1] = values [ins->sreg2];
3825 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3832 case OP_PSHUFLEW_LOW:
3833 case OP_PSHUFLEW_HIGH: {
3835 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3836 int i, mask_size = 0;
3837 int imask = ins->inst_c0;
3839 /* Convert the x86 shuffle mask to LLVM's */
3840 switch (ins->opcode) {
3843 mask [0] = ((imask >> 0) & 3);
3844 mask [1] = ((imask >> 2) & 3);
3845 mask [2] = ((imask >> 4) & 3) + 4;
3846 mask [3] = ((imask >> 6) & 3) + 4;
3847 v1 = values [ins->sreg1];
3848 v2 = values [ins->sreg2];
3852 mask [0] = ((imask >> 0) & 1);
3853 mask [1] = ((imask >> 1) & 1) + 2;
3854 v1 = values [ins->sreg1];
3855 v2 = values [ins->sreg2];
3857 case OP_PSHUFLEW_LOW:
3859 mask [0] = ((imask >> 0) & 3);
3860 mask [1] = ((imask >> 2) & 3);
3861 mask [2] = ((imask >> 4) & 3);
3862 mask [3] = ((imask >> 6) & 3);
3867 v1 = values [ins->sreg1];
3868 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3870 case OP_PSHUFLEW_HIGH:
3876 mask [4] = 4 + ((imask >> 0) & 3);
3877 mask [5] = 4 + ((imask >> 2) & 3);
3878 mask [6] = 4 + ((imask >> 4) & 3);
3879 mask [7] = 4 + ((imask >> 6) & 3);
3880 v1 = values [ins->sreg1];
3881 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3885 mask [0] = ((imask >> 0) & 3);
3886 mask [1] = ((imask >> 2) & 3);
3887 mask [2] = ((imask >> 4) & 3);
3888 mask [3] = ((imask >> 6) & 3);
3889 v1 = values [ins->sreg1];
3890 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3893 g_assert_not_reached ();
3895 for (i = 0; i < mask_size; ++i)
3896 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3898 values [ins->dreg] =
3899 LLVMBuildShuffleVector (builder, v1, v2,
3900 LLVMConstVector (mask_values, mask_size), dname);
3904 case OP_UNPACK_LOWB:
3905 case OP_UNPACK_LOWW:
3906 case OP_UNPACK_LOWD:
3907 case OP_UNPACK_LOWQ:
3908 case OP_UNPACK_LOWPS:
3909 case OP_UNPACK_LOWPD:
3910 case OP_UNPACK_HIGHB:
3911 case OP_UNPACK_HIGHW:
3912 case OP_UNPACK_HIGHD:
3913 case OP_UNPACK_HIGHQ:
3914 case OP_UNPACK_HIGHPS:
3915 case OP_UNPACK_HIGHPD: {
3917 LLVMValueRef mask_values [16];
3918 int i, mask_size = 0;
3919 gboolean low = FALSE;
3921 switch (ins->opcode) {
3922 case OP_UNPACK_LOWB:
3926 case OP_UNPACK_LOWW:
3930 case OP_UNPACK_LOWD:
3931 case OP_UNPACK_LOWPS:
3935 case OP_UNPACK_LOWQ:
3936 case OP_UNPACK_LOWPD:
3940 case OP_UNPACK_HIGHB:
3943 case OP_UNPACK_HIGHW:
3946 case OP_UNPACK_HIGHD:
3947 case OP_UNPACK_HIGHPS:
3950 case OP_UNPACK_HIGHQ:
3951 case OP_UNPACK_HIGHPD:
3955 g_assert_not_reached ();
3959 for (i = 0; i < (mask_size / 2); ++i) {
3961 mask [(i * 2) + 1] = mask_size + i;
3964 for (i = 0; i < (mask_size / 2); ++i) {
3965 mask [(i * 2)] = (mask_size / 2) + i;
3966 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3970 for (i = 0; i < mask_size; ++i)
3971 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3973 values [ins->dreg] =
3974 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3975 LLVMConstVector (mask_values, mask_size), dname);
3980 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3981 LLVMValueRef v, val;
3983 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3984 val = LLVMConstNull (t);
3985 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3986 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3988 values [ins->dreg] = val;
3992 case OP_DUPPS_HIGH: {
3993 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3994 LLVMValueRef v1, v2, val;
3997 if (ins->opcode == OP_DUPPS_LOW) {
3998 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3999 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4001 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4002 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4004 val = LLVMConstNull (t);
4005 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4006 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4007 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4008 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4010 values [ins->dreg] = val;
4020 * EXCEPTION HANDLING
4022 case OP_IMPLICIT_EXCEPTION:
4023 /* This marks a place where an implicit exception can happen */
4024 if (bb->region != -1)
4025 LLVM_FAILURE (ctx, "implicit-exception");
4029 MonoMethodSignature *throw_sig;
4030 LLVMValueRef callee, arg;
4031 gboolean rethrow = (ins->opcode == OP_RETHROW);
4032 const char *icall_name;
4034 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4035 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4038 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4039 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4040 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4041 if (cfg->compile_aot) {
4042 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4044 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4048 * LLVM doesn't push the exception argument, so we need a different
4051 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4053 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4057 mono_memory_barrier ();
4059 ctx->lmodule->rethrow = callee;
4061 ctx->lmodule->throw = callee;
4063 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4064 emit_call (ctx, bb, &builder, callee, &arg, 1);
4067 case OP_CALL_HANDLER: {
4069 * We don't 'call' handlers, but instead simply branch to them.
4070 * The code generated by ENDFINALLY will branch back to us.
4072 LLVMBasicBlockRef noex_bb;
4074 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4076 bb_list = info->call_handler_return_bbs;
4079 * Set the indicator variable for the finally clause.
4081 lhs = info->finally_ind;
4083 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4085 /* Branch to the finally clause */
4086 LLVMBuildBr (builder, info->call_handler_target_bb);
4088 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4089 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4091 builder = ctx->builder = create_builder (ctx);
4092 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4094 bblocks [bb->block_num].end_bblock = noex_bb;
4097 case OP_START_HANDLER: {
4100 case OP_ENDFINALLY: {
4101 LLVMBasicBlockRef resume_bb;
4102 MonoBasicBlock *handler_bb;
4103 LLVMValueRef val, switch_ins, callee;
4107 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4108 g_assert (handler_bb);
4109 info = &bblocks [handler_bb->block_num];
4110 lhs = info->finally_ind;
4113 bb_list = info->call_handler_return_bbs;
4115 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4117 /* Load the finally variable */
4118 val = LLVMBuildLoad (builder, lhs, "");
4120 /* Reset the variable */
4121 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4123 /* Branch to either resume_bb, or to the bblocks in bb_list */
4124 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4126 * The other targets are added at the end to handle OP_CALL_HANDLER
4127 * opcodes processed later.
4129 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4131 builder = ctx->builder = create_builder (ctx);
4132 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4134 if (ctx->cfg->compile_aot) {
4135 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4137 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4139 LLVMBuildCall (builder, callee, NULL, 0, "");
4141 LLVMBuildUnreachable (builder);
4142 has_terminator = TRUE;
4148 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4149 LLVM_FAILURE (ctx, reason);
4154 /* Convert the value to the type required by phi nodes */
4155 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4156 if (!values [ins->dreg])
4158 values [ins->dreg] = addresses [ins->dreg];
4160 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4163 /* Add stores for volatile variables */
4164 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4165 emit_volatile_store (ctx, ins->dreg);
4168 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4169 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4171 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4172 LLVMBuildRetVoid (builder);
4174 if (bb == cfg->bb_entry)
4175 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4184 * mono_llvm_check_method_supported:
4186 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4187 * compiling a method twice.
4190 mono_llvm_check_method_supported (MonoCompile *cfg)
4193 MonoMethodHeader *header = cfg->header;
4194 MonoExceptionClause *clause;
4198 if (cfg->generic_sharing_context && !IS_LLVM_MONO_BRANCH) {
4199 /* No way to obtain location info for this/rgctx */
4200 cfg->exception_message = g_strdup ("gshared");
4201 cfg->disable_llvm = TRUE;
4204 if (cfg->method->save_lmf) {
4205 cfg->exception_message = g_strdup ("lmf");
4206 cfg->disable_llvm = TRUE;
4210 // FIXME: Doesn't work yet with the new LLVM EH Model
4211 if (cfg->header->num_clauses) {
4212 cfg->exception_message = g_strdup ("clauses");
4213 cfg->disable_llvm = TRUE;
4217 for (i = 0; i < header->num_clauses; ++i) {
4218 clause = &header->clauses [i];
4220 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4222 * FIXME: Some tests still fail with nested clauses.
4224 cfg->exception_message = g_strdup ("nested clauses");
4225 cfg->disable_llvm = TRUE;
4231 if (cfg->method->dynamic) {
4232 cfg->exception_message = g_strdup ("dynamic.");
4233 cfg->disable_llvm = TRUE;
4238 * mono_llvm_emit_method:
4240 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4243 mono_llvm_emit_method (MonoCompile *cfg)
4246 MonoMethodSignature *sig;
4248 LLVMTypeRef method_type;
4249 LLVMValueRef method = NULL;
4251 LLVMValueRef *values;
4252 int i, max_block_num, bb_index;
4253 gboolean last = FALSE;
4254 GPtrArray *phi_values;
4255 LLVMCallInfo *linfo;
4257 LLVMModuleRef module;
4259 GPtrArray *bblock_list;
4260 MonoMethodHeader *header;
4261 MonoExceptionClause *clause;
4265 /* The code below might acquire the loader lock, so use it for global locking */
4266 mono_loader_lock ();
4268 /* Used to communicate with the callbacks */
4269 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4271 ctx = g_new0 (EmitContext, 1);
4273 ctx->mempool = cfg->mempool;
4276 * This maps vregs to the LLVM instruction defining them
4278 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4280 * This maps vregs for volatile variables to the LLVM instruction defining their
4283 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4284 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4285 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4286 phi_values = g_ptr_array_new ();
4288 * This signals whenever the vreg was defined by a phi node with no input vars
4289 * (i.e. all its input bblocks end with NOT_REACHABLE).
4291 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4292 /* Whenever the bblock is unreachable */
4293 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4295 bblock_list = g_ptr_array_new ();
4297 ctx->values = values;
4298 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4300 if (cfg->compile_aot) {
4301 ctx->lmodule = &aot_module;
4302 method_name = mono_aot_get_method_name (cfg);
4303 cfg->llvm_method_name = g_strdup (method_name);
4306 ctx->lmodule = &jit_module;
4307 method_name = mono_method_full_name (cfg->method, TRUE);
4310 module = ctx->module = ctx->lmodule->module;
4314 static int count = 0;
4317 if (getenv ("LLVM_COUNT")) {
4318 if (count == atoi (getenv ("LLVM_COUNT"))) {
4319 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4323 if (count > atoi (getenv ("LLVM_COUNT")))
4324 LLVM_FAILURE (ctx, "");
4329 sig = mono_method_signature (cfg->method);
4332 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4334 CHECK_FAILURE (ctx);
4336 if (cfg->rgctx_var) {
4337 if (IS_LLVM_MONO_BRANCH)
4338 linfo->rgctx_arg = TRUE;
4340 LLVM_FAILURE (ctx, "rgctx arg");
4342 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4343 CHECK_FAILURE (ctx);
4346 * This maps parameter indexes in the original signature to the indexes in
4347 * the LLVM signature.
4349 ctx->pindexes = sinfo.pindexes;
4351 method = LLVMAddFunction (module, method_name, method_type);
4352 ctx->lmethod = method;
4354 #ifdef LLVM_MONO_BRANCH
4355 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4357 LLVMSetLinkage (method, LLVMPrivateLinkage);
4359 LLVMAddFunctionAttr (method, LLVMUWTable);
4361 if (cfg->compile_aot) {
4362 LLVMSetLinkage (method, LLVMInternalLinkage);
4363 LLVMSetVisibility (method, LLVMHiddenVisibility);
4365 LLVMSetLinkage (method, LLVMPrivateLinkage);
4368 if (cfg->method->save_lmf)
4369 LLVM_FAILURE (ctx, "lmf");
4371 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4372 LLVM_FAILURE (ctx, "pinvoke signature");
4374 header = cfg->header;
4375 for (i = 0; i < header->num_clauses; ++i) {
4376 clause = &header->clauses [i];
4377 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4378 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4381 if (linfo->rgctx_arg) {
4382 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4384 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4385 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4386 * CC_X86_64_Mono in X86CallingConv.td.
4388 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4389 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4391 if (cfg->vret_addr) {
4392 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4393 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4396 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4397 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4400 names = g_new (char *, sig->param_count);
4401 mono_method_get_param_names (cfg->method, (const char **) names);
4403 for (i = 0; i < sig->param_count; ++i) {
4406 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4407 if (names [i] && names [i][0] != '\0')
4408 name = g_strdup_printf ("arg_%s", names [i]);
4410 name = g_strdup_printf ("arg_%d", i);
4411 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4413 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4414 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4419 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4420 max_block_num = MAX (max_block_num, bb->block_num);
4421 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4423 /* Add branches between non-consecutive bblocks */
4424 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4425 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4426 bb->next_bb != bb->last_ins->inst_false_bb) {
4428 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4429 inst->opcode = OP_BR;
4430 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4431 mono_bblock_add_inst (bb, inst);
4436 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4437 * was later optimized away, so clear these flags, and add them back for the still
4438 * present OP_LDADDR instructions.
4440 for (i = 0; i < cfg->next_vreg; ++i) {
4443 ins = get_vreg_to_inst (cfg, i);
4444 if (ins && ins != cfg->rgctx_var)
4445 ins->flags &= ~MONO_INST_INDIRECT;
4449 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4451 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4453 LLVMBuilderRef builder;
4455 char dname_buf[128];
4457 builder = create_builder (ctx);
4459 for (ins = bb->code; ins; ins = ins->next) {
4460 switch (ins->opcode) {
4465 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4467 CHECK_FAILURE (ctx);
4469 if (ins->opcode == OP_VPHI) {
4470 /* Treat valuetype PHI nodes as operating on the address itself */
4471 g_assert (ins->klass);
4472 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4476 * Have to precreate these, as they can be referenced by
4477 * earlier instructions.
4479 sprintf (dname_buf, "t%d", ins->dreg);
4481 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4483 if (ins->opcode == OP_VPHI)
4484 ctx->addresses [ins->dreg] = values [ins->dreg];
4486 g_ptr_array_add (phi_values, values [ins->dreg]);
4489 * Set the expected type of the incoming arguments since these have
4490 * to have the same type.
4492 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4493 int sreg1 = ins->inst_phi_args [i + 1];
4496 ctx->vreg_types [sreg1] = phi_type;
4501 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4510 * Create an ordering for bblocks, use the depth first order first, then
4511 * put the exception handling bblocks last.
4513 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4514 bb = cfg->bblocks [bb_index];
4515 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4516 g_ptr_array_add (bblock_list, bb);
4517 bblocks [bb->block_num].added = TRUE;
4521 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4522 if (!bblocks [bb->block_num].added)
4523 g_ptr_array_add (bblock_list, bb);
4527 * Second pass: generate code.
4529 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4530 bb = g_ptr_array_index (bblock_list, bb_index);
4532 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4535 process_bb (ctx, bb);
4536 CHECK_FAILURE (ctx);
4539 /* Add incoming phi values */
4540 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4541 GSList *l, *ins_list;
4543 ins_list = bblocks [bb->block_num].phi_nodes;
4545 for (l = ins_list; l; l = l->next) {
4546 PhiNode *node = l->data;
4547 MonoInst *phi = node->phi;
4548 int sreg1 = node->sreg;
4549 LLVMBasicBlockRef in_bb;
4554 in_bb = get_end_bb (ctx, node->in_bb);
4556 if (ctx->unreachable [node->in_bb->block_num])
4559 g_assert (values [sreg1]);
4561 if (phi->opcode == OP_VPHI) {
4562 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4563 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4565 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4566 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4571 /* Create the SWITCH statements for ENDFINALLY instructions */
4572 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4573 BBInfo *info = &bblocks [bb->block_num];
4575 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4576 LLVMValueRef switch_ins = l->data;
4577 GSList *bb_list = info->call_handler_return_bbs;
4579 for (i = 0; i < g_slist_length (bb_list); ++i)
4580 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4584 if (cfg->verbose_level > 1)
4585 mono_llvm_dump_value (method);
4587 mark_as_used (module, method);
4589 if (cfg->compile_aot) {
4590 /* Don't generate native code, keep the LLVM IR */
4591 if (cfg->compile_aot && cfg->verbose_level)
4592 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4594 //LLVMVerifyFunction(method, 0);
4596 mono_llvm_optimize_method (method);
4598 if (cfg->verbose_level > 1)
4599 mono_llvm_dump_value (method);
4601 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4603 /* Set by emit_cb */
4604 g_assert (cfg->code_len);
4606 /* FIXME: Free the LLVM IL for the function */
4614 /* Need to add unused phi nodes as they can be referenced by other values */
4615 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4616 LLVMBuilderRef builder;
4618 builder = create_builder (ctx);
4619 LLVMPositionBuilderAtEnd (builder, phi_bb);
4621 for (i = 0; i < phi_values->len; ++i) {
4622 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4623 if (LLVMGetInstructionParent (v) == NULL)
4624 LLVMInsertIntoBuilder (builder, v);
4627 LLVMDeleteFunction (method);
4632 g_free (ctx->addresses);
4633 g_free (ctx->vreg_types);
4634 g_free (ctx->vreg_cli_types);
4635 g_free (ctx->pindexes);
4636 g_free (ctx->is_dead);
4637 g_free (ctx->unreachable);
4638 g_ptr_array_free (phi_values, TRUE);
4639 g_free (ctx->bblocks);
4640 g_hash_table_destroy (ctx->region_to_handler);
4641 g_free (method_name);
4642 g_ptr_array_free (bblock_list, TRUE);
4644 for (l = ctx->builders; l; l = l->next) {
4645 LLVMBuilderRef builder = l->data;
4646 LLVMDisposeBuilder (builder);
4651 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4653 mono_loader_unlock ();
4657 * mono_llvm_emit_call:
4659 * Same as mono_arch_emit_call () for LLVM.
4662 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4665 MonoMethodSignature *sig;
4666 int i, n, stack_size;
4671 sig = call->signature;
4672 n = sig->param_count + sig->hasthis;
4674 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4676 if (cfg->disable_llvm)
4679 if (sig->call_convention == MONO_CALL_VARARG) {
4680 cfg->exception_message = g_strdup ("varargs");
4681 cfg->disable_llvm = TRUE;
4684 for (i = 0; i < n; ++i) {
4687 ainfo = call->cinfo->args + i;
4689 in = call->args [i];
4691 /* Simply remember the arguments */
4692 switch (ainfo->storage) {
4694 MONO_INST_NEW (cfg, ins, OP_MOVE);
4695 ins->dreg = mono_alloc_ireg (cfg);
4696 ins->sreg1 = in->dreg;
4698 case LLVMArgInFPReg:
4699 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4700 ins->dreg = mono_alloc_freg (cfg);
4701 ins->sreg1 = in->dreg;
4703 case LLVMArgVtypeByVal:
4704 case LLVMArgVtypeInReg:
4705 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4706 ins->dreg = mono_alloc_ireg (cfg);
4707 ins->sreg1 = in->dreg;
4708 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4711 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4712 cfg->exception_message = g_strdup ("ainfo->storage");
4713 cfg->disable_llvm = TRUE;
4717 if (!cfg->disable_llvm) {
4718 MONO_ADD_INS (cfg->cbb, ins);
4719 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4724 static unsigned char*
4725 alloc_cb (LLVMValueRef function, int size)
4729 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4733 return mono_domain_code_reserve (cfg->domain, size);
4735 return mono_domain_code_reserve (mono_domain_get (), size);
4740 emitted_cb (LLVMValueRef function, void *start, void *end)
4744 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4746 cfg->code_len = (guint8*)end - (guint8*)start;
4750 exception_cb (void *data)
4753 MonoJitExceptionInfo *ei;
4754 guint32 ei_len, i, j, nested_len, nindex;
4755 gpointer *type_info;
4756 int this_reg, this_offset;
4758 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4762 * data points to a DWARF FDE structure, convert it to our unwind format and
4764 * An alternative would be to save it directly, and modify our unwinder to work
4767 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);
4769 /* Count nested clauses */
4771 for (i = 0; i < ei_len; ++i) {
4772 for (j = 0; j < ei_len; ++j) {
4773 gint32 cindex1 = *(gint32*)type_info [i];
4774 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4775 gint32 cindex2 = *(gint32*)type_info [j];
4776 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4778 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4784 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4785 cfg->llvm_ex_info_len = ei_len + nested_len;
4786 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4787 /* Fill the rest of the information from the type info */
4788 for (i = 0; i < ei_len; ++i) {
4789 gint32 clause_index = *(gint32*)type_info [i];
4790 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4792 cfg->llvm_ex_info [i].flags = clause->flags;
4793 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4797 * For nested clauses, the LLVM produced exception info associates the try interval with
4798 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4800 /* FIXME: These should be order with the normal clauses */
4802 for (i = 0; i < ei_len; ++i) {
4803 for (j = 0; j < ei_len; ++j) {
4804 gint32 cindex1 = *(gint32*)type_info [i];
4805 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4806 gint32 cindex2 = *(gint32*)type_info [j];
4807 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4809 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4811 * The try interval comes from the nested clause, everything else from the
4814 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4815 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4816 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4821 g_assert (nindex == ei_len + nested_len);
4822 cfg->llvm_this_reg = this_reg;
4823 cfg->llvm_this_offset = this_offset;
4825 /* type_info [i] is cfg mempool allocated, no need to free it */
4832 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4834 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4838 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4840 LLVMTypeRef param_types [4];
4842 param_types [0] = param_type1;
4843 param_types [1] = param_type2;
4845 AddFunc (module, name, ret_type, param_types, 2);
4849 add_intrinsics (LLVMModuleRef module)
4851 /* Emit declarations of instrinsics */
4853 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4854 * type doesn't seem to do any locking.
4857 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4859 memset_param_count = 5;
4860 memset_func_name = "llvm.memset.p0i8.i32";
4862 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4866 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4868 memcpy_param_count = 5;
4869 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4871 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4875 LLVMTypeRef params [] = { LLVMDoubleType () };
4877 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4878 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4879 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4881 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4882 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4886 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4887 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4889 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4890 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4891 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4892 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4893 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4894 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4898 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4899 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4901 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4902 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4903 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4904 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4905 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4906 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4910 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4911 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4912 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4914 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4916 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4921 LLVMTypeRef arg_types [2];
4922 LLVMTypeRef ret_type;
4924 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4925 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4926 eh_selector_name = "llvm.eh.selector";
4927 ret_type = LLVMInt32Type ();
4929 LLVMAddFunction (module, eh_selector_name, LLVMFunctionType (ret_type, arg_types, 2, TRUE));
4931 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
4933 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4935 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4938 /* SSE intrinsics */
4940 LLVMTypeRef ret_type, arg_types [2];
4943 ret_type = type_to_simd_type (MONO_TYPE_I4);
4944 arg_types [0] = ret_type;
4945 arg_types [1] = ret_type;
4946 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4947 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4948 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4950 ret_type = type_to_simd_type (MONO_TYPE_I2);
4951 arg_types [0] = ret_type;
4952 arg_types [1] = ret_type;
4953 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4954 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4955 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4956 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4957 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4958 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4959 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4960 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4961 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4962 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4963 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4965 ret_type = type_to_simd_type (MONO_TYPE_I1);
4966 arg_types [0] = ret_type;
4967 arg_types [1] = ret_type;
4968 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4969 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4970 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4971 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4972 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4973 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4974 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4975 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4976 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4978 ret_type = type_to_simd_type (MONO_TYPE_I8);
4979 arg_types [0] = ret_type;
4980 arg_types [1] = ret_type;
4981 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4983 ret_type = type_to_simd_type (MONO_TYPE_R8);
4984 arg_types [0] = ret_type;
4985 arg_types [1] = ret_type;
4986 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4987 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4988 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4989 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4990 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4992 ret_type = type_to_simd_type (MONO_TYPE_R4);
4993 arg_types [0] = ret_type;
4994 arg_types [1] = ret_type;
4995 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4996 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4997 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4998 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4999 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5002 ret_type = type_to_simd_type (MONO_TYPE_I1);
5003 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5004 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5005 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5006 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5007 ret_type = type_to_simd_type (MONO_TYPE_I2);
5008 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5009 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5010 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5011 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5014 ret_type = type_to_simd_type (MONO_TYPE_R8);
5015 arg_types [0] = ret_type;
5016 arg_types [1] = ret_type;
5017 arg_types [2] = LLVMInt8Type ();
5018 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5019 ret_type = type_to_simd_type (MONO_TYPE_R4);
5020 arg_types [0] = ret_type;
5021 arg_types [1] = ret_type;
5022 arg_types [2] = LLVMInt8Type ();
5023 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5025 /* Conversion ops */
5026 ret_type = type_to_simd_type (MONO_TYPE_R8);
5027 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5028 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5029 ret_type = type_to_simd_type (MONO_TYPE_R4);
5030 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5031 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5032 ret_type = type_to_simd_type (MONO_TYPE_I4);
5033 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5034 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5035 ret_type = type_to_simd_type (MONO_TYPE_I4);
5036 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5037 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5038 ret_type = type_to_simd_type (MONO_TYPE_R4);
5039 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5040 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5041 ret_type = type_to_simd_type (MONO_TYPE_R8);
5042 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5043 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5045 ret_type = type_to_simd_type (MONO_TYPE_I4);
5046 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5047 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5048 ret_type = type_to_simd_type (MONO_TYPE_I4);
5049 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5050 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5053 ret_type = type_to_simd_type (MONO_TYPE_R8);
5054 arg_types [0] = ret_type;
5055 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5056 ret_type = type_to_simd_type (MONO_TYPE_R4);
5057 arg_types [0] = ret_type;
5058 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5059 ret_type = type_to_simd_type (MONO_TYPE_R4);
5060 arg_types [0] = ret_type;
5061 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5062 ret_type = type_to_simd_type (MONO_TYPE_R4);
5063 arg_types [0] = ret_type;
5064 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5067 ret_type = type_to_simd_type (MONO_TYPE_I2);
5068 arg_types [0] = ret_type;
5069 arg_types [1] = LLVMInt32Type ();
5070 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5071 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5072 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5073 ret_type = type_to_simd_type (MONO_TYPE_I4);
5074 arg_types [0] = ret_type;
5075 arg_types [1] = LLVMInt32Type ();
5076 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5077 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5078 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5079 ret_type = type_to_simd_type (MONO_TYPE_I8);
5080 arg_types [0] = ret_type;
5081 arg_types [1] = LLVMInt32Type ();
5082 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5083 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5086 ret_type = LLVMInt32Type ();
5087 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5088 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5091 if (IS_LLVM_MONO_BRANCH) {
5092 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5095 /* Load/Store intrinsics */
5096 if (IS_LLVM_MONO_BRANCH) {
5097 LLVMTypeRef arg_types [5];
5101 for (i = 1; i <= 8; i *= 2) {
5102 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5103 arg_types [1] = LLVMInt32Type ();
5104 arg_types [2] = LLVMInt1Type ();
5105 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5106 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5108 arg_types [0] = LLVMIntType (i * 8);
5109 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5110 arg_types [2] = LLVMInt32Type ();
5111 arg_types [3] = LLVMInt1Type ();
5112 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5113 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5119 mono_llvm_init (void)
5121 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5125 init_jit_module (void)
5127 MonoJitICallInfo *info;
5129 if (jit_module_inited)
5132 mono_loader_lock ();
5134 if (jit_module_inited) {
5135 mono_loader_unlock ();
5139 jit_module.module = LLVMModuleCreateWithName ("mono");
5141 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5143 add_intrinsics (jit_module.module);
5145 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5147 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5149 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5151 jit_module_inited = TRUE;
5153 mono_loader_unlock ();
5157 mono_llvm_cleanup (void)
5160 mono_llvm_dispose_ee (ee);
5162 if (jit_module.llvm_types)
5163 g_hash_table_destroy (jit_module.llvm_types);
5165 if (aot_module.module)
5166 LLVMDisposeModule (aot_module.module);
5168 LLVMContextDispose (LLVMGetGlobalContext ());
5172 mono_llvm_create_aot_module (const char *got_symbol)
5174 /* Delete previous module */
5175 if (aot_module.plt_entries)
5176 g_hash_table_destroy (aot_module.plt_entries);
5177 if (aot_module.module)
5178 LLVMDisposeModule (aot_module.module);
5180 memset (&aot_module, 0, sizeof (aot_module));
5182 aot_module.module = LLVMModuleCreateWithName ("aot");
5183 aot_module.got_symbol = got_symbol;
5185 add_intrinsics (aot_module.module);
5189 * We couldn't compute the type of the LLVM global representing the got because
5190 * its size is only known after all the methods have been emitted. So create
5191 * a dummy variable, and replace all uses it with the real got variable when
5192 * its size is known in mono_llvm_emit_aot_module ().
5195 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5197 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5198 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5201 /* Add a dummy personality function */
5203 LLVMBasicBlockRef lbb;
5204 LLVMBuilderRef lbuilder;
5205 LLVMValueRef personality;
5207 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5208 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5209 lbb = LLVMAppendBasicBlock (personality, "BB0");
5210 lbuilder = LLVMCreateBuilder ();
5211 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5212 LLVMBuildRetVoid (lbuilder);
5215 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5216 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5220 * Emit the aot module into the LLVM bitcode file FILENAME.
5223 mono_llvm_emit_aot_module (const char *filename, int got_size)
5225 LLVMTypeRef got_type;
5226 LLVMValueRef real_got;
5229 * Create the real got variable and replace all uses of the dummy variable with
5232 got_type = LLVMArrayType (IntPtrType (), got_size);
5233 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5234 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5235 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5237 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5239 mark_as_used (aot_module.module, real_got);
5241 /* Delete the dummy got so it doesn't become a global */
5242 LLVMDeleteGlobal (aot_module.got_var);
5248 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5249 g_assert_not_reached ();
5254 LLVMWriteBitcodeToFile (aot_module.module, filename);
5259 - Emit LLVM IR from the mono IR using the LLVM C API.
5260 - The original arch specific code remains, so we can fall back to it if we run
5261 into something we can't handle.
5265 A partial list of issues:
5266 - Handling of opcodes which can throw exceptions.
5268 In the mono JIT, these are implemented using code like this:
5275 push throw_pos - method
5276 call <exception trampoline>
5278 The problematic part is push throw_pos - method, which cannot be represented
5279 in the LLVM IR, since it does not support label values.
5280 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5281 be implemented in JIT mode ?
5282 -> a possible but slower implementation would use the normal exception
5283 throwing code but it would need to control the placement of the throw code
5284 (it needs to be exactly after the compare+branch).
5285 -> perhaps add a PC offset intrinsics ?
5287 - efficient implementation of .ovf opcodes.
5289 These are currently implemented as:
5290 <ins which sets the condition codes>
5293 Some overflow opcodes are now supported by LLVM SVN.
5295 - exception handling, unwinding.
5296 - SSA is disabled for methods with exception handlers
5297 - How to obtain unwind info for LLVM compiled methods ?
5298 -> this is now solved by converting the unwind info generated by LLVM
5300 - LLVM uses the c++ exception handling framework, while we use our home grown
5301 code, and couldn't use the c++ one:
5302 - its not supported under VC++, other exotic platforms.
5303 - it might be impossible to support filter clauses with it.
5307 The trampolines need a predictable call sequence, since they need to disasm
5308 the calling code to obtain register numbers / offsets.
5310 LLVM currently generates this code in non-JIT mode:
5311 mov -0x98(%rax),%eax
5313 Here, the vtable pointer is lost.
5314 -> solution: use one vtable trampoline per class.
5316 - passing/receiving the IMT pointer/RGCTX.
5317 -> solution: pass them as normal arguments ?
5321 LLVM does not allow the specification of argument registers etc. This means
5322 that all calls are made according to the platform ABI.
5324 - passing/receiving vtypes.
5326 Vtypes passed/received in registers are handled by the front end by using
5327 a signature with scalar arguments, and loading the parts of the vtype into those
5330 Vtypes passed on the stack are handled using the 'byval' attribute.
5334 Supported though alloca, we need to emit the load/store code.
5338 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5339 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5340 This is made easier because the IR is already in SSA form.
5341 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5342 types are frequently used incorrectly.
5347 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5348 append the AOT data structures to that file. For methods which cannot be
5349 handled by LLVM, the normal JIT compiled versions are used.
5352 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5353 * - each bblock should end with a branch
5354 * - setting the return value, making cfg->ret non-volatile
5355 * - avoid some transformations in the JIT which make it harder for us to generate
5357 * - use pointer types to help optimizations.