mono_mutex_t mutex;
gboolean use_bin_writer;
gboolean gas_line_numbers;
- /* Whenever to emit LLVM code into a separate object file */
- gboolean llvm_separate;
/* Whenever to emit an object file directly from llc */
gboolean llvm_owriter;
MonoImageWriter *w;
#ifdef TARGET_AMD64
/* mov reg, got+offset(%rip) */
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
/* The GOT symbol is in the LLVM module, the clang assembler has problems emitting symbol diffs for it */
int dreg;
int rex_r;
/* This should be exactly 8 bytes long */
*tramp_size = 8;
/* call *<offset>(%rip) */
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
emit_unset_mode (acfg);
fprintf (acfg->fp, "call *%s+%d(%%rip)\n", acfg->got_symbol, (int)(offset * sizeof (gpointer)));
emit_zero_bytes (acfg, 2);
emit_bytes (acfg, buf, code - buf);
/* jump <method> */
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
emit_unset_mode (acfg);
fprintf (acfg->fp, "jmp %s\n", call_target);
} else {
/* This should be exactly 13 bytes long */
*tramp_size = 13;
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
emit_unset_mode (acfg);
fprintf (acfg->fp, "mov %s+%d(%%rip), %%r10\n", acfg->got_symbol, (int)(offset * sizeof (gpointer)));
fprintf (acfg->fp, "jmp *%s+%d(%%rip)\n", acfg->got_symbol, (int)((offset + 1) * sizeof (gpointer)));
/* MONO_ARCH_IMT_SCRATCH_REG is a free register */
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
emit_unset_mode (acfg);
fprintf (acfg->fp, "mov %s+%d(%%rip), %s\n", acfg->got_symbol, (int)(offset * sizeof (gpointer)), mono_arch_regname (MONO_ARCH_IMT_SCRATCH_REG));
}
mono_amd64_patch (labels [3], code);
x86_breakpoint (code);
- if (!acfg->llvm_separate) {
+ if (!acfg->llvm) {
/* mov <OFFSET>(%rip), MONO_ARCH_IMT_SCRATCH_REG */
amd64_emit_rex (mov_buf_ptr, sizeof(gpointer), MONO_ARCH_IMT_SCRATCH_REG, 0, AMD64_RIP);
*(mov_buf_ptr)++ = (unsigned char)0x8b; /* mov opcode */
emit_label (acfg, cfg->asm_symbol);
- if (acfg->aot_opts.write_symbols && !acfg->global_symbols && !acfg->llvm_separate) {
+ if (acfg->aot_opts.write_symbols && !acfg->global_symbols && !acfg->llvm) {
/*
* Write a C style symbol for every method, this has two uses:
* - it works on platforms where the dwarf debugging info is not
char *s;
char *prefix;
- if (acfg->llvm_separate && llvm_acfg->aot_opts.static_link) {
+ if (acfg->llvm && llvm_acfg->aot_opts.static_link) {
/* Need to add a prefix to create unique symbols */
prefix = g_strdup_printf ("plt_%s_", acfg->assembly_name_sym);
} else {
if (acfg->llvm && !acfg->thumb_mixed) {
emit_label (acfg, plt_entry->llvm_symbol);
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
emit_global_inner (acfg, plt_entry->llvm_symbol, TRUE);
#if defined(TARGET_MACH)
fprintf (acfg->fp, ".private_extern %s\n", plt_entry->llvm_symbol);
emit_label (acfg, plt_entry->llvm_symbol);
- if (acfg->llvm_separate)
+ if (acfg->llvm)
emit_global_inner (acfg, plt_entry->llvm_symbol, TRUE);
arch_emit_llvm_plt_entry (acfg, i);
opts->direct_pinvoke = TRUE;
} else if (str_begins_with (arg, "direct-icalls")) {
opts->direct_icalls = TRUE;
-#if defined(TARGET_ARM) || defined(TARGET_ARM64)
- } else if (str_begins_with (arg, "iphone-abi")) {
- // older full-aot users did depend on this.
-#endif
} else if (str_begins_with (arg, "no-direct-calls")) {
opts->no_direct_calls = TRUE;
} else if (str_begins_with (arg, "print-skipped")) {
flags |= JIT_FLAG_FULL_AOT;
if (acfg->llvm)
flags |= JIT_FLAG_LLVM;
+ if (acfg->aot_opts.no_direct_calls)
+ flags |= JIT_FLAG_NO_DIRECT_ICALLS;
cfg = mini_method_compile (method, acfg->opts, mono_get_root_domain (), flags, 0);
mono_loader_clear_error ();
{
MonoJumpInfo *ji = mono_mempool_alloc (llvm_acfg->mempool, sizeof (MonoJumpInfo));
MonoPltEntry *plt_entry;
+ const char *sym = NULL;
ji->type = type;
ji->data.target = data;
if (!can_encode_patch (llvm_acfg, ji))
return NULL;
+ if (llvm_acfg->aot_opts.direct_icalls) {
+ if (type == MONO_PATCH_INFO_JIT_ICALL_ADDR) {
+ /* Call to a C function implementing a jit icall */
+ sym = mono_lookup_jit_icall_symbol (data);
+ } else if (type == MONO_PATCH_INFO_ICALL_ADDR) {
+ MonoMethod *method = (gpointer)data;
+ if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
+ sym = mono_lookup_icall_symbol (method);
+ }
+ if (sym)
+ return g_strdup (sym);
+ }
+
plt_entry = get_plt_entry (llvm_acfg, ji);
plt_entry->llvm_used = TRUE;
if (acfg->aot_opts.mtriple)
g_string_append_printf (acfg->llc_args, " -mtriple=%s", acfg->aot_opts.mtriple);
- if (acfg->llvm_separate)
- g_string_append_printf (acfg->llc_args, " -mono-eh-frame-symbol=%s", acfg->llvm_eh_frame_symbol);
+ g_string_append_printf (acfg->llc_args, " -mono-eh-frame-symbol=%s", acfg->llvm_eh_frame_symbol);
#if defined(TARGET_MACH) && defined(TARGET_ARM)
/* ios requires PIC code now */
#endif
unlink (acfg->tmpfname);
- if (acfg->llvm_separate) {
- if (acfg->llvm_owriter) {
- /* Emit an object file directly */
- output_fname = g_strdup_printf ("%s", acfg->llvm_ofile);
- g_string_append_printf (acfg->llc_args, " -filetype=obj");
- } else {
- output_fname = g_strdup_printf ("%s", acfg->llvm_sfile);
- }
+ if (acfg->llvm_owriter) {
+ /* Emit an object file directly */
+ output_fname = g_strdup_printf ("%s", acfg->llvm_ofile);
+ g_string_append_printf (acfg->llc_args, " -filetype=obj");
} else {
- output_fname = g_strdup (acfg->tmpfname);
+ output_fname = g_strdup_printf ("%s", acfg->llvm_sfile);
}
command = g_strdup_printf ("\"%sllc\" %s -o \"%s\" \"%s.opt.bc\"", acfg->aot_opts.llvm_path, acfg->llc_args->str, output_fname, acfg->tmpbasename);
+ g_free (output_fname);
aot_printf (acfg, "Executing llc: %s\n", command);
aot_printf (acfg, "Output file: '%s'.\n", acfg->tmpfname);
if (acfg->aot_opts.static_link)
aot_printf (acfg, "Linking symbol: '%s'.\n", acfg->static_linking_symbol);
- if (acfg->llvm_separate)
+ if (acfg->llvm)
aot_printf (acfg, "LLVM output file: '%s'.\n", acfg->llvm_sfile);
return 0;
}
return 1;
}
- if (acfg->llvm_separate && !acfg->llvm_owriter) {
+ if (acfg->llvm && !acfg->llvm_owriter) {
command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", tool_prefix, AS_NAME, AS_OPTIONS, acfg->as_args ? acfg->as_args->str : "", acfg->llvm_ofile, acfg->llvm_sfile);
aot_printf (acfg, "Executing the native assembler: %s\n", command);
if (execute_system (command) != 0) {
tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
- if (acfg->llvm_separate) {
+ if (acfg->llvm) {
llvm_ofile = g_strdup (acfg->llvm_ofile);
} else {
llvm_ofile = g_strdup ("");
mini_llvm_init ();
- if (!acfg->aot_opts.asm_only || acfg->aot_opts.llvm_outfile) {
- /*
- * Emit all LLVM code into a separate assembly/object file and link with it
- * normally.
- */
-#if LLVM_API_VERSION >= 3
- acfg->llvm_separate = TRUE;
- if (!acfg->aot_opts.asm_only)
- acfg->llvm_owriter = TRUE;
-#endif
- }
- if (acfg->aot_opts.llvm_outfile && !acfg->llvm_separate) {
- aot_printerrf (acfg, "The llvm-outputfile= option is not supported on this platform.\n");
+ if (acfg->aot_opts.asm_only && !acfg->aot_opts.llvm_outfile) {
+ aot_printerrf (acfg, "Compiling with LLVM and the asm-only option requires the llvm-outputfile= option.");
return 1;
}
+
+ /*
+ * Emit all LLVM code into a separate assembly/object file and link with it
+ * normally.
+ */
+ if (!acfg->aot_opts.asm_only)
+ acfg->llvm_owriter = TRUE;
}
if (acfg->aot_opts.full_aot)
acfg->got_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, acfg->got_symbol_base);
if (acfg->llvm) {
acfg->llvm_got_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, acfg->llvm_got_symbol_base);
- if (acfg->llvm_separate)
- acfg->llvm_eh_frame_symbol = g_strdup_printf ("mono_aot_%s_eh_frame", acfg->assembly_name_sym);
- else
- acfg->llvm_eh_frame_symbol = g_strdup ("mono_eh_frame");
+ acfg->llvm_eh_frame_symbol = g_strdup_printf ("mono_aot_%s_eh_frame", acfg->assembly_name_sym);
}
acfg->method_index = 1;
- // FIXME:
- /*
if (acfg->aot_opts.full_aot)
mono_set_partial_sharing_supported (TRUE);
- */
-
- mono_set_partial_sharing_supported (FALSE);
res = collect_methods (acfg);
if (!res)
#ifdef ENABLE_LLVM
if (acfg->llvm) {
llvm_acfg = acfg;
- mono_llvm_create_aot_module (acfg->llvm_got_symbol_base, acfg->llvm_separate, acfg->llvm_separate);
+ mono_llvm_create_aot_module (acfg->llvm_got_symbol_base, TRUE, TRUE);
}
#endif
acfg->tmpbasename = g_strdup_printf ("%s", acfg->image->name);
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
}
- if (acfg->llvm_separate) {
- g_assert (acfg->aot_opts.llvm_outfile);
- acfg->llvm_sfile = g_strdup (acfg->aot_opts.llvm_outfile);
- }
+ g_assert (acfg->aot_opts.llvm_outfile);
+ acfg->llvm_sfile = g_strdup (acfg->aot_opts.llvm_outfile);
} else {
acfg->tmpbasename = g_strdup_printf ("%s", "temp");
acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
acfg->w = img_writer_create (acfg->fp, TRUE);
acfg->use_bin_writer = TRUE;
} else {
- if (acfg->llvm && !acfg->llvm_separate) {
- /* Append to the .s file created by llvm */
- /* FIXME: Use multiple files instead */
- acfg->fp = fopen (acfg->tmpfname, "a+");
+ if (acfg->aot_opts.asm_only) {
+ if (acfg->aot_opts.outfile)
+ acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
+ else
+ acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
+ acfg->fp = fopen (acfg->tmpfname, "w+");
} else {
- if (acfg->aot_opts.asm_only) {
- if (acfg->aot_opts.outfile)
- acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
- else
- acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
- acfg->fp = fopen (acfg->tmpfname, "w+");
- } else {
- int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL);
- acfg->fp = fdopen (i, "w+");
- }
+ int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL);
+ acfg->fp = fdopen (i, "w+");
}
if (acfg->fp == 0) {
aot_printerrf (acfg, "Unable to open file '%s': %s\n", acfg->tmpfname, strerror (errno));
if (COMPILE_LLVM (cfg))
cfg->asm_symbol = g_strdup_printf ("%s%s", acfg->llvm_label_prefix, cfg->llvm_method_name);
- else if (acfg->global_symbols || acfg->llvm_separate)
+ else if (acfg->global_symbols || acfg->llvm)
cfg->asm_symbol = get_debug_sym (cfg->orig_method, "", acfg->method_label_hash);
else
cfg->asm_symbol = g_strdup_printf ("%s%sm_%x", acfg->temp_prefix, acfg->llvm_label_prefix, method_index);