LLVM requires two PHI entries if a previous bblock branches to the current bblock...
[mono-project/dkf.git] / mono / mini / mini-llvm.c
blobac5adf9f15af21ee9859fbb1963e0bf142065473
1 /*
2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * (C) 2009 Novell, Inc.
5 */
7 #include "mini.h"
8 #include <mono/metadata/debug-helpers.h>
9 #include <mono/metadata/mempool-internals.h>
10 #include <mono/utils/mono-tls.h>
12 #ifndef __STDC_LIMIT_MACROS
13 #define __STDC_LIMIT_MACROS
14 #endif
15 #ifndef __STDC_CONSTANT_MACROS
16 #define __STDC_CONSTANT_MACROS
17 #endif
19 #include "llvm-c/Core.h"
20 #include "llvm-c/ExecutionEngine.h"
21 #include "llvm-c/BitWriter.h"
22 #include "llvm-c/Analysis.h"
24 #include "mini-llvm-cpp.h"
27 * Information associated by mono with LLVM modules.
29 typedef struct {
30 LLVMModuleRef module;
31 LLVMValueRef throw, rethrow, throw_corlib_exception;
32 GHashTable *llvm_types;
33 LLVMValueRef got_var;
34 const char *got_symbol;
35 GHashTable *plt_entries;
36 } MonoLLVMModule;
39 * Information associated by the backend with mono basic blocks.
41 typedef struct {
42 LLVMBasicBlockRef bblock, end_bblock;
43 LLVMValueRef finally_ind;
44 gboolean added, invoke_target;
45 /*
46 * If this bblock is the start of a finally clause, this is a list of bblocks it
47 * needs to branch to in ENDFINALLY.
49 GSList *call_handler_return_bbs;
51 * If this bblock is the start of a finally clause, this is the bblock that
52 * CALL_HANDLER needs to branch to.
54 LLVMBasicBlockRef call_handler_target_bb;
55 /* The list of switch statements generated by ENDFINALLY instructions */
56 GSList *endfinally_switch_ins_list;
57 GSList *phi_nodes;
58 } BBInfo;
61 * Structure containing emit state
63 typedef struct {
64 MonoMemPool *mempool;
66 /* Maps method names to the corresponding LLVMValueRef */
67 GHashTable *emitted_method_decls;
69 MonoCompile *cfg;
70 LLVMValueRef lmethod;
71 MonoLLVMModule *lmodule;
72 LLVMModuleRef module;
73 BBInfo *bblocks;
74 int sindex, default_index, ex_index;
75 LLVMBuilderRef builder;
76 LLVMValueRef *values, *addresses;
77 MonoType **vreg_cli_types;
78 LLVMCallInfo *linfo;
79 MonoMethodSignature *sig;
80 GSList *builders;
81 GHashTable *region_to_handler;
82 LLVMBuilderRef alloca_builder;
83 LLVMValueRef last_alloca;
84 LLVMValueRef rgctx_arg;
85 LLVMTypeRef *vreg_types;
86 gboolean *is_dead;
87 gboolean *unreachable;
88 int *pindexes;
90 char temp_name [32];
91 } EmitContext;
93 typedef struct {
94 MonoBasicBlock *bb;
95 MonoInst *phi;
96 MonoBasicBlock *in_bb;
97 int sreg;
98 } PhiNode;
101 * Instruction metadata
102 * This is the same as ins_info, but LREG != IREG.
104 #ifdef MINI_OP
105 #undef MINI_OP
106 #endif
107 #ifdef MINI_OP3
108 #undef MINI_OP3
109 #endif
110 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
111 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
112 #define NONE ' '
113 #define IREG 'i'
114 #define FREG 'f'
115 #define VREG 'v'
116 #define XREG 'x'
117 #define LREG 'l'
118 /* keep in sync with the enum in mini.h */
119 const char
120 llvm_ins_info[] = {
121 #include "mini-ops.h"
123 #undef MINI_OP
124 #undef MINI_OP3
126 #if SIZEOF_VOID_P == 4
127 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
128 #else
129 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
130 #endif
132 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
134 #if 0
135 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
136 #else
137 #define TRACE_FAILURE(msg)
138 #endif
140 #ifdef TARGET_X86
141 #define IS_TARGET_X86 1
142 #else
143 #define IS_TARGET_X86 0
144 #endif
146 #define LLVM_FAILURE(ctx, reason) do { \
147 TRACE_FAILURE (reason); \
148 (ctx)->cfg->exception_message = g_strdup (reason); \
149 (ctx)->cfg->disable_llvm = TRUE; \
150 goto FAILURE; \
151 } while (0)
153 #define CHECK_FAILURE(ctx) do { \
154 if ((ctx)->cfg->disable_llvm) \
155 goto FAILURE; \
156 } while (0)
158 static LLVMIntPredicate cond_to_llvm_cond [] = {
159 LLVMIntEQ,
160 LLVMIntNE,
161 LLVMIntSLE,
162 LLVMIntSGE,
163 LLVMIntSLT,
164 LLVMIntSGT,
165 LLVMIntULE,
166 LLVMIntUGE,
167 LLVMIntULT,
168 LLVMIntUGT,
171 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
172 LLVMRealOEQ,
173 LLVMRealUNE,
174 LLVMRealOLE,
175 LLVMRealOGE,
176 LLVMRealOLT,
177 LLVMRealOGT,
178 LLVMRealULE,
179 LLVMRealUGE,
180 LLVMRealULT,
181 LLVMRealUGT,
184 static LLVMExecutionEngineRef ee;
185 static MonoNativeTlsKey current_cfg_tls_id;
187 static MonoLLVMModule jit_module, aot_module;
188 static gboolean jit_module_inited;
189 static int memset_param_count, memcpy_param_count;
190 static const char *memset_func_name;
191 static const char *memcpy_func_name;
192 static const char *eh_selector_name;
194 static void init_jit_module (void);
197 * IntPtrType:
199 * The LLVM type with width == sizeof (gpointer)
201 static LLVMTypeRef
202 IntPtrType (void)
204 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
208 * get_vtype_size:
210 * Return the size of the LLVM representation of the vtype T.
212 static guint32
213 get_vtype_size (MonoType *t)
215 int size;
217 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
219 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
220 size ++;
222 return size;
226 * simd_class_to_llvm_type:
228 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
230 static LLVMTypeRef
231 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
233 if (!strcmp (klass->name, "Vector2d")) {
234 return LLVMVectorType (LLVMDoubleType (), 2);
235 } else if (!strcmp (klass->name, "Vector2l")) {
236 return LLVMVectorType (LLVMInt64Type (), 2);
237 } else if (!strcmp (klass->name, "Vector2ul")) {
238 return LLVMVectorType (LLVMInt64Type (), 2);
239 } else if (!strcmp (klass->name, "Vector4i")) {
240 return LLVMVectorType (LLVMInt32Type (), 4);
241 } else if (!strcmp (klass->name, "Vector4ui")) {
242 return LLVMVectorType (LLVMInt32Type (), 4);
243 } else if (!strcmp (klass->name, "Vector4f")) {
244 return LLVMVectorType (LLVMFloatType (), 4);
245 } else if (!strcmp (klass->name, "Vector8s")) {
246 return LLVMVectorType (LLVMInt16Type (), 8);
247 } else if (!strcmp (klass->name, "Vector8us")) {
248 return LLVMVectorType (LLVMInt16Type (), 8);
249 } else if (!strcmp (klass->name, "Vector16sb")) {
250 return LLVMVectorType (LLVMInt8Type (), 16);
251 } else if (!strcmp (klass->name, "Vector16b")) {
252 return LLVMVectorType (LLVMInt8Type (), 16);
253 } else {
254 printf ("%s\n", klass->name);
255 NOT_IMPLEMENTED;
256 return NULL;
260 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
261 static inline G_GNUC_UNUSED LLVMTypeRef
262 type_to_simd_type (int type)
264 switch (type) {
265 case MONO_TYPE_I1:
266 return LLVMVectorType (LLVMInt8Type (), 16);
267 case MONO_TYPE_I2:
268 return LLVMVectorType (LLVMInt16Type (), 8);
269 case MONO_TYPE_I4:
270 return LLVMVectorType (LLVMInt32Type (), 4);
271 case MONO_TYPE_I8:
272 return LLVMVectorType (LLVMInt64Type (), 2);
273 case MONO_TYPE_R8:
274 return LLVMVectorType (LLVMDoubleType (), 2);
275 case MONO_TYPE_R4:
276 return LLVMVectorType (LLVMFloatType (), 4);
277 default:
278 g_assert_not_reached ();
279 return NULL;
284 * type_to_llvm_type:
286 * Return the LLVM type corresponding to T.
288 static LLVMTypeRef
289 type_to_llvm_type (EmitContext *ctx, MonoType *t)
291 if (t->byref)
292 return LLVMPointerType (LLVMInt8Type (), 0);
293 switch (t->type) {
294 case MONO_TYPE_VOID:
295 return LLVMVoidType ();
296 case MONO_TYPE_I1:
297 return LLVMInt8Type ();
298 case MONO_TYPE_I2:
299 return LLVMInt16Type ();
300 case MONO_TYPE_I4:
301 return LLVMInt32Type ();
302 case MONO_TYPE_U1:
303 return LLVMInt8Type ();
304 case MONO_TYPE_U2:
305 return LLVMInt16Type ();
306 case MONO_TYPE_U4:
307 return LLVMInt32Type ();
308 case MONO_TYPE_BOOLEAN:
309 return LLVMInt8Type ();
310 case MONO_TYPE_I8:
311 case MONO_TYPE_U8:
312 return LLVMInt64Type ();
313 case MONO_TYPE_CHAR:
314 return LLVMInt16Type ();
315 case MONO_TYPE_R4:
316 return LLVMFloatType ();
317 case MONO_TYPE_R8:
318 return LLVMDoubleType ();
319 case MONO_TYPE_I:
320 case MONO_TYPE_U:
321 return IntPtrType ();
322 case MONO_TYPE_OBJECT:
323 case MONO_TYPE_CLASS:
324 case MONO_TYPE_ARRAY:
325 case MONO_TYPE_SZARRAY:
326 case MONO_TYPE_STRING:
327 case MONO_TYPE_PTR:
328 return LLVMPointerType (IntPtrType (), 0);
329 case MONO_TYPE_VAR:
330 case MONO_TYPE_MVAR:
331 /* Because of generic sharing */
332 return IntPtrType ();
333 case MONO_TYPE_GENERICINST:
334 if (!mono_type_generic_inst_is_valuetype (t))
335 return IntPtrType ();
336 /* Fall through */
337 case MONO_TYPE_VALUETYPE:
338 case MONO_TYPE_TYPEDBYREF: {
339 MonoClass *klass;
340 LLVMTypeRef ltype;
342 klass = mono_class_from_mono_type (t);
344 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
345 return simd_class_to_llvm_type (ctx, klass);
347 if (klass->enumtype)
348 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
349 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
350 if (!ltype) {
351 int i, size;
352 LLVMTypeRef *eltypes;
354 size = get_vtype_size (t);
356 eltypes = g_new (LLVMTypeRef, size);
357 for (i = 0; i < size; ++i)
358 eltypes [i] = LLVMInt8Type ();
360 /* We couldn't name these types since LLVM uses structural type equality */
361 ltype = LLVMStructType (eltypes, size, FALSE);
362 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
363 g_free (eltypes);
365 return ltype;
368 default:
369 printf ("X: %d\n", t->type);
370 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
371 ctx->cfg->disable_llvm = TRUE;
372 return NULL;
377 * type_is_unsigned:
379 * Return whenever T is an unsigned int type.
381 static gboolean
382 type_is_unsigned (EmitContext *ctx, MonoType *t)
384 if (t->byref)
385 return FALSE;
386 switch (t->type) {
387 case MONO_TYPE_U1:
388 case MONO_TYPE_U2:
389 case MONO_TYPE_U4:
390 case MONO_TYPE_U8:
391 return TRUE;
392 default:
393 return FALSE;
398 * type_to_llvm_arg_type:
400 * Same as type_to_llvm_type, but treat i8/i16 as i32.
402 static LLVMTypeRef
403 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
405 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
407 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
409 * LLVM generates code which only sets the lower bits, while JITted
410 * code expects all the bits to be set.
412 ptype = LLVMInt32Type ();
415 return ptype;
419 * llvm_type_to_stack_type:
421 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
422 * on the IL stack.
424 static G_GNUC_UNUSED LLVMTypeRef
425 llvm_type_to_stack_type (LLVMTypeRef type)
427 if (type == NULL)
428 return NULL;
429 if (type == LLVMInt8Type ())
430 return LLVMInt32Type ();
431 else if (type == LLVMInt16Type ())
432 return LLVMInt32Type ();
433 else if (type == LLVMFloatType ())
434 return LLVMDoubleType ();
435 else
436 return type;
440 * regtype_to_llvm_type:
442 * Return the LLVM type corresponding to the regtype C used in instruction
443 * descriptions.
445 static LLVMTypeRef
446 regtype_to_llvm_type (char c)
448 switch (c) {
449 case 'i':
450 return LLVMInt32Type ();
451 case 'l':
452 return LLVMInt64Type ();
453 case 'f':
454 return LLVMDoubleType ();
455 default:
456 return NULL;
461 * op_to_llvm_type:
463 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
465 static LLVMTypeRef
466 op_to_llvm_type (int opcode)
468 switch (opcode) {
469 case OP_ICONV_TO_I1:
470 case OP_LCONV_TO_I1:
471 return LLVMInt8Type ();
472 case OP_ICONV_TO_U1:
473 case OP_LCONV_TO_U1:
474 return LLVMInt8Type ();
475 case OP_ICONV_TO_I2:
476 case OP_LCONV_TO_I2:
477 return LLVMInt16Type ();
478 case OP_ICONV_TO_U2:
479 case OP_LCONV_TO_U2:
480 return LLVMInt16Type ();
481 case OP_ICONV_TO_I4:
482 case OP_LCONV_TO_I4:
483 return LLVMInt32Type ();
484 case OP_ICONV_TO_U4:
485 case OP_LCONV_TO_U4:
486 return LLVMInt32Type ();
487 case OP_ICONV_TO_I8:
488 return LLVMInt64Type ();
489 case OP_ICONV_TO_R4:
490 return LLVMFloatType ();
491 case OP_ICONV_TO_R8:
492 return LLVMDoubleType ();
493 case OP_ICONV_TO_U8:
494 return LLVMInt64Type ();
495 case OP_FCONV_TO_I4:
496 return LLVMInt32Type ();
497 case OP_FCONV_TO_I8:
498 return LLVMInt64Type ();
499 case OP_FCONV_TO_I1:
500 case OP_FCONV_TO_U1:
501 return LLVMInt8Type ();
502 case OP_FCONV_TO_I2:
503 case OP_FCONV_TO_U2:
504 return LLVMInt16Type ();
505 case OP_FCONV_TO_I:
506 case OP_FCONV_TO_U:
507 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
508 case OP_IADD_OVF:
509 case OP_IADD_OVF_UN:
510 case OP_ISUB_OVF:
511 case OP_ISUB_OVF_UN:
512 case OP_IMUL_OVF:
513 case OP_IMUL_OVF_UN:
514 return LLVMInt32Type ();
515 case OP_LADD_OVF:
516 case OP_LADD_OVF_UN:
517 case OP_LSUB_OVF:
518 case OP_LSUB_OVF_UN:
519 case OP_LMUL_OVF:
520 case OP_LMUL_OVF_UN:
521 return LLVMInt64Type ();
522 default:
523 printf ("%s\n", mono_inst_name (opcode));
524 g_assert_not_reached ();
525 return NULL;
530 * load_store_to_llvm_type:
532 * Return the size/sign/zero extension corresponding to the load/store opcode
533 * OPCODE.
535 static LLVMTypeRef
536 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
538 *sext = FALSE;
539 *zext = FALSE;
541 switch (opcode) {
542 case OP_LOADI1_MEMBASE:
543 case OP_STOREI1_MEMBASE_REG:
544 case OP_STOREI1_MEMBASE_IMM:
545 *size = 1;
546 *sext = TRUE;
547 return LLVMInt8Type ();
548 case OP_LOADU1_MEMBASE:
549 case OP_LOADU1_MEM:
550 *size = 1;
551 *zext = TRUE;
552 return LLVMInt8Type ();
553 case OP_LOADI2_MEMBASE:
554 case OP_STOREI2_MEMBASE_REG:
555 case OP_STOREI2_MEMBASE_IMM:
556 *size = 2;
557 *sext = TRUE;
558 return LLVMInt16Type ();
559 case OP_LOADU2_MEMBASE:
560 case OP_LOADU2_MEM:
561 *size = 2;
562 *zext = TRUE;
563 return LLVMInt16Type ();
564 case OP_LOADI4_MEMBASE:
565 case OP_LOADU4_MEMBASE:
566 case OP_LOADI4_MEM:
567 case OP_LOADU4_MEM:
568 case OP_STOREI4_MEMBASE_REG:
569 case OP_STOREI4_MEMBASE_IMM:
570 *size = 4;
571 return LLVMInt32Type ();
572 case OP_LOADI8_MEMBASE:
573 case OP_LOADI8_MEM:
574 case OP_STOREI8_MEMBASE_REG:
575 case OP_STOREI8_MEMBASE_IMM:
576 *size = 8;
577 return LLVMInt64Type ();
578 case OP_LOADR4_MEMBASE:
579 case OP_STORER4_MEMBASE_REG:
580 *size = 4;
581 return LLVMFloatType ();
582 case OP_LOADR8_MEMBASE:
583 case OP_STORER8_MEMBASE_REG:
584 *size = 8;
585 return LLVMDoubleType ();
586 case OP_LOAD_MEMBASE:
587 case OP_LOAD_MEM:
588 case OP_STORE_MEMBASE_REG:
589 case OP_STORE_MEMBASE_IMM:
590 *size = sizeof (gpointer);
591 return IntPtrType ();
592 default:
593 g_assert_not_reached ();
594 return NULL;
599 * ovf_op_to_intrins:
601 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
603 static const char*
604 ovf_op_to_intrins (int opcode)
606 switch (opcode) {
607 case OP_IADD_OVF:
608 return "llvm.sadd.with.overflow.i32";
609 case OP_IADD_OVF_UN:
610 return "llvm.uadd.with.overflow.i32";
611 case OP_ISUB_OVF:
612 return "llvm.ssub.with.overflow.i32";
613 case OP_ISUB_OVF_UN:
614 return "llvm.usub.with.overflow.i32";
615 case OP_IMUL_OVF:
616 return "llvm.smul.with.overflow.i32";
617 case OP_IMUL_OVF_UN:
618 return "llvm.umul.with.overflow.i32";
619 case OP_LADD_OVF:
620 return "llvm.sadd.with.overflow.i64";
621 case OP_LADD_OVF_UN:
622 return "llvm.uadd.with.overflow.i64";
623 case OP_LSUB_OVF:
624 return "llvm.ssub.with.overflow.i64";
625 case OP_LSUB_OVF_UN:
626 return "llvm.usub.with.overflow.i64";
627 case OP_LMUL_OVF:
628 return "llvm.smul.with.overflow.i64";
629 case OP_LMUL_OVF_UN:
630 return "llvm.umul.with.overflow.i64";
631 default:
632 g_assert_not_reached ();
633 return NULL;
637 static const char*
638 simd_op_to_intrins (int opcode)
640 switch (opcode) {
641 #if defined(TARGET_X86) || defined(TARGET_AMD64)
642 case OP_MINPD:
643 return "llvm.x86.sse2.min.pd";
644 case OP_MINPS:
645 return "llvm.x86.sse.min.ps";
646 case OP_PMIND_UN:
647 return "llvm.x86.sse41.pminud";
648 case OP_PMINW_UN:
649 return "llvm.x86.sse41.pminuw";
650 case OP_PMINB_UN:
651 return "llvm.x86.sse2.pminu.b";
652 case OP_PMINW:
653 return "llvm.x86.sse2.pmins.w";
654 case OP_MAXPD:
655 return "llvm.x86.sse2.max.pd";
656 case OP_MAXPS:
657 return "llvm.x86.sse.max.ps";
658 case OP_HADDPD:
659 return "llvm.x86.sse3.hadd.pd";
660 case OP_HADDPS:
661 return "llvm.x86.sse3.hadd.ps";
662 case OP_HSUBPD:
663 return "llvm.x86.sse3.hsub.pd";
664 case OP_HSUBPS:
665 return "llvm.x86.sse3.hsub.ps";
666 case OP_PMAXD_UN:
667 return "llvm.x86.sse41.pmaxud";
668 case OP_PMAXW_UN:
669 return "llvm.x86.sse41.pmaxuw";
670 case OP_PMAXB_UN:
671 return "llvm.x86.sse2.pmaxu.b";
672 case OP_ADDSUBPS:
673 return "llvm.x86.sse3.addsub.ps";
674 case OP_ADDSUBPD:
675 return "llvm.x86.sse3.addsub.pd";
676 case OP_EXTRACT_MASK:
677 return "llvm.x86.sse2.pmovmskb.128";
678 case OP_PSHRW:
679 case OP_PSHRW_REG:
680 return "llvm.x86.sse2.psrli.w";
681 case OP_PSHRD:
682 case OP_PSHRD_REG:
683 return "llvm.x86.sse2.psrli.d";
684 case OP_PSHRQ:
685 case OP_PSHRQ_REG:
686 return "llvm.x86.sse2.psrli.q";
687 case OP_PSHLW:
688 case OP_PSHLW_REG:
689 return "llvm.x86.sse2.pslli.w";
690 case OP_PSHLD:
691 case OP_PSHLD_REG:
692 return "llvm.x86.sse2.pslli.d";
693 case OP_PSHLQ:
694 case OP_PSHLQ_REG:
695 return "llvm.x86.sse2.pslli.q";
696 case OP_PSARW:
697 case OP_PSARW_REG:
698 return "llvm.x86.sse2.psrai.w";
699 case OP_PSARD:
700 case OP_PSARD_REG:
701 return "llvm.x86.sse2.psrai.d";
702 case OP_PADDB_SAT:
703 return "llvm.x86.sse2.padds.b";
704 case OP_PADDW_SAT:
705 return "llvm.x86.sse2.padds.w";
706 case OP_PSUBB_SAT:
707 return "llvm.x86.sse2.psubs.b";
708 case OP_PSUBW_SAT:
709 return "llvm.x86.sse2.psubs.w";
710 case OP_PADDB_SAT_UN:
711 return "llvm.x86.sse2.paddus.b";
712 case OP_PADDW_SAT_UN:
713 return "llvm.x86.sse2.paddus.w";
714 case OP_PSUBB_SAT_UN:
715 return "llvm.x86.sse2.psubus.b";
716 case OP_PSUBW_SAT_UN:
717 return "llvm.x86.sse2.psubus.w";
718 case OP_PAVGB_UN:
719 return "llvm.x86.sse2.pavg.b";
720 case OP_PAVGW_UN:
721 return "llvm.x86.sse2.pavg.w";
722 case OP_SQRTPS:
723 return "llvm.x86.sse.sqrt.ps";
724 case OP_SQRTPD:
725 return "llvm.x86.sse2.sqrt.pd";
726 case OP_RSQRTPS:
727 return "llvm.x86.sse.rsqrt.ps";
728 case OP_RCPPS:
729 return "llvm.x86.sse.rcp.ps";
730 case OP_PCMPEQB:
731 return "llvm.x86.sse2.pcmpeq.b";
732 case OP_PCMPEQW:
733 return "llvm.x86.sse2.pcmpeq.w";
734 case OP_PCMPEQD:
735 return "llvm.x86.sse2.pcmpeq.d";
736 case OP_PCMPEQQ:
737 return "llvm.x86.sse41.pcmpeqq";
738 case OP_PCMPGTB:
739 return "llvm.x86.sse2.pcmpgt.b";
740 case OP_CVTDQ2PD:
741 return "llvm.x86.sse2.cvtdq2pd";
742 case OP_CVTDQ2PS:
743 return "llvm.x86.sse2.cvtdq2ps";
744 case OP_CVTPD2DQ:
745 return "llvm.x86.sse2.cvtpd2dq";
746 case OP_CVTPS2DQ:
747 return "llvm.x86.sse2.cvtps2dq";
748 case OP_CVTPD2PS:
749 return "llvm.x86.sse2.cvtpd2ps";
750 case OP_CVTPS2PD:
751 return "llvm.x86.sse2.cvtps2pd";
752 case OP_CVTTPD2DQ:
753 return "llvm.x86.sse2.cvttpd2dq";
754 case OP_CVTTPS2DQ:
755 return "llvm.x86.sse2.cvttps2dq";
756 case OP_COMPPS:
757 return "llvm.x86.sse.cmp.ps";
758 case OP_COMPPD:
759 return "llvm.x86.sse2.cmp.pd";
760 case OP_PACKW:
761 return "llvm.x86.sse2.packsswb.128";
762 case OP_PACKD:
763 return "llvm.x86.sse2.packssdw.128";
764 case OP_PACKW_UN:
765 return "llvm.x86.sse2.packuswb.128";
766 case OP_PACKD_UN:
767 return "llvm.x86.sse41.packusdw";
768 case OP_PMULW_HIGH:
769 return "llvm.x86.sse2.pmulh.w";
770 case OP_PMULW_HIGH_UN:
771 return "llvm.x86.sse2.pmulhu.w";
772 #endif
773 default:
774 g_assert_not_reached ();
775 return NULL;
779 static LLVMTypeRef
780 simd_op_to_llvm_type (int opcode)
782 #if defined(TARGET_X86) || defined(TARGET_AMD64)
783 switch (opcode) {
784 case OP_EXTRACT_R8:
785 case OP_EXPAND_R8:
786 return type_to_simd_type (MONO_TYPE_R8);
787 case OP_EXTRACT_I8:
788 case OP_EXPAND_I8:
789 return type_to_simd_type (MONO_TYPE_I8);
790 case OP_EXTRACT_I4:
791 case OP_EXPAND_I4:
792 return type_to_simd_type (MONO_TYPE_I4);
793 case OP_EXTRACT_I2:
794 case OP_EXTRACT_U2:
795 case OP_EXTRACTX_U2:
796 case OP_EXPAND_I2:
797 return type_to_simd_type (MONO_TYPE_I2);
798 case OP_EXTRACT_I1:
799 case OP_EXTRACT_U1:
800 case OP_EXPAND_I1:
801 return type_to_simd_type (MONO_TYPE_I1);
802 case OP_EXPAND_R4:
803 return type_to_simd_type (MONO_TYPE_R4);
804 case OP_CVTDQ2PD:
805 case OP_CVTDQ2PS:
806 return type_to_simd_type (MONO_TYPE_I4);
807 case OP_CVTPD2DQ:
808 case OP_CVTPD2PS:
809 case OP_CVTTPD2DQ:
810 return type_to_simd_type (MONO_TYPE_R8);
811 case OP_CVTPS2DQ:
812 case OP_CVTPS2PD:
813 case OP_CVTTPS2DQ:
814 return type_to_simd_type (MONO_TYPE_R4);
815 case OP_EXTRACT_MASK:
816 return type_to_simd_type (MONO_TYPE_I1);
817 case OP_SQRTPS:
818 case OP_RSQRTPS:
819 case OP_RCPPS:
820 case OP_DUPPS_LOW:
821 case OP_DUPPS_HIGH:
822 return type_to_simd_type (MONO_TYPE_R4);
823 case OP_SQRTPD:
824 case OP_DUPPD:
825 return type_to_simd_type (MONO_TYPE_R8);
826 default:
827 g_assert_not_reached ();
828 return NULL;
830 #else
831 return NULL;
832 #endif
836 * get_bb:
838 * Return the LLVM basic block corresponding to BB.
840 static LLVMBasicBlockRef
841 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
843 char bb_name [128];
845 if (ctx->bblocks [bb->block_num].bblock == NULL) {
846 sprintf (bb_name, "BB%d", bb->block_num);
848 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
849 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
852 return ctx->bblocks [bb->block_num].bblock;
856 * get_end_bb:
858 * Return the last LLVM bblock corresponding to BB.
859 * This might not be equal to the bb returned by get_bb () since we need to generate
860 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
862 static LLVMBasicBlockRef
863 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
865 get_bb (ctx, bb);
866 return ctx->bblocks [bb->block_num].end_bblock;
869 static LLVMBasicBlockRef
870 gen_bb (EmitContext *ctx, const char *prefix)
872 char bb_name [128];
874 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
875 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
879 * resolve_patch:
881 * Return the target of the patch identified by TYPE and TARGET.
883 static gpointer
884 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
886 MonoJumpInfo ji;
888 memset (&ji, 0, sizeof (ji));
889 ji.type = type;
890 ji.data.target = target;
892 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
896 * convert_full:
898 * Emit code to convert the LLVM value V to DTYPE.
900 static LLVMValueRef
901 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
903 LLVMTypeRef stype = LLVMTypeOf (v);
905 if (stype != dtype) {
906 gboolean ext = FALSE;
908 /* Extend */
909 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
910 ext = TRUE;
911 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
912 ext = TRUE;
913 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
914 ext = TRUE;
916 if (ext)
917 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
919 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
920 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
922 /* Trunc */
923 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
924 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
925 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
926 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
927 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
928 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
929 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
930 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
932 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
933 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
934 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
935 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
936 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
937 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
939 #ifdef MONO_ARCH_SOFT_FLOAT
940 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
941 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
942 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
943 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
944 #endif
946 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
947 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
949 LLVMDumpValue (v);
950 LLVMDumpValue (LLVMConstNull (dtype));
951 g_assert_not_reached ();
952 return NULL;
953 } else {
954 return v;
958 static LLVMValueRef
959 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
961 return convert_full (ctx, v, dtype, FALSE);
965 * emit_volatile_load:
967 * If vreg is volatile, emit a load from its address.
969 static LLVMValueRef
970 emit_volatile_load (EmitContext *ctx, int vreg)
972 MonoType *t;
974 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
975 t = ctx->vreg_cli_types [vreg];
976 if (t && !t->byref) {
978 * Might have to zero extend since llvm doesn't have
979 * unsigned types.
981 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
982 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
983 else if (t->type == MONO_TYPE_U8)
984 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
987 return v;
991 * emit_volatile_store:
993 * If VREG is volatile, emit a store from its value to its address.
995 static void
996 emit_volatile_store (EmitContext *ctx, int vreg)
998 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1000 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1001 g_assert (ctx->addresses [vreg]);
1002 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1006 typedef struct {
1008 * Maps parameter indexes in the original signature to parameter indexes
1009 * in the LLVM signature.
1011 int *pindexes;
1012 /* The indexes of various special arguments in the LLVM signature */
1013 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1014 } LLVMSigInfo;
1017 * sig_to_llvm_sig_full:
1019 * Return the LLVM signature corresponding to the mono signature SIG using the
1020 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1022 static LLVMTypeRef
1023 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1024 LLVMSigInfo *sinfo)
1026 LLVMTypeRef ret_type;
1027 LLVMTypeRef *param_types = NULL;
1028 LLVMTypeRef res;
1029 int i, j, pindex, vret_arg_pindex = 0;
1030 int *pindexes;
1031 gboolean vretaddr = FALSE;
1033 if (sinfo)
1034 memset (sinfo, 0, sizeof (LLVMSigInfo));
1036 ret_type = type_to_llvm_type (ctx, sig->ret);
1037 CHECK_FAILURE (ctx);
1039 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1040 /* LLVM models this by returning an aggregate value */
1041 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1042 LLVMTypeRef members [2];
1044 members [0] = IntPtrType ();
1045 ret_type = LLVMStructType (members, 1, FALSE);
1046 } else {
1047 g_assert_not_reached ();
1049 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1050 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1051 vretaddr = TRUE;
1052 ret_type = LLVMVoidType ();
1055 pindexes = g_new0 (int, sig->param_count);
1056 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1057 pindex = 0;
1058 if (cinfo && cinfo->rgctx_arg) {
1059 if (sinfo)
1060 sinfo->rgctx_arg_pindex = pindex;
1061 param_types [pindex] = IntPtrType ();
1062 pindex ++;
1064 if (cinfo && cinfo->imt_arg && IS_LLVM_MONO_BRANCH) {
1065 if (sinfo)
1066 sinfo->imt_arg_pindex = pindex;
1067 param_types [pindex] = IntPtrType ();
1068 pindex ++;
1070 if (vretaddr) {
1071 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1072 vret_arg_pindex = pindex;
1073 if (cinfo->vret_arg_index == 1) {
1074 /* Add the slots consumed by the first argument */
1075 LLVMArgInfo *ainfo = &cinfo->args [0];
1076 switch (ainfo->storage) {
1077 case LLVMArgVtypeInReg:
1078 for (j = 0; j < 2; ++j) {
1079 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1080 vret_arg_pindex ++;
1082 break;
1083 default:
1084 vret_arg_pindex ++;
1088 if (sinfo)
1089 sinfo->vret_arg_pindex = vret_arg_pindex;
1092 if (vretaddr && vret_arg_pindex == pindex)
1093 param_types [pindex ++] = IntPtrType ();
1094 if (sig->hasthis) {
1095 if (sinfo)
1096 sinfo->this_arg_pindex = pindex;
1097 param_types [pindex ++] = IntPtrType ();
1099 if (vretaddr && vret_arg_pindex == pindex)
1100 param_types [pindex ++] = IntPtrType ();
1101 for (i = 0; i < sig->param_count; ++i) {
1102 if (vretaddr && vret_arg_pindex == pindex)
1103 param_types [pindex ++] = IntPtrType ();
1104 pindexes [i] = pindex;
1105 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1106 for (j = 0; j < 2; ++j) {
1107 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1108 case LLVMArgInIReg:
1109 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1110 break;
1111 case LLVMArgNone:
1112 break;
1113 default:
1114 g_assert_not_reached ();
1117 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1118 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1119 CHECK_FAILURE (ctx);
1120 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1121 pindex ++;
1122 } else {
1123 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1126 if (vretaddr && vret_arg_pindex == pindex)
1127 param_types [pindex ++] = IntPtrType ();
1129 CHECK_FAILURE (ctx);
1131 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1132 g_free (param_types);
1134 if (sinfo) {
1135 sinfo->pindexes = pindexes;
1136 } else {
1137 g_free (pindexes);
1140 return res;
1142 FAILURE:
1143 g_free (param_types);
1145 return NULL;
1148 static LLVMTypeRef
1149 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1151 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1155 * LLVMFunctionType1:
1157 * Create an LLVM function type from the arguments.
1159 static G_GNUC_UNUSED LLVMTypeRef
1160 LLVMFunctionType1(LLVMTypeRef ReturnType,
1161 LLVMTypeRef ParamType1,
1162 int IsVarArg)
1164 LLVMTypeRef param_types [1];
1166 param_types [0] = ParamType1;
1168 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1172 * LLVMFunctionType2:
1174 * Create an LLVM function type from the arguments.
1176 static LLVMTypeRef
1177 LLVMFunctionType2(LLVMTypeRef ReturnType,
1178 LLVMTypeRef ParamType1,
1179 LLVMTypeRef ParamType2,
1180 int IsVarArg)
1182 LLVMTypeRef param_types [2];
1184 param_types [0] = ParamType1;
1185 param_types [1] = ParamType2;
1187 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1191 * LLVMFunctionType3:
1193 * Create an LLVM function type from the arguments.
1195 static LLVMTypeRef
1196 LLVMFunctionType3(LLVMTypeRef ReturnType,
1197 LLVMTypeRef ParamType1,
1198 LLVMTypeRef ParamType2,
1199 LLVMTypeRef ParamType3,
1200 int IsVarArg)
1202 LLVMTypeRef param_types [3];
1204 param_types [0] = ParamType1;
1205 param_types [1] = ParamType2;
1206 param_types [2] = ParamType3;
1208 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1212 * create_builder:
1214 * Create an LLVM builder and remember it so it can be freed later.
1216 static LLVMBuilderRef
1217 create_builder (EmitContext *ctx)
1219 LLVMBuilderRef builder = LLVMCreateBuilder ();
1221 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1223 return builder;
1226 static LLVMValueRef
1227 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1229 char *callee_name = mono_aot_get_plt_symbol (type, data);
1230 LLVMValueRef callee;
1232 if (!callee_name)
1233 return NULL;
1235 if (ctx->cfg->compile_aot)
1236 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1237 mono_add_patch_info (ctx->cfg, 0, type, data);
1239 // FIXME: Locking
1240 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1241 if (!callee) {
1242 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1244 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1246 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1249 return callee;
1252 static int
1253 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1255 MonoMethodHeader *header = cfg->header;
1256 MonoExceptionClause *clause;
1257 int i;
1259 /* Directly */
1260 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1261 return (bb->region >> 8) - 1;
1263 /* Indirectly */
1264 for (i = 0; i < header->num_clauses; ++i) {
1265 clause = &header->clauses [i];
1267 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1268 return i;
1271 return -1;
1274 static void
1275 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1277 LLVMValueRef md_arg;
1278 int md_kind;
1280 if (!IS_LLVM_MONO_BRANCH)
1281 return;
1283 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1284 md_arg = LLVMMDString ("mono", 4);
1285 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1289 * emit_call:
1291 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1292 * a try region.
1294 static LLVMValueRef
1295 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1297 MonoCompile *cfg = ctx->cfg;
1298 LLVMValueRef lcall;
1299 LLVMBuilderRef builder = *builder_ref;
1300 int clause_index;
1302 clause_index = get_handler_clause (cfg, bb);
1304 if (clause_index != -1) {
1305 MonoMethodHeader *header = cfg->header;
1306 MonoExceptionClause *ec = &header->clauses [clause_index];
1307 MonoBasicBlock *tblock;
1308 LLVMBasicBlockRef ex_bb, noex_bb;
1311 * Have to use an invoke instead of a call, branching to the
1312 * handler bblock of the clause containing this bblock.
1315 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1317 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1318 g_assert (tblock);
1320 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1322 ex_bb = get_bb (ctx, tblock);
1324 noex_bb = gen_bb (ctx, "NOEX_BB");
1326 /* Use an invoke */
1327 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1329 builder = ctx->builder = create_builder (ctx);
1330 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1332 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1333 } else {
1334 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1335 ctx->builder = builder;
1338 *builder_ref = ctx->builder;
1340 return lcall;
1343 static LLVMValueRef
1344 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1346 const char *intrins_name;
1347 LLVMValueRef args [16], res;
1348 LLVMTypeRef addr_type;
1350 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1352 * We handle loads which can fault by calling a mono specific intrinsic
1353 * using an invoke, so they are handled properly inside try blocks.
1354 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1355 * are marked with IntrReadArgMem.
1357 switch (size) {
1358 case 1:
1359 intrins_name = "llvm.mono.load.i8.p0i8";
1360 break;
1361 case 2:
1362 intrins_name = "llvm.mono.load.i16.p0i16";
1363 break;
1364 case 4:
1365 intrins_name = "llvm.mono.load.i32.p0i32";
1366 break;
1367 case 8:
1368 intrins_name = "llvm.mono.load.i64.p0i64";
1369 break;
1370 default:
1371 g_assert_not_reached ();
1374 addr_type = LLVMTypeOf (addr);
1375 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1376 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1378 args [0] = addr;
1379 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1380 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1381 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1383 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1384 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1385 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1386 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1388 return res;
1389 } else {
1390 LLVMValueRef res;
1393 * We emit volatile loads for loads which can fault, because otherwise
1394 * LLVM will generate invalid code when encountering a load from a
1395 * NULL address.
1397 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1399 /* Mark it with a custom metadata */
1401 if (is_faulting)
1402 set_metadata_flag (res, "mono.faulting.load");
1405 return res;
1409 static void
1410 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1412 const char *intrins_name;
1413 LLVMValueRef args [16];
1415 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1416 switch (size) {
1417 case 1:
1418 intrins_name = "llvm.mono.store.i8.p0i8";
1419 break;
1420 case 2:
1421 intrins_name = "llvm.mono.store.i16.p0i16";
1422 break;
1423 case 4:
1424 intrins_name = "llvm.mono.store.i32.p0i32";
1425 break;
1426 case 8:
1427 intrins_name = "llvm.mono.store.i64.p0i64";
1428 break;
1429 default:
1430 g_assert_not_reached ();
1433 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1434 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1435 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1438 args [0] = value;
1439 args [1] = addr;
1440 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1441 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1442 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1443 } else {
1444 LLVMBuildStore (*builder_ref, value, addr);
1449 * emit_cond_system_exception:
1451 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1452 * Might set the ctx exception.
1454 static void
1455 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1457 LLVMBasicBlockRef ex_bb, noex_bb;
1458 LLVMBuilderRef builder;
1459 MonoClass *exc_class;
1460 LLVMValueRef args [2];
1462 ex_bb = gen_bb (ctx, "EX_BB");
1463 noex_bb = gen_bb (ctx, "NOEX_BB");
1465 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1467 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1468 g_assert (exc_class);
1470 /* Emit exception throwing code */
1471 builder = create_builder (ctx);
1472 LLVMPositionBuilderAtEnd (builder, ex_bb);
1474 if (!ctx->lmodule->throw_corlib_exception) {
1475 LLVMValueRef callee;
1476 LLVMTypeRef sig;
1477 const char *icall_name;
1479 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1480 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1481 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1482 if (IS_LLVM_MONO_BRANCH) {
1483 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1484 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1485 } else {
1486 icall_name = "llvm_throw_corlib_exception_trampoline";
1487 throw_sig->params [1] = &mono_get_int32_class ()->byval_arg;
1489 sig = sig_to_llvm_sig (ctx, throw_sig);
1491 if (ctx->cfg->compile_aot) {
1492 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1493 } else {
1494 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1497 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1498 * - On x86, LLVM generated code doesn't push the arguments
1499 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1500 * arguments, not a pc offset.
1502 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1505 mono_memory_barrier ();
1506 ctx->lmodule->throw_corlib_exception = callee;
1509 if (IS_TARGET_X86)
1510 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1511 else
1512 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1514 if (IS_LLVM_MONO_BRANCH) {
1516 * The LLVM mono branch contains changes so a block address can be passed as an
1517 * argument to a call.
1519 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1520 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1521 } else {
1523 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1524 * otherwise only the line numbers in stack traces are incorrect.
1526 if (bb->region != -1 && !IS_LLVM_MONO_BRANCH)
1527 LLVM_FAILURE (ctx, "system-ex-in-region");
1529 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1530 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1533 LLVMBuildUnreachable (builder);
1535 ctx->builder = create_builder (ctx);
1536 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1538 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1540 ctx->ex_index ++;
1541 return;
1543 FAILURE:
1544 return;
1548 * emit_reg_to_vtype:
1550 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1552 static void
1553 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1555 int j, size;
1557 size = get_vtype_size (t);
1559 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1560 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1563 for (j = 0; j < 2; ++j) {
1564 LLVMValueRef index [2], addr;
1565 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1566 LLVMTypeRef part_type;
1568 if (ainfo->pair_storage [j] == LLVMArgNone)
1569 continue;
1571 part_type = LLVMIntType (part_size * 8);
1572 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1573 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1574 addr = LLVMBuildGEP (builder, address, index, 1, "");
1575 } else {
1576 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1577 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1578 addr = LLVMBuildGEP (builder, address, index, 2, "");
1580 switch (ainfo->pair_storage [j]) {
1581 case LLVMArgInIReg:
1582 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1583 break;
1584 case LLVMArgNone:
1585 break;
1586 default:
1587 g_assert_not_reached ();
1590 size -= sizeof (gpointer);
1595 * emit_vtype_to_reg:
1597 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1598 * into REGS, and the number of registers into NREGS.
1600 static void
1601 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1603 int pindex = 0;
1604 int j, size;
1606 size = get_vtype_size (t);
1608 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1609 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1612 for (j = 0; j < 2; ++j) {
1613 LLVMValueRef index [2], addr;
1614 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1616 if (ainfo->pair_storage [j] == LLVMArgNone)
1617 continue;
1619 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1620 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1621 addr = LLVMBuildGEP (builder, address, index, 1, "");
1622 } else {
1623 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1624 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1625 addr = LLVMBuildGEP (builder, address, index, 2, "");
1627 switch (ainfo->pair_storage [j]) {
1628 case LLVMArgInIReg:
1629 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1630 break;
1631 case LLVMArgNone:
1632 break;
1633 default:
1634 g_assert_not_reached ();
1636 size -= sizeof (gpointer);
1639 *nregs = pindex;
1642 static LLVMValueRef
1643 build_alloca (EmitContext *ctx, MonoType *t)
1645 MonoClass *k = mono_class_from_mono_type (t);
1646 int align;
1648 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1649 align = 16;
1650 else
1651 align = mono_class_min_align (k);
1653 /* Sometimes align is not a power of 2 */
1654 while (mono_is_power_of_two (align) == -1)
1655 align ++;
1658 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1659 * get executed every time control reaches them.
1661 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1663 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1664 return ctx->last_alloca;
1668 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1670 static void
1671 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1673 LLVMTypeRef used_type;
1674 LLVMValueRef used, used_elem;
1676 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1677 used = LLVMAddGlobal (module, used_type, "llvm.used");
1678 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1679 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1680 LLVMSetLinkage (used, LLVMAppendingLinkage);
1681 LLVMSetSection (used, "llvm.metadata");
1685 * emit_entry_bb:
1687 * Emit code to load/convert arguments.
1689 static void
1690 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1692 int i, pindex;
1693 MonoCompile *cfg = ctx->cfg;
1694 MonoMethodSignature *sig = ctx->sig;
1695 LLVMCallInfo *linfo = ctx->linfo;
1696 MonoBasicBlock *bb;
1698 ctx->alloca_builder = create_builder (ctx);
1701 * Handle indirect/volatile variables by allocating memory for them
1702 * using 'alloca', and storing their address in a temporary.
1704 for (i = 0; i < cfg->num_varinfo; ++i) {
1705 MonoInst *var = cfg->varinfo [i];
1706 LLVMTypeRef vtype;
1708 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1709 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1710 CHECK_FAILURE (ctx);
1711 /* Could be already created by an OP_VPHI */
1712 if (!ctx->addresses [var->dreg])
1713 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1714 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1718 for (i = 0; i < sig->param_count; ++i) {
1719 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1720 int reg = cfg->args [i + sig->hasthis]->dreg;
1722 if (ainfo->storage == LLVMArgVtypeInReg) {
1723 LLVMValueRef regs [2];
1726 * Emit code to save the argument from the registers to
1727 * the real argument.
1729 pindex = ctx->pindexes [i];
1730 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1731 if (ainfo->pair_storage [1] != LLVMArgNone)
1732 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1733 else
1734 regs [1] = NULL;
1736 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1738 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1740 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1741 /* Treat these as normal values */
1742 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1744 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1745 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1747 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1748 /* Treat these as normal values */
1749 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1751 } else {
1752 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1756 if (cfg->vret_addr)
1757 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1758 if (sig->hasthis)
1759 emit_volatile_store (ctx, cfg->args [0]->dreg);
1760 for (i = 0; i < sig->param_count; ++i)
1761 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1762 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1764 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1765 LLVMValueRef this_alloc;
1768 * The exception handling code needs the location where the this argument was
1769 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1770 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1771 * location into the LSDA.
1773 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1774 /* This volatile store will keep the alloca alive */
1775 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1777 set_metadata_flag (this_alloc, "mono.this");
1780 if (cfg->rgctx_var) {
1781 LLVMValueRef rgctx_alloc, store;
1784 * We handle the rgctx arg similarly to the this pointer.
1786 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1787 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1788 /* This volatile store will keep the alloca alive */
1789 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1791 set_metadata_flag (rgctx_alloc, "mono.this");
1795 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1796 * it needs to continue normally, or return back to the exception handling system.
1798 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1799 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1800 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1801 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1802 char name [128];
1803 LLVMValueRef val;
1805 sprintf (name, "finally_ind_bb%d", bb->block_num);
1806 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1807 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1809 ctx->bblocks [bb->block_num].finally_ind = val;
1812 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1813 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1814 * LLVM optimizer passes.
1816 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1817 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1821 FAILURE:
1825 /* Have to export this for AOT */
1826 void
1827 mono_personality (void);
1829 void
1830 mono_personality (void)
1832 /* Not used */
1833 g_assert_not_reached ();
1836 static void
1837 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1839 MonoCompile *cfg = ctx->cfg;
1840 LLVMModuleRef module = ctx->module;
1841 LLVMValueRef *values = ctx->values;
1842 LLVMValueRef *addresses = ctx->addresses;
1843 MonoCallInst *call = (MonoCallInst*)ins;
1844 MonoMethodSignature *sig = call->signature;
1845 LLVMValueRef callee, lcall;
1846 LLVMValueRef *args;
1847 LLVMCallInfo *cinfo;
1848 GSList *l;
1849 int i, len;
1850 gboolean vretaddr;
1851 LLVMTypeRef llvm_sig;
1852 gpointer target;
1853 gboolean virtual, calli;
1854 LLVMBuilderRef builder = *builder_ref;
1855 LLVMSigInfo sinfo;
1857 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1858 LLVM_FAILURE (ctx, "non-default callconv");
1860 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
1861 LLVM_FAILURE (ctx, "rgctx reg in call");
1863 if (call->rgctx_reg && !IS_LLVM_MONO_BRANCH) {
1865 * It might be possible to support this by creating a static rgctx trampoline, but
1866 * common_call_trampoline () would patch callsites to call the trampoline, which
1867 * would be incorrect if the rgctx arg is computed dynamically.
1869 LLVM_FAILURE (ctx, "rgctx reg");
1872 cinfo = call->cinfo;
1873 if (call->rgctx_arg_reg)
1874 cinfo->rgctx_arg = TRUE;
1875 if (call->imt_arg_reg)
1876 cinfo->imt_arg = TRUE;
1878 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1880 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1881 CHECK_FAILURE (ctx);
1883 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);
1884 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);
1886 /* FIXME: Avoid creating duplicate methods */
1888 if (ins->flags & MONO_INST_HAS_METHOD) {
1889 if (virtual) {
1890 callee = NULL;
1891 } else {
1892 if (cfg->compile_aot) {
1893 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1894 if (!callee)
1895 LLVM_FAILURE (ctx, "can't encode patch");
1896 } else {
1897 callee = LLVMAddFunction (module, "", llvm_sig);
1899 target =
1900 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1901 call->method);
1902 LLVMAddGlobalMapping (ee, callee, target);
1905 } else if (calli) {
1906 } else {
1907 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1909 if (info) {
1911 MonoJumpInfo ji;
1913 memset (&ji, 0, sizeof (ji));
1914 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1915 ji.data.target = info->name;
1917 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1919 if (cfg->compile_aot) {
1920 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1921 if (!callee)
1922 LLVM_FAILURE (ctx, "can't encode patch");
1923 } else {
1924 callee = LLVMAddFunction (module, "", llvm_sig);
1925 target = (gpointer)mono_icall_get_wrapper (info);
1926 LLVMAddGlobalMapping (ee, callee, target);
1928 } else {
1929 if (cfg->compile_aot) {
1930 callee = NULL;
1931 if (cfg->abs_patches) {
1932 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1933 if (abs_ji) {
1934 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1935 if (!callee)
1936 LLVM_FAILURE (ctx, "can't encode patch");
1939 if (!callee)
1940 LLVM_FAILURE (ctx, "aot");
1941 } else {
1942 callee = LLVMAddFunction (module, "", llvm_sig);
1943 target = NULL;
1944 if (cfg->abs_patches) {
1945 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1946 if (abs_ji) {
1948 * FIXME: Some trampolines might have
1949 * their own calling convention on some platforms.
1951 #ifndef TARGET_AMD64
1952 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)
1953 LLVM_FAILURE (ctx, "trampoline with own cconv");
1954 #endif
1955 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1956 LLVMAddGlobalMapping (ee, callee, target);
1959 if (!target)
1960 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1965 if (virtual) {
1966 int size = sizeof (gpointer);
1967 LLVMValueRef index;
1969 g_assert (ins->inst_offset % size == 0);
1970 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1973 * When using the llvm mono branch, we can support IMT directly, otherwise
1974 * we need to call a trampoline.
1976 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
1977 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1978 if (cfg->compile_aot) {
1979 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
1980 imt_tramp->method = call->method;
1981 imt_tramp->vt_offset = call->inst.inst_offset;
1983 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
1984 } else {
1985 callee = LLVMAddFunction (module, "", llvm_sig);
1986 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
1987 LLVMAddGlobalMapping (ee, callee, target);
1989 #else
1990 /* No support for passing the IMT argument */
1991 LLVM_FAILURE (ctx, "imt");
1992 #endif
1993 } else {
1994 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1996 } else if (calli) {
1997 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1998 } else {
1999 if (ins->flags & MONO_INST_HAS_METHOD) {
2004 * Collect and convert arguments
2006 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
2007 args = alloca (len);
2008 memset (args, 0, len);
2009 l = call->out_ireg_args;
2011 if (IS_LLVM_MONO_BRANCH) {
2012 if (call->rgctx_arg_reg) {
2013 g_assert (values [call->rgctx_arg_reg]);
2014 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
2016 if (call->imt_arg_reg) {
2017 g_assert (values [call->imt_arg_reg]);
2018 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
2022 if (vretaddr) {
2023 if (!addresses [call->inst.dreg])
2024 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2025 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2028 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2029 guint32 regpair;
2030 int reg, pindex;
2031 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2033 if (sig->hasthis) {
2034 if (i == 0)
2035 pindex = sinfo.this_arg_pindex;
2036 else
2037 pindex = sinfo.pindexes [i - 1];
2038 } else {
2039 pindex = sinfo.pindexes [i];
2042 regpair = (guint32)(gssize)(l->data);
2043 reg = regpair & 0xffffff;
2044 args [pindex] = values [reg];
2045 if (ainfo->storage == LLVMArgVtypeInReg) {
2046 int j;
2047 LLVMValueRef regs [2];
2048 guint32 nregs;
2050 g_assert (ainfo);
2052 g_assert (addresses [reg]);
2054 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2055 for (j = 0; j < nregs; ++j)
2056 args [pindex ++] = regs [j];
2058 // FIXME: alignment
2059 // FIXME: Get rid of the VMOVE
2060 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2061 g_assert (addresses [reg]);
2062 args [pindex] = addresses [reg];
2063 } else {
2064 g_assert (args [pindex]);
2065 if (i == 0 && sig->hasthis)
2066 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2067 else
2068 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2071 l = l->next;
2074 // FIXME: Align call sites
2077 * Emit the call
2080 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2082 #ifdef LLVM_MONO_BRANCH
2084 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2086 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2087 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2088 #endif
2089 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2090 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2091 if (!sig->pinvoke)
2092 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2094 if (call->rgctx_arg_reg)
2095 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2096 if (call->imt_arg_reg)
2097 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2098 #endif
2100 /* Add byval attributes if needed */
2101 for (i = 0; i < sig->param_count; ++i) {
2102 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2104 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2105 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2110 * Convert the result
2112 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2113 LLVMValueRef regs [2];
2115 if (!addresses [ins->dreg])
2116 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2118 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2119 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2120 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2122 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2123 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2124 /* If the method returns an unsigned value, need to zext it */
2126 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));
2129 *builder_ref = ctx->builder;
2131 g_free (sinfo.pindexes);
2133 return;
2134 FAILURE:
2135 return;
2138 static void
2139 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2141 MonoCompile *cfg = ctx->cfg;
2142 MonoMethodSignature *sig = ctx->sig;
2143 LLVMValueRef method = ctx->lmethod;
2144 LLVMValueRef *values = ctx->values;
2145 LLVMValueRef *addresses = ctx->addresses;
2146 int i;
2147 LLVMCallInfo *linfo = ctx->linfo;
2148 LLVMModuleRef module = ctx->module;
2149 BBInfo *bblocks = ctx->bblocks;
2150 MonoInst *ins;
2151 LLVMBasicBlockRef cbb;
2152 LLVMBuilderRef builder;
2153 gboolean has_terminator;
2154 LLVMValueRef v;
2155 LLVMValueRef lhs, rhs;
2157 cbb = get_bb (ctx, bb);
2158 builder = create_builder (ctx);
2159 ctx->builder = builder;
2160 LLVMPositionBuilderAtEnd (builder, cbb);
2162 if (bb == cfg->bb_entry)
2163 emit_entry_bb (ctx, builder);
2164 CHECK_FAILURE (ctx);
2166 if (bb->flags & BB_EXCEPTION_HANDLER) {
2167 LLVMTypeRef i8ptr;
2168 LLVMValueRef eh_selector, eh_exception, personality, args [4];
2169 LLVMBasicBlockRef target_bb;
2170 MonoInst *exvar;
2171 static gint32 mapping_inited;
2172 static int ti_generator;
2173 char ti_name [128];
2174 MonoClass **ti;
2175 LLVMValueRef type_info;
2176 int clause_index;
2178 if (!bblocks [bb->block_num].invoke_target) {
2180 * LLVM asserts if llvm.eh.selector is called from a bblock which
2181 * doesn't have an invoke pointing at it.
2182 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2184 LLVM_FAILURE (ctx, "handler without invokes");
2187 eh_selector = LLVMGetNamedFunction (module, eh_selector_name);
2189 if (cfg->compile_aot) {
2190 /* Use a dummy personality function */
2191 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2192 g_assert (personality);
2193 } else {
2194 personality = LLVMGetNamedFunction (module, "mono_personality");
2195 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2196 LLVMAddGlobalMapping (ee, personality, mono_personality);
2199 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2201 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2204 * Create the type info
2206 sprintf (ti_name, "type_info_%d", ti_generator);
2207 ti_generator ++;
2209 if (cfg->compile_aot) {
2210 /* decode_eh_frame () in aot-runtime.c will decode this */
2211 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2212 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2214 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2215 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2218 * Enabling this causes llc to crash:
2219 * http://llvm.org/bugs/show_bug.cgi?id=6102
2221 //LLVM_FAILURE (ctx, "aot+clauses");
2222 } else {
2224 * After the cfg mempool is freed, the type info will point to stale memory,
2225 * but this is not a problem, since we decode it once in exception_cb during
2226 * compilation.
2228 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2229 *(gint32*)ti = clause_index;
2231 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2233 LLVMAddGlobalMapping (ee, type_info, ti);
2236 args [0] = LLVMConstNull (i8ptr);
2237 args [1] = LLVMConstBitCast (personality, i8ptr);
2238 args [2] = type_info;
2239 LLVMBuildCall (builder, eh_selector, args, 3, "");
2241 /* Store the exception into the exvar */
2242 if (bb->in_scount == 1) {
2243 g_assert (bb->in_scount == 1);
2244 exvar = bb->in_stack [0];
2246 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
2248 // FIXME: This is shared with filter clauses ?
2249 g_assert (!values [exvar->dreg]);
2250 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
2251 emit_volatile_store (ctx, exvar->dreg);
2254 /* Start a new bblock which CALL_HANDLER can branch to */
2255 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2256 if (target_bb) {
2257 LLVMBuildBr (builder, target_bb);
2259 ctx->builder = builder = create_builder (ctx);
2260 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2262 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2266 has_terminator = FALSE;
2267 for (ins = bb->code; ins; ins = ins->next) {
2268 const char *spec = LLVM_INS_INFO (ins->opcode);
2269 char *dname = NULL;
2270 char dname_buf [128];
2272 if (has_terminator)
2273 /* There could be instructions after a terminator, skip them */
2274 break;
2276 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2277 sprintf (dname_buf, "t%d", ins->dreg);
2278 dname = dname_buf;
2281 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2282 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2284 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2285 lhs = emit_volatile_load (ctx, ins->sreg1);
2286 } else {
2287 /* It is ok for SETRET to have an uninitialized argument */
2288 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2289 LLVM_FAILURE (ctx, "sreg1");
2290 lhs = values [ins->sreg1];
2292 } else {
2293 lhs = NULL;
2296 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2297 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2298 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2299 rhs = emit_volatile_load (ctx, ins->sreg2);
2300 } else {
2301 if (!values [ins->sreg2])
2302 LLVM_FAILURE (ctx, "sreg2");
2303 rhs = values [ins->sreg2];
2305 } else {
2306 rhs = NULL;
2309 //mono_print_ins (ins);
2310 switch (ins->opcode) {
2311 case OP_NOP:
2312 case OP_NOT_NULL:
2313 case OP_LIVERANGE_START:
2314 case OP_LIVERANGE_END:
2315 break;
2316 case OP_ICONST:
2317 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2318 break;
2319 case OP_I8CONST:
2320 #if SIZEOF_VOID_P == 4
2321 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2322 #else
2323 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2324 #endif
2325 break;
2326 case OP_R8CONST:
2327 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2328 break;
2329 case OP_R4CONST:
2330 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2331 break;
2332 case OP_BR:
2333 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2334 has_terminator = TRUE;
2335 break;
2336 case OP_SWITCH: {
2337 int i;
2338 LLVMValueRef v;
2339 char bb_name [128];
2340 LLVMBasicBlockRef new_bb;
2341 LLVMBuilderRef new_builder;
2343 // The default branch is already handled
2344 // FIXME: Handle it here
2346 /* Start new bblock */
2347 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2348 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2350 lhs = convert (ctx, lhs, LLVMInt32Type ());
2351 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2352 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2353 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2355 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2358 new_builder = create_builder (ctx);
2359 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2360 LLVMBuildUnreachable (new_builder);
2362 has_terminator = TRUE;
2363 g_assert (!ins->next);
2365 break;
2368 case OP_SETRET:
2369 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2370 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2371 LLVMValueRef part1, retval;
2372 int size;
2374 size = get_vtype_size (sig->ret);
2376 g_assert (addresses [ins->sreg1]);
2378 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2379 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2381 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2383 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2385 LLVMBuildRet (builder, retval);
2386 break;
2389 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2390 LLVMBuildRetVoid (builder);
2391 break;
2394 if (!lhs || ctx->is_dead [ins->sreg1]) {
2396 * The method did not set its return value, probably because it
2397 * ends with a throw.
2399 if (cfg->vret_addr)
2400 LLVMBuildRetVoid (builder);
2401 else
2402 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2403 } else {
2404 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2406 has_terminator = TRUE;
2407 break;
2408 case OP_ICOMPARE:
2409 case OP_FCOMPARE:
2410 case OP_LCOMPARE:
2411 case OP_COMPARE:
2412 case OP_ICOMPARE_IMM:
2413 case OP_LCOMPARE_IMM:
2414 case OP_COMPARE_IMM: {
2415 CompRelation rel;
2416 LLVMValueRef cmp;
2418 if (ins->next->opcode == OP_NOP)
2419 break;
2421 if (ins->next->opcode == OP_BR)
2422 /* The comparison result is not needed */
2423 continue;
2425 rel = mono_opcode_to_cond (ins->next->opcode);
2427 if (ins->opcode == OP_ICOMPARE_IMM) {
2428 lhs = convert (ctx, lhs, LLVMInt32Type ());
2429 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2431 if (ins->opcode == OP_LCOMPARE_IMM) {
2432 lhs = convert (ctx, lhs, LLVMInt64Type ());
2433 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2435 if (ins->opcode == OP_LCOMPARE) {
2436 lhs = convert (ctx, lhs, LLVMInt64Type ());
2437 rhs = convert (ctx, rhs, LLVMInt64Type ());
2439 if (ins->opcode == OP_ICOMPARE) {
2440 lhs = convert (ctx, lhs, LLVMInt32Type ());
2441 rhs = convert (ctx, rhs, LLVMInt32Type ());
2444 if (lhs && rhs) {
2445 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2446 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2447 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2448 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2451 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2452 if (ins->opcode == OP_FCOMPARE)
2453 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2454 else if (ins->opcode == OP_COMPARE_IMM)
2455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2456 else if (ins->opcode == OP_LCOMPARE_IMM) {
2457 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2458 /* The immediate is encoded in two fields */
2459 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2460 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2461 } else {
2462 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2465 else if (ins->opcode == OP_COMPARE)
2466 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2467 else
2468 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2470 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2471 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2473 * If the target bb contains PHI instructions, LLVM requires
2474 * two PHI entries for this bblock, while we only generate one.
2475 * So convert this to an unconditional bblock. (bxc #171).
2477 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2478 } else {
2479 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2481 has_terminator = TRUE;
2482 } else if (MONO_IS_SETCC (ins->next)) {
2483 sprintf (dname_buf, "t%d", ins->next->dreg);
2484 dname = dname_buf;
2485 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2487 /* Add stores for volatile variables */
2488 emit_volatile_store (ctx, ins->next->dreg);
2489 } else if (MONO_IS_COND_EXC (ins->next)) {
2490 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2491 CHECK_FAILURE (ctx);
2492 builder = ctx->builder;
2493 } else {
2494 LLVM_FAILURE (ctx, "next");
2497 ins = ins->next;
2498 break;
2500 case OP_FCEQ:
2501 case OP_FCLT:
2502 case OP_FCLT_UN:
2503 case OP_FCGT:
2504 case OP_FCGT_UN: {
2505 CompRelation rel;
2506 LLVMValueRef cmp;
2508 rel = mono_opcode_to_cond (ins->opcode);
2510 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2511 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2512 break;
2514 case OP_PHI:
2515 case OP_FPHI:
2516 case OP_VPHI:
2517 case OP_XPHI: {
2518 int i;
2519 gboolean empty = TRUE;
2521 /* Check that all input bblocks really branch to us */
2522 for (i = 0; i < bb->in_count; ++i) {
2523 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2524 ins->inst_phi_args [i + 1] = -1;
2525 else
2526 empty = FALSE;
2529 if (empty) {
2530 /* LLVM doesn't like phi instructions with zero operands */
2531 ctx->is_dead [ins->dreg] = TRUE;
2532 break;
2535 /* Created earlier, insert it now */
2536 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2538 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2539 int sreg1 = ins->inst_phi_args [i + 1];
2540 int count, j;
2543 * Count the number of times the incoming bblock branches to us,
2544 * since llvm requires a separate entry for each.
2546 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2547 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2549 count = 0;
2550 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2551 if (switch_ins->inst_many_bb [j] == bb)
2552 count ++;
2554 } else {
2555 count = 1;
2558 /* Remember for later */
2559 for (j = 0; j < count; ++j) {
2560 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2561 node->bb = bb;
2562 node->phi = ins;
2563 node->in_bb = bb->in_bb [i];
2564 node->sreg = sreg1;
2565 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);
2568 break;
2570 case OP_MOVE:
2571 case OP_LMOVE:
2572 case OP_XMOVE:
2573 case OP_SETFRET:
2574 g_assert (lhs);
2575 values [ins->dreg] = lhs;
2576 break;
2577 case OP_FMOVE: {
2578 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2580 g_assert (lhs);
2581 values [ins->dreg] = lhs;
2583 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2585 * This is added by the spilling pass in case of the JIT,
2586 * but we have to do it ourselves.
2588 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2590 break;
2592 case OP_IADD:
2593 case OP_ISUB:
2594 case OP_IAND:
2595 case OP_IMUL:
2596 case OP_IDIV:
2597 case OP_IDIV_UN:
2598 case OP_IREM:
2599 case OP_IREM_UN:
2600 case OP_IOR:
2601 case OP_IXOR:
2602 case OP_ISHL:
2603 case OP_ISHR:
2604 case OP_ISHR_UN:
2605 case OP_FADD:
2606 case OP_FSUB:
2607 case OP_FMUL:
2608 case OP_FDIV:
2609 case OP_LADD:
2610 case OP_LSUB:
2611 case OP_LMUL:
2612 case OP_LDIV:
2613 case OP_LDIV_UN:
2614 case OP_LREM:
2615 case OP_LREM_UN:
2616 case OP_LAND:
2617 case OP_LOR:
2618 case OP_LXOR:
2619 case OP_LSHL:
2620 case OP_LSHR:
2621 case OP_LSHR_UN:
2622 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2623 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2625 switch (ins->opcode) {
2626 case OP_IADD:
2627 case OP_LADD:
2628 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2629 break;
2630 case OP_ISUB:
2631 case OP_LSUB:
2632 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2633 break;
2634 case OP_IMUL:
2635 case OP_LMUL:
2636 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2637 break;
2638 case OP_IREM:
2639 case OP_LREM:
2640 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2641 break;
2642 case OP_IREM_UN:
2643 case OP_LREM_UN:
2644 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2645 break;
2646 case OP_IDIV:
2647 case OP_LDIV:
2648 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2649 break;
2650 case OP_IDIV_UN:
2651 case OP_LDIV_UN:
2652 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2653 break;
2654 case OP_FDIV:
2655 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2656 break;
2657 case OP_IAND:
2658 case OP_LAND:
2659 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2660 break;
2661 case OP_IOR:
2662 case OP_LOR:
2663 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2664 break;
2665 case OP_IXOR:
2666 case OP_LXOR:
2667 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2668 break;
2669 case OP_ISHL:
2670 case OP_LSHL:
2671 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2672 break;
2673 case OP_ISHR:
2674 case OP_LSHR:
2675 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2676 break;
2677 case OP_ISHR_UN:
2678 case OP_LSHR_UN:
2679 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2680 break;
2682 case OP_FADD:
2683 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2684 break;
2685 case OP_FSUB:
2686 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2687 break;
2688 case OP_FMUL:
2689 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2690 break;
2692 default:
2693 g_assert_not_reached ();
2695 break;
2696 case OP_IADD_IMM:
2697 case OP_ISUB_IMM:
2698 case OP_IMUL_IMM:
2699 case OP_IREM_IMM:
2700 case OP_IREM_UN_IMM:
2701 case OP_IDIV_IMM:
2702 case OP_IDIV_UN_IMM:
2703 case OP_IAND_IMM:
2704 case OP_IOR_IMM:
2705 case OP_IXOR_IMM:
2706 case OP_ISHL_IMM:
2707 case OP_ISHR_IMM:
2708 case OP_ISHR_UN_IMM:
2709 case OP_LADD_IMM:
2710 case OP_LSUB_IMM:
2711 case OP_LREM_IMM:
2712 case OP_LAND_IMM:
2713 case OP_LOR_IMM:
2714 case OP_LXOR_IMM:
2715 case OP_LSHL_IMM:
2716 case OP_LSHR_IMM:
2717 case OP_LSHR_UN_IMM:
2718 case OP_ADD_IMM:
2719 case OP_AND_IMM:
2720 case OP_MUL_IMM:
2721 case OP_SHL_IMM:
2722 case OP_SHR_IMM: {
2723 LLVMValueRef imm;
2725 if (spec [MONO_INST_SRC1] == 'l') {
2726 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2727 } else {
2728 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2731 #if SIZEOF_VOID_P == 4
2732 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2733 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2734 #endif
2736 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2737 lhs = convert (ctx, lhs, IntPtrType ());
2738 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2739 switch (ins->opcode) {
2740 case OP_IADD_IMM:
2741 case OP_LADD_IMM:
2742 case OP_ADD_IMM:
2743 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2744 break;
2745 case OP_ISUB_IMM:
2746 case OP_LSUB_IMM:
2747 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2748 break;
2749 case OP_IMUL_IMM:
2750 case OP_MUL_IMM:
2751 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2752 break;
2753 case OP_IDIV_IMM:
2754 case OP_LDIV_IMM:
2755 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2756 break;
2757 case OP_IDIV_UN_IMM:
2758 case OP_LDIV_UN_IMM:
2759 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2760 break;
2761 case OP_IREM_IMM:
2762 case OP_LREM_IMM:
2763 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2764 break;
2765 case OP_IREM_UN_IMM:
2766 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2767 break;
2768 case OP_IAND_IMM:
2769 case OP_LAND_IMM:
2770 case OP_AND_IMM:
2771 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2772 break;
2773 case OP_IOR_IMM:
2774 case OP_LOR_IMM:
2775 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2776 break;
2777 case OP_IXOR_IMM:
2778 case OP_LXOR_IMM:
2779 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2780 break;
2781 case OP_ISHL_IMM:
2782 case OP_LSHL_IMM:
2783 case OP_SHL_IMM:
2784 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2785 break;
2786 case OP_ISHR_IMM:
2787 case OP_LSHR_IMM:
2788 case OP_SHR_IMM:
2789 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2790 break;
2791 case OP_ISHR_UN_IMM:
2792 /* This is used to implement conv.u4, so the lhs could be an i8 */
2793 lhs = convert (ctx, lhs, LLVMInt32Type ());
2794 imm = convert (ctx, imm, LLVMInt32Type ());
2795 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2796 break;
2797 case OP_LSHR_UN_IMM:
2798 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2799 break;
2800 default:
2801 g_assert_not_reached ();
2803 break;
2805 case OP_INEG:
2806 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2807 break;
2808 case OP_LNEG:
2809 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2810 break;
2811 case OP_FNEG:
2812 lhs = convert (ctx, lhs, LLVMDoubleType ());
2813 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2814 break;
2815 case OP_INOT: {
2816 guint32 v = 0xffffffff;
2817 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2818 break;
2820 case OP_LNOT: {
2821 guint64 v = 0xffffffffffffffffLL;
2822 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2823 break;
2825 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2826 case OP_X86_LEA: {
2827 LLVMValueRef v1, v2;
2829 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2830 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2831 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2832 break;
2834 #endif
2836 case OP_ICONV_TO_I1:
2837 case OP_ICONV_TO_I2:
2838 case OP_ICONV_TO_I4:
2839 case OP_ICONV_TO_U1:
2840 case OP_ICONV_TO_U2:
2841 case OP_ICONV_TO_U4:
2842 case OP_LCONV_TO_I1:
2843 case OP_LCONV_TO_I2:
2844 case OP_LCONV_TO_U1:
2845 case OP_LCONV_TO_U2:
2846 case OP_LCONV_TO_U4: {
2847 gboolean sign;
2849 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);
2851 /* Have to do two casts since our vregs have type int */
2852 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2853 if (sign)
2854 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2855 else
2856 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2857 break;
2859 case OP_ICONV_TO_I8:
2860 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2861 break;
2862 case OP_ICONV_TO_U8:
2863 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2864 break;
2865 case OP_FCONV_TO_I4:
2866 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2867 break;
2868 case OP_FCONV_TO_I1:
2869 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2870 break;
2871 case OP_FCONV_TO_U1:
2872 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2873 break;
2874 case OP_FCONV_TO_I2:
2875 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2876 break;
2877 case OP_FCONV_TO_U2:
2878 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2879 break;
2880 case OP_FCONV_TO_I8:
2881 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2882 break;
2883 case OP_FCONV_TO_I:
2884 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2885 break;
2886 case OP_ICONV_TO_R8:
2887 case OP_LCONV_TO_R8:
2888 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2889 break;
2890 case OP_LCONV_TO_R_UN:
2891 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2892 break;
2893 #if SIZEOF_VOID_P == 4
2894 case OP_LCONV_TO_U:
2895 #endif
2896 case OP_LCONV_TO_I4:
2897 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2898 break;
2899 case OP_ICONV_TO_R4:
2900 case OP_LCONV_TO_R4:
2901 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2902 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2903 break;
2904 case OP_FCONV_TO_R4:
2905 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2906 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2907 break;
2908 case OP_SEXT_I4:
2909 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2910 break;
2911 case OP_ZEXT_I4:
2912 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2913 break;
2914 case OP_TRUNC_I4:
2915 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2916 break;
2917 case OP_LOCALLOC_IMM: {
2918 LLVMValueRef v;
2920 guint32 size = ins->inst_imm;
2921 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2923 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2925 if (ins->flags & MONO_INST_INIT) {
2926 LLVMValueRef args [5];
2928 args [0] = v;
2929 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2930 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2931 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2932 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2933 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2936 values [ins->dreg] = v;
2937 break;
2939 case OP_LOCALLOC: {
2940 LLVMValueRef v, size;
2942 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), "");
2944 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2946 if (ins->flags & MONO_INST_INIT) {
2947 LLVMValueRef args [5];
2949 args [0] = v;
2950 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2951 args [2] = size;
2952 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2953 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2954 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2956 values [ins->dreg] = v;
2957 break;
2960 case OP_LOADI1_MEMBASE:
2961 case OP_LOADU1_MEMBASE:
2962 case OP_LOADI2_MEMBASE:
2963 case OP_LOADU2_MEMBASE:
2964 case OP_LOADI4_MEMBASE:
2965 case OP_LOADU4_MEMBASE:
2966 case OP_LOADI8_MEMBASE:
2967 case OP_LOADR4_MEMBASE:
2968 case OP_LOADR8_MEMBASE:
2969 case OP_LOAD_MEMBASE:
2970 case OP_LOADI8_MEM:
2971 case OP_LOADU1_MEM:
2972 case OP_LOADU2_MEM:
2973 case OP_LOADI4_MEM:
2974 case OP_LOADU4_MEM:
2975 case OP_LOAD_MEM: {
2976 int size = 8;
2977 LLVMValueRef base, index, addr;
2978 LLVMTypeRef t;
2979 gboolean sext = FALSE, zext = FALSE;
2980 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2982 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2984 if (sext || zext)
2985 dname = (char*)"";
2987 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)) {
2988 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2989 } else {
2990 /* _MEMBASE */
2991 base = lhs;
2993 if (ins->inst_offset == 0) {
2994 addr = base;
2995 } else if (ins->inst_offset % size != 0) {
2996 /* Unaligned load */
2997 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2998 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2999 } else {
3000 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3001 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3005 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3007 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3009 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
3011 * These will signal LLVM that these loads do not alias any stores, and
3012 * they can't fail, allowing them to be hoisted out of loops.
3014 set_metadata_flag (values [ins->dreg], "mono.noalias");
3015 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3018 if (sext)
3019 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3020 else if (zext)
3021 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3022 else if (ins->opcode == OP_LOADR4_MEMBASE)
3023 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3024 break;
3027 case OP_STOREI1_MEMBASE_REG:
3028 case OP_STOREI2_MEMBASE_REG:
3029 case OP_STOREI4_MEMBASE_REG:
3030 case OP_STOREI8_MEMBASE_REG:
3031 case OP_STORER4_MEMBASE_REG:
3032 case OP_STORER8_MEMBASE_REG:
3033 case OP_STORE_MEMBASE_REG: {
3034 int size = 8;
3035 LLVMValueRef index, addr;
3036 LLVMTypeRef t;
3037 gboolean sext = FALSE, zext = FALSE;
3038 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3040 if (!values [ins->inst_destbasereg])
3041 LLVM_FAILURE (ctx, "inst_destbasereg");
3043 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3045 if (ins->inst_offset % size != 0) {
3046 /* Unaligned store */
3047 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3048 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3049 } else {
3050 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3051 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3053 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3054 break;
3057 case OP_STOREI1_MEMBASE_IMM:
3058 case OP_STOREI2_MEMBASE_IMM:
3059 case OP_STOREI4_MEMBASE_IMM:
3060 case OP_STOREI8_MEMBASE_IMM:
3061 case OP_STORE_MEMBASE_IMM: {
3062 int size = 8;
3063 LLVMValueRef index, addr;
3064 LLVMTypeRef t;
3065 gboolean sext = FALSE, zext = FALSE;
3066 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3068 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3070 if (ins->inst_offset % size != 0) {
3071 /* Unaligned store */
3072 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3073 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3074 } else {
3075 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3076 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3078 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3079 break;
3082 case OP_CHECK_THIS:
3083 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3084 break;
3085 case OP_OUTARG_VTRETADDR:
3086 break;
3087 case OP_VOIDCALL:
3088 case OP_CALL:
3089 case OP_LCALL:
3090 case OP_FCALL:
3091 case OP_VCALL:
3092 case OP_VOIDCALL_MEMBASE:
3093 case OP_CALL_MEMBASE:
3094 case OP_LCALL_MEMBASE:
3095 case OP_FCALL_MEMBASE:
3096 case OP_VCALL_MEMBASE:
3097 case OP_VOIDCALL_REG:
3098 case OP_CALL_REG:
3099 case OP_LCALL_REG:
3100 case OP_FCALL_REG:
3101 case OP_VCALL_REG: {
3102 process_call (ctx, bb, &builder, ins);
3103 CHECK_FAILURE (ctx);
3104 break;
3106 case OP_AOTCONST: {
3107 guint32 got_offset;
3108 LLVMValueRef indexes [2];
3109 MonoJumpInfo *ji;
3110 LLVMValueRef got_entry_addr;
3113 * FIXME: Can't allocate from the cfg mempool since that is freed if
3114 * the LLVM compile fails.
3116 ji = g_new0 (MonoJumpInfo, 1);
3117 ji->type = (MonoJumpInfoType)ins->inst_i1;
3118 ji->data.target = ins->inst_p0;
3120 ji = mono_aot_patch_info_dup (ji);
3122 ji->next = cfg->patch_info;
3123 cfg->patch_info = ji;
3125 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3126 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3128 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3129 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3130 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3132 // FIXME: This doesn't work right now, because it must be
3133 // paired with an invariant.end, and even then, its only in effect
3134 // inside its basic block
3135 #if 0
3137 LLVMValueRef args [3];
3138 LLVMValueRef ptr, val;
3140 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3142 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3143 args [1] = ptr;
3144 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3146 #endif
3148 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3149 break;
3151 case OP_NOT_REACHED:
3152 LLVMBuildUnreachable (builder);
3153 has_terminator = TRUE;
3154 g_assert (bb->block_num < cfg->max_block_num);
3155 ctx->unreachable [bb->block_num] = TRUE;
3156 /* Might have instructions after this */
3157 while (ins->next) {
3158 MonoInst *next = ins->next;
3160 * FIXME: If later code uses the regs defined by these instructions,
3161 * compilation will fail.
3163 MONO_DELETE_INS (bb, next);
3165 break;
3166 case OP_LDADDR: {
3167 MonoInst *var = ins->inst_p0;
3169 values [ins->dreg] = addresses [var->dreg];
3170 break;
3172 case OP_SIN: {
3173 LLVMValueRef args [1];
3175 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3176 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3177 break;
3179 case OP_COS: {
3180 LLVMValueRef args [1];
3182 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3183 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3184 break;
3186 case OP_SQRT: {
3187 LLVMValueRef args [1];
3189 #if 0
3190 /* This no longer seems to happen */
3192 * LLVM optimizes sqrt(nan) into undefined in
3193 * lib/Analysis/ConstantFolding.cpp
3194 * Also, sqrt(NegativeInfinity) is optimized into 0.
3196 LLVM_FAILURE (ctx, "sqrt");
3197 #endif
3198 args [0] = lhs;
3199 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3200 break;
3202 case OP_ABS: {
3203 LLVMValueRef args [1];
3205 args [0] = lhs;
3206 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3207 break;
3210 case OP_IMIN:
3211 case OP_LMIN:
3212 case OP_IMAX:
3213 case OP_LMAX:
3214 case OP_IMIN_UN:
3215 case OP_LMIN_UN:
3216 case OP_IMAX_UN:
3217 case OP_LMAX_UN: {
3218 LLVMValueRef v;
3220 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3221 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3223 switch (ins->opcode) {
3224 case OP_IMIN:
3225 case OP_LMIN:
3226 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3227 break;
3228 case OP_IMAX:
3229 case OP_LMAX:
3230 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3231 break;
3232 case OP_IMIN_UN:
3233 case OP_LMIN_UN:
3234 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3235 break;
3236 case OP_IMAX_UN:
3237 case OP_LMAX_UN:
3238 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3239 break;
3240 default:
3241 g_assert_not_reached ();
3242 break;
3244 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3245 break;
3247 case OP_ATOMIC_EXCHANGE_I4: {
3248 LLVMValueRef args [2];
3250 g_assert (ins->inst_offset == 0);
3252 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3253 args [1] = rhs;
3254 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
3255 break;
3257 case OP_ATOMIC_EXCHANGE_I8: {
3258 LLVMValueRef args [2];
3260 g_assert (ins->inst_offset == 0);
3262 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3263 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3264 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
3265 break;
3267 case OP_ATOMIC_ADD_NEW_I4: {
3268 LLVMValueRef args [2];
3270 g_assert (ins->inst_offset == 0);
3272 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3273 args [1] = rhs;
3274 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
3275 break;
3277 case OP_ATOMIC_ADD_NEW_I8: {
3278 LLVMValueRef args [2];
3280 g_assert (ins->inst_offset == 0);
3282 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3283 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3284 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
3285 break;
3287 case OP_ATOMIC_CAS_I4:
3288 case OP_ATOMIC_CAS_I8: {
3289 LLVMValueRef args [3];
3290 LLVMTypeRef t;
3291 const char *intrins;
3293 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3294 t = LLVMInt32Type ();
3295 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
3296 } else {
3297 t = LLVMInt64Type ();
3298 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
3301 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3302 /* comparand */
3303 args [1] = convert (ctx, values [ins->sreg3], t);
3304 /* new value */
3305 args [2] = convert (ctx, values [ins->sreg2], t);
3306 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
3307 break;
3309 case OP_MEMORY_BARRIER: {
3310 LLVMValueRef args [5];
3312 #ifdef TARGET_ARM
3313 /* Not yet supported by llc on arm */
3314 LLVM_FAILURE (ctx, "memory-barrier+arm");
3315 #endif
3317 for (i = 0; i < 5; ++i)
3318 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
3320 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
3321 break;
3323 case OP_RELAXED_NOP: {
3324 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3325 if (IS_LLVM_MONO_BRANCH)
3326 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3327 else
3328 /* No way to get LLVM to emit this */
3329 LLVM_FAILURE (ctx, "relaxed_nop");
3330 break;
3331 #else
3332 break;
3333 #endif
3335 case OP_TLS_GET: {
3336 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3337 #ifdef TARGET_AMD64
3338 // 257 == FS segment register
3339 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3340 #else
3341 // 256 == GS segment register
3342 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3343 #endif
3345 // FIXME: XEN
3346 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3347 #else
3348 LLVM_FAILURE (ctx, "opcode tls-get");
3349 #endif
3351 break;
3355 * Overflow opcodes.
3357 case OP_IADD_OVF:
3358 case OP_IADD_OVF_UN:
3359 case OP_ISUB_OVF:
3360 case OP_ISUB_OVF_UN:
3361 case OP_IMUL_OVF:
3362 case OP_IMUL_OVF_UN:
3363 #if SIZEOF_VOID_P == 8
3364 case OP_LADD_OVF:
3365 case OP_LADD_OVF_UN:
3366 case OP_LSUB_OVF:
3367 case OP_LSUB_OVF_UN:
3368 case OP_LMUL_OVF:
3369 case OP_LMUL_OVF_UN:
3370 #endif
3372 LLVMValueRef args [2], val, ovf, func;
3374 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3375 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3376 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3377 g_assert (func);
3378 val = LLVMBuildCall (builder, func, args, 2, "");
3379 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3380 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3381 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3382 CHECK_FAILURE (ctx);
3383 builder = ctx->builder;
3384 break;
3388 * Valuetypes.
3389 * We currently model them using arrays. Promotion to local vregs is
3390 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3391 * so we always have an entry in cfg->varinfo for them.
3392 * FIXME: Is this needed ?
3394 case OP_VZERO: {
3395 MonoClass *klass = ins->klass;
3396 LLVMValueRef args [5];
3398 if (!klass) {
3399 // FIXME:
3400 LLVM_FAILURE (ctx, "!klass");
3401 break;
3404 if (!addresses [ins->dreg])
3405 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3406 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3407 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3408 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3409 // FIXME: Alignment
3410 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3411 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3412 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3413 break;
3416 case OP_STOREV_MEMBASE:
3417 case OP_LOADV_MEMBASE:
3418 case OP_VMOVE: {
3419 MonoClass *klass = ins->klass;
3420 LLVMValueRef src, dst, args [5];
3421 gboolean done = FALSE;
3423 if (!klass) {
3424 // FIXME:
3425 LLVM_FAILURE (ctx, "!klass");
3426 break;
3429 switch (ins->opcode) {
3430 case OP_STOREV_MEMBASE:
3431 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3432 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3433 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3434 break;
3436 if (!addresses [ins->sreg1]) {
3437 /* SIMD */
3438 g_assert (values [ins->sreg1]);
3439 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));
3440 LLVMBuildStore (builder, values [ins->sreg1], dst);
3441 done = TRUE;
3442 } else {
3443 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3444 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3446 break;
3447 case OP_LOADV_MEMBASE:
3448 if (!addresses [ins->dreg])
3449 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3450 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3451 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3452 break;
3453 case OP_VMOVE:
3454 if (!addresses [ins->sreg1])
3455 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3456 if (!addresses [ins->dreg])
3457 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3458 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3459 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3460 break;
3461 default:
3462 g_assert_not_reached ();
3464 CHECK_FAILURE (ctx);
3466 if (done)
3467 break;
3469 args [0] = dst;
3470 args [1] = src;
3471 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3472 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3473 // FIXME: Alignment
3474 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3475 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3476 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3477 break;
3479 case OP_LLVM_OUTARG_VT:
3480 if (!addresses [ins->sreg1]) {
3481 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3482 g_assert (values [ins->sreg1]);
3483 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3485 addresses [ins->dreg] = addresses [ins->sreg1];
3486 break;
3489 * SIMD
3491 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3492 case OP_XZERO: {
3493 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3494 break;
3496 case OP_LOADX_MEMBASE: {
3497 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3498 LLVMValueRef src;
3500 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3501 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3502 break;
3504 case OP_STOREX_MEMBASE: {
3505 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3506 LLVMValueRef dest;
3508 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3509 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3510 break;
3512 case OP_PADDB:
3513 case OP_PADDW:
3514 case OP_PADDD:
3515 case OP_PADDQ:
3516 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3517 break;
3518 case OP_ADDPD:
3519 case OP_ADDPS:
3520 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3521 break;
3522 case OP_PSUBB:
3523 case OP_PSUBW:
3524 case OP_PSUBD:
3525 case OP_PSUBQ:
3526 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3527 break;
3528 case OP_SUBPD:
3529 case OP_SUBPS:
3530 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3531 break;
3532 case OP_MULPD:
3533 case OP_MULPS:
3534 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3535 break;
3536 case OP_DIVPD:
3537 case OP_DIVPS:
3538 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3539 break;
3540 case OP_PAND:
3541 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3542 break;
3543 case OP_POR:
3544 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3545 break;
3546 case OP_PXOR:
3547 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3548 break;
3549 case OP_PMULW:
3550 case OP_PMULD:
3551 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3552 break;
3553 case OP_ANDPS:
3554 case OP_ANDNPS:
3555 case OP_ORPS:
3556 case OP_XORPS:
3557 case OP_ANDPD:
3558 case OP_ANDNPD:
3559 case OP_ORPD:
3560 case OP_XORPD: {
3561 LLVMTypeRef t, rt;
3562 LLVMValueRef v;
3564 switch (ins->opcode) {
3565 case OP_ANDPS:
3566 case OP_ANDNPS:
3567 case OP_ORPS:
3568 case OP_XORPS:
3569 t = LLVMVectorType (LLVMInt32Type (), 4);
3570 rt = LLVMVectorType (LLVMFloatType (), 4);
3571 break;
3572 case OP_ANDPD:
3573 case OP_ANDNPD:
3574 case OP_ORPD:
3575 case OP_XORPD:
3576 t = LLVMVectorType (LLVMInt64Type (), 2);
3577 rt = LLVMVectorType (LLVMDoubleType (), 2);
3578 break;
3579 default:
3580 t = LLVMInt32Type ();
3581 rt = LLVMInt32Type ();
3582 g_assert_not_reached ();
3585 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3586 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3587 switch (ins->opcode) {
3588 case OP_ANDPS:
3589 case OP_ANDPD:
3590 v = LLVMBuildAnd (builder, lhs, rhs, "");
3591 break;
3592 case OP_ORPS:
3593 case OP_ORPD:
3594 v = LLVMBuildOr (builder, lhs, rhs, "");
3595 break;
3596 case OP_XORPS:
3597 case OP_XORPD:
3598 v = LLVMBuildXor (builder, lhs, rhs, "");
3599 break;
3600 case OP_ANDNPS:
3601 case OP_ANDNPD:
3602 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3603 break;
3605 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3606 break;
3608 case OP_MINPD:
3609 case OP_MINPS:
3610 case OP_MAXPD:
3611 case OP_MAXPS:
3612 case OP_ADDSUBPD:
3613 case OP_ADDSUBPS:
3614 case OP_PMIND_UN:
3615 case OP_PMINW_UN:
3616 case OP_PMINB_UN:
3617 case OP_PMINW:
3618 case OP_PMAXD_UN:
3619 case OP_PMAXW_UN:
3620 case OP_PMAXB_UN:
3621 case OP_HADDPD:
3622 case OP_HADDPS:
3623 case OP_HSUBPD:
3624 case OP_HSUBPS:
3625 case OP_PADDB_SAT:
3626 case OP_PADDW_SAT:
3627 case OP_PSUBB_SAT:
3628 case OP_PSUBW_SAT:
3629 case OP_PADDB_SAT_UN:
3630 case OP_PADDW_SAT_UN:
3631 case OP_PSUBB_SAT_UN:
3632 case OP_PSUBW_SAT_UN:
3633 case OP_PAVGB_UN:
3634 case OP_PAVGW_UN:
3635 case OP_PCMPEQB:
3636 case OP_PCMPEQW:
3637 case OP_PCMPEQD:
3638 case OP_PCMPEQQ:
3639 case OP_PCMPGTB:
3640 case OP_PACKW:
3641 case OP_PACKD:
3642 case OP_PACKW_UN:
3643 case OP_PACKD_UN:
3644 case OP_PMULW_HIGH:
3645 case OP_PMULW_HIGH_UN: {
3646 LLVMValueRef args [2];
3648 args [0] = lhs;
3649 args [1] = rhs;
3651 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3652 break;
3654 case OP_EXTRACT_R8:
3655 case OP_EXTRACT_I8:
3656 case OP_EXTRACT_I4:
3657 case OP_EXTRACT_I2:
3658 case OP_EXTRACT_U2:
3659 case OP_EXTRACTX_U2:
3660 case OP_EXTRACT_I1:
3661 case OP_EXTRACT_U1: {
3662 LLVMTypeRef t;
3663 gboolean zext = FALSE;
3665 t = simd_op_to_llvm_type (ins->opcode);
3667 switch (ins->opcode) {
3668 case OP_EXTRACT_R8:
3669 case OP_EXTRACT_I8:
3670 case OP_EXTRACT_I4:
3671 case OP_EXTRACT_I2:
3672 case OP_EXTRACT_I1:
3673 break;
3674 case OP_EXTRACT_U2:
3675 case OP_EXTRACTX_U2:
3676 case OP_EXTRACT_U1:
3677 zext = TRUE;
3678 break;
3679 default:
3680 t = LLVMInt32Type ();
3681 g_assert_not_reached ();
3684 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3685 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3686 if (zext)
3687 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3688 break;
3691 case OP_EXPAND_I1:
3692 case OP_EXPAND_I2:
3693 case OP_EXPAND_I4:
3694 case OP_EXPAND_I8:
3695 case OP_EXPAND_R4:
3696 case OP_EXPAND_R8: {
3697 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3698 LLVMValueRef mask [16], v;
3700 for (i = 0; i < 16; ++i)
3701 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3703 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3705 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3706 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3707 break;
3710 case OP_INSERT_I1:
3711 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3712 break;
3713 case OP_INSERT_I2:
3714 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3715 break;
3716 case OP_INSERT_I4:
3717 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3718 break;
3719 case OP_INSERT_I8:
3720 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3721 break;
3722 case OP_INSERT_R4:
3723 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3724 break;
3725 case OP_INSERT_R8:
3726 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3727 break;
3729 case OP_CVTDQ2PD:
3730 case OP_CVTDQ2PS:
3731 case OP_CVTPD2DQ:
3732 case OP_CVTPS2DQ:
3733 case OP_CVTPD2PS:
3734 case OP_CVTPS2PD:
3735 case OP_CVTTPD2DQ:
3736 case OP_CVTTPS2DQ:
3737 case OP_EXTRACT_MASK:
3738 case OP_SQRTPS:
3739 case OP_SQRTPD:
3740 case OP_RSQRTPS:
3741 case OP_RCPPS: {
3742 LLVMValueRef v;
3744 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3746 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3747 break;
3750 case OP_ICONV_TO_R8_RAW:
3751 /* Same as OP_ICONV_TO_R8 */
3752 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3753 break;
3755 case OP_COMPPS:
3756 case OP_COMPPD: {
3757 LLVMValueRef args [3];
3759 args [0] = lhs;
3760 args [1] = rhs;
3761 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3763 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3764 break;
3767 case OP_ICONV_TO_X:
3768 /* This is only used for implementing shifts by non-immediate */
3769 values [ins->dreg] = lhs;
3770 break;
3772 case OP_PSHRW:
3773 case OP_PSHRD:
3774 case OP_PSHRQ:
3775 case OP_PSARW:
3776 case OP_PSARD:
3777 case OP_PSHLW:
3778 case OP_PSHLD:
3779 case OP_PSHLQ: {
3780 LLVMValueRef args [3];
3782 args [0] = lhs;
3783 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3785 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3786 break;
3789 case OP_PSHRW_REG:
3790 case OP_PSHRD_REG:
3791 case OP_PSHRQ_REG:
3792 case OP_PSARW_REG:
3793 case OP_PSARD_REG:
3794 case OP_PSHLW_REG:
3795 case OP_PSHLD_REG:
3796 case OP_PSHLQ_REG: {
3797 LLVMValueRef args [3];
3799 args [0] = lhs;
3800 args [1] = values [ins->sreg2];
3802 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3803 break;
3806 case OP_SHUFPS:
3807 case OP_SHUFPD:
3808 case OP_PSHUFLED:
3809 case OP_PSHUFLEW_LOW:
3810 case OP_PSHUFLEW_HIGH: {
3811 int mask [16];
3812 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3813 int i, mask_size = 0;
3814 int imask = ins->inst_c0;
3816 /* Convert the x86 shuffle mask to LLVM's */
3817 switch (ins->opcode) {
3818 case OP_SHUFPS:
3819 mask_size = 4;
3820 mask [0] = ((imask >> 0) & 3);
3821 mask [1] = ((imask >> 2) & 3);
3822 mask [2] = ((imask >> 4) & 3) + 4;
3823 mask [3] = ((imask >> 6) & 3) + 4;
3824 v1 = values [ins->sreg1];
3825 v2 = values [ins->sreg2];
3826 break;
3827 case OP_SHUFPD:
3828 mask_size = 2;
3829 mask [0] = ((imask >> 0) & 1);
3830 mask [1] = ((imask >> 1) & 1) + 2;
3831 v1 = values [ins->sreg1];
3832 v2 = values [ins->sreg2];
3833 break;
3834 case OP_PSHUFLEW_LOW:
3835 mask_size = 8;
3836 mask [0] = ((imask >> 0) & 3);
3837 mask [1] = ((imask >> 2) & 3);
3838 mask [2] = ((imask >> 4) & 3);
3839 mask [3] = ((imask >> 6) & 3);
3840 mask [4] = 4 + 0;
3841 mask [5] = 4 + 1;
3842 mask [6] = 4 + 2;
3843 mask [7] = 4 + 3;
3844 v1 = values [ins->sreg1];
3845 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3846 break;
3847 case OP_PSHUFLEW_HIGH:
3848 mask_size = 8;
3849 mask [0] = 0;
3850 mask [1] = 1;
3851 mask [2] = 2;
3852 mask [3] = 3;
3853 mask [4] = 4 + ((imask >> 0) & 3);
3854 mask [5] = 4 + ((imask >> 2) & 3);
3855 mask [6] = 4 + ((imask >> 4) & 3);
3856 mask [7] = 4 + ((imask >> 6) & 3);
3857 v1 = values [ins->sreg1];
3858 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3859 break;
3860 case OP_PSHUFLED:
3861 mask_size = 4;
3862 mask [0] = ((imask >> 0) & 3);
3863 mask [1] = ((imask >> 2) & 3);
3864 mask [2] = ((imask >> 4) & 3);
3865 mask [3] = ((imask >> 6) & 3);
3866 v1 = values [ins->sreg1];
3867 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3868 break;
3869 default:
3870 g_assert_not_reached ();
3872 for (i = 0; i < mask_size; ++i)
3873 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3875 values [ins->dreg] =
3876 LLVMBuildShuffleVector (builder, v1, v2,
3877 LLVMConstVector (mask_values, mask_size), dname);
3878 break;
3881 case OP_UNPACK_LOWB:
3882 case OP_UNPACK_LOWW:
3883 case OP_UNPACK_LOWD:
3884 case OP_UNPACK_LOWQ:
3885 case OP_UNPACK_LOWPS:
3886 case OP_UNPACK_LOWPD:
3887 case OP_UNPACK_HIGHB:
3888 case OP_UNPACK_HIGHW:
3889 case OP_UNPACK_HIGHD:
3890 case OP_UNPACK_HIGHQ:
3891 case OP_UNPACK_HIGHPS:
3892 case OP_UNPACK_HIGHPD: {
3893 int mask [16];
3894 LLVMValueRef mask_values [16];
3895 int i, mask_size = 0;
3896 gboolean low = FALSE;
3898 switch (ins->opcode) {
3899 case OP_UNPACK_LOWB:
3900 mask_size = 16;
3901 low = TRUE;
3902 break;
3903 case OP_UNPACK_LOWW:
3904 mask_size = 8;
3905 low = TRUE;
3906 break;
3907 case OP_UNPACK_LOWD:
3908 case OP_UNPACK_LOWPS:
3909 mask_size = 4;
3910 low = TRUE;
3911 break;
3912 case OP_UNPACK_LOWQ:
3913 case OP_UNPACK_LOWPD:
3914 mask_size = 2;
3915 low = TRUE;
3916 break;
3917 case OP_UNPACK_HIGHB:
3918 mask_size = 16;
3919 break;
3920 case OP_UNPACK_HIGHW:
3921 mask_size = 8;
3922 break;
3923 case OP_UNPACK_HIGHD:
3924 case OP_UNPACK_HIGHPS:
3925 mask_size = 4;
3926 break;
3927 case OP_UNPACK_HIGHQ:
3928 case OP_UNPACK_HIGHPD:
3929 mask_size = 2;
3930 break;
3931 default:
3932 g_assert_not_reached ();
3935 if (low) {
3936 for (i = 0; i < (mask_size / 2); ++i) {
3937 mask [(i * 2)] = i;
3938 mask [(i * 2) + 1] = mask_size + i;
3940 } else {
3941 for (i = 0; i < (mask_size / 2); ++i) {
3942 mask [(i * 2)] = (mask_size / 2) + i;
3943 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3947 for (i = 0; i < mask_size; ++i)
3948 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3950 values [ins->dreg] =
3951 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3952 LLVMConstVector (mask_values, mask_size), dname);
3953 break;
3956 case OP_DUPPD: {
3957 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3958 LLVMValueRef v, val;
3960 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3961 val = LLVMConstNull (t);
3962 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3963 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3965 values [ins->dreg] = val;
3966 break;
3968 case OP_DUPPS_LOW:
3969 case OP_DUPPS_HIGH: {
3970 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3971 LLVMValueRef v1, v2, val;
3974 if (ins->opcode == OP_DUPPS_LOW) {
3975 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3976 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3977 } else {
3978 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3979 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3981 val = LLVMConstNull (t);
3982 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3983 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3984 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3985 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3987 values [ins->dreg] = val;
3988 break;
3991 #endif /* SIMD */
3993 case OP_DUMMY_USE:
3994 break;
3997 * EXCEPTION HANDLING
3999 case OP_IMPLICIT_EXCEPTION:
4000 /* This marks a place where an implicit exception can happen */
4001 if (bb->region != -1)
4002 LLVM_FAILURE (ctx, "implicit-exception");
4003 break;
4004 case OP_THROW:
4005 case OP_RETHROW: {
4006 MonoMethodSignature *throw_sig;
4007 LLVMValueRef callee, arg;
4008 gboolean rethrow = (ins->opcode == OP_RETHROW);
4009 const char *icall_name;
4011 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4012 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4014 if (!callee) {
4015 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4016 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4017 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4018 if (cfg->compile_aot) {
4019 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4020 } else {
4021 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4023 #ifdef TARGET_X86
4025 * LLVM doesn't push the exception argument, so we need a different
4026 * trampoline.
4028 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4029 #else
4030 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4031 #endif
4034 mono_memory_barrier ();
4035 if (rethrow)
4036 ctx->lmodule->rethrow = callee;
4037 else
4038 ctx->lmodule->throw = callee;
4040 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4041 emit_call (ctx, bb, &builder, callee, &arg, 1);
4042 break;
4044 case OP_CALL_HANDLER: {
4046 * We don't 'call' handlers, but instead simply branch to them.
4047 * The code generated by ENDFINALLY will branch back to us.
4049 LLVMBasicBlockRef noex_bb;
4050 GSList *bb_list;
4051 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4053 bb_list = info->call_handler_return_bbs;
4056 * Set the indicator variable for the finally clause.
4058 lhs = info->finally_ind;
4059 g_assert (lhs);
4060 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4062 /* Branch to the finally clause */
4063 LLVMBuildBr (builder, info->call_handler_target_bb);
4065 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4066 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4068 builder = ctx->builder = create_builder (ctx);
4069 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4071 bblocks [bb->block_num].end_bblock = noex_bb;
4072 break;
4074 case OP_START_HANDLER: {
4075 break;
4077 case OP_ENDFINALLY: {
4078 LLVMBasicBlockRef resume_bb;
4079 MonoBasicBlock *handler_bb;
4080 LLVMValueRef val, switch_ins, callee;
4081 GSList *bb_list;
4082 BBInfo *info;
4084 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4085 g_assert (handler_bb);
4086 info = &bblocks [handler_bb->block_num];
4087 lhs = info->finally_ind;
4088 g_assert (lhs);
4090 bb_list = info->call_handler_return_bbs;
4092 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4094 /* Load the finally variable */
4095 val = LLVMBuildLoad (builder, lhs, "");
4097 /* Reset the variable */
4098 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4100 /* Branch to either resume_bb, or to the bblocks in bb_list */
4101 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4103 * The other targets are added at the end to handle OP_CALL_HANDLER
4104 * opcodes processed later.
4106 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4108 builder = ctx->builder = create_builder (ctx);
4109 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4111 if (ctx->cfg->compile_aot) {
4112 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4113 } else {
4114 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4116 LLVMBuildCall (builder, callee, NULL, 0, "");
4118 LLVMBuildUnreachable (builder);
4119 has_terminator = TRUE;
4120 break;
4122 default: {
4123 char reason [128];
4125 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4126 LLVM_FAILURE (ctx, reason);
4127 break;
4131 /* Convert the value to the type required by phi nodes */
4132 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4133 if (!values [ins->dreg])
4134 /* vtypes */
4135 values [ins->dreg] = addresses [ins->dreg];
4136 else
4137 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4140 /* Add stores for volatile variables */
4141 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4142 emit_volatile_store (ctx, ins->dreg);
4145 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4146 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4148 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4149 LLVMBuildRetVoid (builder);
4151 if (bb == cfg->bb_entry)
4152 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4154 return;
4156 FAILURE:
4157 return;
4161 * mono_llvm_check_method_supported:
4163 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4164 * compiling a method twice.
4166 void
4167 mono_llvm_check_method_supported (MonoCompile *cfg)
4170 MonoMethodHeader *header = cfg->header;
4171 MonoExceptionClause *clause;
4172 int i;
4175 if (cfg->generic_sharing_context && !IS_LLVM_MONO_BRANCH) {
4176 /* No way to obtain location info for this/rgctx */
4177 cfg->exception_message = g_strdup ("gshared");
4178 cfg->disable_llvm = TRUE;
4181 if (cfg->method->save_lmf) {
4182 cfg->exception_message = g_strdup ("lmf");
4183 cfg->disable_llvm = TRUE;
4186 #if 0
4187 for (i = 0; i < header->num_clauses; ++i) {
4188 clause = &header->clauses [i];
4190 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4192 * FIXME: Some tests still fail with nested clauses.
4194 cfg->exception_message = g_strdup ("nested clauses");
4195 cfg->disable_llvm = TRUE;
4198 #endif
4200 /* FIXME: */
4201 if (cfg->method->dynamic) {
4202 cfg->exception_message = g_strdup ("dynamic.");
4203 cfg->disable_llvm = TRUE;
4208 * mono_llvm_emit_method:
4210 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4212 void
4213 mono_llvm_emit_method (MonoCompile *cfg)
4215 EmitContext *ctx;
4216 MonoMethodSignature *sig;
4217 MonoBasicBlock *bb;
4218 LLVMTypeRef method_type;
4219 LLVMValueRef method = NULL;
4220 char *method_name;
4221 LLVMValueRef *values;
4222 int i, max_block_num, bb_index;
4223 gboolean last = FALSE;
4224 GPtrArray *phi_values;
4225 LLVMCallInfo *linfo;
4226 GSList *l;
4227 LLVMModuleRef module;
4228 BBInfo *bblocks;
4229 GPtrArray *bblock_list;
4230 MonoMethodHeader *header;
4231 MonoExceptionClause *clause;
4232 LLVMSigInfo sinfo;
4233 char **names;
4235 /* The code below might acquire the loader lock, so use it for global locking */
4236 mono_loader_lock ();
4238 /* Used to communicate with the callbacks */
4239 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4241 ctx = g_new0 (EmitContext, 1);
4242 ctx->cfg = cfg;
4243 ctx->mempool = cfg->mempool;
4246 * This maps vregs to the LLVM instruction defining them
4248 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4250 * This maps vregs for volatile variables to the LLVM instruction defining their
4251 * address.
4253 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4254 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4255 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4256 phi_values = g_ptr_array_new ();
4258 * This signals whenever the vreg was defined by a phi node with no input vars
4259 * (i.e. all its input bblocks end with NOT_REACHABLE).
4261 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4262 /* Whenever the bblock is unreachable */
4263 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4265 bblock_list = g_ptr_array_new ();
4267 ctx->values = values;
4268 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4270 if (cfg->compile_aot) {
4271 ctx->lmodule = &aot_module;
4272 method_name = mono_aot_get_method_name (cfg);
4273 cfg->llvm_method_name = g_strdup (method_name);
4274 } else {
4275 init_jit_module ();
4276 ctx->lmodule = &jit_module;
4277 method_name = mono_method_full_name (cfg->method, TRUE);
4280 module = ctx->module = ctx->lmodule->module;
4282 #if 1
4284 static int count = 0;
4285 count ++;
4287 if (getenv ("LLVM_COUNT")) {
4288 if (count == atoi (getenv ("LLVM_COUNT"))) {
4289 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4290 fflush (stdout);
4291 last = TRUE;
4293 if (count > atoi (getenv ("LLVM_COUNT")))
4294 LLVM_FAILURE (ctx, "");
4297 #endif
4299 sig = mono_method_signature (cfg->method);
4300 ctx->sig = sig;
4302 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4303 ctx->linfo = linfo;
4304 CHECK_FAILURE (ctx);
4306 if (cfg->rgctx_var) {
4307 if (IS_LLVM_MONO_BRANCH)
4308 linfo->rgctx_arg = TRUE;
4309 else
4310 LLVM_FAILURE (ctx, "rgctx arg");
4312 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4313 CHECK_FAILURE (ctx);
4316 * This maps parameter indexes in the original signature to the indexes in
4317 * the LLVM signature.
4319 ctx->pindexes = sinfo.pindexes;
4321 method = LLVMAddFunction (module, method_name, method_type);
4322 ctx->lmethod = method;
4324 #ifdef LLVM_MONO_BRANCH
4325 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4326 #endif
4327 LLVMSetLinkage (method, LLVMPrivateLinkage);
4329 LLVMAddFunctionAttr (method, LLVMUWTableAttribute);
4331 if (cfg->compile_aot) {
4332 LLVMSetLinkage (method, LLVMInternalLinkage);
4333 LLVMSetVisibility (method, LLVMHiddenVisibility);
4334 } else {
4335 LLVMSetLinkage (method, LLVMPrivateLinkage);
4338 if (cfg->method->save_lmf)
4339 LLVM_FAILURE (ctx, "lmf");
4341 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4342 LLVM_FAILURE (ctx, "pinvoke signature");
4344 header = cfg->header;
4345 for (i = 0; i < header->num_clauses; ++i) {
4346 clause = &header->clauses [i];
4347 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4348 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4351 if (linfo->rgctx_arg) {
4352 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4354 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4355 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4356 * CC_X86_64_Mono in X86CallingConv.td.
4358 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4359 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4361 if (cfg->vret_addr) {
4362 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4363 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4365 if (sig->hasthis) {
4366 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4367 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4370 names = g_new (char *, sig->param_count);
4371 mono_method_get_param_names (cfg->method, (const char **) names);
4373 for (i = 0; i < sig->param_count; ++i) {
4374 char *name;
4376 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4377 if (names [i] && names [i][0] != '\0')
4378 name = g_strdup_printf ("arg_%s", names [i]);
4379 else
4380 name = g_strdup_printf ("arg_%d", i);
4381 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4382 g_free (name);
4383 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4384 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4386 g_free (names);
4388 max_block_num = 0;
4389 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4390 max_block_num = MAX (max_block_num, bb->block_num);
4391 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4393 /* Add branches between non-consecutive bblocks */
4394 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4395 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4396 bb->next_bb != bb->last_ins->inst_false_bb) {
4398 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4399 inst->opcode = OP_BR;
4400 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4401 mono_bblock_add_inst (bb, inst);
4406 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4407 * was later optimized away, so clear these flags, and add them back for the still
4408 * present OP_LDADDR instructions.
4410 for (i = 0; i < cfg->next_vreg; ++i) {
4411 MonoInst *ins;
4413 ins = get_vreg_to_inst (cfg, i);
4414 if (ins && ins != cfg->rgctx_var)
4415 ins->flags &= ~MONO_INST_INDIRECT;
4419 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4421 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4422 MonoInst *ins;
4423 LLVMBuilderRef builder;
4424 char *dname;
4425 char dname_buf[128];
4427 builder = create_builder (ctx);
4429 for (ins = bb->code; ins; ins = ins->next) {
4430 switch (ins->opcode) {
4431 case OP_PHI:
4432 case OP_FPHI:
4433 case OP_VPHI:
4434 case OP_XPHI: {
4435 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4437 CHECK_FAILURE (ctx);
4439 if (ins->opcode == OP_VPHI) {
4440 /* Treat valuetype PHI nodes as operating on the address itself */
4441 g_assert (ins->klass);
4442 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4446 * Have to precreate these, as they can be referenced by
4447 * earlier instructions.
4449 sprintf (dname_buf, "t%d", ins->dreg);
4450 dname = dname_buf;
4451 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4453 if (ins->opcode == OP_VPHI)
4454 ctx->addresses [ins->dreg] = values [ins->dreg];
4456 g_ptr_array_add (phi_values, values [ins->dreg]);
4459 * Set the expected type of the incoming arguments since these have
4460 * to have the same type.
4462 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4463 int sreg1 = ins->inst_phi_args [i + 1];
4465 if (sreg1 != -1)
4466 ctx->vreg_types [sreg1] = phi_type;
4468 break;
4470 case OP_LDADDR:
4471 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4472 break;
4473 default:
4474 break;
4480 * Create an ordering for bblocks, use the depth first order first, then
4481 * put the exception handling bblocks last.
4483 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4484 bb = cfg->bblocks [bb_index];
4485 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4486 g_ptr_array_add (bblock_list, bb);
4487 bblocks [bb->block_num].added = TRUE;
4491 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4492 if (!bblocks [bb->block_num].added)
4493 g_ptr_array_add (bblock_list, bb);
4497 * Second pass: generate code.
4499 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4500 bb = g_ptr_array_index (bblock_list, bb_index);
4502 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4503 continue;
4505 process_bb (ctx, bb);
4506 CHECK_FAILURE (ctx);
4509 /* Add incoming phi values */
4510 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4511 GSList *l, *ins_list;
4513 ins_list = bblocks [bb->block_num].phi_nodes;
4515 for (l = ins_list; l; l = l->next) {
4516 PhiNode *node = l->data;
4517 MonoInst *phi = node->phi;
4518 int sreg1 = node->sreg;
4519 LLVMBasicBlockRef in_bb;
4521 if (sreg1 == -1)
4522 continue;
4524 in_bb = get_end_bb (ctx, node->in_bb);
4526 if (ctx->unreachable [node->in_bb->block_num])
4527 continue;
4529 g_assert (values [sreg1]);
4531 if (phi->opcode == OP_VPHI) {
4532 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4533 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4534 } else {
4535 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4536 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4541 /* Create the SWITCH statements for ENDFINALLY instructions */
4542 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4543 BBInfo *info = &bblocks [bb->block_num];
4544 GSList *l;
4545 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4546 LLVMValueRef switch_ins = l->data;
4547 GSList *bb_list = info->call_handler_return_bbs;
4549 for (i = 0; i < g_slist_length (bb_list); ++i)
4550 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4554 if (cfg->verbose_level > 1)
4555 mono_llvm_dump_value (method);
4557 mark_as_used (module, method);
4559 if (cfg->compile_aot) {
4560 /* Don't generate native code, keep the LLVM IR */
4561 if (cfg->compile_aot && cfg->verbose_level)
4562 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4564 //LLVMVerifyFunction(method, 0);
4565 } else {
4566 mono_llvm_optimize_method (method);
4568 if (cfg->verbose_level > 1)
4569 mono_llvm_dump_value (method);
4571 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4573 /* Set by emit_cb */
4574 g_assert (cfg->code_len);
4576 /* FIXME: Free the LLVM IL for the function */
4579 goto CLEANUP;
4581 FAILURE:
4583 if (method) {
4584 /* Need to add unused phi nodes as they can be referenced by other values */
4585 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4586 LLVMBuilderRef builder;
4588 builder = create_builder (ctx);
4589 LLVMPositionBuilderAtEnd (builder, phi_bb);
4591 for (i = 0; i < phi_values->len; ++i) {
4592 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4593 if (LLVMGetInstructionParent (v) == NULL)
4594 LLVMInsertIntoBuilder (builder, v);
4597 LLVMDeleteFunction (method);
4600 CLEANUP:
4601 g_free (values);
4602 g_free (ctx->addresses);
4603 g_free (ctx->vreg_types);
4604 g_free (ctx->vreg_cli_types);
4605 g_free (ctx->pindexes);
4606 g_free (ctx->is_dead);
4607 g_free (ctx->unreachable);
4608 g_ptr_array_free (phi_values, TRUE);
4609 g_free (ctx->bblocks);
4610 g_hash_table_destroy (ctx->region_to_handler);
4611 g_free (method_name);
4612 g_ptr_array_free (bblock_list, TRUE);
4614 for (l = ctx->builders; l; l = l->next) {
4615 LLVMBuilderRef builder = l->data;
4616 LLVMDisposeBuilder (builder);
4619 g_free (ctx);
4621 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4623 mono_loader_unlock ();
4627 * mono_llvm_emit_call:
4629 * Same as mono_arch_emit_call () for LLVM.
4631 void
4632 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4634 MonoInst *in;
4635 MonoMethodSignature *sig;
4636 int i, n, stack_size;
4637 LLVMArgInfo *ainfo;
4639 stack_size = 0;
4641 sig = call->signature;
4642 n = sig->param_count + sig->hasthis;
4644 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4646 if (cfg->disable_llvm)
4647 return;
4649 if (sig->call_convention == MONO_CALL_VARARG) {
4650 cfg->exception_message = g_strdup ("varargs");
4651 cfg->disable_llvm = TRUE;
4654 for (i = 0; i < n; ++i) {
4655 MonoInst *ins;
4657 ainfo = call->cinfo->args + i;
4659 in = call->args [i];
4661 /* Simply remember the arguments */
4662 switch (ainfo->storage) {
4663 case LLVMArgInIReg:
4664 MONO_INST_NEW (cfg, ins, OP_MOVE);
4665 ins->dreg = mono_alloc_ireg (cfg);
4666 ins->sreg1 = in->dreg;
4667 break;
4668 case LLVMArgInFPReg:
4669 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4670 ins->dreg = mono_alloc_freg (cfg);
4671 ins->sreg1 = in->dreg;
4672 break;
4673 case LLVMArgVtypeByVal:
4674 case LLVMArgVtypeInReg:
4675 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4676 ins->dreg = mono_alloc_ireg (cfg);
4677 ins->sreg1 = in->dreg;
4678 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4679 break;
4680 default:
4681 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4682 cfg->exception_message = g_strdup ("ainfo->storage");
4683 cfg->disable_llvm = TRUE;
4684 return;
4687 if (!cfg->disable_llvm) {
4688 MONO_ADD_INS (cfg->cbb, ins);
4689 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4694 static unsigned char*
4695 alloc_cb (LLVMValueRef function, int size)
4697 MonoCompile *cfg;
4699 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4701 if (cfg) {
4702 // FIXME: dynamic
4703 return mono_domain_code_reserve (cfg->domain, size);
4704 } else {
4705 return mono_domain_code_reserve (mono_domain_get (), size);
4709 static void
4710 emitted_cb (LLVMValueRef function, void *start, void *end)
4712 MonoCompile *cfg;
4714 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4715 g_assert (cfg);
4716 cfg->code_len = (guint8*)end - (guint8*)start;
4719 static void
4720 exception_cb (void *data)
4722 MonoCompile *cfg;
4723 MonoJitExceptionInfo *ei;
4724 guint32 ei_len, i, j, nested_len, nindex;
4725 gpointer *type_info;
4726 int this_reg, this_offset;
4728 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4729 g_assert (cfg);
4732 * data points to a DWARF FDE structure, convert it to our unwind format and
4733 * save it.
4734 * An alternative would be to save it directly, and modify our unwinder to work
4735 * with it.
4737 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);
4739 /* Count nested clauses */
4740 nested_len = 0;
4741 for (i = 0; i < ei_len; ++i) {
4742 for (j = 0; j < ei_len; ++j) {
4743 gint32 cindex1 = *(gint32*)type_info [i];
4744 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4745 gint32 cindex2 = *(gint32*)type_info [j];
4746 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4748 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4749 nested_len ++;
4754 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4755 cfg->llvm_ex_info_len = ei_len + nested_len;
4756 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4757 /* Fill the rest of the information from the type info */
4758 for (i = 0; i < ei_len; ++i) {
4759 gint32 clause_index = *(gint32*)type_info [i];
4760 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4762 cfg->llvm_ex_info [i].flags = clause->flags;
4763 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4767 * For nested clauses, the LLVM produced exception info associates the try interval with
4768 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4770 /* FIXME: These should be order with the normal clauses */
4771 nindex = ei_len;
4772 for (i = 0; i < ei_len; ++i) {
4773 for (j = 0; j < ei_len; ++j) {
4774 gint32 cindex1 = *(gint32*)type_info [i];
4775 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4776 gint32 cindex2 = *(gint32*)type_info [j];
4777 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4779 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4781 * The try interval comes from the nested clause, everything else from the
4782 * nesting clause.
4784 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4785 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4786 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4787 nindex ++;
4791 g_assert (nindex == ei_len + nested_len);
4792 cfg->llvm_this_reg = this_reg;
4793 cfg->llvm_this_offset = this_offset;
4795 /* type_info [i] is cfg mempool allocated, no need to free it */
4797 g_free (ei);
4798 g_free (type_info);
4801 static inline void
4802 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4804 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4807 static inline void
4808 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4810 LLVMTypeRef param_types [4];
4812 param_types [0] = param_type1;
4813 param_types [1] = param_type2;
4815 AddFunc (module, name, ret_type, param_types, 2);
4818 static void
4819 add_intrinsics (LLVMModuleRef module)
4821 /* Emit declarations of instrinsics */
4823 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4824 * type doesn't seem to do any locking.
4827 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4829 memset_param_count = 5;
4830 memset_func_name = "llvm.memset.p0i8.i32";
4832 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4836 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4838 memcpy_param_count = 5;
4839 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4841 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4845 LLVMTypeRef params [] = { LLVMDoubleType () };
4847 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4848 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4849 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4851 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4852 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4856 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
4858 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4859 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4860 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4861 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4862 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
4863 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
4864 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
4868 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4869 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4871 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4872 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4873 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4874 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4875 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4876 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4880 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4881 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4883 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4884 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4885 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4886 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4887 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4888 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4892 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4893 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4894 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4896 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4898 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4901 /* EH intrinsics */
4903 LLVMTypeRef arg_types [2];
4904 LLVMTypeRef ret_type;
4906 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4907 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4908 eh_selector_name = "llvm.eh.selector";
4909 ret_type = LLVMInt32Type ();
4911 LLVMAddFunction (module, eh_selector_name, LLVMFunctionType (ret_type, arg_types, 2, TRUE));
4913 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
4915 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4917 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4920 /* SSE intrinsics */
4922 LLVMTypeRef ret_type, arg_types [2];
4924 /* Binary ops */
4925 ret_type = type_to_simd_type (MONO_TYPE_I4);
4926 arg_types [0] = ret_type;
4927 arg_types [1] = ret_type;
4928 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4930 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4932 ret_type = type_to_simd_type (MONO_TYPE_I2);
4933 arg_types [0] = ret_type;
4934 arg_types [1] = ret_type;
4935 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4936 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4937 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4938 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4939 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4940 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4941 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4942 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4943 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4944 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4945 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4947 ret_type = type_to_simd_type (MONO_TYPE_I1);
4948 arg_types [0] = ret_type;
4949 arg_types [1] = ret_type;
4950 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4951 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4952 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4953 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4954 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4955 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4956 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4957 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4958 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4960 ret_type = type_to_simd_type (MONO_TYPE_I8);
4961 arg_types [0] = ret_type;
4962 arg_types [1] = ret_type;
4963 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4965 ret_type = type_to_simd_type (MONO_TYPE_R8);
4966 arg_types [0] = ret_type;
4967 arg_types [1] = ret_type;
4968 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4969 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4970 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4971 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4972 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4974 ret_type = type_to_simd_type (MONO_TYPE_R4);
4975 arg_types [0] = ret_type;
4976 arg_types [1] = ret_type;
4977 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4978 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4979 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4980 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4981 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4983 /* pack */
4984 ret_type = type_to_simd_type (MONO_TYPE_I1);
4985 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4986 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4987 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4988 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4989 ret_type = type_to_simd_type (MONO_TYPE_I2);
4990 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4991 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4992 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4993 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4995 /* cmp pd/ps */
4996 ret_type = type_to_simd_type (MONO_TYPE_R8);
4997 arg_types [0] = ret_type;
4998 arg_types [1] = ret_type;
4999 arg_types [2] = LLVMInt8Type ();
5000 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5001 ret_type = type_to_simd_type (MONO_TYPE_R4);
5002 arg_types [0] = ret_type;
5003 arg_types [1] = ret_type;
5004 arg_types [2] = LLVMInt8Type ();
5005 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5007 /* Conversion ops */
5008 ret_type = type_to_simd_type (MONO_TYPE_R8);
5009 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5010 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5011 ret_type = type_to_simd_type (MONO_TYPE_R4);
5012 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5013 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5014 ret_type = type_to_simd_type (MONO_TYPE_I4);
5015 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5016 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5017 ret_type = type_to_simd_type (MONO_TYPE_I4);
5018 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5019 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5020 ret_type = type_to_simd_type (MONO_TYPE_R4);
5021 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5022 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5023 ret_type = type_to_simd_type (MONO_TYPE_R8);
5024 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5025 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5027 ret_type = type_to_simd_type (MONO_TYPE_I4);
5028 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5029 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5030 ret_type = type_to_simd_type (MONO_TYPE_I4);
5031 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5032 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5034 /* Unary ops */
5035 ret_type = type_to_simd_type (MONO_TYPE_R8);
5036 arg_types [0] = ret_type;
5037 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5038 ret_type = type_to_simd_type (MONO_TYPE_R4);
5039 arg_types [0] = ret_type;
5040 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5041 ret_type = type_to_simd_type (MONO_TYPE_R4);
5042 arg_types [0] = ret_type;
5043 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5044 ret_type = type_to_simd_type (MONO_TYPE_R4);
5045 arg_types [0] = ret_type;
5046 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5048 /* shifts */
5049 ret_type = type_to_simd_type (MONO_TYPE_I2);
5050 arg_types [0] = ret_type;
5051 arg_types [1] = LLVMInt32Type ();
5052 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5053 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5054 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5055 ret_type = type_to_simd_type (MONO_TYPE_I4);
5056 arg_types [0] = ret_type;
5057 arg_types [1] = LLVMInt32Type ();
5058 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5059 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5060 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5061 ret_type = type_to_simd_type (MONO_TYPE_I8);
5062 arg_types [0] = ret_type;
5063 arg_types [1] = LLVMInt32Type ();
5064 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5065 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5067 /* pmovmskb */
5068 ret_type = LLVMInt32Type ();
5069 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5070 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5073 if (IS_LLVM_MONO_BRANCH) {
5074 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5077 /* Load/Store intrinsics */
5078 if (IS_LLVM_MONO_BRANCH) {
5079 LLVMTypeRef arg_types [5];
5080 int i;
5081 char name [128];
5083 for (i = 1; i <= 8; i *= 2) {
5084 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5085 arg_types [1] = LLVMInt32Type ();
5086 arg_types [2] = LLVMInt1Type ();
5087 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5088 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5090 arg_types [0] = LLVMIntType (i * 8);
5091 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5092 arg_types [2] = LLVMInt32Type ();
5093 arg_types [3] = LLVMInt1Type ();
5094 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5095 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5100 void
5101 mono_llvm_init (void)
5103 mono_native_tls_alloc (current_cfg_tls_id, NULL);
5106 static void
5107 init_jit_module (void)
5109 MonoJitICallInfo *info;
5111 if (jit_module_inited)
5112 return;
5114 mono_loader_lock ();
5116 if (jit_module_inited) {
5117 mono_loader_unlock ();
5118 return;
5121 jit_module.module = LLVMModuleCreateWithName ("mono");
5123 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5125 add_intrinsics (jit_module.module);
5127 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5129 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5130 g_assert (info);
5131 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5133 jit_module_inited = TRUE;
5135 mono_loader_unlock ();
5138 void
5139 mono_llvm_cleanup (void)
5141 if (ee)
5142 mono_llvm_dispose_ee (ee);
5144 if (jit_module.llvm_types)
5145 g_hash_table_destroy (jit_module.llvm_types);
5147 if (aot_module.module)
5148 LLVMDisposeModule (aot_module.module);
5150 LLVMContextDispose (LLVMGetGlobalContext ());
5153 void
5154 mono_llvm_create_aot_module (const char *got_symbol)
5156 /* Delete previous module */
5157 if (aot_module.plt_entries)
5158 g_hash_table_destroy (aot_module.plt_entries);
5159 if (aot_module.module)
5160 LLVMDisposeModule (aot_module.module);
5162 memset (&aot_module, 0, sizeof (aot_module));
5164 aot_module.module = LLVMModuleCreateWithName ("aot");
5165 aot_module.got_symbol = got_symbol;
5167 add_intrinsics (aot_module.module);
5169 /* Add GOT */
5171 * We couldn't compute the type of the LLVM global representing the got because
5172 * its size is only known after all the methods have been emitted. So create
5173 * a dummy variable, and replace all uses it with the real got variable when
5174 * its size is known in mono_llvm_emit_aot_module ().
5177 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5179 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5180 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5183 /* Add a dummy personality function */
5185 LLVMBasicBlockRef lbb;
5186 LLVMBuilderRef lbuilder;
5187 LLVMValueRef personality;
5189 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5190 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5191 lbb = LLVMAppendBasicBlock (personality, "BB0");
5192 lbuilder = LLVMCreateBuilder ();
5193 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5194 LLVMBuildRetVoid (lbuilder);
5197 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5198 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5202 * Emit the aot module into the LLVM bitcode file FILENAME.
5204 void
5205 mono_llvm_emit_aot_module (const char *filename, int got_size)
5207 LLVMTypeRef got_type;
5208 LLVMValueRef real_got;
5211 * Create the real got variable and replace all uses of the dummy variable with
5212 * the real one.
5214 got_type = LLVMArrayType (IntPtrType (), got_size);
5215 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5216 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5217 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5219 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5221 mark_as_used (aot_module.module, real_got);
5223 /* Delete the dummy got so it doesn't become a global */
5224 LLVMDeleteGlobal (aot_module.got_var);
5226 #if 0
5228 char *verifier_err;
5230 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5231 g_assert_not_reached ();
5234 #endif
5236 LLVMWriteBitcodeToFile (aot_module.module, filename);
5240 DESIGN:
5241 - Emit LLVM IR from the mono IR using the LLVM C API.
5242 - The original arch specific code remains, so we can fall back to it if we run
5243 into something we can't handle.
5247 A partial list of issues:
5248 - Handling of opcodes which can throw exceptions.
5250 In the mono JIT, these are implemented using code like this:
5251 method:
5252 <compare>
5253 throw_pos:
5254 b<cond> ex_label
5255 <rest of code>
5256 ex_label:
5257 push throw_pos - method
5258 call <exception trampoline>
5260 The problematic part is push throw_pos - method, which cannot be represented
5261 in the LLVM IR, since it does not support label values.
5262 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5263 be implemented in JIT mode ?
5264 -> a possible but slower implementation would use the normal exception
5265 throwing code but it would need to control the placement of the throw code
5266 (it needs to be exactly after the compare+branch).
5267 -> perhaps add a PC offset intrinsics ?
5269 - efficient implementation of .ovf opcodes.
5271 These are currently implemented as:
5272 <ins which sets the condition codes>
5273 b<cond> ex_label
5275 Some overflow opcodes are now supported by LLVM SVN.
5277 - exception handling, unwinding.
5278 - SSA is disabled for methods with exception handlers
5279 - How to obtain unwind info for LLVM compiled methods ?
5280 -> this is now solved by converting the unwind info generated by LLVM
5281 into our format.
5282 - LLVM uses the c++ exception handling framework, while we use our home grown
5283 code, and couldn't use the c++ one:
5284 - its not supported under VC++, other exotic platforms.
5285 - it might be impossible to support filter clauses with it.
5287 - trampolines.
5289 The trampolines need a predictable call sequence, since they need to disasm
5290 the calling code to obtain register numbers / offsets.
5292 LLVM currently generates this code in non-JIT mode:
5293 mov -0x98(%rax),%eax
5294 callq *%rax
5295 Here, the vtable pointer is lost.
5296 -> solution: use one vtable trampoline per class.
5298 - passing/receiving the IMT pointer/RGCTX.
5299 -> solution: pass them as normal arguments ?
5301 - argument passing.
5303 LLVM does not allow the specification of argument registers etc. This means
5304 that all calls are made according to the platform ABI.
5306 - passing/receiving vtypes.
5308 Vtypes passed/received in registers are handled by the front end by using
5309 a signature with scalar arguments, and loading the parts of the vtype into those
5310 arguments.
5312 Vtypes passed on the stack are handled using the 'byval' attribute.
5314 - ldaddr.
5316 Supported though alloca, we need to emit the load/store code.
5318 - types.
5320 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5321 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5322 This is made easier because the IR is already in SSA form.
5323 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5324 types are frequently used incorrectly.
5328 AOT SUPPORT:
5329 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5330 append the AOT data structures to that file. For methods which cannot be
5331 handled by LLVM, the normal JIT compiled versions are used.
5334 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5335 * - each bblock should end with a branch
5336 * - setting the return value, making cfg->ret non-volatile
5337 * - avoid some transformations in the JIT which make it harder for us to generate
5338 * code.
5339 * - use pointer types to help optimizations.