Update spec file to 4.5 profile
[mono-project.git] / mono / mini / mini-llvm.c
blobdae43f06b77a75ebf602244ca16f36f29dd4004f
1 /*
2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 */
8 #include "mini.h"
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
13 #ifndef __STDC_LIMIT_MACROS
14 #define __STDC_LIMIT_MACROS
15 #endif
16 #ifndef __STDC_CONSTANT_MACROS
17 #define __STDC_CONSTANT_MACROS
18 #endif
20 #include "llvm-c/Core.h"
21 #include "llvm-c/ExecutionEngine.h"
22 #include "llvm-c/BitWriter.h"
23 #include "llvm-c/Analysis.h"
25 #include "mini-llvm-cpp.h"
28 * Information associated by mono with LLVM modules.
30 typedef struct {
31 LLVMModuleRef module;
32 LLVMValueRef throw, rethrow, throw_corlib_exception;
33 GHashTable *llvm_types;
34 LLVMValueRef got_var;
35 const char *got_symbol;
36 GHashTable *plt_entries;
37 } MonoLLVMModule;
40 * Information associated by the backend with mono basic blocks.
42 typedef struct {
43 LLVMBasicBlockRef bblock, end_bblock;
44 LLVMValueRef finally_ind;
45 gboolean added, invoke_target;
46 /*
47 * If this bblock is the start of a finally clause, this is a list of bblocks it
48 * needs to branch to in ENDFINALLY.
50 GSList *call_handler_return_bbs;
52 * If this bblock is the start of a finally clause, this is the bblock that
53 * CALL_HANDLER needs to branch to.
55 LLVMBasicBlockRef call_handler_target_bb;
56 /* The list of switch statements generated by ENDFINALLY instructions */
57 GSList *endfinally_switch_ins_list;
58 GSList *phi_nodes;
59 } BBInfo;
62 * Structure containing emit state
64 typedef struct {
65 MonoMemPool *mempool;
67 /* Maps method names to the corresponding LLVMValueRef */
68 GHashTable *emitted_method_decls;
70 MonoCompile *cfg;
71 LLVMValueRef lmethod;
72 MonoLLVMModule *lmodule;
73 LLVMModuleRef module;
74 BBInfo *bblocks;
75 int sindex, default_index, ex_index;
76 LLVMBuilderRef builder;
77 LLVMValueRef *values, *addresses;
78 MonoType **vreg_cli_types;
79 LLVMCallInfo *linfo;
80 MonoMethodSignature *sig;
81 GSList *builders;
82 GHashTable *region_to_handler;
83 LLVMBuilderRef alloca_builder;
84 LLVMValueRef last_alloca;
85 LLVMValueRef rgctx_arg;
86 LLVMTypeRef *vreg_types;
87 gboolean *is_dead;
88 gboolean *unreachable;
89 int *pindexes;
91 char temp_name [32];
92 } EmitContext;
94 typedef struct {
95 MonoBasicBlock *bb;
96 MonoInst *phi;
97 MonoBasicBlock *in_bb;
98 int sreg;
99 } PhiNode;
102 * Instruction metadata
103 * This is the same as ins_info, but LREG != IREG.
105 #ifdef MINI_OP
106 #undef MINI_OP
107 #endif
108 #ifdef MINI_OP3
109 #undef MINI_OP3
110 #endif
111 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
112 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
113 #define NONE ' '
114 #define IREG 'i'
115 #define FREG 'f'
116 #define VREG 'v'
117 #define XREG 'x'
118 #define LREG 'l'
119 /* keep in sync with the enum in mini.h */
120 const char
121 llvm_ins_info[] = {
122 #include "mini-ops.h"
124 #undef MINI_OP
125 #undef MINI_OP3
127 #if SIZEOF_VOID_P == 4
128 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
129 #else
130 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
131 #endif
133 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
135 #if 0
136 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
137 #else
138 #define TRACE_FAILURE(msg)
139 #endif
141 #ifdef TARGET_X86
142 #define IS_TARGET_X86 1
143 #else
144 #define IS_TARGET_X86 0
145 #endif
147 #define LLVM_FAILURE(ctx, reason) do { \
148 TRACE_FAILURE (reason); \
149 (ctx)->cfg->exception_message = g_strdup (reason); \
150 (ctx)->cfg->disable_llvm = TRUE; \
151 goto FAILURE; \
152 } while (0)
154 #define CHECK_FAILURE(ctx) do { \
155 if ((ctx)->cfg->disable_llvm) \
156 goto FAILURE; \
157 } while (0)
159 static LLVMIntPredicate cond_to_llvm_cond [] = {
160 LLVMIntEQ,
161 LLVMIntNE,
162 LLVMIntSLE,
163 LLVMIntSGE,
164 LLVMIntSLT,
165 LLVMIntSGT,
166 LLVMIntULE,
167 LLVMIntUGE,
168 LLVMIntULT,
169 LLVMIntUGT,
172 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
173 LLVMRealOEQ,
174 LLVMRealUNE,
175 LLVMRealOLE,
176 LLVMRealOGE,
177 LLVMRealOLT,
178 LLVMRealOGT,
179 LLVMRealULE,
180 LLVMRealUGE,
181 LLVMRealULT,
182 LLVMRealUGT,
185 static LLVMExecutionEngineRef ee;
186 static MonoNativeTlsKey current_cfg_tls_id;
188 static MonoLLVMModule jit_module, aot_module;
189 static gboolean jit_module_inited;
190 static int memset_param_count, memcpy_param_count;
191 static const char *memset_func_name;
192 static const char *memcpy_func_name;
194 static void init_jit_module (void);
197 * IntPtrType:
199 * The LLVM type with width == sizeof (gpointer)
201 static LLVMTypeRef
202 IntPtrType (void)
204 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
208 * get_vtype_size:
210 * Return the size of the LLVM representation of the vtype T.
212 static guint32
213 get_vtype_size (MonoType *t)
215 int size;
217 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
219 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
220 size ++;
222 return size;
226 * simd_class_to_llvm_type:
228 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
230 static LLVMTypeRef
231 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
233 if (!strcmp (klass->name, "Vector2d")) {
234 return LLVMVectorType (LLVMDoubleType (), 2);
235 } else if (!strcmp (klass->name, "Vector2l")) {
236 return LLVMVectorType (LLVMInt64Type (), 2);
237 } else if (!strcmp (klass->name, "Vector2ul")) {
238 return LLVMVectorType (LLVMInt64Type (), 2);
239 } else if (!strcmp (klass->name, "Vector4i")) {
240 return LLVMVectorType (LLVMInt32Type (), 4);
241 } else if (!strcmp (klass->name, "Vector4ui")) {
242 return LLVMVectorType (LLVMInt32Type (), 4);
243 } else if (!strcmp (klass->name, "Vector4f")) {
244 return LLVMVectorType (LLVMFloatType (), 4);
245 } else if (!strcmp (klass->name, "Vector8s")) {
246 return LLVMVectorType (LLVMInt16Type (), 8);
247 } else if (!strcmp (klass->name, "Vector8us")) {
248 return LLVMVectorType (LLVMInt16Type (), 8);
249 } else if (!strcmp (klass->name, "Vector16sb")) {
250 return LLVMVectorType (LLVMInt8Type (), 16);
251 } else if (!strcmp (klass->name, "Vector16b")) {
252 return LLVMVectorType (LLVMInt8Type (), 16);
253 } else {
254 printf ("%s\n", klass->name);
255 NOT_IMPLEMENTED;
256 return NULL;
260 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
261 static inline G_GNUC_UNUSED LLVMTypeRef
262 type_to_simd_type (int type)
264 switch (type) {
265 case MONO_TYPE_I1:
266 return LLVMVectorType (LLVMInt8Type (), 16);
267 case MONO_TYPE_I2:
268 return LLVMVectorType (LLVMInt16Type (), 8);
269 case MONO_TYPE_I4:
270 return LLVMVectorType (LLVMInt32Type (), 4);
271 case MONO_TYPE_I8:
272 return LLVMVectorType (LLVMInt64Type (), 2);
273 case MONO_TYPE_R8:
274 return LLVMVectorType (LLVMDoubleType (), 2);
275 case MONO_TYPE_R4:
276 return LLVMVectorType (LLVMFloatType (), 4);
277 default:
278 g_assert_not_reached ();
279 return NULL;
284 * type_to_llvm_type:
286 * Return the LLVM type corresponding to T.
288 static LLVMTypeRef
289 type_to_llvm_type (EmitContext *ctx, MonoType *t)
291 if (t->byref)
292 return LLVMPointerType (LLVMInt8Type (), 0);
293 switch (t->type) {
294 case MONO_TYPE_VOID:
295 return LLVMVoidType ();
296 case MONO_TYPE_I1:
297 return LLVMInt8Type ();
298 case MONO_TYPE_I2:
299 return LLVMInt16Type ();
300 case MONO_TYPE_I4:
301 return LLVMInt32Type ();
302 case MONO_TYPE_U1:
303 return LLVMInt8Type ();
304 case MONO_TYPE_U2:
305 return LLVMInt16Type ();
306 case MONO_TYPE_U4:
307 return LLVMInt32Type ();
308 case MONO_TYPE_BOOLEAN:
309 return LLVMInt8Type ();
310 case MONO_TYPE_I8:
311 case MONO_TYPE_U8:
312 return LLVMInt64Type ();
313 case MONO_TYPE_CHAR:
314 return LLVMInt16Type ();
315 case MONO_TYPE_R4:
316 return LLVMFloatType ();
317 case MONO_TYPE_R8:
318 return LLVMDoubleType ();
319 case MONO_TYPE_I:
320 case MONO_TYPE_U:
321 return IntPtrType ();
322 case MONO_TYPE_OBJECT:
323 case MONO_TYPE_CLASS:
324 case MONO_TYPE_ARRAY:
325 case MONO_TYPE_SZARRAY:
326 case MONO_TYPE_STRING:
327 case MONO_TYPE_PTR:
328 return IntPtrType ();
329 case MONO_TYPE_VAR:
330 case MONO_TYPE_MVAR:
331 /* Because of generic sharing */
332 return IntPtrType ();
333 case MONO_TYPE_GENERICINST:
334 if (!mono_type_generic_inst_is_valuetype (t))
335 return IntPtrType ();
336 /* Fall through */
337 case MONO_TYPE_VALUETYPE:
338 case MONO_TYPE_TYPEDBYREF: {
339 MonoClass *klass;
340 LLVMTypeRef ltype;
342 klass = mono_class_from_mono_type (t);
344 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
345 return simd_class_to_llvm_type (ctx, klass);
347 if (klass->enumtype)
348 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
349 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
350 if (!ltype) {
351 int i, size;
352 LLVMTypeRef *eltypes;
353 char *name;
355 size = get_vtype_size (t);
357 eltypes = g_new (LLVMTypeRef, size);
358 for (i = 0; i < size; ++i)
359 eltypes [i] = LLVMInt8Type ();
361 name = mono_type_full_name (&klass->byval_arg);
362 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
363 LLVMStructSetBody (ltype, eltypes, size, FALSE);
364 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
365 g_free (eltypes);
367 return ltype;
370 default:
371 printf ("X: %d\n", t->type);
372 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
373 ctx->cfg->disable_llvm = TRUE;
374 return NULL;
379 * type_is_unsigned:
381 * Return whenever T is an unsigned int type.
383 static gboolean
384 type_is_unsigned (EmitContext *ctx, MonoType *t)
386 if (t->byref)
387 return FALSE;
388 switch (t->type) {
389 case MONO_TYPE_U1:
390 case MONO_TYPE_U2:
391 case MONO_TYPE_U4:
392 case MONO_TYPE_U8:
393 return TRUE;
394 default:
395 return FALSE;
400 * type_to_llvm_arg_type:
402 * Same as type_to_llvm_type, but treat i8/i16 as i32.
404 static LLVMTypeRef
405 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
407 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
409 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
411 * LLVM generates code which only sets the lower bits, while JITted
412 * code expects all the bits to be set.
414 ptype = LLVMInt32Type ();
417 return ptype;
421 * llvm_type_to_stack_type:
423 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
424 * on the IL stack.
426 static G_GNUC_UNUSED LLVMTypeRef
427 llvm_type_to_stack_type (LLVMTypeRef type)
429 if (type == NULL)
430 return NULL;
431 if (type == LLVMInt8Type ())
432 return LLVMInt32Type ();
433 else if (type == LLVMInt16Type ())
434 return LLVMInt32Type ();
435 else if (type == LLVMFloatType ())
436 return LLVMDoubleType ();
437 else
438 return type;
442 * regtype_to_llvm_type:
444 * Return the LLVM type corresponding to the regtype C used in instruction
445 * descriptions.
447 static LLVMTypeRef
448 regtype_to_llvm_type (char c)
450 switch (c) {
451 case 'i':
452 return LLVMInt32Type ();
453 case 'l':
454 return LLVMInt64Type ();
455 case 'f':
456 return LLVMDoubleType ();
457 default:
458 return NULL;
463 * op_to_llvm_type:
465 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
467 static LLVMTypeRef
468 op_to_llvm_type (int opcode)
470 switch (opcode) {
471 case OP_ICONV_TO_I1:
472 case OP_LCONV_TO_I1:
473 return LLVMInt8Type ();
474 case OP_ICONV_TO_U1:
475 case OP_LCONV_TO_U1:
476 return LLVMInt8Type ();
477 case OP_ICONV_TO_I2:
478 case OP_LCONV_TO_I2:
479 return LLVMInt16Type ();
480 case OP_ICONV_TO_U2:
481 case OP_LCONV_TO_U2:
482 return LLVMInt16Type ();
483 case OP_ICONV_TO_I4:
484 case OP_LCONV_TO_I4:
485 return LLVMInt32Type ();
486 case OP_ICONV_TO_U4:
487 case OP_LCONV_TO_U4:
488 return LLVMInt32Type ();
489 case OP_ICONV_TO_I8:
490 return LLVMInt64Type ();
491 case OP_ICONV_TO_R4:
492 return LLVMFloatType ();
493 case OP_ICONV_TO_R8:
494 return LLVMDoubleType ();
495 case OP_ICONV_TO_U8:
496 return LLVMInt64Type ();
497 case OP_FCONV_TO_I4:
498 return LLVMInt32Type ();
499 case OP_FCONV_TO_I8:
500 return LLVMInt64Type ();
501 case OP_FCONV_TO_I1:
502 case OP_FCONV_TO_U1:
503 return LLVMInt8Type ();
504 case OP_FCONV_TO_I2:
505 case OP_FCONV_TO_U2:
506 return LLVMInt16Type ();
507 case OP_FCONV_TO_I:
508 case OP_FCONV_TO_U:
509 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
510 case OP_IADD_OVF:
511 case OP_IADD_OVF_UN:
512 case OP_ISUB_OVF:
513 case OP_ISUB_OVF_UN:
514 case OP_IMUL_OVF:
515 case OP_IMUL_OVF_UN:
516 return LLVMInt32Type ();
517 case OP_LADD_OVF:
518 case OP_LADD_OVF_UN:
519 case OP_LSUB_OVF:
520 case OP_LSUB_OVF_UN:
521 case OP_LMUL_OVF:
522 case OP_LMUL_OVF_UN:
523 return LLVMInt64Type ();
524 default:
525 printf ("%s\n", mono_inst_name (opcode));
526 g_assert_not_reached ();
527 return NULL;
532 * load_store_to_llvm_type:
534 * Return the size/sign/zero extension corresponding to the load/store opcode
535 * OPCODE.
537 static LLVMTypeRef
538 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
540 *sext = FALSE;
541 *zext = FALSE;
543 switch (opcode) {
544 case OP_LOADI1_MEMBASE:
545 case OP_STOREI1_MEMBASE_REG:
546 case OP_STOREI1_MEMBASE_IMM:
547 *size = 1;
548 *sext = TRUE;
549 return LLVMInt8Type ();
550 case OP_LOADU1_MEMBASE:
551 case OP_LOADU1_MEM:
552 *size = 1;
553 *zext = TRUE;
554 return LLVMInt8Type ();
555 case OP_LOADI2_MEMBASE:
556 case OP_STOREI2_MEMBASE_REG:
557 case OP_STOREI2_MEMBASE_IMM:
558 *size = 2;
559 *sext = TRUE;
560 return LLVMInt16Type ();
561 case OP_LOADU2_MEMBASE:
562 case OP_LOADU2_MEM:
563 *size = 2;
564 *zext = TRUE;
565 return LLVMInt16Type ();
566 case OP_LOADI4_MEMBASE:
567 case OP_LOADU4_MEMBASE:
568 case OP_LOADI4_MEM:
569 case OP_LOADU4_MEM:
570 case OP_STOREI4_MEMBASE_REG:
571 case OP_STOREI4_MEMBASE_IMM:
572 *size = 4;
573 return LLVMInt32Type ();
574 case OP_LOADI8_MEMBASE:
575 case OP_LOADI8_MEM:
576 case OP_STOREI8_MEMBASE_REG:
577 case OP_STOREI8_MEMBASE_IMM:
578 *size = 8;
579 return LLVMInt64Type ();
580 case OP_LOADR4_MEMBASE:
581 case OP_STORER4_MEMBASE_REG:
582 *size = 4;
583 return LLVMFloatType ();
584 case OP_LOADR8_MEMBASE:
585 case OP_STORER8_MEMBASE_REG:
586 *size = 8;
587 return LLVMDoubleType ();
588 case OP_LOAD_MEMBASE:
589 case OP_LOAD_MEM:
590 case OP_STORE_MEMBASE_REG:
591 case OP_STORE_MEMBASE_IMM:
592 *size = sizeof (gpointer);
593 return IntPtrType ();
594 default:
595 g_assert_not_reached ();
596 return NULL;
601 * ovf_op_to_intrins:
603 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
605 static const char*
606 ovf_op_to_intrins (int opcode)
608 switch (opcode) {
609 case OP_IADD_OVF:
610 return "llvm.sadd.with.overflow.i32";
611 case OP_IADD_OVF_UN:
612 return "llvm.uadd.with.overflow.i32";
613 case OP_ISUB_OVF:
614 return "llvm.ssub.with.overflow.i32";
615 case OP_ISUB_OVF_UN:
616 return "llvm.usub.with.overflow.i32";
617 case OP_IMUL_OVF:
618 return "llvm.smul.with.overflow.i32";
619 case OP_IMUL_OVF_UN:
620 return "llvm.umul.with.overflow.i32";
621 case OP_LADD_OVF:
622 return "llvm.sadd.with.overflow.i64";
623 case OP_LADD_OVF_UN:
624 return "llvm.uadd.with.overflow.i64";
625 case OP_LSUB_OVF:
626 return "llvm.ssub.with.overflow.i64";
627 case OP_LSUB_OVF_UN:
628 return "llvm.usub.with.overflow.i64";
629 case OP_LMUL_OVF:
630 return "llvm.smul.with.overflow.i64";
631 case OP_LMUL_OVF_UN:
632 return "llvm.umul.with.overflow.i64";
633 default:
634 g_assert_not_reached ();
635 return NULL;
639 static const char*
640 simd_op_to_intrins (int opcode)
642 switch (opcode) {
643 #if defined(TARGET_X86) || defined(TARGET_AMD64)
644 case OP_MINPD:
645 return "llvm.x86.sse2.min.pd";
646 case OP_MINPS:
647 return "llvm.x86.sse.min.ps";
648 case OP_PMIND_UN:
649 return "llvm.x86.sse41.pminud";
650 case OP_PMINW_UN:
651 return "llvm.x86.sse41.pminuw";
652 case OP_PMINB_UN:
653 return "llvm.x86.sse2.pminu.b";
654 case OP_PMINW:
655 return "llvm.x86.sse2.pmins.w";
656 case OP_MAXPD:
657 return "llvm.x86.sse2.max.pd";
658 case OP_MAXPS:
659 return "llvm.x86.sse.max.ps";
660 case OP_HADDPD:
661 return "llvm.x86.sse3.hadd.pd";
662 case OP_HADDPS:
663 return "llvm.x86.sse3.hadd.ps";
664 case OP_HSUBPD:
665 return "llvm.x86.sse3.hsub.pd";
666 case OP_HSUBPS:
667 return "llvm.x86.sse3.hsub.ps";
668 case OP_PMAXD_UN:
669 return "llvm.x86.sse41.pmaxud";
670 case OP_PMAXW_UN:
671 return "llvm.x86.sse41.pmaxuw";
672 case OP_PMAXB_UN:
673 return "llvm.x86.sse2.pmaxu.b";
674 case OP_ADDSUBPS:
675 return "llvm.x86.sse3.addsub.ps";
676 case OP_ADDSUBPD:
677 return "llvm.x86.sse3.addsub.pd";
678 case OP_EXTRACT_MASK:
679 return "llvm.x86.sse2.pmovmskb.128";
680 case OP_PSHRW:
681 case OP_PSHRW_REG:
682 return "llvm.x86.sse2.psrli.w";
683 case OP_PSHRD:
684 case OP_PSHRD_REG:
685 return "llvm.x86.sse2.psrli.d";
686 case OP_PSHRQ:
687 case OP_PSHRQ_REG:
688 return "llvm.x86.sse2.psrli.q";
689 case OP_PSHLW:
690 case OP_PSHLW_REG:
691 return "llvm.x86.sse2.pslli.w";
692 case OP_PSHLD:
693 case OP_PSHLD_REG:
694 return "llvm.x86.sse2.pslli.d";
695 case OP_PSHLQ:
696 case OP_PSHLQ_REG:
697 return "llvm.x86.sse2.pslli.q";
698 case OP_PSARW:
699 case OP_PSARW_REG:
700 return "llvm.x86.sse2.psrai.w";
701 case OP_PSARD:
702 case OP_PSARD_REG:
703 return "llvm.x86.sse2.psrai.d";
704 case OP_PADDB_SAT:
705 return "llvm.x86.sse2.padds.b";
706 case OP_PADDW_SAT:
707 return "llvm.x86.sse2.padds.w";
708 case OP_PSUBB_SAT:
709 return "llvm.x86.sse2.psubs.b";
710 case OP_PSUBW_SAT:
711 return "llvm.x86.sse2.psubs.w";
712 case OP_PADDB_SAT_UN:
713 return "llvm.x86.sse2.paddus.b";
714 case OP_PADDW_SAT_UN:
715 return "llvm.x86.sse2.paddus.w";
716 case OP_PSUBB_SAT_UN:
717 return "llvm.x86.sse2.psubus.b";
718 case OP_PSUBW_SAT_UN:
719 return "llvm.x86.sse2.psubus.w";
720 case OP_PAVGB_UN:
721 return "llvm.x86.sse2.pavg.b";
722 case OP_PAVGW_UN:
723 return "llvm.x86.sse2.pavg.w";
724 case OP_SQRTPS:
725 return "llvm.x86.sse.sqrt.ps";
726 case OP_SQRTPD:
727 return "llvm.x86.sse2.sqrt.pd";
728 case OP_RSQRTPS:
729 return "llvm.x86.sse.rsqrt.ps";
730 case OP_RCPPS:
731 return "llvm.x86.sse.rcp.ps";
732 case OP_PCMPEQB:
733 return "llvm.x86.sse2.pcmpeq.b";
734 case OP_PCMPEQW:
735 return "llvm.x86.sse2.pcmpeq.w";
736 case OP_PCMPEQD:
737 return "llvm.x86.sse2.pcmpeq.d";
738 case OP_PCMPEQQ:
739 return "llvm.x86.sse41.pcmpeqq";
740 case OP_PCMPGTB:
741 return "llvm.x86.sse2.pcmpgt.b";
742 case OP_CVTDQ2PD:
743 return "llvm.x86.sse2.cvtdq2pd";
744 case OP_CVTDQ2PS:
745 return "llvm.x86.sse2.cvtdq2ps";
746 case OP_CVTPD2DQ:
747 return "llvm.x86.sse2.cvtpd2dq";
748 case OP_CVTPS2DQ:
749 return "llvm.x86.sse2.cvtps2dq";
750 case OP_CVTPD2PS:
751 return "llvm.x86.sse2.cvtpd2ps";
752 case OP_CVTPS2PD:
753 return "llvm.x86.sse2.cvtps2pd";
754 case OP_CVTTPD2DQ:
755 return "llvm.x86.sse2.cvttpd2dq";
756 case OP_CVTTPS2DQ:
757 return "llvm.x86.sse2.cvttps2dq";
758 case OP_COMPPS:
759 return "llvm.x86.sse.cmp.ps";
760 case OP_COMPPD:
761 return "llvm.x86.sse2.cmp.pd";
762 case OP_PACKW:
763 return "llvm.x86.sse2.packsswb.128";
764 case OP_PACKD:
765 return "llvm.x86.sse2.packssdw.128";
766 case OP_PACKW_UN:
767 return "llvm.x86.sse2.packuswb.128";
768 case OP_PACKD_UN:
769 return "llvm.x86.sse41.packusdw";
770 case OP_PMULW_HIGH:
771 return "llvm.x86.sse2.pmulh.w";
772 case OP_PMULW_HIGH_UN:
773 return "llvm.x86.sse2.pmulhu.w";
774 #endif
775 default:
776 g_assert_not_reached ();
777 return NULL;
781 static LLVMTypeRef
782 simd_op_to_llvm_type (int opcode)
784 #if defined(TARGET_X86) || defined(TARGET_AMD64)
785 switch (opcode) {
786 case OP_EXTRACT_R8:
787 case OP_EXPAND_R8:
788 return type_to_simd_type (MONO_TYPE_R8);
789 case OP_EXTRACT_I8:
790 case OP_EXPAND_I8:
791 return type_to_simd_type (MONO_TYPE_I8);
792 case OP_EXTRACT_I4:
793 case OP_EXPAND_I4:
794 return type_to_simd_type (MONO_TYPE_I4);
795 case OP_EXTRACT_I2:
796 case OP_EXTRACT_U2:
797 case OP_EXTRACTX_U2:
798 case OP_EXPAND_I2:
799 return type_to_simd_type (MONO_TYPE_I2);
800 case OP_EXTRACT_I1:
801 case OP_EXTRACT_U1:
802 case OP_EXPAND_I1:
803 return type_to_simd_type (MONO_TYPE_I1);
804 case OP_EXPAND_R4:
805 return type_to_simd_type (MONO_TYPE_R4);
806 case OP_CVTDQ2PD:
807 case OP_CVTDQ2PS:
808 return type_to_simd_type (MONO_TYPE_I4);
809 case OP_CVTPD2DQ:
810 case OP_CVTPD2PS:
811 case OP_CVTTPD2DQ:
812 return type_to_simd_type (MONO_TYPE_R8);
813 case OP_CVTPS2DQ:
814 case OP_CVTPS2PD:
815 case OP_CVTTPS2DQ:
816 return type_to_simd_type (MONO_TYPE_R4);
817 case OP_EXTRACT_MASK:
818 return type_to_simd_type (MONO_TYPE_I1);
819 case OP_SQRTPS:
820 case OP_RSQRTPS:
821 case OP_RCPPS:
822 case OP_DUPPS_LOW:
823 case OP_DUPPS_HIGH:
824 return type_to_simd_type (MONO_TYPE_R4);
825 case OP_SQRTPD:
826 case OP_DUPPD:
827 return type_to_simd_type (MONO_TYPE_R8);
828 default:
829 g_assert_not_reached ();
830 return NULL;
832 #else
833 return NULL;
834 #endif
838 * get_bb:
840 * Return the LLVM basic block corresponding to BB.
842 static LLVMBasicBlockRef
843 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
845 char bb_name [128];
847 if (ctx->bblocks [bb->block_num].bblock == NULL) {
848 if (bb->flags & BB_EXCEPTION_HANDLER) {
849 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
850 sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
851 } else {
852 sprintf (bb_name, "BB%d", bb->block_num);
855 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
856 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
859 return ctx->bblocks [bb->block_num].bblock;
863 * get_end_bb:
865 * Return the last LLVM bblock corresponding to BB.
866 * This might not be equal to the bb returned by get_bb () since we need to generate
867 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
869 static LLVMBasicBlockRef
870 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
872 get_bb (ctx, bb);
873 return ctx->bblocks [bb->block_num].end_bblock;
876 static LLVMBasicBlockRef
877 gen_bb (EmitContext *ctx, const char *prefix)
879 char bb_name [128];
881 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
882 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
886 * resolve_patch:
888 * Return the target of the patch identified by TYPE and TARGET.
890 static gpointer
891 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
893 MonoJumpInfo ji;
895 memset (&ji, 0, sizeof (ji));
896 ji.type = type;
897 ji.data.target = target;
899 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
903 * convert_full:
905 * Emit code to convert the LLVM value V to DTYPE.
907 static LLVMValueRef
908 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
910 LLVMTypeRef stype = LLVMTypeOf (v);
912 if (stype != dtype) {
913 gboolean ext = FALSE;
915 /* Extend */
916 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
917 ext = TRUE;
918 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
919 ext = TRUE;
920 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
921 ext = TRUE;
923 if (ext)
924 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
926 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
927 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
929 /* Trunc */
930 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
931 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
932 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
933 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
934 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
935 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
936 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
937 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
939 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
940 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
941 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
942 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
943 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
944 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
946 #ifdef MONO_ARCH_SOFT_FLOAT
947 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
948 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
949 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
950 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
951 #endif
953 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
954 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
956 LLVMDumpValue (v);
957 LLVMDumpValue (LLVMConstNull (dtype));
958 g_assert_not_reached ();
959 return NULL;
960 } else {
961 return v;
965 static LLVMValueRef
966 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
968 return convert_full (ctx, v, dtype, FALSE);
972 * emit_volatile_load:
974 * If vreg is volatile, emit a load from its address.
976 static LLVMValueRef
977 emit_volatile_load (EmitContext *ctx, int vreg)
979 MonoType *t;
981 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
982 t = ctx->vreg_cli_types [vreg];
983 if (t && !t->byref) {
985 * Might have to zero extend since llvm doesn't have
986 * unsigned types.
988 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
989 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
990 else if (t->type == MONO_TYPE_U8)
991 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
994 return v;
998 * emit_volatile_store:
1000 * If VREG is volatile, emit a store from its value to its address.
1002 static void
1003 emit_volatile_store (EmitContext *ctx, int vreg)
1005 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1007 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1008 g_assert (ctx->addresses [vreg]);
1009 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1013 typedef struct {
1015 * Maps parameter indexes in the original signature to parameter indexes
1016 * in the LLVM signature.
1018 int *pindexes;
1019 /* The indexes of various special arguments in the LLVM signature */
1020 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1021 } LLVMSigInfo;
1024 * sig_to_llvm_sig_full:
1026 * Return the LLVM signature corresponding to the mono signature SIG using the
1027 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1029 static LLVMTypeRef
1030 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1031 LLVMSigInfo *sinfo)
1033 LLVMTypeRef ret_type;
1034 LLVMTypeRef *param_types = NULL;
1035 LLVMTypeRef res;
1036 int i, j, pindex, vret_arg_pindex = 0;
1037 int *pindexes;
1038 gboolean vretaddr = FALSE;
1040 if (sinfo)
1041 memset (sinfo, 0, sizeof (LLVMSigInfo));
1043 ret_type = type_to_llvm_type (ctx, sig->ret);
1044 CHECK_FAILURE (ctx);
1046 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1047 /* LLVM models this by returning an aggregate value */
1048 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1049 LLVMTypeRef members [2];
1051 members [0] = IntPtrType ();
1052 ret_type = LLVMStructType (members, 1, FALSE);
1053 } else {
1054 g_assert_not_reached ();
1056 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1057 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1058 vretaddr = TRUE;
1059 ret_type = LLVMVoidType ();
1062 pindexes = g_new0 (int, sig->param_count);
1063 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1064 pindex = 0;
1065 if (cinfo && cinfo->rgctx_arg) {
1066 if (sinfo)
1067 sinfo->rgctx_arg_pindex = pindex;
1068 param_types [pindex] = IntPtrType ();
1069 pindex ++;
1071 if (cinfo && cinfo->imt_arg) {
1072 if (sinfo)
1073 sinfo->imt_arg_pindex = pindex;
1074 param_types [pindex] = IntPtrType ();
1075 pindex ++;
1077 if (vretaddr) {
1078 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1079 vret_arg_pindex = pindex;
1080 if (cinfo->vret_arg_index == 1) {
1081 /* Add the slots consumed by the first argument */
1082 LLVMArgInfo *ainfo = &cinfo->args [0];
1083 switch (ainfo->storage) {
1084 case LLVMArgVtypeInReg:
1085 for (j = 0; j < 2; ++j) {
1086 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1087 vret_arg_pindex ++;
1089 break;
1090 default:
1091 vret_arg_pindex ++;
1095 if (sinfo)
1096 sinfo->vret_arg_pindex = vret_arg_pindex;
1099 if (vretaddr && vret_arg_pindex == pindex)
1100 param_types [pindex ++] = IntPtrType ();
1101 if (sig->hasthis) {
1102 if (sinfo)
1103 sinfo->this_arg_pindex = pindex;
1104 param_types [pindex ++] = IntPtrType ();
1106 if (vretaddr && vret_arg_pindex == pindex)
1107 param_types [pindex ++] = IntPtrType ();
1108 for (i = 0; i < sig->param_count; ++i) {
1109 if (vretaddr && vret_arg_pindex == pindex)
1110 param_types [pindex ++] = IntPtrType ();
1111 pindexes [i] = pindex;
1112 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1113 for (j = 0; j < 2; ++j) {
1114 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1115 case LLVMArgInIReg:
1116 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1117 break;
1118 case LLVMArgNone:
1119 break;
1120 default:
1121 g_assert_not_reached ();
1124 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1125 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1126 CHECK_FAILURE (ctx);
1127 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1128 pindex ++;
1129 } else {
1130 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1133 if (vretaddr && vret_arg_pindex == pindex)
1134 param_types [pindex ++] = IntPtrType ();
1136 CHECK_FAILURE (ctx);
1138 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1139 g_free (param_types);
1141 if (sinfo) {
1142 sinfo->pindexes = pindexes;
1143 } else {
1144 g_free (pindexes);
1147 return res;
1149 FAILURE:
1150 g_free (param_types);
1152 return NULL;
1155 static LLVMTypeRef
1156 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1158 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1162 * LLVMFunctionType1:
1164 * Create an LLVM function type from the arguments.
1166 static G_GNUC_UNUSED LLVMTypeRef
1167 LLVMFunctionType1(LLVMTypeRef ReturnType,
1168 LLVMTypeRef ParamType1,
1169 int IsVarArg)
1171 LLVMTypeRef param_types [1];
1173 param_types [0] = ParamType1;
1175 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1179 * LLVMFunctionType2:
1181 * Create an LLVM function type from the arguments.
1183 static G_GNUC_UNUSED LLVMTypeRef
1184 LLVMFunctionType2(LLVMTypeRef ReturnType,
1185 LLVMTypeRef ParamType1,
1186 LLVMTypeRef ParamType2,
1187 int IsVarArg)
1189 LLVMTypeRef param_types [2];
1191 param_types [0] = ParamType1;
1192 param_types [1] = ParamType2;
1194 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1198 * LLVMFunctionType3:
1200 * Create an LLVM function type from the arguments.
1202 static G_GNUC_UNUSED LLVMTypeRef
1203 LLVMFunctionType3(LLVMTypeRef ReturnType,
1204 LLVMTypeRef ParamType1,
1205 LLVMTypeRef ParamType2,
1206 LLVMTypeRef ParamType3,
1207 int IsVarArg)
1209 LLVMTypeRef param_types [3];
1211 param_types [0] = ParamType1;
1212 param_types [1] = ParamType2;
1213 param_types [2] = ParamType3;
1215 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1219 * create_builder:
1221 * Create an LLVM builder and remember it so it can be freed later.
1223 static LLVMBuilderRef
1224 create_builder (EmitContext *ctx)
1226 LLVMBuilderRef builder = LLVMCreateBuilder ();
1228 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1230 return builder;
1233 static LLVMValueRef
1234 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1236 char *callee_name = mono_aot_get_plt_symbol (type, data);
1237 LLVMValueRef callee;
1239 if (!callee_name)
1240 return NULL;
1242 if (ctx->cfg->compile_aot)
1243 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1244 mono_add_patch_info (ctx->cfg, 0, type, data);
1246 // FIXME: Locking
1247 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1248 if (!callee) {
1249 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1251 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1253 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1256 return callee;
1259 static int
1260 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1262 MonoMethodHeader *header = cfg->header;
1263 MonoExceptionClause *clause;
1264 int i;
1266 /* Directly */
1267 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1268 return (bb->region >> 8) - 1;
1270 /* Indirectly */
1271 for (i = 0; i < header->num_clauses; ++i) {
1272 clause = &header->clauses [i];
1274 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1275 return i;
1278 return -1;
1281 static void
1282 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1284 LLVMValueRef md_arg;
1285 int md_kind;
1287 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1288 md_arg = LLVMMDString ("mono", 4);
1289 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1293 * emit_call:
1295 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1296 * a try region.
1298 static LLVMValueRef
1299 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1301 MonoCompile *cfg = ctx->cfg;
1302 LLVMValueRef lcall;
1303 LLVMBuilderRef builder = *builder_ref;
1304 int clause_index;
1306 clause_index = get_handler_clause (cfg, bb);
1308 if (clause_index != -1) {
1309 MonoMethodHeader *header = cfg->header;
1310 MonoExceptionClause *ec = &header->clauses [clause_index];
1311 MonoBasicBlock *tblock;
1312 LLVMBasicBlockRef ex_bb, noex_bb;
1315 * Have to use an invoke instead of a call, branching to the
1316 * handler bblock of the clause containing this bblock.
1319 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1321 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1322 g_assert (tblock);
1324 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1326 ex_bb = get_bb (ctx, tblock);
1328 noex_bb = gen_bb (ctx, "NOEX_BB");
1330 /* Use an invoke */
1331 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1333 builder = ctx->builder = create_builder (ctx);
1334 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1336 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1337 } else {
1338 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1339 ctx->builder = builder;
1342 *builder_ref = ctx->builder;
1344 return lcall;
1347 static LLVMValueRef
1348 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1350 const char *intrins_name;
1351 LLVMValueRef args [16], res;
1352 LLVMTypeRef addr_type;
1354 if (is_faulting && bb->region != -1) {
1356 * We handle loads which can fault by calling a mono specific intrinsic
1357 * using an invoke, so they are handled properly inside try blocks.
1358 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1359 * are marked with IntrReadArgMem.
1361 switch (size) {
1362 case 1:
1363 intrins_name = "llvm.mono.load.i8.p0i8";
1364 break;
1365 case 2:
1366 intrins_name = "llvm.mono.load.i16.p0i16";
1367 break;
1368 case 4:
1369 intrins_name = "llvm.mono.load.i32.p0i32";
1370 break;
1371 case 8:
1372 intrins_name = "llvm.mono.load.i64.p0i64";
1373 break;
1374 default:
1375 g_assert_not_reached ();
1378 addr_type = LLVMTypeOf (addr);
1379 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1380 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1382 args [0] = addr;
1383 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1384 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1385 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1387 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1388 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1389 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1390 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1392 return res;
1393 } else {
1394 LLVMValueRef res;
1397 * We emit volatile loads for loads which can fault, because otherwise
1398 * LLVM will generate invalid code when encountering a load from a
1399 * NULL address.
1401 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1403 /* Mark it with a custom metadata */
1405 if (is_faulting)
1406 set_metadata_flag (res, "mono.faulting.load");
1409 return res;
1413 static void
1414 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1416 const char *intrins_name;
1417 LLVMValueRef args [16];
1419 if (is_faulting && bb->region != -1) {
1420 switch (size) {
1421 case 1:
1422 intrins_name = "llvm.mono.store.i8.p0i8";
1423 break;
1424 case 2:
1425 intrins_name = "llvm.mono.store.i16.p0i16";
1426 break;
1427 case 4:
1428 intrins_name = "llvm.mono.store.i32.p0i32";
1429 break;
1430 case 8:
1431 intrins_name = "llvm.mono.store.i64.p0i64";
1432 break;
1433 default:
1434 g_assert_not_reached ();
1437 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1438 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1439 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1442 args [0] = value;
1443 args [1] = addr;
1444 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1445 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1446 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1447 } else {
1448 LLVMBuildStore (*builder_ref, value, addr);
1453 * emit_cond_system_exception:
1455 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1456 * Might set the ctx exception.
1458 static void
1459 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1461 LLVMBasicBlockRef ex_bb, noex_bb;
1462 LLVMBuilderRef builder;
1463 MonoClass *exc_class;
1464 LLVMValueRef args [2];
1466 ex_bb = gen_bb (ctx, "EX_BB");
1467 noex_bb = gen_bb (ctx, "NOEX_BB");
1469 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1471 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1472 g_assert (exc_class);
1474 /* Emit exception throwing code */
1475 builder = create_builder (ctx);
1476 LLVMPositionBuilderAtEnd (builder, ex_bb);
1478 if (!ctx->lmodule->throw_corlib_exception) {
1479 LLVMValueRef callee;
1480 LLVMTypeRef sig;
1481 const char *icall_name;
1483 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1484 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1485 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1486 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1487 throw_sig->params [1] = &mono_get_intptr_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);
1514 * The LLVM mono branch contains changes so a block address can be passed as an
1515 * argument to a call.
1517 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1518 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1520 LLVMBuildUnreachable (builder);
1522 ctx->builder = create_builder (ctx);
1523 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1525 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1527 ctx->ex_index ++;
1528 return;
1532 * emit_reg_to_vtype:
1534 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1536 static void
1537 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1539 int j, size;
1541 size = get_vtype_size (t);
1543 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1544 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1547 for (j = 0; j < 2; ++j) {
1548 LLVMValueRef index [2], addr;
1549 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1550 LLVMTypeRef part_type;
1552 if (ainfo->pair_storage [j] == LLVMArgNone)
1553 continue;
1555 part_type = LLVMIntType (part_size * 8);
1556 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1557 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1558 addr = LLVMBuildGEP (builder, address, index, 1, "");
1559 } else {
1560 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1561 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1562 addr = LLVMBuildGEP (builder, address, index, 2, "");
1564 switch (ainfo->pair_storage [j]) {
1565 case LLVMArgInIReg:
1566 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1567 break;
1568 case LLVMArgNone:
1569 break;
1570 default:
1571 g_assert_not_reached ();
1574 size -= sizeof (gpointer);
1579 * emit_vtype_to_reg:
1581 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1582 * into REGS, and the number of registers into NREGS.
1584 static void
1585 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1587 int pindex = 0;
1588 int j, size;
1590 size = get_vtype_size (t);
1592 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1593 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1596 for (j = 0; j < 2; ++j) {
1597 LLVMValueRef index [2], addr;
1598 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1600 if (ainfo->pair_storage [j] == LLVMArgNone)
1601 continue;
1603 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1604 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1605 addr = LLVMBuildGEP (builder, address, index, 1, "");
1606 } else {
1607 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1608 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1609 addr = LLVMBuildGEP (builder, address, index, 2, "");
1611 switch (ainfo->pair_storage [j]) {
1612 case LLVMArgInIReg:
1613 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1614 break;
1615 case LLVMArgNone:
1616 break;
1617 default:
1618 g_assert_not_reached ();
1620 size -= sizeof (gpointer);
1623 *nregs = pindex;
1626 static LLVMValueRef
1627 build_alloca (EmitContext *ctx, MonoType *t)
1629 MonoClass *k = mono_class_from_mono_type (t);
1630 int align;
1632 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1633 align = 16;
1634 else
1635 align = mono_class_min_align (k);
1637 /* Sometimes align is not a power of 2 */
1638 while (mono_is_power_of_two (align) == -1)
1639 align ++;
1642 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1643 * get executed every time control reaches them.
1645 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1647 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1648 return ctx->last_alloca;
1652 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1654 static void
1655 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1657 LLVMTypeRef used_type;
1658 LLVMValueRef used, used_elem;
1660 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1661 used = LLVMAddGlobal (module, used_type, "llvm.used");
1662 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1663 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1664 LLVMSetLinkage (used, LLVMAppendingLinkage);
1665 LLVMSetSection (used, "llvm.metadata");
1669 * emit_entry_bb:
1671 * Emit code to load/convert arguments.
1673 static void
1674 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1676 int i, pindex;
1677 MonoCompile *cfg = ctx->cfg;
1678 MonoMethodSignature *sig = ctx->sig;
1679 LLVMCallInfo *linfo = ctx->linfo;
1680 MonoBasicBlock *bb;
1682 ctx->alloca_builder = create_builder (ctx);
1685 * Handle indirect/volatile variables by allocating memory for them
1686 * using 'alloca', and storing their address in a temporary.
1688 for (i = 0; i < cfg->num_varinfo; ++i) {
1689 MonoInst *var = cfg->varinfo [i];
1690 LLVMTypeRef vtype;
1692 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1693 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1694 CHECK_FAILURE (ctx);
1695 /* Could be already created by an OP_VPHI */
1696 if (!ctx->addresses [var->dreg])
1697 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1698 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1702 for (i = 0; i < sig->param_count; ++i) {
1703 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1704 int reg = cfg->args [i + sig->hasthis]->dreg;
1706 if (ainfo->storage == LLVMArgVtypeInReg) {
1707 LLVMValueRef regs [2];
1710 * Emit code to save the argument from the registers to
1711 * the real argument.
1713 pindex = ctx->pindexes [i];
1714 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1715 if (ainfo->pair_storage [1] != LLVMArgNone)
1716 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1717 else
1718 regs [1] = NULL;
1720 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1722 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1724 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1725 /* Treat these as normal values */
1726 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1728 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1729 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1731 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1732 /* Treat these as normal values */
1733 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1735 } else {
1736 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1740 if (cfg->vret_addr)
1741 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1742 if (sig->hasthis)
1743 emit_volatile_store (ctx, cfg->args [0]->dreg);
1744 for (i = 0; i < sig->param_count; ++i)
1745 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1746 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1748 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1749 LLVMValueRef this_alloc;
1752 * The exception handling code needs the location where the this argument was
1753 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1754 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1755 * location into the LSDA.
1757 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1758 /* This volatile store will keep the alloca alive */
1759 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1761 set_metadata_flag (this_alloc, "mono.this");
1764 if (cfg->rgctx_var) {
1765 LLVMValueRef rgctx_alloc, store;
1768 * We handle the rgctx arg similarly to the this pointer.
1770 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1771 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1772 /* This volatile store will keep the alloca alive */
1773 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1775 set_metadata_flag (rgctx_alloc, "mono.this");
1779 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1780 * it needs to continue normally, or return back to the exception handling system.
1782 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1783 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1784 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1785 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1786 char name [128];
1787 LLVMValueRef val;
1789 sprintf (name, "finally_ind_bb%d", bb->block_num);
1790 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1791 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1793 ctx->bblocks [bb->block_num].finally_ind = val;
1796 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1797 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1798 * LLVM optimizer passes.
1800 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1801 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1805 FAILURE:
1809 /* Have to export this for AOT */
1810 void
1811 mono_personality (void);
1813 void
1814 mono_personality (void)
1816 /* Not used */
1817 g_assert_not_reached ();
1820 static void
1821 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1823 MonoCompile *cfg = ctx->cfg;
1824 LLVMModuleRef module = ctx->module;
1825 LLVMValueRef *values = ctx->values;
1826 LLVMValueRef *addresses = ctx->addresses;
1827 MonoCallInst *call = (MonoCallInst*)ins;
1828 MonoMethodSignature *sig = call->signature;
1829 LLVMValueRef callee = NULL, lcall;
1830 LLVMValueRef *args;
1831 LLVMCallInfo *cinfo;
1832 GSList *l;
1833 int i, len;
1834 gboolean vretaddr;
1835 LLVMTypeRef llvm_sig;
1836 gpointer target;
1837 gboolean virtual, calli;
1838 LLVMBuilderRef builder = *builder_ref;
1839 LLVMSigInfo sinfo;
1841 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1842 LLVM_FAILURE (ctx, "non-default callconv");
1844 cinfo = call->cinfo;
1845 if (call->rgctx_arg_reg)
1846 cinfo->rgctx_arg = TRUE;
1847 if (call->imt_arg_reg)
1848 cinfo->imt_arg = TRUE;
1850 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1852 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1853 CHECK_FAILURE (ctx);
1855 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);
1856 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);
1858 /* FIXME: Avoid creating duplicate methods */
1860 if (ins->flags & MONO_INST_HAS_METHOD) {
1861 if (virtual) {
1862 callee = NULL;
1863 } else {
1864 if (cfg->compile_aot) {
1865 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1866 if (!callee)
1867 LLVM_FAILURE (ctx, "can't encode patch");
1868 } else {
1869 callee = LLVMAddFunction (module, "", llvm_sig);
1871 target =
1872 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1873 call->method);
1874 LLVMAddGlobalMapping (ee, callee, target);
1877 } else if (calli) {
1878 } else {
1879 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1881 if (info) {
1883 MonoJumpInfo ji;
1885 memset (&ji, 0, sizeof (ji));
1886 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1887 ji.data.target = info->name;
1889 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1891 if (cfg->compile_aot) {
1892 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1893 if (!callee)
1894 LLVM_FAILURE (ctx, "can't encode patch");
1895 } else {
1896 callee = LLVMAddFunction (module, "", llvm_sig);
1897 target = (gpointer)mono_icall_get_wrapper (info);
1898 LLVMAddGlobalMapping (ee, callee, target);
1900 } else {
1901 if (cfg->compile_aot) {
1902 callee = NULL;
1903 if (cfg->abs_patches) {
1904 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1905 if (abs_ji) {
1906 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1907 if (!callee)
1908 LLVM_FAILURE (ctx, "can't encode patch");
1911 if (!callee)
1912 LLVM_FAILURE (ctx, "aot");
1913 } else {
1914 callee = LLVMAddFunction (module, "", llvm_sig);
1915 target = NULL;
1916 if (cfg->abs_patches) {
1917 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1918 if (abs_ji) {
1920 * FIXME: Some trampolines might have
1921 * their own calling convention on some platforms.
1923 #ifndef TARGET_AMD64
1924 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)
1925 LLVM_FAILURE (ctx, "trampoline with own cconv");
1926 #endif
1927 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1928 LLVMAddGlobalMapping (ee, callee, target);
1931 if (!target)
1932 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1937 if (virtual) {
1938 int size = sizeof (gpointer);
1939 LLVMValueRef index;
1941 g_assert (ins->inst_offset % size == 0);
1942 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1944 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1945 } else if (calli) {
1946 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1947 } else {
1948 if (ins->flags & MONO_INST_HAS_METHOD) {
1953 * Collect and convert arguments
1955 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
1956 args = alloca (len);
1957 memset (args, 0, len);
1958 l = call->out_ireg_args;
1960 if (call->rgctx_arg_reg) {
1961 g_assert (values [call->rgctx_arg_reg]);
1962 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1964 if (call->imt_arg_reg) {
1965 g_assert (values [call->imt_arg_reg]);
1966 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1969 if (vretaddr) {
1970 if (!addresses [call->inst.dreg])
1971 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1972 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1975 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1976 guint32 regpair;
1977 int reg, pindex;
1978 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1980 if (sig->hasthis) {
1981 if (i == 0)
1982 pindex = sinfo.this_arg_pindex;
1983 else
1984 pindex = sinfo.pindexes [i - 1];
1985 } else {
1986 pindex = sinfo.pindexes [i];
1989 regpair = (guint32)(gssize)(l->data);
1990 reg = regpair & 0xffffff;
1991 args [pindex] = values [reg];
1992 if (ainfo->storage == LLVMArgVtypeInReg) {
1993 int j;
1994 LLVMValueRef regs [2];
1995 guint32 nregs;
1997 g_assert (ainfo);
1999 g_assert (addresses [reg]);
2001 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2002 for (j = 0; j < nregs; ++j)
2003 args [pindex ++] = regs [j];
2005 // FIXME: alignment
2006 // FIXME: Get rid of the VMOVE
2007 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2008 g_assert (addresses [reg]);
2009 args [pindex] = addresses [reg];
2010 } else {
2011 g_assert (args [pindex]);
2012 if (i == 0 && sig->hasthis)
2013 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2014 else
2015 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2018 l = l->next;
2021 // FIXME: Align call sites
2024 * Emit the call
2027 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2029 #ifdef LLVM_MONO_BRANCH
2031 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2033 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2034 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2035 #endif
2036 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2037 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2038 if (!sig->pinvoke)
2039 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2041 if (call->rgctx_arg_reg)
2042 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2043 if (call->imt_arg_reg)
2044 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2045 #endif
2047 /* Add byval attributes if needed */
2048 for (i = 0; i < sig->param_count; ++i) {
2049 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2051 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2052 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2057 * Convert the result
2059 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2060 LLVMValueRef regs [2];
2062 if (!addresses [ins->dreg])
2063 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2065 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2066 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2067 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2069 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2070 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2071 /* If the method returns an unsigned value, need to zext it */
2073 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));
2076 *builder_ref = ctx->builder;
2078 g_free (sinfo.pindexes);
2080 return;
2081 FAILURE:
2082 return;
2085 static void
2086 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2088 MonoCompile *cfg = ctx->cfg;
2089 MonoMethodSignature *sig = ctx->sig;
2090 LLVMValueRef method = ctx->lmethod;
2091 LLVMValueRef *values = ctx->values;
2092 LLVMValueRef *addresses = ctx->addresses;
2093 int i;
2094 LLVMCallInfo *linfo = ctx->linfo;
2095 LLVMModuleRef module = ctx->module;
2096 BBInfo *bblocks = ctx->bblocks;
2097 MonoInst *ins;
2098 LLVMBasicBlockRef cbb;
2099 LLVMBuilderRef builder;
2100 gboolean has_terminator;
2101 LLVMValueRef v;
2102 LLVMValueRef lhs, rhs;
2104 cbb = get_bb (ctx, bb);
2105 builder = create_builder (ctx);
2106 ctx->builder = builder;
2107 LLVMPositionBuilderAtEnd (builder, cbb);
2109 if (bb == cfg->bb_entry)
2110 emit_entry_bb (ctx, builder);
2111 CHECK_FAILURE (ctx);
2113 if (bb->flags & BB_EXCEPTION_HANDLER) {
2114 LLVMTypeRef i8ptr;
2115 LLVMValueRef personality;
2116 LLVMBasicBlockRef target_bb;
2117 MonoInst *exvar;
2118 static gint32 mapping_inited;
2119 static int ti_generator;
2120 char ti_name [128];
2121 MonoClass **ti;
2122 LLVMValueRef type_info;
2123 int clause_index;
2125 if (!bblocks [bb->block_num].invoke_target) {
2127 * LLVM asserts if llvm.eh.selector is called from a bblock which
2128 * doesn't have an invoke pointing at it.
2129 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2131 LLVM_FAILURE (ctx, "handler without invokes");
2134 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2136 if (cfg->compile_aot) {
2137 /* Use a dummy personality function */
2138 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2139 g_assert (personality);
2140 } else {
2141 personality = LLVMGetNamedFunction (module, "mono_personality");
2142 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2143 LLVMAddGlobalMapping (ee, personality, mono_personality);
2146 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2148 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2151 * Create the type info
2153 sprintf (ti_name, "type_info_%d", ti_generator);
2154 ti_generator ++;
2156 if (cfg->compile_aot) {
2157 /* decode_eh_frame () in aot-runtime.c will decode this */
2158 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2159 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2161 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2162 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2165 * Enabling this causes llc to crash:
2166 * http://llvm.org/bugs/show_bug.cgi?id=6102
2168 //LLVM_FAILURE (ctx, "aot+clauses");
2169 } else {
2171 * After the cfg mempool is freed, the type info will point to stale memory,
2172 * but this is not a problem, since we decode it once in exception_cb during
2173 * compilation.
2175 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2176 *(gint32*)ti = clause_index;
2178 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2180 LLVMAddGlobalMapping (ee, type_info, ti);
2184 LLVMTypeRef members [2], ret_type;
2185 LLVMValueRef landing_pad;
2187 members [0] = i8ptr;
2188 members [1] = LLVMInt32Type ();
2189 ret_type = LLVMStructType (members, 2, FALSE);
2191 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2192 LLVMAddClause (landing_pad, type_info);
2194 /* Store the exception into the exvar */
2195 if (bb->in_scount == 1) {
2196 g_assert (bb->in_scount == 1);
2197 exvar = bb->in_stack [0];
2199 // FIXME: This is shared with filter clauses ?
2200 g_assert (!values [exvar->dreg]);
2202 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2203 emit_volatile_store (ctx, exvar->dreg);
2207 /* Start a new bblock which CALL_HANDLER can branch to */
2208 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2209 if (target_bb) {
2210 LLVMBuildBr (builder, target_bb);
2212 ctx->builder = builder = create_builder (ctx);
2213 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2215 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2219 has_terminator = FALSE;
2220 for (ins = bb->code; ins; ins = ins->next) {
2221 const char *spec = LLVM_INS_INFO (ins->opcode);
2222 char *dname = NULL;
2223 char dname_buf [128];
2225 if (has_terminator)
2226 /* There could be instructions after a terminator, skip them */
2227 break;
2229 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2230 sprintf (dname_buf, "t%d", ins->dreg);
2231 dname = dname_buf;
2234 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2235 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2237 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2238 lhs = emit_volatile_load (ctx, ins->sreg1);
2239 } else {
2240 /* It is ok for SETRET to have an uninitialized argument */
2241 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2242 LLVM_FAILURE (ctx, "sreg1");
2243 lhs = values [ins->sreg1];
2245 } else {
2246 lhs = NULL;
2249 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2250 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2251 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2252 rhs = emit_volatile_load (ctx, ins->sreg2);
2253 } else {
2254 if (!values [ins->sreg2])
2255 LLVM_FAILURE (ctx, "sreg2");
2256 rhs = values [ins->sreg2];
2258 } else {
2259 rhs = NULL;
2262 //mono_print_ins (ins);
2263 switch (ins->opcode) {
2264 case OP_NOP:
2265 case OP_NOT_NULL:
2266 case OP_LIVERANGE_START:
2267 case OP_LIVERANGE_END:
2268 break;
2269 case OP_ICONST:
2270 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2271 break;
2272 case OP_I8CONST:
2273 #if SIZEOF_VOID_P == 4
2274 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2275 #else
2276 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2277 #endif
2278 break;
2279 case OP_R8CONST:
2280 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2281 break;
2282 case OP_R4CONST:
2283 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2284 break;
2285 case OP_BR:
2286 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2287 has_terminator = TRUE;
2288 break;
2289 case OP_SWITCH: {
2290 int i;
2291 LLVMValueRef v;
2292 char bb_name [128];
2293 LLVMBasicBlockRef new_bb;
2294 LLVMBuilderRef new_builder;
2296 // The default branch is already handled
2297 // FIXME: Handle it here
2299 /* Start new bblock */
2300 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2301 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2303 lhs = convert (ctx, lhs, LLVMInt32Type ());
2304 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2305 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2306 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2308 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2311 new_builder = create_builder (ctx);
2312 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2313 LLVMBuildUnreachable (new_builder);
2315 has_terminator = TRUE;
2316 g_assert (!ins->next);
2318 break;
2321 case OP_SETRET:
2322 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2323 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2324 LLVMValueRef part1, retval;
2325 int size;
2327 size = get_vtype_size (sig->ret);
2329 g_assert (addresses [ins->sreg1]);
2331 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2332 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2334 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2336 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2338 LLVMBuildRet (builder, retval);
2339 break;
2342 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2343 LLVMBuildRetVoid (builder);
2344 break;
2347 if (!lhs || ctx->is_dead [ins->sreg1]) {
2349 * The method did not set its return value, probably because it
2350 * ends with a throw.
2352 if (cfg->vret_addr)
2353 LLVMBuildRetVoid (builder);
2354 else
2355 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2356 } else {
2357 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2359 has_terminator = TRUE;
2360 break;
2361 case OP_ICOMPARE:
2362 case OP_FCOMPARE:
2363 case OP_LCOMPARE:
2364 case OP_COMPARE:
2365 case OP_ICOMPARE_IMM:
2366 case OP_LCOMPARE_IMM:
2367 case OP_COMPARE_IMM: {
2368 CompRelation rel;
2369 LLVMValueRef cmp;
2371 if (ins->next->opcode == OP_NOP)
2372 break;
2374 if (ins->next->opcode == OP_BR)
2375 /* The comparison result is not needed */
2376 continue;
2378 rel = mono_opcode_to_cond (ins->next->opcode);
2380 if (ins->opcode == OP_ICOMPARE_IMM) {
2381 lhs = convert (ctx, lhs, LLVMInt32Type ());
2382 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2384 if (ins->opcode == OP_LCOMPARE_IMM) {
2385 lhs = convert (ctx, lhs, LLVMInt64Type ());
2386 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2388 if (ins->opcode == OP_LCOMPARE) {
2389 lhs = convert (ctx, lhs, LLVMInt64Type ());
2390 rhs = convert (ctx, rhs, LLVMInt64Type ());
2392 if (ins->opcode == OP_ICOMPARE) {
2393 lhs = convert (ctx, lhs, LLVMInt32Type ());
2394 rhs = convert (ctx, rhs, LLVMInt32Type ());
2397 if (lhs && rhs) {
2398 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2399 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2400 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2401 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2404 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2405 if (ins->opcode == OP_FCOMPARE)
2406 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2407 else if (ins->opcode == OP_COMPARE_IMM)
2408 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2409 else if (ins->opcode == OP_LCOMPARE_IMM) {
2410 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2411 /* The immediate is encoded in two fields */
2412 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2413 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2414 } else {
2415 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2418 else if (ins->opcode == OP_COMPARE)
2419 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2420 else
2421 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2423 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2424 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2426 * If the target bb contains PHI instructions, LLVM requires
2427 * two PHI entries for this bblock, while we only generate one.
2428 * So convert this to an unconditional bblock. (bxc #171).
2430 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2431 } else {
2432 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2434 has_terminator = TRUE;
2435 } else if (MONO_IS_SETCC (ins->next)) {
2436 sprintf (dname_buf, "t%d", ins->next->dreg);
2437 dname = dname_buf;
2438 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2440 /* Add stores for volatile variables */
2441 emit_volatile_store (ctx, ins->next->dreg);
2442 } else if (MONO_IS_COND_EXC (ins->next)) {
2443 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2444 CHECK_FAILURE (ctx);
2445 builder = ctx->builder;
2446 } else {
2447 LLVM_FAILURE (ctx, "next");
2450 ins = ins->next;
2451 break;
2453 case OP_FCEQ:
2454 case OP_FCLT:
2455 case OP_FCLT_UN:
2456 case OP_FCGT:
2457 case OP_FCGT_UN: {
2458 CompRelation rel;
2459 LLVMValueRef cmp;
2461 rel = mono_opcode_to_cond (ins->opcode);
2463 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2464 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2465 break;
2467 case OP_PHI:
2468 case OP_FPHI:
2469 case OP_VPHI:
2470 case OP_XPHI: {
2471 int i;
2472 gboolean empty = TRUE;
2474 /* Check that all input bblocks really branch to us */
2475 for (i = 0; i < bb->in_count; ++i) {
2476 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2477 ins->inst_phi_args [i + 1] = -1;
2478 else
2479 empty = FALSE;
2482 if (empty) {
2483 /* LLVM doesn't like phi instructions with zero operands */
2484 ctx->is_dead [ins->dreg] = TRUE;
2485 break;
2488 /* Created earlier, insert it now */
2489 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2491 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2492 int sreg1 = ins->inst_phi_args [i + 1];
2493 int count, j;
2496 * Count the number of times the incoming bblock branches to us,
2497 * since llvm requires a separate entry for each.
2499 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2500 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2502 count = 0;
2503 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2504 if (switch_ins->inst_many_bb [j] == bb)
2505 count ++;
2507 } else {
2508 count = 1;
2511 /* Remember for later */
2512 for (j = 0; j < count; ++j) {
2513 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2514 node->bb = bb;
2515 node->phi = ins;
2516 node->in_bb = bb->in_bb [i];
2517 node->sreg = sreg1;
2518 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);
2521 break;
2523 case OP_MOVE:
2524 case OP_LMOVE:
2525 case OP_XMOVE:
2526 case OP_SETFRET:
2527 g_assert (lhs);
2528 values [ins->dreg] = lhs;
2529 break;
2530 case OP_FMOVE: {
2531 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2533 g_assert (lhs);
2534 values [ins->dreg] = lhs;
2536 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2538 * This is added by the spilling pass in case of the JIT,
2539 * but we have to do it ourselves.
2541 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2543 break;
2545 case OP_IADD:
2546 case OP_ISUB:
2547 case OP_IAND:
2548 case OP_IMUL:
2549 case OP_IDIV:
2550 case OP_IDIV_UN:
2551 case OP_IREM:
2552 case OP_IREM_UN:
2553 case OP_IOR:
2554 case OP_IXOR:
2555 case OP_ISHL:
2556 case OP_ISHR:
2557 case OP_ISHR_UN:
2558 case OP_FADD:
2559 case OP_FSUB:
2560 case OP_FMUL:
2561 case OP_FDIV:
2562 case OP_LADD:
2563 case OP_LSUB:
2564 case OP_LMUL:
2565 case OP_LDIV:
2566 case OP_LDIV_UN:
2567 case OP_LREM:
2568 case OP_LREM_UN:
2569 case OP_LAND:
2570 case OP_LOR:
2571 case OP_LXOR:
2572 case OP_LSHL:
2573 case OP_LSHR:
2574 case OP_LSHR_UN:
2575 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2576 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2578 switch (ins->opcode) {
2579 case OP_IADD:
2580 case OP_LADD:
2581 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2582 break;
2583 case OP_ISUB:
2584 case OP_LSUB:
2585 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2586 break;
2587 case OP_IMUL:
2588 case OP_LMUL:
2589 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2590 break;
2591 case OP_IREM:
2592 case OP_LREM:
2593 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2594 break;
2595 case OP_IREM_UN:
2596 case OP_LREM_UN:
2597 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2598 break;
2599 case OP_IDIV:
2600 case OP_LDIV:
2601 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2602 break;
2603 case OP_IDIV_UN:
2604 case OP_LDIV_UN:
2605 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2606 break;
2607 case OP_FDIV:
2608 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2609 break;
2610 case OP_IAND:
2611 case OP_LAND:
2612 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2613 break;
2614 case OP_IOR:
2615 case OP_LOR:
2616 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2617 break;
2618 case OP_IXOR:
2619 case OP_LXOR:
2620 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2621 break;
2622 case OP_ISHL:
2623 case OP_LSHL:
2624 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2625 break;
2626 case OP_ISHR:
2627 case OP_LSHR:
2628 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2629 break;
2630 case OP_ISHR_UN:
2631 case OP_LSHR_UN:
2632 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2633 break;
2635 case OP_FADD:
2636 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2637 break;
2638 case OP_FSUB:
2639 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2640 break;
2641 case OP_FMUL:
2642 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2643 break;
2645 default:
2646 g_assert_not_reached ();
2648 break;
2649 case OP_IADD_IMM:
2650 case OP_ISUB_IMM:
2651 case OP_IMUL_IMM:
2652 case OP_IREM_IMM:
2653 case OP_IREM_UN_IMM:
2654 case OP_IDIV_IMM:
2655 case OP_IDIV_UN_IMM:
2656 case OP_IAND_IMM:
2657 case OP_IOR_IMM:
2658 case OP_IXOR_IMM:
2659 case OP_ISHL_IMM:
2660 case OP_ISHR_IMM:
2661 case OP_ISHR_UN_IMM:
2662 case OP_LADD_IMM:
2663 case OP_LSUB_IMM:
2664 case OP_LREM_IMM:
2665 case OP_LAND_IMM:
2666 case OP_LOR_IMM:
2667 case OP_LXOR_IMM:
2668 case OP_LSHL_IMM:
2669 case OP_LSHR_IMM:
2670 case OP_LSHR_UN_IMM:
2671 case OP_ADD_IMM:
2672 case OP_AND_IMM:
2673 case OP_MUL_IMM:
2674 case OP_SHL_IMM:
2675 case OP_SHR_IMM: {
2676 LLVMValueRef imm;
2678 if (spec [MONO_INST_SRC1] == 'l') {
2679 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2680 } else {
2681 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2684 #if SIZEOF_VOID_P == 4
2685 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2686 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2687 #endif
2689 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2690 lhs = convert (ctx, lhs, IntPtrType ());
2691 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2692 switch (ins->opcode) {
2693 case OP_IADD_IMM:
2694 case OP_LADD_IMM:
2695 case OP_ADD_IMM:
2696 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2697 break;
2698 case OP_ISUB_IMM:
2699 case OP_LSUB_IMM:
2700 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2701 break;
2702 case OP_IMUL_IMM:
2703 case OP_MUL_IMM:
2704 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2705 break;
2706 case OP_IDIV_IMM:
2707 case OP_LDIV_IMM:
2708 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2709 break;
2710 case OP_IDIV_UN_IMM:
2711 case OP_LDIV_UN_IMM:
2712 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2713 break;
2714 case OP_IREM_IMM:
2715 case OP_LREM_IMM:
2716 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2717 break;
2718 case OP_IREM_UN_IMM:
2719 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2720 break;
2721 case OP_IAND_IMM:
2722 case OP_LAND_IMM:
2723 case OP_AND_IMM:
2724 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2725 break;
2726 case OP_IOR_IMM:
2727 case OP_LOR_IMM:
2728 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2729 break;
2730 case OP_IXOR_IMM:
2731 case OP_LXOR_IMM:
2732 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2733 break;
2734 case OP_ISHL_IMM:
2735 case OP_LSHL_IMM:
2736 case OP_SHL_IMM:
2737 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2738 break;
2739 case OP_ISHR_IMM:
2740 case OP_LSHR_IMM:
2741 case OP_SHR_IMM:
2742 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2743 break;
2744 case OP_ISHR_UN_IMM:
2745 /* This is used to implement conv.u4, so the lhs could be an i8 */
2746 lhs = convert (ctx, lhs, LLVMInt32Type ());
2747 imm = convert (ctx, imm, LLVMInt32Type ());
2748 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2749 break;
2750 case OP_LSHR_UN_IMM:
2751 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2752 break;
2753 default:
2754 g_assert_not_reached ();
2756 break;
2758 case OP_INEG:
2759 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2760 break;
2761 case OP_LNEG:
2762 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2763 break;
2764 case OP_FNEG:
2765 lhs = convert (ctx, lhs, LLVMDoubleType ());
2766 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2767 break;
2768 case OP_INOT: {
2769 guint32 v = 0xffffffff;
2770 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2771 break;
2773 case OP_LNOT: {
2774 guint64 v = 0xffffffffffffffffLL;
2775 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2776 break;
2778 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2779 case OP_X86_LEA: {
2780 LLVMValueRef v1, v2;
2782 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2783 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2784 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2785 break;
2787 #endif
2789 case OP_ICONV_TO_I1:
2790 case OP_ICONV_TO_I2:
2791 case OP_ICONV_TO_I4:
2792 case OP_ICONV_TO_U1:
2793 case OP_ICONV_TO_U2:
2794 case OP_ICONV_TO_U4:
2795 case OP_LCONV_TO_I1:
2796 case OP_LCONV_TO_I2:
2797 case OP_LCONV_TO_U1:
2798 case OP_LCONV_TO_U2:
2799 case OP_LCONV_TO_U4: {
2800 gboolean sign;
2802 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);
2804 /* Have to do two casts since our vregs have type int */
2805 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2806 if (sign)
2807 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2808 else
2809 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2810 break;
2812 case OP_ICONV_TO_I8:
2813 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2814 break;
2815 case OP_ICONV_TO_U8:
2816 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2817 break;
2818 case OP_FCONV_TO_I4:
2819 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2820 break;
2821 case OP_FCONV_TO_I1:
2822 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2823 break;
2824 case OP_FCONV_TO_U1:
2825 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2826 break;
2827 case OP_FCONV_TO_I2:
2828 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2829 break;
2830 case OP_FCONV_TO_U2:
2831 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2832 break;
2833 case OP_FCONV_TO_I8:
2834 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2835 break;
2836 case OP_FCONV_TO_I:
2837 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2838 break;
2839 case OP_ICONV_TO_R8:
2840 case OP_LCONV_TO_R8:
2841 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2842 break;
2843 case OP_LCONV_TO_R_UN:
2844 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2845 break;
2846 #if SIZEOF_VOID_P == 4
2847 case OP_LCONV_TO_U:
2848 #endif
2849 case OP_LCONV_TO_I4:
2850 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2851 break;
2852 case OP_ICONV_TO_R4:
2853 case OP_LCONV_TO_R4:
2854 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2855 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2856 break;
2857 case OP_FCONV_TO_R4:
2858 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2859 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2860 break;
2861 case OP_SEXT_I4:
2862 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2863 break;
2864 case OP_ZEXT_I4:
2865 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2866 break;
2867 case OP_TRUNC_I4:
2868 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2869 break;
2870 case OP_LOCALLOC_IMM: {
2871 LLVMValueRef v;
2873 guint32 size = ins->inst_imm;
2874 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2876 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2878 if (ins->flags & MONO_INST_INIT) {
2879 LLVMValueRef args [5];
2881 args [0] = v;
2882 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2883 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2884 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2885 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2886 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2889 values [ins->dreg] = v;
2890 break;
2892 case OP_LOCALLOC: {
2893 LLVMValueRef v, size;
2895 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), "");
2897 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2899 if (ins->flags & MONO_INST_INIT) {
2900 LLVMValueRef args [5];
2902 args [0] = v;
2903 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2904 args [2] = size;
2905 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2906 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2907 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2909 values [ins->dreg] = v;
2910 break;
2913 case OP_LOADI1_MEMBASE:
2914 case OP_LOADU1_MEMBASE:
2915 case OP_LOADI2_MEMBASE:
2916 case OP_LOADU2_MEMBASE:
2917 case OP_LOADI4_MEMBASE:
2918 case OP_LOADU4_MEMBASE:
2919 case OP_LOADI8_MEMBASE:
2920 case OP_LOADR4_MEMBASE:
2921 case OP_LOADR8_MEMBASE:
2922 case OP_LOAD_MEMBASE:
2923 case OP_LOADI8_MEM:
2924 case OP_LOADU1_MEM:
2925 case OP_LOADU2_MEM:
2926 case OP_LOADI4_MEM:
2927 case OP_LOADU4_MEM:
2928 case OP_LOAD_MEM: {
2929 int size = 8;
2930 LLVMValueRef base, index, addr;
2931 LLVMTypeRef t;
2932 gboolean sext = FALSE, zext = FALSE;
2933 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2935 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2937 if (sext || zext)
2938 dname = (char*)"";
2940 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)) {
2941 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2942 } else {
2943 /* _MEMBASE */
2944 base = lhs;
2946 if (ins->inst_offset == 0) {
2947 addr = base;
2948 } else if (ins->inst_offset % size != 0) {
2949 /* Unaligned load */
2950 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2951 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2952 } else {
2953 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2954 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
2958 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2960 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2962 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2964 * These will signal LLVM that these loads do not alias any stores, and
2965 * they can't fail, allowing them to be hoisted out of loops.
2967 set_metadata_flag (values [ins->dreg], "mono.noalias");
2968 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2971 if (sext)
2972 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2973 else if (zext)
2974 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2975 else if (ins->opcode == OP_LOADR4_MEMBASE)
2976 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2977 break;
2980 case OP_STOREI1_MEMBASE_REG:
2981 case OP_STOREI2_MEMBASE_REG:
2982 case OP_STOREI4_MEMBASE_REG:
2983 case OP_STOREI8_MEMBASE_REG:
2984 case OP_STORER4_MEMBASE_REG:
2985 case OP_STORER8_MEMBASE_REG:
2986 case OP_STORE_MEMBASE_REG: {
2987 int size = 8;
2988 LLVMValueRef index, addr;
2989 LLVMTypeRef t;
2990 gboolean sext = FALSE, zext = FALSE;
2991 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2993 if (!values [ins->inst_destbasereg])
2994 LLVM_FAILURE (ctx, "inst_destbasereg");
2996 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2998 if (ins->inst_offset % size != 0) {
2999 /* Unaligned store */
3000 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3001 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3002 } else {
3003 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3004 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3006 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3007 break;
3010 case OP_STOREI1_MEMBASE_IMM:
3011 case OP_STOREI2_MEMBASE_IMM:
3012 case OP_STOREI4_MEMBASE_IMM:
3013 case OP_STOREI8_MEMBASE_IMM:
3014 case OP_STORE_MEMBASE_IMM: {
3015 int size = 8;
3016 LLVMValueRef index, addr;
3017 LLVMTypeRef t;
3018 gboolean sext = FALSE, zext = FALSE;
3019 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3021 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3023 if (ins->inst_offset % size != 0) {
3024 /* Unaligned store */
3025 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3026 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3027 } else {
3028 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3029 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3031 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3032 break;
3035 case OP_CHECK_THIS:
3036 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3037 break;
3038 case OP_OUTARG_VTRETADDR:
3039 break;
3040 case OP_VOIDCALL:
3041 case OP_CALL:
3042 case OP_LCALL:
3043 case OP_FCALL:
3044 case OP_VCALL:
3045 case OP_VOIDCALL_MEMBASE:
3046 case OP_CALL_MEMBASE:
3047 case OP_LCALL_MEMBASE:
3048 case OP_FCALL_MEMBASE:
3049 case OP_VCALL_MEMBASE:
3050 case OP_VOIDCALL_REG:
3051 case OP_CALL_REG:
3052 case OP_LCALL_REG:
3053 case OP_FCALL_REG:
3054 case OP_VCALL_REG: {
3055 process_call (ctx, bb, &builder, ins);
3056 CHECK_FAILURE (ctx);
3057 break;
3059 case OP_AOTCONST: {
3060 guint32 got_offset;
3061 LLVMValueRef indexes [2];
3062 MonoJumpInfo *ji;
3063 LLVMValueRef got_entry_addr;
3066 * FIXME: Can't allocate from the cfg mempool since that is freed if
3067 * the LLVM compile fails.
3069 ji = g_new0 (MonoJumpInfo, 1);
3070 ji->type = (MonoJumpInfoType)ins->inst_i1;
3071 ji->data.target = ins->inst_p0;
3073 ji = mono_aot_patch_info_dup (ji);
3075 ji->next = cfg->patch_info;
3076 cfg->patch_info = ji;
3078 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3079 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3081 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3082 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3083 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3085 // FIXME: This doesn't work right now, because it must be
3086 // paired with an invariant.end, and even then, its only in effect
3087 // inside its basic block
3088 #if 0
3090 LLVMValueRef args [3];
3091 LLVMValueRef ptr, val;
3093 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3095 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3096 args [1] = ptr;
3097 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3099 #endif
3101 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3102 break;
3104 case OP_NOT_REACHED:
3105 LLVMBuildUnreachable (builder);
3106 has_terminator = TRUE;
3107 g_assert (bb->block_num < cfg->max_block_num);
3108 ctx->unreachable [bb->block_num] = TRUE;
3109 /* Might have instructions after this */
3110 while (ins->next) {
3111 MonoInst *next = ins->next;
3113 * FIXME: If later code uses the regs defined by these instructions,
3114 * compilation will fail.
3116 MONO_DELETE_INS (bb, next);
3118 break;
3119 case OP_LDADDR: {
3120 MonoInst *var = ins->inst_p0;
3122 values [ins->dreg] = addresses [var->dreg];
3123 break;
3125 case OP_SIN: {
3126 LLVMValueRef args [1];
3128 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3129 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3130 break;
3132 case OP_COS: {
3133 LLVMValueRef args [1];
3135 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3136 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3137 break;
3139 case OP_SQRT: {
3140 LLVMValueRef args [1];
3142 #if 0
3143 /* This no longer seems to happen */
3145 * LLVM optimizes sqrt(nan) into undefined in
3146 * lib/Analysis/ConstantFolding.cpp
3147 * Also, sqrt(NegativeInfinity) is optimized into 0.
3149 LLVM_FAILURE (ctx, "sqrt");
3150 #endif
3151 args [0] = lhs;
3152 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3153 break;
3155 case OP_ABS: {
3156 LLVMValueRef args [1];
3158 args [0] = lhs;
3159 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3160 break;
3163 case OP_IMIN:
3164 case OP_LMIN:
3165 case OP_IMAX:
3166 case OP_LMAX:
3167 case OP_IMIN_UN:
3168 case OP_LMIN_UN:
3169 case OP_IMAX_UN:
3170 case OP_LMAX_UN: {
3171 LLVMValueRef v;
3173 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3174 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3176 switch (ins->opcode) {
3177 case OP_IMIN:
3178 case OP_LMIN:
3179 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3180 break;
3181 case OP_IMAX:
3182 case OP_LMAX:
3183 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3184 break;
3185 case OP_IMIN_UN:
3186 case OP_LMIN_UN:
3187 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3188 break;
3189 case OP_IMAX_UN:
3190 case OP_LMAX_UN:
3191 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3192 break;
3193 default:
3194 g_assert_not_reached ();
3195 break;
3197 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3198 break;
3200 case OP_ATOMIC_EXCHANGE_I4: {
3201 LLVMValueRef args [2];
3203 g_assert (ins->inst_offset == 0);
3205 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3206 args [1] = rhs;
3208 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3209 break;
3211 case OP_ATOMIC_EXCHANGE_I8: {
3212 LLVMValueRef args [2];
3214 g_assert (ins->inst_offset == 0);
3216 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3217 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3218 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3219 break;
3221 case OP_ATOMIC_ADD_NEW_I4: {
3222 LLVMValueRef args [2];
3224 g_assert (ins->inst_offset == 0);
3226 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3227 args [1] = rhs;
3228 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3229 break;
3231 case OP_ATOMIC_ADD_NEW_I8: {
3232 LLVMValueRef args [2];
3234 g_assert (ins->inst_offset == 0);
3236 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3237 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3238 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3239 break;
3241 case OP_ATOMIC_CAS_I4:
3242 case OP_ATOMIC_CAS_I8: {
3243 LLVMValueRef args [3];
3244 LLVMTypeRef t;
3246 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3247 t = LLVMInt32Type ();
3248 } else {
3249 t = LLVMInt64Type ();
3252 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3253 /* comparand */
3254 args [1] = convert (ctx, values [ins->sreg3], t);
3255 /* new value */
3256 args [2] = convert (ctx, values [ins->sreg2], t);
3257 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3258 break;
3260 case OP_MEMORY_BARRIER: {
3261 mono_llvm_build_fence (builder);
3262 break;
3264 case OP_RELAXED_NOP: {
3265 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3266 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3267 break;
3268 #else
3269 break;
3270 #endif
3272 case OP_TLS_GET: {
3273 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3274 #ifdef TARGET_AMD64
3275 // 257 == FS segment register
3276 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3277 #else
3278 // 256 == GS segment register
3279 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3280 #endif
3282 // FIXME: XEN
3283 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3284 #else
3285 LLVM_FAILURE (ctx, "opcode tls-get");
3286 #endif
3288 break;
3292 * Overflow opcodes.
3294 case OP_IADD_OVF:
3295 case OP_IADD_OVF_UN:
3296 case OP_ISUB_OVF:
3297 case OP_ISUB_OVF_UN:
3298 case OP_IMUL_OVF:
3299 case OP_IMUL_OVF_UN:
3300 #if SIZEOF_VOID_P == 8
3301 case OP_LADD_OVF:
3302 case OP_LADD_OVF_UN:
3303 case OP_LSUB_OVF:
3304 case OP_LSUB_OVF_UN:
3305 case OP_LMUL_OVF:
3306 case OP_LMUL_OVF_UN:
3307 #endif
3309 LLVMValueRef args [2], val, ovf, func;
3311 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3312 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3313 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3314 g_assert (func);
3315 val = LLVMBuildCall (builder, func, args, 2, "");
3316 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3317 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3318 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3319 CHECK_FAILURE (ctx);
3320 builder = ctx->builder;
3321 break;
3325 * Valuetypes.
3326 * We currently model them using arrays. Promotion to local vregs is
3327 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3328 * so we always have an entry in cfg->varinfo for them.
3329 * FIXME: Is this needed ?
3331 case OP_VZERO: {
3332 MonoClass *klass = ins->klass;
3333 LLVMValueRef args [5];
3335 if (!klass) {
3336 // FIXME:
3337 LLVM_FAILURE (ctx, "!klass");
3338 break;
3341 if (!addresses [ins->dreg])
3342 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3343 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3344 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3345 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3346 // FIXME: Alignment
3347 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3348 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3349 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3350 break;
3353 case OP_STOREV_MEMBASE:
3354 case OP_LOADV_MEMBASE:
3355 case OP_VMOVE: {
3356 MonoClass *klass = ins->klass;
3357 LLVMValueRef src = NULL, dst, args [5];
3358 gboolean done = FALSE;
3360 if (!klass) {
3361 // FIXME:
3362 LLVM_FAILURE (ctx, "!klass");
3363 break;
3366 switch (ins->opcode) {
3367 case OP_STOREV_MEMBASE:
3368 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3369 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3370 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3371 break;
3373 if (!addresses [ins->sreg1]) {
3374 /* SIMD */
3375 g_assert (values [ins->sreg1]);
3376 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));
3377 LLVMBuildStore (builder, values [ins->sreg1], dst);
3378 done = TRUE;
3379 } else {
3380 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3381 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3383 break;
3384 case OP_LOADV_MEMBASE:
3385 if (!addresses [ins->dreg])
3386 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3387 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3388 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3389 break;
3390 case OP_VMOVE:
3391 if (!addresses [ins->sreg1])
3392 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3393 if (!addresses [ins->dreg])
3394 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3395 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3396 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3397 break;
3398 default:
3399 g_assert_not_reached ();
3401 CHECK_FAILURE (ctx);
3403 if (done)
3404 break;
3406 args [0] = dst;
3407 args [1] = src;
3408 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3409 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3410 // FIXME: Alignment
3411 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3412 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3413 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3414 break;
3416 case OP_LLVM_OUTARG_VT:
3417 if (!addresses [ins->sreg1]) {
3418 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3419 g_assert (values [ins->sreg1]);
3420 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3422 addresses [ins->dreg] = addresses [ins->sreg1];
3423 break;
3426 * SIMD
3428 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3429 case OP_XZERO: {
3430 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3431 break;
3433 case OP_LOADX_MEMBASE: {
3434 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3435 LLVMValueRef src;
3437 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3438 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3439 break;
3441 case OP_STOREX_MEMBASE: {
3442 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3443 LLVMValueRef dest;
3445 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3446 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3447 break;
3449 case OP_PADDB:
3450 case OP_PADDW:
3451 case OP_PADDD:
3452 case OP_PADDQ:
3453 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3454 break;
3455 case OP_ADDPD:
3456 case OP_ADDPS:
3457 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3458 break;
3459 case OP_PSUBB:
3460 case OP_PSUBW:
3461 case OP_PSUBD:
3462 case OP_PSUBQ:
3463 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3464 break;
3465 case OP_SUBPD:
3466 case OP_SUBPS:
3467 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3468 break;
3469 case OP_MULPD:
3470 case OP_MULPS:
3471 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3472 break;
3473 case OP_DIVPD:
3474 case OP_DIVPS:
3475 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3476 break;
3477 case OP_PAND:
3478 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3479 break;
3480 case OP_POR:
3481 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3482 break;
3483 case OP_PXOR:
3484 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3485 break;
3486 case OP_PMULW:
3487 case OP_PMULD:
3488 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3489 break;
3490 case OP_ANDPS:
3491 case OP_ANDNPS:
3492 case OP_ORPS:
3493 case OP_XORPS:
3494 case OP_ANDPD:
3495 case OP_ANDNPD:
3496 case OP_ORPD:
3497 case OP_XORPD: {
3498 LLVMTypeRef t, rt;
3499 LLVMValueRef v = NULL;
3501 switch (ins->opcode) {
3502 case OP_ANDPS:
3503 case OP_ANDNPS:
3504 case OP_ORPS:
3505 case OP_XORPS:
3506 t = LLVMVectorType (LLVMInt32Type (), 4);
3507 rt = LLVMVectorType (LLVMFloatType (), 4);
3508 break;
3509 case OP_ANDPD:
3510 case OP_ANDNPD:
3511 case OP_ORPD:
3512 case OP_XORPD:
3513 t = LLVMVectorType (LLVMInt64Type (), 2);
3514 rt = LLVMVectorType (LLVMDoubleType (), 2);
3515 break;
3516 default:
3517 t = LLVMInt32Type ();
3518 rt = LLVMInt32Type ();
3519 g_assert_not_reached ();
3522 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3523 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3524 switch (ins->opcode) {
3525 case OP_ANDPS:
3526 case OP_ANDPD:
3527 v = LLVMBuildAnd (builder, lhs, rhs, "");
3528 break;
3529 case OP_ORPS:
3530 case OP_ORPD:
3531 v = LLVMBuildOr (builder, lhs, rhs, "");
3532 break;
3533 case OP_XORPS:
3534 case OP_XORPD:
3535 v = LLVMBuildXor (builder, lhs, rhs, "");
3536 break;
3537 case OP_ANDNPS:
3538 case OP_ANDNPD:
3539 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3540 break;
3542 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3543 break;
3545 case OP_MINPD:
3546 case OP_MINPS:
3547 case OP_MAXPD:
3548 case OP_MAXPS:
3549 case OP_ADDSUBPD:
3550 case OP_ADDSUBPS:
3551 case OP_PMIND_UN:
3552 case OP_PMINW_UN:
3553 case OP_PMINB_UN:
3554 case OP_PMINW:
3555 case OP_PMAXD_UN:
3556 case OP_PMAXW_UN:
3557 case OP_PMAXB_UN:
3558 case OP_HADDPD:
3559 case OP_HADDPS:
3560 case OP_HSUBPD:
3561 case OP_HSUBPS:
3562 case OP_PADDB_SAT:
3563 case OP_PADDW_SAT:
3564 case OP_PSUBB_SAT:
3565 case OP_PSUBW_SAT:
3566 case OP_PADDB_SAT_UN:
3567 case OP_PADDW_SAT_UN:
3568 case OP_PSUBB_SAT_UN:
3569 case OP_PSUBW_SAT_UN:
3570 case OP_PAVGB_UN:
3571 case OP_PAVGW_UN:
3572 case OP_PCMPEQB:
3573 case OP_PCMPEQW:
3574 case OP_PCMPEQD:
3575 case OP_PCMPEQQ:
3576 case OP_PCMPGTB:
3577 case OP_PACKW:
3578 case OP_PACKD:
3579 case OP_PACKW_UN:
3580 case OP_PACKD_UN:
3581 case OP_PMULW_HIGH:
3582 case OP_PMULW_HIGH_UN: {
3583 LLVMValueRef args [2];
3585 args [0] = lhs;
3586 args [1] = rhs;
3588 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3589 break;
3591 case OP_EXTRACT_R8:
3592 case OP_EXTRACT_I8:
3593 case OP_EXTRACT_I4:
3594 case OP_EXTRACT_I2:
3595 case OP_EXTRACT_U2:
3596 case OP_EXTRACTX_U2:
3597 case OP_EXTRACT_I1:
3598 case OP_EXTRACT_U1: {
3599 LLVMTypeRef t;
3600 gboolean zext = FALSE;
3602 t = simd_op_to_llvm_type (ins->opcode);
3604 switch (ins->opcode) {
3605 case OP_EXTRACT_R8:
3606 case OP_EXTRACT_I8:
3607 case OP_EXTRACT_I4:
3608 case OP_EXTRACT_I2:
3609 case OP_EXTRACT_I1:
3610 break;
3611 case OP_EXTRACT_U2:
3612 case OP_EXTRACTX_U2:
3613 case OP_EXTRACT_U1:
3614 zext = TRUE;
3615 break;
3616 default:
3617 t = LLVMInt32Type ();
3618 g_assert_not_reached ();
3621 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3622 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3623 if (zext)
3624 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3625 break;
3628 case OP_EXPAND_I1:
3629 case OP_EXPAND_I2:
3630 case OP_EXPAND_I4:
3631 case OP_EXPAND_I8:
3632 case OP_EXPAND_R4:
3633 case OP_EXPAND_R8: {
3634 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3635 LLVMValueRef mask [16], v;
3637 for (i = 0; i < 16; ++i)
3638 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3640 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3642 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3643 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3644 break;
3647 case OP_INSERT_I1:
3648 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3649 break;
3650 case OP_INSERT_I2:
3651 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3652 break;
3653 case OP_INSERT_I4:
3654 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3655 break;
3656 case OP_INSERT_I8:
3657 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3658 break;
3659 case OP_INSERT_R4:
3660 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3661 break;
3662 case OP_INSERT_R8:
3663 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3664 break;
3666 case OP_CVTDQ2PD:
3667 case OP_CVTDQ2PS:
3668 case OP_CVTPD2DQ:
3669 case OP_CVTPS2DQ:
3670 case OP_CVTPD2PS:
3671 case OP_CVTPS2PD:
3672 case OP_CVTTPD2DQ:
3673 case OP_CVTTPS2DQ:
3674 case OP_EXTRACT_MASK:
3675 case OP_SQRTPS:
3676 case OP_SQRTPD:
3677 case OP_RSQRTPS:
3678 case OP_RCPPS: {
3679 LLVMValueRef v;
3681 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3683 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3684 break;
3687 case OP_ICONV_TO_R8_RAW:
3688 /* Same as OP_ICONV_TO_R8 */
3689 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3690 break;
3692 case OP_COMPPS:
3693 case OP_COMPPD: {
3694 LLVMValueRef args [3];
3696 args [0] = lhs;
3697 args [1] = rhs;
3698 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3700 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3701 break;
3704 case OP_ICONV_TO_X:
3705 /* This is only used for implementing shifts by non-immediate */
3706 values [ins->dreg] = lhs;
3707 break;
3709 case OP_PSHRW:
3710 case OP_PSHRD:
3711 case OP_PSHRQ:
3712 case OP_PSARW:
3713 case OP_PSARD:
3714 case OP_PSHLW:
3715 case OP_PSHLD:
3716 case OP_PSHLQ: {
3717 LLVMValueRef args [3];
3719 args [0] = lhs;
3720 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3722 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3723 break;
3726 case OP_PSHRW_REG:
3727 case OP_PSHRD_REG:
3728 case OP_PSHRQ_REG:
3729 case OP_PSARW_REG:
3730 case OP_PSARD_REG:
3731 case OP_PSHLW_REG:
3732 case OP_PSHLD_REG:
3733 case OP_PSHLQ_REG: {
3734 LLVMValueRef args [3];
3736 args [0] = lhs;
3737 args [1] = values [ins->sreg2];
3739 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3740 break;
3743 case OP_SHUFPS:
3744 case OP_SHUFPD:
3745 case OP_PSHUFLED:
3746 case OP_PSHUFLEW_LOW:
3747 case OP_PSHUFLEW_HIGH: {
3748 int mask [16];
3749 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [4];
3750 int i, mask_size = 0;
3751 int imask = ins->inst_c0;
3753 /* Convert the x86 shuffle mask to LLVM's */
3754 switch (ins->opcode) {
3755 case OP_SHUFPS:
3756 mask_size = 4;
3757 mask [0] = ((imask >> 0) & 3);
3758 mask [1] = ((imask >> 2) & 3);
3759 mask [2] = ((imask >> 4) & 3) + 4;
3760 mask [3] = ((imask >> 6) & 3) + 4;
3761 v1 = values [ins->sreg1];
3762 v2 = values [ins->sreg2];
3763 break;
3764 case OP_SHUFPD:
3765 mask_size = 2;
3766 mask [0] = ((imask >> 0) & 1);
3767 mask [1] = ((imask >> 1) & 1) + 2;
3768 v1 = values [ins->sreg1];
3769 v2 = values [ins->sreg2];
3770 break;
3771 case OP_PSHUFLEW_LOW:
3772 mask_size = 8;
3773 mask [0] = ((imask >> 0) & 3);
3774 mask [1] = ((imask >> 2) & 3);
3775 mask [2] = ((imask >> 4) & 3);
3776 mask [3] = ((imask >> 6) & 3);
3777 mask [4] = 4 + 0;
3778 mask [5] = 4 + 1;
3779 mask [6] = 4 + 2;
3780 mask [7] = 4 + 3;
3781 v1 = values [ins->sreg1];
3782 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3783 break;
3784 case OP_PSHUFLEW_HIGH:
3785 mask_size = 8;
3786 mask [0] = 0;
3787 mask [1] = 1;
3788 mask [2] = 2;
3789 mask [3] = 3;
3790 mask [4] = 4 + ((imask >> 0) & 3);
3791 mask [5] = 4 + ((imask >> 2) & 3);
3792 mask [6] = 4 + ((imask >> 4) & 3);
3793 mask [7] = 4 + ((imask >> 6) & 3);
3794 v1 = values [ins->sreg1];
3795 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3796 break;
3797 case OP_PSHUFLED:
3798 mask_size = 4;
3799 mask [0] = ((imask >> 0) & 3);
3800 mask [1] = ((imask >> 2) & 3);
3801 mask [2] = ((imask >> 4) & 3);
3802 mask [3] = ((imask >> 6) & 3);
3803 v1 = values [ins->sreg1];
3804 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3805 break;
3806 default:
3807 g_assert_not_reached ();
3809 for (i = 0; i < mask_size; ++i)
3810 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3812 values [ins->dreg] =
3813 LLVMBuildShuffleVector (builder, v1, v2,
3814 LLVMConstVector (mask_values, mask_size), dname);
3815 break;
3818 case OP_UNPACK_LOWB:
3819 case OP_UNPACK_LOWW:
3820 case OP_UNPACK_LOWD:
3821 case OP_UNPACK_LOWQ:
3822 case OP_UNPACK_LOWPS:
3823 case OP_UNPACK_LOWPD:
3824 case OP_UNPACK_HIGHB:
3825 case OP_UNPACK_HIGHW:
3826 case OP_UNPACK_HIGHD:
3827 case OP_UNPACK_HIGHQ:
3828 case OP_UNPACK_HIGHPS:
3829 case OP_UNPACK_HIGHPD: {
3830 int mask [16];
3831 LLVMValueRef mask_values [16];
3832 int i, mask_size = 0;
3833 gboolean low = FALSE;
3835 switch (ins->opcode) {
3836 case OP_UNPACK_LOWB:
3837 mask_size = 16;
3838 low = TRUE;
3839 break;
3840 case OP_UNPACK_LOWW:
3841 mask_size = 8;
3842 low = TRUE;
3843 break;
3844 case OP_UNPACK_LOWD:
3845 case OP_UNPACK_LOWPS:
3846 mask_size = 4;
3847 low = TRUE;
3848 break;
3849 case OP_UNPACK_LOWQ:
3850 case OP_UNPACK_LOWPD:
3851 mask_size = 2;
3852 low = TRUE;
3853 break;
3854 case OP_UNPACK_HIGHB:
3855 mask_size = 16;
3856 break;
3857 case OP_UNPACK_HIGHW:
3858 mask_size = 8;
3859 break;
3860 case OP_UNPACK_HIGHD:
3861 case OP_UNPACK_HIGHPS:
3862 mask_size = 4;
3863 break;
3864 case OP_UNPACK_HIGHQ:
3865 case OP_UNPACK_HIGHPD:
3866 mask_size = 2;
3867 break;
3868 default:
3869 g_assert_not_reached ();
3872 if (low) {
3873 for (i = 0; i < (mask_size / 2); ++i) {
3874 mask [(i * 2)] = i;
3875 mask [(i * 2) + 1] = mask_size + i;
3877 } else {
3878 for (i = 0; i < (mask_size / 2); ++i) {
3879 mask [(i * 2)] = (mask_size / 2) + i;
3880 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3884 for (i = 0; i < mask_size; ++i)
3885 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3887 values [ins->dreg] =
3888 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3889 LLVMConstVector (mask_values, mask_size), dname);
3890 break;
3893 case OP_DUPPD: {
3894 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3895 LLVMValueRef v, val;
3897 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3898 val = LLVMConstNull (t);
3899 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3900 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3902 values [ins->dreg] = val;
3903 break;
3905 case OP_DUPPS_LOW:
3906 case OP_DUPPS_HIGH: {
3907 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3908 LLVMValueRef v1, v2, val;
3911 if (ins->opcode == OP_DUPPS_LOW) {
3912 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3913 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3914 } else {
3915 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3916 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3918 val = LLVMConstNull (t);
3919 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3920 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
3921 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
3922 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
3924 values [ins->dreg] = val;
3925 break;
3928 #endif /* SIMD */
3930 case OP_DUMMY_USE:
3931 break;
3934 * EXCEPTION HANDLING
3936 case OP_IMPLICIT_EXCEPTION:
3937 /* This marks a place where an implicit exception can happen */
3938 if (bb->region != -1)
3939 LLVM_FAILURE (ctx, "implicit-exception");
3940 break;
3941 case OP_THROW:
3942 case OP_RETHROW: {
3943 MonoMethodSignature *throw_sig;
3944 LLVMValueRef callee, arg;
3945 gboolean rethrow = (ins->opcode == OP_RETHROW);
3946 const char *icall_name;
3948 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3949 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3951 if (!callee) {
3952 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3953 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3954 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3955 if (cfg->compile_aot) {
3956 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3957 } else {
3958 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3960 #ifdef TARGET_X86
3962 * LLVM doesn't push the exception argument, so we need a different
3963 * trampoline.
3965 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3966 #else
3967 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3968 #endif
3971 mono_memory_barrier ();
3972 if (rethrow)
3973 ctx->lmodule->rethrow = callee;
3974 else
3975 ctx->lmodule->throw = callee;
3977 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3978 emit_call (ctx, bb, &builder, callee, &arg, 1);
3979 break;
3981 case OP_CALL_HANDLER: {
3983 * We don't 'call' handlers, but instead simply branch to them.
3984 * The code generated by ENDFINALLY will branch back to us.
3986 LLVMBasicBlockRef noex_bb;
3987 GSList *bb_list;
3988 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
3990 bb_list = info->call_handler_return_bbs;
3993 * Set the indicator variable for the finally clause.
3995 lhs = info->finally_ind;
3996 g_assert (lhs);
3997 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
3999 /* Branch to the finally clause */
4000 LLVMBuildBr (builder, info->call_handler_target_bb);
4002 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4003 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4005 builder = ctx->builder = create_builder (ctx);
4006 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4008 bblocks [bb->block_num].end_bblock = noex_bb;
4009 break;
4011 case OP_START_HANDLER: {
4012 break;
4014 case OP_ENDFINALLY: {
4015 LLVMBasicBlockRef resume_bb;
4016 MonoBasicBlock *handler_bb;
4017 LLVMValueRef val, switch_ins, callee;
4018 GSList *bb_list;
4019 BBInfo *info;
4021 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4022 g_assert (handler_bb);
4023 info = &bblocks [handler_bb->block_num];
4024 lhs = info->finally_ind;
4025 g_assert (lhs);
4027 bb_list = info->call_handler_return_bbs;
4029 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4031 /* Load the finally variable */
4032 val = LLVMBuildLoad (builder, lhs, "");
4034 /* Reset the variable */
4035 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4037 /* Branch to either resume_bb, or to the bblocks in bb_list */
4038 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4040 * The other targets are added at the end to handle OP_CALL_HANDLER
4041 * opcodes processed later.
4043 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4045 builder = ctx->builder = create_builder (ctx);
4046 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4048 if (ctx->cfg->compile_aot) {
4049 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4050 } else {
4051 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4053 LLVMBuildCall (builder, callee, NULL, 0, "");
4055 LLVMBuildUnreachable (builder);
4056 has_terminator = TRUE;
4057 break;
4059 default: {
4060 char reason [128];
4062 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4063 LLVM_FAILURE (ctx, reason);
4064 break;
4068 /* Convert the value to the type required by phi nodes */
4069 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4070 if (!values [ins->dreg])
4071 /* vtypes */
4072 values [ins->dreg] = addresses [ins->dreg];
4073 else
4074 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4077 /* Add stores for volatile variables */
4078 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4079 emit_volatile_store (ctx, ins->dreg);
4082 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4083 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4085 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4086 LLVMBuildRetVoid (builder);
4088 if (bb == cfg->bb_entry)
4089 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4091 return;
4093 FAILURE:
4094 return;
4098 * mono_llvm_check_method_supported:
4100 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4101 * compiling a method twice.
4103 void
4104 mono_llvm_check_method_supported (MonoCompile *cfg)
4107 MonoMethodHeader *header = cfg->header;
4108 MonoExceptionClause *clause;
4109 int i;
4112 if (cfg->method->save_lmf) {
4113 cfg->exception_message = g_strdup ("lmf");
4114 cfg->disable_llvm = TRUE;
4117 #if 0
4118 for (i = 0; i < header->num_clauses; ++i) {
4119 clause = &header->clauses [i];
4121 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4123 * FIXME: Some tests still fail with nested clauses.
4125 cfg->exception_message = g_strdup ("nested clauses");
4126 cfg->disable_llvm = TRUE;
4129 #endif
4131 /* FIXME: */
4132 if (cfg->method->dynamic) {
4133 cfg->exception_message = g_strdup ("dynamic.");
4134 cfg->disable_llvm = TRUE;
4139 * mono_llvm_emit_method:
4141 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4143 void
4144 mono_llvm_emit_method (MonoCompile *cfg)
4146 EmitContext *ctx;
4147 MonoMethodSignature *sig;
4148 MonoBasicBlock *bb;
4149 LLVMTypeRef method_type;
4150 LLVMValueRef method = NULL;
4151 char *method_name;
4152 LLVMValueRef *values;
4153 int i, max_block_num, bb_index;
4154 gboolean last = FALSE;
4155 GPtrArray *phi_values;
4156 LLVMCallInfo *linfo;
4157 GSList *l;
4158 LLVMModuleRef module;
4159 BBInfo *bblocks;
4160 GPtrArray *bblock_list;
4161 MonoMethodHeader *header;
4162 MonoExceptionClause *clause;
4163 LLVMSigInfo sinfo;
4164 char **names;
4166 /* The code below might acquire the loader lock, so use it for global locking */
4167 mono_loader_lock ();
4169 /* Used to communicate with the callbacks */
4170 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4172 ctx = g_new0 (EmitContext, 1);
4173 ctx->cfg = cfg;
4174 ctx->mempool = cfg->mempool;
4177 * This maps vregs to the LLVM instruction defining them
4179 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4181 * This maps vregs for volatile variables to the LLVM instruction defining their
4182 * address.
4184 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4185 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4186 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4187 phi_values = g_ptr_array_new ();
4189 * This signals whenever the vreg was defined by a phi node with no input vars
4190 * (i.e. all its input bblocks end with NOT_REACHABLE).
4192 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4193 /* Whenever the bblock is unreachable */
4194 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4196 bblock_list = g_ptr_array_new ();
4198 ctx->values = values;
4199 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4201 if (cfg->compile_aot) {
4202 ctx->lmodule = &aot_module;
4203 method_name = mono_aot_get_method_name (cfg);
4204 cfg->llvm_method_name = g_strdup (method_name);
4205 } else {
4206 init_jit_module ();
4207 ctx->lmodule = &jit_module;
4208 method_name = mono_method_full_name (cfg->method, TRUE);
4211 module = ctx->module = ctx->lmodule->module;
4213 #if 1
4215 static int count = 0;
4216 count ++;
4218 if (getenv ("LLVM_COUNT")) {
4219 if (count == atoi (getenv ("LLVM_COUNT"))) {
4220 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4221 fflush (stdout);
4222 last = TRUE;
4224 if (count > atoi (getenv ("LLVM_COUNT")))
4225 LLVM_FAILURE (ctx, "");
4228 #endif
4230 sig = mono_method_signature (cfg->method);
4231 ctx->sig = sig;
4233 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4234 ctx->linfo = linfo;
4235 CHECK_FAILURE (ctx);
4237 if (cfg->rgctx_var)
4238 linfo->rgctx_arg = TRUE;
4239 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4240 CHECK_FAILURE (ctx);
4243 * This maps parameter indexes in the original signature to the indexes in
4244 * the LLVM signature.
4246 ctx->pindexes = sinfo.pindexes;
4248 method = LLVMAddFunction (module, method_name, method_type);
4249 ctx->lmethod = method;
4251 #ifdef LLVM_MONO_BRANCH
4252 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4253 #endif
4254 LLVMSetLinkage (method, LLVMPrivateLinkage);
4256 LLVMAddFunctionAttr (method, LLVMUWTable);
4258 if (cfg->compile_aot) {
4259 LLVMSetLinkage (method, LLVMInternalLinkage);
4260 LLVMSetVisibility (method, LLVMHiddenVisibility);
4261 } else {
4262 LLVMSetLinkage (method, LLVMPrivateLinkage);
4265 if (cfg->method->save_lmf)
4266 LLVM_FAILURE (ctx, "lmf");
4268 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4269 LLVM_FAILURE (ctx, "pinvoke signature");
4271 header = cfg->header;
4272 for (i = 0; i < header->num_clauses; ++i) {
4273 clause = &header->clauses [i];
4274 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4275 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4278 if (linfo->rgctx_arg) {
4279 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4281 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4282 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4283 * CC_X86_64_Mono in X86CallingConv.td.
4285 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4286 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4288 if (cfg->vret_addr) {
4289 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4290 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4292 if (sig->hasthis) {
4293 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4294 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4297 names = g_new (char *, sig->param_count);
4298 mono_method_get_param_names (cfg->method, (const char **) names);
4300 for (i = 0; i < sig->param_count; ++i) {
4301 char *name;
4303 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4304 if (names [i] && names [i][0] != '\0')
4305 name = g_strdup_printf ("arg_%s", names [i]);
4306 else
4307 name = g_strdup_printf ("arg_%d", i);
4308 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4309 g_free (name);
4310 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4311 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4313 g_free (names);
4315 max_block_num = 0;
4316 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4317 max_block_num = MAX (max_block_num, bb->block_num);
4318 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4320 /* Add branches between non-consecutive bblocks */
4321 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4322 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4323 bb->next_bb != bb->last_ins->inst_false_bb) {
4325 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4326 inst->opcode = OP_BR;
4327 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4328 mono_bblock_add_inst (bb, inst);
4333 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4334 * was later optimized away, so clear these flags, and add them back for the still
4335 * present OP_LDADDR instructions.
4337 for (i = 0; i < cfg->next_vreg; ++i) {
4338 MonoInst *ins;
4340 ins = get_vreg_to_inst (cfg, i);
4341 if (ins && ins != cfg->rgctx_var)
4342 ins->flags &= ~MONO_INST_INDIRECT;
4346 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4348 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4349 MonoInst *ins;
4350 LLVMBuilderRef builder;
4351 char *dname;
4352 char dname_buf[128];
4354 builder = create_builder (ctx);
4356 for (ins = bb->code; ins; ins = ins->next) {
4357 switch (ins->opcode) {
4358 case OP_PHI:
4359 case OP_FPHI:
4360 case OP_VPHI:
4361 case OP_XPHI: {
4362 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4364 CHECK_FAILURE (ctx);
4366 if (ins->opcode == OP_VPHI) {
4367 /* Treat valuetype PHI nodes as operating on the address itself */
4368 g_assert (ins->klass);
4369 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4373 * Have to precreate these, as they can be referenced by
4374 * earlier instructions.
4376 sprintf (dname_buf, "t%d", ins->dreg);
4377 dname = dname_buf;
4378 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4380 if (ins->opcode == OP_VPHI)
4381 ctx->addresses [ins->dreg] = values [ins->dreg];
4383 g_ptr_array_add (phi_values, values [ins->dreg]);
4386 * Set the expected type of the incoming arguments since these have
4387 * to have the same type.
4389 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4390 int sreg1 = ins->inst_phi_args [i + 1];
4392 if (sreg1 != -1)
4393 ctx->vreg_types [sreg1] = phi_type;
4395 break;
4397 case OP_LDADDR:
4398 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4399 break;
4400 default:
4401 break;
4407 * Create an ordering for bblocks, use the depth first order first, then
4408 * put the exception handling bblocks last.
4410 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4411 bb = cfg->bblocks [bb_index];
4412 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4413 g_ptr_array_add (bblock_list, bb);
4414 bblocks [bb->block_num].added = TRUE;
4418 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4419 if (!bblocks [bb->block_num].added)
4420 g_ptr_array_add (bblock_list, bb);
4424 * Second pass: generate code.
4426 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4427 bb = g_ptr_array_index (bblock_list, bb_index);
4429 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4430 continue;
4432 process_bb (ctx, bb);
4433 CHECK_FAILURE (ctx);
4436 /* Add incoming phi values */
4437 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4438 GSList *l, *ins_list;
4440 ins_list = bblocks [bb->block_num].phi_nodes;
4442 for (l = ins_list; l; l = l->next) {
4443 PhiNode *node = l->data;
4444 MonoInst *phi = node->phi;
4445 int sreg1 = node->sreg;
4446 LLVMBasicBlockRef in_bb;
4448 if (sreg1 == -1)
4449 continue;
4451 in_bb = get_end_bb (ctx, node->in_bb);
4453 if (ctx->unreachable [node->in_bb->block_num])
4454 continue;
4456 g_assert (values [sreg1]);
4458 if (phi->opcode == OP_VPHI) {
4459 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4460 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4461 } else {
4462 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4463 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4468 /* Create the SWITCH statements for ENDFINALLY instructions */
4469 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4470 BBInfo *info = &bblocks [bb->block_num];
4471 GSList *l;
4472 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4473 LLVMValueRef switch_ins = l->data;
4474 GSList *bb_list = info->call_handler_return_bbs;
4476 for (i = 0; i < g_slist_length (bb_list); ++i)
4477 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4481 if (cfg->verbose_level > 1)
4482 mono_llvm_dump_value (method);
4484 mark_as_used (module, method);
4486 if (cfg->compile_aot) {
4487 /* Don't generate native code, keep the LLVM IR */
4488 if (cfg->compile_aot && cfg->verbose_level)
4489 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4491 //LLVMVerifyFunction(method, 0);
4492 } else {
4493 mono_llvm_optimize_method (method);
4495 if (cfg->verbose_level > 1)
4496 mono_llvm_dump_value (method);
4498 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4500 /* Set by emit_cb */
4501 g_assert (cfg->code_len);
4503 /* FIXME: Free the LLVM IL for the function */
4506 goto CLEANUP;
4508 FAILURE:
4510 if (method) {
4511 /* Need to add unused phi nodes as they can be referenced by other values */
4512 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4513 LLVMBuilderRef builder;
4515 builder = create_builder (ctx);
4516 LLVMPositionBuilderAtEnd (builder, phi_bb);
4518 for (i = 0; i < phi_values->len; ++i) {
4519 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4520 if (LLVMGetInstructionParent (v) == NULL)
4521 LLVMInsertIntoBuilder (builder, v);
4524 LLVMDeleteFunction (method);
4527 CLEANUP:
4528 g_free (values);
4529 g_free (ctx->addresses);
4530 g_free (ctx->vreg_types);
4531 g_free (ctx->vreg_cli_types);
4532 g_free (ctx->pindexes);
4533 g_free (ctx->is_dead);
4534 g_free (ctx->unreachable);
4535 g_ptr_array_free (phi_values, TRUE);
4536 g_free (ctx->bblocks);
4537 g_hash_table_destroy (ctx->region_to_handler);
4538 g_free (method_name);
4539 g_ptr_array_free (bblock_list, TRUE);
4541 for (l = ctx->builders; l; l = l->next) {
4542 LLVMBuilderRef builder = l->data;
4543 LLVMDisposeBuilder (builder);
4546 g_free (ctx);
4548 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4550 mono_loader_unlock ();
4554 * mono_llvm_emit_call:
4556 * Same as mono_arch_emit_call () for LLVM.
4558 void
4559 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4561 MonoInst *in;
4562 MonoMethodSignature *sig;
4563 int i, n, stack_size;
4564 LLVMArgInfo *ainfo;
4566 stack_size = 0;
4568 sig = call->signature;
4569 n = sig->param_count + sig->hasthis;
4571 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4573 if (cfg->disable_llvm)
4574 return;
4576 if (sig->call_convention == MONO_CALL_VARARG) {
4577 cfg->exception_message = g_strdup ("varargs");
4578 cfg->disable_llvm = TRUE;
4581 for (i = 0; i < n; ++i) {
4582 MonoInst *ins;
4584 ainfo = call->cinfo->args + i;
4586 in = call->args [i];
4588 /* Simply remember the arguments */
4589 switch (ainfo->storage) {
4590 case LLVMArgInIReg:
4591 case LLVMArgInFPReg: {
4592 MonoType *t = (sig->hasthis && i == 0) ? &mono_defaults.int_class->byval_arg : sig->params [i - sig->hasthis];
4594 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4595 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4596 ins->dreg = mono_alloc_freg (cfg);
4597 } else {
4598 MONO_INST_NEW (cfg, ins, OP_MOVE);
4599 ins->dreg = mono_alloc_ireg (cfg);
4601 ins->sreg1 = in->dreg;
4602 break;
4604 case LLVMArgVtypeByVal:
4605 case LLVMArgVtypeInReg:
4606 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4607 ins->dreg = mono_alloc_ireg (cfg);
4608 ins->sreg1 = in->dreg;
4609 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4610 break;
4611 default:
4612 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4613 cfg->exception_message = g_strdup ("ainfo->storage");
4614 cfg->disable_llvm = TRUE;
4615 return;
4618 if (!cfg->disable_llvm) {
4619 MONO_ADD_INS (cfg->cbb, ins);
4620 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4625 static unsigned char*
4626 alloc_cb (LLVMValueRef function, int size)
4628 MonoCompile *cfg;
4630 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4632 if (cfg) {
4633 // FIXME: dynamic
4634 return mono_domain_code_reserve (cfg->domain, size);
4635 } else {
4636 return mono_domain_code_reserve (mono_domain_get (), size);
4640 static void
4641 emitted_cb (LLVMValueRef function, void *start, void *end)
4643 MonoCompile *cfg;
4645 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4646 g_assert (cfg);
4647 cfg->code_len = (guint8*)end - (guint8*)start;
4650 static void
4651 exception_cb (void *data)
4653 MonoCompile *cfg;
4654 MonoJitExceptionInfo *ei;
4655 guint32 ei_len, i, j, nested_len, nindex;
4656 gpointer *type_info;
4657 int this_reg, this_offset;
4659 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4660 g_assert (cfg);
4663 * data points to a DWARF FDE structure, convert it to our unwind format and
4664 * save it.
4665 * An alternative would be to save it directly, and modify our unwinder to work
4666 * with it.
4668 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);
4670 /* Count nested clauses */
4671 nested_len = 0;
4672 for (i = 0; i < ei_len; ++i) {
4673 for (j = 0; j < ei_len; ++j) {
4674 gint32 cindex1 = *(gint32*)type_info [i];
4675 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4676 gint32 cindex2 = *(gint32*)type_info [j];
4677 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4679 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4680 nested_len ++;
4685 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4686 cfg->llvm_ex_info_len = ei_len + nested_len;
4687 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4688 /* Fill the rest of the information from the type info */
4689 for (i = 0; i < ei_len; ++i) {
4690 gint32 clause_index = *(gint32*)type_info [i];
4691 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4693 cfg->llvm_ex_info [i].flags = clause->flags;
4694 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4698 * For nested clauses, the LLVM produced exception info associates the try interval with
4699 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4701 /* FIXME: These should be order with the normal clauses */
4702 nindex = ei_len;
4703 for (i = 0; i < ei_len; ++i) {
4704 for (j = 0; j < ei_len; ++j) {
4705 gint32 cindex1 = *(gint32*)type_info [i];
4706 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4707 gint32 cindex2 = *(gint32*)type_info [j];
4708 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4710 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4712 * The try interval comes from the nested clause, everything else from the
4713 * nesting clause.
4715 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4716 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4717 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4718 nindex ++;
4722 g_assert (nindex == ei_len + nested_len);
4723 cfg->llvm_this_reg = this_reg;
4724 cfg->llvm_this_offset = this_offset;
4726 /* type_info [i] is cfg mempool allocated, no need to free it */
4728 g_free (ei);
4729 g_free (type_info);
4732 static inline void
4733 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4735 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4738 static inline void
4739 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4741 LLVMTypeRef param_types [4];
4743 param_types [0] = param_type1;
4744 param_types [1] = param_type2;
4746 AddFunc (module, name, ret_type, param_types, 2);
4749 static void
4750 add_intrinsics (LLVMModuleRef module)
4752 /* Emit declarations of instrinsics */
4754 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4755 * type doesn't seem to do any locking.
4758 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4760 memset_param_count = 5;
4761 memset_func_name = "llvm.memset.p0i8.i32";
4763 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4767 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4769 memcpy_param_count = 5;
4770 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4772 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4776 LLVMTypeRef params [] = { LLVMDoubleType () };
4778 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4779 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4780 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4782 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4783 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4787 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4788 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4790 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4791 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4792 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4793 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4794 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4795 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4799 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4800 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4802 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4803 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4804 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4805 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4806 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4807 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4811 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4812 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4813 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4815 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4817 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4820 /* EH intrinsics */
4822 LLVMTypeRef arg_types [2];
4823 LLVMTypeRef ret_type;
4825 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4826 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4827 ret_type = LLVMInt32Type ();
4829 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4831 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4834 /* SSE intrinsics */
4836 LLVMTypeRef ret_type, arg_types [16];
4838 /* Binary ops */
4839 ret_type = type_to_simd_type (MONO_TYPE_I4);
4840 arg_types [0] = ret_type;
4841 arg_types [1] = ret_type;
4842 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4843 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4844 AddFunc (module, "llvm.x86.sse2.pcmpeq.d", ret_type, arg_types, 2);
4846 ret_type = type_to_simd_type (MONO_TYPE_I2);
4847 arg_types [0] = ret_type;
4848 arg_types [1] = ret_type;
4849 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4850 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4851 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4852 AddFunc (module, "llvm.x86.sse2.pcmpeq.w", ret_type, arg_types, 2);
4853 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4854 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4855 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4856 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4857 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4858 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4859 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4861 ret_type = type_to_simd_type (MONO_TYPE_I1);
4862 arg_types [0] = ret_type;
4863 arg_types [1] = ret_type;
4864 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4865 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4866 AddFunc (module, "llvm.x86.sse2.pcmpeq.b", ret_type, arg_types, 2);
4867 AddFunc (module, "llvm.x86.sse2.pcmpgt.b", ret_type, arg_types, 2);
4868 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4869 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4870 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4871 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4872 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4874 ret_type = type_to_simd_type (MONO_TYPE_I8);
4875 arg_types [0] = ret_type;
4876 arg_types [1] = ret_type;
4877 AddFunc (module, "llvm.x86.sse41.pcmpeqq", ret_type, arg_types, 2);
4879 ret_type = type_to_simd_type (MONO_TYPE_R8);
4880 arg_types [0] = ret_type;
4881 arg_types [1] = ret_type;
4882 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4883 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4884 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4885 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4886 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4888 ret_type = type_to_simd_type (MONO_TYPE_R4);
4889 arg_types [0] = ret_type;
4890 arg_types [1] = ret_type;
4891 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
4892 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
4893 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
4894 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
4895 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
4897 /* pack */
4898 ret_type = type_to_simd_type (MONO_TYPE_I1);
4899 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
4900 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
4901 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
4902 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
4903 ret_type = type_to_simd_type (MONO_TYPE_I2);
4904 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4905 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
4906 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
4907 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
4909 /* cmp pd/ps */
4910 ret_type = type_to_simd_type (MONO_TYPE_R8);
4911 arg_types [0] = ret_type;
4912 arg_types [1] = ret_type;
4913 arg_types [2] = LLVMInt8Type ();
4914 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
4915 ret_type = type_to_simd_type (MONO_TYPE_R4);
4916 arg_types [0] = ret_type;
4917 arg_types [1] = ret_type;
4918 arg_types [2] = LLVMInt8Type ();
4919 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
4921 /* Conversion ops */
4922 ret_type = type_to_simd_type (MONO_TYPE_R8);
4923 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4924 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
4925 ret_type = type_to_simd_type (MONO_TYPE_R4);
4926 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4927 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
4928 ret_type = type_to_simd_type (MONO_TYPE_I4);
4929 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4930 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
4931 ret_type = type_to_simd_type (MONO_TYPE_I4);
4932 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4933 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
4934 ret_type = type_to_simd_type (MONO_TYPE_R4);
4935 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4936 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
4937 ret_type = type_to_simd_type (MONO_TYPE_R8);
4938 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4939 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
4941 ret_type = type_to_simd_type (MONO_TYPE_I4);
4942 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4943 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
4944 ret_type = type_to_simd_type (MONO_TYPE_I4);
4945 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4946 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
4948 /* Unary ops */
4949 ret_type = type_to_simd_type (MONO_TYPE_R8);
4950 arg_types [0] = ret_type;
4951 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
4952 ret_type = type_to_simd_type (MONO_TYPE_R4);
4953 arg_types [0] = ret_type;
4954 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
4955 ret_type = type_to_simd_type (MONO_TYPE_R4);
4956 arg_types [0] = ret_type;
4957 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
4958 ret_type = type_to_simd_type (MONO_TYPE_R4);
4959 arg_types [0] = ret_type;
4960 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
4962 /* shifts */
4963 ret_type = type_to_simd_type (MONO_TYPE_I2);
4964 arg_types [0] = ret_type;
4965 arg_types [1] = LLVMInt32Type ();
4966 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
4967 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
4968 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
4969 ret_type = type_to_simd_type (MONO_TYPE_I4);
4970 arg_types [0] = ret_type;
4971 arg_types [1] = LLVMInt32Type ();
4972 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
4973 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
4974 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
4975 ret_type = type_to_simd_type (MONO_TYPE_I8);
4976 arg_types [0] = ret_type;
4977 arg_types [1] = LLVMInt32Type ();
4978 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
4979 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
4981 /* pmovmskb */
4982 ret_type = LLVMInt32Type ();
4983 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
4984 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
4987 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
4989 /* Load/Store intrinsics */
4991 LLVMTypeRef arg_types [5];
4992 int i;
4993 char name [128];
4995 for (i = 1; i <= 8; i *= 2) {
4996 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
4997 arg_types [1] = LLVMInt32Type ();
4998 arg_types [2] = LLVMInt1Type ();
4999 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5000 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5002 arg_types [0] = LLVMIntType (i * 8);
5003 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5004 arg_types [2] = LLVMInt32Type ();
5005 arg_types [3] = LLVMInt1Type ();
5006 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5007 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5012 void
5013 mono_llvm_init (void)
5015 mono_native_tls_alloc (&current_cfg_tls_id, NULL);
5018 static void
5019 init_jit_module (void)
5021 MonoJitICallInfo *info;
5023 if (jit_module_inited)
5024 return;
5026 mono_loader_lock ();
5028 if (jit_module_inited) {
5029 mono_loader_unlock ();
5030 return;
5033 jit_module.module = LLVMModuleCreateWithName ("mono");
5035 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
5037 add_intrinsics (jit_module.module);
5039 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5041 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5042 g_assert (info);
5043 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5045 jit_module_inited = TRUE;
5047 mono_loader_unlock ();
5050 void
5051 mono_llvm_cleanup (void)
5053 if (ee)
5054 mono_llvm_dispose_ee (ee);
5056 if (jit_module.llvm_types)
5057 g_hash_table_destroy (jit_module.llvm_types);
5059 if (aot_module.module)
5060 LLVMDisposeModule (aot_module.module);
5062 LLVMContextDispose (LLVMGetGlobalContext ());
5065 void
5066 mono_llvm_create_aot_module (const char *got_symbol)
5068 /* Delete previous module */
5069 if (aot_module.plt_entries)
5070 g_hash_table_destroy (aot_module.plt_entries);
5071 if (aot_module.module)
5072 LLVMDisposeModule (aot_module.module);
5074 memset (&aot_module, 0, sizeof (aot_module));
5076 aot_module.module = LLVMModuleCreateWithName ("aot");
5077 aot_module.got_symbol = got_symbol;
5079 add_intrinsics (aot_module.module);
5081 /* Add GOT */
5083 * We couldn't compute the type of the LLVM global representing the got because
5084 * its size is only known after all the methods have been emitted. So create
5085 * a dummy variable, and replace all uses it with the real got variable when
5086 * its size is known in mono_llvm_emit_aot_module ().
5089 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
5091 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5092 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5095 /* Add a dummy personality function */
5097 LLVMBasicBlockRef lbb;
5098 LLVMBuilderRef lbuilder;
5099 LLVMValueRef personality;
5101 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5102 LLVMSetLinkage (personality, LLVMPrivateLinkage);
5103 lbb = LLVMAppendBasicBlock (personality, "BB0");
5104 lbuilder = LLVMCreateBuilder ();
5105 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5106 LLVMBuildRetVoid (lbuilder);
5109 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5110 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5114 * Emit the aot module into the LLVM bitcode file FILENAME.
5116 void
5117 mono_llvm_emit_aot_module (const char *filename, int got_size)
5119 LLVMTypeRef got_type;
5120 LLVMValueRef real_got;
5123 * Create the real got variable and replace all uses of the dummy variable with
5124 * the real one.
5126 got_type = LLVMArrayType (IntPtrType (), got_size);
5127 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5128 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5129 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5131 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5133 mark_as_used (aot_module.module, real_got);
5135 /* Delete the dummy got so it doesn't become a global */
5136 LLVMDeleteGlobal (aot_module.got_var);
5138 #if 0
5140 char *verifier_err;
5142 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5143 g_assert_not_reached ();
5146 #endif
5148 LLVMWriteBitcodeToFile (aot_module.module, filename);
5152 DESIGN:
5153 - Emit LLVM IR from the mono IR using the LLVM C API.
5154 - The original arch specific code remains, so we can fall back to it if we run
5155 into something we can't handle.
5159 A partial list of issues:
5160 - Handling of opcodes which can throw exceptions.
5162 In the mono JIT, these are implemented using code like this:
5163 method:
5164 <compare>
5165 throw_pos:
5166 b<cond> ex_label
5167 <rest of code>
5168 ex_label:
5169 push throw_pos - method
5170 call <exception trampoline>
5172 The problematic part is push throw_pos - method, which cannot be represented
5173 in the LLVM IR, since it does not support label values.
5174 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5175 be implemented in JIT mode ?
5176 -> a possible but slower implementation would use the normal exception
5177 throwing code but it would need to control the placement of the throw code
5178 (it needs to be exactly after the compare+branch).
5179 -> perhaps add a PC offset intrinsics ?
5181 - efficient implementation of .ovf opcodes.
5183 These are currently implemented as:
5184 <ins which sets the condition codes>
5185 b<cond> ex_label
5187 Some overflow opcodes are now supported by LLVM SVN.
5189 - exception handling, unwinding.
5190 - SSA is disabled for methods with exception handlers
5191 - How to obtain unwind info for LLVM compiled methods ?
5192 -> this is now solved by converting the unwind info generated by LLVM
5193 into our format.
5194 - LLVM uses the c++ exception handling framework, while we use our home grown
5195 code, and couldn't use the c++ one:
5196 - its not supported under VC++, other exotic platforms.
5197 - it might be impossible to support filter clauses with it.
5199 - trampolines.
5201 The trampolines need a predictable call sequence, since they need to disasm
5202 the calling code to obtain register numbers / offsets.
5204 LLVM currently generates this code in non-JIT mode:
5205 mov -0x98(%rax),%eax
5206 callq *%rax
5207 Here, the vtable pointer is lost.
5208 -> solution: use one vtable trampoline per class.
5210 - passing/receiving the IMT pointer/RGCTX.
5211 -> solution: pass them as normal arguments ?
5213 - argument passing.
5215 LLVM does not allow the specification of argument registers etc. This means
5216 that all calls are made according to the platform ABI.
5218 - passing/receiving vtypes.
5220 Vtypes passed/received in registers are handled by the front end by using
5221 a signature with scalar arguments, and loading the parts of the vtype into those
5222 arguments.
5224 Vtypes passed on the stack are handled using the 'byval' attribute.
5226 - ldaddr.
5228 Supported though alloca, we need to emit the load/store code.
5230 - types.
5232 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5233 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5234 This is made easier because the IR is already in SSA form.
5235 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5236 types are frequently used incorrectly.
5240 AOT SUPPORT:
5241 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5242 append the AOT data structures to that file. For methods which cannot be
5243 handled by LLVM, the normal JIT compiled versions are used.
5246 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5247 * - each bblock should end with a branch
5248 * - setting the return value, making cfg->ret non-volatile
5249 * - avoid some transformations in the JIT which make it harder for us to generate
5250 * code.
5251 * - use pointer types to help optimizations.