update rx (mobile builds).
[mono-project.git] / mono / mini / mini-llvm.c
bloba369d550756d5a2d18c982c1086aa03b3813aba6
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 */
8 #include "mini.h"
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
16 #endif
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
19 #endif
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
31 typedef struct {
32 LLVMModuleRef module;
33 LLVMValueRef throw, rethrow, throw_corlib_exception;
34 GHashTable *llvm_types;
35 LLVMValueRef got_var;
36 const char *got_symbol;
37 GHashTable *plt_entries;
38 } MonoLLVMModule;
41 * Information associated by the backend with mono basic blocks.
43 typedef struct {
44 LLVMBasicBlockRef bblock, end_bblock;
45 LLVMValueRef finally_ind;
46 gboolean added, invoke_target;
47 /*
48 * If this bblock is the start of a finally clause, this is a list of bblocks it
49 * needs to branch to in ENDFINALLY.
51 GSList *call_handler_return_bbs;
53 * If this bblock is the start of a finally clause, this is the bblock that
54 * CALL_HANDLER needs to branch to.
56 LLVMBasicBlockRef call_handler_target_bb;
57 /* The list of switch statements generated by ENDFINALLY instructions */
58 GSList *endfinally_switch_ins_list;
59 GSList *phi_nodes;
60 } BBInfo;
63 * Structure containing emit state
65 typedef struct {
66 MonoMemPool *mempool;
68 /* Maps method names to the corresponding LLVMValueRef */
69 GHashTable *emitted_method_decls;
71 MonoCompile *cfg;
72 LLVMValueRef lmethod;
73 MonoLLVMModule *lmodule;
74 LLVMModuleRef module;
75 BBInfo *bblocks;
76 int sindex, default_index, ex_index;
77 LLVMBuilderRef builder;
78 LLVMValueRef *values, *addresses;
79 MonoType **vreg_cli_types;
80 LLVMCallInfo *linfo;
81 MonoMethodSignature *sig;
82 GSList *builders;
83 GHashTable *region_to_handler;
84 LLVMBuilderRef alloca_builder;
85 LLVMValueRef last_alloca;
86 LLVMValueRef rgctx_arg;
87 LLVMTypeRef *vreg_types;
88 gboolean *is_dead;
89 gboolean *unreachable;
90 int *pindexes;
92 char temp_name [32];
93 } EmitContext;
95 typedef struct {
96 MonoBasicBlock *bb;
97 MonoInst *phi;
98 MonoBasicBlock *in_bb;
99 int sreg;
100 } PhiNode;
103 * Instruction metadata
104 * This is the same as ins_info, but LREG != IREG.
106 #ifdef MINI_OP
107 #undef MINI_OP
108 #endif
109 #ifdef MINI_OP3
110 #undef MINI_OP3
111 #endif
112 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
113 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
114 #define NONE ' '
115 #define IREG 'i'
116 #define FREG 'f'
117 #define VREG 'v'
118 #define XREG 'x'
119 #define LREG 'l'
120 /* keep in sync with the enum in mini.h */
121 const char
122 llvm_ins_info[] = {
123 #include "mini-ops.h"
125 #undef MINI_OP
126 #undef MINI_OP3
128 #if SIZEOF_VOID_P == 4
129 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
130 #else
131 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
132 #endif
134 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
136 #if 0
137 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
138 #else
139 #define TRACE_FAILURE(msg)
140 #endif
142 #ifdef TARGET_X86
143 #define IS_TARGET_X86 1
144 #else
145 #define IS_TARGET_X86 0
146 #endif
148 #define LLVM_FAILURE(ctx, reason) do { \
149 TRACE_FAILURE (reason); \
150 (ctx)->cfg->exception_message = g_strdup (reason); \
151 (ctx)->cfg->disable_llvm = TRUE; \
152 goto FAILURE; \
153 } while (0)
155 #define CHECK_FAILURE(ctx) do { \
156 if ((ctx)->cfg->disable_llvm) \
157 goto FAILURE; \
158 } while (0)
160 static LLVMIntPredicate cond_to_llvm_cond [] = {
161 LLVMIntEQ,
162 LLVMIntNE,
163 LLVMIntSLE,
164 LLVMIntSGE,
165 LLVMIntSLT,
166 LLVMIntSGT,
167 LLVMIntULE,
168 LLVMIntUGE,
169 LLVMIntULT,
170 LLVMIntUGT,
173 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
174 LLVMRealOEQ,
175 LLVMRealUNE,
176 LLVMRealOLE,
177 LLVMRealOGE,
178 LLVMRealOLT,
179 LLVMRealOGT,
180 LLVMRealULE,
181 LLVMRealUGE,
182 LLVMRealULT,
183 LLVMRealUGT,
186 static LLVMExecutionEngineRef ee;
187 static MonoNativeTlsKey current_cfg_tls_id;
189 static MonoLLVMModule jit_module, aot_module;
190 static gboolean jit_module_inited;
191 static int memset_param_count, memcpy_param_count;
192 static const char *memset_func_name;
193 static const char *memcpy_func_name;
195 static void init_jit_module (void);
198 * IntPtrType:
200 * The LLVM type with width == sizeof (gpointer)
202 static LLVMTypeRef
203 IntPtrType (void)
205 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
209 * get_vtype_size:
211 * Return the size of the LLVM representation of the vtype T.
213 static guint32
214 get_vtype_size (MonoType *t)
216 int size;
218 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
220 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
221 size ++;
223 return size;
227 * simd_class_to_llvm_type:
229 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
231 static LLVMTypeRef
232 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
234 if (!strcmp (klass->name, "Vector2d")) {
235 return LLVMVectorType (LLVMDoubleType (), 2);
236 } else if (!strcmp (klass->name, "Vector2l")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector2ul")) {
239 return LLVMVectorType (LLVMInt64Type (), 2);
240 } else if (!strcmp (klass->name, "Vector4i")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4ui")) {
243 return LLVMVectorType (LLVMInt32Type (), 4);
244 } else if (!strcmp (klass->name, "Vector4f")) {
245 return LLVMVectorType (LLVMFloatType (), 4);
246 } else if (!strcmp (klass->name, "Vector8s")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector8us")) {
249 return LLVMVectorType (LLVMInt16Type (), 8);
250 } else if (!strcmp (klass->name, "Vector16sb")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else if (!strcmp (klass->name, "Vector16b")) {
253 return LLVMVectorType (LLVMInt8Type (), 16);
254 } else {
255 printf ("%s\n", klass->name);
256 NOT_IMPLEMENTED;
257 return NULL;
261 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
262 static inline G_GNUC_UNUSED LLVMTypeRef
263 type_to_simd_type (int type)
265 switch (type) {
266 case MONO_TYPE_I1:
267 return LLVMVectorType (LLVMInt8Type (), 16);
268 case MONO_TYPE_I2:
269 return LLVMVectorType (LLVMInt16Type (), 8);
270 case MONO_TYPE_I4:
271 return LLVMVectorType (LLVMInt32Type (), 4);
272 case MONO_TYPE_I8:
273 return LLVMVectorType (LLVMInt64Type (), 2);
274 case MONO_TYPE_R8:
275 return LLVMVectorType (LLVMDoubleType (), 2);
276 case MONO_TYPE_R4:
277 return LLVMVectorType (LLVMFloatType (), 4);
278 default:
279 g_assert_not_reached ();
280 return NULL;
285 * type_to_llvm_type:
287 * Return the LLVM type corresponding to T.
289 static LLVMTypeRef
290 type_to_llvm_type (EmitContext *ctx, MonoType *t)
292 if (t->byref)
293 return LLVMPointerType (LLVMInt8Type (), 0);
294 switch (t->type) {
295 case MONO_TYPE_VOID:
296 return LLVMVoidType ();
297 case MONO_TYPE_I1:
298 return LLVMInt8Type ();
299 case MONO_TYPE_I2:
300 return LLVMInt16Type ();
301 case MONO_TYPE_I4:
302 return LLVMInt32Type ();
303 case MONO_TYPE_U1:
304 return LLVMInt8Type ();
305 case MONO_TYPE_U2:
306 return LLVMInt16Type ();
307 case MONO_TYPE_U4:
308 return LLVMInt32Type ();
309 case MONO_TYPE_BOOLEAN:
310 return LLVMInt8Type ();
311 case MONO_TYPE_I8:
312 case MONO_TYPE_U8:
313 return LLVMInt64Type ();
314 case MONO_TYPE_CHAR:
315 return LLVMInt16Type ();
316 case MONO_TYPE_R4:
317 return LLVMFloatType ();
318 case MONO_TYPE_R8:
319 return LLVMDoubleType ();
320 case MONO_TYPE_I:
321 case MONO_TYPE_U:
322 return IntPtrType ();
323 case MONO_TYPE_OBJECT:
324 case MONO_TYPE_CLASS:
325 case MONO_TYPE_ARRAY:
326 case MONO_TYPE_SZARRAY:
327 case MONO_TYPE_STRING:
328 case MONO_TYPE_PTR:
329 return IntPtrType ();
330 case MONO_TYPE_VAR:
331 case MONO_TYPE_MVAR:
332 /* Because of generic sharing */
333 if (mini_type_var_is_vt (ctx->cfg, t))
334 return type_to_llvm_type (ctx, mini_get_gsharedvt_alloc_type_for_type (ctx->cfg, t));
335 else
336 return IntPtrType ();
337 case MONO_TYPE_GENERICINST:
338 if (!mono_type_generic_inst_is_valuetype (t))
339 return IntPtrType ();
340 /* Fall through */
341 case MONO_TYPE_VALUETYPE:
342 case MONO_TYPE_TYPEDBYREF: {
343 MonoClass *klass;
344 LLVMTypeRef ltype;
346 klass = mono_class_from_mono_type (t);
348 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
349 return simd_class_to_llvm_type (ctx, klass);
351 if (klass->enumtype)
352 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
353 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
354 if (!ltype) {
355 int i, size;
356 LLVMTypeRef *eltypes;
357 char *name;
359 size = get_vtype_size (t);
361 eltypes = g_new (LLVMTypeRef, size);
362 for (i = 0; i < size; ++i)
363 eltypes [i] = LLVMInt8Type ();
365 name = mono_type_full_name (&klass->byval_arg);
366 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
367 LLVMStructSetBody (ltype, eltypes, size, FALSE);
368 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
369 g_free (eltypes);
371 return ltype;
374 default:
375 printf ("X: %d\n", t->type);
376 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
377 ctx->cfg->disable_llvm = TRUE;
378 return NULL;
383 * type_is_unsigned:
385 * Return whenever T is an unsigned int type.
387 static gboolean
388 type_is_unsigned (EmitContext *ctx, MonoType *t)
390 if (t->byref)
391 return FALSE;
392 switch (t->type) {
393 case MONO_TYPE_U1:
394 case MONO_TYPE_U2:
395 case MONO_TYPE_U4:
396 case MONO_TYPE_U8:
397 return TRUE;
398 default:
399 return FALSE;
404 * type_to_llvm_arg_type:
406 * Same as type_to_llvm_type, but treat i8/i16 as i32.
408 static LLVMTypeRef
409 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
411 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
413 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
415 * LLVM generates code which only sets the lower bits, while JITted
416 * code expects all the bits to be set.
418 ptype = LLVMInt32Type ();
421 return ptype;
425 * llvm_type_to_stack_type:
427 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
428 * on the IL stack.
430 static G_GNUC_UNUSED LLVMTypeRef
431 llvm_type_to_stack_type (LLVMTypeRef type)
433 if (type == NULL)
434 return NULL;
435 if (type == LLVMInt8Type ())
436 return LLVMInt32Type ();
437 else if (type == LLVMInt16Type ())
438 return LLVMInt32Type ();
439 else if (type == LLVMFloatType ())
440 return LLVMDoubleType ();
441 else
442 return type;
446 * regtype_to_llvm_type:
448 * Return the LLVM type corresponding to the regtype C used in instruction
449 * descriptions.
451 static LLVMTypeRef
452 regtype_to_llvm_type (char c)
454 switch (c) {
455 case 'i':
456 return LLVMInt32Type ();
457 case 'l':
458 return LLVMInt64Type ();
459 case 'f':
460 return LLVMDoubleType ();
461 default:
462 return NULL;
467 * op_to_llvm_type:
469 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
471 static LLVMTypeRef
472 op_to_llvm_type (int opcode)
474 switch (opcode) {
475 case OP_ICONV_TO_I1:
476 case OP_LCONV_TO_I1:
477 return LLVMInt8Type ();
478 case OP_ICONV_TO_U1:
479 case OP_LCONV_TO_U1:
480 return LLVMInt8Type ();
481 case OP_ICONV_TO_I2:
482 case OP_LCONV_TO_I2:
483 return LLVMInt16Type ();
484 case OP_ICONV_TO_U2:
485 case OP_LCONV_TO_U2:
486 return LLVMInt16Type ();
487 case OP_ICONV_TO_I4:
488 case OP_LCONV_TO_I4:
489 return LLVMInt32Type ();
490 case OP_ICONV_TO_U4:
491 case OP_LCONV_TO_U4:
492 return LLVMInt32Type ();
493 case OP_ICONV_TO_I8:
494 return LLVMInt64Type ();
495 case OP_ICONV_TO_R4:
496 return LLVMFloatType ();
497 case OP_ICONV_TO_R8:
498 return LLVMDoubleType ();
499 case OP_ICONV_TO_U8:
500 return LLVMInt64Type ();
501 case OP_FCONV_TO_I4:
502 return LLVMInt32Type ();
503 case OP_FCONV_TO_I8:
504 return LLVMInt64Type ();
505 case OP_FCONV_TO_I1:
506 case OP_FCONV_TO_U1:
507 return LLVMInt8Type ();
508 case OP_FCONV_TO_I2:
509 case OP_FCONV_TO_U2:
510 return LLVMInt16Type ();
511 case OP_FCONV_TO_I:
512 case OP_FCONV_TO_U:
513 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
514 case OP_IADD_OVF:
515 case OP_IADD_OVF_UN:
516 case OP_ISUB_OVF:
517 case OP_ISUB_OVF_UN:
518 case OP_IMUL_OVF:
519 case OP_IMUL_OVF_UN:
520 return LLVMInt32Type ();
521 case OP_LADD_OVF:
522 case OP_LADD_OVF_UN:
523 case OP_LSUB_OVF:
524 case OP_LSUB_OVF_UN:
525 case OP_LMUL_OVF:
526 case OP_LMUL_OVF_UN:
527 return LLVMInt64Type ();
528 default:
529 printf ("%s\n", mono_inst_name (opcode));
530 g_assert_not_reached ();
531 return NULL;
536 * load_store_to_llvm_type:
538 * Return the size/sign/zero extension corresponding to the load/store opcode
539 * OPCODE.
541 static LLVMTypeRef
542 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
544 *sext = FALSE;
545 *zext = FALSE;
547 switch (opcode) {
548 case OP_LOADI1_MEMBASE:
549 case OP_STOREI1_MEMBASE_REG:
550 case OP_STOREI1_MEMBASE_IMM:
551 *size = 1;
552 *sext = TRUE;
553 return LLVMInt8Type ();
554 case OP_LOADU1_MEMBASE:
555 case OP_LOADU1_MEM:
556 *size = 1;
557 *zext = TRUE;
558 return LLVMInt8Type ();
559 case OP_LOADI2_MEMBASE:
560 case OP_STOREI2_MEMBASE_REG:
561 case OP_STOREI2_MEMBASE_IMM:
562 *size = 2;
563 *sext = TRUE;
564 return LLVMInt16Type ();
565 case OP_LOADU2_MEMBASE:
566 case OP_LOADU2_MEM:
567 *size = 2;
568 *zext = TRUE;
569 return LLVMInt16Type ();
570 case OP_LOADI4_MEMBASE:
571 case OP_LOADU4_MEMBASE:
572 case OP_LOADI4_MEM:
573 case OP_LOADU4_MEM:
574 case OP_STOREI4_MEMBASE_REG:
575 case OP_STOREI4_MEMBASE_IMM:
576 *size = 4;
577 return LLVMInt32Type ();
578 case OP_LOADI8_MEMBASE:
579 case OP_LOADI8_MEM:
580 case OP_STOREI8_MEMBASE_REG:
581 case OP_STOREI8_MEMBASE_IMM:
582 *size = 8;
583 return LLVMInt64Type ();
584 case OP_LOADR4_MEMBASE:
585 case OP_STORER4_MEMBASE_REG:
586 *size = 4;
587 return LLVMFloatType ();
588 case OP_LOADR8_MEMBASE:
589 case OP_STORER8_MEMBASE_REG:
590 *size = 8;
591 return LLVMDoubleType ();
592 case OP_LOAD_MEMBASE:
593 case OP_LOAD_MEM:
594 case OP_STORE_MEMBASE_REG:
595 case OP_STORE_MEMBASE_IMM:
596 *size = sizeof (gpointer);
597 return IntPtrType ();
598 default:
599 g_assert_not_reached ();
600 return NULL;
605 * ovf_op_to_intrins:
607 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
609 static const char*
610 ovf_op_to_intrins (int opcode)
612 switch (opcode) {
613 case OP_IADD_OVF:
614 return "llvm.sadd.with.overflow.i32";
615 case OP_IADD_OVF_UN:
616 return "llvm.uadd.with.overflow.i32";
617 case OP_ISUB_OVF:
618 return "llvm.ssub.with.overflow.i32";
619 case OP_ISUB_OVF_UN:
620 return "llvm.usub.with.overflow.i32";
621 case OP_IMUL_OVF:
622 return "llvm.smul.with.overflow.i32";
623 case OP_IMUL_OVF_UN:
624 return "llvm.umul.with.overflow.i32";
625 case OP_LADD_OVF:
626 return "llvm.sadd.with.overflow.i64";
627 case OP_LADD_OVF_UN:
628 return "llvm.uadd.with.overflow.i64";
629 case OP_LSUB_OVF:
630 return "llvm.ssub.with.overflow.i64";
631 case OP_LSUB_OVF_UN:
632 return "llvm.usub.with.overflow.i64";
633 case OP_LMUL_OVF:
634 return "llvm.smul.with.overflow.i64";
635 case OP_LMUL_OVF_UN:
636 return "llvm.umul.with.overflow.i64";
637 default:
638 g_assert_not_reached ();
639 return NULL;
643 static const char*
644 simd_op_to_intrins (int opcode)
646 switch (opcode) {
647 #if defined(TARGET_X86) || defined(TARGET_AMD64)
648 case OP_MINPD:
649 return "llvm.x86.sse2.min.pd";
650 case OP_MINPS:
651 return "llvm.x86.sse.min.ps";
652 case OP_PMIND_UN:
653 return "llvm.x86.sse41.pminud";
654 case OP_PMINW_UN:
655 return "llvm.x86.sse41.pminuw";
656 case OP_PMINB_UN:
657 return "llvm.x86.sse2.pminu.b";
658 case OP_PMINW:
659 return "llvm.x86.sse2.pmins.w";
660 case OP_MAXPD:
661 return "llvm.x86.sse2.max.pd";
662 case OP_MAXPS:
663 return "llvm.x86.sse.max.ps";
664 case OP_HADDPD:
665 return "llvm.x86.sse3.hadd.pd";
666 case OP_HADDPS:
667 return "llvm.x86.sse3.hadd.ps";
668 case OP_HSUBPD:
669 return "llvm.x86.sse3.hsub.pd";
670 case OP_HSUBPS:
671 return "llvm.x86.sse3.hsub.ps";
672 case OP_PMAXD_UN:
673 return "llvm.x86.sse41.pmaxud";
674 case OP_PMAXW_UN:
675 return "llvm.x86.sse41.pmaxuw";
676 case OP_PMAXB_UN:
677 return "llvm.x86.sse2.pmaxu.b";
678 case OP_ADDSUBPS:
679 return "llvm.x86.sse3.addsub.ps";
680 case OP_ADDSUBPD:
681 return "llvm.x86.sse3.addsub.pd";
682 case OP_EXTRACT_MASK:
683 return "llvm.x86.sse2.pmovmskb.128";
684 case OP_PSHRW:
685 case OP_PSHRW_REG:
686 return "llvm.x86.sse2.psrli.w";
687 case OP_PSHRD:
688 case OP_PSHRD_REG:
689 return "llvm.x86.sse2.psrli.d";
690 case OP_PSHRQ:
691 case OP_PSHRQ_REG:
692 return "llvm.x86.sse2.psrli.q";
693 case OP_PSHLW:
694 case OP_PSHLW_REG:
695 return "llvm.x86.sse2.pslli.w";
696 case OP_PSHLD:
697 case OP_PSHLD_REG:
698 return "llvm.x86.sse2.pslli.d";
699 case OP_PSHLQ:
700 case OP_PSHLQ_REG:
701 return "llvm.x86.sse2.pslli.q";
702 case OP_PSARW:
703 case OP_PSARW_REG:
704 return "llvm.x86.sse2.psrai.w";
705 case OP_PSARD:
706 case OP_PSARD_REG:
707 return "llvm.x86.sse2.psrai.d";
708 case OP_PADDB_SAT:
709 return "llvm.x86.sse2.padds.b";
710 case OP_PADDW_SAT:
711 return "llvm.x86.sse2.padds.w";
712 case OP_PSUBB_SAT:
713 return "llvm.x86.sse2.psubs.b";
714 case OP_PSUBW_SAT:
715 return "llvm.x86.sse2.psubs.w";
716 case OP_PADDB_SAT_UN:
717 return "llvm.x86.sse2.paddus.b";
718 case OP_PADDW_SAT_UN:
719 return "llvm.x86.sse2.paddus.w";
720 case OP_PSUBB_SAT_UN:
721 return "llvm.x86.sse2.psubus.b";
722 case OP_PSUBW_SAT_UN:
723 return "llvm.x86.sse2.psubus.w";
724 case OP_PAVGB_UN:
725 return "llvm.x86.sse2.pavg.b";
726 case OP_PAVGW_UN:
727 return "llvm.x86.sse2.pavg.w";
728 case OP_SQRTPS:
729 return "llvm.x86.sse.sqrt.ps";
730 case OP_SQRTPD:
731 return "llvm.x86.sse2.sqrt.pd";
732 case OP_RSQRTPS:
733 return "llvm.x86.sse.rsqrt.ps";
734 case OP_RCPPS:
735 return "llvm.x86.sse.rcp.ps";
736 case OP_CVTDQ2PD:
737 return "llvm.x86.sse2.cvtdq2pd";
738 case OP_CVTDQ2PS:
739 return "llvm.x86.sse2.cvtdq2ps";
740 case OP_CVTPD2DQ:
741 return "llvm.x86.sse2.cvtpd2dq";
742 case OP_CVTPS2DQ:
743 return "llvm.x86.sse2.cvtps2dq";
744 case OP_CVTPD2PS:
745 return "llvm.x86.sse2.cvtpd2ps";
746 case OP_CVTPS2PD:
747 return "llvm.x86.sse2.cvtps2pd";
748 case OP_CVTTPD2DQ:
749 return "llvm.x86.sse2.cvttpd2dq";
750 case OP_CVTTPS2DQ:
751 return "llvm.x86.sse2.cvttps2dq";
752 case OP_COMPPS:
753 return "llvm.x86.sse.cmp.ps";
754 case OP_COMPPD:
755 return "llvm.x86.sse2.cmp.pd";
756 case OP_PACKW:
757 return "llvm.x86.sse2.packsswb.128";
758 case OP_PACKD:
759 return "llvm.x86.sse2.packssdw.128";
760 case OP_PACKW_UN:
761 return "llvm.x86.sse2.packuswb.128";
762 case OP_PACKD_UN:
763 return "llvm.x86.sse41.packusdw";
764 case OP_PMULW_HIGH:
765 return "llvm.x86.sse2.pmulh.w";
766 case OP_PMULW_HIGH_UN:
767 return "llvm.x86.sse2.pmulhu.w";
768 #endif
769 default:
770 g_assert_not_reached ();
771 return NULL;
775 static LLVMTypeRef
776 simd_op_to_llvm_type (int opcode)
778 #if defined(TARGET_X86) || defined(TARGET_AMD64)
779 switch (opcode) {
780 case OP_EXTRACT_R8:
781 case OP_EXPAND_R8:
782 return type_to_simd_type (MONO_TYPE_R8);
783 case OP_EXTRACT_I8:
784 case OP_EXPAND_I8:
785 return type_to_simd_type (MONO_TYPE_I8);
786 case OP_EXTRACT_I4:
787 case OP_EXPAND_I4:
788 return type_to_simd_type (MONO_TYPE_I4);
789 case OP_EXTRACT_I2:
790 case OP_EXTRACT_U2:
791 case OP_EXTRACTX_U2:
792 case OP_EXPAND_I2:
793 return type_to_simd_type (MONO_TYPE_I2);
794 case OP_EXTRACT_I1:
795 case OP_EXTRACT_U1:
796 case OP_EXPAND_I1:
797 return type_to_simd_type (MONO_TYPE_I1);
798 case OP_EXPAND_R4:
799 return type_to_simd_type (MONO_TYPE_R4);
800 case OP_CVTDQ2PD:
801 case OP_CVTDQ2PS:
802 return type_to_simd_type (MONO_TYPE_I4);
803 case OP_CVTPD2DQ:
804 case OP_CVTPD2PS:
805 case OP_CVTTPD2DQ:
806 return type_to_simd_type (MONO_TYPE_R8);
807 case OP_CVTPS2DQ:
808 case OP_CVTPS2PD:
809 case OP_CVTTPS2DQ:
810 return type_to_simd_type (MONO_TYPE_R4);
811 case OP_EXTRACT_MASK:
812 return type_to_simd_type (MONO_TYPE_I1);
813 case OP_SQRTPS:
814 case OP_RSQRTPS:
815 case OP_RCPPS:
816 case OP_DUPPS_LOW:
817 case OP_DUPPS_HIGH:
818 return type_to_simd_type (MONO_TYPE_R4);
819 case OP_SQRTPD:
820 case OP_DUPPD:
821 return type_to_simd_type (MONO_TYPE_R8);
822 default:
823 g_assert_not_reached ();
824 return NULL;
826 #else
827 return NULL;
828 #endif
832 * get_bb:
834 * Return the LLVM basic block corresponding to BB.
836 static LLVMBasicBlockRef
837 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
839 char bb_name [128];
841 if (ctx->bblocks [bb->block_num].bblock == NULL) {
842 if (bb->flags & BB_EXCEPTION_HANDLER) {
843 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
844 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
845 } else {
846 sprintf (bb_name, "BB%d", bb->block_num);
849 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
850 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
853 return ctx->bblocks [bb->block_num].bblock;
857 * get_end_bb:
859 * Return the last LLVM bblock corresponding to BB.
860 * This might not be equal to the bb returned by get_bb () since we need to generate
861 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
863 static LLVMBasicBlockRef
864 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
866 get_bb (ctx, bb);
867 return ctx->bblocks [bb->block_num].end_bblock;
870 static LLVMBasicBlockRef
871 gen_bb (EmitContext *ctx, const char *prefix)
873 char bb_name [128];
875 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
876 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
880 * resolve_patch:
882 * Return the target of the patch identified by TYPE and TARGET.
884 static gpointer
885 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
887 MonoJumpInfo ji;
889 memset (&ji, 0, sizeof (ji));
890 ji.type = type;
891 ji.data.target = target;
893 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
897 * convert_full:
899 * Emit code to convert the LLVM value V to DTYPE.
901 static LLVMValueRef
902 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
904 LLVMTypeRef stype = LLVMTypeOf (v);
906 if (stype != dtype) {
907 gboolean ext = FALSE;
909 /* Extend */
910 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
911 ext = TRUE;
912 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
913 ext = TRUE;
914 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
915 ext = TRUE;
917 if (ext)
918 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
920 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
921 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
923 /* Trunc */
924 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
925 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
926 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
927 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
928 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
929 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
930 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
931 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
933 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
934 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
935 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
936 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
937 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
938 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
940 #ifdef MONO_ARCH_SOFT_FLOAT
941 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
942 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
943 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
944 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
945 #endif
947 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
948 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
950 LLVMDumpValue (v);
951 LLVMDumpValue (LLVMConstNull (dtype));
952 g_assert_not_reached ();
953 return NULL;
954 } else {
955 return v;
959 static LLVMValueRef
960 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
962 return convert_full (ctx, v, dtype, FALSE);
966 * emit_volatile_load:
968 * If vreg is volatile, emit a load from its address.
970 static LLVMValueRef
971 emit_volatile_load (EmitContext *ctx, int vreg)
973 MonoType *t;
975 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
976 t = ctx->vreg_cli_types [vreg];
977 if (t && !t->byref) {
979 * Might have to zero extend since llvm doesn't have
980 * unsigned types.
982 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
983 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
984 else if (t->type == MONO_TYPE_U8)
985 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
988 return v;
992 * emit_volatile_store:
994 * If VREG is volatile, emit a store from its value to its address.
996 static void
997 emit_volatile_store (EmitContext *ctx, int vreg)
999 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1001 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1002 g_assert (ctx->addresses [vreg]);
1003 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1007 typedef struct {
1009 * Maps parameter indexes in the original signature to parameter indexes
1010 * in the LLVM signature.
1012 int *pindexes;
1013 /* The indexes of various special arguments in the LLVM signature */
1014 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1015 } LLVMSigInfo;
1018 * sig_to_llvm_sig_full:
1020 * Return the LLVM signature corresponding to the mono signature SIG using the
1021 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1023 static LLVMTypeRef
1024 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1025 LLVMSigInfo *sinfo)
1027 LLVMTypeRef ret_type;
1028 LLVMTypeRef *param_types = NULL;
1029 LLVMTypeRef res;
1030 int i, j, pindex, vret_arg_pindex = 0;
1031 int *pindexes;
1032 gboolean vretaddr = FALSE;
1034 if (sinfo)
1035 memset (sinfo, 0, sizeof (LLVMSigInfo));
1037 ret_type = type_to_llvm_type (ctx, sig->ret);
1038 CHECK_FAILURE (ctx);
1040 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1041 /* LLVM models this by returning an aggregate value */
1042 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1043 LLVMTypeRef members [2];
1045 members [0] = IntPtrType ();
1046 ret_type = LLVMStructType (members, 1, FALSE);
1047 } else {
1048 g_assert_not_reached ();
1050 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1051 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1052 vretaddr = TRUE;
1053 ret_type = LLVMVoidType ();
1056 pindexes = g_new0 (int, sig->param_count);
1057 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1058 pindex = 0;
1059 if (cinfo && cinfo->rgctx_arg) {
1060 if (sinfo)
1061 sinfo->rgctx_arg_pindex = pindex;
1062 param_types [pindex] = IntPtrType ();
1063 pindex ++;
1065 if (cinfo && cinfo->imt_arg) {
1066 if (sinfo)
1067 sinfo->imt_arg_pindex = pindex;
1068 param_types [pindex] = IntPtrType ();
1069 pindex ++;
1071 if (vretaddr) {
1072 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1073 vret_arg_pindex = pindex;
1074 if (cinfo->vret_arg_index == 1) {
1075 /* Add the slots consumed by the first argument */
1076 LLVMArgInfo *ainfo = &cinfo->args [0];
1077 switch (ainfo->storage) {
1078 case LLVMArgVtypeInReg:
1079 for (j = 0; j < 2; ++j) {
1080 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1081 vret_arg_pindex ++;
1083 break;
1084 default:
1085 vret_arg_pindex ++;
1089 if (sinfo)
1090 sinfo->vret_arg_pindex = vret_arg_pindex;
1093 if (vretaddr && vret_arg_pindex == pindex)
1094 param_types [pindex ++] = IntPtrType ();
1095 if (sig->hasthis) {
1096 if (sinfo)
1097 sinfo->this_arg_pindex = pindex;
1098 param_types [pindex ++] = IntPtrType ();
1100 if (vretaddr && vret_arg_pindex == pindex)
1101 param_types [pindex ++] = IntPtrType ();
1102 for (i = 0; i < sig->param_count; ++i) {
1103 if (vretaddr && vret_arg_pindex == pindex)
1104 param_types [pindex ++] = IntPtrType ();
1105 pindexes [i] = pindex;
1106 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1107 for (j = 0; j < 2; ++j) {
1108 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1109 case LLVMArgInIReg:
1110 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1111 break;
1112 case LLVMArgNone:
1113 break;
1114 default:
1115 g_assert_not_reached ();
1118 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1119 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1120 CHECK_FAILURE (ctx);
1121 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1122 pindex ++;
1123 } else {
1124 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1127 if (vretaddr && vret_arg_pindex == pindex)
1128 param_types [pindex ++] = IntPtrType ();
1130 CHECK_FAILURE (ctx);
1132 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1133 g_free (param_types);
1135 if (sinfo) {
1136 sinfo->pindexes = pindexes;
1137 } else {
1138 g_free (pindexes);
1141 return res;
1143 FAILURE:
1144 g_free (param_types);
1146 return NULL;
1149 static LLVMTypeRef
1150 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1152 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1156 * LLVMFunctionType1:
1158 * Create an LLVM function type from the arguments.
1160 static G_GNUC_UNUSED LLVMTypeRef
1161 LLVMFunctionType1(LLVMTypeRef ReturnType,
1162 LLVMTypeRef ParamType1,
1163 int IsVarArg)
1165 LLVMTypeRef param_types [1];
1167 param_types [0] = ParamType1;
1169 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1173 * LLVMFunctionType2:
1175 * Create an LLVM function type from the arguments.
1177 static G_GNUC_UNUSED LLVMTypeRef
1178 LLVMFunctionType2(LLVMTypeRef ReturnType,
1179 LLVMTypeRef ParamType1,
1180 LLVMTypeRef ParamType2,
1181 int IsVarArg)
1183 LLVMTypeRef param_types [2];
1185 param_types [0] = ParamType1;
1186 param_types [1] = ParamType2;
1188 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1192 * LLVMFunctionType3:
1194 * Create an LLVM function type from the arguments.
1196 static G_GNUC_UNUSED LLVMTypeRef
1197 LLVMFunctionType3(LLVMTypeRef ReturnType,
1198 LLVMTypeRef ParamType1,
1199 LLVMTypeRef ParamType2,
1200 LLVMTypeRef ParamType3,
1201 int IsVarArg)
1203 LLVMTypeRef param_types [3];
1205 param_types [0] = ParamType1;
1206 param_types [1] = ParamType2;
1207 param_types [2] = ParamType3;
1209 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1213 * create_builder:
1215 * Create an LLVM builder and remember it so it can be freed later.
1217 static LLVMBuilderRef
1218 create_builder (EmitContext *ctx)
1220 LLVMBuilderRef builder = LLVMCreateBuilder ();
1222 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1224 return builder;
1227 static LLVMValueRef
1228 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1230 char *callee_name = mono_aot_get_plt_symbol (type, data);
1231 LLVMValueRef callee;
1233 if (!callee_name)
1234 return NULL;
1236 if (ctx->cfg->compile_aot)
1237 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1238 mono_add_patch_info (ctx->cfg, 0, type, data);
1240 // FIXME: Locking
1241 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1242 if (!callee) {
1243 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1245 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1247 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1250 return callee;
1253 static int
1254 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1256 MonoMethodHeader *header = cfg->header;
1257 MonoExceptionClause *clause;
1258 int i;
1260 /* Directly */
1261 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1262 return (bb->region >> 8) - 1;
1264 /* Indirectly */
1265 for (i = 0; i < header->num_clauses; ++i) {
1266 clause = &header->clauses [i];
1268 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1269 return i;
1272 return -1;
1275 static void
1276 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1278 LLVMValueRef md_arg;
1279 int md_kind;
1281 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1282 md_arg = LLVMMDString ("mono", 4);
1283 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1287 * emit_call:
1289 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1290 * a try region.
1292 static LLVMValueRef
1293 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1295 MonoCompile *cfg = ctx->cfg;
1296 LLVMValueRef lcall;
1297 LLVMBuilderRef builder = *builder_ref;
1298 int clause_index;
1300 clause_index = get_handler_clause (cfg, bb);
1302 if (clause_index != -1) {
1303 MonoMethodHeader *header = cfg->header;
1304 MonoExceptionClause *ec = &header->clauses [clause_index];
1305 MonoBasicBlock *tblock;
1306 LLVMBasicBlockRef ex_bb, noex_bb;
1309 * Have to use an invoke instead of a call, branching to the
1310 * handler bblock of the clause containing this bblock.
1313 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1315 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1316 g_assert (tblock);
1318 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1320 ex_bb = get_bb (ctx, tblock);
1322 noex_bb = gen_bb (ctx, "NOEX_BB");
1324 /* Use an invoke */
1325 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1327 builder = ctx->builder = create_builder (ctx);
1328 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1330 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1331 } else {
1332 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1333 ctx->builder = builder;
1336 *builder_ref = ctx->builder;
1338 return lcall;
1341 static LLVMValueRef
1342 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1344 const char *intrins_name;
1345 LLVMValueRef args [16], res;
1346 LLVMTypeRef addr_type;
1348 if (is_faulting && bb->region != -1) {
1350 * We handle loads which can fault by calling a mono specific intrinsic
1351 * using an invoke, so they are handled properly inside try blocks.
1352 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1353 * are marked with IntrReadArgMem.
1355 switch (size) {
1356 case 1:
1357 intrins_name = "llvm.mono.load.i8.p0i8";
1358 break;
1359 case 2:
1360 intrins_name = "llvm.mono.load.i16.p0i16";
1361 break;
1362 case 4:
1363 intrins_name = "llvm.mono.load.i32.p0i32";
1364 break;
1365 case 8:
1366 intrins_name = "llvm.mono.load.i64.p0i64";
1367 break;
1368 default:
1369 g_assert_not_reached ();
1372 addr_type = LLVMTypeOf (addr);
1373 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1374 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1376 args [0] = addr;
1377 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1378 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1379 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1381 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1382 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1383 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1384 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1386 return res;
1387 } else {
1388 LLVMValueRef res;
1391 * We emit volatile loads for loads which can fault, because otherwise
1392 * LLVM will generate invalid code when encountering a load from a
1393 * NULL address.
1395 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1397 /* Mark it with a custom metadata */
1399 if (is_faulting)
1400 set_metadata_flag (res, "mono.faulting.load");
1403 return res;
1407 static void
1408 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1410 const char *intrins_name;
1411 LLVMValueRef args [16];
1413 if (is_faulting && bb->region != -1) {
1414 switch (size) {
1415 case 1:
1416 intrins_name = "llvm.mono.store.i8.p0i8";
1417 break;
1418 case 2:
1419 intrins_name = "llvm.mono.store.i16.p0i16";
1420 break;
1421 case 4:
1422 intrins_name = "llvm.mono.store.i32.p0i32";
1423 break;
1424 case 8:
1425 intrins_name = "llvm.mono.store.i64.p0i64";
1426 break;
1427 default:
1428 g_assert_not_reached ();
1431 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1432 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1433 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1436 args [0] = value;
1437 args [1] = addr;
1438 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1439 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1440 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1441 } else {
1442 LLVMBuildStore (*builder_ref, value, addr);
1447 * emit_cond_system_exception:
1449 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1450 * Might set the ctx exception.
1452 static void
1453 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1455 LLVMBasicBlockRef ex_bb, noex_bb;
1456 LLVMBuilderRef builder;
1457 MonoClass *exc_class;
1458 LLVMValueRef args [2];
1460 ex_bb = gen_bb (ctx, "EX_BB");
1461 noex_bb = gen_bb (ctx, "NOEX_BB");
1463 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1465 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1466 g_assert (exc_class);
1468 /* Emit exception throwing code */
1469 builder = create_builder (ctx);
1470 LLVMPositionBuilderAtEnd (builder, ex_bb);
1472 if (!ctx->lmodule->throw_corlib_exception) {
1473 LLVMValueRef callee;
1474 LLVMTypeRef sig;
1475 const char *icall_name;
1477 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1478 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1479 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1480 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1481 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1482 sig = sig_to_llvm_sig (ctx, throw_sig);
1484 if (ctx->cfg->compile_aot) {
1485 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1486 } else {
1487 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1490 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1491 * - On x86, LLVM generated code doesn't push the arguments
1492 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1493 * arguments, not a pc offset.
1495 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1498 mono_memory_barrier ();
1499 ctx->lmodule->throw_corlib_exception = callee;
1502 if (IS_TARGET_X86)
1503 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1504 else
1505 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1508 * The LLVM mono branch contains changes so a block address can be passed as an
1509 * argument to a call.
1511 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1512 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1514 LLVMBuildUnreachable (builder);
1516 ctx->builder = create_builder (ctx);
1517 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1519 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1521 ctx->ex_index ++;
1522 return;
1526 * emit_reg_to_vtype:
1528 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1530 static void
1531 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1533 int j, size;
1535 size = get_vtype_size (t);
1537 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1538 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1541 for (j = 0; j < 2; ++j) {
1542 LLVMValueRef index [2], addr;
1543 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1544 LLVMTypeRef part_type;
1546 if (ainfo->pair_storage [j] == LLVMArgNone)
1547 continue;
1549 part_type = LLVMIntType (part_size * 8);
1550 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1551 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1552 addr = LLVMBuildGEP (builder, address, index, 1, "");
1553 } else {
1554 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1555 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1556 addr = LLVMBuildGEP (builder, address, index, 2, "");
1558 switch (ainfo->pair_storage [j]) {
1559 case LLVMArgInIReg:
1560 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1561 break;
1562 case LLVMArgNone:
1563 break;
1564 default:
1565 g_assert_not_reached ();
1568 size -= sizeof (gpointer);
1573 * emit_vtype_to_reg:
1575 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1576 * into REGS, and the number of registers into NREGS.
1578 static void
1579 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1581 int pindex = 0;
1582 int j, size;
1584 size = get_vtype_size (t);
1586 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1587 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1590 for (j = 0; j < 2; ++j) {
1591 LLVMValueRef index [2], addr;
1592 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1594 if (ainfo->pair_storage [j] == LLVMArgNone)
1595 continue;
1597 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1598 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1599 addr = LLVMBuildGEP (builder, address, index, 1, "");
1600 } else {
1601 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1602 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1603 addr = LLVMBuildGEP (builder, address, index, 2, "");
1605 switch (ainfo->pair_storage [j]) {
1606 case LLVMArgInIReg:
1607 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1608 break;
1609 case LLVMArgNone:
1610 break;
1611 default:
1612 g_assert_not_reached ();
1614 size -= sizeof (gpointer);
1617 *nregs = pindex;
1620 static LLVMValueRef
1621 build_alloca (EmitContext *ctx, MonoType *t)
1623 MonoClass *k = mono_class_from_mono_type (t);
1624 int align;
1626 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1627 align = 16;
1628 else
1629 align = mono_class_min_align (k);
1631 /* Sometimes align is not a power of 2 */
1632 while (mono_is_power_of_two (align) == -1)
1633 align ++;
1636 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1637 * get executed every time control reaches them.
1639 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1641 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1642 return ctx->last_alloca;
1646 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1648 static void
1649 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1651 LLVMTypeRef used_type;
1652 LLVMValueRef used, used_elem;
1654 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1655 used = LLVMAddGlobal (module, used_type, "llvm.used");
1656 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1657 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1658 LLVMSetLinkage (used, LLVMAppendingLinkage);
1659 LLVMSetSection (used, "llvm.metadata");
1663 * emit_entry_bb:
1665 * Emit code to load/convert arguments.
1667 static void
1668 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1670 int i, pindex;
1671 MonoCompile *cfg = ctx->cfg;
1672 MonoMethodSignature *sig = ctx->sig;
1673 LLVMCallInfo *linfo = ctx->linfo;
1674 MonoBasicBlock *bb;
1676 ctx->alloca_builder = create_builder (ctx);
1679 * Handle indirect/volatile variables by allocating memory for them
1680 * using 'alloca', and storing their address in a temporary.
1682 for (i = 0; i < cfg->num_varinfo; ++i) {
1683 MonoInst *var = cfg->varinfo [i];
1684 LLVMTypeRef vtype;
1686 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1687 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1688 CHECK_FAILURE (ctx);
1689 /* Could be already created by an OP_VPHI */
1690 if (!ctx->addresses [var->dreg])
1691 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1692 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1696 for (i = 0; i < sig->param_count; ++i) {
1697 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1698 int reg = cfg->args [i + sig->hasthis]->dreg;
1700 if (ainfo->storage == LLVMArgVtypeInReg) {
1701 LLVMValueRef regs [2];
1704 * Emit code to save the argument from the registers to
1705 * the real argument.
1707 pindex = ctx->pindexes [i];
1708 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1709 if (ainfo->pair_storage [1] != LLVMArgNone)
1710 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1711 else
1712 regs [1] = NULL;
1714 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1716 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1718 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1719 /* Treat these as normal values */
1720 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1722 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1723 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1725 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1726 /* Treat these as normal values */
1727 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1729 } else {
1730 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1734 if (cfg->vret_addr)
1735 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1736 if (sig->hasthis)
1737 emit_volatile_store (ctx, cfg->args [0]->dreg);
1738 for (i = 0; i < sig->param_count; ++i)
1739 if (!mini_type_is_vtype (cfg, sig->params [i]))
1740 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1742 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1743 LLVMValueRef this_alloc;
1746 * The exception handling code needs the location where the this argument was
1747 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1748 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1749 * location into the LSDA.
1751 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1752 /* This volatile store will keep the alloca alive */
1753 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1755 set_metadata_flag (this_alloc, "mono.this");
1758 if (cfg->rgctx_var) {
1759 LLVMValueRef rgctx_alloc, store;
1762 * We handle the rgctx arg similarly to the this pointer.
1764 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1765 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1766 /* This volatile store will keep the alloca alive */
1767 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1769 set_metadata_flag (rgctx_alloc, "mono.this");
1773 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1774 * it needs to continue normally, or return back to the exception handling system.
1776 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1777 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1778 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1779 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1780 char name [128];
1781 LLVMValueRef val;
1783 sprintf (name, "finally_ind_bb%d", bb->block_num);
1784 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1785 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1787 ctx->bblocks [bb->block_num].finally_ind = val;
1790 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1791 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1792 * LLVM optimizer passes.
1794 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1795 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1799 FAILURE:
1803 /* Have to export this for AOT */
1804 void
1805 mono_personality (void);
1807 void
1808 mono_personality (void)
1810 /* Not used */
1811 g_assert_not_reached ();
1814 static void
1815 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1817 MonoCompile *cfg = ctx->cfg;
1818 LLVMModuleRef module = ctx->module;
1819 LLVMValueRef *values = ctx->values;
1820 LLVMValueRef *addresses = ctx->addresses;
1821 MonoCallInst *call = (MonoCallInst*)ins;
1822 MonoMethodSignature *sig = call->signature;
1823 LLVMValueRef callee = NULL, lcall;
1824 LLVMValueRef *args;
1825 LLVMCallInfo *cinfo;
1826 GSList *l;
1827 int i, len, nargs;
1828 gboolean vretaddr;
1829 LLVMTypeRef llvm_sig;
1830 gpointer target;
1831 gboolean virtual, calli;
1832 LLVMBuilderRef builder = *builder_ref;
1833 LLVMSigInfo sinfo;
1835 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1836 LLVM_FAILURE (ctx, "non-default callconv");
1838 cinfo = call->cinfo;
1839 if (call->rgctx_arg_reg)
1840 cinfo->rgctx_arg = TRUE;
1841 if (call->imt_arg_reg)
1842 cinfo->imt_arg = TRUE;
1844 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1846 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1847 CHECK_FAILURE (ctx);
1849 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);
1850 calli = (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG);
1852 /* FIXME: Avoid creating duplicate methods */
1854 if (ins->flags & MONO_INST_HAS_METHOD) {
1855 if (virtual) {
1856 callee = NULL;
1857 } else {
1858 if (cfg->compile_aot) {
1859 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1860 if (!callee)
1861 LLVM_FAILURE (ctx, "can't encode patch");
1862 } else {
1863 callee = LLVMAddFunction (module, "", llvm_sig);
1865 target =
1866 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1867 call->method);
1868 LLVMAddGlobalMapping (ee, callee, target);
1871 } else if (calli) {
1872 } else {
1873 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1875 if (info) {
1877 MonoJumpInfo ji;
1879 memset (&ji, 0, sizeof (ji));
1880 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1881 ji.data.target = info->name;
1883 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1885 if (cfg->compile_aot) {
1886 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1887 if (!callee)
1888 LLVM_FAILURE (ctx, "can't encode patch");
1889 } else {
1890 callee = LLVMAddFunction (module, "", llvm_sig);
1891 target = (gpointer)mono_icall_get_wrapper (info);
1892 LLVMAddGlobalMapping (ee, callee, target);
1894 } else {
1895 if (cfg->compile_aot) {
1896 callee = NULL;
1897 if (cfg->abs_patches) {
1898 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1899 if (abs_ji) {
1900 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1901 if (!callee)
1902 LLVM_FAILURE (ctx, "can't encode patch");
1905 if (!callee)
1906 LLVM_FAILURE (ctx, "aot");
1907 } else {
1908 callee = LLVMAddFunction (module, "", llvm_sig);
1909 target = NULL;
1910 if (cfg->abs_patches) {
1911 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1912 if (abs_ji) {
1914 * FIXME: Some trampolines might have
1915 * their own calling convention on some platforms.
1917 #ifndef TARGET_AMD64
1918 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
1919 LLVM_FAILURE (ctx, "trampoline with own cconv");
1920 #endif
1921 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1922 LLVMAddGlobalMapping (ee, callee, target);
1925 if (!target)
1926 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1931 if (virtual) {
1932 int size = sizeof (gpointer);
1933 LLVMValueRef index;
1935 g_assert (ins->inst_offset % size == 0);
1936 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1938 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1939 } else if (calli) {
1940 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1941 } else {
1942 if (ins->flags & MONO_INST_HAS_METHOD) {
1947 * Collect and convert arguments
1949 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
1950 len = sizeof (LLVMValueRef) * nargs;
1951 args = alloca (len);
1952 memset (args, 0, len);
1953 l = call->out_ireg_args;
1955 if (call->rgctx_arg_reg) {
1956 g_assert (values [call->rgctx_arg_reg]);
1957 g_assert (sinfo.rgctx_arg_pindex < nargs);
1958 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1960 if (call->imt_arg_reg) {
1961 g_assert (values [call->imt_arg_reg]);
1962 g_assert (sinfo.imt_arg_pindex < nargs);
1963 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1966 if (vretaddr) {
1967 if (!addresses [call->inst.dreg])
1968 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1969 g_assert (sinfo.vret_arg_pindex < nargs);
1970 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1973 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1974 guint32 regpair;
1975 int reg, pindex;
1976 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1978 if (sig->hasthis) {
1979 if (i == 0)
1980 pindex = sinfo.this_arg_pindex;
1981 else
1982 pindex = sinfo.pindexes [i - 1];
1983 } else {
1984 pindex = sinfo.pindexes [i];
1987 regpair = (guint32)(gssize)(l->data);
1988 reg = regpair & 0xffffff;
1989 args [pindex] = values [reg];
1990 if (ainfo->storage == LLVMArgVtypeInReg) {
1991 int j;
1992 LLVMValueRef regs [2];
1993 guint32 nregs;
1995 g_assert (ainfo);
1997 g_assert (addresses [reg]);
1999 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2000 for (j = 0; j < nregs; ++j)
2001 args [pindex ++] = regs [j];
2003 // FIXME: alignment
2004 // FIXME: Get rid of the VMOVE
2005 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2006 g_assert (addresses [reg]);
2007 args [pindex] = addresses [reg];
2008 } else {
2009 g_assert (args [pindex]);
2010 if (i == 0 && sig->hasthis)
2011 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2012 else
2013 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2016 l = l->next;
2019 // FIXME: Align call sites
2022 * Emit the call
2025 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2027 #ifdef LLVM_MONO_BRANCH
2029 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2031 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2032 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2033 #endif
2034 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2035 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2036 if (!sig->pinvoke)
2037 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2039 if (call->rgctx_arg_reg)
2040 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2041 if (call->imt_arg_reg)
2042 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2043 #endif
2045 /* Add byval attributes if needed */
2046 for (i = 0; i < sig->param_count; ++i) {
2047 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2049 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2050 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2055 * Convert the result
2057 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2058 LLVMValueRef regs [2];
2060 if (!addresses [ins->dreg])
2061 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2063 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2064 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2065 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2067 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2068 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2069 /* If the method returns an unsigned value, need to zext it */
2071 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2074 *builder_ref = ctx->builder;
2076 g_free (sinfo.pindexes);
2078 return;
2079 FAILURE:
2080 return;
2083 static void
2084 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2086 MonoCompile *cfg = ctx->cfg;
2087 MonoMethodSignature *sig = ctx->sig;
2088 LLVMValueRef method = ctx->lmethod;
2089 LLVMValueRef *values = ctx->values;
2090 LLVMValueRef *addresses = ctx->addresses;
2091 int i;
2092 LLVMCallInfo *linfo = ctx->linfo;
2093 LLVMModuleRef module = ctx->module;
2094 BBInfo *bblocks = ctx->bblocks;
2095 MonoInst *ins;
2096 LLVMBasicBlockRef cbb;
2097 LLVMBuilderRef builder, starting_builder;
2098 gboolean has_terminator;
2099 LLVMValueRef v;
2100 LLVMValueRef lhs, rhs;
2101 int nins = 0;
2103 cbb = get_bb (ctx, bb);
2104 builder = create_builder (ctx);
2105 ctx->builder = builder;
2106 LLVMPositionBuilderAtEnd (builder, cbb);
2108 if (bb == cfg->bb_entry)
2109 emit_entry_bb (ctx, builder);
2110 CHECK_FAILURE (ctx);
2112 if (bb->flags & BB_EXCEPTION_HANDLER) {
2113 LLVMTypeRef i8ptr;
2114 LLVMValueRef personality;
2115 LLVMBasicBlockRef target_bb;
2116 MonoInst *exvar;
2117 static gint32 mapping_inited;
2118 static int ti_generator;
2119 char ti_name [128];
2120 MonoClass **ti;
2121 LLVMValueRef type_info;
2122 int clause_index;
2124 if (!bblocks [bb->block_num].invoke_target) {
2126 * LLVM asserts if llvm.eh.selector is called from a bblock which
2127 * doesn't have an invoke pointing at it.
2128 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2130 LLVM_FAILURE (ctx, "handler without invokes");
2133 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2135 if (cfg->compile_aot) {
2136 /* Use a dummy personality function */
2137 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2138 g_assert (personality);
2139 } else {
2140 personality = LLVMGetNamedFunction (module, "mono_personality");
2141 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2142 LLVMAddGlobalMapping (ee, personality, mono_personality);
2145 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2147 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2150 * Create the type info
2152 sprintf (ti_name, "type_info_%d", ti_generator);
2153 ti_generator ++;
2155 if (cfg->compile_aot) {
2156 /* decode_eh_frame () in aot-runtime.c will decode this */
2157 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2158 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2160 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2161 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2164 * Enabling this causes llc to crash:
2165 * http://llvm.org/bugs/show_bug.cgi?id=6102
2167 //LLVM_FAILURE (ctx, "aot+clauses");
2168 #ifdef TARGET_ARM
2169 // test_0_invalid_unbox_arrays () fails
2170 LLVM_FAILURE (ctx, "aot+clauses");
2171 #endif
2172 } else {
2174 * After the cfg mempool is freed, the type info will point to stale memory,
2175 * but this is not a problem, since we decode it once in exception_cb during
2176 * compilation.
2178 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2179 *(gint32*)ti = clause_index;
2181 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2183 LLVMAddGlobalMapping (ee, type_info, ti);
2187 LLVMTypeRef members [2], ret_type;
2188 LLVMValueRef landing_pad;
2190 members [0] = i8ptr;
2191 members [1] = LLVMInt32Type ();
2192 ret_type = LLVMStructType (members, 2, FALSE);
2194 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2195 LLVMAddClause (landing_pad, type_info);
2197 /* Store the exception into the exvar */
2198 if (bb->in_scount == 1) {
2199 g_assert (bb->in_scount == 1);
2200 exvar = bb->in_stack [0];
2202 // FIXME: This is shared with filter clauses ?
2203 g_assert (!values [exvar->dreg]);
2205 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2206 emit_volatile_store (ctx, exvar->dreg);
2210 /* Start a new bblock which CALL_HANDLER can branch to */
2211 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2212 if (target_bb) {
2213 LLVMBuildBr (builder, target_bb);
2215 ctx->builder = builder = create_builder (ctx);
2216 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2218 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2222 has_terminator = FALSE;
2223 starting_builder = builder;
2224 for (ins = bb->code; ins; ins = ins->next) {
2225 const char *spec = LLVM_INS_INFO (ins->opcode);
2226 char *dname = NULL;
2227 char dname_buf [128];
2229 nins ++;
2230 if (nins > 5000 && builder == starting_builder) {
2231 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2232 LLVM_FAILURE (ctx, "basic block too long");
2235 if (has_terminator)
2236 /* There could be instructions after a terminator, skip them */
2237 break;
2239 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2240 sprintf (dname_buf, "t%d", ins->dreg);
2241 dname = dname_buf;
2244 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2245 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2247 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2248 lhs = emit_volatile_load (ctx, ins->sreg1);
2249 } else {
2250 /* It is ok for SETRET to have an uninitialized argument */
2251 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2252 LLVM_FAILURE (ctx, "sreg1");
2253 lhs = values [ins->sreg1];
2255 } else {
2256 lhs = NULL;
2259 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2260 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2261 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2262 rhs = emit_volatile_load (ctx, ins->sreg2);
2263 } else {
2264 if (!values [ins->sreg2])
2265 LLVM_FAILURE (ctx, "sreg2");
2266 rhs = values [ins->sreg2];
2268 } else {
2269 rhs = NULL;
2272 //mono_print_ins (ins);
2273 switch (ins->opcode) {
2274 case OP_NOP:
2275 case OP_NOT_NULL:
2276 case OP_LIVERANGE_START:
2277 case OP_LIVERANGE_END:
2278 break;
2279 case OP_ICONST:
2280 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2281 break;
2282 case OP_I8CONST:
2283 #if SIZEOF_VOID_P == 4
2284 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2285 #else
2286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2287 #endif
2288 break;
2289 case OP_R8CONST:
2290 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2291 break;
2292 case OP_R4CONST:
2293 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2294 break;
2295 case OP_BR:
2296 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2297 has_terminator = TRUE;
2298 break;
2299 case OP_SWITCH: {
2300 int i;
2301 LLVMValueRef v;
2302 char bb_name [128];
2303 LLVMBasicBlockRef new_bb;
2304 LLVMBuilderRef new_builder;
2306 // The default branch is already handled
2307 // FIXME: Handle it here
2309 /* Start new bblock */
2310 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2311 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2313 lhs = convert (ctx, lhs, LLVMInt32Type ());
2314 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2315 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2316 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2318 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2321 new_builder = create_builder (ctx);
2322 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2323 LLVMBuildUnreachable (new_builder);
2325 has_terminator = TRUE;
2326 g_assert (!ins->next);
2328 break;
2331 case OP_SETRET:
2332 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2333 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2334 LLVMValueRef part1, retval;
2335 int size;
2337 size = get_vtype_size (sig->ret);
2339 g_assert (addresses [ins->sreg1]);
2341 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2342 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2344 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2346 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2348 LLVMBuildRet (builder, retval);
2349 break;
2352 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2353 LLVMBuildRetVoid (builder);
2354 break;
2357 if (!lhs || ctx->is_dead [ins->sreg1]) {
2359 * The method did not set its return value, probably because it
2360 * ends with a throw.
2362 if (cfg->vret_addr)
2363 LLVMBuildRetVoid (builder);
2364 else
2365 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2366 } else {
2367 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2369 has_terminator = TRUE;
2370 break;
2371 case OP_ICOMPARE:
2372 case OP_FCOMPARE:
2373 case OP_LCOMPARE:
2374 case OP_COMPARE:
2375 case OP_ICOMPARE_IMM:
2376 case OP_LCOMPARE_IMM:
2377 case OP_COMPARE_IMM: {
2378 CompRelation rel;
2379 LLVMValueRef cmp;
2381 if (ins->next->opcode == OP_NOP)
2382 break;
2384 if (ins->next->opcode == OP_BR)
2385 /* The comparison result is not needed */
2386 continue;
2388 rel = mono_opcode_to_cond (ins->next->opcode);
2390 if (ins->opcode == OP_ICOMPARE_IMM) {
2391 lhs = convert (ctx, lhs, LLVMInt32Type ());
2392 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2394 if (ins->opcode == OP_LCOMPARE_IMM) {
2395 lhs = convert (ctx, lhs, LLVMInt64Type ());
2396 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2398 if (ins->opcode == OP_LCOMPARE) {
2399 lhs = convert (ctx, lhs, LLVMInt64Type ());
2400 rhs = convert (ctx, rhs, LLVMInt64Type ());
2402 if (ins->opcode == OP_ICOMPARE) {
2403 lhs = convert (ctx, lhs, LLVMInt32Type ());
2404 rhs = convert (ctx, rhs, LLVMInt32Type ());
2407 if (lhs && rhs) {
2408 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2409 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2410 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2411 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2414 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2415 if (ins->opcode == OP_FCOMPARE)
2416 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2417 else if (ins->opcode == OP_COMPARE_IMM)
2418 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2419 else if (ins->opcode == OP_LCOMPARE_IMM) {
2420 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2421 /* The immediate is encoded in two fields */
2422 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2423 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2424 } else {
2425 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2428 else if (ins->opcode == OP_COMPARE)
2429 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2430 else
2431 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2433 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2434 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2436 * If the target bb contains PHI instructions, LLVM requires
2437 * two PHI entries for this bblock, while we only generate one.
2438 * So convert this to an unconditional bblock. (bxc #171).
2440 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2441 } else {
2442 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2444 has_terminator = TRUE;
2445 } else if (MONO_IS_SETCC (ins->next)) {
2446 sprintf (dname_buf, "t%d", ins->next->dreg);
2447 dname = dname_buf;
2448 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2450 /* Add stores for volatile variables */
2451 emit_volatile_store (ctx, ins->next->dreg);
2452 } else if (MONO_IS_COND_EXC (ins->next)) {
2453 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2454 CHECK_FAILURE (ctx);
2455 builder = ctx->builder;
2456 } else {
2457 LLVM_FAILURE (ctx, "next");
2460 ins = ins->next;
2461 break;
2463 case OP_FCEQ:
2464 case OP_FCLT:
2465 case OP_FCLT_UN:
2466 case OP_FCGT:
2467 case OP_FCGT_UN: {
2468 CompRelation rel;
2469 LLVMValueRef cmp;
2471 rel = mono_opcode_to_cond (ins->opcode);
2473 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2474 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2475 break;
2477 case OP_PHI:
2478 case OP_FPHI:
2479 case OP_VPHI:
2480 case OP_XPHI: {
2481 int i;
2482 gboolean empty = TRUE;
2484 /* Check that all input bblocks really branch to us */
2485 for (i = 0; i < bb->in_count; ++i) {
2486 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2487 ins->inst_phi_args [i + 1] = -1;
2488 else
2489 empty = FALSE;
2492 if (empty) {
2493 /* LLVM doesn't like phi instructions with zero operands */
2494 ctx->is_dead [ins->dreg] = TRUE;
2495 break;
2498 /* Created earlier, insert it now */
2499 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2501 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2502 int sreg1 = ins->inst_phi_args [i + 1];
2503 int count, j;
2506 * Count the number of times the incoming bblock branches to us,
2507 * since llvm requires a separate entry for each.
2509 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2510 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2512 count = 0;
2513 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2514 if (switch_ins->inst_many_bb [j] == bb)
2515 count ++;
2517 } else {
2518 count = 1;
2521 /* Remember for later */
2522 for (j = 0; j < count; ++j) {
2523 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2524 node->bb = bb;
2525 node->phi = ins;
2526 node->in_bb = bb->in_bb [i];
2527 node->sreg = sreg1;
2528 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);
2531 break;
2533 case OP_MOVE:
2534 case OP_LMOVE:
2535 case OP_XMOVE:
2536 case OP_SETFRET:
2537 g_assert (lhs);
2538 values [ins->dreg] = lhs;
2539 break;
2540 case OP_FMOVE: {
2541 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2543 g_assert (lhs);
2544 values [ins->dreg] = lhs;
2546 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2548 * This is added by the spilling pass in case of the JIT,
2549 * but we have to do it ourselves.
2551 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2553 break;
2555 case OP_IADD:
2556 case OP_ISUB:
2557 case OP_IAND:
2558 case OP_IMUL:
2559 case OP_IDIV:
2560 case OP_IDIV_UN:
2561 case OP_IREM:
2562 case OP_IREM_UN:
2563 case OP_IOR:
2564 case OP_IXOR:
2565 case OP_ISHL:
2566 case OP_ISHR:
2567 case OP_ISHR_UN:
2568 case OP_FADD:
2569 case OP_FSUB:
2570 case OP_FMUL:
2571 case OP_FDIV:
2572 case OP_LADD:
2573 case OP_LSUB:
2574 case OP_LMUL:
2575 case OP_LDIV:
2576 case OP_LDIV_UN:
2577 case OP_LREM:
2578 case OP_LREM_UN:
2579 case OP_LAND:
2580 case OP_LOR:
2581 case OP_LXOR:
2582 case OP_LSHL:
2583 case OP_LSHR:
2584 case OP_LSHR_UN:
2585 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2586 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2588 switch (ins->opcode) {
2589 case OP_IADD:
2590 case OP_LADD:
2591 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2592 break;
2593 case OP_ISUB:
2594 case OP_LSUB:
2595 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2596 break;
2597 case OP_IMUL:
2598 case OP_LMUL:
2599 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2600 break;
2601 case OP_IREM:
2602 case OP_LREM:
2603 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2604 break;
2605 case OP_IREM_UN:
2606 case OP_LREM_UN:
2607 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2608 break;
2609 case OP_IDIV:
2610 case OP_LDIV:
2611 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2612 break;
2613 case OP_IDIV_UN:
2614 case OP_LDIV_UN:
2615 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2616 break;
2617 case OP_FDIV:
2618 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2619 break;
2620 case OP_IAND:
2621 case OP_LAND:
2622 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2623 break;
2624 case OP_IOR:
2625 case OP_LOR:
2626 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2627 break;
2628 case OP_IXOR:
2629 case OP_LXOR:
2630 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2631 break;
2632 case OP_ISHL:
2633 case OP_LSHL:
2634 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2635 break;
2636 case OP_ISHR:
2637 case OP_LSHR:
2638 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2639 break;
2640 case OP_ISHR_UN:
2641 case OP_LSHR_UN:
2642 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2643 break;
2645 case OP_FADD:
2646 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2647 break;
2648 case OP_FSUB:
2649 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2650 break;
2651 case OP_FMUL:
2652 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2653 break;
2655 default:
2656 g_assert_not_reached ();
2658 break;
2659 case OP_IADD_IMM:
2660 case OP_ISUB_IMM:
2661 case OP_IMUL_IMM:
2662 case OP_IREM_IMM:
2663 case OP_IREM_UN_IMM:
2664 case OP_IDIV_IMM:
2665 case OP_IDIV_UN_IMM:
2666 case OP_IAND_IMM:
2667 case OP_IOR_IMM:
2668 case OP_IXOR_IMM:
2669 case OP_ISHL_IMM:
2670 case OP_ISHR_IMM:
2671 case OP_ISHR_UN_IMM:
2672 case OP_LADD_IMM:
2673 case OP_LSUB_IMM:
2674 case OP_LREM_IMM:
2675 case OP_LAND_IMM:
2676 case OP_LOR_IMM:
2677 case OP_LXOR_IMM:
2678 case OP_LSHL_IMM:
2679 case OP_LSHR_IMM:
2680 case OP_LSHR_UN_IMM:
2681 case OP_ADD_IMM:
2682 case OP_AND_IMM:
2683 case OP_MUL_IMM:
2684 case OP_SHL_IMM:
2685 case OP_SHR_IMM: {
2686 LLVMValueRef imm;
2688 if (spec [MONO_INST_SRC1] == 'l') {
2689 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2690 } else {
2691 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2694 #if SIZEOF_VOID_P == 4
2695 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2696 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2697 #endif
2699 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2700 lhs = convert (ctx, lhs, IntPtrType ());
2701 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2702 switch (ins->opcode) {
2703 case OP_IADD_IMM:
2704 case OP_LADD_IMM:
2705 case OP_ADD_IMM:
2706 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2707 break;
2708 case OP_ISUB_IMM:
2709 case OP_LSUB_IMM:
2710 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2711 break;
2712 case OP_IMUL_IMM:
2713 case OP_MUL_IMM:
2714 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2715 break;
2716 case OP_IDIV_IMM:
2717 case OP_LDIV_IMM:
2718 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2719 break;
2720 case OP_IDIV_UN_IMM:
2721 case OP_LDIV_UN_IMM:
2722 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2723 break;
2724 case OP_IREM_IMM:
2725 case OP_LREM_IMM:
2726 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2727 break;
2728 case OP_IREM_UN_IMM:
2729 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2730 break;
2731 case OP_IAND_IMM:
2732 case OP_LAND_IMM:
2733 case OP_AND_IMM:
2734 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2735 break;
2736 case OP_IOR_IMM:
2737 case OP_LOR_IMM:
2738 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2739 break;
2740 case OP_IXOR_IMM:
2741 case OP_LXOR_IMM:
2742 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2743 break;
2744 case OP_ISHL_IMM:
2745 case OP_LSHL_IMM:
2746 case OP_SHL_IMM:
2747 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2748 break;
2749 case OP_ISHR_IMM:
2750 case OP_LSHR_IMM:
2751 case OP_SHR_IMM:
2752 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2753 break;
2754 case OP_ISHR_UN_IMM:
2755 /* This is used to implement conv.u4, so the lhs could be an i8 */
2756 lhs = convert (ctx, lhs, LLVMInt32Type ());
2757 imm = convert (ctx, imm, LLVMInt32Type ());
2758 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2759 break;
2760 case OP_LSHR_UN_IMM:
2761 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2762 break;
2763 default:
2764 g_assert_not_reached ();
2766 break;
2768 case OP_INEG:
2769 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2770 break;
2771 case OP_LNEG:
2772 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2773 break;
2774 case OP_FNEG:
2775 lhs = convert (ctx, lhs, LLVMDoubleType ());
2776 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2777 break;
2778 case OP_INOT: {
2779 guint32 v = 0xffffffff;
2780 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2781 break;
2783 case OP_LNOT: {
2784 guint64 v = 0xffffffffffffffffLL;
2785 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2786 break;
2788 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2789 case OP_X86_LEA: {
2790 LLVMValueRef v1, v2;
2792 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2793 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2794 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2795 break;
2797 #endif
2799 case OP_ICONV_TO_I1:
2800 case OP_ICONV_TO_I2:
2801 case OP_ICONV_TO_I4:
2802 case OP_ICONV_TO_U1:
2803 case OP_ICONV_TO_U2:
2804 case OP_ICONV_TO_U4:
2805 case OP_LCONV_TO_I1:
2806 case OP_LCONV_TO_I2:
2807 case OP_LCONV_TO_U1:
2808 case OP_LCONV_TO_U2:
2809 case OP_LCONV_TO_U4: {
2810 gboolean sign;
2812 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);
2814 /* Have to do two casts since our vregs have type int */
2815 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2816 if (sign)
2817 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2818 else
2819 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2820 break;
2822 case OP_ICONV_TO_I8:
2823 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2824 break;
2825 case OP_ICONV_TO_U8:
2826 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2827 break;
2828 case OP_FCONV_TO_I4:
2829 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2830 break;
2831 case OP_FCONV_TO_I1:
2832 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2833 break;
2834 case OP_FCONV_TO_U1:
2835 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2836 break;
2837 case OP_FCONV_TO_I2:
2838 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2839 break;
2840 case OP_FCONV_TO_U2:
2841 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2842 break;
2843 case OP_FCONV_TO_I8:
2844 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2845 break;
2846 case OP_FCONV_TO_I:
2847 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2848 break;
2849 case OP_ICONV_TO_R8:
2850 case OP_LCONV_TO_R8:
2851 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2852 break;
2853 case OP_LCONV_TO_R_UN:
2854 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2855 break;
2856 #if SIZEOF_VOID_P == 4
2857 case OP_LCONV_TO_U:
2858 #endif
2859 case OP_LCONV_TO_I4:
2860 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2861 break;
2862 case OP_ICONV_TO_R4:
2863 case OP_LCONV_TO_R4:
2864 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2865 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2866 break;
2867 case OP_FCONV_TO_R4:
2868 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2869 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2870 break;
2871 case OP_SEXT_I4:
2872 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2873 break;
2874 case OP_ZEXT_I4:
2875 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2876 break;
2877 case OP_TRUNC_I4:
2878 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2879 break;
2880 case OP_LOCALLOC_IMM: {
2881 LLVMValueRef v;
2883 guint32 size = ins->inst_imm;
2884 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2886 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2888 if (ins->flags & MONO_INST_INIT) {
2889 LLVMValueRef args [5];
2891 args [0] = v;
2892 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2893 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2894 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2895 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2896 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2899 values [ins->dreg] = v;
2900 break;
2902 case OP_LOCALLOC: {
2903 LLVMValueRef v, size;
2905 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), "");
2907 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2909 if (ins->flags & MONO_INST_INIT) {
2910 LLVMValueRef args [5];
2912 args [0] = v;
2913 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2914 args [2] = size;
2915 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2916 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2917 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2919 values [ins->dreg] = v;
2920 break;
2923 case OP_LOADI1_MEMBASE:
2924 case OP_LOADU1_MEMBASE:
2925 case OP_LOADI2_MEMBASE:
2926 case OP_LOADU2_MEMBASE:
2927 case OP_LOADI4_MEMBASE:
2928 case OP_LOADU4_MEMBASE:
2929 case OP_LOADI8_MEMBASE:
2930 case OP_LOADR4_MEMBASE:
2931 case OP_LOADR8_MEMBASE:
2932 case OP_LOAD_MEMBASE:
2933 case OP_LOADI8_MEM:
2934 case OP_LOADU1_MEM:
2935 case OP_LOADU2_MEM:
2936 case OP_LOADI4_MEM:
2937 case OP_LOADU4_MEM:
2938 case OP_LOAD_MEM: {
2939 int size = 8;
2940 LLVMValueRef base, index, addr;
2941 LLVMTypeRef t;
2942 gboolean sext = FALSE, zext = FALSE;
2943 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2945 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2947 if (sext || zext)
2948 dname = (char*)"";
2950 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)) {
2951 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2952 } else {
2953 /* _MEMBASE */
2954 base = lhs;
2956 if (ins->inst_offset == 0) {
2957 addr = base;
2958 } else if (ins->inst_offset % size != 0) {
2959 /* Unaligned load */
2960 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2961 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2962 } else {
2963 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2964 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2968 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2970 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2972 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2974 * These will signal LLVM that these loads do not alias any stores, and
2975 * they can't fail, allowing them to be hoisted out of loops.
2977 set_metadata_flag (values [ins->dreg], "mono.noalias");
2978 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2981 if (sext)
2982 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2983 else if (zext)
2984 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2985 else if (ins->opcode == OP_LOADR4_MEMBASE)
2986 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2987 break;
2990 case OP_STOREI1_MEMBASE_REG:
2991 case OP_STOREI2_MEMBASE_REG:
2992 case OP_STOREI4_MEMBASE_REG:
2993 case OP_STOREI8_MEMBASE_REG:
2994 case OP_STORER4_MEMBASE_REG:
2995 case OP_STORER8_MEMBASE_REG:
2996 case OP_STORE_MEMBASE_REG: {
2997 int size = 8;
2998 LLVMValueRef index, addr;
2999 LLVMTypeRef t;
3000 gboolean sext = FALSE, zext = FALSE;
3001 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3003 if (!values [ins->inst_destbasereg])
3004 LLVM_FAILURE (ctx, "inst_destbasereg");
3006 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3008 if (ins->inst_offset % size != 0) {
3009 /* Unaligned store */
3010 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3011 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3012 } else {
3013 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3014 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3016 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3017 break;
3020 case OP_STOREI1_MEMBASE_IMM:
3021 case OP_STOREI2_MEMBASE_IMM:
3022 case OP_STOREI4_MEMBASE_IMM:
3023 case OP_STOREI8_MEMBASE_IMM:
3024 case OP_STORE_MEMBASE_IMM: {
3025 int size = 8;
3026 LLVMValueRef index, addr;
3027 LLVMTypeRef t;
3028 gboolean sext = FALSE, zext = FALSE;
3029 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3031 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3033 if (ins->inst_offset % size != 0) {
3034 /* Unaligned store */
3035 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3036 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3037 } else {
3038 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3039 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3041 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3042 break;
3045 case OP_CHECK_THIS:
3046 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3047 break;
3048 case OP_OUTARG_VTRETADDR:
3049 break;
3050 case OP_VOIDCALL:
3051 case OP_CALL:
3052 case OP_LCALL:
3053 case OP_FCALL:
3054 case OP_VCALL:
3055 case OP_VOIDCALL_MEMBASE:
3056 case OP_CALL_MEMBASE:
3057 case OP_LCALL_MEMBASE:
3058 case OP_FCALL_MEMBASE:
3059 case OP_VCALL_MEMBASE:
3060 case OP_VOIDCALL_REG:
3061 case OP_CALL_REG:
3062 case OP_LCALL_REG:
3063 case OP_FCALL_REG:
3064 case OP_VCALL_REG: {
3065 process_call (ctx, bb, &builder, ins);
3066 CHECK_FAILURE (ctx);
3067 break;
3069 case OP_AOTCONST: {
3070 guint32 got_offset;
3071 LLVMValueRef indexes [2];
3072 MonoJumpInfo *ji;
3073 LLVMValueRef got_entry_addr;
3076 * FIXME: Can't allocate from the cfg mempool since that is freed if
3077 * the LLVM compile fails.
3079 ji = g_new0 (MonoJumpInfo, 1);
3080 ji->type = (MonoJumpInfoType)ins->inst_i1;
3081 ji->data.target = ins->inst_p0;
3083 ji = mono_aot_patch_info_dup (ji);
3085 ji->next = cfg->patch_info;
3086 cfg->patch_info = ji;
3088 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3089 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3091 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3092 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3093 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3095 // FIXME: This doesn't work right now, because it must be
3096 // paired with an invariant.end, and even then, its only in effect
3097 // inside its basic block
3098 #if 0
3100 LLVMValueRef args [3];
3101 LLVMValueRef ptr, val;
3103 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3105 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3106 args [1] = ptr;
3107 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3109 #endif
3111 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3112 break;
3114 case OP_NOT_REACHED:
3115 LLVMBuildUnreachable (builder);
3116 has_terminator = TRUE;
3117 g_assert (bb->block_num < cfg->max_block_num);
3118 ctx->unreachable [bb->block_num] = TRUE;
3119 /* Might have instructions after this */
3120 while (ins->next) {
3121 MonoInst *next = ins->next;
3123 * FIXME: If later code uses the regs defined by these instructions,
3124 * compilation will fail.
3126 MONO_DELETE_INS (bb, next);
3128 break;
3129 case OP_LDADDR: {
3130 MonoInst *var = ins->inst_p0;
3132 values [ins->dreg] = addresses [var->dreg];
3133 break;
3135 case OP_SIN: {
3136 LLVMValueRef args [1];
3138 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3139 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3140 break;
3142 case OP_COS: {
3143 LLVMValueRef args [1];
3145 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3146 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3147 break;
3149 case OP_SQRT: {
3150 LLVMValueRef args [1];
3152 #if 0
3153 /* This no longer seems to happen */
3155 * LLVM optimizes sqrt(nan) into undefined in
3156 * lib/Analysis/ConstantFolding.cpp
3157 * Also, sqrt(NegativeInfinity) is optimized into 0.
3159 LLVM_FAILURE (ctx, "sqrt");
3160 #endif
3161 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3162 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3163 break;
3165 case OP_ABS: {
3166 LLVMValueRef args [1];
3168 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3169 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3170 break;
3173 case OP_IMIN:
3174 case OP_LMIN:
3175 case OP_IMAX:
3176 case OP_LMAX:
3177 case OP_IMIN_UN:
3178 case OP_LMIN_UN:
3179 case OP_IMAX_UN:
3180 case OP_LMAX_UN: {
3181 LLVMValueRef v;
3183 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3184 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3186 switch (ins->opcode) {
3187 case OP_IMIN:
3188 case OP_LMIN:
3189 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3190 break;
3191 case OP_IMAX:
3192 case OP_LMAX:
3193 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3194 break;
3195 case OP_IMIN_UN:
3196 case OP_LMIN_UN:
3197 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3198 break;
3199 case OP_IMAX_UN:
3200 case OP_LMAX_UN:
3201 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3202 break;
3203 default:
3204 g_assert_not_reached ();
3205 break;
3207 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3208 break;
3210 case OP_ATOMIC_EXCHANGE_I4: {
3211 LLVMValueRef args [2];
3213 g_assert (ins->inst_offset == 0);
3215 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3216 args [1] = rhs;
3218 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3219 break;
3221 case OP_ATOMIC_EXCHANGE_I8: {
3222 LLVMValueRef args [2];
3224 g_assert (ins->inst_offset == 0);
3226 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3227 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3228 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3229 break;
3231 case OP_ATOMIC_ADD_NEW_I4: {
3232 LLVMValueRef args [2];
3234 g_assert (ins->inst_offset == 0);
3236 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3237 args [1] = rhs;
3238 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3239 break;
3241 case OP_ATOMIC_ADD_NEW_I8: {
3242 LLVMValueRef args [2];
3244 g_assert (ins->inst_offset == 0);
3246 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3247 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3248 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3249 break;
3251 case OP_ATOMIC_CAS_I4:
3252 case OP_ATOMIC_CAS_I8: {
3253 LLVMValueRef args [3];
3254 LLVMTypeRef t;
3256 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3257 t = LLVMInt32Type ();
3258 } else {
3259 t = LLVMInt64Type ();
3262 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3263 /* comparand */
3264 args [1] = convert (ctx, values [ins->sreg3], t);
3265 /* new value */
3266 args [2] = convert (ctx, values [ins->sreg2], t);
3267 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3268 break;
3270 case OP_MEMORY_BARRIER: {
3271 mono_llvm_build_fence (builder);
3272 break;
3274 case OP_RELAXED_NOP: {
3275 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3276 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3277 break;
3278 #else
3279 break;
3280 #endif
3282 case OP_TLS_GET: {
3283 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3284 #ifdef TARGET_AMD64
3285 // 257 == FS segment register
3286 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3287 #else
3288 // 256 == GS segment register
3289 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3290 #endif
3292 // FIXME: XEN
3293 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3294 #else
3295 LLVM_FAILURE (ctx, "opcode tls-get");
3296 #endif
3298 break;
3302 * Overflow opcodes.
3304 case OP_IADD_OVF:
3305 case OP_IADD_OVF_UN:
3306 case OP_ISUB_OVF:
3307 case OP_ISUB_OVF_UN:
3308 case OP_IMUL_OVF:
3309 case OP_IMUL_OVF_UN:
3310 #if SIZEOF_VOID_P == 8
3311 case OP_LADD_OVF:
3312 case OP_LADD_OVF_UN:
3313 case OP_LSUB_OVF:
3314 case OP_LSUB_OVF_UN:
3315 case OP_LMUL_OVF:
3316 case OP_LMUL_OVF_UN:
3317 #endif
3319 LLVMValueRef args [2], val, ovf, func;
3321 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3322 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3323 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3324 g_assert (func);
3325 val = LLVMBuildCall (builder, func, args, 2, "");
3326 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3327 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3328 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3329 CHECK_FAILURE (ctx);
3330 builder = ctx->builder;
3331 break;
3335 * Valuetypes.
3336 * We currently model them using arrays. Promotion to local vregs is
3337 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3338 * so we always have an entry in cfg->varinfo for them.
3339 * FIXME: Is this needed ?
3341 case OP_VZERO: {
3342 MonoClass *klass = ins->klass;
3343 LLVMValueRef args [5];
3345 if (!klass) {
3346 // FIXME:
3347 LLVM_FAILURE (ctx, "!klass");
3348 break;
3351 if (!addresses [ins->dreg])
3352 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3353 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3354 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3355 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3356 // FIXME: Alignment
3357 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3358 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3359 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3360 break;
3363 case OP_STOREV_MEMBASE:
3364 case OP_LOADV_MEMBASE:
3365 case OP_VMOVE: {
3366 MonoClass *klass = ins->klass;
3367 LLVMValueRef src = NULL, dst, args [5];
3368 gboolean done = FALSE;
3370 if (!klass) {
3371 // FIXME:
3372 LLVM_FAILURE (ctx, "!klass");
3373 break;
3376 if (mini_is_gsharedvt_klass (cfg, klass)) {
3377 // FIXME:
3378 LLVM_FAILURE (ctx, "gsharedvt");
3379 break;
3382 switch (ins->opcode) {
3383 case OP_STOREV_MEMBASE:
3384 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3385 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3386 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3387 break;
3389 if (!addresses [ins->sreg1]) {
3390 /* SIMD */
3391 g_assert (values [ins->sreg1]);
3392 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));
3393 LLVMBuildStore (builder, values [ins->sreg1], dst);
3394 done = TRUE;
3395 } else {
3396 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3397 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3399 break;
3400 case OP_LOADV_MEMBASE:
3401 if (!addresses [ins->dreg])
3402 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3403 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3404 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3405 break;
3406 case OP_VMOVE:
3407 if (!addresses [ins->sreg1])
3408 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3409 if (!addresses [ins->dreg])
3410 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3411 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3412 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3413 break;
3414 default:
3415 g_assert_not_reached ();
3417 CHECK_FAILURE (ctx);
3419 if (done)
3420 break;
3422 args [0] = dst;
3423 args [1] = src;
3424 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3425 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3426 // FIXME: Alignment
3427 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3428 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3429 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3430 break;
3432 case OP_LLVM_OUTARG_VT:
3433 if (!addresses [ins->sreg1]) {
3434 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3435 g_assert (values [ins->sreg1]);
3436 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3438 addresses [ins->dreg] = addresses [ins->sreg1];
3439 break;
3442 * SIMD
3444 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3445 case OP_XZERO: {
3446 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3447 break;
3449 case OP_LOADX_MEMBASE: {
3450 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3451 LLVMValueRef src;
3453 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3454 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3455 break;
3457 case OP_STOREX_MEMBASE: {
3458 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3459 LLVMValueRef dest;
3461 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3462 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3463 break;
3465 case OP_PADDB:
3466 case OP_PADDW:
3467 case OP_PADDD:
3468 case OP_PADDQ:
3469 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3470 break;
3471 case OP_ADDPD:
3472 case OP_ADDPS:
3473 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3474 break;
3475 case OP_PSUBB:
3476 case OP_PSUBW:
3477 case OP_PSUBD:
3478 case OP_PSUBQ:
3479 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3480 break;
3481 case OP_SUBPD:
3482 case OP_SUBPS:
3483 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3484 break;
3485 case OP_MULPD:
3486 case OP_MULPS:
3487 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3488 break;
3489 case OP_DIVPD:
3490 case OP_DIVPS:
3491 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3492 break;
3493 case OP_PAND:
3494 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3495 break;
3496 case OP_POR:
3497 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3498 break;
3499 case OP_PXOR:
3500 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3501 break;
3502 case OP_PMULW:
3503 case OP_PMULD:
3504 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3505 break;
3506 case OP_ANDPS:
3507 case OP_ANDNPS:
3508 case OP_ORPS:
3509 case OP_XORPS:
3510 case OP_ANDPD:
3511 case OP_ANDNPD:
3512 case OP_ORPD:
3513 case OP_XORPD: {
3514 LLVMTypeRef t, rt;
3515 LLVMValueRef v = NULL;
3517 switch (ins->opcode) {
3518 case OP_ANDPS:
3519 case OP_ANDNPS:
3520 case OP_ORPS:
3521 case OP_XORPS:
3522 t = LLVMVectorType (LLVMInt32Type (), 4);
3523 rt = LLVMVectorType (LLVMFloatType (), 4);
3524 break;
3525 case OP_ANDPD:
3526 case OP_ANDNPD:
3527 case OP_ORPD:
3528 case OP_XORPD:
3529 t = LLVMVectorType (LLVMInt64Type (), 2);
3530 rt = LLVMVectorType (LLVMDoubleType (), 2);
3531 break;
3532 default:
3533 t = LLVMInt32Type ();
3534 rt = LLVMInt32Type ();
3535 g_assert_not_reached ();
3538 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3539 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3540 switch (ins->opcode) {
3541 case OP_ANDPS:
3542 case OP_ANDPD:
3543 v = LLVMBuildAnd (builder, lhs, rhs, "");
3544 break;
3545 case OP_ORPS:
3546 case OP_ORPD:
3547 v = LLVMBuildOr (builder, lhs, rhs, "");
3548 break;
3549 case OP_XORPS:
3550 case OP_XORPD:
3551 v = LLVMBuildXor (builder, lhs, rhs, "");
3552 break;
3553 case OP_ANDNPS:
3554 case OP_ANDNPD:
3555 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3556 break;
3558 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3559 break;
3561 case OP_MINPD:
3562 case OP_MINPS:
3563 case OP_MAXPD:
3564 case OP_MAXPS:
3565 case OP_ADDSUBPD:
3566 case OP_ADDSUBPS:
3567 case OP_PMIND_UN:
3568 case OP_PMINW_UN:
3569 case OP_PMINB_UN:
3570 case OP_PMINW:
3571 case OP_PMAXD_UN:
3572 case OP_PMAXW_UN:
3573 case OP_PMAXB_UN:
3574 case OP_HADDPD:
3575 case OP_HADDPS:
3576 case OP_HSUBPD:
3577 case OP_HSUBPS:
3578 case OP_PADDB_SAT:
3579 case OP_PADDW_SAT:
3580 case OP_PSUBB_SAT:
3581 case OP_PSUBW_SAT:
3582 case OP_PADDB_SAT_UN:
3583 case OP_PADDW_SAT_UN:
3584 case OP_PSUBB_SAT_UN:
3585 case OP_PSUBW_SAT_UN:
3586 case OP_PAVGB_UN:
3587 case OP_PAVGW_UN:
3588 case OP_PACKW:
3589 case OP_PACKD:
3590 case OP_PACKW_UN:
3591 case OP_PACKD_UN:
3592 case OP_PMULW_HIGH:
3593 case OP_PMULW_HIGH_UN: {
3594 LLVMValueRef args [2];
3596 args [0] = lhs;
3597 args [1] = rhs;
3599 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3600 break;
3602 case OP_PCMPEQB:
3603 case OP_PCMPEQW:
3604 case OP_PCMPEQD:
3605 case OP_PCMPEQQ: {
3606 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3607 break;
3609 case OP_PCMPGTB: {
3610 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3611 break;
3613 case OP_EXTRACT_R8:
3614 case OP_EXTRACT_I8:
3615 case OP_EXTRACT_I4:
3616 case OP_EXTRACT_I2:
3617 case OP_EXTRACT_U2:
3618 case OP_EXTRACTX_U2:
3619 case OP_EXTRACT_I1:
3620 case OP_EXTRACT_U1: {
3621 LLVMTypeRef t;
3622 gboolean zext = FALSE;
3624 t = simd_op_to_llvm_type (ins->opcode);
3626 switch (ins->opcode) {
3627 case OP_EXTRACT_R8:
3628 case OP_EXTRACT_I8:
3629 case OP_EXTRACT_I4:
3630 case OP_EXTRACT_I2:
3631 case OP_EXTRACT_I1:
3632 break;
3633 case OP_EXTRACT_U2:
3634 case OP_EXTRACTX_U2:
3635 case OP_EXTRACT_U1:
3636 zext = TRUE;
3637 break;
3638 default:
3639 t = LLVMInt32Type ();
3640 g_assert_not_reached ();
3643 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3644 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3645 if (zext)
3646 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3647 break;
3650 case OP_EXPAND_I1:
3651 case OP_EXPAND_I2:
3652 case OP_EXPAND_I4:
3653 case OP_EXPAND_I8:
3654 case OP_EXPAND_R4:
3655 case OP_EXPAND_R8: {
3656 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3657 LLVMValueRef mask [16], v;
3659 for (i = 0; i < 16; ++i)
3660 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3662 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3664 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3665 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3666 break;
3669 case OP_INSERT_I1:
3670 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3671 break;
3672 case OP_INSERT_I2:
3673 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3674 break;
3675 case OP_INSERT_I4:
3676 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3677 break;
3678 case OP_INSERT_I8:
3679 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3680 break;
3681 case OP_INSERT_R4:
3682 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3683 break;
3684 case OP_INSERT_R8:
3685 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3686 break;
3688 case OP_CVTDQ2PD:
3689 case OP_CVTDQ2PS:
3690 case OP_CVTPD2DQ:
3691 case OP_CVTPS2DQ:
3692 case OP_CVTPD2PS:
3693 case OP_CVTPS2PD:
3694 case OP_CVTTPD2DQ:
3695 case OP_CVTTPS2DQ:
3696 case OP_EXTRACT_MASK:
3697 case OP_SQRTPS:
3698 case OP_SQRTPD:
3699 case OP_RSQRTPS:
3700 case OP_RCPPS: {
3701 LLVMValueRef v;
3703 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3705 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3706 break;
3709 case OP_ICONV_TO_R8_RAW:
3710 /* Same as OP_ICONV_TO_R8 */
3711 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3712 break;
3714 case OP_COMPPS:
3715 case OP_COMPPD: {
3716 LLVMValueRef args [3];
3718 args [0] = lhs;
3719 args [1] = rhs;
3720 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3722 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3723 break;
3726 case OP_ICONV_TO_X:
3727 /* This is only used for implementing shifts by non-immediate */
3728 values [ins->dreg] = lhs;
3729 break;
3731 case OP_PSHRW:
3732 case OP_PSHRD:
3733 case OP_PSHRQ:
3734 case OP_PSARW:
3735 case OP_PSARD:
3736 case OP_PSHLW:
3737 case OP_PSHLD:
3738 case OP_PSHLQ: {
3739 LLVMValueRef args [3];
3741 args [0] = lhs;
3742 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3744 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3745 break;
3748 case OP_PSHRW_REG:
3749 case OP_PSHRD_REG:
3750 case OP_PSHRQ_REG:
3751 case OP_PSARW_REG:
3752 case OP_PSARD_REG:
3753 case OP_PSHLW_REG:
3754 case OP_PSHLD_REG:
3755 case OP_PSHLQ_REG: {
3756 LLVMValueRef args [3];
3758 args [0] = lhs;
3759 args [1] = values [ins->sreg2];
3761 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3762 break;
3765 case OP_SHUFPS:
3766 case OP_SHUFPD:
3767 case OP_PSHUFLED:
3768 case OP_PSHUFLEW_LOW:
3769 case OP_PSHUFLEW_HIGH: {
3770 int mask [16];
3771 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3772 int i, mask_size = 0;
3773 int imask = ins->inst_c0;
3775 /* Convert the x86 shuffle mask to LLVM's */
3776 switch (ins->opcode) {
3777 case OP_SHUFPS:
3778 mask_size = 4;
3779 mask [0] = ((imask >> 0) & 3);
3780 mask [1] = ((imask >> 2) & 3);
3781 mask [2] = ((imask >> 4) & 3) + 4;
3782 mask [3] = ((imask >> 6) & 3) + 4;
3783 v1 = values [ins->sreg1];
3784 v2 = values [ins->sreg2];
3785 break;
3786 case OP_SHUFPD:
3787 mask_size = 2;
3788 mask [0] = ((imask >> 0) & 1);
3789 mask [1] = ((imask >> 1) & 1) + 2;
3790 v1 = values [ins->sreg1];
3791 v2 = values [ins->sreg2];
3792 break;
3793 case OP_PSHUFLEW_LOW:
3794 mask_size = 8;
3795 mask [0] = ((imask >> 0) & 3);
3796 mask [1] = ((imask >> 2) & 3);
3797 mask [2] = ((imask >> 4) & 3);
3798 mask [3] = ((imask >> 6) & 3);
3799 mask [4] = 4 + 0;
3800 mask [5] = 4 + 1;
3801 mask [6] = 4 + 2;
3802 mask [7] = 4 + 3;
3803 v1 = values [ins->sreg1];
3804 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3805 break;
3806 case OP_PSHUFLEW_HIGH:
3807 mask_size = 8;
3808 mask [0] = 0;
3809 mask [1] = 1;
3810 mask [2] = 2;
3811 mask [3] = 3;
3812 mask [4] = 4 + ((imask >> 0) & 3);
3813 mask [5] = 4 + ((imask >> 2) & 3);
3814 mask [6] = 4 + ((imask >> 4) & 3);
3815 mask [7] = 4 + ((imask >> 6) & 3);
3816 v1 = values [ins->sreg1];
3817 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3818 break;
3819 case OP_PSHUFLED:
3820 mask_size = 4;
3821 mask [0] = ((imask >> 0) & 3);
3822 mask [1] = ((imask >> 2) & 3);
3823 mask [2] = ((imask >> 4) & 3);
3824 mask [3] = ((imask >> 6) & 3);
3825 v1 = values [ins->sreg1];
3826 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3827 break;
3828 default:
3829 g_assert_not_reached ();
3831 for (i = 0; i < mask_size; ++i)
3832 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3834 values [ins->dreg] =
3835 LLVMBuildShuffleVector (builder, v1, v2,
3836 LLVMConstVector (mask_values, mask_size), dname);
3837 break;
3840 case OP_UNPACK_LOWB:
3841 case OP_UNPACK_LOWW:
3842 case OP_UNPACK_LOWD:
3843 case OP_UNPACK_LOWQ:
3844 case OP_UNPACK_LOWPS:
3845 case OP_UNPACK_LOWPD:
3846 case OP_UNPACK_HIGHB:
3847 case OP_UNPACK_HIGHW:
3848 case OP_UNPACK_HIGHD:
3849 case OP_UNPACK_HIGHQ:
3850 case OP_UNPACK_HIGHPS:
3851 case OP_UNPACK_HIGHPD: {
3852 int mask [16];
3853 LLVMValueRef mask_values [16];
3854 int i, mask_size = 0;
3855 gboolean low = FALSE;
3857 switch (ins->opcode) {
3858 case OP_UNPACK_LOWB:
3859 mask_size = 16;
3860 low = TRUE;
3861 break;
3862 case OP_UNPACK_LOWW:
3863 mask_size = 8;
3864 low = TRUE;
3865 break;
3866 case OP_UNPACK_LOWD:
3867 case OP_UNPACK_LOWPS:
3868 mask_size = 4;
3869 low = TRUE;
3870 break;
3871 case OP_UNPACK_LOWQ:
3872 case OP_UNPACK_LOWPD:
3873 mask_size = 2;
3874 low = TRUE;
3875 break;
3876 case OP_UNPACK_HIGHB:
3877 mask_size = 16;
3878 break;
3879 case OP_UNPACK_HIGHW:
3880 mask_size = 8;
3881 break;
3882 case OP_UNPACK_HIGHD:
3883 case OP_UNPACK_HIGHPS:
3884 mask_size = 4;
3885 break;
3886 case OP_UNPACK_HIGHQ:
3887 case OP_UNPACK_HIGHPD:
3888 mask_size = 2;
3889 break;
3890 default:
3891 g_assert_not_reached ();
3894 if (low) {
3895 for (i = 0; i < (mask_size / 2); ++i) {
3896 mask [(i * 2)] = i;
3897 mask [(i * 2) + 1] = mask_size + i;
3899 } else {
3900 for (i = 0; i < (mask_size / 2); ++i) {
3901 mask [(i * 2)] = (mask_size / 2) + i;
3902 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3906 for (i = 0; i < mask_size; ++i)
3907 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3909 values [ins->dreg] =
3910 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3911 LLVMConstVector (mask_values, mask_size), dname);
3912 break;
3915 case OP_DUPPD: {
3916 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3917 LLVMValueRef v, val;
3919 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3920 val = LLVMConstNull (t);
3921 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3922 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3924 values [ins->dreg] = val;
3925 break;
3927 case OP_DUPPS_LOW:
3928 case OP_DUPPS_HIGH: {
3929 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3930 LLVMValueRef v1, v2, val;
3933 if (ins->opcode == OP_DUPPS_LOW) {
3934 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3935 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3936 } else {
3937 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3938 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3940 val = LLVMConstNull (t);
3941 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3942 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3943 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3944 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3946 values [ins->dreg] = val;
3947 break;
3950 #endif /* SIMD */
3952 case OP_DUMMY_USE:
3953 break;
3956 * EXCEPTION HANDLING
3958 case OP_IMPLICIT_EXCEPTION:
3959 /* This marks a place where an implicit exception can happen */
3960 if (bb->region != -1)
3961 LLVM_FAILURE (ctx, "implicit-exception");
3962 break;
3963 case OP_THROW:
3964 case OP_RETHROW: {
3965 MonoMethodSignature *throw_sig;
3966 LLVMValueRef callee, arg;
3967 gboolean rethrow = (ins->opcode == OP_RETHROW);
3968 const char *icall_name;
3970 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3971 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3973 if (!callee) {
3974 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3975 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3976 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3977 if (cfg->compile_aot) {
3978 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3979 } else {
3980 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3982 #ifdef TARGET_X86
3984 * LLVM doesn't push the exception argument, so we need a different
3985 * trampoline.
3987 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3988 #else
3989 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3990 #endif
3993 mono_memory_barrier ();
3994 if (rethrow)
3995 ctx->lmodule->rethrow = callee;
3996 else
3997 ctx->lmodule->throw = callee;
3999 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4000 emit_call (ctx, bb, &builder, callee, &arg, 1);
4001 break;
4003 case OP_CALL_HANDLER: {
4005 * We don't 'call' handlers, but instead simply branch to them.
4006 * The code generated by ENDFINALLY will branch back to us.
4008 LLVMBasicBlockRef noex_bb;
4009 GSList *bb_list;
4010 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4012 bb_list = info->call_handler_return_bbs;
4015 * Set the indicator variable for the finally clause.
4017 lhs = info->finally_ind;
4018 g_assert (lhs);
4019 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4021 /* Branch to the finally clause */
4022 LLVMBuildBr (builder, info->call_handler_target_bb);
4024 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4025 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4027 builder = ctx->builder = create_builder (ctx);
4028 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4030 bblocks [bb->block_num].end_bblock = noex_bb;
4031 break;
4033 case OP_START_HANDLER: {
4034 break;
4036 case OP_ENDFINALLY: {
4037 LLVMBasicBlockRef resume_bb;
4038 MonoBasicBlock *handler_bb;
4039 LLVMValueRef val, switch_ins, callee;
4040 GSList *bb_list;
4041 BBInfo *info;
4043 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4044 g_assert (handler_bb);
4045 info = &bblocks [handler_bb->block_num];
4046 lhs = info->finally_ind;
4047 g_assert (lhs);
4049 bb_list = info->call_handler_return_bbs;
4051 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4053 /* Load the finally variable */
4054 val = LLVMBuildLoad (builder, lhs, "");
4056 /* Reset the variable */
4057 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4059 /* Branch to either resume_bb, or to the bblocks in bb_list */
4060 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4062 * The other targets are added at the end to handle OP_CALL_HANDLER
4063 * opcodes processed later.
4065 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4067 builder = ctx->builder = create_builder (ctx);
4068 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4070 if (ctx->cfg->compile_aot) {
4071 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4072 } else {
4073 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4075 LLVMBuildCall (builder, callee, NULL, 0, "");
4077 LLVMBuildUnreachable (builder);
4078 has_terminator = TRUE;
4079 break;
4081 default: {
4082 char reason [128];
4084 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4085 LLVM_FAILURE (ctx, reason);
4086 break;
4090 /* Convert the value to the type required by phi nodes */
4091 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4092 if (!values [ins->dreg])
4093 /* vtypes */
4094 values [ins->dreg] = addresses [ins->dreg];
4095 else
4096 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4099 /* Add stores for volatile variables */
4100 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4101 emit_volatile_store (ctx, ins->dreg);
4104 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4105 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4107 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4108 LLVMBuildRetVoid (builder);
4110 if (bb == cfg->bb_entry)
4111 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4113 return;
4115 FAILURE:
4116 return;
4120 * mono_llvm_check_method_supported:
4122 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4123 * compiling a method twice.
4125 void
4126 mono_llvm_check_method_supported (MonoCompile *cfg)
4128 MonoMethodHeader *header = cfg->header;
4129 MonoExceptionClause *clause;
4130 int i;
4132 if (cfg->method->save_lmf) {
4133 cfg->exception_message = g_strdup ("lmf");
4134 cfg->disable_llvm = TRUE;
4137 #if 1
4138 for (i = 0; i < header->num_clauses; ++i) {
4139 clause = &header->clauses [i];
4141 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4143 * FIXME: Some tests still fail with nested clauses.
4145 cfg->exception_message = g_strdup ("nested clauses");
4146 cfg->disable_llvm = TRUE;
4149 #endif
4151 /* FIXME: */
4152 if (cfg->method->dynamic) {
4153 cfg->exception_message = g_strdup ("dynamic.");
4154 cfg->disable_llvm = TRUE;
4159 * mono_llvm_emit_method:
4161 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4163 void
4164 mono_llvm_emit_method (MonoCompile *cfg)
4166 EmitContext *ctx;
4167 MonoMethodSignature *sig;
4168 MonoBasicBlock *bb;
4169 LLVMTypeRef method_type;
4170 LLVMValueRef method = NULL;
4171 char *method_name;
4172 LLVMValueRef *values;
4173 int i, max_block_num, bb_index;
4174 gboolean last = FALSE;
4175 GPtrArray *phi_values;
4176 LLVMCallInfo *linfo;
4177 GSList *l;
4178 LLVMModuleRef module;
4179 BBInfo *bblocks;
4180 GPtrArray *bblock_list;
4181 MonoMethodHeader *header;
4182 MonoExceptionClause *clause;
4183 LLVMSigInfo sinfo;
4184 char **names;
4186 /* The code below might acquire the loader lock, so use it for global locking */
4187 mono_loader_lock ();
4189 /* Used to communicate with the callbacks */
4190 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4192 ctx = g_new0 (EmitContext, 1);
4193 ctx->cfg = cfg;
4194 ctx->mempool = cfg->mempool;
4197 * This maps vregs to the LLVM instruction defining them
4199 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4201 * This maps vregs for volatile variables to the LLVM instruction defining their
4202 * address.
4204 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4205 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4206 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4207 phi_values = g_ptr_array_new ();
4209 * This signals whenever the vreg was defined by a phi node with no input vars
4210 * (i.e. all its input bblocks end with NOT_REACHABLE).
4212 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4213 /* Whenever the bblock is unreachable */
4214 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4216 bblock_list = g_ptr_array_new ();
4218 ctx->values = values;
4219 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4221 if (cfg->compile_aot) {
4222 ctx->lmodule = &aot_module;
4223 method_name = mono_aot_get_method_name (cfg);
4224 cfg->llvm_method_name = g_strdup (method_name);
4225 } else {
4226 init_jit_module ();
4227 ctx->lmodule = &jit_module;
4228 method_name = mono_method_full_name (cfg->method, TRUE);
4231 module = ctx->module = ctx->lmodule->module;
4233 #if 1
4235 static int count = 0;
4236 count ++;
4238 if (getenv ("LLVM_COUNT")) {
4239 if (count == atoi (getenv ("LLVM_COUNT"))) {
4240 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4241 fflush (stdout);
4242 last = TRUE;
4244 if (count > atoi (getenv ("LLVM_COUNT")))
4245 LLVM_FAILURE (ctx, "");
4248 #endif
4250 sig = mono_method_signature (cfg->method);
4251 ctx->sig = sig;
4253 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4254 ctx->linfo = linfo;
4255 CHECK_FAILURE (ctx);
4257 if (cfg->rgctx_var)
4258 linfo->rgctx_arg = TRUE;
4259 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4260 CHECK_FAILURE (ctx);
4263 * This maps parameter indexes in the original signature to the indexes in
4264 * the LLVM signature.
4266 ctx->pindexes = sinfo.pindexes;
4268 method = LLVMAddFunction (module, method_name, method_type);
4269 ctx->lmethod = method;
4271 #ifdef LLVM_MONO_BRANCH
4272 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4273 #endif
4274 LLVMSetLinkage (method, LLVMPrivateLinkage);
4276 LLVMAddFunctionAttr (method, LLVMUWTable);
4278 if (cfg->compile_aot) {
4279 LLVMSetLinkage (method, LLVMInternalLinkage);
4280 LLVMSetVisibility (method, LLVMHiddenVisibility);
4281 } else {
4282 LLVMSetLinkage (method, LLVMPrivateLinkage);
4285 if (cfg->method->save_lmf)
4286 LLVM_FAILURE (ctx, "lmf");
4288 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4289 LLVM_FAILURE (ctx, "pinvoke signature");
4291 header = cfg->header;
4292 for (i = 0; i < header->num_clauses; ++i) {
4293 clause = &header->clauses [i];
4294 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4295 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4298 if (linfo->rgctx_arg) {
4299 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4301 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4302 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4303 * CC_X86_64_Mono in X86CallingConv.td.
4305 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4306 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4308 if (cfg->vret_addr) {
4309 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4310 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4312 if (sig->hasthis) {
4313 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4314 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4317 names = g_new (char *, sig->param_count);
4318 mono_method_get_param_names (cfg->method, (const char **) names);
4320 for (i = 0; i < sig->param_count; ++i) {
4321 char *name;
4323 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4324 if (names [i] && names [i][0] != '\0')
4325 name = g_strdup_printf ("arg_%s", names [i]);
4326 else
4327 name = g_strdup_printf ("arg_%d", i);
4328 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4329 g_free (name);
4330 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4331 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4333 g_free (names);
4335 max_block_num = 0;
4336 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4337 max_block_num = MAX (max_block_num, bb->block_num);
4338 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4340 /* Add branches between non-consecutive bblocks */
4341 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4342 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4343 bb->next_bb != bb->last_ins->inst_false_bb) {
4345 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4346 inst->opcode = OP_BR;
4347 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4348 mono_bblock_add_inst (bb, inst);
4353 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4354 * was later optimized away, so clear these flags, and add them back for the still
4355 * present OP_LDADDR instructions.
4357 for (i = 0; i < cfg->next_vreg; ++i) {
4358 MonoInst *ins;
4360 ins = get_vreg_to_inst (cfg, i);
4361 if (ins && ins != cfg->rgctx_var)
4362 ins->flags &= ~MONO_INST_INDIRECT;
4366 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4368 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4369 MonoInst *ins;
4370 LLVMBuilderRef builder;
4371 char *dname;
4372 char dname_buf[128];
4374 builder = create_builder (ctx);
4376 for (ins = bb->code; ins; ins = ins->next) {
4377 switch (ins->opcode) {
4378 case OP_PHI:
4379 case OP_FPHI:
4380 case OP_VPHI:
4381 case OP_XPHI: {
4382 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4384 CHECK_FAILURE (ctx);
4386 if (ins->opcode == OP_VPHI) {
4387 /* Treat valuetype PHI nodes as operating on the address itself */
4388 g_assert (ins->klass);
4389 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4393 * Have to precreate these, as they can be referenced by
4394 * earlier instructions.
4396 sprintf (dname_buf, "t%d", ins->dreg);
4397 dname = dname_buf;
4398 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4400 if (ins->opcode == OP_VPHI)
4401 ctx->addresses [ins->dreg] = values [ins->dreg];
4403 g_ptr_array_add (phi_values, values [ins->dreg]);
4406 * Set the expected type of the incoming arguments since these have
4407 * to have the same type.
4409 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4410 int sreg1 = ins->inst_phi_args [i + 1];
4412 if (sreg1 != -1)
4413 ctx->vreg_types [sreg1] = phi_type;
4415 break;
4417 case OP_LDADDR:
4418 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4419 break;
4420 default:
4421 break;
4427 * Create an ordering for bblocks, use the depth first order first, then
4428 * put the exception handling bblocks last.
4430 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4431 bb = cfg->bblocks [bb_index];
4432 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4433 g_ptr_array_add (bblock_list, bb);
4434 bblocks [bb->block_num].added = TRUE;
4438 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4439 if (!bblocks [bb->block_num].added)
4440 g_ptr_array_add (bblock_list, bb);
4444 * Second pass: generate code.
4446 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4447 bb = g_ptr_array_index (bblock_list, bb_index);
4449 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4450 continue;
4452 process_bb (ctx, bb);
4453 CHECK_FAILURE (ctx);
4456 /* Add incoming phi values */
4457 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4458 GSList *l, *ins_list;
4460 ins_list = bblocks [bb->block_num].phi_nodes;
4462 for (l = ins_list; l; l = l->next) {
4463 PhiNode *node = l->data;
4464 MonoInst *phi = node->phi;
4465 int sreg1 = node->sreg;
4466 LLVMBasicBlockRef in_bb;
4468 if (sreg1 == -1)
4469 continue;
4471 in_bb = get_end_bb (ctx, node->in_bb);
4473 if (ctx->unreachable [node->in_bb->block_num])
4474 continue;
4476 if (!values [sreg1])
4477 /* Can happen with values in EH clauses */
4478 LLVM_FAILURE (ctx, "incoming phi sreg1");
4480 if (phi->opcode == OP_VPHI) {
4481 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4482 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4483 } else {
4484 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4485 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4490 /* Create the SWITCH statements for ENDFINALLY instructions */
4491 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4492 BBInfo *info = &bblocks [bb->block_num];
4493 GSList *l;
4494 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4495 LLVMValueRef switch_ins = l->data;
4496 GSList *bb_list = info->call_handler_return_bbs;
4498 for (i = 0; i < g_slist_length (bb_list); ++i)
4499 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4503 if (cfg->verbose_level > 1)
4504 mono_llvm_dump_value (method);
4506 mark_as_used (module, method);
4508 if (cfg->compile_aot) {
4509 /* Don't generate native code, keep the LLVM IR */
4510 if (cfg->compile_aot && cfg->verbose_level)
4511 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4513 //LLVMVerifyFunction(method, 0);
4514 } else {
4515 mono_llvm_optimize_method (method);
4517 if (cfg->verbose_level > 1)
4518 mono_llvm_dump_value (method);
4520 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4522 /* Set by emit_cb */
4523 g_assert (cfg->code_len);
4525 /* FIXME: Free the LLVM IL for the function */
4528 goto CLEANUP;
4530 FAILURE:
4532 if (method) {
4533 /* Need to add unused phi nodes as they can be referenced by other values */
4534 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4535 LLVMBuilderRef builder;
4537 builder = create_builder (ctx);
4538 LLVMPositionBuilderAtEnd (builder, phi_bb);
4540 for (i = 0; i < phi_values->len; ++i) {
4541 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4542 if (LLVMGetInstructionParent (v) == NULL)
4543 LLVMInsertIntoBuilder (builder, v);
4546 LLVMDeleteFunction (method);
4549 CLEANUP:
4550 g_free (values);
4551 g_free (ctx->addresses);
4552 g_free (ctx->vreg_types);
4553 g_free (ctx->vreg_cli_types);
4554 g_free (ctx->pindexes);
4555 g_free (ctx->is_dead);
4556 g_free (ctx->unreachable);
4557 g_ptr_array_free (phi_values, TRUE);
4558 g_free (ctx->bblocks);
4559 g_hash_table_destroy (ctx->region_to_handler);
4560 g_free (method_name);
4561 g_ptr_array_free (bblock_list, TRUE);
4563 for (l = ctx->builders; l; l = l->next) {
4564 LLVMBuilderRef builder = l->data;
4565 LLVMDisposeBuilder (builder);
4568 g_free (ctx);
4570 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4572 mono_loader_unlock ();
4576 * mono_llvm_emit_call:
4578 * Same as mono_arch_emit_call () for LLVM.
4580 void
4581 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4583 MonoInst *in;
4584 MonoMethodSignature *sig;
4585 int i, n, stack_size;
4586 LLVMArgInfo *ainfo;
4588 stack_size = 0;
4590 sig = call->signature;
4591 n = sig->param_count + sig->hasthis;
4593 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4595 if (cfg->disable_llvm)
4596 return;
4598 if (sig->call_convention == MONO_CALL_VARARG) {
4599 cfg->exception_message = g_strdup ("varargs");
4600 cfg->disable_llvm = TRUE;
4603 for (i = 0; i < n; ++i) {
4604 MonoInst *ins;
4606 ainfo = call->cinfo->args + i;
4608 in = call->args [i];
4610 /* Simply remember the arguments */
4611 switch (ainfo->storage) {
4612 case LLVMArgInIReg:
4613 case LLVMArgInFPReg: {
4614 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4616 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4617 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4618 ins->dreg = mono_alloc_freg (cfg);
4619 } else {
4620 MONO_INST_NEW (cfg, ins, OP_MOVE);
4621 ins->dreg = mono_alloc_ireg (cfg);
4623 ins->sreg1 = in->dreg;
4624 break;
4626 case LLVMArgVtypeByVal:
4627 case LLVMArgVtypeInReg:
4628 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4629 ins->dreg = mono_alloc_ireg (cfg);
4630 ins->sreg1 = in->dreg;
4631 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4632 break;
4633 default:
4634 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4635 cfg->exception_message = g_strdup ("ainfo->storage");
4636 cfg->disable_llvm = TRUE;
4637 return;
4640 if (!cfg->disable_llvm) {
4641 MONO_ADD_INS (cfg->cbb, ins);
4642 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4647 static unsigned char*
4648 alloc_cb (LLVMValueRef function, int size)
4650 MonoCompile *cfg;
4652 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4654 if (cfg) {
4655 // FIXME: dynamic
4656 return mono_domain_code_reserve (cfg->domain, size);
4657 } else {
4658 return mono_domain_code_reserve (mono_domain_get (), size);
4662 static void
4663 emitted_cb (LLVMValueRef function, void *start, void *end)
4665 MonoCompile *cfg;
4667 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4668 g_assert (cfg);
4669 cfg->code_len = (guint8*)end - (guint8*)start;
4672 static void
4673 exception_cb (void *data)
4675 MonoCompile *cfg;
4676 MonoJitExceptionInfo *ei;
4677 guint32 ei_len, i, j, nested_len, nindex;
4678 gpointer *type_info;
4679 int this_reg, this_offset;
4681 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4682 g_assert (cfg);
4685 * data points to a DWARF FDE structure, convert it to our unwind format and
4686 * save it.
4687 * An alternative would be to save it directly, and modify our unwinder to work
4688 * with it.
4690 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);
4692 /* Count nested clauses */
4693 nested_len = 0;
4694 for (i = 0; i < ei_len; ++i) {
4695 for (j = 0; j < ei_len; ++j) {
4696 gint32 cindex1 = *(gint32*)type_info [i];
4697 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4698 gint32 cindex2 = *(gint32*)type_info [j];
4699 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4701 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4702 nested_len ++;
4707 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4708 cfg->llvm_ex_info_len = ei_len + nested_len;
4709 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4710 /* Fill the rest of the information from the type info */
4711 for (i = 0; i < ei_len; ++i) {
4712 gint32 clause_index = *(gint32*)type_info [i];
4713 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4715 cfg->llvm_ex_info [i].flags = clause->flags;
4716 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4720 * For nested clauses, the LLVM produced exception info associates the try interval with
4721 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4723 /* FIXME: These should be order with the normal clauses */
4724 nindex = ei_len;
4725 for (i = 0; i < ei_len; ++i) {
4726 for (j = 0; j < ei_len; ++j) {
4727 gint32 cindex1 = *(gint32*)type_info [i];
4728 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4729 gint32 cindex2 = *(gint32*)type_info [j];
4730 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4732 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4734 * The try interval comes from the nested clause, everything else from the
4735 * nesting clause.
4737 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4738 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4739 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4740 nindex ++;
4744 g_assert (nindex == ei_len + nested_len);
4745 cfg->llvm_this_reg = this_reg;
4746 cfg->llvm_this_offset = this_offset;
4748 /* type_info [i] is cfg mempool allocated, no need to free it */
4750 g_free (ei);
4751 g_free (type_info);
4754 static char*
4755 dlsym_cb (const char *name, void **symbol)
4757 MonoDl *current;
4758 char *err;
4760 err = NULL;
4761 if (!strcmp (name, "__bzero")) {
4762 *symbol = (void*)bzero;
4763 } else {
4764 current = mono_dl_open (NULL, 0, NULL);
4765 g_assert (current);
4767 err = mono_dl_symbol (current, name, symbol);
4769 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4770 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4771 #endif
4772 return err;
4775 static inline void
4776 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4778 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4781 static inline void
4782 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4784 LLVMTypeRef param_types [4];
4786 param_types [0] = param_type1;
4787 param_types [1] = param_type2;
4789 AddFunc (module, name, ret_type, param_types, 2);
4792 static void
4793 add_intrinsics (LLVMModuleRef module)
4795 /* Emit declarations of instrinsics */
4797 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4798 * type doesn't seem to do any locking.
4801 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4803 memset_param_count = 5;
4804 memset_func_name = "llvm.memset.p0i8.i32";
4806 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4810 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4812 memcpy_param_count = 5;
4813 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4815 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4819 LLVMTypeRef params [] = { LLVMDoubleType () };
4821 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4822 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4823 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4825 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4826 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4830 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4831 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4833 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4834 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4835 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4836 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4837 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4838 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4842 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4843 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4845 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4846 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4847 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4848 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4849 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4850 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4854 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4855 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4856 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4858 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4860 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4863 /* EH intrinsics */
4865 LLVMTypeRef arg_types [2];
4866 LLVMTypeRef ret_type;
4868 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4869 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4870 ret_type = LLVMInt32Type ();
4872 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4874 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4877 /* SSE intrinsics */
4879 LLVMTypeRef ret_type, arg_types [16];
4881 /* Binary ops */
4882 ret_type = type_to_simd_type (MONO_TYPE_I4);
4883 arg_types [0] = ret_type;
4884 arg_types [1] = ret_type;
4885 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4886 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4888 ret_type = type_to_simd_type (MONO_TYPE_I2);
4889 arg_types [0] = ret_type;
4890 arg_types [1] = ret_type;
4891 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4892 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4893 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4894 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4895 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4896 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4897 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4898 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4899 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4900 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4902 ret_type = type_to_simd_type (MONO_TYPE_I1);
4903 arg_types [0] = ret_type;
4904 arg_types [1] = ret_type;
4905 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4906 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4907 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4908 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4909 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4910 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4911 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4913 ret_type = type_to_simd_type (MONO_TYPE_R8);
4914 arg_types [0] = ret_type;
4915 arg_types [1] = ret_type;
4916 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4917 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4918 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4919 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4920 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4922 ret_type = type_to_simd_type (MONO_TYPE_R4);
4923 arg_types [0] = ret_type;
4924 arg_types [1] = ret_type;
4925 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4926 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4927 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4928 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4931 /* pack */
4932 ret_type = type_to_simd_type (MONO_TYPE_I1);
4933 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4934 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4935 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4936 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4937 ret_type = type_to_simd_type (MONO_TYPE_I2);
4938 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4939 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4940 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4941 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4943 /* cmp pd/ps */
4944 ret_type = type_to_simd_type (MONO_TYPE_R8);
4945 arg_types [0] = ret_type;
4946 arg_types [1] = ret_type;
4947 arg_types [2] = LLVMInt8Type ();
4948 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4949 ret_type = type_to_simd_type (MONO_TYPE_R4);
4950 arg_types [0] = ret_type;
4951 arg_types [1] = ret_type;
4952 arg_types [2] = LLVMInt8Type ();
4953 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4955 /* Conversion ops */
4956 ret_type = type_to_simd_type (MONO_TYPE_R8);
4957 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4958 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4959 ret_type = type_to_simd_type (MONO_TYPE_R4);
4960 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4961 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4962 ret_type = type_to_simd_type (MONO_TYPE_I4);
4963 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4964 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4965 ret_type = type_to_simd_type (MONO_TYPE_I4);
4966 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4967 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4968 ret_type = type_to_simd_type (MONO_TYPE_R4);
4969 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4970 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4971 ret_type = type_to_simd_type (MONO_TYPE_R8);
4972 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4973 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4975 ret_type = type_to_simd_type (MONO_TYPE_I4);
4976 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4977 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4978 ret_type = type_to_simd_type (MONO_TYPE_I4);
4979 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4980 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4982 /* Unary ops */
4983 ret_type = type_to_simd_type (MONO_TYPE_R8);
4984 arg_types [0] = ret_type;
4985 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
4986 ret_type = type_to_simd_type (MONO_TYPE_R4);
4987 arg_types [0] = ret_type;
4988 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
4989 ret_type = type_to_simd_type (MONO_TYPE_R4);
4990 arg_types [0] = ret_type;
4991 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
4992 ret_type = type_to_simd_type (MONO_TYPE_R4);
4993 arg_types [0] = ret_type;
4994 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
4996 /* shifts */
4997 ret_type = type_to_simd_type (MONO_TYPE_I2);
4998 arg_types [0] = ret_type;
4999 arg_types [1] = LLVMInt32Type ();
5000 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5001 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5002 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5003 ret_type = type_to_simd_type (MONO_TYPE_I4);
5004 arg_types [0] = ret_type;
5005 arg_types [1] = LLVMInt32Type ();
5006 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5007 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5008 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5009 ret_type = type_to_simd_type (MONO_TYPE_I8);
5010 arg_types [0] = ret_type;
5011 arg_types [1] = LLVMInt32Type ();
5012 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5013 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5015 /* pmovmskb */
5016 ret_type = LLVMInt32Type ();
5017 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5018 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5021 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5023 /* Load/Store intrinsics */
5025 LLVMTypeRef arg_types [5];
5026 int i;
5027 char name [128];
5029 for (i = 1; i <= 8; i *= 2) {
5030 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5031 arg_types [1] = LLVMInt32Type ();
5032 arg_types [2] = LLVMInt1Type ();
5033 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5034 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5036 arg_types [0] = LLVMIntType (i * 8);
5037 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5038 arg_types [2] = LLVMInt32Type ();
5039 arg_types [3] = LLVMInt1Type ();
5040 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5041 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5046 void
5047 mono_llvm_init (void)
5049 mono_native_tls_alloc (&current_cfg_tls_id, NULL);
5052 static void
5053 init_jit_module (void)
5055 MonoJitICallInfo *info;
5057 if (jit_module_inited)
5058 return;
5060 mono_loader_lock ();
5062 if (jit_module_inited) {
5063 mono_loader_unlock ();
5064 return;
5067 jit_module.module = LLVMModuleCreateWithName ("mono");
5069 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5071 add_intrinsics (jit_module.module);
5073 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5075 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5076 g_assert (info);
5077 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5079 jit_module_inited = TRUE;
5081 mono_loader_unlock ();
5084 void
5085 mono_llvm_cleanup (void)
5087 if (ee)
5088 mono_llvm_dispose_ee (ee);
5090 if (jit_module.llvm_types)
5091 g_hash_table_destroy (jit_module.llvm_types);
5093 if (aot_module.module)
5094 LLVMDisposeModule (aot_module.module);
5096 LLVMContextDispose (LLVMGetGlobalContext ());
5099 void
5100 mono_llvm_create_aot_module (const char *got_symbol)
5102 /* Delete previous module */
5103 if (aot_module.plt_entries)
5104 g_hash_table_destroy (aot_module.plt_entries);
5105 if (aot_module.module)
5106 LLVMDisposeModule (aot_module.module);
5108 memset (&aot_module, 0, sizeof (aot_module));
5110 aot_module.module = LLVMModuleCreateWithName ("aot");
5111 aot_module.got_symbol = got_symbol;
5113 add_intrinsics (aot_module.module);
5115 /* Add GOT */
5117 * We couldn't compute the type of the LLVM global representing the got because
5118 * its size is only known after all the methods have been emitted. So create
5119 * a dummy variable, and replace all uses it with the real got variable when
5120 * its size is known in mono_llvm_emit_aot_module ().
5123 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5125 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5126 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5129 /* Add a dummy personality function */
5131 LLVMBasicBlockRef lbb;
5132 LLVMBuilderRef lbuilder;
5133 LLVMValueRef personality;
5135 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5136 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5137 lbb = LLVMAppendBasicBlock (personality, "BB0");
5138 lbuilder = LLVMCreateBuilder ();
5139 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5140 LLVMBuildRetVoid (lbuilder);
5143 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5144 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5148 * Emit the aot module into the LLVM bitcode file FILENAME.
5150 void
5151 mono_llvm_emit_aot_module (const char *filename, int got_size)
5153 LLVMTypeRef got_type;
5154 LLVMValueRef real_got;
5157 * Create the real got variable and replace all uses of the dummy variable with
5158 * the real one.
5160 got_type = LLVMArrayType (IntPtrType (), got_size);
5161 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5162 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5163 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5165 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5167 mark_as_used (aot_module.module, real_got);
5169 /* Delete the dummy got so it doesn't become a global */
5170 LLVMDeleteGlobal (aot_module.got_var);
5172 #if 0
5174 char *verifier_err;
5176 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5177 g_assert_not_reached ();
5180 #endif
5182 LLVMWriteBitcodeToFile (aot_module.module, filename);
5186 DESIGN:
5187 - Emit LLVM IR from the mono IR using the LLVM C API.
5188 - The original arch specific code remains, so we can fall back to it if we run
5189 into something we can't handle.
5193 A partial list of issues:
5194 - Handling of opcodes which can throw exceptions.
5196 In the mono JIT, these are implemented using code like this:
5197 method:
5198 <compare>
5199 throw_pos:
5200 b<cond> ex_label
5201 <rest of code>
5202 ex_label:
5203 push throw_pos - method
5204 call <exception trampoline>
5206 The problematic part is push throw_pos - method, which cannot be represented
5207 in the LLVM IR, since it does not support label values.
5208 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5209 be implemented in JIT mode ?
5210 -> a possible but slower implementation would use the normal exception
5211 throwing code but it would need to control the placement of the throw code
5212 (it needs to be exactly after the compare+branch).
5213 -> perhaps add a PC offset intrinsics ?
5215 - efficient implementation of .ovf opcodes.
5217 These are currently implemented as:
5218 <ins which sets the condition codes>
5219 b<cond> ex_label
5221 Some overflow opcodes are now supported by LLVM SVN.
5223 - exception handling, unwinding.
5224 - SSA is disabled for methods with exception handlers
5225 - How to obtain unwind info for LLVM compiled methods ?
5226 -> this is now solved by converting the unwind info generated by LLVM
5227 into our format.
5228 - LLVM uses the c++ exception handling framework, while we use our home grown
5229 code, and couldn't use the c++ one:
5230 - its not supported under VC++, other exotic platforms.
5231 - it might be impossible to support filter clauses with it.
5233 - trampolines.
5235 The trampolines need a predictable call sequence, since they need to disasm
5236 the calling code to obtain register numbers / offsets.
5238 LLVM currently generates this code in non-JIT mode:
5239 mov -0x98(%rax),%eax
5240 callq *%rax
5241 Here, the vtable pointer is lost.
5242 -> solution: use one vtable trampoline per class.
5244 - passing/receiving the IMT pointer/RGCTX.
5245 -> solution: pass them as normal arguments ?
5247 - argument passing.
5249 LLVM does not allow the specification of argument registers etc. This means
5250 that all calls are made according to the platform ABI.
5252 - passing/receiving vtypes.
5254 Vtypes passed/received in registers are handled by the front end by using
5255 a signature with scalar arguments, and loading the parts of the vtype into those
5256 arguments.
5258 Vtypes passed on the stack are handled using the 'byval' attribute.
5260 - ldaddr.
5262 Supported though alloca, we need to emit the load/store code.
5264 - types.
5266 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5267 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5268 This is made easier because the IR is already in SSA form.
5269 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5270 types are frequently used incorrectly.
5274 AOT SUPPORT:
5275 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5276 append the AOT data structures to that file. For methods which cannot be
5277 handled by LLVM, the normal JIT compiled versions are used.
5280 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5281 * - each bblock should end with a branch
5282 * - setting the return value, making cfg->ret non-volatile
5283 * - avoid some transformations in the JIT which make it harder for us to generate
5284 * code.
5285 * - use pointer types to help optimizations.