[llvm] Use the global llvm context instead of creating a new one for each aot module...
[mono-project.git] / mono / mini / mini-llvm.c
blobb83c823acfb57b9c0df3e1d56790906fa106dae8
1 /*
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)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
7 */
9 #include "mini.h"
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
23 #endif
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
26 #endif
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
32 #include "llvm-jit.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
36 #ifdef __MINGW32__
38 #include <stddef.h>
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
42 #endif
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
46 #endif
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
53 typedef struct {
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
57 LLVMValueRef got_var;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
65 char **bb_names;
66 int bb_names_len;
67 GPtrArray *used;
68 LLVMTypeRef ptr_type;
69 GPtrArray *subprogram_mds;
70 MonoEERef *mono_ee;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
73 gboolean emit_dwarf;
74 int max_got_offset;
75 LLVMValueRef personality;
77 /* For AOT */
78 MonoAssembly *assembly;
79 char *global_prefix;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
89 gboolean static_link;
90 gboolean llvm_only;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
98 GHashTable *objc_selector_to_var;
99 } MonoLLVMModule;
102 * Information associated by the backend with mono basic blocks.
104 typedef struct {
105 LLVMBasicBlockRef bblock, end_bblock;
106 LLVMValueRef finally_ind;
107 gboolean added, invoke_target;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList *call_handler_return_bbs;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList *endfinally_switch_ins_list;
120 GSList *phi_nodes;
121 } BBInfo;
124 * Structure containing emit state
126 typedef struct {
127 MonoMemPool *mempool;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable *emitted_method_decls;
132 MonoCompile *cfg;
133 LLVMValueRef lmethod;
134 MonoLLVMModule *module;
135 LLVMModuleRef lmodule;
136 BBInfo *bblocks;
137 int sindex, default_index, ex_index;
138 LLVMBuilderRef builder;
139 LLVMValueRef *values, *addresses;
140 MonoType **vreg_cli_types;
141 LLVMCallInfo *linfo;
142 MonoMethodSignature *sig;
143 GSList *builders;
144 GHashTable *region_to_handler;
145 GHashTable *clause_to_handler;
146 LLVMBuilderRef alloca_builder;
147 LLVMValueRef last_alloca;
148 LLVMValueRef rgctx_arg;
149 LLVMValueRef this_arg;
150 LLVMTypeRef *vreg_types;
151 gboolean *is_vphi;
152 LLVMTypeRef method_type;
153 LLVMBasicBlockRef init_bb, inited_bb;
154 gboolean *is_dead;
155 gboolean *unreachable;
156 gboolean llvm_only;
157 gboolean has_got_access;
158 gboolean is_linkonce;
159 int this_arg_pindex, rgctx_arg_pindex;
160 LLVMValueRef imt_rgctx_loc;
161 GHashTable *llvm_types;
162 LLVMValueRef dbg_md;
163 MonoDebugMethodInfo *minfo;
164 char temp_name [32];
165 /* For every clause, the clauses it is nested in */
166 GSList **nested_in;
167 LLVMValueRef ex_var;
168 GHashTable *exc_meta;
169 GHashTable *method_to_callers;
170 GPtrArray *phi_values;
171 GPtrArray *bblock_list;
172 char *method_name;
173 GHashTable *jit_callees;
174 } EmitContext;
176 typedef struct {
177 MonoBasicBlock *bb;
178 MonoInst *phi;
179 MonoBasicBlock *in_bb;
180 int sreg;
181 } PhiNode;
184 * Instruction metadata
185 * This is the same as ins_info, but LREG != IREG.
187 #ifdef MINI_OP
188 #undef MINI_OP
189 #endif
190 #ifdef MINI_OP3
191 #undef MINI_OP3
192 #endif
193 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
194 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
195 #define NONE ' '
196 #define IREG 'i'
197 #define FREG 'f'
198 #define VREG 'v'
199 #define XREG 'x'
200 #define LREG 'l'
201 /* keep in sync with the enum in mini.h */
202 const char
203 llvm_ins_info[] = {
204 #include "mini-ops.h"
206 #undef MINI_OP
207 #undef MINI_OP3
209 #if SIZEOF_VOID_P == 4
210 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
211 #else
212 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
213 #endif
215 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
217 #if 0
218 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
219 #else
220 #define TRACE_FAILURE(msg)
221 #endif
223 #ifdef TARGET_X86
224 #define IS_TARGET_X86 1
225 #else
226 #define IS_TARGET_X86 0
227 #endif
229 #ifdef TARGET_AMD64
230 #define IS_TARGET_AMD64 1
231 #else
232 #define IS_TARGET_AMD64 0
233 #endif
235 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
237 static LLVMIntPredicate cond_to_llvm_cond [] = {
238 LLVMIntEQ,
239 LLVMIntNE,
240 LLVMIntSLE,
241 LLVMIntSGE,
242 LLVMIntSLT,
243 LLVMIntSGT,
244 LLVMIntULE,
245 LLVMIntUGE,
246 LLVMIntULT,
247 LLVMIntUGT,
250 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
251 LLVMRealOEQ,
252 LLVMRealUNE,
253 LLVMRealOLE,
254 LLVMRealOGE,
255 LLVMRealOLT,
256 LLVMRealOGT,
257 LLVMRealULE,
258 LLVMRealUGE,
259 LLVMRealULT,
260 LLVMRealUGT,
263 static MonoNativeTlsKey current_cfg_tls_id;
265 static MonoLLVMModule aot_module;
267 static GHashTable *intrins_id_to_name;
268 static GHashTable *intrins_name_to_id;
270 static void init_jit_module (MonoDomain *domain);
272 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
273 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
274 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
275 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
276 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
277 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
279 static inline void
280 set_failure (EmitContext *ctx, const char *message)
282 TRACE_FAILURE (reason);
283 ctx->cfg->exception_message = g_strdup (message);
284 ctx->cfg->disable_llvm = TRUE;
288 * IntPtrType:
290 * The LLVM type with width == sizeof (gpointer)
292 static LLVMTypeRef
293 IntPtrType (void)
295 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
298 static LLVMTypeRef
299 ObjRefType (void)
301 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 static LLVMTypeRef
305 ThisType (void)
307 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 * get_vtype_size:
313 * Return the size of the LLVM representation of the vtype T.
315 static guint32
316 get_vtype_size (MonoType *t)
318 int size;
320 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
322 /* LLVMArgAsIArgs depends on this since it stores whole words */
323 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
324 size ++;
326 return size;
330 * simd_class_to_llvm_type:
332 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
334 static LLVMTypeRef
335 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
337 if (!strcmp (klass->name, "Vector2d")) {
338 return LLVMVectorType (LLVMDoubleType (), 2);
339 } else if (!strcmp (klass->name, "Vector2l")) {
340 return LLVMVectorType (LLVMInt64Type (), 2);
341 } else if (!strcmp (klass->name, "Vector2ul")) {
342 return LLVMVectorType (LLVMInt64Type (), 2);
343 } else if (!strcmp (klass->name, "Vector4i")) {
344 return LLVMVectorType (LLVMInt32Type (), 4);
345 } else if (!strcmp (klass->name, "Vector4ui")) {
346 return LLVMVectorType (LLVMInt32Type (), 4);
347 } else if (!strcmp (klass->name, "Vector4f")) {
348 return LLVMVectorType (LLVMFloatType (), 4);
349 } else if (!strcmp (klass->name, "Vector8s")) {
350 return LLVMVectorType (LLVMInt16Type (), 8);
351 } else if (!strcmp (klass->name, "Vector8us")) {
352 return LLVMVectorType (LLVMInt16Type (), 8);
353 } else if (!strcmp (klass->name, "Vector16sb")) {
354 return LLVMVectorType (LLVMInt8Type (), 16);
355 } else if (!strcmp (klass->name, "Vector16b")) {
356 return LLVMVectorType (LLVMInt8Type (), 16);
357 } else {
358 printf ("%s\n", klass->name);
359 NOT_IMPLEMENTED;
360 return NULL;
364 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
365 static inline G_GNUC_UNUSED LLVMTypeRef
366 type_to_simd_type (int type)
368 switch (type) {
369 case MONO_TYPE_I1:
370 return LLVMVectorType (LLVMInt8Type (), 16);
371 case MONO_TYPE_I2:
372 return LLVMVectorType (LLVMInt16Type (), 8);
373 case MONO_TYPE_I4:
374 return LLVMVectorType (LLVMInt32Type (), 4);
375 case MONO_TYPE_I8:
376 return LLVMVectorType (LLVMInt64Type (), 2);
377 case MONO_TYPE_R8:
378 return LLVMVectorType (LLVMDoubleType (), 2);
379 case MONO_TYPE_R4:
380 return LLVMVectorType (LLVMFloatType (), 4);
381 default:
382 g_assert_not_reached ();
383 return NULL;
387 static LLVMTypeRef
388 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
390 int i, size, nfields, esize;
391 LLVMTypeRef *eltypes;
392 char *name;
393 MonoType *t;
394 LLVMTypeRef ltype;
396 t = &klass->byval_arg;
398 if (mini_type_is_hfa (t, &nfields, &esize)) {
400 * This is needed on arm64 where HFAs are returned in
401 * registers.
403 size = nfields;
404 eltypes = g_new (LLVMTypeRef, size);
405 for (i = 0; i < size; ++i)
406 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
407 } else {
408 size = get_vtype_size (t);
410 eltypes = g_new (LLVMTypeRef, size);
411 for (i = 0; i < size; ++i)
412 eltypes [i] = LLVMInt8Type ();
415 name = mono_type_full_name (&klass->byval_arg);
416 ltype = LLVMStructCreateNamed (module->context, name);
417 LLVMStructSetBody (ltype, eltypes, size, FALSE);
418 g_free (eltypes);
419 g_free (name);
421 return ltype;
425 * type_to_llvm_type:
427 * Return the LLVM type corresponding to T.
429 static LLVMTypeRef
430 type_to_llvm_type (EmitContext *ctx, MonoType *t)
432 t = mini_get_underlying_type (t);
434 switch (t->type) {
435 case MONO_TYPE_VOID:
436 return LLVMVoidType ();
437 case MONO_TYPE_I1:
438 return LLVMInt8Type ();
439 case MONO_TYPE_I2:
440 return LLVMInt16Type ();
441 case MONO_TYPE_I4:
442 return LLVMInt32Type ();
443 case MONO_TYPE_U1:
444 return LLVMInt8Type ();
445 case MONO_TYPE_U2:
446 return LLVMInt16Type ();
447 case MONO_TYPE_U4:
448 return LLVMInt32Type ();
449 case MONO_TYPE_BOOLEAN:
450 return LLVMInt8Type ();
451 case MONO_TYPE_I8:
452 case MONO_TYPE_U8:
453 return LLVMInt64Type ();
454 case MONO_TYPE_CHAR:
455 return LLVMInt16Type ();
456 case MONO_TYPE_R4:
457 return LLVMFloatType ();
458 case MONO_TYPE_R8:
459 return LLVMDoubleType ();
460 case MONO_TYPE_I:
461 case MONO_TYPE_U:
462 return IntPtrType ();
463 case MONO_TYPE_OBJECT:
464 case MONO_TYPE_CLASS:
465 case MONO_TYPE_ARRAY:
466 case MONO_TYPE_SZARRAY:
467 case MONO_TYPE_STRING:
468 case MONO_TYPE_PTR:
469 return ObjRefType ();
470 case MONO_TYPE_VAR:
471 case MONO_TYPE_MVAR:
472 /* Because of generic sharing */
473 return ObjRefType ();
474 case MONO_TYPE_GENERICINST:
475 if (!mono_type_generic_inst_is_valuetype (t))
476 return ObjRefType ();
477 /* Fall through */
478 case MONO_TYPE_VALUETYPE:
479 case MONO_TYPE_TYPEDBYREF: {
480 MonoClass *klass;
481 LLVMTypeRef ltype;
483 klass = mono_class_from_mono_type (t);
485 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
486 return simd_class_to_llvm_type (ctx, klass);
488 if (klass->enumtype)
489 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
491 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
492 if (!ltype) {
493 ltype = create_llvm_type_for_type (ctx->module, klass);
494 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
496 return ltype;
499 default:
500 printf ("X: %d\n", t->type);
501 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
502 ctx->cfg->disable_llvm = TRUE;
503 return NULL;
508 * type_is_unsigned:
510 * Return whenever T is an unsigned int type.
512 static gboolean
513 type_is_unsigned (EmitContext *ctx, MonoType *t)
515 t = mini_get_underlying_type (t);
516 if (t->byref)
517 return FALSE;
518 switch (t->type) {
519 case MONO_TYPE_U1:
520 case MONO_TYPE_U2:
521 case MONO_TYPE_CHAR:
522 case MONO_TYPE_U4:
523 case MONO_TYPE_U8:
524 return TRUE;
525 default:
526 return FALSE;
531 * type_to_llvm_arg_type:
533 * Same as type_to_llvm_type, but treat i8/i16 as i32.
535 static LLVMTypeRef
536 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
538 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
540 if (ctx->cfg->llvm_only)
541 return ptype;
544 * This works on all abis except arm64/ios which passes multiple
545 * arguments in one stack slot.
547 #ifndef TARGET_ARM64
548 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
550 * LLVM generates code which only sets the lower bits, while JITted
551 * code expects all the bits to be set.
553 ptype = LLVMInt32Type ();
555 #endif
557 return ptype;
561 * llvm_type_to_stack_type:
563 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
564 * on the IL stack.
566 static G_GNUC_UNUSED LLVMTypeRef
567 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
569 if (type == NULL)
570 return NULL;
571 if (type == LLVMInt8Type ())
572 return LLVMInt32Type ();
573 else if (type == LLVMInt16Type ())
574 return LLVMInt32Type ();
575 else if (!cfg->r4fp && type == LLVMFloatType ())
576 return LLVMDoubleType ();
577 else
578 return type;
582 * regtype_to_llvm_type:
584 * Return the LLVM type corresponding to the regtype C used in instruction
585 * descriptions.
587 static LLVMTypeRef
588 regtype_to_llvm_type (char c)
590 switch (c) {
591 case 'i':
592 return LLVMInt32Type ();
593 case 'l':
594 return LLVMInt64Type ();
595 case 'f':
596 return LLVMDoubleType ();
597 default:
598 return NULL;
603 * op_to_llvm_type:
605 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
607 static LLVMTypeRef
608 op_to_llvm_type (int opcode)
610 switch (opcode) {
611 case OP_ICONV_TO_I1:
612 case OP_LCONV_TO_I1:
613 return LLVMInt8Type ();
614 case OP_ICONV_TO_U1:
615 case OP_LCONV_TO_U1:
616 return LLVMInt8Type ();
617 case OP_ICONV_TO_I2:
618 case OP_LCONV_TO_I2:
619 return LLVMInt16Type ();
620 case OP_ICONV_TO_U2:
621 case OP_LCONV_TO_U2:
622 return LLVMInt16Type ();
623 case OP_ICONV_TO_I4:
624 case OP_LCONV_TO_I4:
625 return LLVMInt32Type ();
626 case OP_ICONV_TO_U4:
627 case OP_LCONV_TO_U4:
628 return LLVMInt32Type ();
629 case OP_ICONV_TO_I8:
630 return LLVMInt64Type ();
631 case OP_ICONV_TO_R4:
632 return LLVMFloatType ();
633 case OP_ICONV_TO_R8:
634 return LLVMDoubleType ();
635 case OP_ICONV_TO_U8:
636 return LLVMInt64Type ();
637 case OP_FCONV_TO_I4:
638 return LLVMInt32Type ();
639 case OP_FCONV_TO_I8:
640 return LLVMInt64Type ();
641 case OP_FCONV_TO_I1:
642 case OP_FCONV_TO_U1:
643 case OP_RCONV_TO_I1:
644 case OP_RCONV_TO_U1:
645 return LLVMInt8Type ();
646 case OP_FCONV_TO_I2:
647 case OP_FCONV_TO_U2:
648 case OP_RCONV_TO_I2:
649 case OP_RCONV_TO_U2:
650 return LLVMInt16Type ();
651 case OP_RCONV_TO_U4:
652 return LLVMInt32Type ();
653 case OP_FCONV_TO_I:
654 case OP_FCONV_TO_U:
655 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
656 case OP_IADD_OVF:
657 case OP_IADD_OVF_UN:
658 case OP_ISUB_OVF:
659 case OP_ISUB_OVF_UN:
660 case OP_IMUL_OVF:
661 case OP_IMUL_OVF_UN:
662 return LLVMInt32Type ();
663 case OP_LADD_OVF:
664 case OP_LADD_OVF_UN:
665 case OP_LSUB_OVF:
666 case OP_LSUB_OVF_UN:
667 case OP_LMUL_OVF:
668 case OP_LMUL_OVF_UN:
669 return LLVMInt64Type ();
670 default:
671 printf ("%s\n", mono_inst_name (opcode));
672 g_assert_not_reached ();
673 return NULL;
677 #define CLAUSE_START(clause) ((clause)->try_offset)
678 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
681 * load_store_to_llvm_type:
683 * Return the size/sign/zero extension corresponding to the load/store opcode
684 * OPCODE.
686 static LLVMTypeRef
687 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
689 *sext = FALSE;
690 *zext = FALSE;
692 switch (opcode) {
693 case OP_LOADI1_MEMBASE:
694 case OP_STOREI1_MEMBASE_REG:
695 case OP_STOREI1_MEMBASE_IMM:
696 case OP_ATOMIC_LOAD_I1:
697 case OP_ATOMIC_STORE_I1:
698 *size = 1;
699 *sext = TRUE;
700 return LLVMInt8Type ();
701 case OP_LOADU1_MEMBASE:
702 case OP_LOADU1_MEM:
703 case OP_ATOMIC_LOAD_U1:
704 case OP_ATOMIC_STORE_U1:
705 *size = 1;
706 *zext = TRUE;
707 return LLVMInt8Type ();
708 case OP_LOADI2_MEMBASE:
709 case OP_STOREI2_MEMBASE_REG:
710 case OP_STOREI2_MEMBASE_IMM:
711 case OP_ATOMIC_LOAD_I2:
712 case OP_ATOMIC_STORE_I2:
713 *size = 2;
714 *sext = TRUE;
715 return LLVMInt16Type ();
716 case OP_LOADU2_MEMBASE:
717 case OP_LOADU2_MEM:
718 case OP_ATOMIC_LOAD_U2:
719 case OP_ATOMIC_STORE_U2:
720 *size = 2;
721 *zext = TRUE;
722 return LLVMInt16Type ();
723 case OP_LOADI4_MEMBASE:
724 case OP_LOADU4_MEMBASE:
725 case OP_LOADI4_MEM:
726 case OP_LOADU4_MEM:
727 case OP_STOREI4_MEMBASE_REG:
728 case OP_STOREI4_MEMBASE_IMM:
729 case OP_ATOMIC_LOAD_I4:
730 case OP_ATOMIC_STORE_I4:
731 case OP_ATOMIC_LOAD_U4:
732 case OP_ATOMIC_STORE_U4:
733 *size = 4;
734 return LLVMInt32Type ();
735 case OP_LOADI8_MEMBASE:
736 case OP_LOADI8_MEM:
737 case OP_STOREI8_MEMBASE_REG:
738 case OP_STOREI8_MEMBASE_IMM:
739 case OP_ATOMIC_LOAD_I8:
740 case OP_ATOMIC_STORE_I8:
741 case OP_ATOMIC_LOAD_U8:
742 case OP_ATOMIC_STORE_U8:
743 *size = 8;
744 return LLVMInt64Type ();
745 case OP_LOADR4_MEMBASE:
746 case OP_STORER4_MEMBASE_REG:
747 case OP_ATOMIC_LOAD_R4:
748 case OP_ATOMIC_STORE_R4:
749 *size = 4;
750 return LLVMFloatType ();
751 case OP_LOADR8_MEMBASE:
752 case OP_STORER8_MEMBASE_REG:
753 case OP_ATOMIC_LOAD_R8:
754 case OP_ATOMIC_STORE_R8:
755 *size = 8;
756 return LLVMDoubleType ();
757 case OP_LOAD_MEMBASE:
758 case OP_LOAD_MEM:
759 case OP_STORE_MEMBASE_REG:
760 case OP_STORE_MEMBASE_IMM:
761 *size = sizeof (gpointer);
762 return IntPtrType ();
763 default:
764 g_assert_not_reached ();
765 return NULL;
770 * ovf_op_to_intrins:
772 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
774 static const char*
775 ovf_op_to_intrins (int opcode)
777 switch (opcode) {
778 case OP_IADD_OVF:
779 return "llvm.sadd.with.overflow.i32";
780 case OP_IADD_OVF_UN:
781 return "llvm.uadd.with.overflow.i32";
782 case OP_ISUB_OVF:
783 return "llvm.ssub.with.overflow.i32";
784 case OP_ISUB_OVF_UN:
785 return "llvm.usub.with.overflow.i32";
786 case OP_IMUL_OVF:
787 return "llvm.smul.with.overflow.i32";
788 case OP_IMUL_OVF_UN:
789 return "llvm.umul.with.overflow.i32";
790 case OP_LADD_OVF:
791 return "llvm.sadd.with.overflow.i64";
792 case OP_LADD_OVF_UN:
793 return "llvm.uadd.with.overflow.i64";
794 case OP_LSUB_OVF:
795 return "llvm.ssub.with.overflow.i64";
796 case OP_LSUB_OVF_UN:
797 return "llvm.usub.with.overflow.i64";
798 case OP_LMUL_OVF:
799 return "llvm.smul.with.overflow.i64";
800 case OP_LMUL_OVF_UN:
801 return "llvm.umul.with.overflow.i64";
802 default:
803 g_assert_not_reached ();
804 return NULL;
808 static const char*
809 simd_op_to_intrins (int opcode)
811 switch (opcode) {
812 #if defined(TARGET_X86) || defined(TARGET_AMD64)
813 case OP_MINPD:
814 return "llvm.x86.sse2.min.pd";
815 case OP_MINPS:
816 return "llvm.x86.sse.min.ps";
817 case OP_MAXPD:
818 return "llvm.x86.sse2.max.pd";
819 case OP_MAXPS:
820 return "llvm.x86.sse.max.ps";
821 case OP_HADDPD:
822 return "llvm.x86.sse3.hadd.pd";
823 case OP_HADDPS:
824 return "llvm.x86.sse3.hadd.ps";
825 case OP_HSUBPD:
826 return "llvm.x86.sse3.hsub.pd";
827 case OP_HSUBPS:
828 return "llvm.x86.sse3.hsub.ps";
829 case OP_ADDSUBPS:
830 return "llvm.x86.sse3.addsub.ps";
831 case OP_ADDSUBPD:
832 return "llvm.x86.sse3.addsub.pd";
833 case OP_EXTRACT_MASK:
834 return "llvm.x86.sse2.pmovmskb.128";
835 case OP_PSHRW:
836 case OP_PSHRW_REG:
837 return "llvm.x86.sse2.psrli.w";
838 case OP_PSHRD:
839 case OP_PSHRD_REG:
840 return "llvm.x86.sse2.psrli.d";
841 case OP_PSHRQ:
842 case OP_PSHRQ_REG:
843 return "llvm.x86.sse2.psrli.q";
844 case OP_PSHLW:
845 case OP_PSHLW_REG:
846 return "llvm.x86.sse2.pslli.w";
847 case OP_PSHLD:
848 case OP_PSHLD_REG:
849 return "llvm.x86.sse2.pslli.d";
850 case OP_PSHLQ:
851 case OP_PSHLQ_REG:
852 return "llvm.x86.sse2.pslli.q";
853 case OP_PSARW:
854 case OP_PSARW_REG:
855 return "llvm.x86.sse2.psrai.w";
856 case OP_PSARD:
857 case OP_PSARD_REG:
858 return "llvm.x86.sse2.psrai.d";
859 case OP_PADDB_SAT:
860 return "llvm.x86.sse2.padds.b";
861 case OP_PADDW_SAT:
862 return "llvm.x86.sse2.padds.w";
863 case OP_PSUBB_SAT:
864 return "llvm.x86.sse2.psubs.b";
865 case OP_PSUBW_SAT:
866 return "llvm.x86.sse2.psubs.w";
867 case OP_PADDB_SAT_UN:
868 return "llvm.x86.sse2.paddus.b";
869 case OP_PADDW_SAT_UN:
870 return "llvm.x86.sse2.paddus.w";
871 case OP_PSUBB_SAT_UN:
872 return "llvm.x86.sse2.psubus.b";
873 case OP_PSUBW_SAT_UN:
874 return "llvm.x86.sse2.psubus.w";
875 case OP_PAVGB_UN:
876 return "llvm.x86.sse2.pavg.b";
877 case OP_PAVGW_UN:
878 return "llvm.x86.sse2.pavg.w";
879 case OP_SQRTPS:
880 return "llvm.x86.sse.sqrt.ps";
881 case OP_SQRTPD:
882 return "llvm.x86.sse2.sqrt.pd";
883 case OP_RSQRTPS:
884 return "llvm.x86.sse.rsqrt.ps";
885 case OP_RCPPS:
886 return "llvm.x86.sse.rcp.ps";
887 case OP_CVTDQ2PD:
888 return "llvm.x86.sse2.cvtdq2pd";
889 case OP_CVTDQ2PS:
890 return "llvm.x86.sse2.cvtdq2ps";
891 case OP_CVTPD2DQ:
892 return "llvm.x86.sse2.cvtpd2dq";
893 case OP_CVTPS2DQ:
894 return "llvm.x86.sse2.cvtps2dq";
895 case OP_CVTPD2PS:
896 return "llvm.x86.sse2.cvtpd2ps";
897 case OP_CVTPS2PD:
898 return "llvm.x86.sse2.cvtps2pd";
899 case OP_CVTTPD2DQ:
900 return "llvm.x86.sse2.cvttpd2dq";
901 case OP_CVTTPS2DQ:
902 return "llvm.x86.sse2.cvttps2dq";
903 case OP_PACKW:
904 return "llvm.x86.sse2.packsswb.128";
905 case OP_PACKD:
906 return "llvm.x86.sse2.packssdw.128";
907 case OP_PACKW_UN:
908 return "llvm.x86.sse2.packuswb.128";
909 case OP_PACKD_UN:
910 return "llvm.x86.sse41.packusdw";
911 case OP_PMULW_HIGH:
912 return "llvm.x86.sse2.pmulh.w";
913 case OP_PMULW_HIGH_UN:
914 return "llvm.x86.sse2.pmulhu.w";
915 #endif
916 default:
917 g_assert_not_reached ();
918 return NULL;
922 static LLVMTypeRef
923 simd_op_to_llvm_type (int opcode)
925 #if defined(TARGET_X86) || defined(TARGET_AMD64)
926 switch (opcode) {
927 case OP_EXTRACT_R8:
928 case OP_EXPAND_R8:
929 return type_to_simd_type (MONO_TYPE_R8);
930 case OP_EXTRACT_I8:
931 case OP_EXPAND_I8:
932 return type_to_simd_type (MONO_TYPE_I8);
933 case OP_EXTRACT_I4:
934 case OP_EXPAND_I4:
935 return type_to_simd_type (MONO_TYPE_I4);
936 case OP_EXTRACT_I2:
937 case OP_EXTRACT_U2:
938 case OP_EXTRACTX_U2:
939 case OP_EXPAND_I2:
940 return type_to_simd_type (MONO_TYPE_I2);
941 case OP_EXTRACT_I1:
942 case OP_EXTRACT_U1:
943 case OP_EXPAND_I1:
944 return type_to_simd_type (MONO_TYPE_I1);
945 case OP_EXPAND_R4:
946 return type_to_simd_type (MONO_TYPE_R4);
947 case OP_CVTDQ2PD:
948 case OP_CVTDQ2PS:
949 return type_to_simd_type (MONO_TYPE_I4);
950 case OP_CVTPD2DQ:
951 case OP_CVTPD2PS:
952 case OP_CVTTPD2DQ:
953 return type_to_simd_type (MONO_TYPE_R8);
954 case OP_CVTPS2DQ:
955 case OP_CVTPS2PD:
956 case OP_CVTTPS2DQ:
957 return type_to_simd_type (MONO_TYPE_R4);
958 case OP_EXTRACT_MASK:
959 return type_to_simd_type (MONO_TYPE_I1);
960 case OP_SQRTPS:
961 case OP_RSQRTPS:
962 case OP_RCPPS:
963 case OP_DUPPS_LOW:
964 case OP_DUPPS_HIGH:
965 return type_to_simd_type (MONO_TYPE_R4);
966 case OP_SQRTPD:
967 case OP_DUPPD:
968 return type_to_simd_type (MONO_TYPE_R8);
969 default:
970 g_assert_not_reached ();
971 return NULL;
973 #else
974 return NULL;
975 #endif
979 * get_bb:
981 * Return the LLVM basic block corresponding to BB.
983 static LLVMBasicBlockRef
984 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
986 char bb_name_buf [128];
987 char *bb_name;
989 if (ctx->bblocks [bb->block_num].bblock == NULL) {
990 if (bb->flags & BB_EXCEPTION_HANDLER) {
991 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
992 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
993 bb_name = bb_name_buf;
994 } else if (bb->block_num < 256) {
995 if (!ctx->module->bb_names) {
996 ctx->module->bb_names_len = 256;
997 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
999 if (!ctx->module->bb_names [bb->block_num]) {
1000 char *n;
1002 n = g_strdup_printf ("BB%d", bb->block_num);
1003 mono_memory_barrier ();
1004 ctx->module->bb_names [bb->block_num] = n;
1006 bb_name = ctx->module->bb_names [bb->block_num];
1007 } else {
1008 sprintf (bb_name_buf, "BB%d", bb->block_num);
1009 bb_name = bb_name_buf;
1012 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1013 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1016 return ctx->bblocks [bb->block_num].bblock;
1020 * get_end_bb:
1022 * Return the last LLVM bblock corresponding to BB.
1023 * This might not be equal to the bb returned by get_bb () since we need to generate
1024 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1026 static LLVMBasicBlockRef
1027 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1029 get_bb (ctx, bb);
1030 return ctx->bblocks [bb->block_num].end_bblock;
1033 static LLVMBasicBlockRef
1034 gen_bb (EmitContext *ctx, const char *prefix)
1036 char bb_name [128];
1038 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1039 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1043 * resolve_patch:
1045 * Return the target of the patch identified by TYPE and TARGET.
1047 static gpointer
1048 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1050 MonoJumpInfo ji;
1051 MonoError error;
1052 gpointer res;
1054 memset (&ji, 0, sizeof (ji));
1055 ji.type = type;
1056 ji.data.target = target;
1058 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1059 mono_error_assert_ok (&error);
1061 return res;
1065 * convert_full:
1067 * Emit code to convert the LLVM value V to DTYPE.
1069 static LLVMValueRef
1070 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1072 LLVMTypeRef stype = LLVMTypeOf (v);
1074 if (stype != dtype) {
1075 gboolean ext = FALSE;
1077 /* Extend */
1078 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1079 ext = TRUE;
1080 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 ext = TRUE;
1082 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1083 ext = TRUE;
1085 if (ext)
1086 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1088 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1089 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1091 /* Trunc */
1092 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1093 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1094 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1095 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1096 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1097 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1098 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1099 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1101 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1102 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1103 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1104 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1105 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1106 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1108 if (mono_arch_is_soft_float ()) {
1109 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1110 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1112 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1115 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1116 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 LLVMDumpValue (v);
1119 LLVMDumpValue (LLVMConstNull (dtype));
1120 g_assert_not_reached ();
1121 return NULL;
1122 } else {
1123 return v;
1127 static LLVMValueRef
1128 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1130 return convert_full (ctx, v, dtype, FALSE);
1134 * emit_volatile_load:
1136 * If vreg is volatile, emit a load from its address.
1138 static LLVMValueRef
1139 emit_volatile_load (EmitContext *ctx, int vreg)
1141 MonoType *t;
1142 LLVMValueRef v;
1144 #ifdef TARGET_ARM64
1145 // FIXME: This hack is required because we pass the rgctx in a callee saved
1146 // register on arm64 (x15), and llvm might keep the value in that register
1147 // even through the register is marked as 'reserved' inside llvm.
1148 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1149 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1150 else
1151 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1152 #else
1153 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1154 #endif
1155 t = ctx->vreg_cli_types [vreg];
1156 if (t && !t->byref) {
1158 * Might have to zero extend since llvm doesn't have
1159 * unsigned types.
1161 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1162 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1163 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1164 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1165 else if (t->type == MONO_TYPE_U8)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1169 return v;
1173 * emit_volatile_store:
1175 * If VREG is volatile, emit a store from its value to its address.
1177 static void
1178 emit_volatile_store (EmitContext *ctx, int vreg)
1180 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1182 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1183 g_assert (ctx->addresses [vreg]);
1184 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1188 static LLVMTypeRef
1189 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1191 LLVMTypeRef ret_type;
1192 LLVMTypeRef *param_types = NULL;
1193 LLVMTypeRef res;
1194 int i, pindex;
1195 MonoType *rtype;
1197 rtype = mini_get_underlying_type (sig->ret);
1198 ret_type = type_to_llvm_type (ctx, rtype);
1199 if (!ctx_ok (ctx))
1200 return NULL;
1202 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1203 pindex = 0;
1205 if (sig->hasthis)
1206 param_types [pindex ++] = ThisType ();
1207 for (i = 0; i < sig->param_count; ++i)
1208 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1210 if (!ctx_ok (ctx)) {
1211 g_free (param_types);
1212 return NULL;
1215 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1216 g_free (param_types);
1218 return res;
1222 * sig_to_llvm_sig_full:
1224 * Return the LLVM signature corresponding to the mono signature SIG using the
1225 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1227 static LLVMTypeRef
1228 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1230 LLVMTypeRef ret_type;
1231 LLVMTypeRef *param_types = NULL;
1232 LLVMTypeRef res;
1233 int i, j, pindex, vret_arg_pindex = 0;
1234 gboolean vretaddr = FALSE;
1235 MonoType *rtype;
1237 if (!cinfo)
1238 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1240 rtype = mini_get_underlying_type (sig->ret);
1241 ret_type = type_to_llvm_type (ctx, rtype);
1242 if (!ctx_ok (ctx))
1243 return NULL;
1245 switch (cinfo->ret.storage) {
1246 case LLVMArgVtypeInReg:
1247 /* LLVM models this by returning an aggregate value */
1248 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1249 LLVMTypeRef members [2];
1251 members [0] = IntPtrType ();
1252 ret_type = LLVMStructType (members, 1, FALSE);
1253 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1254 /* Empty struct */
1255 ret_type = LLVMVoidType ();
1256 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1257 LLVMTypeRef members [2];
1259 members [0] = IntPtrType ();
1260 members [1] = IntPtrType ();
1261 ret_type = LLVMStructType (members, 2, FALSE);
1262 } else {
1263 g_assert_not_reached ();
1265 break;
1266 case LLVMArgVtypeByVal:
1267 /* Vtype returned normally by val */
1268 break;
1269 case LLVMArgVtypeAsScalar: {
1270 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1271 /* LLVM models this by returning an int */
1272 if (size < SIZEOF_VOID_P) {
1273 g_assert (cinfo->ret.nslots == 1);
1274 ret_type = LLVMIntType (size * 8);
1275 } else {
1276 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1277 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1279 break;
1281 case LLVMArgAsIArgs:
1282 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1283 break;
1284 case LLVMArgFpStruct: {
1285 /* Vtype returned as a fp struct */
1286 LLVMTypeRef members [16];
1288 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1289 for (i = 0; i < cinfo->ret.nslots; ++i)
1290 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1291 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1292 break;
1294 case LLVMArgVtypeByRef:
1295 /* Vtype returned using a hidden argument */
1296 ret_type = LLVMVoidType ();
1297 break;
1298 case LLVMArgVtypeRetAddr:
1299 case LLVMArgGsharedvtFixed:
1300 case LLVMArgGsharedvtFixedVtype:
1301 case LLVMArgGsharedvtVariable:
1302 vretaddr = TRUE;
1303 ret_type = LLVMVoidType ();
1304 break;
1305 default:
1306 break;
1309 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1310 pindex = 0;
1311 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1313 * Has to be the first argument because of the sret argument attribute
1314 * FIXME: This might conflict with passing 'this' as the first argument, but
1315 * this is only used on arm64 which has a dedicated struct return register.
1317 cinfo->vret_arg_pindex = pindex;
1318 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1319 if (!ctx_ok (ctx)) {
1320 g_free (param_types);
1321 return NULL;
1323 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1324 pindex ++;
1326 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1327 cinfo->rgctx_arg_pindex = pindex;
1328 param_types [pindex] = ctx->module->ptr_type;
1329 pindex ++;
1331 if (cinfo->imt_arg) {
1332 cinfo->imt_arg_pindex = pindex;
1333 param_types [pindex] = ctx->module->ptr_type;
1334 pindex ++;
1336 if (vretaddr) {
1337 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1338 vret_arg_pindex = pindex;
1339 if (cinfo->vret_arg_index == 1) {
1340 /* Add the slots consumed by the first argument */
1341 LLVMArgInfo *ainfo = &cinfo->args [0];
1342 switch (ainfo->storage) {
1343 case LLVMArgVtypeInReg:
1344 for (j = 0; j < 2; ++j) {
1345 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1346 vret_arg_pindex ++;
1348 break;
1349 default:
1350 vret_arg_pindex ++;
1354 cinfo->vret_arg_pindex = vret_arg_pindex;
1357 if (vretaddr && vret_arg_pindex == pindex)
1358 param_types [pindex ++] = IntPtrType ();
1359 if (sig->hasthis) {
1360 cinfo->this_arg_pindex = pindex;
1361 param_types [pindex ++] = ThisType ();
1362 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1364 if (vretaddr && vret_arg_pindex == pindex)
1365 param_types [pindex ++] = IntPtrType ();
1366 for (i = 0; i < sig->param_count; ++i) {
1367 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1369 if (vretaddr && vret_arg_pindex == pindex)
1370 param_types [pindex ++] = IntPtrType ();
1371 ainfo->pindex = pindex;
1373 switch (ainfo->storage) {
1374 case LLVMArgVtypeInReg:
1375 for (j = 0; j < 2; ++j) {
1376 switch (ainfo->pair_storage [j]) {
1377 case LLVMArgInIReg:
1378 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1379 break;
1380 case LLVMArgNone:
1381 break;
1382 default:
1383 g_assert_not_reached ();
1386 break;
1387 case LLVMArgVtypeByVal:
1388 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1389 if (!ctx_ok (ctx))
1390 break;
1391 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1392 pindex ++;
1393 break;
1394 case LLVMArgAsIArgs:
1395 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1396 pindex ++;
1397 break;
1398 case LLVMArgVtypeByRef:
1399 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1400 if (!ctx_ok (ctx))
1401 break;
1402 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1403 pindex ++;
1404 break;
1405 case LLVMArgAsFpArgs: {
1406 int j;
1408 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1409 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1410 param_types [pindex ++] = LLVMDoubleType ();
1411 for (j = 0; j < ainfo->nslots; ++j)
1412 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1413 break;
1415 case LLVMArgVtypeAsScalar:
1416 g_assert_not_reached ();
1417 break;
1418 case LLVMArgGsharedvtFixed:
1419 case LLVMArgGsharedvtFixedVtype:
1420 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1421 break;
1422 case LLVMArgGsharedvtVariable:
1423 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1424 break;
1425 default:
1426 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 break;
1430 if (!ctx_ok (ctx)) {
1431 g_free (param_types);
1432 return NULL;
1434 if (vretaddr && vret_arg_pindex == pindex)
1435 param_types [pindex ++] = IntPtrType ();
1436 if (ctx->llvm_only && cinfo->rgctx_arg) {
1437 /* Pass the rgctx as the last argument */
1438 cinfo->rgctx_arg_pindex = pindex;
1439 param_types [pindex] = ctx->module->ptr_type;
1440 pindex ++;
1443 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1444 g_free (param_types);
1446 return res;
1449 static LLVMTypeRef
1450 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1452 return sig_to_llvm_sig_full (ctx, sig, NULL);
1456 * LLVMFunctionType1:
1458 * Create an LLVM function type from the arguments.
1460 static G_GNUC_UNUSED LLVMTypeRef
1461 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1462 int IsVarArg)
1464 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1468 * LLVMFunctionType1:
1470 * Create an LLVM function type from the arguments.
1472 static G_GNUC_UNUSED LLVMTypeRef
1473 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1474 LLVMTypeRef ParamType1,
1475 int IsVarArg)
1477 LLVMTypeRef param_types [1];
1479 param_types [0] = ParamType1;
1481 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1485 * LLVMFunctionType2:
1487 * Create an LLVM function type from the arguments.
1489 static G_GNUC_UNUSED LLVMTypeRef
1490 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1491 LLVMTypeRef ParamType1,
1492 LLVMTypeRef ParamType2,
1493 int IsVarArg)
1495 LLVMTypeRef param_types [2];
1497 param_types [0] = ParamType1;
1498 param_types [1] = ParamType2;
1500 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1504 * LLVMFunctionType3:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1511 LLVMTypeRef ParamType2,
1512 LLVMTypeRef ParamType3,
1513 int IsVarArg)
1515 LLVMTypeRef param_types [3];
1517 param_types [0] = ParamType1;
1518 param_types [1] = ParamType2;
1519 param_types [2] = ParamType3;
1521 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1528 LLVMTypeRef ParamType3,
1529 LLVMTypeRef ParamType4,
1530 LLVMTypeRef ParamType5,
1531 int IsVarArg)
1533 LLVMTypeRef param_types [5];
1535 param_types [0] = ParamType1;
1536 param_types [1] = ParamType2;
1537 param_types [2] = ParamType3;
1538 param_types [3] = ParamType4;
1539 param_types [4] = ParamType5;
1541 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1545 * create_builder:
1547 * Create an LLVM builder and remember it so it can be freed later.
1549 static LLVMBuilderRef
1550 create_builder (EmitContext *ctx)
1552 LLVMBuilderRef builder = LLVMCreateBuilder ();
1554 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1556 return builder;
1559 static char*
1560 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1562 char *name;
1564 switch (type) {
1565 case MONO_PATCH_INFO_INTERNAL_METHOD:
1566 name = g_strdup_printf ("jit_icall_%s", data);
1567 break;
1568 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1569 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1570 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1571 break;
1573 default:
1574 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1575 break;
1578 return name;
1581 static LLVMValueRef
1582 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1584 MonoCompile *cfg;
1585 guint32 got_offset;
1586 LLVMValueRef indexes [2];
1587 LLVMValueRef got_entry_addr, load;
1588 LLVMBuilderRef builder = ctx->builder;
1589 char *name = NULL;
1591 cfg = ctx->cfg;
1593 MonoJumpInfo tmp_ji;
1594 tmp_ji.type = type;
1595 tmp_ji.data.target = data;
1597 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1599 ji->next = cfg->patch_info;
1600 cfg->patch_info = ji;
1602 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1603 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1605 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1606 * explicitly initialize it.
1608 if (!mono_aot_is_shared_got_offset (got_offset)) {
1609 //mono_print_ji (ji);
1610 //printf ("\n");
1611 ctx->has_got_access = TRUE;
1614 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1615 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1616 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1618 name = get_aotconst_name (type, data, got_offset);
1619 if (llvm_type) {
1620 load = LLVMBuildLoad (builder, got_entry_addr, "");
1621 load = convert (ctx, load, llvm_type);
1622 LLVMSetValueName (load, name ? name : "");
1623 } else {
1624 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1626 g_free (name);
1627 //set_invariant_load_flag (load);
1629 return load;
1632 static LLVMValueRef
1633 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1635 return get_aotconst_typed (ctx, type, data, NULL);
1638 static LLVMValueRef
1639 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1641 LLVMValueRef callee;
1642 char *callee_name;
1643 if (ctx->llvm_only) {
1644 callee_name = mono_aot_get_direct_call_symbol (type, data);
1645 if (callee_name) {
1646 /* Directly callable */
1647 // FIXME: Locking
1648 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1649 if (!callee) {
1650 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1652 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1654 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1655 } else {
1656 /* LLVMTypeRef's are uniqued */
1657 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1658 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1660 g_free (callee_name);
1662 return callee;
1666 * Calls are made through the GOT.
1668 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1669 } else {
1670 MonoJumpInfo *ji = NULL;
1672 callee_name = mono_aot_get_plt_symbol (type, data);
1673 if (!callee_name)
1674 return NULL;
1676 if (ctx->cfg->compile_aot)
1677 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1678 mono_add_patch_info (ctx->cfg, 0, type, data);
1680 // FIXME: Locking
1681 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1682 if (!callee) {
1683 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1685 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1687 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1690 if (ctx->cfg->compile_aot) {
1691 ji = g_new0 (MonoJumpInfo, 1);
1692 ji->type = type;
1693 ji->data.target = data;
1695 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1698 return callee;
1702 static LLVMValueRef
1703 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1705 #if LLVM_API_VERSION > 100
1706 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1707 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1708 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1709 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1710 return callee;
1711 #else
1712 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1713 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1714 return callee;
1715 #endif
1718 static int
1719 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1721 MonoMethodHeader *header = cfg->header;
1722 MonoExceptionClause *clause;
1723 int i;
1725 /* Directly */
1726 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1727 return (bb->region >> 8) - 1;
1729 /* Indirectly */
1730 for (i = 0; i < header->num_clauses; ++i) {
1731 clause = &header->clauses [i];
1733 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1734 return i;
1737 return -1;
1740 static MonoExceptionClause *
1741 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1743 if (bb == cfg->bb_init)
1744 return NULL;
1745 // Since they're sorted by nesting we just need
1746 // the first one that the bb is a member of
1747 for (int i = 0; i < cfg->header->num_clauses; i++) {
1748 MonoExceptionClause *curr = &cfg->header->clauses [i];
1750 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1751 return curr;
1754 return NULL;
1757 static void
1758 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1760 LLVMValueRef md_arg;
1761 int md_kind;
1763 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1764 md_arg = LLVMMDString ("mono", 4);
1765 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1768 static void
1769 set_invariant_load_flag (LLVMValueRef v)
1771 LLVMValueRef md_arg;
1772 int md_kind;
1773 const char *flag_name;
1775 // FIXME: Cache this
1776 flag_name = "invariant.load";
1777 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1778 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1779 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1783 * emit_call:
1785 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1786 * a try region.
1788 static LLVMValueRef
1789 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1791 MonoCompile *cfg = ctx->cfg;
1792 LLVMValueRef lcall = NULL;
1793 LLVMBuilderRef builder = *builder_ref;
1794 MonoExceptionClause *clause;
1796 if (ctx->llvm_only) {
1797 clause = get_most_deep_clause (cfg, ctx, bb);
1799 if (clause) {
1800 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1806 intptr_t key = CLAUSE_END(clause);
1808 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1810 // FIXME: Find the one that has the lowest end bound for the right start address
1811 // FIXME: Finally + nesting
1813 if (lpad_bb) {
1814 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1816 /* Use an invoke */
1817 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1819 builder = ctx->builder = create_builder (ctx);
1820 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1822 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1825 } else {
1826 int clause_index = get_handler_clause (cfg, bb);
1828 if (clause_index != -1) {
1829 MonoMethodHeader *header = cfg->header;
1830 MonoExceptionClause *ec = &header->clauses [clause_index];
1831 MonoBasicBlock *tblock;
1832 LLVMBasicBlockRef ex_bb, noex_bb;
1835 * Have to use an invoke instead of a call, branching to the
1836 * handler bblock of the clause containing this bblock.
1839 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1841 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1842 g_assert (tblock);
1844 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1846 ex_bb = get_bb (ctx, tblock);
1848 noex_bb = gen_bb (ctx, "NOEX_BB");
1850 /* Use an invoke */
1851 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1853 builder = ctx->builder = create_builder (ctx);
1854 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1856 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1860 if (!lcall) {
1861 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1862 ctx->builder = builder;
1865 if (builder_ref)
1866 *builder_ref = ctx->builder;
1868 return lcall;
1871 static LLVMValueRef
1872 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1874 const char *intrins_name;
1875 LLVMValueRef args [16], res;
1876 LLVMTypeRef addr_type;
1877 gboolean use_intrinsics = TRUE;
1879 #if LLVM_API_VERSION > 100
1880 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1881 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1882 LLVMValueRef cmp;
1884 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1885 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1886 *builder_ref = ctx->builder;
1887 use_intrinsics = FALSE;
1889 #endif
1891 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1892 LLVMAtomicOrdering ordering;
1894 switch (barrier) {
1895 case LLVM_BARRIER_NONE:
1896 ordering = LLVMAtomicOrderingNotAtomic;
1897 break;
1898 case LLVM_BARRIER_ACQ:
1899 ordering = LLVMAtomicOrderingAcquire;
1900 break;
1901 case LLVM_BARRIER_SEQ:
1902 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1903 break;
1904 default:
1905 g_assert_not_reached ();
1906 break;
1910 * We handle loads which can fault by calling a mono specific intrinsic
1911 * using an invoke, so they are handled properly inside try blocks.
1912 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1913 * are marked with IntrReadArgMem.
1915 switch (size) {
1916 case 1:
1917 intrins_name = "llvm.mono.load.i8.p0i8";
1918 break;
1919 case 2:
1920 intrins_name = "llvm.mono.load.i16.p0i16";
1921 break;
1922 case 4:
1923 intrins_name = "llvm.mono.load.i32.p0i32";
1924 break;
1925 case 8:
1926 intrins_name = "llvm.mono.load.i64.p0i64";
1927 break;
1928 default:
1929 g_assert_not_reached ();
1932 addr_type = LLVMTypeOf (addr);
1933 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1934 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1936 args [0] = addr;
1937 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1938 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1939 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1940 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1942 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1943 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1944 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1945 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1947 return res;
1948 } else {
1949 LLVMValueRef res;
1952 * We emit volatile loads for loads which can fault, because otherwise
1953 * LLVM will generate invalid code when encountering a load from a
1954 * NULL address.
1956 if (barrier != LLVM_BARRIER_NONE)
1957 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1958 else
1959 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1961 /* Mark it with a custom metadata */
1963 if (is_faulting)
1964 set_metadata_flag (res, "mono.faulting.load");
1967 return res;
1971 static LLVMValueRef
1972 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1974 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1977 static void
1978 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1980 const char *intrins_name;
1981 LLVMValueRef args [16];
1982 gboolean use_intrinsics = TRUE;
1984 #if LLVM_API_VERSION > 100
1985 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1986 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1987 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1988 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1989 *builder_ref = ctx->builder;
1990 use_intrinsics = FALSE;
1992 #endif
1994 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1995 LLVMAtomicOrdering ordering;
1997 switch (barrier) {
1998 case LLVM_BARRIER_NONE:
1999 ordering = LLVMAtomicOrderingNotAtomic;
2000 break;
2001 case LLVM_BARRIER_REL:
2002 ordering = LLVMAtomicOrderingRelease;
2003 break;
2004 case LLVM_BARRIER_SEQ:
2005 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2006 break;
2007 default:
2008 g_assert_not_reached ();
2009 break;
2012 switch (size) {
2013 case 1:
2014 intrins_name = "llvm.mono.store.i8.p0i8";
2015 break;
2016 case 2:
2017 intrins_name = "llvm.mono.store.i16.p0i16";
2018 break;
2019 case 4:
2020 intrins_name = "llvm.mono.store.i32.p0i32";
2021 break;
2022 case 8:
2023 intrins_name = "llvm.mono.store.i64.p0i64";
2024 break;
2025 default:
2026 g_assert_not_reached ();
2029 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2030 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2031 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2034 args [0] = value;
2035 args [1] = addr;
2036 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2037 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2038 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2039 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2040 } else {
2041 if (barrier != LLVM_BARRIER_NONE)
2042 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2043 else
2044 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2048 static void
2049 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2051 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2055 * emit_cond_system_exception:
2057 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2058 * Might set the ctx exception.
2060 static void
2061 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2063 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2064 LLVMBuilderRef builder;
2065 MonoClass *exc_class;
2066 LLVMValueRef args [2];
2067 LLVMValueRef callee;
2068 gboolean no_pc = FALSE;
2070 if (IS_TARGET_AMD64)
2071 /* Some platforms don't require the pc argument */
2072 no_pc = TRUE;
2074 ex_bb = gen_bb (ctx, "EX_BB");
2075 if (ctx->llvm_only)
2076 ex2_bb = gen_bb (ctx, "EX2_BB");
2077 noex_bb = gen_bb (ctx, "NOEX_BB");
2079 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2081 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2083 /* Emit exception throwing code */
2084 ctx->builder = builder = create_builder (ctx);
2085 LLVMPositionBuilderAtEnd (builder, ex_bb);
2087 if (ctx->cfg->llvm_only) {
2088 static LLVMTypeRef sig;
2090 if (!sig)
2091 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2092 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2094 LLVMBuildBr (builder, ex2_bb);
2096 ctx->builder = builder = create_builder (ctx);
2097 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2099 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2100 emit_call (ctx, bb, &builder, callee, args, 1);
2101 LLVMBuildUnreachable (builder);
2103 ctx->builder = builder = create_builder (ctx);
2104 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2106 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2108 ctx->ex_index ++;
2109 return;
2112 callee = ctx->module->throw_corlib_exception;
2113 if (!callee) {
2114 LLVMTypeRef sig;
2115 const char *icall_name;
2117 if (no_pc)
2118 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2119 else
2120 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2121 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2123 if (ctx->cfg->compile_aot) {
2124 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2125 } else {
2127 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2128 * - On x86, LLVM generated code doesn't push the arguments
2129 * - The trampoline takes the throw address as an arguments, not a pc offset.
2131 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2132 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2134 #if LLVM_API_VERSION > 100
2136 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2137 * added by emit_jit_callee ().
2139 ex2_bb = gen_bb (ctx, "EX2_BB");
2140 LLVMBuildBr (builder, ex2_bb);
2141 ex_bb = ex2_bb;
2143 ctx->builder = builder = create_builder (ctx);
2144 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2145 #else
2146 mono_memory_barrier ();
2147 ctx->module->throw_corlib_exception = callee;
2148 #endif
2152 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2155 * The LLVM mono branch contains changes so a block address can be passed as an
2156 * argument to a call.
2158 if (no_pc) {
2159 emit_call (ctx, bb, &builder, callee, args, 1);
2160 } else {
2161 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2162 emit_call (ctx, bb, &builder, callee, args, 2);
2165 LLVMBuildUnreachable (builder);
2167 ctx->builder = builder = create_builder (ctx);
2168 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2170 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2172 ctx->ex_index ++;
2173 return;
2177 * emit_args_to_vtype:
2179 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2181 static void
2182 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2184 int j, size, nslots;
2186 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2188 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2189 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2192 if (ainfo->storage == LLVMArgAsFpArgs)
2193 nslots = ainfo->nslots;
2194 else
2195 nslots = 2;
2197 for (j = 0; j < nslots; ++j) {
2198 LLVMValueRef index [2], addr, daddr;
2199 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2200 LLVMTypeRef part_type;
2202 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2203 part_size ++;
2205 if (ainfo->pair_storage [j] == LLVMArgNone)
2206 continue;
2208 switch (ainfo->pair_storage [j]) {
2209 case LLVMArgInIReg: {
2210 part_type = LLVMIntType (part_size * 8);
2211 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2212 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2213 addr = LLVMBuildGEP (builder, address, index, 1, "");
2214 } else {
2215 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2216 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2217 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2219 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2220 break;
2222 case LLVMArgInFPReg: {
2223 LLVMTypeRef arg_type;
2225 if (ainfo->esize == 8)
2226 arg_type = LLVMDoubleType ();
2227 else
2228 arg_type = LLVMFloatType ();
2230 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2231 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2232 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2233 LLVMBuildStore (builder, args [j], addr);
2234 break;
2236 case LLVMArgNone:
2237 break;
2238 default:
2239 g_assert_not_reached ();
2242 size -= sizeof (gpointer);
2247 * emit_vtype_to_args:
2249 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2250 * into ARGS, and the number of arguments into NARGS.
2252 static void
2253 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2255 int pindex = 0;
2256 int j, size, nslots;
2257 LLVMTypeRef arg_type;
2259 size = get_vtype_size (t);
2261 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2262 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2264 if (ainfo->storage == LLVMArgAsFpArgs)
2265 nslots = ainfo->nslots;
2266 else
2267 nslots = 2;
2268 for (j = 0; j < nslots; ++j) {
2269 LLVMValueRef index [2], addr, daddr;
2270 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2272 if (ainfo->pair_storage [j] == LLVMArgNone)
2273 continue;
2275 switch (ainfo->pair_storage [j]) {
2276 case LLVMArgInIReg:
2277 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2278 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2279 addr = LLVMBuildGEP (builder, address, index, 1, "");
2280 } else {
2281 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2282 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2283 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2285 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2286 break;
2287 case LLVMArgInFPReg:
2288 if (ainfo->esize == 8)
2289 arg_type = LLVMDoubleType ();
2290 else
2291 arg_type = LLVMFloatType ();
2292 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2293 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2294 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2295 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2296 break;
2297 case LLVMArgNone:
2298 break;
2299 default:
2300 g_assert_not_reached ();
2302 size -= sizeof (gpointer);
2305 *nargs = pindex;
2308 static LLVMValueRef
2309 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2312 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2313 * get executed every time control reaches them.
2315 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2317 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2318 return ctx->last_alloca;
2321 static LLVMValueRef
2322 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2324 return build_alloca_llvm_type_name (ctx, t, align, "");
2327 static LLVMValueRef
2328 build_alloca (EmitContext *ctx, MonoType *t)
2330 MonoClass *k = mono_class_from_mono_type (t);
2331 int align;
2333 g_assert (!mini_is_gsharedvt_variable_type (t));
2335 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2336 align = 16;
2337 else
2338 align = mono_class_min_align (k);
2340 /* Sometimes align is not a power of 2 */
2341 while (mono_is_power_of_two (align) == -1)
2342 align ++;
2344 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2347 static LLVMValueRef
2348 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2351 * gsharedvt local.
2352 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2354 MonoCompile *cfg = ctx->cfg;
2355 LLVMBuilderRef builder = ctx->builder;
2356 LLVMValueRef offset, offset_var;
2357 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2358 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2359 LLVMValueRef ptr;
2360 char *name;
2362 g_assert (info_var);
2363 g_assert (locals_var);
2365 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2367 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2368 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2370 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2371 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2373 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2377 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2379 static void
2380 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2382 if (!module->used)
2383 module->used = g_ptr_array_sized_new (16);
2384 g_ptr_array_add (module->used, global);
2387 static void
2388 emit_llvm_used (MonoLLVMModule *module)
2390 LLVMModuleRef lmodule = module->lmodule;
2391 LLVMTypeRef used_type;
2392 LLVMValueRef used, *used_elem;
2393 int i;
2395 if (!module->used)
2396 return;
2398 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2399 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2400 used_elem = g_new0 (LLVMValueRef, module->used->len);
2401 for (i = 0; i < module->used->len; ++i)
2402 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2403 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2404 LLVMSetLinkage (used, LLVMAppendingLinkage);
2405 LLVMSetSection (used, "llvm.metadata");
2409 * emit_get_method:
2411 * Emit a function mapping method indexes to their code
2413 static void
2414 emit_get_method (MonoLLVMModule *module)
2416 LLVMModuleRef lmodule = module->lmodule;
2417 LLVMValueRef func, switch_ins, m;
2418 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2419 LLVMBasicBlockRef *bbs;
2420 LLVMTypeRef rtype;
2421 LLVMBuilderRef builder = LLVMCreateBuilder ();
2422 char *name;
2423 int i;
2426 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2427 * but generating code seems safer.
2429 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2430 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2431 LLVMSetLinkage (func, LLVMExternalLinkage);
2432 LLVMSetVisibility (func, LLVMHiddenVisibility);
2433 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2434 module->get_method = func;
2436 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2439 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2440 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2441 * then we will have to find another solution.
2444 name = g_strdup_printf ("BB_CODE_START");
2445 code_start_bb = LLVMAppendBasicBlock (func, name);
2446 g_free (name);
2447 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2448 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2450 name = g_strdup_printf ("BB_CODE_END");
2451 code_end_bb = LLVMAppendBasicBlock (func, name);
2452 g_free (name);
2453 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2454 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2456 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2457 for (i = 0; i < module->max_method_idx + 1; ++i) {
2458 name = g_strdup_printf ("BB_%d", i);
2459 bb = LLVMAppendBasicBlock (func, name);
2460 g_free (name);
2461 bbs [i] = bb;
2463 LLVMPositionBuilderAtEnd (builder, bb);
2465 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2466 if (m)
2467 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2468 else
2469 LLVMBuildRet (builder, LLVMConstNull (rtype));
2472 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2473 LLVMPositionBuilderAtEnd (builder, fail_bb);
2474 LLVMBuildRet (builder, LLVMConstNull (rtype));
2476 LLVMPositionBuilderAtEnd (builder, entry_bb);
2478 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2481 for (i = 0; i < module->max_method_idx + 1; ++i) {
2482 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2485 mark_as_used (module, func);
2487 LLVMDisposeBuilder (builder);
2491 * emit_get_unbox_tramp:
2493 * Emit a function mapping method indexes to their unbox trampoline
2495 static void
2496 emit_get_unbox_tramp (MonoLLVMModule *module)
2498 LLVMModuleRef lmodule = module->lmodule;
2499 LLVMValueRef func, switch_ins, m;
2500 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2501 LLVMBasicBlockRef *bbs;
2502 LLVMTypeRef rtype;
2503 LLVMBuilderRef builder = LLVMCreateBuilder ();
2504 char *name;
2505 int i;
2507 /* Similar to emit_get_method () */
2509 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2510 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2511 LLVMSetLinkage (func, LLVMExternalLinkage);
2512 LLVMSetVisibility (func, LLVMHiddenVisibility);
2513 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2514 module->get_unbox_tramp = func;
2516 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2518 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2519 for (i = 0; i < module->max_method_idx + 1; ++i) {
2520 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2521 if (!m)
2522 continue;
2524 name = g_strdup_printf ("BB_%d", i);
2525 bb = LLVMAppendBasicBlock (func, name);
2526 g_free (name);
2527 bbs [i] = bb;
2529 LLVMPositionBuilderAtEnd (builder, bb);
2531 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2534 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2535 LLVMPositionBuilderAtEnd (builder, fail_bb);
2536 LLVMBuildRet (builder, LLVMConstNull (rtype));
2538 LLVMPositionBuilderAtEnd (builder, entry_bb);
2540 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2541 for (i = 0; i < module->max_method_idx + 1; ++i) {
2542 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2543 if (!m)
2544 continue;
2546 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2549 mark_as_used (module, func);
2550 LLVMDisposeBuilder (builder);
2553 /* Add a function to mark the beginning of LLVM code */
2554 static void
2555 emit_llvm_code_start (MonoLLVMModule *module)
2557 LLVMModuleRef lmodule = module->lmodule;
2558 LLVMValueRef func;
2559 LLVMBasicBlockRef entry_bb;
2560 LLVMBuilderRef builder;
2562 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2563 LLVMSetLinkage (func, LLVMInternalLinkage);
2564 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2565 module->code_start = func;
2566 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2567 builder = LLVMCreateBuilder ();
2568 LLVMPositionBuilderAtEnd (builder, entry_bb);
2569 LLVMBuildRetVoid (builder);
2570 LLVMDisposeBuilder (builder);
2573 static LLVMValueRef
2574 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2576 LLVMModuleRef lmodule = module->lmodule;
2577 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2578 LLVMBasicBlockRef entry_bb;
2579 LLVMBuilderRef builder;
2580 LLVMTypeRef sig;
2581 MonoJumpInfo *ji;
2582 int got_offset;
2584 switch (subtype) {
2585 case 0:
2586 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2587 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2588 break;
2589 case 1:
2590 case 3:
2591 /* mrgctx/vtable */
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2594 break;
2595 case 2:
2596 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2597 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2598 break;
2599 default:
2600 g_assert_not_reached ();
2602 LLVMSetLinkage (func, LLVMInternalLinkage);
2603 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2604 mono_llvm_set_preserveall_cc (func);
2605 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2606 builder = LLVMCreateBuilder ();
2607 LLVMPositionBuilderAtEnd (builder, entry_bb);
2609 /* get_aotconst */
2610 ji = g_new0 (MonoJumpInfo, 1);
2611 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2612 ji = mono_aot_patch_info_dup (ji);
2613 got_offset = mono_aot_get_got_offset (ji);
2614 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2616 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2617 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2618 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2619 args [1] = LLVMGetParam (func, 0);
2620 if (subtype)
2621 args [2] = LLVMGetParam (func, 1);
2623 ji = g_new0 (MonoJumpInfo, 1);
2624 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2625 ji->data.name = icall_name;
2626 ji = mono_aot_patch_info_dup (ji);
2627 got_offset = mono_aot_get_got_offset (ji);
2628 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2629 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2630 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2631 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2632 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2633 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2634 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2636 // Set the inited flag
2637 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2638 indexes [1] = LLVMGetParam (func, 0);
2639 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2641 LLVMBuildRetVoid (builder);
2643 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2644 LLVMDisposeBuilder (builder);
2645 return func;
2649 * Emit wrappers around the C icalls used to initialize llvm methods, to
2650 * make the calling code smaller and to enable usage of the llvm
2651 * PreserveAll calling convention.
2653 static void
2654 emit_init_icall_wrappers (MonoLLVMModule *module)
2656 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2657 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2658 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2659 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2662 static void
2663 emit_llvm_code_end (MonoLLVMModule *module)
2665 LLVMModuleRef lmodule = module->lmodule;
2666 LLVMValueRef func;
2667 LLVMBasicBlockRef entry_bb;
2668 LLVMBuilderRef builder;
2670 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2671 LLVMSetLinkage (func, LLVMInternalLinkage);
2672 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2673 module->code_end = func;
2674 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2675 builder = LLVMCreateBuilder ();
2676 LLVMPositionBuilderAtEnd (builder, entry_bb);
2677 LLVMBuildRetVoid (builder);
2678 LLVMDisposeBuilder (builder);
2681 static void
2682 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2684 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2686 if (bb->region)
2687 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2688 need_div_check = TRUE;
2690 if (!need_div_check)
2691 return;
2693 switch (ins->opcode) {
2694 case OP_IDIV:
2695 case OP_LDIV:
2696 case OP_IREM:
2697 case OP_LREM:
2698 case OP_IDIV_UN:
2699 case OP_LDIV_UN:
2700 case OP_IREM_UN:
2701 case OP_LREM_UN:
2702 case OP_IDIV_IMM:
2703 case OP_LDIV_IMM:
2704 case OP_IREM_IMM:
2705 case OP_LREM_IMM:
2706 case OP_IDIV_UN_IMM:
2707 case OP_LDIV_UN_IMM:
2708 case OP_IREM_UN_IMM:
2709 case OP_LREM_UN_IMM: {
2710 LLVMValueRef cmp;
2711 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2712 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2714 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2715 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2716 if (!ctx_ok (ctx))
2717 break;
2718 builder = ctx->builder;
2720 /* b == -1 && a == 0x80000000 */
2721 if (is_signed) {
2722 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2723 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2724 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2726 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2727 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2728 if (!ctx_ok (ctx))
2729 break;
2730 builder = ctx->builder;
2732 break;
2734 default:
2735 break;
2740 * emit_init_method:
2742 * Emit code to initialize the GOT slots used by the method.
2744 static void
2745 emit_init_method (EmitContext *ctx)
2747 LLVMValueRef indexes [16], args [16], callee;
2748 LLVMValueRef inited_var, cmp, call;
2749 LLVMBasicBlockRef inited_bb, notinited_bb;
2750 LLVMBuilderRef builder = ctx->builder;
2751 MonoCompile *cfg = ctx->cfg;
2753 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2755 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2756 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2757 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2759 args [0] = inited_var;
2760 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2761 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2763 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2765 inited_bb = ctx->inited_bb;
2766 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2768 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2770 builder = ctx->builder = create_builder (ctx);
2771 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2773 // FIXME: Cache
2774 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2775 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2776 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2777 callee = ctx->module->init_method_gshared_mrgctx;
2778 call = LLVMBuildCall (builder, callee, args, 2, "");
2779 } else if (ctx->rgctx_arg) {
2780 /* A vtable is passed as the rgctx argument */
2781 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2782 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2783 callee = ctx->module->init_method_gshared_vtable;
2784 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 } else if (cfg->gshared) {
2786 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2787 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2788 callee = ctx->module->init_method_gshared_this;
2789 call = LLVMBuildCall (builder, callee, args, 2, "");
2790 } else {
2791 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2792 callee = ctx->module->init_method;
2793 call = LLVMBuildCall (builder, callee, args, 1, "");
2797 * This enables llvm to keep arguments in their original registers/
2798 * scratch registers, since the call will not clobber them.
2800 mono_llvm_set_call_preserveall_cc (call);
2802 LLVMBuildBr (builder, inited_bb);
2803 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2805 builder = ctx->builder = create_builder (ctx);
2806 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2809 static void
2810 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2813 * Emit unbox trampoline using a tail call
2815 LLVMValueRef tramp, call, *args;
2816 LLVMBuilderRef builder;
2817 LLVMBasicBlockRef lbb;
2818 LLVMCallInfo *linfo;
2819 char *tramp_name;
2820 int i, nargs;
2822 tramp_name = g_strdup_printf ("ut_%s", method_name);
2823 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2824 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2825 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2826 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2827 linfo = ctx->linfo;
2828 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2829 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2830 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2831 if (ctx->cfg->vret_addr) {
2832 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2833 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2834 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2835 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2839 lbb = LLVMAppendBasicBlock (tramp, "");
2840 builder = LLVMCreateBuilder ();
2841 LLVMPositionBuilderAtEnd (builder, lbb);
2843 nargs = LLVMCountParamTypes (method_type);
2844 args = g_new0 (LLVMValueRef, nargs);
2845 for (i = 0; i < nargs; ++i) {
2846 args [i] = LLVMGetParam (tramp, i);
2847 if (i == ctx->this_arg_pindex) {
2848 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2850 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2851 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2852 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2855 call = LLVMBuildCall (builder, method, args, nargs, "");
2856 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2857 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2858 if (linfo->ret.storage == LLVMArgVtypeByRef)
2859 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2861 // FIXME: This causes assertions in clang
2862 //mono_llvm_set_must_tail (call);
2863 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2864 LLVMBuildRetVoid (builder);
2865 else
2866 LLVMBuildRet (builder, call);
2868 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2869 LLVMDisposeBuilder (builder);
2873 * emit_entry_bb:
2875 * Emit code to load/convert arguments.
2877 static void
2878 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2880 int i, j, pindex;
2881 MonoCompile *cfg = ctx->cfg;
2882 MonoMethodSignature *sig = ctx->sig;
2883 LLVMCallInfo *linfo = ctx->linfo;
2884 MonoBasicBlock *bb;
2885 char **names;
2887 LLVMBuilderRef old_builder = ctx->builder;
2888 ctx->builder = builder;
2890 ctx->alloca_builder = create_builder (ctx);
2893 * Handle indirect/volatile variables by allocating memory for them
2894 * using 'alloca', and storing their address in a temporary.
2896 for (i = 0; i < cfg->num_varinfo; ++i) {
2897 MonoInst *var = cfg->varinfo [i];
2898 LLVMTypeRef vtype;
2900 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2901 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2902 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2903 if (!ctx_ok (ctx))
2904 return;
2905 /* Could be already created by an OP_VPHI */
2906 if (!ctx->addresses [var->dreg]) {
2907 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2908 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2910 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2914 names = g_new (char *, sig->param_count);
2915 mono_method_get_param_names (cfg->method, (const char **) names);
2917 for (i = 0; i < sig->param_count; ++i) {
2918 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2919 int reg = cfg->args [i + sig->hasthis]->dreg;
2920 char *name;
2922 pindex = ainfo->pindex;
2924 switch (ainfo->storage) {
2925 case LLVMArgVtypeInReg:
2926 case LLVMArgAsFpArgs: {
2927 LLVMValueRef args [8];
2928 int j;
2930 pindex += ainfo->ndummy_fpargs;
2932 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2933 memset (args, 0, sizeof (args));
2934 if (ainfo->storage == LLVMArgVtypeInReg) {
2935 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2936 if (ainfo->pair_storage [1] != LLVMArgNone)
2937 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2938 } else {
2939 g_assert (ainfo->nslots <= 8);
2940 for (j = 0; j < ainfo->nslots; ++j)
2941 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2943 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2945 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2947 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2948 /* Treat these as normal values */
2949 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2951 break;
2953 case LLVMArgVtypeByVal: {
2954 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2956 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2957 /* Treat these as normal values */
2958 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2960 break;
2962 case LLVMArgVtypeByRef: {
2963 /* The argument is passed by ref */
2964 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2965 break;
2967 case LLVMArgAsIArgs: {
2968 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2969 int size;
2971 /* The argument is received as an array of ints, store it into the real argument */
2972 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2974 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2975 if (size < SIZEOF_VOID_P) {
2976 /* The upper bits of the registers might not be valid */
2977 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2978 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2979 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2980 } else {
2981 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2983 break;
2985 case LLVMArgVtypeAsScalar:
2986 g_assert_not_reached ();
2987 break;
2988 case LLVMArgGsharedvtFixed: {
2989 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2990 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2992 if (names [i])
2993 name = g_strdup_printf ("arg_%s", names [i]);
2994 else
2995 name = g_strdup_printf ("arg_%d", i);
2997 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2998 break;
3000 case LLVMArgGsharedvtFixedVtype: {
3001 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3003 if (names [i])
3004 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3005 else
3006 name = g_strdup_printf ("vtype_arg_%d", i);
3008 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3009 g_assert (ctx->addresses [reg]);
3010 LLVMSetValueName (ctx->addresses [reg], name);
3011 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3012 break;
3014 case LLVMArgGsharedvtVariable:
3015 /* The IR treats these as variables with addresses */
3016 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3017 break;
3018 default:
3019 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3020 break;
3023 g_free (names);
3025 if (cfg->vret_addr)
3026 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3027 if (sig->hasthis)
3028 emit_volatile_store (ctx, cfg->args [0]->dreg);
3029 for (i = 0; i < sig->param_count; ++i)
3030 if (!mini_type_is_vtype (sig->params [i]))
3031 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3033 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3034 LLVMValueRef this_alloc;
3037 * The exception handling code needs the location where the this argument was
3038 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3039 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3040 * location into the LSDA.
3042 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3043 /* This volatile store will keep the alloca alive */
3044 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3046 set_metadata_flag (this_alloc, "mono.this");
3049 if (cfg->rgctx_var) {
3050 LLVMValueRef rgctx_alloc, store;
3053 * We handle the rgctx arg similarly to the this pointer.
3055 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3056 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3057 /* This volatile store will keep the alloca alive */
3058 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3060 set_metadata_flag (rgctx_alloc, "mono.this");
3063 /* Initialize the method if needed */
3064 if (cfg->compile_aot && ctx->llvm_only) {
3065 /* Emit a location for the initialization code */
3066 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3067 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3069 LLVMBuildBr (ctx->builder, ctx->init_bb);
3070 builder = ctx->builder = create_builder (ctx);
3071 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3072 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3075 /* Compute nesting between clauses */
3076 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3077 for (i = 0; i < cfg->header->num_clauses; ++i) {
3078 for (j = 0; j < cfg->header->num_clauses; ++j) {
3079 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3080 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3082 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3083 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3088 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3089 * it needs to continue normally, or return back to the exception handling system.
3091 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3092 int clause_index;
3093 char name [128];
3095 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3096 continue;
3098 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3099 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3100 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3102 if (bb->in_scount == 0) {
3103 LLVMValueRef val;
3105 sprintf (name, "finally_ind_bb%d", bb->block_num);
3106 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3107 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3109 ctx->bblocks [bb->block_num].finally_ind = val;
3110 } else {
3111 /* Create a variable to hold the exception var */
3112 if (!ctx->ex_var)
3113 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3117 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3118 * LLVM bblock containing a landing pad causes problems for the
3119 * LLVM optimizer passes.
3121 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3122 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3124 ctx->builder = old_builder;
3127 static void
3128 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3130 MonoCompile *cfg = ctx->cfg;
3131 LLVMValueRef *values = ctx->values;
3132 LLVMValueRef *addresses = ctx->addresses;
3133 MonoCallInst *call = (MonoCallInst*)ins;
3134 MonoMethodSignature *sig = call->signature;
3135 LLVMValueRef callee = NULL, lcall;
3136 LLVMValueRef *args;
3137 LLVMCallInfo *cinfo;
3138 GSList *l;
3139 int i, len, nargs;
3140 gboolean vretaddr;
3141 LLVMTypeRef llvm_sig;
3142 gpointer target;
3143 gboolean is_virtual, calli, preserveall;
3144 LLVMBuilderRef builder = *builder_ref;
3146 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3147 set_failure (ctx, "non-default callconv");
3148 return;
3151 cinfo = call->cinfo;
3152 g_assert (cinfo);
3153 if (call->rgctx_arg_reg)
3154 cinfo->rgctx_arg = TRUE;
3155 if (call->imt_arg_reg)
3156 cinfo->imt_arg = TRUE;
3158 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3160 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3161 if (!ctx_ok (ctx))
3162 return;
3164 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3165 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3166 /* Unused */
3167 preserveall = FALSE;
3169 /* FIXME: Avoid creating duplicate methods */
3171 if (ins->flags & MONO_INST_HAS_METHOD) {
3172 if (is_virtual) {
3173 callee = NULL;
3174 } else {
3175 if (cfg->compile_aot) {
3176 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3177 if (!callee) {
3178 set_failure (ctx, "can't encode patch");
3179 return;
3181 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3183 * Collect instructions representing the callee into a hash so they can be replaced
3184 * by the llvm method for the callee if the callee turns out to be direct
3185 * callable. Currently this only requires it to not fail llvm compilation.
3187 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3188 l = g_slist_prepend (l, callee);
3189 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3191 } else {
3192 MonoError error;
3193 static int tramp_index;
3194 char *name;
3196 name = g_strdup_printf ("tramp_%d", tramp_index);
3197 tramp_index ++;
3199 #if LLVM_API_VERSION > 100
3201 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3202 * Make all calls through a global. The address of the global will be saved in
3203 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3204 * compiled.
3206 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3207 if (!tramp_var) {
3208 target =
3209 mono_create_jit_trampoline (mono_domain_get (),
3210 call->method, &error);
3211 if (!is_ok (&error)) {
3212 set_failure (ctx, mono_error_get_message (&error));
3213 mono_error_cleanup (&error);
3214 return;
3217 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3218 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3219 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3220 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3222 callee = LLVMBuildLoad (builder, tramp_var, "");
3223 #else
3224 target =
3225 mono_create_jit_trampoline (mono_domain_get (),
3226 call->method, &error);
3227 if (!is_ok (&error)) {
3228 g_free (name);
3229 set_failure (ctx, mono_error_get_message (&error));
3230 mono_error_cleanup (&error);
3231 return;
3234 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3235 g_free (name);
3237 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3238 #endif
3242 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3243 /* LLVM miscompiles async methods */
3244 set_failure (ctx, "#13734");
3245 return;
3247 } else if (calli) {
3248 } else {
3249 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3251 if (info) {
3253 MonoJumpInfo ji;
3255 memset (&ji, 0, sizeof (ji));
3256 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3257 ji.data.target = info->name;
3259 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3261 if (cfg->compile_aot) {
3262 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3263 if (!callee) {
3264 set_failure (ctx, "can't encode patch");
3265 return;
3267 } else {
3268 target = (gpointer)mono_icall_get_wrapper (info);
3269 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3271 } else {
3272 if (cfg->compile_aot) {
3273 callee = NULL;
3274 if (cfg->abs_patches) {
3275 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3276 if (abs_ji) {
3277 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3278 if (!callee) {
3279 set_failure (ctx, "can't encode patch");
3280 return;
3284 if (!callee) {
3285 set_failure (ctx, "aot");
3286 return;
3288 } else {
3289 #if LLVM_API_VERSION > 100
3290 if (cfg->abs_patches) {
3291 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3292 if (abs_ji) {
3293 MonoError error;
3295 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3296 mono_error_assert_ok (&error);
3297 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3298 } else {
3299 g_assert_not_reached ();
3301 } else {
3302 g_assert_not_reached ();
3304 #else
3305 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3306 target = NULL;
3307 if (cfg->abs_patches) {
3308 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3309 if (abs_ji) {
3310 MonoError error;
3313 * FIXME: Some trampolines might have
3314 * their own calling convention on some platforms.
3316 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3317 mono_error_assert_ok (&error);
3318 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3321 if (!target)
3322 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3323 #endif
3328 if (is_virtual) {
3329 int size = sizeof (gpointer);
3330 LLVMValueRef index;
3332 g_assert (ins->inst_offset % size == 0);
3333 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3335 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3336 } else if (calli) {
3337 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3338 } else {
3339 if (ins->flags & MONO_INST_HAS_METHOD) {
3344 * Collect and convert arguments
3346 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3347 len = sizeof (LLVMValueRef) * nargs;
3348 args = (LLVMValueRef*)alloca (len);
3349 memset (args, 0, len);
3350 l = call->out_ireg_args;
3352 if (call->rgctx_arg_reg) {
3353 g_assert (values [call->rgctx_arg_reg]);
3354 g_assert (cinfo->rgctx_arg_pindex < nargs);
3356 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3357 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3358 * it using a volatile load.
3360 #ifdef TARGET_ARM
3361 if (!ctx->imt_rgctx_loc)
3362 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3363 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3364 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3365 #else
3366 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3367 #endif
3369 if (call->imt_arg_reg) {
3370 g_assert (!ctx->llvm_only);
3371 g_assert (values [call->imt_arg_reg]);
3372 g_assert (cinfo->imt_arg_pindex < nargs);
3373 #ifdef TARGET_ARM
3374 if (!ctx->imt_rgctx_loc)
3375 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3376 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3377 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3378 #else
3379 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3380 #endif
3382 switch (cinfo->ret.storage) {
3383 case LLVMArgGsharedvtVariable: {
3384 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3386 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3387 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3388 } else {
3389 g_assert (addresses [call->inst.dreg]);
3390 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3392 break;
3394 default:
3395 if (vretaddr) {
3396 if (!addresses [call->inst.dreg])
3397 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3398 g_assert (cinfo->vret_arg_pindex < nargs);
3399 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3400 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3401 else
3402 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3404 break;
3408 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3409 * use the real callee for argument type conversion.
3411 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3412 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3413 LLVMGetParamTypes (callee_type, param_types);
3415 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3416 guint32 regpair;
3417 int reg, pindex;
3418 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3420 pindex = ainfo->pindex;
3422 regpair = (guint32)(gssize)(l->data);
3423 reg = regpair & 0xffffff;
3424 args [pindex] = values [reg];
3425 switch (ainfo->storage) {
3426 case LLVMArgVtypeInReg:
3427 case LLVMArgAsFpArgs: {
3428 guint32 nargs;
3429 int j;
3431 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3432 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3433 pindex += ainfo->ndummy_fpargs;
3435 g_assert (addresses [reg]);
3436 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3437 pindex += nargs;
3439 // FIXME: alignment
3440 // FIXME: Get rid of the VMOVE
3441 break;
3443 case LLVMArgVtypeByVal:
3444 g_assert (addresses [reg]);
3445 args [pindex] = addresses [reg];
3446 break;
3447 case LLVMArgVtypeByRef: {
3448 g_assert (addresses [reg]);
3449 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3450 break;
3452 case LLVMArgAsIArgs:
3453 g_assert (addresses [reg]);
3454 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3455 break;
3456 case LLVMArgVtypeAsScalar:
3457 g_assert_not_reached ();
3458 break;
3459 case LLVMArgGsharedvtFixed:
3460 case LLVMArgGsharedvtFixedVtype:
3461 g_assert (addresses [reg]);
3462 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3463 break;
3464 case LLVMArgGsharedvtVariable:
3465 g_assert (addresses [reg]);
3466 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3467 break;
3468 default:
3469 g_assert (args [pindex]);
3470 if (i == 0 && sig->hasthis)
3471 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3472 else
3473 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3474 break;
3476 g_assert (pindex <= nargs);
3478 l = l->next;
3481 // FIXME: Align call sites
3484 * Emit the call
3487 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3490 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3492 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3493 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3494 #endif
3495 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3496 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3497 if (!sig->pinvoke && !cfg->llvm_only)
3498 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3499 if (preserveall)
3500 mono_llvm_set_call_preserveall_cc (lcall);
3502 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3503 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3504 if (!ctx->llvm_only && call->rgctx_arg_reg)
3505 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3506 if (call->imt_arg_reg)
3507 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3509 /* Add byval attributes if needed */
3510 for (i = 0; i < sig->param_count; ++i) {
3511 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3513 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3514 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3518 * Convert the result
3520 switch (cinfo->ret.storage) {
3521 case LLVMArgVtypeInReg: {
3522 LLVMValueRef regs [2];
3524 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3525 /* Empty struct */
3526 break;
3528 if (!addresses [ins->dreg])
3529 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3531 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3532 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3533 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3534 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3535 break;
3537 case LLVMArgVtypeByVal:
3538 if (!addresses [call->inst.dreg])
3539 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3540 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3541 break;
3542 case LLVMArgAsIArgs:
3543 case LLVMArgFpStruct:
3544 if (!addresses [call->inst.dreg])
3545 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3546 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3547 break;
3548 case LLVMArgVtypeAsScalar:
3549 if (!addresses [call->inst.dreg])
3550 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3551 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3552 break;
3553 case LLVMArgVtypeRetAddr:
3554 case LLVMArgVtypeByRef:
3555 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3556 /* Some opcodes like STOREX_MEMBASE access these by value */
3557 g_assert (addresses [call->inst.dreg]);
3558 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3560 break;
3561 case LLVMArgGsharedvtVariable:
3562 break;
3563 case LLVMArgGsharedvtFixed:
3564 case LLVMArgGsharedvtFixedVtype:
3565 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3566 break;
3567 default:
3568 if (sig->ret->type != MONO_TYPE_VOID)
3569 /* If the method returns an unsigned value, need to zext it */
3570 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
3571 break;
3574 *builder_ref = ctx->builder;
3577 static void
3578 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3580 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3581 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3583 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3585 if (!callee) {
3586 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3588 if (ctx->cfg->compile_aot) {
3589 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3590 } else {
3591 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3592 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3593 mono_memory_barrier ();
3595 if (rethrow)
3596 ctx->module->rethrow = callee;
3597 else
3598 ctx->module->throw_icall = callee;
3602 LLVMValueRef args [2];
3604 args [0] = convert (ctx, exc, exc_type);
3605 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3607 LLVMBuildUnreachable (ctx->builder);
3609 ctx->builder = create_builder (ctx);
3612 static void
3613 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3615 MonoMethodSignature *throw_sig;
3616 LLVMValueRef callee, arg;
3617 const char *icall_name;
3619 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3620 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3622 if (!callee) {
3623 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3624 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3625 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3626 if (ctx->cfg->compile_aot) {
3627 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3628 } else {
3629 gpointer target;
3630 #ifdef TARGET_X86
3632 * LLVM doesn't push the exception argument, so we need a different
3633 * trampoline.
3635 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3636 #else
3637 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3638 #endif
3639 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3642 mono_memory_barrier ();
3643 #if LLVM_API_VERSION < 100
3644 if (rethrow)
3645 ctx->module->rethrow = callee;
3646 else
3647 ctx->module->throw_icall = callee;
3648 #endif
3650 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3651 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3654 static void
3655 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3657 const char *icall_name = "mono_llvm_resume_exception";
3658 LLVMValueRef callee = ctx->module->resume_eh;
3660 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3662 if (!callee) {
3663 if (ctx->cfg->compile_aot) {
3664 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3665 } else {
3666 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3667 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3668 mono_memory_barrier ();
3670 ctx->module->resume_eh = callee;
3674 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3676 LLVMBuildUnreachable (ctx->builder);
3678 ctx->builder = create_builder (ctx);
3681 static LLVMValueRef
3682 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3684 const char *icall_name = "mono_llvm_clear_exception";
3686 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3687 LLVMValueRef callee = NULL;
3689 if (!callee) {
3690 if (ctx->cfg->compile_aot) {
3691 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3692 } else {
3693 // FIXME: This is broken.
3694 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3698 g_assert (builder && callee);
3700 return LLVMBuildCall (builder, callee, NULL, 0, "");
3703 static LLVMValueRef
3704 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3706 const char *icall_name = "mono_llvm_load_exception";
3708 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3709 LLVMValueRef callee = NULL;
3711 if (!callee) {
3712 if (ctx->cfg->compile_aot) {
3713 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3714 } else {
3715 // FIXME: This is broken.
3716 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3720 g_assert (builder && callee);
3722 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3726 static LLVMValueRef
3727 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3729 const char *icall_name = "mono_llvm_match_exception";
3731 ctx->builder = builder;
3733 const int num_args = 5;
3734 LLVMValueRef args [num_args];
3735 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3736 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3737 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3738 if (ctx->cfg->rgctx_var) {
3739 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3740 g_assert (rgctx_alloc);
3741 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3742 } else {
3743 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3745 if (ctx->this_arg)
3746 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3747 else
3748 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3750 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3751 LLVMValueRef callee = ctx->module->match_exc;
3753 if (!callee) {
3754 if (ctx->cfg->compile_aot) {
3755 ctx->builder = builder;
3756 // get_callee expects ctx->builder to be the emitting builder
3757 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3758 } else {
3759 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3760 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3761 ctx->module->match_exc = callee;
3762 mono_memory_barrier ();
3766 g_assert (builder && callee);
3768 g_assert (ctx->ex_var);
3770 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3773 // FIXME: This won't work because the code-finding makes this
3774 // not a constant.
3775 /*#define MONO_PERSONALITY_DEBUG*/
3777 #ifdef MONO_PERSONALITY_DEBUG
3778 static const gboolean use_debug_personality = TRUE;
3779 static const char *default_personality_name = "mono_debug_personality";
3780 #else
3781 static const gboolean use_debug_personality = FALSE;
3782 static const char *default_personality_name = "__gxx_personality_v0";
3783 #endif
3785 static LLVMTypeRef
3786 default_cpp_lpad_exc_signature (void)
3788 static gboolean inited = FALSE;
3789 static LLVMTypeRef sig;
3791 if (!sig) {
3792 LLVMTypeRef signature [2];
3793 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3794 signature [1] = LLVMInt32Type ();
3795 sig = LLVMStructType (signature, 2, FALSE);
3796 inited = TRUE;
3799 return sig;
3802 static LLVMValueRef
3803 get_mono_personality (EmitContext *ctx)
3805 LLVMValueRef personality = NULL;
3806 static gint32 mapping_inited = FALSE;
3807 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3809 if (!use_debug_personality) {
3810 if (ctx->cfg->compile_aot) {
3811 personality = get_intrinsic (ctx, default_personality_name);
3812 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3813 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3814 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3816 } else {
3817 if (ctx->cfg->compile_aot) {
3818 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3819 } else {
3820 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3821 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3822 mono_memory_barrier ();
3826 g_assert (personality);
3827 return personality;
3830 static LLVMBasicBlockRef
3831 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3833 MonoCompile *cfg = ctx->cfg;
3834 LLVMBuilderRef old_builder = ctx->builder;
3835 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3837 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3838 ctx->builder = lpadBuilder;
3840 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3841 g_assert (handler_bb);
3843 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3844 LLVMValueRef personality = get_mono_personality (ctx);
3845 g_assert (personality);
3847 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3848 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3849 g_free (bb_name);
3850 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3851 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3852 g_assert (landing_pad);
3854 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3855 LLVMAddClause (landing_pad, cast);
3857 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3858 LLVMBuilderRef resume_builder = create_builder (ctx);
3859 ctx->builder = resume_builder;
3860 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3862 emit_resume_eh (ctx, handler_bb);
3864 // Build match
3865 ctx->builder = lpadBuilder;
3866 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3868 gboolean finally_only = TRUE;
3870 MonoExceptionClause *group_cursor = group_start;
3872 for (int i = 0; i < group_size; i ++) {
3873 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3874 finally_only = FALSE;
3876 group_cursor++;
3879 // FIXME:
3880 // Handle landing pad inlining
3882 if (!finally_only) {
3883 // So at each level of the exception stack we will match the exception again.
3884 // During that match, we need to compare against the handler types for the current
3885 // protected region. We send the try start and end so that we can only check against
3886 // handlers for this lexical protected region.
3887 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3889 // if returns -1, resume
3890 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3892 // else move to that target bb
3893 for (int i=0; i < group_size; i++) {
3894 MonoExceptionClause *clause = group_start + i;
3895 int clause_index = clause - cfg->header->clauses;
3896 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3897 g_assert (handler_bb);
3898 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3899 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3901 } else {
3902 int clause_index = group_start - cfg->header->clauses;
3903 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3904 g_assert (finally_bb);
3906 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3909 ctx->builder = old_builder;
3911 return lpad_bb;
3915 static void
3916 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3918 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3919 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3921 // Make exception available to catch blocks
3922 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3923 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3925 g_assert (ctx->ex_var);
3926 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3928 if (bb->in_scount == 1) {
3929 MonoInst *exvar = bb->in_stack [0];
3930 g_assert (!ctx->values [exvar->dreg]);
3931 g_assert (ctx->ex_var);
3932 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3933 emit_volatile_store (ctx, exvar->dreg);
3936 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3939 LLVMBuilderRef handler_builder = create_builder (ctx);
3940 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3941 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3943 // Make the handler code end with a jump to cbb
3944 LLVMBuildBr (handler_builder, cbb);
3947 static void
3948 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3950 MonoCompile *cfg = ctx->cfg;
3951 LLVMValueRef *values = ctx->values;
3952 LLVMModuleRef lmodule = ctx->lmodule;
3953 BBInfo *bblocks = ctx->bblocks;
3954 LLVMTypeRef i8ptr;
3955 LLVMValueRef personality;
3956 LLVMValueRef landing_pad;
3957 LLVMBasicBlockRef target_bb;
3958 MonoInst *exvar;
3959 static int ti_generator;
3960 char ti_name [128];
3961 LLVMValueRef type_info;
3962 int clause_index;
3963 GSList *l;
3965 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3967 if (cfg->compile_aot) {
3968 /* Use a dummy personality function */
3969 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3970 g_assert (personality);
3971 } else {
3972 #if LLVM_API_VERSION > 100
3973 personality = ctx->module->personality;
3974 if (!personality) {
3975 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3976 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3977 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3978 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3979 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3980 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3981 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3982 ctx->module->personality = personality;
3983 LLVMDisposeBuilder (builder2);
3985 #else
3986 static gint32 mapping_inited;
3988 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3990 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3991 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3992 #endif
3995 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3997 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4000 * Create the type info
4002 sprintf (ti_name, "type_info_%d", ti_generator);
4003 ti_generator ++;
4005 if (cfg->compile_aot) {
4006 /* decode_eh_frame () in aot-runtime.c will decode this */
4007 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4008 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4011 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4013 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4014 } else {
4015 #if LLVM_API_VERSION > 100
4016 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4017 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4018 #else
4019 gint32 *ti;
4022 * After the cfg mempool is freed, the type info will point to stale memory,
4023 * but this is not a problem, since we decode it once in exception_cb during
4024 * compilation.
4026 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4027 *(gint32*)ti = clause_index;
4029 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4031 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4032 #endif
4036 LLVMTypeRef members [2], ret_type;
4038 members [0] = i8ptr;
4039 members [1] = LLVMInt32Type ();
4040 ret_type = LLVMStructType (members, 2, FALSE);
4042 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4043 LLVMAddClause (landing_pad, type_info);
4045 /* Store the exception into the exvar */
4046 if (ctx->ex_var)
4047 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4051 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4052 * code expects control to be transferred to this landing pad even in the
4053 * presence of nested clauses. The landing pad needs to branch to the landing
4054 * pads belonging to nested clauses based on the selector value returned by
4055 * the landing pad instruction, which is passed to the landing pad in a
4056 * register by the EH code.
4058 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4059 g_assert (target_bb);
4062 * Branch to the correct landing pad
4064 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4065 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4067 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4068 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4069 MonoBasicBlock *handler_bb;
4071 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4072 g_assert (handler_bb);
4074 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4075 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4078 /* Start a new bblock which CALL_HANDLER can branch to */
4079 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4080 if (target_bb) {
4081 ctx->builder = builder = create_builder (ctx);
4082 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4084 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4086 /* Store the exception into the IL level exvar */
4087 if (bb->in_scount == 1) {
4088 g_assert (bb->in_scount == 1);
4089 exvar = bb->in_stack [0];
4091 // FIXME: This is shared with filter clauses ?
4092 g_assert (!values [exvar->dreg]);
4094 g_assert (ctx->ex_var);
4095 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4096 emit_volatile_store (ctx, exvar->dreg);
4101 static void
4102 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4104 MonoCompile *cfg = ctx->cfg;
4105 MonoMethodSignature *sig = ctx->sig;
4106 LLVMValueRef method = ctx->lmethod;
4107 LLVMValueRef *values = ctx->values;
4108 LLVMValueRef *addresses = ctx->addresses;
4109 LLVMCallInfo *linfo = ctx->linfo;
4110 BBInfo *bblocks = ctx->bblocks;
4111 MonoInst *ins;
4112 LLVMBasicBlockRef cbb;
4113 LLVMBuilderRef builder, starting_builder;
4114 gboolean has_terminator;
4115 LLVMValueRef v;
4116 LLVMValueRef lhs, rhs;
4117 int nins = 0;
4119 cbb = get_end_bb (ctx, bb);
4121 builder = create_builder (ctx);
4122 ctx->builder = builder;
4123 LLVMPositionBuilderAtEnd (builder, cbb);
4125 if (!ctx_ok (ctx))
4126 return;
4128 if (bb->flags & BB_EXCEPTION_HANDLER) {
4129 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4130 set_failure (ctx, "handler without invokes");
4131 return;
4134 if (ctx->llvm_only)
4135 emit_llvmonly_handler_start (ctx, bb, cbb);
4136 else
4137 emit_handler_start (ctx, bb, builder);
4138 if (!ctx_ok (ctx))
4139 return;
4140 builder = ctx->builder;
4143 has_terminator = FALSE;
4144 starting_builder = builder;
4145 for (ins = bb->code; ins; ins = ins->next) {
4146 const char *spec = LLVM_INS_INFO (ins->opcode);
4147 char *dname = NULL;
4148 char dname_buf [128];
4150 emit_dbg_loc (ctx, builder, ins->cil_code);
4152 nins ++;
4153 if (nins > 1000) {
4155 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4156 * Start a new bblock. If the llvm optimization passes merge these, we
4157 * can work around that by doing a volatile load + cond branch from
4158 * localloc-ed memory.
4160 if (!cfg->llvm_only)
4161 set_failure (ctx, "basic block too long");
4162 cbb = gen_bb (ctx, "CONT_LONG_BB");
4163 LLVMBuildBr (ctx->builder, cbb);
4164 ctx->builder = builder = create_builder (ctx);
4165 LLVMPositionBuilderAtEnd (builder, cbb);
4166 ctx->bblocks [bb->block_num].end_bblock = cbb;
4167 nins = 0;
4170 if (has_terminator)
4171 /* There could be instructions after a terminator, skip them */
4172 break;
4174 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4175 sprintf (dname_buf, "t%d", ins->dreg);
4176 dname = dname_buf;
4179 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4180 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4182 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4183 lhs = emit_volatile_load (ctx, ins->sreg1);
4184 } else {
4185 /* It is ok for SETRET to have an uninitialized argument */
4186 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4187 set_failure (ctx, "sreg1");
4188 return;
4190 lhs = values [ins->sreg1];
4192 } else {
4193 lhs = NULL;
4196 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4197 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4198 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4199 rhs = emit_volatile_load (ctx, ins->sreg2);
4200 } else {
4201 if (!values [ins->sreg2]) {
4202 set_failure (ctx, "sreg2");
4203 return;
4205 rhs = values [ins->sreg2];
4207 } else {
4208 rhs = NULL;
4211 //mono_print_ins (ins);
4212 switch (ins->opcode) {
4213 case OP_NOP:
4214 case OP_NOT_NULL:
4215 case OP_LIVERANGE_START:
4216 case OP_LIVERANGE_END:
4217 break;
4218 case OP_ICONST:
4219 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4220 break;
4221 case OP_I8CONST:
4222 #if SIZEOF_VOID_P == 4
4223 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4224 #else
4225 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4226 #endif
4227 break;
4228 case OP_R8CONST:
4229 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4230 break;
4231 case OP_R4CONST:
4232 if (cfg->r4fp)
4233 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4234 else
4235 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4236 break;
4237 case OP_DUMMY_ICONST:
4238 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4239 break;
4240 case OP_DUMMY_I8CONST:
4241 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4242 break;
4243 case OP_DUMMY_R8CONST:
4244 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4245 break;
4246 case OP_BR: {
4247 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4248 LLVMBuildBr (builder, target_bb);
4249 has_terminator = TRUE;
4250 break;
4252 case OP_SWITCH: {
4253 int i;
4254 LLVMValueRef v;
4255 char bb_name [128];
4256 LLVMBasicBlockRef new_bb;
4257 LLVMBuilderRef new_builder;
4259 // The default branch is already handled
4260 // FIXME: Handle it here
4262 /* Start new bblock */
4263 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4264 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4266 lhs = convert (ctx, lhs, LLVMInt32Type ());
4267 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4268 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4269 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4271 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4274 new_builder = create_builder (ctx);
4275 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4276 LLVMBuildUnreachable (new_builder);
4278 has_terminator = TRUE;
4279 g_assert (!ins->next);
4281 break;
4284 case OP_SETRET:
4285 switch (linfo->ret.storage) {
4286 case LLVMArgVtypeInReg: {
4287 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4288 LLVMValueRef val, addr, retval;
4289 int i;
4291 retval = LLVMGetUndef (ret_type);
4293 if (!addresses [ins->sreg1]) {
4295 * The return type is an LLVM vector type, have to convert between it and the
4296 * real return type which is a struct type.
4298 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4299 /* Convert to 2xi64 first */
4300 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4302 for (i = 0; i < 2; ++i) {
4303 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4304 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4305 } else {
4306 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4309 } else {
4310 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4311 for (i = 0; i < 2; ++i) {
4312 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4313 LLVMValueRef indexes [2], part_addr;
4315 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4316 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4317 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4319 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4320 } else {
4321 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4325 LLVMBuildRet (builder, retval);
4326 break;
4328 case LLVMArgVtypeAsScalar: {
4329 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4330 LLVMValueRef retval;
4332 g_assert (addresses [ins->sreg1]);
4334 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4335 LLVMBuildRet (builder, retval);
4336 break;
4338 case LLVMArgVtypeByVal: {
4339 LLVMValueRef retval;
4341 g_assert (addresses [ins->sreg1]);
4342 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4343 LLVMBuildRet (builder, retval);
4344 break;
4346 case LLVMArgVtypeByRef: {
4347 LLVMBuildRetVoid (builder);
4348 break;
4350 case LLVMArgGsharedvtFixed: {
4351 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4352 /* The return value is in lhs, need to store to the vret argument */
4353 /* sreg1 might not be set */
4354 if (lhs) {
4355 g_assert (cfg->vret_addr);
4356 g_assert (values [cfg->vret_addr->dreg]);
4357 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4359 LLVMBuildRetVoid (builder);
4360 break;
4362 case LLVMArgGsharedvtFixedVtype: {
4363 /* Already set */
4364 LLVMBuildRetVoid (builder);
4365 break;
4367 case LLVMArgGsharedvtVariable: {
4368 /* Already set */
4369 LLVMBuildRetVoid (builder);
4370 break;
4372 case LLVMArgVtypeRetAddr: {
4373 LLVMBuildRetVoid (builder);
4374 break;
4376 case LLVMArgAsIArgs:
4377 case LLVMArgFpStruct: {
4378 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4379 LLVMValueRef retval;
4381 g_assert (addresses [ins->sreg1]);
4382 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4383 LLVMBuildRet (builder, retval);
4384 break;
4386 case LLVMArgNone:
4387 case LLVMArgNormal: {
4388 if (!lhs || ctx->is_dead [ins->sreg1]) {
4390 * The method did not set its return value, probably because it
4391 * ends with a throw.
4393 if (cfg->vret_addr)
4394 LLVMBuildRetVoid (builder);
4395 else
4396 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4397 } else {
4398 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4400 has_terminator = TRUE;
4401 break;
4403 default:
4404 g_assert_not_reached ();
4405 break;
4407 break;
4408 case OP_ICOMPARE:
4409 case OP_FCOMPARE:
4410 case OP_RCOMPARE:
4411 case OP_LCOMPARE:
4412 case OP_COMPARE:
4413 case OP_ICOMPARE_IMM:
4414 case OP_LCOMPARE_IMM:
4415 case OP_COMPARE_IMM: {
4416 CompRelation rel;
4417 LLVMValueRef cmp, args [16];
4418 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4420 if (ins->next->opcode == OP_NOP)
4421 break;
4423 if (ins->next->opcode == OP_BR)
4424 /* The comparison result is not needed */
4425 continue;
4427 rel = mono_opcode_to_cond (ins->next->opcode);
4429 if (ins->opcode == OP_ICOMPARE_IMM) {
4430 lhs = convert (ctx, lhs, LLVMInt32Type ());
4431 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4433 if (ins->opcode == OP_LCOMPARE_IMM) {
4434 lhs = convert (ctx, lhs, LLVMInt64Type ());
4435 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4437 if (ins->opcode == OP_LCOMPARE) {
4438 lhs = convert (ctx, lhs, LLVMInt64Type ());
4439 rhs = convert (ctx, rhs, LLVMInt64Type ());
4441 if (ins->opcode == OP_ICOMPARE) {
4442 lhs = convert (ctx, lhs, LLVMInt32Type ());
4443 rhs = convert (ctx, rhs, LLVMInt32Type ());
4446 if (lhs && rhs) {
4447 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4448 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4449 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4450 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4453 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4454 if (ins->opcode == OP_FCOMPARE) {
4455 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4456 } else if (ins->opcode == OP_RCOMPARE) {
4457 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4458 } else if (ins->opcode == OP_COMPARE_IMM) {
4459 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4460 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4461 else
4462 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4463 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4464 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4465 /* The immediate is encoded in two fields */
4466 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4467 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4468 } else {
4469 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4472 else if (ins->opcode == OP_COMPARE) {
4473 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4474 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4475 else
4476 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4477 } else
4478 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4480 if (likely) {
4481 args [0] = cmp;
4482 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4483 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4486 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4487 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4489 * If the target bb contains PHI instructions, LLVM requires
4490 * two PHI entries for this bblock, while we only generate one.
4491 * So convert this to an unconditional bblock. (bxc #171).
4493 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4494 } else {
4495 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4497 has_terminator = TRUE;
4498 } else if (MONO_IS_SETCC (ins->next)) {
4499 sprintf (dname_buf, "t%d", ins->next->dreg);
4500 dname = dname_buf;
4501 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4503 /* Add stores for volatile variables */
4504 emit_volatile_store (ctx, ins->next->dreg);
4505 } else if (MONO_IS_COND_EXC (ins->next)) {
4506 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4507 if (!ctx_ok (ctx))
4508 break;
4509 builder = ctx->builder;
4510 } else {
4511 set_failure (ctx, "next");
4512 break;
4515 ins = ins->next;
4516 break;
4518 case OP_FCEQ:
4519 case OP_FCNEQ:
4520 case OP_FCLT:
4521 case OP_FCLT_UN:
4522 case OP_FCGT:
4523 case OP_FCGT_UN:
4524 case OP_FCGE:
4525 case OP_FCLE: {
4526 CompRelation rel;
4527 LLVMValueRef cmp;
4529 rel = mono_opcode_to_cond (ins->opcode);
4531 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4532 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4533 break;
4535 case OP_RCEQ:
4536 case OP_RCLT:
4537 case OP_RCLT_UN:
4538 case OP_RCGT:
4539 case OP_RCGT_UN: {
4540 CompRelation rel;
4541 LLVMValueRef cmp;
4543 rel = mono_opcode_to_cond (ins->opcode);
4545 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4546 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4547 break;
4549 case OP_PHI:
4550 case OP_FPHI:
4551 case OP_VPHI:
4552 case OP_XPHI: {
4553 int i;
4554 gboolean empty = TRUE;
4556 /* Check that all input bblocks really branch to us */
4557 for (i = 0; i < bb->in_count; ++i) {
4558 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4559 ins->inst_phi_args [i + 1] = -1;
4560 else
4561 empty = FALSE;
4564 if (empty) {
4565 /* LLVM doesn't like phi instructions with zero operands */
4566 ctx->is_dead [ins->dreg] = TRUE;
4567 break;
4570 /* Created earlier, insert it now */
4571 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4573 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4574 int sreg1 = ins->inst_phi_args [i + 1];
4575 int count, j;
4578 * Count the number of times the incoming bblock branches to us,
4579 * since llvm requires a separate entry for each.
4581 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4582 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4584 count = 0;
4585 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4586 if (switch_ins->inst_many_bb [j] == bb)
4587 count ++;
4589 } else {
4590 count = 1;
4593 /* Remember for later */
4594 for (j = 0; j < count; ++j) {
4595 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4596 node->bb = bb;
4597 node->phi = ins;
4598 node->in_bb = bb->in_bb [i];
4599 node->sreg = sreg1;
4600 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);
4603 break;
4605 case OP_MOVE:
4606 case OP_LMOVE:
4607 case OP_XMOVE:
4608 case OP_SETFRET:
4609 g_assert (lhs);
4610 values [ins->dreg] = lhs;
4611 break;
4612 case OP_FMOVE:
4613 case OP_RMOVE: {
4614 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4616 g_assert (lhs);
4617 values [ins->dreg] = lhs;
4619 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4621 * This is added by the spilling pass in case of the JIT,
4622 * but we have to do it ourselves.
4624 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4626 break;
4628 case OP_MOVE_F_TO_I4: {
4629 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4630 break;
4632 case OP_MOVE_I4_TO_F: {
4633 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4634 break;
4636 case OP_MOVE_F_TO_I8: {
4637 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4638 break;
4640 case OP_MOVE_I8_TO_F: {
4641 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4642 break;
4644 case OP_IADD:
4645 case OP_ISUB:
4646 case OP_IAND:
4647 case OP_IMUL:
4648 case OP_IDIV:
4649 case OP_IDIV_UN:
4650 case OP_IREM:
4651 case OP_IREM_UN:
4652 case OP_IOR:
4653 case OP_IXOR:
4654 case OP_ISHL:
4655 case OP_ISHR:
4656 case OP_ISHR_UN:
4657 case OP_FADD:
4658 case OP_FSUB:
4659 case OP_FMUL:
4660 case OP_FDIV:
4661 case OP_LADD:
4662 case OP_LSUB:
4663 case OP_LMUL:
4664 case OP_LDIV:
4665 case OP_LDIV_UN:
4666 case OP_LREM:
4667 case OP_LREM_UN:
4668 case OP_LAND:
4669 case OP_LOR:
4670 case OP_LXOR:
4671 case OP_LSHL:
4672 case OP_LSHR:
4673 case OP_LSHR_UN:
4674 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4675 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4677 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4678 if (!ctx_ok (ctx))
4679 break;
4680 builder = ctx->builder;
4682 switch (ins->opcode) {
4683 case OP_IADD:
4684 case OP_LADD:
4685 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4686 break;
4687 case OP_ISUB:
4688 case OP_LSUB:
4689 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4690 break;
4691 case OP_IMUL:
4692 case OP_LMUL:
4693 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4694 break;
4695 case OP_IREM:
4696 case OP_LREM:
4697 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4698 break;
4699 case OP_IREM_UN:
4700 case OP_LREM_UN:
4701 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4702 break;
4703 case OP_IDIV:
4704 case OP_LDIV:
4705 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4706 break;
4707 case OP_IDIV_UN:
4708 case OP_LDIV_UN:
4709 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4710 break;
4711 case OP_FDIV:
4712 case OP_RDIV:
4713 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4714 break;
4715 case OP_IAND:
4716 case OP_LAND:
4717 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4718 break;
4719 case OP_IOR:
4720 case OP_LOR:
4721 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4722 break;
4723 case OP_IXOR:
4724 case OP_LXOR:
4725 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4726 break;
4727 case OP_ISHL:
4728 case OP_LSHL:
4729 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4730 break;
4731 case OP_ISHR:
4732 case OP_LSHR:
4733 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4734 break;
4735 case OP_ISHR_UN:
4736 case OP_LSHR_UN:
4737 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4738 break;
4740 case OP_FADD:
4741 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4742 break;
4743 case OP_FSUB:
4744 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4745 break;
4746 case OP_FMUL:
4747 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4748 break;
4750 default:
4751 g_assert_not_reached ();
4753 break;
4754 case OP_RADD:
4755 case OP_RSUB:
4756 case OP_RMUL:
4757 case OP_RDIV: {
4758 lhs = convert (ctx, lhs, LLVMFloatType ());
4759 rhs = convert (ctx, rhs, LLVMFloatType ());
4760 switch (ins->opcode) {
4761 case OP_RADD:
4762 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4763 break;
4764 case OP_RSUB:
4765 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4766 break;
4767 case OP_RMUL:
4768 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4769 break;
4770 case OP_RDIV:
4771 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4772 break;
4773 default:
4774 g_assert_not_reached ();
4775 break;
4777 break;
4779 case OP_IADD_IMM:
4780 case OP_ISUB_IMM:
4781 case OP_IMUL_IMM:
4782 case OP_IREM_IMM:
4783 case OP_IREM_UN_IMM:
4784 case OP_IDIV_IMM:
4785 case OP_IDIV_UN_IMM:
4786 case OP_IAND_IMM:
4787 case OP_IOR_IMM:
4788 case OP_IXOR_IMM:
4789 case OP_ISHL_IMM:
4790 case OP_ISHR_IMM:
4791 case OP_ISHR_UN_IMM:
4792 case OP_LADD_IMM:
4793 case OP_LSUB_IMM:
4794 case OP_LMUL_IMM:
4795 case OP_LREM_IMM:
4796 case OP_LAND_IMM:
4797 case OP_LOR_IMM:
4798 case OP_LXOR_IMM:
4799 case OP_LSHL_IMM:
4800 case OP_LSHR_IMM:
4801 case OP_LSHR_UN_IMM:
4802 case OP_ADD_IMM:
4803 case OP_AND_IMM:
4804 case OP_MUL_IMM:
4805 case OP_SHL_IMM:
4806 case OP_SHR_IMM:
4807 case OP_SHR_UN_IMM: {
4808 LLVMValueRef imm;
4810 if (spec [MONO_INST_SRC1] == 'l') {
4811 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4812 } else {
4813 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4816 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4817 if (!ctx_ok (ctx))
4818 break;
4819 builder = ctx->builder;
4821 #if SIZEOF_VOID_P == 4
4822 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4823 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4824 #endif
4826 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4827 lhs = convert (ctx, lhs, IntPtrType ());
4828 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4829 switch (ins->opcode) {
4830 case OP_IADD_IMM:
4831 case OP_LADD_IMM:
4832 case OP_ADD_IMM:
4833 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4834 break;
4835 case OP_ISUB_IMM:
4836 case OP_LSUB_IMM:
4837 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4838 break;
4839 case OP_IMUL_IMM:
4840 case OP_MUL_IMM:
4841 case OP_LMUL_IMM:
4842 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4843 break;
4844 case OP_IDIV_IMM:
4845 case OP_LDIV_IMM:
4846 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4847 break;
4848 case OP_IDIV_UN_IMM:
4849 case OP_LDIV_UN_IMM:
4850 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4851 break;
4852 case OP_IREM_IMM:
4853 case OP_LREM_IMM:
4854 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4855 break;
4856 case OP_IREM_UN_IMM:
4857 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4858 break;
4859 case OP_IAND_IMM:
4860 case OP_LAND_IMM:
4861 case OP_AND_IMM:
4862 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4863 break;
4864 case OP_IOR_IMM:
4865 case OP_LOR_IMM:
4866 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4867 break;
4868 case OP_IXOR_IMM:
4869 case OP_LXOR_IMM:
4870 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4871 break;
4872 case OP_ISHL_IMM:
4873 case OP_LSHL_IMM:
4874 case OP_SHL_IMM:
4875 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4876 break;
4877 case OP_ISHR_IMM:
4878 case OP_LSHR_IMM:
4879 case OP_SHR_IMM:
4880 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4881 break;
4882 case OP_ISHR_UN_IMM:
4883 /* This is used to implement conv.u4, so the lhs could be an i8 */
4884 lhs = convert (ctx, lhs, LLVMInt32Type ());
4885 imm = convert (ctx, imm, LLVMInt32Type ());
4886 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4887 break;
4888 case OP_LSHR_UN_IMM:
4889 case OP_SHR_UN_IMM:
4890 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4891 break;
4892 default:
4893 g_assert_not_reached ();
4895 break;
4897 case OP_INEG:
4898 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4899 break;
4900 case OP_LNEG:
4901 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4902 break;
4903 case OP_FNEG:
4904 lhs = convert (ctx, lhs, LLVMDoubleType ());
4905 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4906 break;
4907 case OP_RNEG:
4908 lhs = convert (ctx, lhs, LLVMFloatType ());
4909 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4910 break;
4911 case OP_INOT: {
4912 guint32 v = 0xffffffff;
4913 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4914 break;
4916 case OP_LNOT: {
4917 guint64 v = 0xffffffffffffffffLL;
4918 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4919 break;
4921 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4922 case OP_X86_LEA: {
4923 LLVMValueRef v1, v2;
4925 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4926 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4927 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4928 break;
4930 #endif
4932 case OP_ICONV_TO_I1:
4933 case OP_ICONV_TO_I2:
4934 case OP_ICONV_TO_I4:
4935 case OP_ICONV_TO_U1:
4936 case OP_ICONV_TO_U2:
4937 case OP_ICONV_TO_U4:
4938 case OP_LCONV_TO_I1:
4939 case OP_LCONV_TO_I2:
4940 case OP_LCONV_TO_U1:
4941 case OP_LCONV_TO_U2:
4942 case OP_LCONV_TO_U4: {
4943 gboolean sign;
4945 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);
4947 /* Have to do two casts since our vregs have type int */
4948 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4949 if (sign)
4950 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4951 else
4952 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4953 break;
4955 case OP_ICONV_TO_I8:
4956 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4957 break;
4958 case OP_ICONV_TO_U8:
4959 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4960 break;
4961 case OP_FCONV_TO_I4:
4962 case OP_RCONV_TO_I4:
4963 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4964 break;
4965 case OP_FCONV_TO_I1:
4966 case OP_RCONV_TO_I1:
4967 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4968 break;
4969 case OP_FCONV_TO_U1:
4970 case OP_RCONV_TO_U1:
4971 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4972 break;
4973 case OP_FCONV_TO_I2:
4974 case OP_RCONV_TO_I2:
4975 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4976 break;
4977 case OP_FCONV_TO_U2:
4978 case OP_RCONV_TO_U2:
4979 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4980 break;
4981 case OP_RCONV_TO_U4:
4982 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4983 break;
4984 case OP_FCONV_TO_I8:
4985 case OP_RCONV_TO_I8:
4986 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4987 break;
4988 case OP_FCONV_TO_I:
4989 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4990 break;
4991 case OP_ICONV_TO_R8:
4992 case OP_LCONV_TO_R8:
4993 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4994 break;
4995 case OP_ICONV_TO_R_UN:
4996 case OP_LCONV_TO_R_UN:
4997 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4998 break;
4999 #if SIZEOF_VOID_P == 4
5000 case OP_LCONV_TO_U:
5001 #endif
5002 case OP_LCONV_TO_I4:
5003 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5004 break;
5005 case OP_ICONV_TO_R4:
5006 case OP_LCONV_TO_R4:
5007 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5008 if (cfg->r4fp)
5009 values [ins->dreg] = v;
5010 else
5011 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5012 break;
5013 case OP_FCONV_TO_R4:
5014 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5015 if (cfg->r4fp)
5016 values [ins->dreg] = v;
5017 else
5018 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5019 break;
5020 case OP_RCONV_TO_R8:
5021 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5022 break;
5023 case OP_RCONV_TO_R4:
5024 values [ins->dreg] = lhs;
5025 break;
5026 case OP_SEXT_I4:
5027 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5028 break;
5029 case OP_ZEXT_I4:
5030 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5031 break;
5032 case OP_TRUNC_I4:
5033 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5034 break;
5035 case OP_LOCALLOC_IMM: {
5036 LLVMValueRef v;
5038 guint32 size = ins->inst_imm;
5039 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5041 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5043 if (ins->flags & MONO_INST_INIT) {
5044 LLVMValueRef args [5];
5046 args [0] = v;
5047 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5048 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5049 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5050 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5051 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5054 values [ins->dreg] = v;
5055 break;
5057 case OP_LOCALLOC: {
5058 LLVMValueRef v, size;
5060 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), "");
5062 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5064 if (ins->flags & MONO_INST_INIT) {
5065 LLVMValueRef args [5];
5067 args [0] = v;
5068 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5069 args [2] = size;
5070 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5071 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5072 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5074 values [ins->dreg] = v;
5075 break;
5078 case OP_LOADI1_MEMBASE:
5079 case OP_LOADU1_MEMBASE:
5080 case OP_LOADI2_MEMBASE:
5081 case OP_LOADU2_MEMBASE:
5082 case OP_LOADI4_MEMBASE:
5083 case OP_LOADU4_MEMBASE:
5084 case OP_LOADI8_MEMBASE:
5085 case OP_LOADR4_MEMBASE:
5086 case OP_LOADR8_MEMBASE:
5087 case OP_LOAD_MEMBASE:
5088 case OP_LOADI8_MEM:
5089 case OP_LOADU1_MEM:
5090 case OP_LOADU2_MEM:
5091 case OP_LOADI4_MEM:
5092 case OP_LOADU4_MEM:
5093 case OP_LOAD_MEM: {
5094 int size = 8;
5095 LLVMValueRef base, index, addr;
5096 LLVMTypeRef t;
5097 gboolean sext = FALSE, zext = FALSE;
5098 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5100 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5102 if (sext || zext)
5103 dname = (char*)"";
5105 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)) {
5106 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5107 base = addr;
5108 } else {
5109 /* _MEMBASE */
5110 base = lhs;
5112 if (ins->inst_offset == 0) {
5113 addr = base;
5114 } else if (ins->inst_offset % size != 0) {
5115 /* Unaligned load */
5116 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5117 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5118 } else {
5119 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5120 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5124 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5126 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5128 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5130 * These will signal LLVM that these loads do not alias any stores, and
5131 * they can't fail, allowing them to be hoisted out of loops.
5133 set_invariant_load_flag (values [ins->dreg]);
5134 #if LLVM_API_VERSION < 100
5135 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5136 #endif
5139 if (sext)
5140 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5141 else if (zext)
5142 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5143 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5144 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5145 break;
5148 case OP_STOREI1_MEMBASE_REG:
5149 case OP_STOREI2_MEMBASE_REG:
5150 case OP_STOREI4_MEMBASE_REG:
5151 case OP_STOREI8_MEMBASE_REG:
5152 case OP_STORER4_MEMBASE_REG:
5153 case OP_STORER8_MEMBASE_REG:
5154 case OP_STORE_MEMBASE_REG: {
5155 int size = 8;
5156 LLVMValueRef index, addr, base;
5157 LLVMTypeRef t;
5158 gboolean sext = FALSE, zext = FALSE;
5159 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5161 if (!values [ins->inst_destbasereg]) {
5162 set_failure (ctx, "inst_destbasereg");
5163 break;
5166 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5168 base = values [ins->inst_destbasereg];
5169 if (ins->inst_offset % size != 0) {
5170 /* Unaligned store */
5171 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5172 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5173 } else {
5174 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5175 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5177 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5178 break;
5181 case OP_STOREI1_MEMBASE_IMM:
5182 case OP_STOREI2_MEMBASE_IMM:
5183 case OP_STOREI4_MEMBASE_IMM:
5184 case OP_STOREI8_MEMBASE_IMM:
5185 case OP_STORE_MEMBASE_IMM: {
5186 int size = 8;
5187 LLVMValueRef index, addr, base;
5188 LLVMTypeRef t;
5189 gboolean sext = FALSE, zext = FALSE;
5190 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5192 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5194 base = values [ins->inst_destbasereg];
5195 if (ins->inst_offset % size != 0) {
5196 /* Unaligned store */
5197 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5198 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5199 } else {
5200 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5201 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5203 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5204 break;
5207 case OP_CHECK_THIS:
5208 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5209 break;
5210 case OP_OUTARG_VTRETADDR:
5211 break;
5212 case OP_VOIDCALL:
5213 case OP_CALL:
5214 case OP_LCALL:
5215 case OP_FCALL:
5216 case OP_RCALL:
5217 case OP_VCALL:
5218 case OP_VOIDCALL_MEMBASE:
5219 case OP_CALL_MEMBASE:
5220 case OP_LCALL_MEMBASE:
5221 case OP_FCALL_MEMBASE:
5222 case OP_RCALL_MEMBASE:
5223 case OP_VCALL_MEMBASE:
5224 case OP_VOIDCALL_REG:
5225 case OP_CALL_REG:
5226 case OP_LCALL_REG:
5227 case OP_FCALL_REG:
5228 case OP_RCALL_REG:
5229 case OP_VCALL_REG: {
5230 process_call (ctx, bb, &builder, ins);
5231 break;
5233 case OP_AOTCONST: {
5234 guint32 got_offset;
5235 LLVMValueRef indexes [2];
5236 MonoJumpInfo *tmp_ji, *ji;
5237 LLVMValueRef got_entry_addr;
5238 char *name;
5241 * FIXME: Can't allocate from the cfg mempool since that is freed if
5242 * the LLVM compile fails.
5244 tmp_ji = g_new0 (MonoJumpInfo, 1);
5245 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5246 tmp_ji->data.target = ins->inst_p0;
5248 ji = mono_aot_patch_info_dup (tmp_ji);
5249 g_free (tmp_ji);
5251 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5252 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5253 if (symbol) {
5255 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5256 * resolvable at runtime using dlsym ().
5258 g_free (symbol);
5259 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5260 break;
5264 ji->next = cfg->patch_info;
5265 cfg->patch_info = ji;
5267 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5268 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5269 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5270 if (!mono_aot_is_shared_got_offset (got_offset)) {
5271 //mono_print_ji (ji);
5272 //printf ("\n");
5273 ctx->has_got_access = TRUE;
5276 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5277 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5278 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5280 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5281 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5282 g_free (name);
5283 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5284 if (!cfg->llvm_only)
5285 set_invariant_load_flag (values [ins->dreg]);
5286 break;
5288 case OP_NOT_REACHED:
5289 LLVMBuildUnreachable (builder);
5290 has_terminator = TRUE;
5291 g_assert (bb->block_num < cfg->max_block_num);
5292 ctx->unreachable [bb->block_num] = TRUE;
5293 /* Might have instructions after this */
5294 while (ins->next) {
5295 MonoInst *next = ins->next;
5297 * FIXME: If later code uses the regs defined by these instructions,
5298 * compilation will fail.
5300 MONO_DELETE_INS (bb, next);
5302 break;
5303 case OP_LDADDR: {
5304 MonoInst *var = ins->inst_i0;
5306 if (var->opcode == OP_VTARG_ADDR) {
5307 /* The variable contains the vtype address */
5308 values [ins->dreg] = values [var->dreg];
5309 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5310 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5311 } else {
5312 values [ins->dreg] = addresses [var->dreg];
5314 break;
5316 case OP_SIN: {
5317 LLVMValueRef args [1];
5319 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5320 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5321 break;
5323 case OP_COS: {
5324 LLVMValueRef args [1];
5326 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5327 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5328 break;
5330 case OP_SQRT: {
5331 LLVMValueRef args [1];
5333 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5334 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5335 break;
5337 case OP_ABS: {
5338 LLVMValueRef args [1];
5340 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5341 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5342 break;
5345 case OP_IMIN:
5346 case OP_LMIN:
5347 case OP_IMAX:
5348 case OP_LMAX:
5349 case OP_IMIN_UN:
5350 case OP_LMIN_UN:
5351 case OP_IMAX_UN:
5352 case OP_LMAX_UN: {
5353 LLVMValueRef v;
5355 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5356 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5358 switch (ins->opcode) {
5359 case OP_IMIN:
5360 case OP_LMIN:
5361 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5362 break;
5363 case OP_IMAX:
5364 case OP_LMAX:
5365 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5366 break;
5367 case OP_IMIN_UN:
5368 case OP_LMIN_UN:
5369 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5370 break;
5371 case OP_IMAX_UN:
5372 case OP_LMAX_UN:
5373 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5374 break;
5375 default:
5376 g_assert_not_reached ();
5377 break;
5379 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5380 break;
5384 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5385 * hack is necessary (for now).
5387 #ifdef TARGET_ARM64
5388 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5389 #else
5390 #define ARM64_ATOMIC_FENCE_FIX
5391 #endif
5393 case OP_ATOMIC_EXCHANGE_I4:
5394 case OP_ATOMIC_EXCHANGE_I8: {
5395 LLVMValueRef args [2];
5396 LLVMTypeRef t;
5398 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5399 t = LLVMInt32Type ();
5400 else
5401 t = LLVMInt64Type ();
5403 g_assert (ins->inst_offset == 0);
5405 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5406 args [1] = convert (ctx, rhs, t);
5408 ARM64_ATOMIC_FENCE_FIX;
5409 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5410 ARM64_ATOMIC_FENCE_FIX;
5411 break;
5413 case OP_ATOMIC_ADD_I4:
5414 case OP_ATOMIC_ADD_I8: {
5415 LLVMValueRef args [2];
5416 LLVMTypeRef t;
5418 if (ins->opcode == OP_ATOMIC_ADD_I4)
5419 t = LLVMInt32Type ();
5420 else
5421 t = LLVMInt64Type ();
5423 g_assert (ins->inst_offset == 0);
5425 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5426 args [1] = convert (ctx, rhs, t);
5427 ARM64_ATOMIC_FENCE_FIX;
5428 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5429 ARM64_ATOMIC_FENCE_FIX;
5430 break;
5432 case OP_ATOMIC_CAS_I4:
5433 case OP_ATOMIC_CAS_I8: {
5434 LLVMValueRef args [3], val;
5435 LLVMTypeRef t;
5437 if (ins->opcode == OP_ATOMIC_CAS_I4)
5438 t = LLVMInt32Type ();
5439 else
5440 t = LLVMInt64Type ();
5442 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5443 /* comparand */
5444 args [1] = convert (ctx, values [ins->sreg3], t);
5445 /* new value */
5446 args [2] = convert (ctx, values [ins->sreg2], t);
5447 ARM64_ATOMIC_FENCE_FIX;
5448 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5449 ARM64_ATOMIC_FENCE_FIX;
5450 /* cmpxchg returns a pair */
5451 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5452 break;
5454 case OP_MEMORY_BARRIER: {
5455 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5456 break;
5458 case OP_ATOMIC_LOAD_I1:
5459 case OP_ATOMIC_LOAD_I2:
5460 case OP_ATOMIC_LOAD_I4:
5461 case OP_ATOMIC_LOAD_I8:
5462 case OP_ATOMIC_LOAD_U1:
5463 case OP_ATOMIC_LOAD_U2:
5464 case OP_ATOMIC_LOAD_U4:
5465 case OP_ATOMIC_LOAD_U8:
5466 case OP_ATOMIC_LOAD_R4:
5467 case OP_ATOMIC_LOAD_R8: {
5468 #if LLVM_API_VERSION > 100
5469 int size;
5470 gboolean sext, zext;
5471 LLVMTypeRef t;
5472 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5473 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5474 LLVMValueRef index, addr;
5476 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5478 if (sext || zext)
5479 dname = (char *)"";
5481 if (ins->inst_offset != 0) {
5482 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5483 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5484 } else {
5485 addr = lhs;
5488 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5490 ARM64_ATOMIC_FENCE_FIX;
5491 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5492 ARM64_ATOMIC_FENCE_FIX;
5494 if (sext)
5495 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5496 else if (zext)
5497 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5498 break;
5499 #else
5500 set_failure (ctx, "atomic mono.load intrinsic");
5501 break;
5502 #endif
5504 case OP_ATOMIC_STORE_I1:
5505 case OP_ATOMIC_STORE_I2:
5506 case OP_ATOMIC_STORE_I4:
5507 case OP_ATOMIC_STORE_I8:
5508 case OP_ATOMIC_STORE_U1:
5509 case OP_ATOMIC_STORE_U2:
5510 case OP_ATOMIC_STORE_U4:
5511 case OP_ATOMIC_STORE_U8:
5512 case OP_ATOMIC_STORE_R4:
5513 case OP_ATOMIC_STORE_R8: {
5514 int size;
5515 gboolean sext, zext;
5516 LLVMTypeRef t;
5517 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5518 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5519 LLVMValueRef index, addr, value, base;
5521 #if LLVM_API_VERSION < 100
5522 if (!cfg->llvm_only) {
5523 set_failure (ctx, "atomic mono.store intrinsic");
5524 break;
5526 #endif
5528 if (!values [ins->inst_destbasereg]) {
5529 set_failure (ctx, "inst_destbasereg");
5530 break;
5533 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5535 base = values [ins->inst_destbasereg];
5536 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5537 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5538 value = convert (ctx, values [ins->sreg1], t);
5540 ARM64_ATOMIC_FENCE_FIX;
5541 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5542 ARM64_ATOMIC_FENCE_FIX;
5543 break;
5545 case OP_RELAXED_NOP: {
5546 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5547 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5548 break;
5549 #else
5550 break;
5551 #endif
5553 case OP_TLS_GET: {
5554 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5555 #ifdef TARGET_AMD64
5556 // 257 == FS segment register
5557 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5558 #else
5559 // 256 == GS segment register
5560 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5561 #endif
5562 // FIXME: XEN
5563 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5564 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5565 /* See mono_amd64_emit_tls_get () */
5566 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5568 // 256 == GS segment register
5569 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5570 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5571 #else
5572 set_failure (ctx, "opcode tls-get");
5573 break;
5574 #endif
5576 break;
5578 case OP_TLS_GET_REG: {
5579 #if defined(TARGET_AMD64) && defined(__linux__)
5580 // 257 == FS segment register
5581 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5582 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5583 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5584 /* See emit_tls_get_reg () */
5585 // 256 == GS segment register
5586 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5587 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5588 #else
5589 set_failure (ctx, "opcode tls-get");
5590 break;
5591 #endif
5592 break;
5595 case OP_TLS_SET_REG: {
5596 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5597 /* See emit_tls_get_reg () */
5598 // 256 == GS segment register
5599 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5600 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5601 #else
5602 set_failure (ctx, "opcode tls-set-reg");
5603 break;
5604 #endif
5605 break;
5607 case OP_GC_SAFE_POINT: {
5608 LLVMValueRef val, cmp, callee;
5609 LLVMBasicBlockRef poll_bb, cont_bb;
5610 static LLVMTypeRef sig;
5611 const char *icall_name = "mono_threads_state_poll";
5613 if (!sig)
5614 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5617 * if (!*sreg1)
5618 * mono_threads_state_poll ();
5619 * FIXME: Use a preserveall wrapper
5621 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5622 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5623 poll_bb = gen_bb (ctx, "POLL_BB");
5624 cont_bb = gen_bb (ctx, "CONT_BB");
5625 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5627 ctx->builder = builder = create_builder (ctx);
5628 LLVMPositionBuilderAtEnd (builder, poll_bb);
5630 if (ctx->cfg->compile_aot) {
5631 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5632 } else {
5633 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5634 callee = emit_jit_callee (ctx, icall_name, sig, target);
5636 LLVMBuildCall (builder, callee, NULL, 0, "");
5637 LLVMBuildBr (builder, cont_bb);
5639 ctx->builder = builder = create_builder (ctx);
5640 LLVMPositionBuilderAtEnd (builder, cont_bb);
5641 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5642 break;
5646 * Overflow opcodes.
5648 case OP_IADD_OVF:
5649 case OP_IADD_OVF_UN:
5650 case OP_ISUB_OVF:
5651 case OP_ISUB_OVF_UN:
5652 case OP_IMUL_OVF:
5653 case OP_IMUL_OVF_UN:
5654 case OP_LADD_OVF:
5655 case OP_LADD_OVF_UN:
5656 case OP_LSUB_OVF:
5657 case OP_LSUB_OVF_UN:
5658 case OP_LMUL_OVF:
5659 case OP_LMUL_OVF_UN:
5661 LLVMValueRef args [2], val, ovf, func;
5663 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5664 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5665 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5666 g_assert (func);
5667 val = LLVMBuildCall (builder, func, args, 2, "");
5668 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5669 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5670 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5671 if (!ctx_ok (ctx))
5672 break;
5673 builder = ctx->builder;
5674 break;
5678 * Valuetypes.
5679 * We currently model them using arrays. Promotion to local vregs is
5680 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5681 * so we always have an entry in cfg->varinfo for them.
5682 * FIXME: Is this needed ?
5684 case OP_VZERO: {
5685 MonoClass *klass = ins->klass;
5686 LLVMValueRef args [5];
5688 if (!klass) {
5689 // FIXME:
5690 set_failure (ctx, "!klass");
5691 break;
5694 if (!addresses [ins->dreg])
5695 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5696 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5697 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5698 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5699 // FIXME: Alignment
5700 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5701 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5702 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5703 break;
5705 case OP_DUMMY_VZERO:
5706 break;
5708 case OP_STOREV_MEMBASE:
5709 case OP_LOADV_MEMBASE:
5710 case OP_VMOVE: {
5711 MonoClass *klass = ins->klass;
5712 LLVMValueRef src = NULL, dst, args [5];
5713 gboolean done = FALSE;
5715 if (!klass) {
5716 // FIXME:
5717 set_failure (ctx, "!klass");
5718 break;
5721 if (mini_is_gsharedvt_klass (klass)) {
5722 // FIXME:
5723 set_failure (ctx, "gsharedvt");
5724 break;
5727 switch (ins->opcode) {
5728 case OP_STOREV_MEMBASE:
5729 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5730 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5731 /* Decomposed earlier */
5732 g_assert_not_reached ();
5733 break;
5735 if (!addresses [ins->sreg1]) {
5736 /* SIMD */
5737 g_assert (values [ins->sreg1]);
5738 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));
5739 LLVMBuildStore (builder, values [ins->sreg1], dst);
5740 done = TRUE;
5741 } else {
5742 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5743 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5745 break;
5746 case OP_LOADV_MEMBASE:
5747 if (!addresses [ins->dreg])
5748 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5749 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5750 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5751 break;
5752 case OP_VMOVE:
5753 if (!addresses [ins->sreg1])
5754 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5755 if (!addresses [ins->dreg])
5756 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5757 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5758 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5759 break;
5760 default:
5761 g_assert_not_reached ();
5763 if (!ctx_ok (ctx))
5764 break;
5766 if (done)
5767 break;
5769 args [0] = dst;
5770 args [1] = src;
5771 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5772 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5773 // FIXME: Alignment
5774 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5775 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5776 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5777 break;
5779 case OP_LLVM_OUTARG_VT: {
5780 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5781 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5783 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5784 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5786 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5787 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5788 } else {
5789 g_assert (addresses [ins->sreg1]);
5790 addresses [ins->dreg] = addresses [ins->sreg1];
5792 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5793 if (!addresses [ins->sreg1]) {
5794 addresses [ins->sreg1] = build_alloca (ctx, t);
5795 g_assert (values [ins->sreg1]);
5797 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5798 addresses [ins->dreg] = addresses [ins->sreg1];
5799 } else {
5800 if (!addresses [ins->sreg1]) {
5801 addresses [ins->sreg1] = build_alloca (ctx, t);
5802 g_assert (values [ins->sreg1]);
5803 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5805 addresses [ins->dreg] = addresses [ins->sreg1];
5807 break;
5809 case OP_OBJC_GET_SELECTOR: {
5810 const char *name = (const char*)ins->inst_p0;
5811 LLVMValueRef var;
5813 if (!ctx->module->objc_selector_to_var)
5814 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5815 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5816 if (!var) {
5817 LLVMValueRef indexes [16];
5819 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5820 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5821 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5822 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5823 mark_as_used (ctx->module, name_var);
5825 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5827 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5828 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5829 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5830 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5831 LLVMSetExternallyInitialized (ref_var, TRUE);
5832 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5833 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5834 mark_as_used (ctx->module, ref_var);
5836 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5837 var = ref_var;
5840 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5841 break;
5845 * SIMD
5847 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5848 case OP_XZERO: {
5849 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5850 break;
5852 case OP_LOADX_MEMBASE: {
5853 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5854 LLVMValueRef src;
5856 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5857 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5858 break;
5860 case OP_STOREX_MEMBASE: {
5861 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5862 LLVMValueRef dest;
5864 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5865 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5866 break;
5868 case OP_PADDB:
5869 case OP_PADDW:
5870 case OP_PADDD:
5871 case OP_PADDQ:
5872 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5873 break;
5874 case OP_ADDPD:
5875 case OP_ADDPS:
5876 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5877 break;
5878 case OP_PSUBB:
5879 case OP_PSUBW:
5880 case OP_PSUBD:
5881 case OP_PSUBQ:
5882 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5883 break;
5884 case OP_SUBPD:
5885 case OP_SUBPS:
5886 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5887 break;
5888 case OP_MULPD:
5889 case OP_MULPS:
5890 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5891 break;
5892 case OP_DIVPD:
5893 case OP_DIVPS:
5894 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5895 break;
5896 case OP_PAND:
5897 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5898 break;
5899 case OP_POR:
5900 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5901 break;
5902 case OP_PXOR:
5903 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5904 break;
5905 case OP_PMULW:
5906 case OP_PMULD:
5907 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5908 break;
5909 case OP_ANDPS:
5910 case OP_ANDNPS:
5911 case OP_ORPS:
5912 case OP_XORPS:
5913 case OP_ANDPD:
5914 case OP_ANDNPD:
5915 case OP_ORPD:
5916 case OP_XORPD: {
5917 LLVMTypeRef t, rt;
5918 LLVMValueRef v = NULL;
5920 switch (ins->opcode) {
5921 case OP_ANDPS:
5922 case OP_ANDNPS:
5923 case OP_ORPS:
5924 case OP_XORPS:
5925 t = LLVMVectorType (LLVMInt32Type (), 4);
5926 rt = LLVMVectorType (LLVMFloatType (), 4);
5927 break;
5928 case OP_ANDPD:
5929 case OP_ANDNPD:
5930 case OP_ORPD:
5931 case OP_XORPD:
5932 t = LLVMVectorType (LLVMInt64Type (), 2);
5933 rt = LLVMVectorType (LLVMDoubleType (), 2);
5934 break;
5935 default:
5936 t = LLVMInt32Type ();
5937 rt = LLVMInt32Type ();
5938 g_assert_not_reached ();
5941 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5942 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5943 switch (ins->opcode) {
5944 case OP_ANDPS:
5945 case OP_ANDPD:
5946 v = LLVMBuildAnd (builder, lhs, rhs, "");
5947 break;
5948 case OP_ORPS:
5949 case OP_ORPD:
5950 v = LLVMBuildOr (builder, lhs, rhs, "");
5951 break;
5952 case OP_XORPS:
5953 case OP_XORPD:
5954 v = LLVMBuildXor (builder, lhs, rhs, "");
5955 break;
5956 case OP_ANDNPS:
5957 case OP_ANDNPD:
5958 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5959 break;
5961 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5962 break;
5964 case OP_PMIND_UN:
5965 case OP_PMINW_UN:
5966 case OP_PMINB_UN: {
5967 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5968 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5969 break;
5971 case OP_PMAXD_UN:
5972 case OP_PMAXW_UN:
5973 case OP_PMAXB_UN: {
5974 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
5975 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5976 break;
5978 case OP_PMINW: {
5979 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
5980 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5981 break;
5983 case OP_MINPD:
5984 case OP_MINPS:
5985 case OP_MAXPD:
5986 case OP_MAXPS:
5987 case OP_ADDSUBPD:
5988 case OP_ADDSUBPS:
5989 case OP_HADDPD:
5990 case OP_HADDPS:
5991 case OP_HSUBPD:
5992 case OP_HSUBPS:
5993 case OP_PADDB_SAT:
5994 case OP_PADDW_SAT:
5995 case OP_PSUBB_SAT:
5996 case OP_PSUBW_SAT:
5997 case OP_PADDB_SAT_UN:
5998 case OP_PADDW_SAT_UN:
5999 case OP_PSUBB_SAT_UN:
6000 case OP_PSUBW_SAT_UN:
6001 case OP_PAVGB_UN:
6002 case OP_PAVGW_UN:
6003 case OP_PACKW:
6004 case OP_PACKD:
6005 case OP_PACKW_UN:
6006 case OP_PACKD_UN:
6007 case OP_PMULW_HIGH:
6008 case OP_PMULW_HIGH_UN: {
6009 LLVMValueRef args [2];
6011 args [0] = lhs;
6012 args [1] = rhs;
6014 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6015 break;
6017 case OP_PCMPEQB:
6018 case OP_PCMPEQW:
6019 case OP_PCMPEQD:
6020 case OP_PCMPEQQ: {
6021 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6022 break;
6024 case OP_PCMPGTB: {
6025 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6026 break;
6028 case OP_EXTRACT_R8:
6029 case OP_EXTRACT_I8:
6030 case OP_EXTRACT_I4:
6031 case OP_EXTRACT_I2:
6032 case OP_EXTRACT_U2:
6033 case OP_EXTRACTX_U2:
6034 case OP_EXTRACT_I1:
6035 case OP_EXTRACT_U1: {
6036 LLVMTypeRef t;
6037 gboolean zext = FALSE;
6039 t = simd_op_to_llvm_type (ins->opcode);
6041 switch (ins->opcode) {
6042 case OP_EXTRACT_R8:
6043 case OP_EXTRACT_I8:
6044 case OP_EXTRACT_I4:
6045 case OP_EXTRACT_I2:
6046 case OP_EXTRACT_I1:
6047 break;
6048 case OP_EXTRACT_U2:
6049 case OP_EXTRACTX_U2:
6050 case OP_EXTRACT_U1:
6051 zext = TRUE;
6052 break;
6053 default:
6054 t = LLVMInt32Type ();
6055 g_assert_not_reached ();
6058 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6059 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6060 if (zext)
6061 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6062 break;
6065 case OP_EXPAND_I1:
6066 case OP_EXPAND_I2:
6067 case OP_EXPAND_I4:
6068 case OP_EXPAND_I8:
6069 case OP_EXPAND_R4:
6070 case OP_EXPAND_R8: {
6071 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6072 LLVMValueRef mask [16], v;
6073 int i;
6075 for (i = 0; i < 16; ++i)
6076 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6078 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6080 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6081 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6082 break;
6085 case OP_INSERT_I1:
6086 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6087 break;
6088 case OP_INSERT_I2:
6089 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6090 break;
6091 case OP_INSERT_I4:
6092 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6093 break;
6094 case OP_INSERT_I8:
6095 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6096 break;
6097 case OP_INSERT_R4:
6098 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6099 break;
6100 case OP_INSERT_R8:
6101 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6102 break;
6104 #if 0
6105 // Requires a later llvm version
6106 case OP_CVTDQ2PD: {
6107 LLVMValueRef indexes [16];
6109 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6110 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6111 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6112 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6113 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6114 break;
6116 case OP_CVTPS2PD: {
6117 LLVMValueRef indexes [16];
6119 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6120 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6121 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6122 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6123 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6124 break;
6126 case OP_CVTTPS2DQ:
6127 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6128 break;
6129 #endif
6131 case OP_CVTDQ2PD:
6132 case OP_CVTDQ2PS:
6133 case OP_CVTPD2DQ:
6134 case OP_CVTPS2DQ:
6135 case OP_CVTPD2PS:
6136 case OP_CVTPS2PD:
6137 case OP_CVTTPD2DQ:
6138 case OP_CVTTPS2DQ:
6139 case OP_EXTRACT_MASK:
6140 case OP_SQRTPS:
6141 case OP_SQRTPD:
6142 case OP_RSQRTPS:
6143 case OP_RCPPS: {
6144 LLVMValueRef v;
6146 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6148 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6149 break;
6151 case OP_COMPPS:
6152 case OP_COMPPD: {
6153 LLVMRealPredicate op;
6155 switch (ins->inst_c0) {
6156 case SIMD_COMP_EQ:
6157 op = LLVMRealOEQ;
6158 break;
6159 case SIMD_COMP_LT:
6160 op = LLVMRealOLT;
6161 break;
6162 case SIMD_COMP_LE:
6163 op = LLVMRealOLE;
6164 break;
6165 case SIMD_COMP_UNORD:
6166 op = LLVMRealUNO;
6167 break;
6168 case SIMD_COMP_NEQ:
6169 op = LLVMRealUNE;
6170 break;
6171 case SIMD_COMP_NLT:
6172 op = LLVMRealUGE;
6173 break;
6174 case SIMD_COMP_NLE:
6175 op = LLVMRealUGT;
6176 break;
6177 case SIMD_COMP_ORD:
6178 op = LLVMRealORD;
6179 break;
6180 default:
6181 g_assert_not_reached ();
6184 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6185 if (ins->opcode == OP_COMPPD)
6186 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6187 else
6188 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6189 break;
6191 case OP_ICONV_TO_X:
6192 /* This is only used for implementing shifts by non-immediate */
6193 values [ins->dreg] = lhs;
6194 break;
6196 case OP_PSHRW:
6197 case OP_PSHRD:
6198 case OP_PSHRQ:
6199 case OP_PSARW:
6200 case OP_PSARD:
6201 case OP_PSHLW:
6202 case OP_PSHLD:
6203 case OP_PSHLQ: {
6204 LLVMValueRef args [3];
6206 args [0] = lhs;
6207 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6209 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6210 break;
6213 case OP_PSHRW_REG:
6214 case OP_PSHRD_REG:
6215 case OP_PSHRQ_REG:
6216 case OP_PSARW_REG:
6217 case OP_PSARD_REG:
6218 case OP_PSHLW_REG:
6219 case OP_PSHLD_REG:
6220 case OP_PSHLQ_REG: {
6221 LLVMValueRef args [3];
6223 args [0] = lhs;
6224 args [1] = values [ins->sreg2];
6226 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6227 break;
6230 case OP_SHUFPS:
6231 case OP_SHUFPD:
6232 case OP_PSHUFLED:
6233 case OP_PSHUFLEW_LOW:
6234 case OP_PSHUFLEW_HIGH: {
6235 int mask [16];
6236 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6237 int i, mask_size = 0;
6238 int imask = ins->inst_c0;
6240 /* Convert the x86 shuffle mask to LLVM's */
6241 switch (ins->opcode) {
6242 case OP_SHUFPS:
6243 mask_size = 4;
6244 mask [0] = ((imask >> 0) & 3);
6245 mask [1] = ((imask >> 2) & 3);
6246 mask [2] = ((imask >> 4) & 3) + 4;
6247 mask [3] = ((imask >> 6) & 3) + 4;
6248 v1 = values [ins->sreg1];
6249 v2 = values [ins->sreg2];
6250 break;
6251 case OP_SHUFPD:
6252 mask_size = 2;
6253 mask [0] = ((imask >> 0) & 1);
6254 mask [1] = ((imask >> 1) & 1) + 2;
6255 v1 = values [ins->sreg1];
6256 v2 = values [ins->sreg2];
6257 break;
6258 case OP_PSHUFLEW_LOW:
6259 mask_size = 8;
6260 mask [0] = ((imask >> 0) & 3);
6261 mask [1] = ((imask >> 2) & 3);
6262 mask [2] = ((imask >> 4) & 3);
6263 mask [3] = ((imask >> 6) & 3);
6264 mask [4] = 4 + 0;
6265 mask [5] = 4 + 1;
6266 mask [6] = 4 + 2;
6267 mask [7] = 4 + 3;
6268 v1 = values [ins->sreg1];
6269 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6270 break;
6271 case OP_PSHUFLEW_HIGH:
6272 mask_size = 8;
6273 mask [0] = 0;
6274 mask [1] = 1;
6275 mask [2] = 2;
6276 mask [3] = 3;
6277 mask [4] = 4 + ((imask >> 0) & 3);
6278 mask [5] = 4 + ((imask >> 2) & 3);
6279 mask [6] = 4 + ((imask >> 4) & 3);
6280 mask [7] = 4 + ((imask >> 6) & 3);
6281 v1 = values [ins->sreg1];
6282 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6283 break;
6284 case OP_PSHUFLED:
6285 mask_size = 4;
6286 mask [0] = ((imask >> 0) & 3);
6287 mask [1] = ((imask >> 2) & 3);
6288 mask [2] = ((imask >> 4) & 3);
6289 mask [3] = ((imask >> 6) & 3);
6290 v1 = values [ins->sreg1];
6291 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6292 break;
6293 default:
6294 g_assert_not_reached ();
6296 for (i = 0; i < mask_size; ++i)
6297 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6299 values [ins->dreg] =
6300 LLVMBuildShuffleVector (builder, v1, v2,
6301 LLVMConstVector (mask_values, mask_size), dname);
6302 break;
6305 case OP_UNPACK_LOWB:
6306 case OP_UNPACK_LOWW:
6307 case OP_UNPACK_LOWD:
6308 case OP_UNPACK_LOWQ:
6309 case OP_UNPACK_LOWPS:
6310 case OP_UNPACK_LOWPD:
6311 case OP_UNPACK_HIGHB:
6312 case OP_UNPACK_HIGHW:
6313 case OP_UNPACK_HIGHD:
6314 case OP_UNPACK_HIGHQ:
6315 case OP_UNPACK_HIGHPS:
6316 case OP_UNPACK_HIGHPD: {
6317 int mask [16];
6318 LLVMValueRef mask_values [16];
6319 int i, mask_size = 0;
6320 gboolean low = FALSE;
6322 switch (ins->opcode) {
6323 case OP_UNPACK_LOWB:
6324 mask_size = 16;
6325 low = TRUE;
6326 break;
6327 case OP_UNPACK_LOWW:
6328 mask_size = 8;
6329 low = TRUE;
6330 break;
6331 case OP_UNPACK_LOWD:
6332 case OP_UNPACK_LOWPS:
6333 mask_size = 4;
6334 low = TRUE;
6335 break;
6336 case OP_UNPACK_LOWQ:
6337 case OP_UNPACK_LOWPD:
6338 mask_size = 2;
6339 low = TRUE;
6340 break;
6341 case OP_UNPACK_HIGHB:
6342 mask_size = 16;
6343 break;
6344 case OP_UNPACK_HIGHW:
6345 mask_size = 8;
6346 break;
6347 case OP_UNPACK_HIGHD:
6348 case OP_UNPACK_HIGHPS:
6349 mask_size = 4;
6350 break;
6351 case OP_UNPACK_HIGHQ:
6352 case OP_UNPACK_HIGHPD:
6353 mask_size = 2;
6354 break;
6355 default:
6356 g_assert_not_reached ();
6359 if (low) {
6360 for (i = 0; i < (mask_size / 2); ++i) {
6361 mask [(i * 2)] = i;
6362 mask [(i * 2) + 1] = mask_size + i;
6364 } else {
6365 for (i = 0; i < (mask_size / 2); ++i) {
6366 mask [(i * 2)] = (mask_size / 2) + i;
6367 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6371 for (i = 0; i < mask_size; ++i)
6372 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6374 values [ins->dreg] =
6375 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6376 LLVMConstVector (mask_values, mask_size), dname);
6377 break;
6380 case OP_DUPPD: {
6381 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6382 LLVMValueRef v, val;
6384 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6385 val = LLVMConstNull (t);
6386 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6387 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6389 values [ins->dreg] = val;
6390 break;
6392 case OP_DUPPS_LOW:
6393 case OP_DUPPS_HIGH: {
6394 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6395 LLVMValueRef v1, v2, val;
6398 if (ins->opcode == OP_DUPPS_LOW) {
6399 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6400 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6401 } else {
6402 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6403 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6405 val = LLVMConstNull (t);
6406 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6407 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6408 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6409 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6411 values [ins->dreg] = val;
6412 break;
6415 #endif /* SIMD */
6417 case OP_DUMMY_USE:
6418 break;
6421 * EXCEPTION HANDLING
6423 case OP_IMPLICIT_EXCEPTION:
6424 /* This marks a place where an implicit exception can happen */
6425 if (bb->region != -1)
6426 set_failure (ctx, "implicit-exception");
6427 break;
6428 case OP_THROW:
6429 case OP_RETHROW: {
6430 gboolean rethrow = (ins->opcode == OP_RETHROW);
6431 if (ctx->llvm_only) {
6432 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6433 has_terminator = TRUE;
6434 ctx->unreachable [bb->block_num] = TRUE;
6435 } else {
6436 emit_throw (ctx, bb, rethrow, lhs);
6437 builder = ctx->builder;
6439 break;
6441 case OP_CALL_HANDLER: {
6443 * We don't 'call' handlers, but instead simply branch to them.
6444 * The code generated by ENDFINALLY will branch back to us.
6446 LLVMBasicBlockRef noex_bb;
6447 GSList *bb_list;
6448 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6450 bb_list = info->call_handler_return_bbs;
6453 * Set the indicator variable for the finally clause.
6455 lhs = info->finally_ind;
6456 g_assert (lhs);
6457 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6459 /* Branch to the finally clause */
6460 LLVMBuildBr (builder, info->call_handler_target_bb);
6462 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6463 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6465 builder = ctx->builder = create_builder (ctx);
6466 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6468 bblocks [bb->block_num].end_bblock = noex_bb;
6469 break;
6471 case OP_START_HANDLER: {
6472 break;
6474 case OP_ENDFINALLY: {
6475 LLVMBasicBlockRef resume_bb;
6476 MonoBasicBlock *handler_bb;
6477 LLVMValueRef val, switch_ins, callee;
6478 GSList *bb_list;
6479 BBInfo *info;
6481 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6482 g_assert (handler_bb);
6483 info = &bblocks [handler_bb->block_num];
6484 lhs = info->finally_ind;
6485 g_assert (lhs);
6487 bb_list = info->call_handler_return_bbs;
6489 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6491 /* Load the finally variable */
6492 val = LLVMBuildLoad (builder, lhs, "");
6494 /* Reset the variable */
6495 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6497 /* Branch to either resume_bb, or to the bblocks in bb_list */
6498 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6500 * The other targets are added at the end to handle OP_CALL_HANDLER
6501 * opcodes processed later.
6503 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6505 builder = ctx->builder = create_builder (ctx);
6506 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6508 if (ctx->llvm_only) {
6509 emit_resume_eh (ctx, bb);
6510 } else {
6511 if (ctx->cfg->compile_aot) {
6512 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6513 } else {
6514 #if LLVM_API_VERSION > 100
6515 MonoJitICallInfo *info;
6517 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6518 g_assert (info);
6519 gpointer target = (void*)info->func;
6520 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6521 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6522 #else
6523 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6524 #endif
6526 LLVMBuildCall (builder, callee, NULL, 0, "");
6527 LLVMBuildUnreachable (builder);
6530 has_terminator = TRUE;
6531 break;
6533 case OP_IL_SEQ_POINT:
6534 break;
6535 default: {
6536 char reason [128];
6538 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6539 set_failure (ctx, reason);
6540 break;
6544 if (!ctx_ok (ctx))
6545 break;
6547 /* Convert the value to the type required by phi nodes */
6548 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6549 if (ctx->is_vphi [ins->dreg])
6550 /* vtypes */
6551 values [ins->dreg] = addresses [ins->dreg];
6552 else
6553 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6556 /* Add stores for volatile variables */
6557 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6558 emit_volatile_store (ctx, ins->dreg);
6561 if (!ctx_ok (ctx))
6562 return;
6564 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6565 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6568 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6569 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6570 LLVMBuildRetVoid (builder);
6573 if (bb == cfg->bb_entry)
6574 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6578 * mono_llvm_check_method_supported:
6580 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6581 * compiling a method twice.
6583 void
6584 mono_llvm_check_method_supported (MonoCompile *cfg)
6586 int i, j;
6588 if (cfg->llvm_only)
6589 return;
6591 if (cfg->method->save_lmf) {
6592 cfg->exception_message = g_strdup ("lmf");
6593 cfg->disable_llvm = TRUE;
6595 if (cfg->disable_llvm)
6596 return;
6599 * Nested clauses where one of the clauses is a finally clause is
6600 * not supported, because LLVM can't figure out the control flow,
6601 * probably because we resume exception handling by calling our
6602 * own function instead of using the 'resume' llvm instruction.
6604 for (i = 0; i < cfg->header->num_clauses; ++i) {
6605 for (j = 0; j < cfg->header->num_clauses; ++j) {
6606 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6607 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6609 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6610 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6611 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6612 cfg->exception_message = g_strdup ("nested clauses");
6613 cfg->disable_llvm = TRUE;
6614 break;
6618 if (cfg->disable_llvm)
6619 return;
6621 /* FIXME: */
6622 if (cfg->method->dynamic) {
6623 cfg->exception_message = g_strdup ("dynamic.");
6624 cfg->disable_llvm = TRUE;
6626 if (cfg->disable_llvm)
6627 return;
6630 static LLVMCallInfo*
6631 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6633 LLVMCallInfo *linfo;
6634 int i;
6636 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6637 int i, n, pindex;
6640 * Gsharedvt methods have the following calling convention:
6641 * - all arguments are passed by ref, even non generic ones
6642 * - the return value is returned by ref too, using a vret
6643 * argument passed after 'this'.
6645 n = sig->param_count + sig->hasthis;
6646 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6648 pindex = 0;
6649 if (sig->hasthis)
6650 linfo->args [pindex ++].storage = LLVMArgNormal;
6652 if (sig->ret->type != MONO_TYPE_VOID) {
6653 if (mini_is_gsharedvt_variable_type (sig->ret))
6654 linfo->ret.storage = LLVMArgGsharedvtVariable;
6655 else if (mini_type_is_vtype (sig->ret))
6656 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6657 else
6658 linfo->ret.storage = LLVMArgGsharedvtFixed;
6659 linfo->vret_arg_index = pindex;
6660 } else {
6661 linfo->ret.storage = LLVMArgNone;
6664 for (i = 0; i < sig->param_count; ++i) {
6665 if (sig->params [i]->byref)
6666 linfo->args [pindex].storage = LLVMArgNormal;
6667 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6668 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6669 else if (mini_type_is_vtype (sig->params [i]))
6670 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6671 else
6672 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6673 linfo->args [pindex].type = sig->params [i];
6674 pindex ++;
6676 return linfo;
6680 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6681 for (i = 0; i < sig->param_count; ++i)
6682 linfo->args [i + sig->hasthis].type = sig->params [i];
6684 return linfo;
6687 static void
6688 emit_method_inner (EmitContext *ctx);
6690 static void
6691 free_ctx (EmitContext *ctx)
6693 GSList *l;
6695 g_free (ctx->values);
6696 g_free (ctx->addresses);
6697 g_free (ctx->vreg_types);
6698 g_free (ctx->is_vphi);
6699 g_free (ctx->vreg_cli_types);
6700 g_free (ctx->is_dead);
6701 g_free (ctx->unreachable);
6702 g_ptr_array_free (ctx->phi_values, TRUE);
6703 g_free (ctx->bblocks);
6704 g_hash_table_destroy (ctx->region_to_handler);
6705 g_hash_table_destroy (ctx->clause_to_handler);
6706 g_hash_table_destroy (ctx->jit_callees);
6708 GHashTableIter iter;
6709 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6710 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6711 g_slist_free (l);
6713 g_hash_table_destroy (ctx->method_to_callers);
6715 g_free (ctx->method_name);
6716 g_ptr_array_free (ctx->bblock_list, TRUE);
6718 for (l = ctx->builders; l; l = l->next) {
6719 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6720 LLVMDisposeBuilder (builder);
6723 g_free (ctx);
6727 * mono_llvm_emit_method:
6729 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6731 void
6732 mono_llvm_emit_method (MonoCompile *cfg)
6734 EmitContext *ctx;
6735 char *method_name;
6736 gboolean is_linkonce = FALSE;
6737 int i;
6739 /* The code below might acquire the loader lock, so use it for global locking */
6740 mono_loader_lock ();
6742 /* Used to communicate with the callbacks */
6743 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6745 ctx = g_new0 (EmitContext, 1);
6746 ctx->cfg = cfg;
6747 ctx->mempool = cfg->mempool;
6750 * This maps vregs to the LLVM instruction defining them
6752 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6754 * This maps vregs for volatile variables to the LLVM instruction defining their
6755 * address.
6757 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6758 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6759 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6760 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6761 ctx->phi_values = g_ptr_array_sized_new (256);
6763 * This signals whenever the vreg was defined by a phi node with no input vars
6764 * (i.e. all its input bblocks end with NOT_REACHABLE).
6766 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6767 /* Whenever the bblock is unreachable */
6768 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6769 ctx->bblock_list = g_ptr_array_sized_new (256);
6771 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6772 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6773 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6774 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6775 if (cfg->compile_aot) {
6776 ctx->module = &aot_module;
6778 method_name = NULL;
6780 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6781 * linkage for them. This requires the following:
6782 * - the method needs to have a unique mangled name
6783 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6785 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6786 if (is_linkonce) {
6787 method_name = mono_aot_get_mangled_method_name (cfg->method);
6788 if (!method_name)
6789 is_linkonce = FALSE;
6791 if (method_name)
6792 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6793 else
6794 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6797 if (!method_name)
6798 method_name = mono_aot_get_method_name (cfg);
6799 cfg->llvm_method_name = g_strdup (method_name);
6800 } else {
6801 init_jit_module (cfg->domain);
6802 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6803 method_name = mono_method_full_name (cfg->method, TRUE);
6805 ctx->method_name = method_name;
6806 ctx->is_linkonce = is_linkonce;
6808 #if LLVM_API_VERSION > 100
6809 if (cfg->compile_aot)
6810 ctx->lmodule = ctx->module->lmodule;
6811 else
6812 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6813 #else
6814 ctx->lmodule = ctx->module->lmodule;
6815 #endif
6816 ctx->llvm_only = ctx->module->llvm_only;
6818 emit_method_inner (ctx);
6820 if (!ctx_ok (ctx)) {
6821 if (ctx->lmethod) {
6822 /* Need to add unused phi nodes as they can be referenced by other values */
6823 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6824 LLVMBuilderRef builder;
6826 builder = create_builder (ctx);
6827 LLVMPositionBuilderAtEnd (builder, phi_bb);
6829 for (i = 0; i < ctx->phi_values->len; ++i) {
6830 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6831 if (LLVMGetInstructionParent (v) == NULL)
6832 LLVMInsertIntoBuilder (builder, v);
6835 LLVMDeleteFunction (ctx->lmethod);
6839 free_ctx (ctx);
6841 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6843 mono_loader_unlock ();
6846 static void
6847 emit_method_inner (EmitContext *ctx)
6849 MonoCompile *cfg = ctx->cfg;
6850 MonoMethodSignature *sig;
6851 MonoBasicBlock *bb;
6852 LLVMTypeRef method_type;
6853 LLVMValueRef method = NULL;
6854 LLVMValueRef *values = ctx->values;
6855 int i, max_block_num, bb_index;
6856 gboolean last = FALSE;
6857 LLVMCallInfo *linfo;
6858 LLVMModuleRef lmodule = ctx->lmodule;
6859 BBInfo *bblocks;
6860 GPtrArray *bblock_list = ctx->bblock_list;
6861 MonoMethodHeader *header;
6862 MonoExceptionClause *clause;
6863 char **names;
6865 if (cfg->gsharedvt && !cfg->llvm_only) {
6866 set_failure (ctx, "gsharedvt");
6867 return;
6870 #if 1
6872 static int count = 0;
6873 count ++;
6875 if (g_getenv ("LLVM_COUNT")) {
6876 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6877 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6878 fflush (stdout);
6879 last = TRUE;
6881 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6882 set_failure (ctx, "count");
6883 return;
6887 #endif
6889 sig = mono_method_signature (cfg->method);
6890 ctx->sig = sig;
6892 linfo = get_llvm_call_info (cfg, sig);
6893 ctx->linfo = linfo;
6894 if (!ctx_ok (ctx))
6895 return;
6897 if (cfg->rgctx_var)
6898 linfo->rgctx_arg = TRUE;
6899 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6900 if (!ctx_ok (ctx))
6901 return;
6903 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6904 ctx->lmethod = method;
6906 if (!cfg->llvm_only)
6907 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6908 LLVMSetLinkage (method, LLVMPrivateLinkage);
6910 LLVMAddFunctionAttr (method, LLVMUWTable);
6912 if (cfg->compile_aot) {
6913 LLVMSetLinkage (method, LLVMInternalLinkage);
6914 if (ctx->module->external_symbols) {
6915 LLVMSetLinkage (method, LLVMExternalLinkage);
6916 LLVMSetVisibility (method, LLVMHiddenVisibility);
6918 if (ctx->is_linkonce) {
6919 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6920 LLVMSetVisibility (method, LLVMDefaultVisibility);
6922 } else {
6923 #if LLVM_API_VERSION > 100
6924 LLVMSetLinkage (method, LLVMExternalLinkage);
6925 #else
6926 LLVMSetLinkage (method, LLVMPrivateLinkage);
6927 #endif
6930 if (cfg->method->save_lmf && !cfg->llvm_only) {
6931 set_failure (ctx, "lmf");
6932 return;
6935 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6936 set_failure (ctx, "pinvoke signature");
6937 return;
6940 header = cfg->header;
6941 for (i = 0; i < header->num_clauses; ++i) {
6942 clause = &header->clauses [i];
6943 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6944 set_failure (ctx, "non-finally/catch clause.");
6945 return;
6948 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6949 /* We can't handle inlined methods with clauses */
6950 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6952 if (linfo->rgctx_arg) {
6953 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6954 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6956 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6957 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6958 * CC_X86_64_Mono in X86CallingConv.td.
6960 if (!ctx->llvm_only)
6961 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6962 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6963 } else {
6964 ctx->rgctx_arg_pindex = -1;
6966 if (cfg->vret_addr) {
6967 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6968 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6969 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6970 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6971 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6975 if (sig->hasthis) {
6976 ctx->this_arg_pindex = linfo->this_arg_pindex;
6977 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6978 values [cfg->args [0]->dreg] = ctx->this_arg;
6979 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6982 names = g_new (char *, sig->param_count);
6983 mono_method_get_param_names (cfg->method, (const char **) names);
6985 /* Set parameter names/attributes */
6986 for (i = 0; i < sig->param_count; ++i) {
6987 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6988 char *name;
6989 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6990 int j;
6992 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6993 name = g_strdup_printf ("dummy_%d_%d", i, j);
6994 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6995 g_free (name);
6998 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
6999 continue;
7001 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7002 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7003 if (names [i] && names [i][0] != '\0')
7004 name = g_strdup_printf ("p_arg_%s", names [i]);
7005 else
7006 name = g_strdup_printf ("p_arg_%d", i);
7007 } else {
7008 if (names [i] && names [i][0] != '\0')
7009 name = g_strdup_printf ("arg_%s", names [i]);
7010 else
7011 name = g_strdup_printf ("arg_%d", i);
7013 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7014 g_free (name);
7015 if (ainfo->storage == LLVMArgVtypeByVal)
7016 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7018 if (ainfo->storage == LLVMArgVtypeByRef) {
7019 /* For OP_LDADDR */
7020 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7023 g_free (names);
7025 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7026 ctx->minfo = mono_debug_lookup_method (cfg->method);
7027 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7030 max_block_num = 0;
7031 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7032 max_block_num = MAX (max_block_num, bb->block_num);
7033 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7035 /* Add branches between non-consecutive bblocks */
7036 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7037 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7038 bb->next_bb != bb->last_ins->inst_false_bb) {
7040 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7041 inst->opcode = OP_BR;
7042 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7043 mono_bblock_add_inst (bb, inst);
7048 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7049 * was later optimized away, so clear these flags, and add them back for the still
7050 * present OP_LDADDR instructions.
7052 for (i = 0; i < cfg->next_vreg; ++i) {
7053 MonoInst *ins;
7055 ins = get_vreg_to_inst (cfg, i);
7056 if (ins && ins != cfg->rgctx_var)
7057 ins->flags &= ~MONO_INST_INDIRECT;
7061 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7063 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7064 MonoInst *ins;
7065 LLVMBuilderRef builder;
7066 char *dname;
7067 char dname_buf[128];
7069 builder = create_builder (ctx);
7071 for (ins = bb->code; ins; ins = ins->next) {
7072 switch (ins->opcode) {
7073 case OP_PHI:
7074 case OP_FPHI:
7075 case OP_VPHI:
7076 case OP_XPHI: {
7077 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7079 if (!ctx_ok (ctx))
7080 return;
7082 if (ins->opcode == OP_VPHI) {
7083 /* Treat valuetype PHI nodes as operating on the address itself */
7084 g_assert (ins->klass);
7085 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7089 * Have to precreate these, as they can be referenced by
7090 * earlier instructions.
7092 sprintf (dname_buf, "t%d", ins->dreg);
7093 dname = dname_buf;
7094 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7096 if (ins->opcode == OP_VPHI)
7097 ctx->addresses [ins->dreg] = values [ins->dreg];
7099 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7102 * Set the expected type of the incoming arguments since these have
7103 * to have the same type.
7105 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7106 int sreg1 = ins->inst_phi_args [i + 1];
7108 if (sreg1 != -1) {
7109 if (ins->opcode == OP_VPHI)
7110 ctx->is_vphi [sreg1] = TRUE;
7111 ctx->vreg_types [sreg1] = phi_type;
7114 break;
7116 case OP_LDADDR:
7117 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7118 break;
7119 default:
7120 break;
7126 * Create an ordering for bblocks, use the depth first order first, then
7127 * put the exception handling bblocks last.
7129 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7130 bb = cfg->bblocks [bb_index];
7131 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7132 g_ptr_array_add (bblock_list, bb);
7133 bblocks [bb->block_num].added = TRUE;
7137 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7138 if (!bblocks [bb->block_num].added)
7139 g_ptr_array_add (bblock_list, bb);
7143 * Second pass: generate code.
7145 // Emit entry point
7146 LLVMBuilderRef entry_builder = create_builder (ctx);
7147 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7148 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7149 emit_entry_bb (ctx, entry_builder);
7151 // Make landing pads first
7152 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7154 if (ctx->llvm_only) {
7155 size_t group_index = 0;
7156 while (group_index < cfg->header->num_clauses) {
7157 int count = 0;
7158 size_t cursor = group_index;
7159 while (cursor < cfg->header->num_clauses &&
7160 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7161 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7162 count++;
7163 cursor++;
7166 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7167 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7168 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7170 group_index = cursor;
7174 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7175 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7177 // Prune unreachable mono BBs.
7178 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7179 continue;
7181 process_bb (ctx, bb);
7182 if (!ctx_ok (ctx))
7183 return;
7185 g_hash_table_destroy (ctx->exc_meta);
7187 mono_memory_barrier ();
7189 /* Add incoming phi values */
7190 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7191 GSList *l, *ins_list;
7193 ins_list = bblocks [bb->block_num].phi_nodes;
7195 for (l = ins_list; l; l = l->next) {
7196 PhiNode *node = (PhiNode*)l->data;
7197 MonoInst *phi = node->phi;
7198 int sreg1 = node->sreg;
7199 LLVMBasicBlockRef in_bb;
7201 if (sreg1 == -1)
7202 continue;
7204 in_bb = get_end_bb (ctx, node->in_bb);
7206 if (ctx->unreachable [node->in_bb->block_num])
7207 continue;
7209 if (!values [sreg1]) {
7210 /* Can happen with values in EH clauses */
7211 set_failure (ctx, "incoming phi sreg1");
7212 return;
7215 if (phi->opcode == OP_VPHI) {
7216 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7217 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7218 } else {
7219 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7220 set_failure (ctx, "incoming phi arg type mismatch");
7221 return;
7223 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7224 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7229 /* Nullify empty phi instructions */
7230 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7231 GSList *l, *ins_list;
7233 ins_list = bblocks [bb->block_num].phi_nodes;
7235 for (l = ins_list; l; l = l->next) {
7236 PhiNode *node = (PhiNode*)l->data;
7237 MonoInst *phi = node->phi;
7238 LLVMValueRef phi_ins = values [phi->dreg];
7240 if (!phi_ins)
7241 /* Already removed */
7242 continue;
7244 if (LLVMCountIncoming (phi_ins) == 0) {
7245 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7246 LLVMInstructionEraseFromParent (phi_ins);
7247 values [phi->dreg] = NULL;
7252 /* Create the SWITCH statements for ENDFINALLY instructions */
7253 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7254 BBInfo *info = &bblocks [bb->block_num];
7255 GSList *l;
7256 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7257 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7258 GSList *bb_list = info->call_handler_return_bbs;
7260 for (i = 0; i < g_slist_length (bb_list); ++i)
7261 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7265 /* Initialize the method if needed */
7266 if (cfg->compile_aot && ctx->llvm_only) {
7267 // FIXME: Add more shared got entries
7268 ctx->builder = create_builder (ctx);
7269 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7271 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7273 // FIXME: beforefieldinit
7275 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7276 * in load_method ().
7278 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7280 * linkonce methods shouldn't have initialization,
7281 * because they might belong to assemblies which
7282 * haven't been loaded yet.
7284 g_assert (!ctx->is_linkonce);
7285 emit_init_method (ctx);
7286 } else {
7287 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7291 if (cfg->llvm_only) {
7292 GHashTableIter iter;
7293 MonoMethod *method;
7294 GSList *callers, *l, *l2;
7297 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7298 * We can't do this earlier, as it contains llvm instructions which can be
7299 * freed if compilation fails.
7300 * FIXME: Get rid of this when all methods can be llvm compiled.
7302 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7303 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7304 for (l = callers; l; l = l->next) {
7305 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7306 l2 = g_slist_prepend (l2, l->data);
7307 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7312 if (cfg->verbose_level > 1)
7313 mono_llvm_dump_value (method);
7315 if (cfg->compile_aot && !cfg->llvm_only)
7316 mark_as_used (ctx->module, method);
7318 if (!cfg->llvm_only) {
7319 LLVMValueRef md_args [16];
7320 LLVMValueRef md_node;
7321 int method_index;
7323 if (cfg->compile_aot)
7324 method_index = mono_aot_get_method_index (cfg->orig_method);
7325 else
7326 method_index = 1;
7327 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7328 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7329 md_node = LLVMMDNode (md_args, 2);
7330 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7331 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7334 if (cfg->compile_aot) {
7335 /* Don't generate native code, keep the LLVM IR */
7336 if (cfg->verbose_level)
7337 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7339 #if LLVM_API_VERSION < 100
7340 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7341 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7342 g_assert (err == 0);
7343 #endif
7344 } else {
7345 //LLVMVerifyFunction(method, 0);
7346 #if LLVM_API_VERSION > 100
7347 MonoDomain *domain = mono_domain_get ();
7348 MonoJitDomainInfo *domain_info;
7349 int nvars = g_hash_table_size (ctx->jit_callees);
7350 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7351 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7352 GHashTableIter iter;
7353 LLVMValueRef var;
7354 MonoMethod *callee;
7355 gpointer eh_frame;
7358 * Compute the addresses of the LLVM globals pointing to the
7359 * methods called by the current method. Pass it to the trampoline
7360 * code so it can update them after their corresponding method was
7361 * compiled.
7363 g_hash_table_iter_init (&iter, ctx->jit_callees);
7364 i = 0;
7365 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7366 callee_vars [i ++] = var;
7368 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7370 decode_llvm_eh_info (ctx, eh_frame);
7372 mono_domain_lock (domain);
7373 domain_info = domain_jit_info (domain);
7374 if (!domain_info->llvm_jit_callees)
7375 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7376 g_hash_table_iter_init (&iter, ctx->jit_callees);
7377 i = 0;
7378 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7379 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7380 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7381 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7382 i ++;
7384 mono_domain_unlock (domain);
7385 #else
7386 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7388 if (cfg->verbose_level > 1)
7389 mono_llvm_dump_value (ctx->lmethod);
7391 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7393 /* Set by emit_cb */
7394 g_assert (cfg->code_len);
7395 #endif
7398 if (ctx->module->method_to_lmethod)
7399 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7400 if (ctx->module->idx_to_lmethod)
7401 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7403 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7404 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7408 * mono_llvm_create_vars:
7410 * Same as mono_arch_create_vars () for LLVM.
7412 void
7413 mono_llvm_create_vars (MonoCompile *cfg)
7415 MonoMethodSignature *sig;
7417 sig = mono_method_signature (cfg->method);
7418 if (cfg->gsharedvt && cfg->llvm_only) {
7419 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7420 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7421 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7422 printf ("vret_addr = ");
7423 mono_print_ins (cfg->vret_addr);
7426 } else {
7427 mono_arch_create_vars (cfg);
7432 * mono_llvm_emit_call:
7434 * Same as mono_arch_emit_call () for LLVM.
7436 void
7437 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7439 MonoInst *in;
7440 MonoMethodSignature *sig;
7441 int i, n, stack_size;
7442 LLVMArgInfo *ainfo;
7444 stack_size = 0;
7446 sig = call->signature;
7447 n = sig->param_count + sig->hasthis;
7449 call->cinfo = get_llvm_call_info (cfg, sig);
7451 if (cfg->disable_llvm)
7452 return;
7454 if (sig->call_convention == MONO_CALL_VARARG) {
7455 cfg->exception_message = g_strdup ("varargs");
7456 cfg->disable_llvm = TRUE;
7459 for (i = 0; i < n; ++i) {
7460 MonoInst *ins;
7462 ainfo = call->cinfo->args + i;
7464 in = call->args [i];
7466 /* Simply remember the arguments */
7467 switch (ainfo->storage) {
7468 case LLVMArgNormal: {
7469 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7470 int opcode;
7472 opcode = mono_type_to_regmove (cfg, t);
7473 if (opcode == OP_FMOVE) {
7474 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7475 ins->dreg = mono_alloc_freg (cfg);
7476 } else if (opcode == OP_LMOVE) {
7477 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7478 ins->dreg = mono_alloc_lreg (cfg);
7479 } else if (opcode == OP_RMOVE) {
7480 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7481 ins->dreg = mono_alloc_freg (cfg);
7482 } else {
7483 MONO_INST_NEW (cfg, ins, OP_MOVE);
7484 ins->dreg = mono_alloc_ireg (cfg);
7486 ins->sreg1 = in->dreg;
7487 break;
7489 case LLVMArgVtypeByVal:
7490 case LLVMArgVtypeByRef:
7491 case LLVMArgVtypeInReg:
7492 case LLVMArgVtypeAsScalar:
7493 case LLVMArgAsIArgs:
7494 case LLVMArgAsFpArgs:
7495 case LLVMArgGsharedvtVariable:
7496 case LLVMArgGsharedvtFixed:
7497 case LLVMArgGsharedvtFixedVtype:
7498 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7499 ins->dreg = mono_alloc_ireg (cfg);
7500 ins->sreg1 = in->dreg;
7501 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7502 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7503 ins->inst_vtype = ainfo->type;
7504 ins->klass = mono_class_from_mono_type (ainfo->type);
7505 break;
7506 default:
7507 cfg->exception_message = g_strdup ("ainfo->storage");
7508 cfg->disable_llvm = TRUE;
7509 return;
7512 if (!cfg->disable_llvm) {
7513 MONO_ADD_INS (cfg->cbb, ins);
7514 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7519 static unsigned char*
7520 alloc_cb (LLVMValueRef function, int size)
7522 MonoCompile *cfg;
7524 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7526 if (cfg) {
7527 // FIXME: dynamic
7528 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7529 } else {
7530 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7534 static void
7535 emitted_cb (LLVMValueRef function, void *start, void *end)
7537 MonoCompile *cfg;
7539 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7540 g_assert (cfg);
7541 cfg->code_len = (guint8*)end - (guint8*)start;
7544 static void
7545 exception_cb (void *data)
7547 MonoCompile *cfg;
7548 MonoJitExceptionInfo *ei;
7549 guint32 ei_len, i, j, nested_len, nindex;
7550 gpointer *type_info;
7551 int this_reg, this_offset;
7553 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7554 g_assert (cfg);
7557 * data points to a DWARF FDE structure, convert it to our unwind format and
7558 * save it.
7559 * An alternative would be to save it directly, and modify our unwinder to work
7560 * with it.
7562 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);
7563 if (cfg->verbose_level > 1)
7564 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7566 /* Count nested clauses */
7567 nested_len = 0;
7568 for (i = 0; i < ei_len; ++i) {
7569 gint32 cindex1 = *(gint32*)type_info [i];
7570 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7572 for (j = 0; j < cfg->header->num_clauses; ++j) {
7573 int cindex2 = j;
7574 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7576 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7577 nested_len ++;
7582 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7583 cfg->llvm_ex_info_len = ei_len + nested_len;
7584 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7585 /* Fill the rest of the information from the type info */
7586 for (i = 0; i < ei_len; ++i) {
7587 gint32 clause_index = *(gint32*)type_info [i];
7588 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7590 cfg->llvm_ex_info [i].flags = clause->flags;
7591 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7592 cfg->llvm_ex_info [i].clause_index = clause_index;
7596 * For nested clauses, the LLVM produced exception info associates the try interval with
7597 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7598 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7599 * and everything else from the nested clause.
7601 nindex = ei_len;
7602 for (i = 0; i < ei_len; ++i) {
7603 gint32 cindex1 = *(gint32*)type_info [i];
7604 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7606 for (j = 0; j < cfg->header->num_clauses; ++j) {
7607 int cindex2 = j;
7608 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7609 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7611 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7612 /* clause1 is the nested clause */
7613 nested_ei = &cfg->llvm_ex_info [i];
7614 nesting_ei = &cfg->llvm_ex_info [nindex];
7615 nindex ++;
7617 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7619 nesting_ei->flags = clause2->flags;
7620 nesting_ei->data.catch_class = clause2->data.catch_class;
7621 nesting_ei->clause_index = cindex2;
7625 g_assert (nindex == ei_len + nested_len);
7626 cfg->llvm_this_reg = this_reg;
7627 cfg->llvm_this_offset = this_offset;
7629 /* type_info [i] is cfg mempool allocated, no need to free it */
7631 g_free (ei);
7632 g_free (type_info);
7635 #if LLVM_API_VERSION > 100
7637 * decode_llvm_eh_info:
7639 * Decode the EH table emitted by llvm in jit mode, and store
7640 * the result into cfg.
7642 static void
7643 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7645 MonoCompile *cfg = ctx->cfg;
7646 guint8 *cie, *fde;
7647 int fde_len;
7648 MonoLLVMFDEInfo info;
7649 MonoJitExceptionInfo *ei;
7650 guint8 *p = eh_frame;
7651 int version, fde_count, fde_offset;
7652 guint32 ei_len, i, nested_len;
7653 gpointer *type_info;
7654 gint32 *table;
7657 * Decode the one element EH table emitted by the MonoException class
7658 * in llvm.
7661 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7663 version = *p;
7664 g_assert (version == 3);
7665 p ++;
7666 p ++;
7667 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7669 fde_count = *(guint32*)p;
7670 p += 4;
7671 table = (gint32*)p;
7673 g_assert (fde_count <= 2);
7675 /* The first entry is the real method */
7676 g_assert (table [0] == 1);
7677 fde_offset = table [1];
7678 table += fde_count * 2;
7679 /* Extra entry */
7680 cfg->code_len = table [0];
7681 fde_len = table [1] - fde_offset;
7682 table += 2;
7684 fde = (guint8*)eh_frame + fde_offset;
7685 cie = (guint8*)table;
7687 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7689 cfg->encoded_unwind_ops = info.unw_info;
7690 cfg->encoded_unwind_ops_len = info.unw_info_len;
7691 if (cfg->verbose_level > 1)
7692 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7693 if (info.this_reg != -1) {
7694 cfg->llvm_this_reg = info.this_reg;
7695 cfg->llvm_this_offset = info.this_offset;
7698 ei = info.ex_info;
7699 ei_len = info.ex_info_len;
7700 type_info = info.type_info;
7702 // Nested clauses are currently disabled
7703 nested_len = 0;
7705 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7706 cfg->llvm_ex_info_len = ei_len + nested_len;
7707 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7708 /* Fill the rest of the information from the type info */
7709 for (i = 0; i < ei_len; ++i) {
7710 gint32 clause_index = *(gint32*)type_info [i];
7711 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7713 cfg->llvm_ex_info [i].flags = clause->flags;
7714 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7715 cfg->llvm_ex_info [i].clause_index = clause_index;
7718 #endif
7720 static char*
7721 dlsym_cb (const char *name, void **symbol)
7723 MonoDl *current;
7724 char *err;
7726 err = NULL;
7727 if (!strcmp (name, "__bzero")) {
7728 *symbol = (void*)bzero;
7729 } else {
7730 current = mono_dl_open (NULL, 0, NULL);
7731 g_assert (current);
7733 err = mono_dl_symbol (current, name, symbol);
7735 mono_dl_close (current);
7737 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7738 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7739 #endif
7740 return err;
7743 static inline void
7744 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7746 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7749 static inline void
7750 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7752 LLVMTypeRef param_types [4];
7754 param_types [0] = param_type1;
7755 param_types [1] = param_type2;
7757 AddFunc (module, name, ret_type, param_types, 2);
7760 typedef enum {
7761 INTRINS_MEMSET,
7762 INTRINS_MEMCPY,
7763 INTRINS_SADD_OVF_I32,
7764 INTRINS_UADD_OVF_I32,
7765 INTRINS_SSUB_OVF_I32,
7766 INTRINS_USUB_OVF_I32,
7767 INTRINS_SMUL_OVF_I32,
7768 INTRINS_UMUL_OVF_I32,
7769 INTRINS_SADD_OVF_I64,
7770 INTRINS_UADD_OVF_I64,
7771 INTRINS_SSUB_OVF_I64,
7772 INTRINS_USUB_OVF_I64,
7773 INTRINS_SMUL_OVF_I64,
7774 INTRINS_UMUL_OVF_I64,
7775 INTRINS_SIN,
7776 INTRINS_COS,
7777 INTRINS_SQRT,
7778 INTRINS_FABS,
7779 INTRINS_EXPECT_I8,
7780 INTRINS_EXPECT_I1,
7781 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7782 INTRINS_SSE_PMOVMSKB,
7783 INTRINS_SSE_PSRLI_W,
7784 INTRINS_SSE_PSRAI_W,
7785 INTRINS_SSE_PSLLI_W,
7786 INTRINS_SSE_PSRLI_D,
7787 INTRINS_SSE_PSRAI_D,
7788 INTRINS_SSE_PSLLI_D,
7789 INTRINS_SSE_PSRLI_Q,
7790 INTRINS_SSE_PSLLI_Q,
7791 INTRINS_SSE_SQRT_PD,
7792 INTRINS_SSE_SQRT_PS,
7793 INTRINS_SSE_RSQRT_PS,
7794 INTRINS_SSE_RCP_PS,
7795 INTRINS_SSE_CVTTPD2DQ,
7796 INTRINS_SSE_CVTTPS2DQ,
7797 INTRINS_SSE_CVTDQ2PD,
7798 INTRINS_SSE_CVTDQ2PS,
7799 INTRINS_SSE_CVTPD2DQ,
7800 INTRINS_SSE_CVTPS2DQ,
7801 INTRINS_SSE_CVTPD2PS,
7802 INTRINS_SSE_CVTPS2PD,
7803 INTRINS_SSE_CMPPD,
7804 INTRINS_SSE_CMPPS,
7805 INTRINS_SSE_PACKSSWB,
7806 INTRINS_SSE_PACKUSWB,
7807 INTRINS_SSE_PACKSSDW,
7808 INTRINS_SSE_PACKUSDW,
7809 INTRINS_SSE_MINPS,
7810 INTRINS_SSE_MAXPS,
7811 INTRINS_SSE_HADDPS,
7812 INTRINS_SSE_HSUBPS,
7813 INTRINS_SSE_ADDSUBPS,
7814 INTRINS_SSE_MINPD,
7815 INTRINS_SSE_MAXPD,
7816 INTRINS_SSE_HADDPD,
7817 INTRINS_SSE_HSUBPD,
7818 INTRINS_SSE_ADDSUBPD,
7819 INTRINS_SSE_PADDSW,
7820 INTRINS_SSE_PSUBSW,
7821 INTRINS_SSE_PADDUSW,
7822 INTRINS_SSE_PSUBUSW,
7823 INTRINS_SSE_PAVGW,
7824 INTRINS_SSE_PMULHW,
7825 INTRINS_SSE_PMULHU,
7826 INTRINS_SE_PADDSB,
7827 INTRINS_SSE_PSUBSB,
7828 INTRINS_SSE_PADDUSB,
7829 INTRINS_SSE_PSUBUSB,
7830 INTRINS_SSE_PAVGB,
7831 INTRINS_SSE_PAUSE,
7832 #endif
7833 INTRINS_NUM
7834 } IntrinsicId;
7836 typedef struct {
7837 IntrinsicId id;
7838 const char *name;
7839 } IntrinsicDesc;
7841 static IntrinsicDesc intrinsics[] = {
7842 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7843 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7844 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7845 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7846 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7847 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7848 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7849 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7850 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7851 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7852 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7853 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7854 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7855 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7856 {INTRINS_SIN, "llvm.sin.f64"},
7857 {INTRINS_COS, "llvm.cos.f64"},
7858 {INTRINS_SQRT, "llvm.sqrt.f64"},
7859 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7860 {INTRINS_FABS, "fabs"},
7861 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7862 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7863 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7864 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7865 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7866 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7867 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7868 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7869 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7870 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7871 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7872 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7873 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7874 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7875 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7876 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7877 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7878 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7879 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7880 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7881 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7882 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7883 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7884 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7885 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7886 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7887 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7888 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7889 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7890 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7891 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7892 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7893 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7894 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7895 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7896 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7897 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7898 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7899 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7900 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7901 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7902 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7903 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7904 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7905 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7906 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7907 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7908 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7909 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7910 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7911 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7912 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7913 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7914 #endif
7917 static void
7918 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7920 LLVMTypeRef ret_type = type_to_simd_type (type);
7921 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7924 static void
7925 add_intrinsic (LLVMModuleRef module, int id)
7927 const char *name;
7928 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7929 LLVMTypeRef ret_type, arg_types [16];
7930 #endif
7932 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7933 g_assert (name);
7935 switch (id) {
7936 case INTRINS_MEMSET: {
7937 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7939 AddFunc (module, name, LLVMVoidType (), params, 5);
7940 break;
7942 case INTRINS_MEMCPY: {
7943 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7945 AddFunc (module, name, LLVMVoidType (), params, 5);
7946 break;
7948 case INTRINS_SADD_OVF_I32:
7949 case INTRINS_UADD_OVF_I32:
7950 case INTRINS_SSUB_OVF_I32:
7951 case INTRINS_USUB_OVF_I32:
7952 case INTRINS_SMUL_OVF_I32:
7953 case INTRINS_UMUL_OVF_I32: {
7954 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7955 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7956 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7958 AddFunc (module, name, ret_type, params, 2);
7959 break;
7961 case INTRINS_SADD_OVF_I64:
7962 case INTRINS_UADD_OVF_I64:
7963 case INTRINS_SSUB_OVF_I64:
7964 case INTRINS_USUB_OVF_I64:
7965 case INTRINS_SMUL_OVF_I64:
7966 case INTRINS_UMUL_OVF_I64: {
7967 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7968 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7969 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7971 AddFunc (module, name, ret_type, params, 2);
7972 break;
7974 case INTRINS_SIN:
7975 case INTRINS_COS:
7976 case INTRINS_SQRT:
7977 case INTRINS_FABS: {
7978 LLVMTypeRef params [] = { LLVMDoubleType () };
7980 AddFunc (module, name, LLVMDoubleType (), params, 1);
7981 break;
7983 case INTRINS_EXPECT_I8:
7984 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7985 break;
7986 case INTRINS_EXPECT_I1:
7987 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7988 break;
7989 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7990 case INTRINS_SSE_PMOVMSKB:
7991 /* pmovmskb */
7992 ret_type = LLVMInt32Type ();
7993 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7994 AddFunc (module, name, ret_type, arg_types, 1);
7995 break;
7996 case INTRINS_SSE_PSRLI_W:
7997 case INTRINS_SSE_PSRAI_W:
7998 case INTRINS_SSE_PSLLI_W:
7999 /* shifts */
8000 ret_type = type_to_simd_type (MONO_TYPE_I2);
8001 arg_types [0] = ret_type;
8002 arg_types [1] = LLVMInt32Type ();
8003 AddFunc (module, name, ret_type, arg_types, 2);
8004 break;
8005 case INTRINS_SSE_PSRLI_D:
8006 case INTRINS_SSE_PSRAI_D:
8007 case INTRINS_SSE_PSLLI_D:
8008 ret_type = type_to_simd_type (MONO_TYPE_I4);
8009 arg_types [0] = ret_type;
8010 arg_types [1] = LLVMInt32Type ();
8011 AddFunc (module, name, ret_type, arg_types, 2);
8012 break;
8013 case INTRINS_SSE_PSRLI_Q:
8014 case INTRINS_SSE_PSLLI_Q:
8015 ret_type = type_to_simd_type (MONO_TYPE_I8);
8016 arg_types [0] = ret_type;
8017 arg_types [1] = LLVMInt32Type ();
8018 AddFunc (module, name, ret_type, arg_types, 2);
8019 break;
8020 case INTRINS_SSE_SQRT_PD:
8021 /* Unary ops */
8022 ret_type = type_to_simd_type (MONO_TYPE_R8);
8023 arg_types [0] = ret_type;
8024 AddFunc (module, name, ret_type, arg_types, 1);
8025 break;
8026 case INTRINS_SSE_SQRT_PS:
8027 ret_type = type_to_simd_type (MONO_TYPE_R4);
8028 arg_types [0] = ret_type;
8029 AddFunc (module, name, ret_type, arg_types, 1);
8030 break;
8031 case INTRINS_SSE_RSQRT_PS:
8032 ret_type = type_to_simd_type (MONO_TYPE_R4);
8033 arg_types [0] = ret_type;
8034 AddFunc (module, name, ret_type, arg_types, 1);
8035 break;
8036 case INTRINS_SSE_RCP_PS:
8037 ret_type = type_to_simd_type (MONO_TYPE_R4);
8038 arg_types [0] = ret_type;
8039 AddFunc (module, name, ret_type, arg_types, 1);
8040 break;
8041 case INTRINS_SSE_CVTTPD2DQ:
8042 ret_type = type_to_simd_type (MONO_TYPE_I4);
8043 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8044 AddFunc (module, name, ret_type, arg_types, 1);
8045 break;
8046 case INTRINS_SSE_CVTTPS2DQ:
8047 ret_type = type_to_simd_type (MONO_TYPE_I4);
8048 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8049 AddFunc (module, name, ret_type, arg_types, 1);
8050 break;
8051 case INTRINS_SSE_CVTDQ2PD:
8052 /* Conversion ops */
8053 ret_type = type_to_simd_type (MONO_TYPE_R8);
8054 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8055 AddFunc (module, name, ret_type, arg_types, 1);
8056 break;
8057 case INTRINS_SSE_CVTDQ2PS:
8058 ret_type = type_to_simd_type (MONO_TYPE_R4);
8059 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8060 AddFunc (module, name, ret_type, arg_types, 1);
8061 break;
8062 case INTRINS_SSE_CVTPD2DQ:
8063 ret_type = type_to_simd_type (MONO_TYPE_I4);
8064 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8065 AddFunc (module, name, ret_type, arg_types, 1);
8066 break;
8067 case INTRINS_SSE_CVTPS2DQ:
8068 ret_type = type_to_simd_type (MONO_TYPE_I4);
8069 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8070 AddFunc (module, name, ret_type, arg_types, 1);
8071 break;
8072 case INTRINS_SSE_CVTPD2PS:
8073 ret_type = type_to_simd_type (MONO_TYPE_R4);
8074 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8075 AddFunc (module, name, ret_type, arg_types, 1);
8076 break;
8077 case INTRINS_SSE_CVTPS2PD:
8078 ret_type = type_to_simd_type (MONO_TYPE_R8);
8079 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8080 AddFunc (module, name, ret_type, arg_types, 1);
8081 break;
8082 case INTRINS_SSE_CMPPD:
8083 /* cmp pd/ps */
8084 ret_type = type_to_simd_type (MONO_TYPE_R8);
8085 arg_types [0] = ret_type;
8086 arg_types [1] = ret_type;
8087 arg_types [2] = LLVMInt8Type ();
8088 AddFunc (module, name, ret_type, arg_types, 3);
8089 break;
8090 case INTRINS_SSE_CMPPS:
8091 ret_type = type_to_simd_type (MONO_TYPE_R4);
8092 arg_types [0] = ret_type;
8093 arg_types [1] = ret_type;
8094 arg_types [2] = LLVMInt8Type ();
8095 AddFunc (module, name, ret_type, arg_types, 3);
8096 break;
8097 case INTRINS_SSE_PACKSSWB:
8098 case INTRINS_SSE_PACKUSWB:
8099 case INTRINS_SSE_PACKSSDW:
8100 /* pack */
8101 ret_type = type_to_simd_type (MONO_TYPE_I1);
8102 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8103 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8104 AddFunc (module, name, ret_type, arg_types, 2);
8105 break;
8106 case INTRINS_SSE_PACKUSDW:
8107 ret_type = type_to_simd_type (MONO_TYPE_I2);
8108 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8109 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8110 AddFunc (module, name, ret_type, arg_types, 2);
8111 break;
8112 /* SSE Binary ops */
8113 case INTRINS_SSE_PADDSW:
8114 case INTRINS_SSE_PSUBSW:
8115 case INTRINS_SSE_PADDUSW:
8116 case INTRINS_SSE_PSUBUSW:
8117 case INTRINS_SSE_PAVGW:
8118 case INTRINS_SSE_PMULHW:
8119 case INTRINS_SSE_PMULHU:
8120 add_sse_binary (module, name, MONO_TYPE_I2);
8121 break;
8122 case INTRINS_SSE_MINPS:
8123 case INTRINS_SSE_MAXPS:
8124 case INTRINS_SSE_HADDPS:
8125 case INTRINS_SSE_HSUBPS:
8126 case INTRINS_SSE_ADDSUBPS:
8127 add_sse_binary (module, name, MONO_TYPE_R4);
8128 break;
8129 case INTRINS_SSE_MINPD:
8130 case INTRINS_SSE_MAXPD:
8131 case INTRINS_SSE_HADDPD:
8132 case INTRINS_SSE_HSUBPD:
8133 case INTRINS_SSE_ADDSUBPD:
8134 add_sse_binary (module, name, MONO_TYPE_R8);
8135 break;
8136 case INTRINS_SE_PADDSB:
8137 case INTRINS_SSE_PSUBSB:
8138 case INTRINS_SSE_PADDUSB:
8139 case INTRINS_SSE_PSUBUSB:
8140 case INTRINS_SSE_PAVGB:
8141 add_sse_binary (module, name, MONO_TYPE_I1);
8142 break;
8143 case INTRINS_SSE_PAUSE:
8144 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8145 break;
8146 #endif
8147 default:
8148 g_assert_not_reached ();
8149 break;
8153 static LLVMValueRef
8154 get_intrinsic (EmitContext *ctx, const char *name)
8156 #if LLVM_API_VERSION > 100
8157 LLVMValueRef res;
8160 * Every method is emitted into its own module so
8161 * we can add intrinsics on demand.
8163 res = LLVMGetNamedFunction (ctx->lmodule, name);
8164 if (!res) {
8165 int id = -1;
8167 /* No locking needed */
8168 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8169 id --;
8170 if (id == -1)
8171 printf ("%s\n", name);
8172 g_assert (id != -1);
8173 add_intrinsic (ctx->lmodule, id);
8174 res = LLVMGetNamedFunction (ctx->lmodule, name);
8175 g_assert (res);
8178 return res;
8179 #else
8180 LLVMValueRef res;
8182 res = LLVMGetNamedFunction (ctx->lmodule, name);
8183 g_assert (res);
8184 return res;
8185 #endif
8188 static void
8189 add_intrinsics (LLVMModuleRef module)
8191 int i;
8193 /* Emit declarations of instrinsics */
8195 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8196 * type doesn't seem to do any locking.
8198 for (i = 0; i < INTRINS_NUM; ++i)
8199 add_intrinsic (module, i);
8201 /* EH intrinsics */
8203 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8205 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8208 /* Load/Store intrinsics */
8210 LLVMTypeRef arg_types [5];
8211 int i;
8212 char name [128];
8214 for (i = 1; i <= 8; i *= 2) {
8215 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8216 arg_types [1] = LLVMInt32Type ();
8217 arg_types [2] = LLVMInt1Type ();
8218 arg_types [3] = LLVMInt32Type ();
8219 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8220 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8222 arg_types [0] = LLVMIntType (i * 8);
8223 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8224 arg_types [2] = LLVMInt32Type ();
8225 arg_types [3] = LLVMInt1Type ();
8226 arg_types [4] = LLVMInt32Type ();
8227 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8228 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8233 static void
8234 add_types (MonoLLVMModule *module)
8236 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8239 void
8240 mono_llvm_init (void)
8242 GHashTable *h;
8243 int i;
8245 mono_native_tls_alloc (&current_cfg_tls_id, NULL);
8247 h = g_hash_table_new (NULL, NULL);
8248 for (i = 0; i < INTRINS_NUM; ++i)
8249 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8250 intrins_id_to_name = h;
8252 h = g_hash_table_new (g_str_hash, g_str_equal);
8253 for (i = 0; i < INTRINS_NUM; ++i)
8254 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8255 intrins_name_to_id = h;
8258 static void
8259 init_jit_module (MonoDomain *domain)
8261 MonoJitDomainInfo *dinfo;
8262 MonoLLVMModule *module;
8263 char *name;
8265 dinfo = domain_jit_info (domain);
8266 if (dinfo->llvm_module)
8267 return;
8269 mono_loader_lock ();
8271 if (dinfo->llvm_module) {
8272 mono_loader_unlock ();
8273 return;
8276 module = g_new0 (MonoLLVMModule, 1);
8278 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8279 module->lmodule = LLVMModuleCreateWithName (name);
8280 module->context = LLVMGetGlobalContext ();
8282 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8284 add_intrinsics (module->lmodule);
8285 add_types (module);
8287 module->llvm_types = g_hash_table_new (NULL, NULL);
8289 #if LLVM_API_VERSION < 100
8290 MonoJitICallInfo *info;
8292 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8293 g_assert (info);
8294 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8295 #endif
8297 mono_memory_barrier ();
8299 dinfo->llvm_module = module;
8301 mono_loader_unlock ();
8304 void
8305 mono_llvm_cleanup (void)
8307 MonoLLVMModule *module = &aot_module;
8309 if (module->lmodule)
8310 LLVMDisposeModule (module->lmodule);
8312 if (module->context)
8313 LLVMContextDispose (module->context);
8316 void
8317 mono_llvm_free_domain_info (MonoDomain *domain)
8319 MonoJitDomainInfo *info = domain_jit_info (domain);
8320 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8321 int i;
8323 if (!module)
8324 return;
8326 if (module->llvm_types)
8327 g_hash_table_destroy (module->llvm_types);
8329 mono_llvm_dispose_ee (module->mono_ee);
8331 if (module->bb_names) {
8332 for (i = 0; i < module->bb_names_len; ++i)
8333 g_free (module->bb_names [i]);
8334 g_free (module->bb_names);
8336 //LLVMDisposeModule (module->module);
8338 g_free (module);
8340 info->llvm_module = NULL;
8343 void
8344 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8346 MonoLLVMModule *module = &aot_module;
8348 /* Delete previous module */
8349 if (module->plt_entries)
8350 g_hash_table_destroy (module->plt_entries);
8351 if (module->lmodule)
8352 LLVMDisposeModule (module->lmodule);
8354 memset (module, 0, sizeof (aot_module));
8356 module->lmodule = LLVMModuleCreateWithName ("aot");
8357 module->assembly = assembly;
8358 module->global_prefix = g_strdup (global_prefix);
8359 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8360 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8361 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8362 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8363 module->external_symbols = TRUE;
8364 module->emit_dwarf = emit_dwarf;
8365 module->static_link = static_link;
8366 module->llvm_only = llvm_only;
8367 /* The first few entries are reserved */
8368 module->max_got_offset = 16;
8369 module->context = LLVMGetGlobalContext ();
8371 if (llvm_only)
8372 /* clang ignores our debug info because it has an invalid version */
8373 module->emit_dwarf = FALSE;
8375 add_intrinsics (module->lmodule);
8376 add_types (module);
8378 #if LLVM_API_VERSION > 100
8379 if (module->emit_dwarf) {
8380 char *dir, *build_info, *s, *cu_name;
8382 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8384 // FIXME:
8385 dir = g_strdup (".");
8386 build_info = mono_get_runtime_build_info ();
8387 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8388 cu_name = g_path_get_basename (assembly->image->name);
8389 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8390 g_free (dir);
8391 g_free (build_info);
8392 g_free (s);
8394 #endif
8396 /* Add GOT */
8398 * We couldn't compute the type of the LLVM global representing the got because
8399 * its size is only known after all the methods have been emitted. So create
8400 * a dummy variable, and replace all uses it with the real got variable when
8401 * its size is known in mono_llvm_emit_aot_module ().
8404 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8406 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8407 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8410 /* Add initialization array */
8411 if (llvm_only) {
8412 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8414 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8415 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8418 if (llvm_only)
8419 emit_init_icall_wrappers (module);
8421 emit_llvm_code_start (module);
8423 /* Add a dummy personality function */
8424 if (!use_debug_personality) {
8425 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8426 LLVMSetLinkage (personality, LLVMExternalLinkage);
8427 mark_as_used (module, personality);
8430 /* Add a reference to the c++ exception we throw/catch */
8432 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8433 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8434 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8435 mono_llvm_set_is_constant (module->sentinel_exception);
8438 module->llvm_types = g_hash_table_new (NULL, NULL);
8439 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8440 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8441 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8442 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8443 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8444 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8445 module->method_to_callers = g_hash_table_new (NULL, NULL);
8448 static LLVMValueRef
8449 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8451 int i;
8452 LLVMValueRef res, *vals;
8454 vals = g_new0 (LLVMValueRef, nvalues);
8455 for (i = 0; i < nvalues; ++i)
8456 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8457 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8458 g_free (vals);
8459 return res;
8462 static LLVMValueRef
8463 llvm_array_from_bytes (guint8 *values, int nvalues)
8465 int i;
8466 LLVMValueRef res, *vals;
8468 vals = g_new0 (LLVMValueRef, nvalues);
8469 for (i = 0; i < nvalues; ++i)
8470 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8471 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8472 g_free (vals);
8473 return res;
8476 * mono_llvm_emit_aot_file_info:
8478 * Emit the MonoAotFileInfo structure.
8479 * Same as emit_aot_file_info () in aot-compiler.c.
8481 void
8482 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8484 MonoLLVMModule *module = &aot_module;
8486 /* Save these for later */
8487 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8488 module->has_jitted_code = has_jitted_code;
8492 * mono_llvm_emit_aot_data:
8494 * Emit the binary data DATA pointed to by symbol SYMBOL.
8496 void
8497 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8499 MonoLLVMModule *module = &aot_module;
8500 LLVMTypeRef type;
8501 LLVMValueRef d;
8503 type = LLVMArrayType (LLVMInt8Type (), data_len);
8504 d = LLVMAddGlobal (module->lmodule, type, symbol);
8505 LLVMSetVisibility (d, LLVMHiddenVisibility);
8506 LLVMSetLinkage (d, LLVMInternalLinkage);
8507 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8508 mono_llvm_set_is_constant (d);
8511 /* Add a reference to a global defined in JITted code */
8512 static LLVMValueRef
8513 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8515 char *s;
8516 LLVMValueRef v;
8518 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8519 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8520 g_free (s);
8521 return v;
8524 static void
8525 emit_aot_file_info (MonoLLVMModule *module)
8527 LLVMTypeRef file_info_type;
8528 LLVMTypeRef *eltypes, eltype;
8529 LLVMValueRef info_var;
8530 LLVMValueRef *fields;
8531 int i, nfields, tindex;
8532 MonoAotFileInfo *info;
8533 LLVMModuleRef lmodule = module->lmodule;
8535 info = &module->aot_info;
8537 /* Create an LLVM type to represent MonoAotFileInfo */
8538 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8539 eltypes = g_new (LLVMTypeRef, nfields);
8540 tindex = 0;
8541 eltypes [tindex ++] = LLVMInt32Type ();
8542 eltypes [tindex ++] = LLVMInt32Type ();
8543 /* Symbols */
8544 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8545 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8546 /* Scalars */
8547 for (i = 0; i < 15; ++i)
8548 eltypes [tindex ++] = LLVMInt32Type ();
8549 /* Arrays */
8550 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8551 for (i = 0; i < 4; ++i)
8552 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8553 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8554 g_assert (tindex == nfields);
8555 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8556 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8558 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8559 if (module->static_link) {
8560 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8561 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8563 fields = g_new (LLVMValueRef, nfields);
8564 tindex = 0;
8565 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8566 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8568 /* Symbols */
8570 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8571 * for symbols defined in the .s file emitted by the aot compiler.
8573 eltype = eltypes [tindex];
8574 if (module->llvm_only)
8575 fields [tindex ++] = LLVMConstNull (eltype);
8576 else
8577 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8578 fields [tindex ++] = module->got_var;
8579 /* llc defines this directly */
8580 if (!module->llvm_only) {
8581 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8582 fields [tindex ++] = LLVMConstNull (eltype);
8583 fields [tindex ++] = LLVMConstNull (eltype);
8584 } else {
8585 fields [tindex ++] = LLVMConstNull (eltype);
8586 fields [tindex ++] = module->get_method;
8587 fields [tindex ++] = module->get_unbox_tramp;
8589 if (module->has_jitted_code) {
8590 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8591 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8592 } else {
8593 fields [tindex ++] = LLVMConstNull (eltype);
8594 fields [tindex ++] = LLVMConstNull (eltype);
8596 if (!module->llvm_only)
8597 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8598 else
8599 fields [tindex ++] = LLVMConstNull (eltype);
8600 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8601 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8602 fields [tindex ++] = LLVMConstNull (eltype);
8603 } else {
8604 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8605 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8606 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8607 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8608 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8609 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8610 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8611 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8612 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8613 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8615 /* Not needed (mem_end) */
8616 fields [tindex ++] = LLVMConstNull (eltype);
8617 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8618 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8619 if (info->trampoline_size [0]) {
8620 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8621 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8622 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8623 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8624 } else {
8625 fields [tindex ++] = LLVMConstNull (eltype);
8626 fields [tindex ++] = LLVMConstNull (eltype);
8627 fields [tindex ++] = LLVMConstNull (eltype);
8628 fields [tindex ++] = LLVMConstNull (eltype);
8630 if (module->static_link && !module->llvm_only)
8631 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8632 else
8633 fields [tindex ++] = LLVMConstNull (eltype);
8634 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8635 if (!module->llvm_only) {
8636 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8637 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8638 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8639 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8640 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8641 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8642 } else {
8643 fields [tindex ++] = LLVMConstNull (eltype);
8644 fields [tindex ++] = LLVMConstNull (eltype);
8645 fields [tindex ++] = LLVMConstNull (eltype);
8646 fields [tindex ++] = LLVMConstNull (eltype);
8647 fields [tindex ++] = LLVMConstNull (eltype);
8648 fields [tindex ++] = LLVMConstNull (eltype);
8651 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8652 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8654 /* Scalars */
8655 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8656 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8657 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8658 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8659 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8660 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8661 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8662 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8663 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8664 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8665 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8666 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8667 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8668 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8669 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8670 /* Arrays */
8671 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8672 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8673 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8674 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8675 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8677 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8678 g_assert (tindex == nfields);
8680 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8682 if (module->static_link) {
8683 char *s, *p;
8684 LLVMValueRef var;
8686 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8687 /* Get rid of characters which cannot occur in symbols */
8688 p = s;
8689 for (p = s; *p; ++p) {
8690 if (!(isalnum (*p) || *p == '_'))
8691 *p = '_';
8693 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8694 g_free (s);
8695 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8696 LLVMSetLinkage (var, LLVMExternalLinkage);
8701 * Emit the aot module into the LLVM bitcode file FILENAME.
8703 void
8704 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8706 LLVMTypeRef got_type, inited_type;
8707 LLVMValueRef real_got, real_inited;
8708 MonoLLVMModule *module = &aot_module;
8710 emit_llvm_code_end (module);
8713 * Create the real got variable and replace all uses of the dummy variable with
8714 * the real one.
8716 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8717 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8718 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8719 if (module->external_symbols) {
8720 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8721 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8722 } else {
8723 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8725 mono_llvm_replace_uses_of (module->got_var, real_got);
8727 mark_as_used (&aot_module, real_got);
8729 /* Delete the dummy got so it doesn't become a global */
8730 LLVMDeleteGlobal (module->got_var);
8731 module->got_var = real_got;
8734 * Same for the init_var
8736 if (module->llvm_only) {
8737 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8738 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8739 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8740 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8741 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8742 LLVMDeleteGlobal (module->inited_var);
8745 if (module->llvm_only) {
8746 emit_get_method (&aot_module);
8747 emit_get_unbox_tramp (&aot_module);
8750 emit_llvm_used (&aot_module);
8751 emit_dbg_info (&aot_module, filename, cu_name);
8752 emit_aot_file_info (&aot_module);
8755 * Replace GOT entries for directly callable methods with the methods themselves.
8756 * It would be easier to implement this by predefining all methods before compiling
8757 * their bodies, but that couldn't handle the case when a method fails to compile
8758 * with llvm.
8760 if (module->llvm_only) {
8761 GHashTableIter iter;
8762 MonoMethod *method;
8763 GSList *callers, *l;
8765 g_hash_table_iter_init (&iter, module->method_to_callers);
8766 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8767 LLVMValueRef lmethod;
8769 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8770 continue;
8772 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8773 if (lmethod) {
8774 for (l = callers; l; l = l->next) {
8775 LLVMValueRef caller = (LLVMValueRef)l->data;
8777 mono_llvm_replace_uses_of (caller, lmethod);
8783 /* Replace PLT entries for directly callable methods with the methods themselves */
8785 GHashTableIter iter;
8786 MonoJumpInfo *ji;
8787 LLVMValueRef callee;
8789 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8790 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8791 if (mono_aot_is_direct_callable (ji)) {
8792 LLVMValueRef lmethod;
8794 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8795 /* The types might not match because the caller might pass an rgctx */
8796 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8797 mono_llvm_replace_uses_of (callee, lmethod);
8798 mono_aot_mark_unused_llvm_plt_entry (ji);
8804 #if 1
8806 char *verifier_err;
8808 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8809 printf ("%s\n", verifier_err);
8810 g_assert_not_reached ();
8813 #endif
8815 LLVMWriteBitcodeToFile (module->lmodule, filename);
8819 static LLVMValueRef
8820 md_string (const char *s)
8822 return LLVMMDString (s, strlen (s));
8825 /* Debugging support */
8827 static void
8828 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8830 LLVMModuleRef lmodule = module->lmodule;
8831 LLVMValueRef args [16], ver;
8834 * This can only be enabled when LLVM code is emitted into a separate object
8835 * file, since the AOT compiler also emits dwarf info,
8836 * and the abbrev indexes will not be correct since llvm has added its own
8837 * abbrevs.
8839 if (!module->emit_dwarf)
8840 return;
8842 #if LLVM_API_VERSION > 100
8843 mono_llvm_di_builder_finalize (module->di_builder);
8844 #else
8845 LLVMValueRef cu_args [16], cu;
8846 int n_cuargs;
8847 char *build_info, *s, *dir;
8850 * Emit dwarf info in the form of LLVM metadata. There is some
8851 * out-of-date documentation at:
8852 * http://llvm.org/docs/SourceLevelDebugging.html
8853 * but most of this was gathered from the llvm and
8854 * clang sources.
8857 n_cuargs = 0;
8858 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8859 /* CU name/compilation dir */
8860 dir = g_path_get_dirname (filename);
8861 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8862 args [1] = LLVMMDString (dir, strlen (dir));
8863 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8864 g_free (dir);
8865 /* Language */
8866 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8867 /* Producer */
8868 build_info = mono_get_runtime_build_info ();
8869 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8870 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8871 g_free (build_info);
8872 /* Optimized */
8873 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8874 /* Flags */
8875 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8876 /* Runtime version */
8877 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8878 /* Enums */
8879 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8880 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8881 /* Subprograms */
8882 if (module->subprogram_mds) {
8883 LLVMValueRef *mds;
8884 int i;
8886 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8887 for (i = 0; i < module->subprogram_mds->len; ++i)
8888 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8889 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8890 } else {
8891 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8893 /* GVs */
8894 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8895 /* Imported modules */
8896 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8897 /* SplitName */
8898 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8899 /* DebugEmissionKind = FullDebug */
8900 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8901 cu = LLVMMDNode (cu_args, n_cuargs);
8902 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8903 #endif
8905 #if LLVM_API_VERSION > 100
8906 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8907 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8908 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8909 ver = LLVMMDNode (args, 3);
8910 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8912 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8913 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8914 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8915 ver = LLVMMDNode (args, 3);
8916 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8917 #else
8918 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8919 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8920 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8921 ver = LLVMMDNode (args, 3);
8922 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8924 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8925 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8926 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8927 ver = LLVMMDNode (args, 3);
8928 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8929 #endif
8932 static LLVMValueRef
8933 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8935 MonoLLVMModule *module = ctx->module;
8936 MonoDebugMethodInfo *minfo = ctx->minfo;
8937 char *source_file, *dir, *filename;
8938 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8939 MonoSymSeqPoint *sym_seq_points;
8940 int n_seq_points;
8942 if (!minfo)
8943 return NULL;
8945 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8946 if (!source_file)
8947 source_file = g_strdup ("<unknown>");
8948 dir = g_path_get_dirname (source_file);
8949 filename = g_path_get_basename (source_file);
8951 #if LLVM_API_VERSION > 100
8952 return mono_llvm_di_create_function (module->di_builder, module->cu, method, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8953 #endif
8955 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8956 args [0] = md_string (filename);
8957 args [1] = md_string (dir);
8958 ctx_args [1] = LLVMMDNode (args, 2);
8959 ctx_md = LLVMMDNode (ctx_args, 2);
8961 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8962 type_args [1] = NULL;
8963 type_args [2] = NULL;
8964 type_args [3] = LLVMMDString ("", 0);
8965 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8966 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8967 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8968 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8969 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8970 type_args [9] = NULL;
8971 type_args [10] = NULL;
8972 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8973 type_args [12] = NULL;
8974 type_args [13] = NULL;
8975 type_args [14] = NULL;
8976 type_md = LLVMMDNode (type_args, 14);
8978 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8979 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8980 /* Source directory + file pair */
8981 args [0] = md_string (filename);
8982 args [1] = md_string (dir);
8983 md_args [1] = LLVMMDNode (args ,2);
8984 md_args [2] = ctx_md;
8985 md_args [3] = md_string (cfg->method->name);
8986 md_args [4] = md_string (name);
8987 md_args [5] = md_string (name);
8988 /* Line number */
8989 if (n_seq_points)
8990 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8991 else
8992 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8993 /* Type */
8994 md_args [7] = type_md;
8995 /* static */
8996 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8997 /* not extern */
8998 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8999 /* Virtuality */
9000 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9001 /* Index into a virtual function */
9002 md_args [11] = NULL;
9003 md_args [12] = NULL;
9004 /* Flags */
9005 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9006 /* isOptimized */
9007 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9008 /* Pointer to LLVM function */
9009 md_args [15] = method;
9010 /* Function template parameter */
9011 md_args [16] = NULL;
9012 /* Function declaration descriptor */
9013 md_args [17] = NULL;
9014 /* List of function variables */
9015 md_args [18] = LLVMMDNode (args, 0);
9016 /* Line number */
9017 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9018 md = LLVMMDNode (md_args, 20);
9020 if (!module->subprogram_mds)
9021 module->subprogram_mds = g_ptr_array_new ();
9022 g_ptr_array_add (module->subprogram_mds, md);
9024 g_free (dir);
9025 g_free (filename);
9026 g_free (source_file);
9027 g_free (sym_seq_points);
9029 return md;
9032 static void
9033 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9035 MonoCompile *cfg = ctx->cfg;
9037 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9038 MonoDebugSourceLocation *loc;
9039 LLVMValueRef loc_md;
9041 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9043 if (loc) {
9044 #if LLVM_API_VERSION > 100
9045 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9046 mono_llvm_di_set_location (builder, loc_md);
9047 #else
9048 LLVMValueRef md_args [16];
9049 int nmd_args;
9051 nmd_args = 0;
9052 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9053 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9054 md_args [nmd_args ++] = ctx->dbg_md;
9055 md_args [nmd_args ++] = NULL;
9056 loc_md = LLVMMDNode (md_args, nmd_args);
9057 LLVMSetCurrentDebugLocation (builder, loc_md);
9058 #endif
9059 mono_debug_symfile_free_location (loc);
9064 void
9065 default_mono_llvm_unhandled_exception (void)
9067 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9068 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9070 mono_unhandled_exception (target);
9071 mono_invoke_unhandled_exception_hook (target);
9072 g_assert_not_reached ();
9076 DESIGN:
9077 - Emit LLVM IR from the mono IR using the LLVM C API.
9078 - The original arch specific code remains, so we can fall back to it if we run
9079 into something we can't handle.
9083 A partial list of issues:
9084 - Handling of opcodes which can throw exceptions.
9086 In the mono JIT, these are implemented using code like this:
9087 method:
9088 <compare>
9089 throw_pos:
9090 b<cond> ex_label
9091 <rest of code>
9092 ex_label:
9093 push throw_pos - method
9094 call <exception trampoline>
9096 The problematic part is push throw_pos - method, which cannot be represented
9097 in the LLVM IR, since it does not support label values.
9098 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9099 be implemented in JIT mode ?
9100 -> a possible but slower implementation would use the normal exception
9101 throwing code but it would need to control the placement of the throw code
9102 (it needs to be exactly after the compare+branch).
9103 -> perhaps add a PC offset intrinsics ?
9105 - efficient implementation of .ovf opcodes.
9107 These are currently implemented as:
9108 <ins which sets the condition codes>
9109 b<cond> ex_label
9111 Some overflow opcodes are now supported by LLVM SVN.
9113 - exception handling, unwinding.
9114 - SSA is disabled for methods with exception handlers
9115 - How to obtain unwind info for LLVM compiled methods ?
9116 -> this is now solved by converting the unwind info generated by LLVM
9117 into our format.
9118 - LLVM uses the c++ exception handling framework, while we use our home grown
9119 code, and couldn't use the c++ one:
9120 - its not supported under VC++, other exotic platforms.
9121 - it might be impossible to support filter clauses with it.
9123 - trampolines.
9125 The trampolines need a predictable call sequence, since they need to disasm
9126 the calling code to obtain register numbers / offsets.
9128 LLVM currently generates this code in non-JIT mode:
9129 mov -0x98(%rax),%eax
9130 callq *%rax
9131 Here, the vtable pointer is lost.
9132 -> solution: use one vtable trampoline per class.
9134 - passing/receiving the IMT pointer/RGCTX.
9135 -> solution: pass them as normal arguments ?
9137 - argument passing.
9139 LLVM does not allow the specification of argument registers etc. This means
9140 that all calls are made according to the platform ABI.
9142 - passing/receiving vtypes.
9144 Vtypes passed/received in registers are handled by the front end by using
9145 a signature with scalar arguments, and loading the parts of the vtype into those
9146 arguments.
9148 Vtypes passed on the stack are handled using the 'byval' attribute.
9150 - ldaddr.
9152 Supported though alloca, we need to emit the load/store code.
9154 - types.
9156 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9157 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9158 This is made easier because the IR is already in SSA form.
9159 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9160 types are frequently used incorrectly.
9164 AOT SUPPORT:
9165 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9166 it with the file containing the methods emitted by the JIT and the AOT data
9167 structures.
9170 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9171 * - each bblock should end with a branch
9172 * - setting the return value, making cfg->ret non-volatile
9173 * - avoid some transformations in the JIT which make it harder for us to generate
9174 * code.
9175 * - use pointer types to help optimizations.