Treat CEE_BREAK the same as Debugger:Break (), i.e. route it through sdb.
[mono-project/dkf.git] / mono / mini / mini-llvm.c
blob3398b96d612391fa700679649ee8241f2e67b738
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>
11 #ifndef __STDC_LIMIT_MACROS
12 #define __STDC_LIMIT_MACROS
13 #endif
14 #ifndef __STDC_CONSTANT_MACROS
15 #define __STDC_CONSTANT_MACROS
16 #endif
18 #include "llvm-c/Core.h"
19 #include "llvm-c/ExecutionEngine.h"
20 #include "llvm-c/BitWriter.h"
21 #include "llvm-c/Analysis.h"
23 #include "mini-llvm-cpp.h"
26 * Information associated by mono with LLVM modules.
28 typedef struct {
29 LLVMModuleRef module;
30 LLVMValueRef throw, rethrow, throw_corlib_exception;
31 GHashTable *llvm_types;
32 LLVMValueRef got_var;
33 const char *got_symbol;
34 GHashTable *plt_entries;
35 } MonoLLVMModule;
38 * Information associated by the backend with mono basic blocks.
40 typedef struct {
41 LLVMBasicBlockRef bblock, end_bblock;
42 LLVMValueRef finally_ind;
43 gboolean added, invoke_target;
44 /*
45 * If this bblock is the start of a finally clause, this is a list of bblocks it
46 * needs to branch to in ENDFINALLY.
48 GSList *call_handler_return_bbs;
50 * If this bblock is the start of a finally clause, this is the bblock that
51 * CALL_HANDLER needs to branch to.
53 LLVMBasicBlockRef call_handler_target_bb;
54 /* The list of switch statements generated by ENDFINALLY instructions */
55 GSList *endfinally_switch_ins_list;
56 GSList *phi_nodes;
57 } BBInfo;
60 * Structure containing emit state
62 typedef struct {
63 MonoMemPool *mempool;
65 /* Maps method names to the corresponding LLVMValueRef */
66 GHashTable *emitted_method_decls;
68 MonoCompile *cfg;
69 LLVMValueRef lmethod;
70 MonoLLVMModule *lmodule;
71 LLVMModuleRef module;
72 BBInfo *bblocks;
73 int sindex, default_index, ex_index;
74 LLVMBuilderRef builder;
75 LLVMValueRef *values, *addresses;
76 MonoType **vreg_cli_types;
77 LLVMCallInfo *linfo;
78 MonoMethodSignature *sig;
79 GSList *builders;
80 GHashTable *region_to_handler;
81 LLVMBuilderRef alloca_builder;
82 LLVMValueRef last_alloca;
83 LLVMValueRef rgctx_arg;
84 LLVMTypeRef *vreg_types;
85 gboolean *is_dead;
86 gboolean *unreachable;
87 int *pindexes;
89 char temp_name [32];
90 } EmitContext;
92 typedef struct {
93 MonoBasicBlock *bb;
94 MonoInst *phi;
95 MonoBasicBlock *in_bb;
96 int sreg;
97 } PhiNode;
100 * Instruction metadata
101 * This is the same as ins_info, but LREG != IREG.
103 #ifdef MINI_OP
104 #undef MINI_OP
105 #endif
106 #ifdef MINI_OP3
107 #undef MINI_OP3
108 #endif
109 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
110 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
111 #define NONE ' '
112 #define IREG 'i'
113 #define FREG 'f'
114 #define VREG 'v'
115 #define XREG 'x'
116 #define LREG 'l'
117 /* keep in sync with the enum in mini.h */
118 const char
119 llvm_ins_info[] = {
120 #include "mini-ops.h"
122 #undef MINI_OP
123 #undef MINI_OP3
125 #if SIZEOF_VOID_P == 4
126 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
127 #else
128 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
129 #endif
131 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
133 #if 0
134 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
135 #else
136 #define TRACE_FAILURE(msg)
137 #endif
139 #ifdef TARGET_X86
140 #define IS_TARGET_X86 1
141 #else
142 #define IS_TARGET_X86 0
143 #endif
145 #define LLVM_FAILURE(ctx, reason) do { \
146 TRACE_FAILURE (reason); \
147 (ctx)->cfg->exception_message = g_strdup (reason); \
148 (ctx)->cfg->disable_llvm = TRUE; \
149 goto FAILURE; \
150 } while (0)
152 #define CHECK_FAILURE(ctx) do { \
153 if ((ctx)->cfg->disable_llvm) \
154 goto FAILURE; \
155 } while (0)
157 static LLVMIntPredicate cond_to_llvm_cond [] = {
158 LLVMIntEQ,
159 LLVMIntNE,
160 LLVMIntSLE,
161 LLVMIntSGE,
162 LLVMIntSLT,
163 LLVMIntSGT,
164 LLVMIntULE,
165 LLVMIntUGE,
166 LLVMIntULT,
167 LLVMIntUGT,
170 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
171 LLVMRealOEQ,
172 LLVMRealUNE,
173 LLVMRealOLE,
174 LLVMRealOGE,
175 LLVMRealOLT,
176 LLVMRealOGT,
177 LLVMRealULE,
178 LLVMRealUGE,
179 LLVMRealULT,
180 LLVMRealUGT,
183 static LLVMExecutionEngineRef ee;
184 static guint32 current_cfg_tls_id;
186 static MonoLLVMModule jit_module, aot_module;
187 static gboolean jit_module_inited;
188 static int memset_param_count, memcpy_param_count;
189 static const char *memset_func_name;
190 static const char *memcpy_func_name;
191 static const char *eh_selector_name;
193 static void init_jit_module (void);
196 * IntPtrType:
198 * The LLVM type with width == sizeof (gpointer)
200 static LLVMTypeRef
201 IntPtrType (void)
203 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
207 * get_vtype_size:
209 * Return the size of the LLVM representation of the vtype T.
211 static guint32
212 get_vtype_size (MonoType *t)
214 int size;
216 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
218 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
219 size ++;
221 return size;
225 * simd_class_to_llvm_type:
227 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
229 static LLVMTypeRef
230 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
232 if (!strcmp (klass->name, "Vector2d")) {
233 return LLVMVectorType (LLVMDoubleType (), 2);
234 } else if (!strcmp (klass->name, "Vector2l")) {
235 return LLVMVectorType (LLVMInt64Type (), 2);
236 } else if (!strcmp (klass->name, "Vector2ul")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector4i")) {
239 return LLVMVectorType (LLVMInt32Type (), 4);
240 } else if (!strcmp (klass->name, "Vector4ui")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4f")) {
243 return LLVMVectorType (LLVMFloatType (), 4);
244 } else if (!strcmp (klass->name, "Vector8s")) {
245 return LLVMVectorType (LLVMInt16Type (), 8);
246 } else if (!strcmp (klass->name, "Vector8us")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector16sb")) {
249 return LLVMVectorType (LLVMInt8Type (), 16);
250 } else if (!strcmp (klass->name, "Vector16b")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
252 } else {
253 printf ("%s\n", klass->name);
254 NOT_IMPLEMENTED;
255 return NULL;
259 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
260 static inline G_GNUC_UNUSED LLVMTypeRef
261 type_to_simd_type (int type)
263 switch (type) {
264 case MONO_TYPE_I1:
265 return LLVMVectorType (LLVMInt8Type (), 16);
266 case MONO_TYPE_I2:
267 return LLVMVectorType (LLVMInt16Type (), 8);
268 case MONO_TYPE_I4:
269 return LLVMVectorType (LLVMInt32Type (), 4);
270 case MONO_TYPE_I8:
271 return LLVMVectorType (LLVMInt64Type (), 2);
272 case MONO_TYPE_R8:
273 return LLVMVectorType (LLVMDoubleType (), 2);
274 case MONO_TYPE_R4:
275 return LLVMVectorType (LLVMFloatType (), 4);
276 default:
277 g_assert_not_reached ();
278 return NULL;
283 * type_to_llvm_type:
285 * Return the LLVM type corresponding to T.
287 static LLVMTypeRef
288 type_to_llvm_type (EmitContext *ctx, MonoType *t)
290 if (t->byref)
291 return LLVMPointerType (LLVMInt8Type (), 0);
292 switch (t->type) {
293 case MONO_TYPE_VOID:
294 return LLVMVoidType ();
295 case MONO_TYPE_I1:
296 return LLVMInt8Type ();
297 case MONO_TYPE_I2:
298 return LLVMInt16Type ();
299 case MONO_TYPE_I4:
300 return LLVMInt32Type ();
301 case MONO_TYPE_U1:
302 return LLVMInt8Type ();
303 case MONO_TYPE_U2:
304 return LLVMInt16Type ();
305 case MONO_TYPE_U4:
306 return LLVMInt32Type ();
307 case MONO_TYPE_BOOLEAN:
308 return LLVMInt8Type ();
309 case MONO_TYPE_I8:
310 case MONO_TYPE_U8:
311 return LLVMInt64Type ();
312 case MONO_TYPE_CHAR:
313 return LLVMInt16Type ();
314 case MONO_TYPE_R4:
315 return LLVMFloatType ();
316 case MONO_TYPE_R8:
317 return LLVMDoubleType ();
318 case MONO_TYPE_I:
319 case MONO_TYPE_U:
320 return IntPtrType ();
321 case MONO_TYPE_OBJECT:
322 case MONO_TYPE_CLASS:
323 case MONO_TYPE_ARRAY:
324 case MONO_TYPE_SZARRAY:
325 case MONO_TYPE_STRING:
326 case MONO_TYPE_PTR:
327 return LLVMPointerType (IntPtrType (), 0);
328 case MONO_TYPE_VAR:
329 case MONO_TYPE_MVAR:
330 /* Because of generic sharing */
331 return IntPtrType ();
332 case MONO_TYPE_GENERICINST:
333 if (!mono_type_generic_inst_is_valuetype (t))
334 return IntPtrType ();
335 /* Fall through */
336 case MONO_TYPE_VALUETYPE:
337 case MONO_TYPE_TYPEDBYREF: {
338 MonoClass *klass;
339 LLVMTypeRef ltype;
341 klass = mono_class_from_mono_type (t);
343 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
344 return simd_class_to_llvm_type (ctx, klass);
346 if (klass->enumtype)
347 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
348 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
349 if (!ltype) {
350 int i, size;
351 LLVMTypeRef *eltypes;
353 size = get_vtype_size (t);
355 eltypes = g_new (LLVMTypeRef, size);
356 for (i = 0; i < size; ++i)
357 eltypes [i] = LLVMInt8Type ();
359 /* We couldn't name these types since LLVM uses structural type equality */
360 ltype = LLVMStructType (eltypes, size, FALSE);
361 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
362 g_free (eltypes);
364 return ltype;
367 default:
368 printf ("X: %d\n", t->type);
369 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
370 ctx->cfg->disable_llvm = TRUE;
371 return NULL;
376 * type_is_unsigned:
378 * Return whenever T is an unsigned int type.
380 static gboolean
381 type_is_unsigned (EmitContext *ctx, MonoType *t)
383 if (t->byref)
384 return FALSE;
385 switch (t->type) {
386 case MONO_TYPE_U1:
387 case MONO_TYPE_U2:
388 case MONO_TYPE_U4:
389 case MONO_TYPE_U8:
390 return TRUE;
391 default:
392 return FALSE;
397 * type_to_llvm_arg_type:
399 * Same as type_to_llvm_type, but treat i8/i16 as i32.
401 static LLVMTypeRef
402 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
404 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
406 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
408 * LLVM generates code which only sets the lower bits, while JITted
409 * code expects all the bits to be set.
411 ptype = LLVMInt32Type ();
414 return ptype;
418 * llvm_type_to_stack_type:
420 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
421 * on the IL stack.
423 static G_GNUC_UNUSED LLVMTypeRef
424 llvm_type_to_stack_type (LLVMTypeRef type)
426 if (type == NULL)
427 return NULL;
428 if (type == LLVMInt8Type ())
429 return LLVMInt32Type ();
430 else if (type == LLVMInt16Type ())
431 return LLVMInt32Type ();
432 else if (type == LLVMFloatType ())
433 return LLVMDoubleType ();
434 else
435 return type;
439 * regtype_to_llvm_type:
441 * Return the LLVM type corresponding to the regtype C used in instruction
442 * descriptions.
444 static LLVMTypeRef
445 regtype_to_llvm_type (char c)
447 switch (c) {
448 case 'i':
449 return LLVMInt32Type ();
450 case 'l':
451 return LLVMInt64Type ();
452 case 'f':
453 return LLVMDoubleType ();
454 default:
455 return NULL;
460 * op_to_llvm_type:
462 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
464 static LLVMTypeRef
465 op_to_llvm_type (int opcode)
467 switch (opcode) {
468 case OP_ICONV_TO_I1:
469 case OP_LCONV_TO_I1:
470 return LLVMInt8Type ();
471 case OP_ICONV_TO_U1:
472 case OP_LCONV_TO_U1:
473 return LLVMInt8Type ();
474 case OP_ICONV_TO_I2:
475 case OP_LCONV_TO_I2:
476 return LLVMInt16Type ();
477 case OP_ICONV_TO_U2:
478 case OP_LCONV_TO_U2:
479 return LLVMInt16Type ();
480 case OP_ICONV_TO_I4:
481 case OP_LCONV_TO_I4:
482 return LLVMInt32Type ();
483 case OP_ICONV_TO_U4:
484 case OP_LCONV_TO_U4:
485 return LLVMInt32Type ();
486 case OP_ICONV_TO_I8:
487 return LLVMInt64Type ();
488 case OP_ICONV_TO_R4:
489 return LLVMFloatType ();
490 case OP_ICONV_TO_R8:
491 return LLVMDoubleType ();
492 case OP_ICONV_TO_U8:
493 return LLVMInt64Type ();
494 case OP_FCONV_TO_I4:
495 return LLVMInt32Type ();
496 case OP_FCONV_TO_I8:
497 return LLVMInt64Type ();
498 case OP_FCONV_TO_I1:
499 case OP_FCONV_TO_U1:
500 return LLVMInt8Type ();
501 case OP_FCONV_TO_I2:
502 case OP_FCONV_TO_U2:
503 return LLVMInt16Type ();
504 case OP_FCONV_TO_I:
505 case OP_FCONV_TO_U:
506 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
507 case OP_IADD_OVF:
508 case OP_IADD_OVF_UN:
509 case OP_ISUB_OVF:
510 case OP_ISUB_OVF_UN:
511 case OP_IMUL_OVF:
512 case OP_IMUL_OVF_UN:
513 return LLVMInt32Type ();
514 case OP_LADD_OVF:
515 case OP_LADD_OVF_UN:
516 case OP_LSUB_OVF:
517 case OP_LSUB_OVF_UN:
518 case OP_LMUL_OVF:
519 case OP_LMUL_OVF_UN:
520 return LLVMInt64Type ();
521 default:
522 printf ("%s\n", mono_inst_name (opcode));
523 g_assert_not_reached ();
524 return NULL;
529 * load_store_to_llvm_type:
531 * Return the size/sign/zero extension corresponding to the load/store opcode
532 * OPCODE.
534 static LLVMTypeRef
535 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
537 *sext = FALSE;
538 *zext = FALSE;
540 switch (opcode) {
541 case OP_LOADI1_MEMBASE:
542 case OP_STOREI1_MEMBASE_REG:
543 case OP_STOREI1_MEMBASE_IMM:
544 *size = 1;
545 *sext = TRUE;
546 return LLVMInt8Type ();
547 case OP_LOADU1_MEMBASE:
548 case OP_LOADU1_MEM:
549 *size = 1;
550 *zext = TRUE;
551 return LLVMInt8Type ();
552 case OP_LOADI2_MEMBASE:
553 case OP_STOREI2_MEMBASE_REG:
554 case OP_STOREI2_MEMBASE_IMM:
555 *size = 2;
556 *sext = TRUE;
557 return LLVMInt16Type ();
558 case OP_LOADU2_MEMBASE:
559 case OP_LOADU2_MEM:
560 *size = 2;
561 *zext = TRUE;
562 return LLVMInt16Type ();
563 case OP_LOADI4_MEMBASE:
564 case OP_LOADU4_MEMBASE:
565 case OP_LOADI4_MEM:
566 case OP_LOADU4_MEM:
567 case OP_STOREI4_MEMBASE_REG:
568 case OP_STOREI4_MEMBASE_IMM:
569 *size = 4;
570 return LLVMInt32Type ();
571 case OP_LOADI8_MEMBASE:
572 case OP_LOADI8_MEM:
573 case OP_STOREI8_MEMBASE_REG:
574 case OP_STOREI8_MEMBASE_IMM:
575 *size = 8;
576 return LLVMInt64Type ();
577 case OP_LOADR4_MEMBASE:
578 case OP_STORER4_MEMBASE_REG:
579 *size = 4;
580 return LLVMFloatType ();
581 case OP_LOADR8_MEMBASE:
582 case OP_STORER8_MEMBASE_REG:
583 *size = 8;
584 return LLVMDoubleType ();
585 case OP_LOAD_MEMBASE:
586 case OP_LOAD_MEM:
587 case OP_STORE_MEMBASE_REG:
588 case OP_STORE_MEMBASE_IMM:
589 *size = sizeof (gpointer);
590 return IntPtrType ();
591 default:
592 g_assert_not_reached ();
593 return NULL;
598 * ovf_op_to_intrins:
600 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
602 static const char*
603 ovf_op_to_intrins (int opcode)
605 switch (opcode) {
606 case OP_IADD_OVF:
607 return "llvm.sadd.with.overflow.i32";
608 case OP_IADD_OVF_UN:
609 return "llvm.uadd.with.overflow.i32";
610 case OP_ISUB_OVF:
611 return "llvm.ssub.with.overflow.i32";
612 case OP_ISUB_OVF_UN:
613 return "llvm.usub.with.overflow.i32";
614 case OP_IMUL_OVF:
615 return "llvm.smul.with.overflow.i32";
616 case OP_IMUL_OVF_UN:
617 return "llvm.umul.with.overflow.i32";
618 case OP_LADD_OVF:
619 return "llvm.sadd.with.overflow.i64";
620 case OP_LADD_OVF_UN:
621 return "llvm.uadd.with.overflow.i64";
622 case OP_LSUB_OVF:
623 return "llvm.ssub.with.overflow.i64";
624 case OP_LSUB_OVF_UN:
625 return "llvm.usub.with.overflow.i64";
626 case OP_LMUL_OVF:
627 return "llvm.smul.with.overflow.i64";
628 case OP_LMUL_OVF_UN:
629 return "llvm.umul.with.overflow.i64";
630 default:
631 g_assert_not_reached ();
632 return NULL;
636 static const char*
637 simd_op_to_intrins (int opcode)
639 switch (opcode) {
640 #if defined(TARGET_X86) || defined(TARGET_AMD64)
641 case OP_MINPD:
642 return "llvm.x86.sse2.min.pd";
643 case OP_MINPS:
644 return "llvm.x86.sse.min.ps";
645 case OP_PMIND_UN:
646 return "llvm.x86.sse41.pminud";
647 case OP_PMINW_UN:
648 return "llvm.x86.sse41.pminuw";
649 case OP_PMINB_UN:
650 return "llvm.x86.sse2.pminu.b";
651 case OP_PMINW:
652 return "llvm.x86.sse2.pmins.w";
653 case OP_MAXPD:
654 return "llvm.x86.sse2.max.pd";
655 case OP_MAXPS:
656 return "llvm.x86.sse.max.ps";
657 case OP_HADDPD:
658 return "llvm.x86.sse3.hadd.pd";
659 case OP_HADDPS:
660 return "llvm.x86.sse3.hadd.ps";
661 case OP_HSUBPD:
662 return "llvm.x86.sse3.hsub.pd";
663 case OP_HSUBPS:
664 return "llvm.x86.sse3.hsub.ps";
665 case OP_PMAXD_UN:
666 return "llvm.x86.sse41.pmaxud";
667 case OP_PMAXW_UN:
668 return "llvm.x86.sse41.pmaxuw";
669 case OP_PMAXB_UN:
670 return "llvm.x86.sse2.pmaxu.b";
671 case OP_ADDSUBPS:
672 return "llvm.x86.sse3.addsub.ps";
673 case OP_ADDSUBPD:
674 return "llvm.x86.sse3.addsub.pd";
675 case OP_EXTRACT_MASK:
676 return "llvm.x86.sse2.pmovmskb.128";
677 case OP_PSHRW:
678 case OP_PSHRW_REG:
679 return "llvm.x86.sse2.psrli.w";
680 case OP_PSHRD:
681 case OP_PSHRD_REG:
682 return "llvm.x86.sse2.psrli.d";
683 case OP_PSHRQ:
684 case OP_PSHRQ_REG:
685 return "llvm.x86.sse2.psrli.q";
686 case OP_PSHLW:
687 case OP_PSHLW_REG:
688 return "llvm.x86.sse2.pslli.w";
689 case OP_PSHLD:
690 case OP_PSHLD_REG:
691 return "llvm.x86.sse2.pslli.d";
692 case OP_PSHLQ:
693 case OP_PSHLQ_REG:
694 return "llvm.x86.sse2.pslli.q";
695 case OP_PSARW:
696 case OP_PSARW_REG:
697 return "llvm.x86.sse2.psrai.w";
698 case OP_PSARD:
699 case OP_PSARD_REG:
700 return "llvm.x86.sse2.psrai.d";
701 case OP_PADDB_SAT:
702 return "llvm.x86.sse2.padds.b";
703 case OP_PADDW_SAT:
704 return "llvm.x86.sse2.padds.w";
705 case OP_PSUBB_SAT:
706 return "llvm.x86.sse2.psubs.b";
707 case OP_PSUBW_SAT:
708 return "llvm.x86.sse2.psubs.w";
709 case OP_PADDB_SAT_UN:
710 return "llvm.x86.sse2.paddus.b";
711 case OP_PADDW_SAT_UN:
712 return "llvm.x86.sse2.paddus.w";
713 case OP_PSUBB_SAT_UN:
714 return "llvm.x86.sse2.psubus.b";
715 case OP_PSUBW_SAT_UN:
716 return "llvm.x86.sse2.psubus.w";
717 case OP_PAVGB_UN:
718 return "llvm.x86.sse2.pavg.b";
719 case OP_PAVGW_UN:
720 return "llvm.x86.sse2.pavg.w";
721 case OP_SQRTPS:
722 return "llvm.x86.sse.sqrt.ps";
723 case OP_SQRTPD:
724 return "llvm.x86.sse2.sqrt.pd";
725 case OP_RSQRTPS:
726 return "llvm.x86.sse.rsqrt.ps";
727 case OP_RCPPS:
728 return "llvm.x86.sse.rcp.ps";
729 case OP_PCMPEQB:
730 return "llvm.x86.sse2.pcmpeq.b";
731 case OP_PCMPEQW:
732 return "llvm.x86.sse2.pcmpeq.w";
733 case OP_PCMPEQD:
734 return "llvm.x86.sse2.pcmpeq.d";
735 case OP_PCMPEQQ:
736 return "llvm.x86.sse41.pcmpeqq";
737 case OP_PCMPGTB:
738 return "llvm.x86.sse2.pcmpgt.b";
739 case OP_CVTDQ2PD:
740 return "llvm.x86.sse2.cvtdq2pd";
741 case OP_CVTDQ2PS:
742 return "llvm.x86.sse2.cvtdq2ps";
743 case OP_CVTPD2DQ:
744 return "llvm.x86.sse2.cvtpd2dq";
745 case OP_CVTPS2DQ:
746 return "llvm.x86.sse2.cvtps2dq";
747 case OP_CVTPD2PS:
748 return "llvm.x86.sse2.cvtpd2ps";
749 case OP_CVTPS2PD:
750 return "llvm.x86.sse2.cvtps2pd";
751 case OP_CVTTPD2DQ:
752 return "llvm.x86.sse2.cvttpd2dq";
753 case OP_CVTTPS2DQ:
754 return "llvm.x86.sse2.cvttps2dq";
755 case OP_COMPPS:
756 return "llvm.x86.sse.cmp.ps";
757 case OP_COMPPD:
758 return "llvm.x86.sse2.cmp.pd";
759 case OP_PACKW:
760 return "llvm.x86.sse2.packsswb.128";
761 case OP_PACKD:
762 return "llvm.x86.sse2.packssdw.128";
763 case OP_PACKW_UN:
764 return "llvm.x86.sse2.packuswb.128";
765 case OP_PACKD_UN:
766 return "llvm.x86.sse41.packusdw";
767 case OP_PMULW_HIGH:
768 return "llvm.x86.sse2.pmulh.w";
769 case OP_PMULW_HIGH_UN:
770 return "llvm.x86.sse2.pmulhu.w";
771 #endif
772 default:
773 g_assert_not_reached ();
774 return NULL;
778 static LLVMTypeRef
779 simd_op_to_llvm_type (int opcode)
781 #if defined(TARGET_X86) || defined(TARGET_AMD64)
782 switch (opcode) {
783 case OP_EXTRACT_R8:
784 case OP_EXPAND_R8:
785 return type_to_simd_type (MONO_TYPE_R8);
786 case OP_EXTRACT_I8:
787 case OP_EXPAND_I8:
788 return type_to_simd_type (MONO_TYPE_I8);
789 case OP_EXTRACT_I4:
790 case OP_EXPAND_I4:
791 return type_to_simd_type (MONO_TYPE_I4);
792 case OP_EXTRACT_I2:
793 case OP_EXTRACT_U2:
794 case OP_EXTRACTX_U2:
795 case OP_EXPAND_I2:
796 return type_to_simd_type (MONO_TYPE_I2);
797 case OP_EXTRACT_I1:
798 case OP_EXTRACT_U1:
799 case OP_EXPAND_I1:
800 return type_to_simd_type (MONO_TYPE_I1);
801 case OP_EXPAND_R4:
802 return type_to_simd_type (MONO_TYPE_R4);
803 case OP_CVTDQ2PD:
804 case OP_CVTDQ2PS:
805 return type_to_simd_type (MONO_TYPE_I4);
806 case OP_CVTPD2DQ:
807 case OP_CVTPD2PS:
808 case OP_CVTTPD2DQ:
809 return type_to_simd_type (MONO_TYPE_R8);
810 case OP_CVTPS2DQ:
811 case OP_CVTPS2PD:
812 case OP_CVTTPS2DQ:
813 return type_to_simd_type (MONO_TYPE_R4);
814 case OP_EXTRACT_MASK:
815 return type_to_simd_type (MONO_TYPE_I1);
816 case OP_SQRTPS:
817 case OP_RSQRTPS:
818 case OP_RCPPS:
819 case OP_DUPPS_LOW:
820 case OP_DUPPS_HIGH:
821 return type_to_simd_type (MONO_TYPE_R4);
822 case OP_SQRTPD:
823 case OP_DUPPD:
824 return type_to_simd_type (MONO_TYPE_R8);
825 default:
826 g_assert_not_reached ();
827 return NULL;
829 #else
830 return NULL;
831 #endif
835 * get_bb:
837 * Return the LLVM basic block corresponding to BB.
839 static LLVMBasicBlockRef
840 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
842 char bb_name [128];
844 if (ctx->bblocks [bb->block_num].bblock == NULL) {
845 sprintf (bb_name, "BB%d", bb->block_num);
847 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
848 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
851 return ctx->bblocks [bb->block_num].bblock;
855 * get_end_bb:
857 * Return the last LLVM bblock corresponding to BB.
858 * This might not be equal to the bb returned by get_bb () since we need to generate
859 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
861 static LLVMBasicBlockRef
862 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
864 get_bb (ctx, bb);
865 return ctx->bblocks [bb->block_num].end_bblock;
868 static LLVMBasicBlockRef
869 gen_bb (EmitContext *ctx, const char *prefix)
871 char bb_name [128];
873 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
874 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
878 * resolve_patch:
880 * Return the target of the patch identified by TYPE and TARGET.
882 static gpointer
883 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
885 MonoJumpInfo ji;
887 memset (&ji, 0, sizeof (ji));
888 ji.type = type;
889 ji.data.target = target;
891 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
895 * convert_full:
897 * Emit code to convert the LLVM value V to DTYPE.
899 static LLVMValueRef
900 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
902 LLVMTypeRef stype = LLVMTypeOf (v);
904 if (stype != dtype) {
905 gboolean ext = FALSE;
907 /* Extend */
908 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
909 ext = TRUE;
910 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
911 ext = TRUE;
912 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
913 ext = TRUE;
915 if (ext)
916 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
918 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
919 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
921 /* Trunc */
922 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
923 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
924 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
925 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
926 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
927 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
928 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
929 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
931 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
932 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
933 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
934 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
935 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
936 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
938 #ifdef MONO_ARCH_SOFT_FLOAT
939 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
940 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
941 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
942 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
943 #endif
945 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
946 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
948 LLVMDumpValue (v);
949 LLVMDumpValue (LLVMConstNull (dtype));
950 g_assert_not_reached ();
951 return NULL;
952 } else {
953 return v;
957 static LLVMValueRef
958 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
960 return convert_full (ctx, v, dtype, FALSE);
964 * emit_volatile_load:
966 * If vreg is volatile, emit a load from its address.
968 static LLVMValueRef
969 emit_volatile_load (EmitContext *ctx, int vreg)
971 MonoType *t;
973 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
974 t = ctx->vreg_cli_types [vreg];
975 if (t && !t->byref) {
977 * Might have to zero extend since llvm doesn't have
978 * unsigned types.
980 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
981 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
982 else if (t->type == MONO_TYPE_U8)
983 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
986 return v;
990 * emit_volatile_store:
992 * If VREG is volatile, emit a store from its value to its address.
994 static void
995 emit_volatile_store (EmitContext *ctx, int vreg)
997 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
999 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1000 g_assert (ctx->addresses [vreg]);
1001 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1005 typedef struct {
1007 * Maps parameter indexes in the original signature to parameter indexes
1008 * in the LLVM signature.
1010 int *pindexes;
1011 /* The indexes of various special arguments in the LLVM signature */
1012 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1013 } LLVMSigInfo;
1016 * sig_to_llvm_sig_full:
1018 * Return the LLVM signature corresponding to the mono signature SIG using the
1019 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1021 static LLVMTypeRef
1022 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1023 LLVMSigInfo *sinfo)
1025 LLVMTypeRef ret_type;
1026 LLVMTypeRef *param_types = NULL;
1027 LLVMTypeRef res;
1028 int i, j, pindex, vret_arg_pindex = 0;
1029 int *pindexes;
1030 gboolean vretaddr = FALSE;
1032 if (sinfo)
1033 memset (sinfo, 0, sizeof (LLVMSigInfo));
1035 ret_type = type_to_llvm_type (ctx, sig->ret);
1036 CHECK_FAILURE (ctx);
1038 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1039 /* LLVM models this by returning an aggregate value */
1040 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1041 LLVMTypeRef members [2];
1043 members [0] = IntPtrType ();
1044 ret_type = LLVMStructType (members, 1, FALSE);
1045 } else {
1046 g_assert_not_reached ();
1048 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1049 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1050 vretaddr = TRUE;
1051 ret_type = LLVMVoidType ();
1054 pindexes = g_new0 (int, sig->param_count);
1055 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1056 pindex = 0;
1057 if (cinfo && cinfo->rgctx_arg) {
1058 if (sinfo)
1059 sinfo->rgctx_arg_pindex = pindex;
1060 param_types [pindex] = IntPtrType ();
1061 pindex ++;
1063 if (cinfo && cinfo->imt_arg && IS_LLVM_MONO_BRANCH) {
1064 if (sinfo)
1065 sinfo->imt_arg_pindex = pindex;
1066 param_types [pindex] = IntPtrType ();
1067 pindex ++;
1069 if (vretaddr) {
1070 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1071 vret_arg_pindex = pindex;
1072 if (cinfo->vret_arg_index == 1) {
1073 /* Add the slots consumed by the first argument */
1074 LLVMArgInfo *ainfo = &cinfo->args [0];
1075 switch (ainfo->storage) {
1076 case LLVMArgVtypeInReg:
1077 for (j = 0; j < 2; ++j) {
1078 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1079 vret_arg_pindex ++;
1081 break;
1082 default:
1083 vret_arg_pindex ++;
1087 if (sinfo)
1088 sinfo->vret_arg_pindex = vret_arg_pindex;
1091 if (vretaddr && vret_arg_pindex == pindex)
1092 param_types [pindex ++] = IntPtrType ();
1093 if (sig->hasthis) {
1094 if (sinfo)
1095 sinfo->this_arg_pindex = pindex;
1096 param_types [pindex ++] = IntPtrType ();
1098 if (vretaddr && vret_arg_pindex == pindex)
1099 param_types [pindex ++] = IntPtrType ();
1100 for (i = 0; i < sig->param_count; ++i) {
1101 if (vretaddr && vret_arg_pindex == pindex)
1102 param_types [pindex ++] = IntPtrType ();
1103 pindexes [i] = pindex;
1104 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1105 for (j = 0; j < 2; ++j) {
1106 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1107 case LLVMArgInIReg:
1108 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1109 break;
1110 case LLVMArgNone:
1111 break;
1112 default:
1113 g_assert_not_reached ();
1116 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1117 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1118 CHECK_FAILURE (ctx);
1119 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1120 pindex ++;
1121 } else {
1122 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1125 if (vretaddr && vret_arg_pindex == pindex)
1126 param_types [pindex ++] = IntPtrType ();
1128 CHECK_FAILURE (ctx);
1130 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1131 g_free (param_types);
1133 if (sinfo) {
1134 sinfo->pindexes = pindexes;
1135 } else {
1136 g_free (pindexes);
1139 return res;
1141 FAILURE:
1142 g_free (param_types);
1144 return NULL;
1147 static LLVMTypeRef
1148 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1150 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1154 * LLVMFunctionType1:
1156 * Create an LLVM function type from the arguments.
1158 static G_GNUC_UNUSED LLVMTypeRef
1159 LLVMFunctionType1(LLVMTypeRef ReturnType,
1160 LLVMTypeRef ParamType1,
1161 int IsVarArg)
1163 LLVMTypeRef param_types [1];
1165 param_types [0] = ParamType1;
1167 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1171 * LLVMFunctionType2:
1173 * Create an LLVM function type from the arguments.
1175 static LLVMTypeRef
1176 LLVMFunctionType2(LLVMTypeRef ReturnType,
1177 LLVMTypeRef ParamType1,
1178 LLVMTypeRef ParamType2,
1179 int IsVarArg)
1181 LLVMTypeRef param_types [2];
1183 param_types [0] = ParamType1;
1184 param_types [1] = ParamType2;
1186 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1190 * LLVMFunctionType3:
1192 * Create an LLVM function type from the arguments.
1194 static LLVMTypeRef
1195 LLVMFunctionType3(LLVMTypeRef ReturnType,
1196 LLVMTypeRef ParamType1,
1197 LLVMTypeRef ParamType2,
1198 LLVMTypeRef ParamType3,
1199 int IsVarArg)
1201 LLVMTypeRef param_types [3];
1203 param_types [0] = ParamType1;
1204 param_types [1] = ParamType2;
1205 param_types [2] = ParamType3;
1207 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1211 * create_builder:
1213 * Create an LLVM builder and remember it so it can be freed later.
1215 static LLVMBuilderRef
1216 create_builder (EmitContext *ctx)
1218 LLVMBuilderRef builder = LLVMCreateBuilder ();
1220 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1222 return builder;
1225 static LLVMValueRef
1226 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1228 char *callee_name = mono_aot_get_plt_symbol (type, data);
1229 LLVMValueRef callee;
1231 if (!callee_name)
1232 return NULL;
1234 if (ctx->cfg->compile_aot)
1235 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1236 mono_add_patch_info (ctx->cfg, 0, type, data);
1238 // FIXME: Locking
1239 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1240 if (!callee) {
1241 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1243 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1245 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1248 return callee;
1251 static int
1252 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1254 MonoMethodHeader *header = cfg->header;
1255 MonoExceptionClause *clause;
1256 int i;
1258 /* Directly */
1259 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1260 return (bb->region >> 8) - 1;
1262 /* Indirectly */
1263 for (i = 0; i < header->num_clauses; ++i) {
1264 clause = &header->clauses [i];
1266 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1267 return i;
1270 return -1;
1273 static void
1274 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1276 LLVMValueRef md_arg;
1277 int md_kind;
1279 if (!IS_LLVM_MONO_BRANCH)
1280 return;
1282 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1283 md_arg = LLVMMDString ("mono", 4);
1284 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1288 * emit_call:
1290 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1291 * a try region.
1293 static LLVMValueRef
1294 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1296 MonoCompile *cfg = ctx->cfg;
1297 LLVMValueRef lcall;
1298 LLVMBuilderRef builder = *builder_ref;
1299 int clause_index;
1301 clause_index = get_handler_clause (cfg, bb);
1303 if (clause_index != -1) {
1304 MonoMethodHeader *header = cfg->header;
1305 MonoExceptionClause *ec = &header->clauses [clause_index];
1306 MonoBasicBlock *tblock;
1307 LLVMBasicBlockRef ex_bb, noex_bb;
1310 * Have to use an invoke instead of a call, branching to the
1311 * handler bblock of the clause containing this bblock.
1314 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1316 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1317 g_assert (tblock);
1319 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1321 ex_bb = get_bb (ctx, tblock);
1323 noex_bb = gen_bb (ctx, "NOEX_BB");
1325 /* Use an invoke */
1326 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1328 builder = ctx->builder = create_builder (ctx);
1329 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1331 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1332 } else {
1333 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1334 ctx->builder = builder;
1337 *builder_ref = ctx->builder;
1339 return lcall;
1342 static LLVMValueRef
1343 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1345 const char *intrins_name;
1346 LLVMValueRef args [16], res;
1347 LLVMTypeRef addr_type;
1349 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1351 * We handle loads which can fault by calling a mono specific intrinsic
1352 * using an invoke, so they are handled properly inside try blocks.
1353 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1354 * are marked with IntrReadArgMem.
1356 switch (size) {
1357 case 1:
1358 intrins_name = "llvm.mono.load.i8.p0i8";
1359 break;
1360 case 2:
1361 intrins_name = "llvm.mono.load.i16.p0i16";
1362 break;
1363 case 4:
1364 intrins_name = "llvm.mono.load.i32.p0i32";
1365 break;
1366 case 8:
1367 intrins_name = "llvm.mono.load.i64.p0i64";
1368 break;
1369 default:
1370 g_assert_not_reached ();
1373 addr_type = LLVMTypeOf (addr);
1374 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1375 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1377 args [0] = addr;
1378 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1379 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1380 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1382 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1383 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1384 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1385 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1387 return res;
1388 } else {
1389 LLVMValueRef res;
1392 * We emit volatile loads for loads which can fault, because otherwise
1393 * LLVM will generate invalid code when encountering a load from a
1394 * NULL address.
1396 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1398 /* Mark it with a custom metadata */
1400 if (is_faulting)
1401 set_metadata_flag (res, "mono.faulting.load");
1404 return res;
1408 static void
1409 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1411 const char *intrins_name;
1412 LLVMValueRef args [16];
1414 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1415 switch (size) {
1416 case 1:
1417 intrins_name = "llvm.mono.store.i8.p0i8";
1418 break;
1419 case 2:
1420 intrins_name = "llvm.mono.store.i16.p0i16";
1421 break;
1422 case 4:
1423 intrins_name = "llvm.mono.store.i32.p0i32";
1424 break;
1425 case 8:
1426 intrins_name = "llvm.mono.store.i64.p0i64";
1427 break;
1428 default:
1429 g_assert_not_reached ();
1432 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1433 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1434 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1437 args [0] = value;
1438 args [1] = addr;
1439 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1440 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1441 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1442 } else {
1443 LLVMBuildStore (*builder_ref, value, addr);
1448 * emit_cond_system_exception:
1450 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1451 * Might set the ctx exception.
1453 static void
1454 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1456 LLVMBasicBlockRef ex_bb, noex_bb;
1457 LLVMBuilderRef builder;
1458 MonoClass *exc_class;
1459 LLVMValueRef args [2];
1461 ex_bb = gen_bb (ctx, "EX_BB");
1462 noex_bb = gen_bb (ctx, "NOEX_BB");
1464 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1466 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1467 g_assert (exc_class);
1469 /* Emit exception throwing code */
1470 builder = create_builder (ctx);
1471 LLVMPositionBuilderAtEnd (builder, ex_bb);
1473 if (!ctx->lmodule->throw_corlib_exception) {
1474 LLVMValueRef callee;
1475 LLVMTypeRef sig;
1476 const char *icall_name;
1478 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1479 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1480 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1481 if (IS_LLVM_MONO_BRANCH) {
1482 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1483 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1484 } else {
1485 icall_name = "llvm_throw_corlib_exception_trampoline";
1486 throw_sig->params [1] = &mono_get_int32_class ()->byval_arg;
1488 sig = sig_to_llvm_sig (ctx, throw_sig);
1490 if (ctx->cfg->compile_aot) {
1491 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1492 } else {
1493 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1496 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1497 * - On x86, LLVM generated code doesn't push the arguments
1498 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1499 * arguments, not a pc offset.
1501 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1504 mono_memory_barrier ();
1505 ctx->lmodule->throw_corlib_exception = callee;
1508 if (IS_TARGET_X86)
1509 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1510 else
1511 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1513 if (IS_LLVM_MONO_BRANCH) {
1515 * The LLVM mono branch contains changes so a block address can be passed as an
1516 * argument to a call.
1518 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1519 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1520 } else {
1522 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1523 * otherwise only the line numbers in stack traces are incorrect.
1525 if (bb->region != -1 && !IS_LLVM_MONO_BRANCH)
1526 LLVM_FAILURE (ctx, "system-ex-in-region");
1528 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1529 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1532 LLVMBuildUnreachable (builder);
1534 ctx->builder = create_builder (ctx);
1535 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1537 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1539 ctx->ex_index ++;
1540 return;
1542 FAILURE:
1543 return;
1547 * emit_reg_to_vtype:
1549 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1551 static void
1552 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1554 int j, size;
1556 size = get_vtype_size (t);
1558 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1559 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1562 for (j = 0; j < 2; ++j) {
1563 LLVMValueRef index [2], addr;
1564 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1565 LLVMTypeRef part_type;
1567 if (ainfo->pair_storage [j] == LLVMArgNone)
1568 continue;
1570 part_type = LLVMIntType (part_size * 8);
1571 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1572 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1573 addr = LLVMBuildGEP (builder, address, index, 1, "");
1574 } else {
1575 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1576 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1577 addr = LLVMBuildGEP (builder, address, index, 2, "");
1579 switch (ainfo->pair_storage [j]) {
1580 case LLVMArgInIReg:
1581 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1582 break;
1583 case LLVMArgNone:
1584 break;
1585 default:
1586 g_assert_not_reached ();
1589 size -= sizeof (gpointer);
1594 * emit_vtype_to_reg:
1596 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1597 * into REGS, and the number of registers into NREGS.
1599 static void
1600 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1602 int pindex = 0;
1603 int j, size;
1605 size = get_vtype_size (t);
1607 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1608 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1611 for (j = 0; j < 2; ++j) {
1612 LLVMValueRef index [2], addr;
1613 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1615 if (ainfo->pair_storage [j] == LLVMArgNone)
1616 continue;
1618 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1619 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1620 addr = LLVMBuildGEP (builder, address, index, 1, "");
1621 } else {
1622 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1623 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1624 addr = LLVMBuildGEP (builder, address, index, 2, "");
1626 switch (ainfo->pair_storage [j]) {
1627 case LLVMArgInIReg:
1628 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1629 break;
1630 case LLVMArgNone:
1631 break;
1632 default:
1633 g_assert_not_reached ();
1635 size -= sizeof (gpointer);
1638 *nregs = pindex;
1641 static LLVMValueRef
1642 build_alloca (EmitContext *ctx, MonoType *t)
1644 MonoClass *k = mono_class_from_mono_type (t);
1645 int align;
1647 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1648 align = 16;
1649 else
1650 align = mono_class_min_align (k);
1652 /* Sometimes align is not a power of 2 */
1653 while (mono_is_power_of_two (align) == -1)
1654 align ++;
1657 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1658 * get executed every time control reaches them.
1660 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1662 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1663 return ctx->last_alloca;
1667 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1669 static void
1670 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1672 LLVMTypeRef used_type;
1673 LLVMValueRef used, used_elem;
1675 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1676 used = LLVMAddGlobal (module, used_type, "llvm.used");
1677 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1678 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1679 LLVMSetLinkage (used, LLVMAppendingLinkage);
1680 LLVMSetSection (used, "llvm.metadata");
1684 * emit_entry_bb:
1686 * Emit code to load/convert arguments.
1688 static void
1689 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1691 int i, pindex;
1692 MonoCompile *cfg = ctx->cfg;
1693 MonoMethodSignature *sig = ctx->sig;
1694 LLVMCallInfo *linfo = ctx->linfo;
1695 MonoBasicBlock *bb;
1697 ctx->alloca_builder = create_builder (ctx);
1700 * Handle indirect/volatile variables by allocating memory for them
1701 * using 'alloca', and storing their address in a temporary.
1703 for (i = 0; i < cfg->num_varinfo; ++i) {
1704 MonoInst *var = cfg->varinfo [i];
1705 LLVMTypeRef vtype;
1707 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1708 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1709 CHECK_FAILURE (ctx);
1710 /* Could be already created by an OP_VPHI */
1711 if (!ctx->addresses [var->dreg])
1712 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1713 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1717 for (i = 0; i < sig->param_count; ++i) {
1718 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1719 int reg = cfg->args [i + sig->hasthis]->dreg;
1721 if (ainfo->storage == LLVMArgVtypeInReg) {
1722 LLVMValueRef regs [2];
1725 * Emit code to save the argument from the registers to
1726 * the real argument.
1728 pindex = ctx->pindexes [i];
1729 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1730 if (ainfo->pair_storage [1] != LLVMArgNone)
1731 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1732 else
1733 regs [1] = NULL;
1735 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1737 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1739 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1740 /* Treat these as normal values */
1741 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1743 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1744 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1746 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1747 /* Treat these as normal values */
1748 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1750 } else {
1751 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1755 if (cfg->vret_addr)
1756 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1757 if (sig->hasthis)
1758 emit_volatile_store (ctx, cfg->args [0]->dreg);
1759 for (i = 0; i < sig->param_count; ++i)
1760 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1761 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1763 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1764 LLVMValueRef this_alloc;
1767 * The exception handling code needs the location where the this argument was
1768 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1769 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1770 * location into the LSDA.
1772 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1773 /* This volatile store will keep the alloca alive */
1774 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1776 set_metadata_flag (this_alloc, "mono.this");
1779 if (cfg->rgctx_var) {
1780 LLVMValueRef rgctx_alloc, store;
1783 * We handle the rgctx arg similarly to the this pointer.
1785 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1786 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1787 /* This volatile store will keep the alloca alive */
1788 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1790 set_metadata_flag (rgctx_alloc, "mono.this");
1794 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1795 * it needs to continue normally, or return back to the exception handling system.
1797 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1798 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1799 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1800 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1801 char name [128];
1802 LLVMValueRef val;
1804 sprintf (name, "finally_ind_bb%d", bb->block_num);
1805 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1806 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1808 ctx->bblocks [bb->block_num].finally_ind = val;
1811 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1812 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1813 * LLVM optimizer passes.
1815 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1816 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1820 FAILURE:
1824 /* Have to export this for AOT */
1825 void
1826 mono_personality (void);
1828 void
1829 mono_personality (void)
1831 /* Not used */
1832 g_assert_not_reached ();
1835 static void
1836 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1838 MonoCompile *cfg = ctx->cfg;
1839 LLVMModuleRef module = ctx->module;
1840 LLVMValueRef *values = ctx->values;
1841 LLVMValueRef *addresses = ctx->addresses;
1842 MonoCallInst *call = (MonoCallInst*)ins;
1843 MonoMethodSignature *sig = call->signature;
1844 LLVMValueRef callee, lcall;
1845 LLVMValueRef *args;
1846 LLVMCallInfo *cinfo;
1847 GSList *l;
1848 int i, len;
1849 gboolean vretaddr;
1850 LLVMTypeRef llvm_sig;
1851 gpointer target;
1852 gboolean virtual, calli;
1853 LLVMBuilderRef builder = *builder_ref;
1854 LLVMSigInfo sinfo;
1856 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1857 LLVM_FAILURE (ctx, "non-default callconv");
1859 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
1860 LLVM_FAILURE (ctx, "rgctx reg in call");
1862 if (call->rgctx_reg && !IS_LLVM_MONO_BRANCH) {
1864 * It might be possible to support this by creating a static rgctx trampoline, but
1865 * common_call_trampoline () would patch callsites to call the trampoline, which
1866 * would be incorrect if the rgctx arg is computed dynamically.
1868 LLVM_FAILURE (ctx, "rgctx reg");
1871 cinfo = call->cinfo;
1872 if (call->rgctx_arg_reg)
1873 cinfo->rgctx_arg = TRUE;
1874 if (call->imt_arg_reg)
1875 cinfo->imt_arg = TRUE;
1877 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1879 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1880 CHECK_FAILURE (ctx);
1882 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);
1883 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);
1885 /* FIXME: Avoid creating duplicate methods */
1887 if (ins->flags & MONO_INST_HAS_METHOD) {
1888 if (virtual) {
1889 callee = NULL;
1890 } else {
1891 if (cfg->compile_aot) {
1892 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1893 if (!callee)
1894 LLVM_FAILURE (ctx, "can't encode patch");
1895 } else {
1896 callee = LLVMAddFunction (module, "", llvm_sig);
1898 target =
1899 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1900 call->method);
1901 LLVMAddGlobalMapping (ee, callee, target);
1904 } else if (calli) {
1905 } else {
1906 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1908 if (info) {
1910 MonoJumpInfo ji;
1912 memset (&ji, 0, sizeof (ji));
1913 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1914 ji.data.target = info->name;
1916 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1918 if (cfg->compile_aot) {
1919 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1920 if (!callee)
1921 LLVM_FAILURE (ctx, "can't encode patch");
1922 } else {
1923 callee = LLVMAddFunction (module, "", llvm_sig);
1924 target = (gpointer)mono_icall_get_wrapper (info);
1925 LLVMAddGlobalMapping (ee, callee, target);
1927 } else {
1928 if (cfg->compile_aot) {
1929 callee = NULL;
1930 if (cfg->abs_patches) {
1931 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1932 if (abs_ji) {
1933 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1934 if (!callee)
1935 LLVM_FAILURE (ctx, "can't encode patch");
1938 if (!callee)
1939 LLVM_FAILURE (ctx, "aot");
1940 } else {
1941 callee = LLVMAddFunction (module, "", llvm_sig);
1942 target = NULL;
1943 if (cfg->abs_patches) {
1944 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1945 if (abs_ji) {
1947 * FIXME: Some trampolines might have
1948 * their own calling convention on some platforms.
1950 #ifndef TARGET_AMD64
1951 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)
1952 LLVM_FAILURE (ctx, "trampoline with own cconv");
1953 #endif
1954 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1955 LLVMAddGlobalMapping (ee, callee, target);
1958 if (!target)
1959 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1964 if (virtual) {
1965 int size = sizeof (gpointer);
1966 LLVMValueRef index;
1968 g_assert (ins->inst_offset % size == 0);
1969 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1972 * When using the llvm mono branch, we can support IMT directly, otherwise
1973 * we need to call a trampoline.
1975 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
1976 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1977 if (cfg->compile_aot) {
1978 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
1979 imt_tramp->method = call->method;
1980 imt_tramp->vt_offset = call->inst.inst_offset;
1982 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
1983 } else {
1984 callee = LLVMAddFunction (module, "", llvm_sig);
1985 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
1986 LLVMAddGlobalMapping (ee, callee, target);
1988 #else
1989 /* No support for passing the IMT argument */
1990 LLVM_FAILURE (ctx, "imt");
1991 #endif
1992 } else {
1993 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1995 } else if (calli) {
1996 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1997 } else {
1998 if (ins->flags & MONO_INST_HAS_METHOD) {
2003 * Collect and convert arguments
2005 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
2006 args = alloca (len);
2007 memset (args, 0, len);
2008 l = call->out_ireg_args;
2010 if (IS_LLVM_MONO_BRANCH) {
2011 if (call->rgctx_arg_reg) {
2012 g_assert (values [call->rgctx_arg_reg]);
2013 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
2015 if (call->imt_arg_reg) {
2016 g_assert (values [call->imt_arg_reg]);
2017 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
2021 if (vretaddr) {
2022 if (!addresses [call->inst.dreg])
2023 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2024 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2027 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2028 guint32 regpair;
2029 int reg, pindex;
2030 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2032 if (sig->hasthis) {
2033 if (i == 0)
2034 pindex = sinfo.this_arg_pindex;
2035 else
2036 pindex = sinfo.pindexes [i - 1];
2037 } else {
2038 pindex = sinfo.pindexes [i];
2041 regpair = (guint32)(gssize)(l->data);
2042 reg = regpair & 0xffffff;
2043 args [pindex] = values [reg];
2044 if (ainfo->storage == LLVMArgVtypeInReg) {
2045 int j;
2046 LLVMValueRef regs [2];
2047 guint32 nregs;
2049 g_assert (ainfo);
2051 g_assert (addresses [reg]);
2053 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2054 for (j = 0; j < nregs; ++j)
2055 args [pindex ++] = regs [j];
2057 // FIXME: alignment
2058 // FIXME: Get rid of the VMOVE
2059 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2060 g_assert (addresses [reg]);
2061 args [pindex] = addresses [reg];
2062 } else {
2063 g_assert (args [pindex]);
2064 if (i == 0 && sig->hasthis)
2065 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2066 else
2067 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2070 l = l->next;
2073 // FIXME: Align call sites
2076 * Emit the call
2079 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2081 #ifdef LLVM_MONO_BRANCH
2083 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2085 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2086 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2087 #endif
2088 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2089 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2090 if (!sig->pinvoke)
2091 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2093 if (call->rgctx_arg_reg)
2094 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2095 if (call->imt_arg_reg)
2096 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2097 #endif
2099 /* Add byval attributes if needed */
2100 for (i = 0; i < sig->param_count; ++i) {
2101 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2103 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2104 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2109 * Convert the result
2111 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2112 LLVMValueRef regs [2];
2114 if (!addresses [ins->dreg])
2115 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2117 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2118 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2119 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2121 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2122 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2123 /* If the method returns an unsigned value, need to zext it */
2125 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));
2128 *builder_ref = ctx->builder;
2130 g_free (sinfo.pindexes);
2132 return;
2133 FAILURE:
2134 return;
2137 static void
2138 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2140 MonoCompile *cfg = ctx->cfg;
2141 MonoMethodSignature *sig = ctx->sig;
2142 LLVMValueRef method = ctx->lmethod;
2143 LLVMValueRef *values = ctx->values;
2144 LLVMValueRef *addresses = ctx->addresses;
2145 int i;
2146 LLVMCallInfo *linfo = ctx->linfo;
2147 LLVMModuleRef module = ctx->module;
2148 BBInfo *bblocks = ctx->bblocks;
2149 MonoInst *ins;
2150 LLVMBasicBlockRef cbb;
2151 LLVMBuilderRef builder;
2152 gboolean has_terminator;
2153 LLVMValueRef v;
2154 LLVMValueRef lhs, rhs;
2156 cbb = get_bb (ctx, bb);
2157 builder = create_builder (ctx);
2158 ctx->builder = builder;
2159 LLVMPositionBuilderAtEnd (builder, cbb);
2161 if (bb == cfg->bb_entry)
2162 emit_entry_bb (ctx, builder);
2163 CHECK_FAILURE (ctx);
2165 if (bb->flags & BB_EXCEPTION_HANDLER) {
2166 LLVMTypeRef i8ptr;
2167 LLVMValueRef eh_selector, eh_exception, personality, args [4];
2168 LLVMBasicBlockRef target_bb;
2169 MonoInst *exvar;
2170 static gint32 mapping_inited;
2171 static int ti_generator;
2172 char ti_name [128];
2173 MonoClass **ti;
2174 LLVMValueRef type_info;
2175 int clause_index;
2177 if (!bblocks [bb->block_num].invoke_target) {
2179 * LLVM asserts if llvm.eh.selector is called from a bblock which
2180 * doesn't have an invoke pointing at it.
2181 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2183 LLVM_FAILURE (ctx, "handler without invokes");
2186 eh_selector = LLVMGetNamedFunction (module, eh_selector_name);
2188 if (cfg->compile_aot) {
2189 /* Use a dummy personality function */
2190 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2191 g_assert (personality);
2192 } else {
2193 personality = LLVMGetNamedFunction (module, "mono_personality");
2194 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2195 LLVMAddGlobalMapping (ee, personality, mono_personality);
2198 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2200 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2203 * Create the type info
2205 sprintf (ti_name, "type_info_%d", ti_generator);
2206 ti_generator ++;
2208 if (cfg->compile_aot) {
2209 /* decode_eh_frame () in aot-runtime.c will decode this */
2210 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2211 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2213 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2214 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2217 * Enabling this causes llc to crash:
2218 * http://llvm.org/bugs/show_bug.cgi?id=6102
2220 //LLVM_FAILURE (ctx, "aot+clauses");
2221 } else {
2223 * After the cfg mempool is freed, the type info will point to stale memory,
2224 * but this is not a problem, since we decode it once in exception_cb during
2225 * compilation.
2227 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2228 *(gint32*)ti = clause_index;
2230 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2232 LLVMAddGlobalMapping (ee, type_info, ti);
2235 args [0] = LLVMConstNull (i8ptr);
2236 args [1] = LLVMConstBitCast (personality, i8ptr);
2237 args [2] = type_info;
2238 LLVMBuildCall (builder, eh_selector, args, 3, "");
2240 /* Store the exception into the exvar */
2241 if (bb->in_scount == 1) {
2242 g_assert (bb->in_scount == 1);
2243 exvar = bb->in_stack [0];
2245 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
2247 // FIXME: This is shared with filter clauses ?
2248 g_assert (!values [exvar->dreg]);
2249 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
2250 emit_volatile_store (ctx, exvar->dreg);
2253 /* Start a new bblock which CALL_HANDLER can branch to */
2254 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2255 if (target_bb) {
2256 LLVMBuildBr (builder, target_bb);
2258 ctx->builder = builder = create_builder (ctx);
2259 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2261 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2265 has_terminator = FALSE;
2266 for (ins = bb->code; ins; ins = ins->next) {
2267 const char *spec = LLVM_INS_INFO (ins->opcode);
2268 char *dname = NULL;
2269 char dname_buf [128];
2271 if (has_terminator)
2272 /* There could be instructions after a terminator, skip them */
2273 break;
2275 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2276 sprintf (dname_buf, "t%d", ins->dreg);
2277 dname = dname_buf;
2280 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2281 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2283 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2284 lhs = emit_volatile_load (ctx, ins->sreg1);
2285 } else {
2286 /* It is ok for SETRET to have an uninitialized argument */
2287 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2288 LLVM_FAILURE (ctx, "sreg1");
2289 lhs = values [ins->sreg1];
2291 } else {
2292 lhs = NULL;
2295 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2296 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2297 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2298 rhs = emit_volatile_load (ctx, ins->sreg2);
2299 } else {
2300 if (!values [ins->sreg2])
2301 LLVM_FAILURE (ctx, "sreg2");
2302 rhs = values [ins->sreg2];
2304 } else {
2305 rhs = NULL;
2308 //mono_print_ins (ins);
2309 switch (ins->opcode) {
2310 case OP_NOP:
2311 case OP_NOT_NULL:
2312 case OP_LIVERANGE_START:
2313 case OP_LIVERANGE_END:
2314 break;
2315 case OP_ICONST:
2316 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2317 break;
2318 case OP_I8CONST:
2319 #if SIZEOF_VOID_P == 4
2320 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2321 #else
2322 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2323 #endif
2324 break;
2325 case OP_R8CONST:
2326 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2327 break;
2328 case OP_R4CONST:
2329 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2330 break;
2331 case OP_BR:
2332 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2333 has_terminator = TRUE;
2334 break;
2335 case OP_SWITCH: {
2336 int i;
2337 LLVMValueRef v;
2338 char bb_name [128];
2339 LLVMBasicBlockRef new_bb;
2340 LLVMBuilderRef new_builder;
2342 // The default branch is already handled
2343 // FIXME: Handle it here
2345 /* Start new bblock */
2346 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2347 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2349 lhs = convert (ctx, lhs, LLVMInt32Type ());
2350 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2351 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2352 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2354 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2357 new_builder = create_builder (ctx);
2358 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2359 LLVMBuildUnreachable (new_builder);
2361 has_terminator = TRUE;
2362 g_assert (!ins->next);
2364 break;
2367 case OP_SETRET:
2368 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2369 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2370 LLVMValueRef part1, retval;
2371 int size;
2373 size = get_vtype_size (sig->ret);
2375 g_assert (addresses [ins->sreg1]);
2377 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2378 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2380 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2382 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2384 LLVMBuildRet (builder, retval);
2385 break;
2388 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2389 LLVMBuildRetVoid (builder);
2390 break;
2393 if (!lhs || ctx->is_dead [ins->sreg1]) {
2395 * The method did not set its return value, probably because it
2396 * ends with a throw.
2398 if (cfg->vret_addr)
2399 LLVMBuildRetVoid (builder);
2400 else
2401 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2402 } else {
2403 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2405 has_terminator = TRUE;
2406 break;
2407 case OP_ICOMPARE:
2408 case OP_FCOMPARE:
2409 case OP_LCOMPARE:
2410 case OP_COMPARE:
2411 case OP_ICOMPARE_IMM:
2412 case OP_LCOMPARE_IMM:
2413 case OP_COMPARE_IMM: {
2414 CompRelation rel;
2415 LLVMValueRef cmp;
2417 if (ins->next->opcode == OP_NOP)
2418 break;
2420 if (ins->next->opcode == OP_BR)
2421 /* The comparison result is not needed */
2422 continue;
2424 rel = mono_opcode_to_cond (ins->next->opcode);
2426 if (ins->opcode == OP_ICOMPARE_IMM) {
2427 lhs = convert (ctx, lhs, LLVMInt32Type ());
2428 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2430 if (ins->opcode == OP_LCOMPARE_IMM) {
2431 lhs = convert (ctx, lhs, LLVMInt64Type ());
2432 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2434 if (ins->opcode == OP_LCOMPARE) {
2435 lhs = convert (ctx, lhs, LLVMInt64Type ());
2436 rhs = convert (ctx, rhs, LLVMInt64Type ());
2438 if (ins->opcode == OP_ICOMPARE) {
2439 lhs = convert (ctx, lhs, LLVMInt32Type ());
2440 rhs = convert (ctx, rhs, LLVMInt32Type ());
2443 if (lhs && rhs) {
2444 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2445 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2446 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2447 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2450 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2451 if (ins->opcode == OP_FCOMPARE)
2452 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2453 else if (ins->opcode == OP_COMPARE_IMM)
2454 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2455 else if (ins->opcode == OP_LCOMPARE_IMM) {
2456 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2457 /* The immediate is encoded in two fields */
2458 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2459 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2460 } else {
2461 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2464 else if (ins->opcode == OP_COMPARE)
2465 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2466 else
2467 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2469 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2470 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2471 has_terminator = TRUE;
2472 } else if (MONO_IS_SETCC (ins->next)) {
2473 sprintf (dname_buf, "t%d", ins->next->dreg);
2474 dname = dname_buf;
2475 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2477 /* Add stores for volatile variables */
2478 emit_volatile_store (ctx, ins->next->dreg);
2479 } else if (MONO_IS_COND_EXC (ins->next)) {
2480 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2481 CHECK_FAILURE (ctx);
2482 builder = ctx->builder;
2483 } else {
2484 LLVM_FAILURE (ctx, "next");
2487 ins = ins->next;
2488 break;
2490 case OP_FCEQ:
2491 case OP_FCLT:
2492 case OP_FCLT_UN:
2493 case OP_FCGT:
2494 case OP_FCGT_UN: {
2495 CompRelation rel;
2496 LLVMValueRef cmp;
2498 rel = mono_opcode_to_cond (ins->opcode);
2500 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2501 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2502 break;
2504 case OP_PHI:
2505 case OP_FPHI:
2506 case OP_VPHI:
2507 case OP_XPHI: {
2508 int i;
2509 gboolean empty = TRUE;
2511 /* Check that all input bblocks really branch to us */
2512 for (i = 0; i < bb->in_count; ++i) {
2513 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2514 ins->inst_phi_args [i + 1] = -1;
2515 else
2516 empty = FALSE;
2519 if (empty) {
2520 /* LLVM doesn't like phi instructions with zero operands */
2521 ctx->is_dead [ins->dreg] = TRUE;
2522 break;
2525 /* Created earlier, insert it now */
2526 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2528 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2529 int sreg1 = ins->inst_phi_args [i + 1];
2530 int count, j;
2533 * Count the number of times the incoming bblock branches to us,
2534 * since llvm requires a separate entry for each.
2536 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2537 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2539 count = 0;
2540 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2541 if (switch_ins->inst_many_bb [j] == bb)
2542 count ++;
2544 } else {
2545 count = 1;
2548 /* Remember for later */
2549 for (j = 0; j < count; ++j) {
2550 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2551 node->bb = bb;
2552 node->phi = ins;
2553 node->in_bb = bb->in_bb [i];
2554 node->sreg = sreg1;
2555 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);
2558 break;
2560 case OP_MOVE:
2561 case OP_LMOVE:
2562 case OP_XMOVE:
2563 case OP_SETFRET:
2564 g_assert (lhs);
2565 values [ins->dreg] = lhs;
2566 break;
2567 case OP_FMOVE: {
2568 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2570 g_assert (lhs);
2571 values [ins->dreg] = lhs;
2573 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2575 * This is added by the spilling pass in case of the JIT,
2576 * but we have to do it ourselves.
2578 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2580 break;
2582 case OP_IADD:
2583 case OP_ISUB:
2584 case OP_IAND:
2585 case OP_IMUL:
2586 case OP_IDIV:
2587 case OP_IDIV_UN:
2588 case OP_IREM:
2589 case OP_IREM_UN:
2590 case OP_IOR:
2591 case OP_IXOR:
2592 case OP_ISHL:
2593 case OP_ISHR:
2594 case OP_ISHR_UN:
2595 case OP_FADD:
2596 case OP_FSUB:
2597 case OP_FMUL:
2598 case OP_FDIV:
2599 case OP_LADD:
2600 case OP_LSUB:
2601 case OP_LMUL:
2602 case OP_LDIV:
2603 case OP_LDIV_UN:
2604 case OP_LREM:
2605 case OP_LREM_UN:
2606 case OP_LAND:
2607 case OP_LOR:
2608 case OP_LXOR:
2609 case OP_LSHL:
2610 case OP_LSHR:
2611 case OP_LSHR_UN:
2612 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2613 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2615 switch (ins->opcode) {
2616 case OP_IADD:
2617 case OP_LADD:
2618 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2619 break;
2620 case OP_ISUB:
2621 case OP_LSUB:
2622 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2623 break;
2624 case OP_IMUL:
2625 case OP_LMUL:
2626 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2627 break;
2628 case OP_IREM:
2629 case OP_LREM:
2630 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2631 break;
2632 case OP_IREM_UN:
2633 case OP_LREM_UN:
2634 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2635 break;
2636 case OP_IDIV:
2637 case OP_LDIV:
2638 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2639 break;
2640 case OP_IDIV_UN:
2641 case OP_LDIV_UN:
2642 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2643 break;
2644 case OP_FDIV:
2645 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2646 break;
2647 case OP_IAND:
2648 case OP_LAND:
2649 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2650 break;
2651 case OP_IOR:
2652 case OP_LOR:
2653 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2654 break;
2655 case OP_IXOR:
2656 case OP_LXOR:
2657 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2658 break;
2659 case OP_ISHL:
2660 case OP_LSHL:
2661 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2662 break;
2663 case OP_ISHR:
2664 case OP_LSHR:
2665 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2666 break;
2667 case OP_ISHR_UN:
2668 case OP_LSHR_UN:
2669 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2670 break;
2672 case OP_FADD:
2673 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2674 break;
2675 case OP_FSUB:
2676 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2677 break;
2678 case OP_FMUL:
2679 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2680 break;
2682 default:
2683 g_assert_not_reached ();
2685 break;
2686 case OP_IADD_IMM:
2687 case OP_ISUB_IMM:
2688 case OP_IMUL_IMM:
2689 case OP_IREM_IMM:
2690 case OP_IREM_UN_IMM:
2691 case OP_IDIV_IMM:
2692 case OP_IDIV_UN_IMM:
2693 case OP_IAND_IMM:
2694 case OP_IOR_IMM:
2695 case OP_IXOR_IMM:
2696 case OP_ISHL_IMM:
2697 case OP_ISHR_IMM:
2698 case OP_ISHR_UN_IMM:
2699 case OP_LADD_IMM:
2700 case OP_LSUB_IMM:
2701 case OP_LREM_IMM:
2702 case OP_LAND_IMM:
2703 case OP_LOR_IMM:
2704 case OP_LXOR_IMM:
2705 case OP_LSHL_IMM:
2706 case OP_LSHR_IMM:
2707 case OP_LSHR_UN_IMM:
2708 case OP_ADD_IMM:
2709 case OP_AND_IMM:
2710 case OP_MUL_IMM:
2711 case OP_SHL_IMM:
2712 case OP_SHR_IMM: {
2713 LLVMValueRef imm;
2715 if (spec [MONO_INST_SRC1] == 'l') {
2716 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2717 } else {
2718 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2721 #if SIZEOF_VOID_P == 4
2722 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2723 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2724 #endif
2726 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2727 lhs = convert (ctx, lhs, IntPtrType ());
2728 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2729 switch (ins->opcode) {
2730 case OP_IADD_IMM:
2731 case OP_LADD_IMM:
2732 case OP_ADD_IMM:
2733 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2734 break;
2735 case OP_ISUB_IMM:
2736 case OP_LSUB_IMM:
2737 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2738 break;
2739 case OP_IMUL_IMM:
2740 case OP_MUL_IMM:
2741 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2742 break;
2743 case OP_IDIV_IMM:
2744 case OP_LDIV_IMM:
2745 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2746 break;
2747 case OP_IDIV_UN_IMM:
2748 case OP_LDIV_UN_IMM:
2749 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2750 break;
2751 case OP_IREM_IMM:
2752 case OP_LREM_IMM:
2753 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2754 break;
2755 case OP_IREM_UN_IMM:
2756 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2757 break;
2758 case OP_IAND_IMM:
2759 case OP_LAND_IMM:
2760 case OP_AND_IMM:
2761 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2762 break;
2763 case OP_IOR_IMM:
2764 case OP_LOR_IMM:
2765 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2766 break;
2767 case OP_IXOR_IMM:
2768 case OP_LXOR_IMM:
2769 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2770 break;
2771 case OP_ISHL_IMM:
2772 case OP_LSHL_IMM:
2773 case OP_SHL_IMM:
2774 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2775 break;
2776 case OP_ISHR_IMM:
2777 case OP_LSHR_IMM:
2778 case OP_SHR_IMM:
2779 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2780 break;
2781 case OP_ISHR_UN_IMM:
2782 /* This is used to implement conv.u4, so the lhs could be an i8 */
2783 lhs = convert (ctx, lhs, LLVMInt32Type ());
2784 imm = convert (ctx, imm, LLVMInt32Type ());
2785 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2786 break;
2787 case OP_LSHR_UN_IMM:
2788 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2789 break;
2790 default:
2791 g_assert_not_reached ();
2793 break;
2795 case OP_INEG:
2796 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2797 break;
2798 case OP_LNEG:
2799 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2800 break;
2801 case OP_FNEG:
2802 lhs = convert (ctx, lhs, LLVMDoubleType ());
2803 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2804 break;
2805 case OP_INOT: {
2806 guint32 v = 0xffffffff;
2807 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2808 break;
2810 case OP_LNOT: {
2811 guint64 v = 0xffffffffffffffffLL;
2812 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2813 break;
2815 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2816 case OP_X86_LEA: {
2817 LLVMValueRef v1, v2;
2819 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2820 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2821 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2822 break;
2824 #endif
2826 case OP_ICONV_TO_I1:
2827 case OP_ICONV_TO_I2:
2828 case OP_ICONV_TO_I4:
2829 case OP_ICONV_TO_U1:
2830 case OP_ICONV_TO_U2:
2831 case OP_ICONV_TO_U4:
2832 case OP_LCONV_TO_I1:
2833 case OP_LCONV_TO_I2:
2834 case OP_LCONV_TO_U1:
2835 case OP_LCONV_TO_U2:
2836 case OP_LCONV_TO_U4: {
2837 gboolean sign;
2839 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);
2841 /* Have to do two casts since our vregs have type int */
2842 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2843 if (sign)
2844 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2845 else
2846 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2847 break;
2849 case OP_ICONV_TO_I8:
2850 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2851 break;
2852 case OP_ICONV_TO_U8:
2853 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2854 break;
2855 case OP_FCONV_TO_I4:
2856 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2857 break;
2858 case OP_FCONV_TO_I1:
2859 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2860 break;
2861 case OP_FCONV_TO_U1:
2862 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2863 break;
2864 case OP_FCONV_TO_I2:
2865 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2866 break;
2867 case OP_FCONV_TO_U2:
2868 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2869 break;
2870 case OP_FCONV_TO_I8:
2871 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2872 break;
2873 case OP_FCONV_TO_I:
2874 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2875 break;
2876 case OP_ICONV_TO_R8:
2877 case OP_LCONV_TO_R8:
2878 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2879 break;
2880 case OP_LCONV_TO_R_UN:
2881 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2882 break;
2883 #if SIZEOF_VOID_P == 4
2884 case OP_LCONV_TO_U:
2885 #endif
2886 case OP_LCONV_TO_I4:
2887 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2888 break;
2889 case OP_ICONV_TO_R4:
2890 case OP_LCONV_TO_R4:
2891 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2892 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2893 break;
2894 case OP_FCONV_TO_R4:
2895 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2896 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2897 break;
2898 case OP_SEXT_I4:
2899 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2900 break;
2901 case OP_ZEXT_I4:
2902 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2903 break;
2904 case OP_TRUNC_I4:
2905 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2906 break;
2907 case OP_LOCALLOC_IMM: {
2908 LLVMValueRef v;
2910 guint32 size = ins->inst_imm;
2911 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2913 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2915 if (ins->flags & MONO_INST_INIT) {
2916 LLVMValueRef args [5];
2918 args [0] = v;
2919 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2920 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2921 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2922 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2923 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2926 values [ins->dreg] = v;
2927 break;
2929 case OP_LOCALLOC: {
2930 LLVMValueRef v, size;
2932 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), "");
2934 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2936 if (ins->flags & MONO_INST_INIT) {
2937 LLVMValueRef args [5];
2939 args [0] = v;
2940 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2941 args [2] = size;
2942 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2943 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2944 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2946 values [ins->dreg] = v;
2947 break;
2950 case OP_LOADI1_MEMBASE:
2951 case OP_LOADU1_MEMBASE:
2952 case OP_LOADI2_MEMBASE:
2953 case OP_LOADU2_MEMBASE:
2954 case OP_LOADI4_MEMBASE:
2955 case OP_LOADU4_MEMBASE:
2956 case OP_LOADI8_MEMBASE:
2957 case OP_LOADR4_MEMBASE:
2958 case OP_LOADR8_MEMBASE:
2959 case OP_LOAD_MEMBASE:
2960 case OP_LOADI8_MEM:
2961 case OP_LOADU1_MEM:
2962 case OP_LOADU2_MEM:
2963 case OP_LOADI4_MEM:
2964 case OP_LOADU4_MEM:
2965 case OP_LOAD_MEM: {
2966 int size = 8;
2967 LLVMValueRef base, index, addr;
2968 LLVMTypeRef t;
2969 gboolean sext = FALSE, zext = FALSE;
2970 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2972 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2974 if (sext || zext)
2975 dname = (char*)"";
2977 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)) {
2978 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2979 } else {
2980 /* _MEMBASE */
2981 base = lhs;
2983 if (ins->inst_offset == 0) {
2984 addr = base;
2985 } else if (ins->inst_offset % size != 0) {
2986 /* Unaligned load */
2987 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2988 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2989 } else {
2990 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2991 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2995 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2997 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2999 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
3001 * These will signal LLVM that these loads do not alias any stores, and
3002 * they can't fail, allowing them to be hoisted out of loops.
3004 set_metadata_flag (values [ins->dreg], "mono.noalias");
3005 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3008 if (sext)
3009 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3010 else if (zext)
3011 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3012 else if (ins->opcode == OP_LOADR4_MEMBASE)
3013 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3014 break;
3017 case OP_STOREI1_MEMBASE_REG:
3018 case OP_STOREI2_MEMBASE_REG:
3019 case OP_STOREI4_MEMBASE_REG:
3020 case OP_STOREI8_MEMBASE_REG:
3021 case OP_STORER4_MEMBASE_REG:
3022 case OP_STORER8_MEMBASE_REG:
3023 case OP_STORE_MEMBASE_REG: {
3024 int size = 8;
3025 LLVMValueRef index, addr;
3026 LLVMTypeRef t;
3027 gboolean sext = FALSE, zext = FALSE;
3028 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3030 if (!values [ins->inst_destbasereg])
3031 LLVM_FAILURE (ctx, "inst_destbasereg");
3033 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3035 if (ins->inst_offset % size != 0) {
3036 /* Unaligned store */
3037 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3038 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3039 } else {
3040 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3041 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3043 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3044 break;
3047 case OP_STOREI1_MEMBASE_IMM:
3048 case OP_STOREI2_MEMBASE_IMM:
3049 case OP_STOREI4_MEMBASE_IMM:
3050 case OP_STOREI8_MEMBASE_IMM:
3051 case OP_STORE_MEMBASE_IMM: {
3052 int size = 8;
3053 LLVMValueRef index, addr;
3054 LLVMTypeRef t;
3055 gboolean sext = FALSE, zext = FALSE;
3056 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3058 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3060 if (ins->inst_offset % size != 0) {
3061 /* Unaligned store */
3062 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3063 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3064 } else {
3065 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3066 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3068 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3069 break;
3072 case OP_CHECK_THIS:
3073 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3074 break;
3075 case OP_OUTARG_VTRETADDR:
3076 break;
3077 case OP_VOIDCALL:
3078 case OP_CALL:
3079 case OP_LCALL:
3080 case OP_FCALL:
3081 case OP_VCALL:
3082 case OP_VOIDCALL_MEMBASE:
3083 case OP_CALL_MEMBASE:
3084 case OP_LCALL_MEMBASE:
3085 case OP_FCALL_MEMBASE:
3086 case OP_VCALL_MEMBASE:
3087 case OP_VOIDCALL_REG:
3088 case OP_CALL_REG:
3089 case OP_LCALL_REG:
3090 case OP_FCALL_REG:
3091 case OP_VCALL_REG: {
3092 process_call (ctx, bb, &builder, ins);
3093 CHECK_FAILURE (ctx);
3094 break;
3096 case OP_AOTCONST: {
3097 guint32 got_offset;
3098 LLVMValueRef indexes [2];
3099 MonoJumpInfo *ji;
3100 LLVMValueRef got_entry_addr;
3103 * FIXME: Can't allocate from the cfg mempool since that is freed if
3104 * the LLVM compile fails.
3106 ji = g_new0 (MonoJumpInfo, 1);
3107 ji->type = (MonoJumpInfoType)ins->inst_i1;
3108 ji->data.target = ins->inst_p0;
3110 ji = mono_aot_patch_info_dup (ji);
3112 ji->next = cfg->patch_info;
3113 cfg->patch_info = ji;
3115 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3116 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3118 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3119 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3120 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3122 // FIXME: This doesn't work right now, because it must be
3123 // paired with an invariant.end, and even then, its only in effect
3124 // inside its basic block
3125 #if 0
3127 LLVMValueRef args [3];
3128 LLVMValueRef ptr, val;
3130 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3132 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3133 args [1] = ptr;
3134 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3136 #endif
3138 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3139 break;
3141 case OP_NOT_REACHED:
3142 LLVMBuildUnreachable (builder);
3143 has_terminator = TRUE;
3144 g_assert (bb->block_num < cfg->max_block_num);
3145 ctx->unreachable [bb->block_num] = TRUE;
3146 /* Might have instructions after this */
3147 while (ins->next) {
3148 MonoInst *next = ins->next;
3150 * FIXME: If later code uses the regs defined by these instructions,
3151 * compilation will fail.
3153 MONO_DELETE_INS (bb, next);
3155 break;
3156 case OP_LDADDR: {
3157 MonoInst *var = ins->inst_p0;
3159 values [ins->dreg] = addresses [var->dreg];
3160 break;
3162 case OP_SIN: {
3163 LLVMValueRef args [1];
3165 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3166 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3167 break;
3169 case OP_COS: {
3170 LLVMValueRef args [1];
3172 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3173 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3174 break;
3176 case OP_SQRT: {
3177 LLVMValueRef args [1];
3179 #if 0
3180 /* This no longer seems to happen */
3182 * LLVM optimizes sqrt(nan) into undefined in
3183 * lib/Analysis/ConstantFolding.cpp
3184 * Also, sqrt(NegativeInfinity) is optimized into 0.
3186 LLVM_FAILURE (ctx, "sqrt");
3187 #endif
3188 args [0] = lhs;
3189 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3190 break;
3192 case OP_ABS: {
3193 LLVMValueRef args [1];
3195 args [0] = lhs;
3196 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3197 break;
3200 case OP_IMIN:
3201 case OP_LMIN:
3202 case OP_IMAX:
3203 case OP_LMAX:
3204 case OP_IMIN_UN:
3205 case OP_LMIN_UN:
3206 case OP_IMAX_UN:
3207 case OP_LMAX_UN: {
3208 LLVMValueRef v;
3210 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3211 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3213 switch (ins->opcode) {
3214 case OP_IMIN:
3215 case OP_LMIN:
3216 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3217 break;
3218 case OP_IMAX:
3219 case OP_LMAX:
3220 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3221 break;
3222 case OP_IMIN_UN:
3223 case OP_LMIN_UN:
3224 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3225 break;
3226 case OP_IMAX_UN:
3227 case OP_LMAX_UN:
3228 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3229 break;
3230 default:
3231 g_assert_not_reached ();
3232 break;
3234 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3235 break;
3237 case OP_ATOMIC_EXCHANGE_I4: {
3238 LLVMValueRef args [2];
3240 g_assert (ins->inst_offset == 0);
3242 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3243 args [1] = rhs;
3244 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
3245 break;
3247 case OP_ATOMIC_EXCHANGE_I8: {
3248 LLVMValueRef args [2];
3250 g_assert (ins->inst_offset == 0);
3252 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3253 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3254 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
3255 break;
3257 case OP_ATOMIC_ADD_NEW_I4: {
3258 LLVMValueRef args [2];
3260 g_assert (ins->inst_offset == 0);
3262 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3263 args [1] = rhs;
3264 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
3265 break;
3267 case OP_ATOMIC_ADD_NEW_I8: {
3268 LLVMValueRef args [2];
3270 g_assert (ins->inst_offset == 0);
3272 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3273 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3274 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
3275 break;
3277 case OP_ATOMIC_CAS_I4:
3278 case OP_ATOMIC_CAS_I8: {
3279 LLVMValueRef args [3];
3280 LLVMTypeRef t;
3281 const char *intrins;
3283 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3284 t = LLVMInt32Type ();
3285 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
3286 } else {
3287 t = LLVMInt64Type ();
3288 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
3291 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3292 /* comparand */
3293 args [1] = convert (ctx, values [ins->sreg3], t);
3294 /* new value */
3295 args [2] = convert (ctx, values [ins->sreg2], t);
3296 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
3297 break;
3299 case OP_MEMORY_BARRIER: {
3300 LLVMValueRef args [5];
3302 #ifdef TARGET_ARM
3303 /* Not yet supported by llc on arm */
3304 LLVM_FAILURE (ctx, "memory-barrier+arm");
3305 #endif
3307 for (i = 0; i < 5; ++i)
3308 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
3310 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
3311 break;
3313 case OP_RELAXED_NOP: {
3314 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3315 if (IS_LLVM_MONO_BRANCH)
3316 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3317 else
3318 /* No way to get LLVM to emit this */
3319 LLVM_FAILURE (ctx, "relaxed_nop");
3320 break;
3321 #else
3322 break;
3323 #endif
3325 case OP_TLS_GET: {
3326 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3327 #ifdef TARGET_AMD64
3328 // 257 == FS segment register
3329 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3330 #else
3331 // 256 == GS segment register
3332 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3333 #endif
3335 // FIXME: XEN
3336 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3337 #else
3338 LLVM_FAILURE (ctx, "opcode tls-get");
3339 #endif
3341 break;
3345 * Overflow opcodes.
3347 case OP_IADD_OVF:
3348 case OP_IADD_OVF_UN:
3349 case OP_ISUB_OVF:
3350 case OP_ISUB_OVF_UN:
3351 case OP_IMUL_OVF:
3352 case OP_IMUL_OVF_UN:
3353 #if SIZEOF_VOID_P == 8
3354 case OP_LADD_OVF:
3355 case OP_LADD_OVF_UN:
3356 case OP_LSUB_OVF:
3357 case OP_LSUB_OVF_UN:
3358 case OP_LMUL_OVF:
3359 case OP_LMUL_OVF_UN:
3360 #endif
3362 LLVMValueRef args [2], val, ovf, func;
3364 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3365 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3366 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3367 g_assert (func);
3368 val = LLVMBuildCall (builder, func, args, 2, "");
3369 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3370 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3371 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3372 CHECK_FAILURE (ctx);
3373 builder = ctx->builder;
3374 break;
3378 * Valuetypes.
3379 * We currently model them using arrays. Promotion to local vregs is
3380 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3381 * so we always have an entry in cfg->varinfo for them.
3382 * FIXME: Is this needed ?
3384 case OP_VZERO: {
3385 MonoClass *klass = ins->klass;
3386 LLVMValueRef args [5];
3388 if (!klass) {
3389 // FIXME:
3390 LLVM_FAILURE (ctx, "!klass");
3391 break;
3394 if (!addresses [ins->dreg])
3395 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3396 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3397 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3398 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3399 // FIXME: Alignment
3400 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3401 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3402 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3403 break;
3406 case OP_STOREV_MEMBASE:
3407 case OP_LOADV_MEMBASE:
3408 case OP_VMOVE: {
3409 MonoClass *klass = ins->klass;
3410 LLVMValueRef src, dst, args [5];
3411 gboolean done = FALSE;
3413 if (!klass) {
3414 // FIXME:
3415 LLVM_FAILURE (ctx, "!klass");
3416 break;
3419 switch (ins->opcode) {
3420 case OP_STOREV_MEMBASE:
3421 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3422 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3423 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3424 break;
3426 if (!addresses [ins->sreg1]) {
3427 /* SIMD */
3428 g_assert (values [ins->sreg1]);
3429 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));
3430 LLVMBuildStore (builder, values [ins->sreg1], dst);
3431 done = TRUE;
3432 } else {
3433 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3434 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3436 break;
3437 case OP_LOADV_MEMBASE:
3438 if (!addresses [ins->dreg])
3439 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3440 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3441 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3442 break;
3443 case OP_VMOVE:
3444 if (!addresses [ins->sreg1])
3445 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3446 if (!addresses [ins->dreg])
3447 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3448 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3449 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3450 break;
3451 default:
3452 g_assert_not_reached ();
3454 CHECK_FAILURE (ctx);
3456 if (done)
3457 break;
3459 args [0] = dst;
3460 args [1] = src;
3461 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3462 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3463 // FIXME: Alignment
3464 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3465 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3466 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3467 break;
3469 case OP_LLVM_OUTARG_VT:
3470 if (!addresses [ins->sreg1]) {
3471 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3472 g_assert (values [ins->sreg1]);
3473 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3475 addresses [ins->dreg] = addresses [ins->sreg1];
3476 break;
3479 * SIMD
3481 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3482 case OP_XZERO: {
3483 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3484 break;
3486 case OP_LOADX_MEMBASE: {
3487 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3488 LLVMValueRef src;
3490 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3491 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3492 break;
3494 case OP_STOREX_MEMBASE: {
3495 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3496 LLVMValueRef dest;
3498 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3499 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3500 break;
3502 case OP_PADDB:
3503 case OP_PADDW:
3504 case OP_PADDD:
3505 case OP_PADDQ:
3506 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3507 break;
3508 case OP_ADDPD:
3509 case OP_ADDPS:
3510 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3511 break;
3512 case OP_PSUBB:
3513 case OP_PSUBW:
3514 case OP_PSUBD:
3515 case OP_PSUBQ:
3516 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3517 break;
3518 case OP_SUBPD:
3519 case OP_SUBPS:
3520 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3521 break;
3522 case OP_MULPD:
3523 case OP_MULPS:
3524 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3525 break;
3526 case OP_DIVPD:
3527 case OP_DIVPS:
3528 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3529 break;
3530 case OP_PAND:
3531 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3532 break;
3533 case OP_POR:
3534 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3535 break;
3536 case OP_PXOR:
3537 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3538 break;
3539 case OP_PMULW:
3540 case OP_PMULD:
3541 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3542 break;
3543 case OP_ANDPS:
3544 case OP_ANDNPS:
3545 case OP_ORPS:
3546 case OP_XORPS:
3547 case OP_ANDPD:
3548 case OP_ANDNPD:
3549 case OP_ORPD:
3550 case OP_XORPD: {
3551 LLVMTypeRef t, rt;
3552 LLVMValueRef v;
3554 switch (ins->opcode) {
3555 case OP_ANDPS:
3556 case OP_ANDNPS:
3557 case OP_ORPS:
3558 case OP_XORPS:
3559 t = LLVMVectorType (LLVMInt32Type (), 4);
3560 rt = LLVMVectorType (LLVMFloatType (), 4);
3561 break;
3562 case OP_ANDPD:
3563 case OP_ANDNPD:
3564 case OP_ORPD:
3565 case OP_XORPD:
3566 t = LLVMVectorType (LLVMInt64Type (), 2);
3567 rt = LLVMVectorType (LLVMDoubleType (), 2);
3568 break;
3569 default:
3570 t = LLVMInt32Type ();
3571 rt = LLVMInt32Type ();
3572 g_assert_not_reached ();
3575 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3576 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3577 switch (ins->opcode) {
3578 case OP_ANDPS:
3579 case OP_ANDPD:
3580 v = LLVMBuildAnd (builder, lhs, rhs, "");
3581 break;
3582 case OP_ORPS:
3583 case OP_ORPD:
3584 v = LLVMBuildOr (builder, lhs, rhs, "");
3585 break;
3586 case OP_XORPS:
3587 case OP_XORPD:
3588 v = LLVMBuildXor (builder, lhs, rhs, "");
3589 break;
3590 case OP_ANDNPS:
3591 case OP_ANDNPD:
3592 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3593 break;
3595 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3596 break;
3598 case OP_MINPD:
3599 case OP_MINPS:
3600 case OP_MAXPD:
3601 case OP_MAXPS:
3602 case OP_ADDSUBPD:
3603 case OP_ADDSUBPS:
3604 case OP_PMIND_UN:
3605 case OP_PMINW_UN:
3606 case OP_PMINB_UN:
3607 case OP_PMINW:
3608 case OP_PMAXD_UN:
3609 case OP_PMAXW_UN:
3610 case OP_PMAXB_UN:
3611 case OP_HADDPD:
3612 case OP_HADDPS:
3613 case OP_HSUBPD:
3614 case OP_HSUBPS:
3615 case OP_PADDB_SAT:
3616 case OP_PADDW_SAT:
3617 case OP_PSUBB_SAT:
3618 case OP_PSUBW_SAT:
3619 case OP_PADDB_SAT_UN:
3620 case OP_PADDW_SAT_UN:
3621 case OP_PSUBB_SAT_UN:
3622 case OP_PSUBW_SAT_UN:
3623 case OP_PAVGB_UN:
3624 case OP_PAVGW_UN:
3625 case OP_PCMPEQB:
3626 case OP_PCMPEQW:
3627 case OP_PCMPEQD:
3628 case OP_PCMPEQQ:
3629 case OP_PCMPGTB:
3630 case OP_PACKW:
3631 case OP_PACKD:
3632 case OP_PACKW_UN:
3633 case OP_PACKD_UN:
3634 case OP_PMULW_HIGH:
3635 case OP_PMULW_HIGH_UN: {
3636 LLVMValueRef args [2];
3638 args [0] = lhs;
3639 args [1] = rhs;
3641 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3642 break;
3644 case OP_EXTRACT_R8:
3645 case OP_EXTRACT_I8:
3646 case OP_EXTRACT_I4:
3647 case OP_EXTRACT_I2:
3648 case OP_EXTRACT_U2:
3649 case OP_EXTRACTX_U2:
3650 case OP_EXTRACT_I1:
3651 case OP_EXTRACT_U1: {
3652 LLVMTypeRef t;
3653 gboolean zext = FALSE;
3655 t = simd_op_to_llvm_type (ins->opcode);
3657 switch (ins->opcode) {
3658 case OP_EXTRACT_R8:
3659 case OP_EXTRACT_I8:
3660 case OP_EXTRACT_I4:
3661 case OP_EXTRACT_I2:
3662 case OP_EXTRACT_I1:
3663 break;
3664 case OP_EXTRACT_U2:
3665 case OP_EXTRACTX_U2:
3666 case OP_EXTRACT_U1:
3667 zext = TRUE;
3668 break;
3669 default:
3670 t = LLVMInt32Type ();
3671 g_assert_not_reached ();
3674 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3675 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3676 if (zext)
3677 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3678 break;
3681 case OP_EXPAND_I1:
3682 case OP_EXPAND_I2:
3683 case OP_EXPAND_I4:
3684 case OP_EXPAND_I8:
3685 case OP_EXPAND_R4:
3686 case OP_EXPAND_R8: {
3687 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3688 LLVMValueRef mask [16], v;
3690 for (i = 0; i < 16; ++i)
3691 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3693 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3695 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3696 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3697 break;
3700 case OP_INSERT_I1:
3701 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3702 break;
3703 case OP_INSERT_I2:
3704 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3705 break;
3706 case OP_INSERT_I4:
3707 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3708 break;
3709 case OP_INSERT_I8:
3710 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3711 break;
3712 case OP_INSERT_R4:
3713 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3714 break;
3715 case OP_INSERT_R8:
3716 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3717 break;
3719 case OP_CVTDQ2PD:
3720 case OP_CVTDQ2PS:
3721 case OP_CVTPD2DQ:
3722 case OP_CVTPS2DQ:
3723 case OP_CVTPD2PS:
3724 case OP_CVTPS2PD:
3725 case OP_CVTTPD2DQ:
3726 case OP_CVTTPS2DQ:
3727 case OP_EXTRACT_MASK:
3728 case OP_SQRTPS:
3729 case OP_SQRTPD:
3730 case OP_RSQRTPS:
3731 case OP_RCPPS: {
3732 LLVMValueRef v;
3734 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3736 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3737 break;
3740 case OP_ICONV_TO_R8_RAW:
3741 /* Same as OP_ICONV_TO_R8 */
3742 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3743 break;
3745 case OP_COMPPS:
3746 case OP_COMPPD: {
3747 LLVMValueRef args [3];
3749 args [0] = lhs;
3750 args [1] = rhs;
3751 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3753 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3754 break;
3757 case OP_ICONV_TO_X:
3758 /* This is only used for implementing shifts by non-immediate */
3759 values [ins->dreg] = lhs;
3760 break;
3762 case OP_PSHRW:
3763 case OP_PSHRD:
3764 case OP_PSHRQ:
3765 case OP_PSARW:
3766 case OP_PSARD:
3767 case OP_PSHLW:
3768 case OP_PSHLD:
3769 case OP_PSHLQ: {
3770 LLVMValueRef args [3];
3772 args [0] = lhs;
3773 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3775 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3776 break;
3779 case OP_PSHRW_REG:
3780 case OP_PSHRD_REG:
3781 case OP_PSHRQ_REG:
3782 case OP_PSARW_REG:
3783 case OP_PSARD_REG:
3784 case OP_PSHLW_REG:
3785 case OP_PSHLD_REG:
3786 case OP_PSHLQ_REG: {
3787 LLVMValueRef args [3];
3789 args [0] = lhs;
3790 args [1] = values [ins->sreg2];
3792 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3793 break;
3796 case OP_SHUFPS:
3797 case OP_SHUFPD:
3798 case OP_PSHUFLED:
3799 case OP_PSHUFLEW_LOW:
3800 case OP_PSHUFLEW_HIGH: {
3801 int mask [16];
3802 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3803 int i, mask_size = 0;
3804 int imask = ins->inst_c0;
3806 /* Convert the x86 shuffle mask to LLVM's */
3807 switch (ins->opcode) {
3808 case OP_SHUFPS:
3809 mask_size = 4;
3810 mask [0] = ((imask >> 0) & 3);
3811 mask [1] = ((imask >> 2) & 3);
3812 mask [2] = ((imask >> 4) & 3) + 4;
3813 mask [3] = ((imask >> 6) & 3) + 4;
3814 v1 = values [ins->sreg1];
3815 v2 = values [ins->sreg2];
3816 break;
3817 case OP_SHUFPD:
3818 mask_size = 2;
3819 mask [0] = ((imask >> 0) & 1);
3820 mask [1] = ((imask >> 1) & 1) + 2;
3821 v1 = values [ins->sreg1];
3822 v2 = values [ins->sreg2];
3823 break;
3824 case OP_PSHUFLEW_LOW:
3825 mask_size = 8;
3826 mask [0] = ((imask >> 0) & 3);
3827 mask [1] = ((imask >> 2) & 3);
3828 mask [2] = ((imask >> 4) & 3);
3829 mask [3] = ((imask >> 6) & 3);
3830 mask [4] = 4 + 0;
3831 mask [5] = 4 + 1;
3832 mask [6] = 4 + 2;
3833 mask [7] = 4 + 3;
3834 v1 = values [ins->sreg1];
3835 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3836 break;
3837 case OP_PSHUFLEW_HIGH:
3838 mask_size = 8;
3839 mask [0] = 0;
3840 mask [1] = 1;
3841 mask [2] = 2;
3842 mask [3] = 3;
3843 mask [4] = 4 + ((imask >> 0) & 3);
3844 mask [5] = 4 + ((imask >> 2) & 3);
3845 mask [6] = 4 + ((imask >> 4) & 3);
3846 mask [7] = 4 + ((imask >> 6) & 3);
3847 v1 = values [ins->sreg1];
3848 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3849 break;
3850 case OP_PSHUFLED:
3851 mask_size = 4;
3852 mask [0] = ((imask >> 0) & 3);
3853 mask [1] = ((imask >> 2) & 3);
3854 mask [2] = ((imask >> 4) & 3);
3855 mask [3] = ((imask >> 6) & 3);
3856 v1 = values [ins->sreg1];
3857 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3858 break;
3859 default:
3860 g_assert_not_reached ();
3862 for (i = 0; i < mask_size; ++i)
3863 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3865 values [ins->dreg] =
3866 LLVMBuildShuffleVector (builder, v1, v2,
3867 LLVMConstVector (mask_values, mask_size), dname);
3868 break;
3871 case OP_UNPACK_LOWB:
3872 case OP_UNPACK_LOWW:
3873 case OP_UNPACK_LOWD:
3874 case OP_UNPACK_LOWQ:
3875 case OP_UNPACK_LOWPS:
3876 case OP_UNPACK_LOWPD:
3877 case OP_UNPACK_HIGHB:
3878 case OP_UNPACK_HIGHW:
3879 case OP_UNPACK_HIGHD:
3880 case OP_UNPACK_HIGHQ:
3881 case OP_UNPACK_HIGHPS:
3882 case OP_UNPACK_HIGHPD: {
3883 int mask [16];
3884 LLVMValueRef mask_values [16];
3885 int i, mask_size = 0;
3886 gboolean low = FALSE;
3888 switch (ins->opcode) {
3889 case OP_UNPACK_LOWB:
3890 mask_size = 16;
3891 low = TRUE;
3892 break;
3893 case OP_UNPACK_LOWW:
3894 mask_size = 8;
3895 low = TRUE;
3896 break;
3897 case OP_UNPACK_LOWD:
3898 case OP_UNPACK_LOWPS:
3899 mask_size = 4;
3900 low = TRUE;
3901 break;
3902 case OP_UNPACK_LOWQ:
3903 case OP_UNPACK_LOWPD:
3904 mask_size = 2;
3905 low = TRUE;
3906 break;
3907 case OP_UNPACK_HIGHB:
3908 mask_size = 16;
3909 break;
3910 case OP_UNPACK_HIGHW:
3911 mask_size = 8;
3912 break;
3913 case OP_UNPACK_HIGHD:
3914 case OP_UNPACK_HIGHPS:
3915 mask_size = 4;
3916 break;
3917 case OP_UNPACK_HIGHQ:
3918 case OP_UNPACK_HIGHPD:
3919 mask_size = 2;
3920 break;
3921 default:
3922 g_assert_not_reached ();
3925 if (low) {
3926 for (i = 0; i < (mask_size / 2); ++i) {
3927 mask [(i * 2)] = i;
3928 mask [(i * 2) + 1] = mask_size + i;
3930 } else {
3931 for (i = 0; i < (mask_size / 2); ++i) {
3932 mask [(i * 2)] = (mask_size / 2) + i;
3933 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3937 for (i = 0; i < mask_size; ++i)
3938 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3940 values [ins->dreg] =
3941 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3942 LLVMConstVector (mask_values, mask_size), dname);
3943 break;
3946 case OP_DUPPD: {
3947 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3948 LLVMValueRef v, val;
3950 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3951 val = LLVMConstNull (t);
3952 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3953 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3955 values [ins->dreg] = val;
3956 break;
3958 case OP_DUPPS_LOW:
3959 case OP_DUPPS_HIGH: {
3960 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3961 LLVMValueRef v1, v2, val;
3964 if (ins->opcode == OP_DUPPS_LOW) {
3965 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3966 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3967 } else {
3968 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3969 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3971 val = LLVMConstNull (t);
3972 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3973 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3974 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3975 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3977 values [ins->dreg] = val;
3978 break;
3981 #endif /* SIMD */
3983 case OP_DUMMY_USE:
3984 break;
3987 * EXCEPTION HANDLING
3989 case OP_IMPLICIT_EXCEPTION:
3990 /* This marks a place where an implicit exception can happen */
3991 if (bb->region != -1)
3992 LLVM_FAILURE (ctx, "implicit-exception");
3993 break;
3994 case OP_THROW:
3995 case OP_RETHROW: {
3996 MonoMethodSignature *throw_sig;
3997 LLVMValueRef callee, arg;
3998 gboolean rethrow = (ins->opcode == OP_RETHROW);
3999 const char *icall_name;
4001 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4002 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4004 if (!callee) {
4005 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4006 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4007 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4008 if (cfg->compile_aot) {
4009 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4010 } else {
4011 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4013 #ifdef TARGET_X86
4015 * LLVM doesn't push the exception argument, so we need a different
4016 * trampoline.
4018 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4019 #else
4020 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4021 #endif
4024 mono_memory_barrier ();
4025 if (rethrow)
4026 ctx->lmodule->rethrow = callee;
4027 else
4028 ctx->lmodule->throw = callee;
4030 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4031 emit_call (ctx, bb, &builder, callee, &arg, 1);
4032 break;
4034 case OP_CALL_HANDLER: {
4036 * We don't 'call' handlers, but instead simply branch to them.
4037 * The code generated by ENDFINALLY will branch back to us.
4039 LLVMBasicBlockRef noex_bb;
4040 GSList *bb_list;
4041 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4043 bb_list = info->call_handler_return_bbs;
4046 * Set the indicator variable for the finally clause.
4048 lhs = info->finally_ind;
4049 g_assert (lhs);
4050 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4052 /* Branch to the finally clause */
4053 LLVMBuildBr (builder, info->call_handler_target_bb);
4055 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4056 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4058 builder = ctx->builder = create_builder (ctx);
4059 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4061 bblocks [bb->block_num].end_bblock = noex_bb;
4062 break;
4064 case OP_START_HANDLER: {
4065 break;
4067 case OP_ENDFINALLY: {
4068 LLVMBasicBlockRef resume_bb;
4069 MonoBasicBlock *handler_bb;
4070 LLVMValueRef val, switch_ins, callee;
4071 GSList *bb_list;
4072 BBInfo *info;
4074 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4075 g_assert (handler_bb);
4076 info = &bblocks [handler_bb->block_num];
4077 lhs = info->finally_ind;
4078 g_assert (lhs);
4080 bb_list = info->call_handler_return_bbs;
4082 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4084 /* Load the finally variable */
4085 val = LLVMBuildLoad (builder, lhs, "");
4087 /* Reset the variable */
4088 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4090 /* Branch to either resume_bb, or to the bblocks in bb_list */
4091 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4093 * The other targets are added at the end to handle OP_CALL_HANDLER
4094 * opcodes processed later.
4096 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4098 builder = ctx->builder = create_builder (ctx);
4099 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4101 if (ctx->cfg->compile_aot) {
4102 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4103 } else {
4104 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4106 LLVMBuildCall (builder, callee, NULL, 0, "");
4108 LLVMBuildUnreachable (builder);
4109 has_terminator = TRUE;
4110 break;
4112 default: {
4113 char reason [128];
4115 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4116 LLVM_FAILURE (ctx, reason);
4117 break;
4121 /* Convert the value to the type required by phi nodes */
4122 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4123 if (!values [ins->dreg])
4124 /* vtypes */
4125 values [ins->dreg] = addresses [ins->dreg];
4126 else
4127 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4130 /* Add stores for volatile variables */
4131 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4132 emit_volatile_store (ctx, ins->dreg);
4135 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4136 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4138 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4139 LLVMBuildRetVoid (builder);
4141 if (bb == cfg->bb_entry)
4142 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4144 return;
4146 FAILURE:
4147 return;
4151 * mono_llvm_check_method_supported:
4153 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4154 * compiling a method twice.
4156 void
4157 mono_llvm_check_method_supported (MonoCompile *cfg)
4160 MonoMethodHeader *header = cfg->header;
4161 MonoExceptionClause *clause;
4162 int i;
4165 if (cfg->generic_sharing_context && !IS_LLVM_MONO_BRANCH) {
4166 /* No way to obtain location info for this/rgctx */
4167 cfg->exception_message = g_strdup ("gshared");
4168 cfg->disable_llvm = TRUE;
4171 if (cfg->method->save_lmf) {
4172 cfg->exception_message = g_strdup ("lmf");
4173 cfg->disable_llvm = TRUE;
4176 #if 0
4177 for (i = 0; i < header->num_clauses; ++i) {
4178 clause = &header->clauses [i];
4180 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4182 * FIXME: Some tests still fail with nested clauses.
4184 cfg->exception_message = g_strdup ("nested clauses");
4185 cfg->disable_llvm = TRUE;
4188 #endif
4190 /* FIXME: */
4191 if (cfg->method->dynamic) {
4192 cfg->exception_message = g_strdup ("dynamic.");
4193 cfg->disable_llvm = TRUE;
4198 * mono_llvm_emit_method:
4200 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4202 void
4203 mono_llvm_emit_method (MonoCompile *cfg)
4205 EmitContext *ctx;
4206 MonoMethodSignature *sig;
4207 MonoBasicBlock *bb;
4208 LLVMTypeRef method_type;
4209 LLVMValueRef method = NULL;
4210 char *method_name;
4211 LLVMValueRef *values;
4212 int i, max_block_num, bb_index;
4213 gboolean last = FALSE;
4214 GPtrArray *phi_values;
4215 LLVMCallInfo *linfo;
4216 GSList *l;
4217 LLVMModuleRef module;
4218 BBInfo *bblocks;
4219 GPtrArray *bblock_list;
4220 MonoMethodHeader *header;
4221 MonoExceptionClause *clause;
4222 LLVMSigInfo sinfo;
4223 char **names;
4225 /* The code below might acquire the loader lock, so use it for global locking */
4226 mono_loader_lock ();
4228 /* Used to communicate with the callbacks */
4229 TlsSetValue (current_cfg_tls_id, cfg);
4231 ctx = g_new0 (EmitContext, 1);
4232 ctx->cfg = cfg;
4233 ctx->mempool = cfg->mempool;
4236 * This maps vregs to the LLVM instruction defining them
4238 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4240 * This maps vregs for volatile variables to the LLVM instruction defining their
4241 * address.
4243 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4244 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4245 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4246 phi_values = g_ptr_array_new ();
4248 * This signals whenever the vreg was defined by a phi node with no input vars
4249 * (i.e. all its input bblocks end with NOT_REACHABLE).
4251 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4252 /* Whenever the bblock is unreachable */
4253 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4255 bblock_list = g_ptr_array_new ();
4257 ctx->values = values;
4258 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4260 if (cfg->compile_aot) {
4261 ctx->lmodule = &aot_module;
4262 method_name = mono_aot_get_method_name (cfg);
4263 cfg->llvm_method_name = g_strdup (method_name);
4264 } else {
4265 init_jit_module ();
4266 ctx->lmodule = &jit_module;
4267 method_name = mono_method_full_name (cfg->method, TRUE);
4270 module = ctx->module = ctx->lmodule->module;
4272 #if 1
4274 static int count = 0;
4275 count ++;
4277 if (getenv ("LLVM_COUNT")) {
4278 if (count == atoi (getenv ("LLVM_COUNT"))) {
4279 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4280 fflush (stdout);
4281 last = TRUE;
4283 if (count > atoi (getenv ("LLVM_COUNT")))
4284 LLVM_FAILURE (ctx, "");
4287 #endif
4289 sig = mono_method_signature (cfg->method);
4290 ctx->sig = sig;
4292 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4293 ctx->linfo = linfo;
4294 CHECK_FAILURE (ctx);
4296 if (cfg->rgctx_var) {
4297 if (IS_LLVM_MONO_BRANCH)
4298 linfo->rgctx_arg = TRUE;
4299 else
4300 LLVM_FAILURE (ctx, "rgctx arg");
4302 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4303 CHECK_FAILURE (ctx);
4306 * This maps parameter indexes in the original signature to the indexes in
4307 * the LLVM signature.
4309 ctx->pindexes = sinfo.pindexes;
4311 method = LLVMAddFunction (module, method_name, method_type);
4312 ctx->lmethod = method;
4314 #ifdef LLVM_MONO_BRANCH
4315 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4316 #endif
4317 LLVMSetLinkage (method, LLVMPrivateLinkage);
4319 LLVMAddFunctionAttr (method, LLVMUWTableAttribute);
4321 if (cfg->compile_aot) {
4322 LLVMSetLinkage (method, LLVMInternalLinkage);
4323 LLVMSetVisibility (method, LLVMHiddenVisibility);
4324 } else {
4325 LLVMSetLinkage (method, LLVMPrivateLinkage);
4328 if (cfg->method->save_lmf)
4329 LLVM_FAILURE (ctx, "lmf");
4331 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4332 LLVM_FAILURE (ctx, "pinvoke signature");
4334 header = cfg->header;
4335 for (i = 0; i < header->num_clauses; ++i) {
4336 clause = &header->clauses [i];
4337 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4338 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4341 if (linfo->rgctx_arg) {
4342 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4344 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4345 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4346 * CC_X86_64_Mono in X86CallingConv.td.
4348 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4349 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4351 if (cfg->vret_addr) {
4352 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4353 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4355 if (sig->hasthis) {
4356 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4357 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4360 names = g_new (char *, sig->param_count);
4361 mono_method_get_param_names (cfg->method, (const char **) names);
4363 for (i = 0; i < sig->param_count; ++i) {
4364 char *name;
4366 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4367 if (names [i] && names [i][0] != '\0')
4368 name = g_strdup_printf ("arg_%s", names [i]);
4369 else
4370 name = g_strdup_printf ("arg_%d", i);
4371 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4372 g_free (name);
4373 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4374 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4376 g_free (names);
4378 max_block_num = 0;
4379 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4380 max_block_num = MAX (max_block_num, bb->block_num);
4381 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4383 /* Add branches between non-consecutive bblocks */
4384 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4385 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4386 bb->next_bb != bb->last_ins->inst_false_bb) {
4388 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4389 inst->opcode = OP_BR;
4390 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4391 mono_bblock_add_inst (bb, inst);
4396 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4397 * was later optimized away, so clear these flags, and add them back for the still
4398 * present OP_LDADDR instructions.
4400 for (i = 0; i < cfg->next_vreg; ++i) {
4401 MonoInst *ins;
4403 ins = get_vreg_to_inst (cfg, i);
4404 if (ins && ins != cfg->rgctx_var)
4405 ins->flags &= ~MONO_INST_INDIRECT;
4409 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4411 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4412 MonoInst *ins;
4413 LLVMBuilderRef builder;
4414 char *dname;
4415 char dname_buf[128];
4417 builder = create_builder (ctx);
4419 for (ins = bb->code; ins; ins = ins->next) {
4420 switch (ins->opcode) {
4421 case OP_PHI:
4422 case OP_FPHI:
4423 case OP_VPHI:
4424 case OP_XPHI: {
4425 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4427 CHECK_FAILURE (ctx);
4429 if (ins->opcode == OP_VPHI) {
4430 /* Treat valuetype PHI nodes as operating on the address itself */
4431 g_assert (ins->klass);
4432 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4436 * Have to precreate these, as they can be referenced by
4437 * earlier instructions.
4439 sprintf (dname_buf, "t%d", ins->dreg);
4440 dname = dname_buf;
4441 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4443 if (ins->opcode == OP_VPHI)
4444 ctx->addresses [ins->dreg] = values [ins->dreg];
4446 g_ptr_array_add (phi_values, values [ins->dreg]);
4449 * Set the expected type of the incoming arguments since these have
4450 * to have the same type.
4452 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4453 int sreg1 = ins->inst_phi_args [i + 1];
4455 if (sreg1 != -1)
4456 ctx->vreg_types [sreg1] = phi_type;
4458 break;
4460 case OP_LDADDR:
4461 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4462 break;
4463 default:
4464 break;
4470 * Create an ordering for bblocks, use the depth first order first, then
4471 * put the exception handling bblocks last.
4473 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4474 bb = cfg->bblocks [bb_index];
4475 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4476 g_ptr_array_add (bblock_list, bb);
4477 bblocks [bb->block_num].added = TRUE;
4481 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4482 if (!bblocks [bb->block_num].added)
4483 g_ptr_array_add (bblock_list, bb);
4487 * Second pass: generate code.
4489 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4490 bb = g_ptr_array_index (bblock_list, bb_index);
4492 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4493 continue;
4495 process_bb (ctx, bb);
4496 CHECK_FAILURE (ctx);
4499 /* Add incoming phi values */
4500 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4501 GSList *l, *ins_list;
4503 ins_list = bblocks [bb->block_num].phi_nodes;
4505 for (l = ins_list; l; l = l->next) {
4506 PhiNode *node = l->data;
4507 MonoInst *phi = node->phi;
4508 int sreg1 = node->sreg;
4509 LLVMBasicBlockRef in_bb;
4511 if (sreg1 == -1)
4512 continue;
4514 in_bb = get_end_bb (ctx, node->in_bb);
4516 if (ctx->unreachable [node->in_bb->block_num])
4517 continue;
4519 g_assert (values [sreg1]);
4521 if (phi->opcode == OP_VPHI) {
4522 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4523 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4524 } else {
4525 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4526 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4531 /* Create the SWITCH statements for ENDFINALLY instructions */
4532 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4533 BBInfo *info = &bblocks [bb->block_num];
4534 GSList *l;
4535 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4536 LLVMValueRef switch_ins = l->data;
4537 GSList *bb_list = info->call_handler_return_bbs;
4539 for (i = 0; i < g_slist_length (bb_list); ++i)
4540 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4544 if (cfg->verbose_level > 1)
4545 mono_llvm_dump_value (method);
4547 mark_as_used (module, method);
4549 if (cfg->compile_aot) {
4550 /* Don't generate native code, keep the LLVM IR */
4551 if (cfg->compile_aot && cfg->verbose_level)
4552 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4554 //LLVMVerifyFunction(method, 0);
4555 } else {
4556 mono_llvm_optimize_method (method);
4558 if (cfg->verbose_level > 1)
4559 mono_llvm_dump_value (method);
4561 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4563 /* Set by emit_cb */
4564 g_assert (cfg->code_len);
4566 /* FIXME: Free the LLVM IL for the function */
4569 goto CLEANUP;
4571 FAILURE:
4573 if (method) {
4574 /* Need to add unused phi nodes as they can be referenced by other values */
4575 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4576 LLVMBuilderRef builder;
4578 builder = create_builder (ctx);
4579 LLVMPositionBuilderAtEnd (builder, phi_bb);
4581 for (i = 0; i < phi_values->len; ++i) {
4582 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4583 if (LLVMGetInstructionParent (v) == NULL)
4584 LLVMInsertIntoBuilder (builder, v);
4587 LLVMDeleteFunction (method);
4590 CLEANUP:
4591 g_free (values);
4592 g_free (ctx->addresses);
4593 g_free (ctx->vreg_types);
4594 g_free (ctx->vreg_cli_types);
4595 g_free (ctx->pindexes);
4596 g_free (ctx->is_dead);
4597 g_free (ctx->unreachable);
4598 g_ptr_array_free (phi_values, TRUE);
4599 g_free (ctx->bblocks);
4600 g_hash_table_destroy (ctx->region_to_handler);
4601 g_free (method_name);
4602 g_ptr_array_free (bblock_list, TRUE);
4604 for (l = ctx->builders; l; l = l->next) {
4605 LLVMBuilderRef builder = l->data;
4606 LLVMDisposeBuilder (builder);
4609 g_free (ctx);
4611 TlsSetValue (current_cfg_tls_id, NULL);
4613 mono_loader_unlock ();
4617 * mono_llvm_emit_call:
4619 * Same as mono_arch_emit_call () for LLVM.
4621 void
4622 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4624 MonoInst *in;
4625 MonoMethodSignature *sig;
4626 int i, n, stack_size;
4627 LLVMArgInfo *ainfo;
4629 stack_size = 0;
4631 sig = call->signature;
4632 n = sig->param_count + sig->hasthis;
4634 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4636 if (cfg->disable_llvm)
4637 return;
4639 if (sig->call_convention == MONO_CALL_VARARG) {
4640 cfg->exception_message = g_strdup ("varargs");
4641 cfg->disable_llvm = TRUE;
4644 for (i = 0; i < n; ++i) {
4645 MonoInst *ins;
4647 ainfo = call->cinfo->args + i;
4649 in = call->args [i];
4651 /* Simply remember the arguments */
4652 switch (ainfo->storage) {
4653 case LLVMArgInIReg:
4654 MONO_INST_NEW (cfg, ins, OP_MOVE);
4655 ins->dreg = mono_alloc_ireg (cfg);
4656 ins->sreg1 = in->dreg;
4657 break;
4658 case LLVMArgInFPReg:
4659 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4660 ins->dreg = mono_alloc_freg (cfg);
4661 ins->sreg1 = in->dreg;
4662 break;
4663 case LLVMArgVtypeByVal:
4664 case LLVMArgVtypeInReg:
4665 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4666 ins->dreg = mono_alloc_ireg (cfg);
4667 ins->sreg1 = in->dreg;
4668 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4669 break;
4670 default:
4671 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4672 cfg->exception_message = g_strdup ("ainfo->storage");
4673 cfg->disable_llvm = TRUE;
4674 return;
4677 if (!cfg->disable_llvm) {
4678 MONO_ADD_INS (cfg->cbb, ins);
4679 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4684 static unsigned char*
4685 alloc_cb (LLVMValueRef function, int size)
4687 MonoCompile *cfg;
4689 cfg = TlsGetValue (current_cfg_tls_id);
4691 if (cfg) {
4692 // FIXME: dynamic
4693 return mono_domain_code_reserve (cfg->domain, size);
4694 } else {
4695 return mono_domain_code_reserve (mono_domain_get (), size);
4699 static void
4700 emitted_cb (LLVMValueRef function, void *start, void *end)
4702 MonoCompile *cfg;
4704 cfg = TlsGetValue (current_cfg_tls_id);
4705 g_assert (cfg);
4706 cfg->code_len = (guint8*)end - (guint8*)start;
4709 static void
4710 exception_cb (void *data)
4712 MonoCompile *cfg;
4713 MonoJitExceptionInfo *ei;
4714 guint32 ei_len, i, j, nested_len, nindex;
4715 gpointer *type_info;
4716 int this_reg, this_offset;
4718 cfg = TlsGetValue (current_cfg_tls_id);
4719 g_assert (cfg);
4722 * data points to a DWARF FDE structure, convert it to our unwind format and
4723 * save it.
4724 * An alternative would be to save it directly, and modify our unwinder to work
4725 * with it.
4727 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);
4729 /* Count nested clauses */
4730 nested_len = 0;
4731 for (i = 0; i < ei_len; ++i) {
4732 for (j = 0; j < ei_len; ++j) {
4733 gint32 cindex1 = *(gint32*)type_info [i];
4734 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4735 gint32 cindex2 = *(gint32*)type_info [j];
4736 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4738 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4739 nested_len ++;
4744 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4745 cfg->llvm_ex_info_len = ei_len + nested_len;
4746 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4747 /* Fill the rest of the information from the type info */
4748 for (i = 0; i < ei_len; ++i) {
4749 gint32 clause_index = *(gint32*)type_info [i];
4750 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4752 cfg->llvm_ex_info [i].flags = clause->flags;
4753 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4757 * For nested clauses, the LLVM produced exception info associates the try interval with
4758 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4760 /* FIXME: These should be order with the normal clauses */
4761 nindex = ei_len;
4762 for (i = 0; i < ei_len; ++i) {
4763 for (j = 0; j < ei_len; ++j) {
4764 gint32 cindex1 = *(gint32*)type_info [i];
4765 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4766 gint32 cindex2 = *(gint32*)type_info [j];
4767 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4769 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4771 * The try interval comes from the nested clause, everything else from the
4772 * nesting clause.
4774 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4775 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4776 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4777 nindex ++;
4781 g_assert (nindex == ei_len + nested_len);
4782 cfg->llvm_this_reg = this_reg;
4783 cfg->llvm_this_offset = this_offset;
4785 /* type_info [i] is cfg mempool allocated, no need to free it */
4787 g_free (ei);
4788 g_free (type_info);
4791 static inline void
4792 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4794 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4797 static inline void
4798 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4800 LLVMTypeRef param_types [4];
4802 param_types [0] = param_type1;
4803 param_types [1] = param_type2;
4805 AddFunc (module, name, ret_type, param_types, 2);
4808 static void
4809 add_intrinsics (LLVMModuleRef module)
4811 /* Emit declarations of instrinsics */
4813 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4814 * type doesn't seem to do any locking.
4817 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4819 memset_param_count = 5;
4820 memset_func_name = "llvm.memset.p0i8.i32";
4822 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4826 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4828 memcpy_param_count = 5;
4829 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4831 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4835 LLVMTypeRef params [] = { LLVMDoubleType () };
4837 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4838 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4839 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4841 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4842 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4846 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
4848 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4849 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4850 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4851 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4852 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
4853 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
4854 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
4858 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4859 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4861 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4862 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4863 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4864 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4865 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4866 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4870 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4871 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4873 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4874 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4875 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4876 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4877 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4878 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4882 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4883 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4884 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4886 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4888 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4891 /* EH intrinsics */
4893 LLVMTypeRef arg_types [2];
4894 LLVMTypeRef ret_type;
4896 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4897 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4898 eh_selector_name = "llvm.eh.selector";
4899 ret_type = LLVMInt32Type ();
4901 LLVMAddFunction (module, eh_selector_name, LLVMFunctionType (ret_type, arg_types, 2, TRUE));
4903 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
4905 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4907 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4910 /* SSE intrinsics */
4912 LLVMTypeRef ret_type, arg_types [2];
4914 /* Binary ops */
4915 ret_type = type_to_simd_type (MONO_TYPE_I4);
4916 arg_types [0] = ret_type;
4917 arg_types [1] = ret_type;
4918 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4919 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4920 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4922 ret_type = type_to_simd_type (MONO_TYPE_I2);
4923 arg_types [0] = ret_type;
4924 arg_types [1] = ret_type;
4925 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4926 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4927 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4928 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4929 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4930 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4931 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4932 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4933 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4934 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4935 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4937 ret_type = type_to_simd_type (MONO_TYPE_I1);
4938 arg_types [0] = ret_type;
4939 arg_types [1] = ret_type;
4940 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4941 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4942 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4943 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4944 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4945 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4946 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4947 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4948 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4950 ret_type = type_to_simd_type (MONO_TYPE_I8);
4951 arg_types [0] = ret_type;
4952 arg_types [1] = ret_type;
4953 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4955 ret_type = type_to_simd_type (MONO_TYPE_R8);
4956 arg_types [0] = ret_type;
4957 arg_types [1] = ret_type;
4958 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4959 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4960 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4961 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4962 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4964 ret_type = type_to_simd_type (MONO_TYPE_R4);
4965 arg_types [0] = ret_type;
4966 arg_types [1] = ret_type;
4967 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4968 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4969 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4970 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4971 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4973 /* pack */
4974 ret_type = type_to_simd_type (MONO_TYPE_I1);
4975 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4976 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4977 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4978 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4979 ret_type = type_to_simd_type (MONO_TYPE_I2);
4980 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4981 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4982 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4983 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4985 /* cmp pd/ps */
4986 ret_type = type_to_simd_type (MONO_TYPE_R8);
4987 arg_types [0] = ret_type;
4988 arg_types [1] = ret_type;
4989 arg_types [2] = LLVMInt8Type ();
4990 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4991 ret_type = type_to_simd_type (MONO_TYPE_R4);
4992 arg_types [0] = ret_type;
4993 arg_types [1] = ret_type;
4994 arg_types [2] = LLVMInt8Type ();
4995 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4997 /* Conversion ops */
4998 ret_type = type_to_simd_type (MONO_TYPE_R8);
4999 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5000 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5001 ret_type = type_to_simd_type (MONO_TYPE_R4);
5002 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5003 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5004 ret_type = type_to_simd_type (MONO_TYPE_I4);
5005 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5006 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5007 ret_type = type_to_simd_type (MONO_TYPE_I4);
5008 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5009 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5010 ret_type = type_to_simd_type (MONO_TYPE_R4);
5011 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5012 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5013 ret_type = type_to_simd_type (MONO_TYPE_R8);
5014 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5015 AddFunc (module, "llvm.x86.sse2.cvtps2pd", 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_R8);
5019 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5020 ret_type = type_to_simd_type (MONO_TYPE_I4);
5021 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5022 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5024 /* Unary ops */
5025 ret_type = type_to_simd_type (MONO_TYPE_R8);
5026 arg_types [0] = ret_type;
5027 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5028 ret_type = type_to_simd_type (MONO_TYPE_R4);
5029 arg_types [0] = ret_type;
5030 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5031 ret_type = type_to_simd_type (MONO_TYPE_R4);
5032 arg_types [0] = ret_type;
5033 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5034 ret_type = type_to_simd_type (MONO_TYPE_R4);
5035 arg_types [0] = ret_type;
5036 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5038 /* shifts */
5039 ret_type = type_to_simd_type (MONO_TYPE_I2);
5040 arg_types [0] = ret_type;
5041 arg_types [1] = LLVMInt32Type ();
5042 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5043 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5044 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5045 ret_type = type_to_simd_type (MONO_TYPE_I4);
5046 arg_types [0] = ret_type;
5047 arg_types [1] = LLVMInt32Type ();
5048 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5049 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5050 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5051 ret_type = type_to_simd_type (MONO_TYPE_I8);
5052 arg_types [0] = ret_type;
5053 arg_types [1] = LLVMInt32Type ();
5054 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5055 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5057 /* pmovmskb */
5058 ret_type = LLVMInt32Type ();
5059 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5060 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5063 if (IS_LLVM_MONO_BRANCH) {
5064 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5067 /* Load/Store intrinsics */
5068 if (IS_LLVM_MONO_BRANCH) {
5069 LLVMTypeRef arg_types [5];
5070 int i;
5071 char name [128];
5073 for (i = 1; i <= 8; i *= 2) {
5074 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5075 arg_types [1] = LLVMInt32Type ();
5076 arg_types [2] = LLVMInt1Type ();
5077 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5078 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5080 arg_types [0] = LLVMIntType (i * 8);
5081 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5082 arg_types [2] = LLVMInt32Type ();
5083 arg_types [3] = LLVMInt1Type ();
5084 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5085 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5090 void
5091 mono_llvm_init (void)
5093 current_cfg_tls_id = TlsAlloc ();
5096 static void
5097 init_jit_module (void)
5099 MonoJitICallInfo *info;
5101 if (jit_module_inited)
5102 return;
5104 mono_loader_lock ();
5106 if (jit_module_inited) {
5107 mono_loader_unlock ();
5108 return;
5111 jit_module.module = LLVMModuleCreateWithName ("mono");
5113 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5115 add_intrinsics (jit_module.module);
5117 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5119 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5120 g_assert (info);
5121 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5123 jit_module_inited = TRUE;
5125 mono_loader_unlock ();
5128 void
5129 mono_llvm_cleanup (void)
5131 if (ee)
5132 mono_llvm_dispose_ee (ee);
5134 if (jit_module.llvm_types)
5135 g_hash_table_destroy (jit_module.llvm_types);
5137 if (aot_module.module)
5138 LLVMDisposeModule (aot_module.module);
5140 LLVMContextDispose (LLVMGetGlobalContext ());
5143 void
5144 mono_llvm_create_aot_module (const char *got_symbol)
5146 /* Delete previous module */
5147 if (aot_module.plt_entries)
5148 g_hash_table_destroy (aot_module.plt_entries);
5149 if (aot_module.module)
5150 LLVMDisposeModule (aot_module.module);
5152 memset (&aot_module, 0, sizeof (aot_module));
5154 aot_module.module = LLVMModuleCreateWithName ("aot");
5155 aot_module.got_symbol = got_symbol;
5157 add_intrinsics (aot_module.module);
5159 /* Add GOT */
5161 * We couldn't compute the type of the LLVM global representing the got because
5162 * its size is only known after all the methods have been emitted. So create
5163 * a dummy variable, and replace all uses it with the real got variable when
5164 * its size is known in mono_llvm_emit_aot_module ().
5167 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5169 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5170 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5173 /* Add a dummy personality function */
5175 LLVMBasicBlockRef lbb;
5176 LLVMBuilderRef lbuilder;
5177 LLVMValueRef personality;
5179 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5180 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5181 lbb = LLVMAppendBasicBlock (personality, "BB0");
5182 lbuilder = LLVMCreateBuilder ();
5183 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5184 LLVMBuildRetVoid (lbuilder);
5187 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5188 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5192 * Emit the aot module into the LLVM bitcode file FILENAME.
5194 void
5195 mono_llvm_emit_aot_module (const char *filename, int got_size)
5197 LLVMTypeRef got_type;
5198 LLVMValueRef real_got;
5201 * Create the real got variable and replace all uses of the dummy variable with
5202 * the real one.
5204 got_type = LLVMArrayType (IntPtrType (), got_size);
5205 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5206 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5207 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5209 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5211 mark_as_used (aot_module.module, real_got);
5213 /* Delete the dummy got so it doesn't become a global */
5214 LLVMDeleteGlobal (aot_module.got_var);
5216 #if 0
5218 char *verifier_err;
5220 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5221 g_assert_not_reached ();
5224 #endif
5226 LLVMWriteBitcodeToFile (aot_module.module, filename);
5230 DESIGN:
5231 - Emit LLVM IR from the mono IR using the LLVM C API.
5232 - The original arch specific code remains, so we can fall back to it if we run
5233 into something we can't handle.
5237 A partial list of issues:
5238 - Handling of opcodes which can throw exceptions.
5240 In the mono JIT, these are implemented using code like this:
5241 method:
5242 <compare>
5243 throw_pos:
5244 b<cond> ex_label
5245 <rest of code>
5246 ex_label:
5247 push throw_pos - method
5248 call <exception trampoline>
5250 The problematic part is push throw_pos - method, which cannot be represented
5251 in the LLVM IR, since it does not support label values.
5252 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5253 be implemented in JIT mode ?
5254 -> a possible but slower implementation would use the normal exception
5255 throwing code but it would need to control the placement of the throw code
5256 (it needs to be exactly after the compare+branch).
5257 -> perhaps add a PC offset intrinsics ?
5259 - efficient implementation of .ovf opcodes.
5261 These are currently implemented as:
5262 <ins which sets the condition codes>
5263 b<cond> ex_label
5265 Some overflow opcodes are now supported by LLVM SVN.
5267 - exception handling, unwinding.
5268 - SSA is disabled for methods with exception handlers
5269 - How to obtain unwind info for LLVM compiled methods ?
5270 -> this is now solved by converting the unwind info generated by LLVM
5271 into our format.
5272 - LLVM uses the c++ exception handling framework, while we use our home grown
5273 code, and couldn't use the c++ one:
5274 - its not supported under VC++, other exotic platforms.
5275 - it might be impossible to support filter clauses with it.
5277 - trampolines.
5279 The trampolines need a predictable call sequence, since they need to disasm
5280 the calling code to obtain register numbers / offsets.
5282 LLVM currently generates this code in non-JIT mode:
5283 mov -0x98(%rax),%eax
5284 callq *%rax
5285 Here, the vtable pointer is lost.
5286 -> solution: use one vtable trampoline per class.
5288 - passing/receiving the IMT pointer/RGCTX.
5289 -> solution: pass them as normal arguments ?
5291 - argument passing.
5293 LLVM does not allow the specification of argument registers etc. This means
5294 that all calls are made according to the platform ABI.
5296 - passing/receiving vtypes.
5298 Vtypes passed/received in registers are handled by the front end by using
5299 a signature with scalar arguments, and loading the parts of the vtype into those
5300 arguments.
5302 Vtypes passed on the stack are handled using the 'byval' attribute.
5304 - ldaddr.
5306 Supported though alloca, we need to emit the load/store code.
5308 - types.
5310 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5311 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5312 This is made easier because the IR is already in SSA form.
5313 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5314 types are frequently used incorrectly.
5318 AOT SUPPORT:
5319 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5320 append the AOT data structures to that file. For methods which cannot be
5321 handled by LLVM, the normal JIT compiled versions are used.
5324 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5325 * - each bblock should end with a branch
5326 * - setting the return value, making cfg->ret non-volatile
5327 * - avoid some transformations in the JIT which make it harder for us to generate
5328 * code.
5329 * - use pointer types to help optimizations.