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