if (COMPILE_LLVM (cfg))
break;
- if (cfg->ilp32 && SIZEOF_REGISTER == 8)
+ if (cfg->backend->ilp32 && SIZEOF_REGISTER == 8)
opcode = OP_LADDCC;
else
opcode = OP_ADDCC;
if (COMPILE_LLVM (cfg))
break;
- if (cfg->ilp32 && SIZEOF_REGISTER == 8)
+ if (cfg->backend->ilp32 && SIZEOF_REGISTER == 8)
opcode = OP_LADDCC;
else
opcode = OP_ADDCC;
if (COMPILE_LLVM (cfg))
break;
- if (cfg->ilp32 && SIZEOF_REGISTER == 8)
+ if (cfg->backend->ilp32 && SIZEOF_REGISTER == 8)
opcode = OP_LSUBCC;
else
opcode = OP_SUBCC;
if (COMPILE_LLVM (cfg))
break;
- if (cfg->ilp32 && SIZEOF_REGISTER == 8)
+ if (cfg->backend->ilp32 && SIZEOF_REGISTER == 8)
opcode = OP_LSUBCC;
else
opcode = OP_SUBCC;
MonoInst *
mono_get_got_var (MonoCompile *cfg)
{
- if (!cfg->need_got_var)
+ if (!cfg->compile_aot || !cfg->need_got_var)
return NULL;
if (!cfg->got_var) {
cfg->got_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
mono_gc_get_nursery (&nursery_shift_bits, &nursery_size);
- if (cfg->have_card_table_wb && !cfg->compile_aot && card_table && nursery_shift_bits > 0 && !COMPILE_LLVM (cfg)) {
+ if (cfg->backend->have_card_table_wb && !cfg->compile_aot && card_table && nursery_shift_bits > 0 && !COMPILE_LLVM (cfg)) {
MonoInst *wbarrier;
MONO_INST_NEW (cfg, wbarrier, OP_CARD_TABLE_WBARRIER);
EMIT_NEW_VTABLECONST (cfg, vtable_arg, vtable);
}
- if (!COMPILE_LLVM (cfg) && cfg->have_op_generic_class_init) {
+ if (!COMPILE_LLVM (cfg) && cfg->backend->have_op_generic_class_init) {
MonoInst *ins;
/*
return mini_emit_ldelema_1_ins (cfg, eclass, sp [0], sp [1], TRUE);
/* emit_ldelema_2 depends on OP_LMUL */
- if (!cfg->emulate_mul_div && rank == 2 && (cfg->opt & MONO_OPT_INTRINS) && !mini_is_gsharedvt_variable_klass (eclass)) {
+ if (!cfg->backend->emulate_mul_div && rank == 2 && (cfg->opt & MONO_OPT_INTRINS) && !mini_is_gsharedvt_variable_klass (eclass)) {
return mini_emit_ldelema_2_ins (cfg, eclass, sp [0], sp [1], sp [2]);
}
type_from_op (cfg, ins, NULL, NULL);
return ins;
- } else if (!cfg->emulate_mul_div && strcmp (cmethod->name, "InternalGetHashCode") == 0 && fsig->param_count == 1 && !mono_gc_is_moving ()) {
+ } else if (!cfg->backend->emulate_mul_div && strcmp (cmethod->name, "InternalGetHashCode") == 0 && fsig->param_count == 1 && !mono_gc_is_moving ()) {
int dreg = alloc_ireg (cfg);
int t1 = alloc_ireg (cfg);
!strcmp (cmethod->klass->name_space, "ObjCRuntime") &&
!strcmp (cmethod->klass->name, "Selector"))
) {
- if (cfg->have_objc_get_selector &&
+ if (cfg->backend->have_objc_get_selector &&
!strcmp (cmethod->name, "GetHandle") && fsig->param_count == 1 &&
(args [0]->opcode == OP_GOT_ENTRY || args [0]->opcode == OP_AOTCONST) &&
cfg->compile_aot) {
* (OP_DUMMY_ICONST etc.) which generate no code. These are only supported
* on some platforms.
*/
- if ((cfg->opt & MONO_OPT_UNSAFE) && cfg->have_dummy_init)
+ if ((cfg->opt & MONO_OPT_UNSAFE) && cfg->backend->have_dummy_init)
init_locals = header->init_locals;
else
init_locals = TRUE;
link_bblock (cfg, cfg->cbb, end_bblock);
ip += 5;
break;
- } else if (cfg->have_op_tail_call) {
+ } else if (cfg->backend->have_op_tail_call) {
/* Handle tail calls similarly to calls */
DISABLE_AOT (cfg);
if (cfg->gsharedvt && mini_is_gsharedvt_signature (fsig))
GSHAREDVT_FAILURE (*ip);
- if (cfg->have_generalized_imt_thunk && cfg->gshared_supported && cmethod->wrapper_type == MONO_WRAPPER_NONE) {
+ if (cfg->backend->have_generalized_imt_thunk && cfg->backend->gshared_supported && cmethod->wrapper_type == MONO_WRAPPER_NONE) {
g_assert (!imt_arg);
if (!context_used)
g_assert (cmethod->is_inflated);
//printf ("HIT: %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
- if (cfg->have_op_tail_call) {
+ if (cfg->backend->have_op_tail_call) {
/* Handle tail calls similarly to normal calls */
tail_call = TRUE;
} else {
ins->sreg2 = sp [1]->dreg;
MONO_ADD_INS (cfg->cbb, ins);
- cfg->param_area = MAX (cfg->param_area, cfg->dyn_call_param_area);
+ cfg->param_area = MAX (cfg->param_area, cfg->backend->dyn_call_param_area);
ip += 2;
inline_costs += 10 * num_calls++;
ad_ins = mono_get_domain_intrinsic (cfg);
jit_tls_ins = mono_get_jit_tls_intrinsic (cfg);
- if (cfg->have_tls_get && ad_ins && jit_tls_ins) {
+ if (cfg->backend->have_tls_get && ad_ins && jit_tls_ins) {
NEW_BBLOCK (cfg, next_bb);
NEW_BBLOCK (cfg, call_bb);
* sregs could use it. So set a flag, and do it after
* the sregs.
*/
- if ((!cfg->use_fpstack || ((store_opcode != OP_STORER8_MEMBASE_REG) && (store_opcode != OP_STORER4_MEMBASE_REG))) && !((var)->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)))
+ if ((!cfg->backend->use_fpstack || ((store_opcode != OP_STORER8_MEMBASE_REG) && (store_opcode != OP_STORER4_MEMBASE_REG))) && !((var)->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)))
dest_has_lvreg = TRUE;
}
}
sreg = alloc_dreg (cfg, stacktypes [regtype]);
- if ((!cfg->use_fpstack || ((load_opcode != OP_LOADR8_MEMBASE) && (load_opcode != OP_LOADR4_MEMBASE))) && !((var)->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && !no_lvreg) {
+ if ((!cfg->backend->use_fpstack || ((load_opcode != OP_LOADR8_MEMBASE) && (load_opcode != OP_LOADR4_MEMBASE))) && !((var)->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && !no_lvreg) {
if (var->dreg == prev_dreg) {
/*
* sreg refers to the value loaded by the load
* Emit LIVERANGE_START/LIVERANGE_END opcodes, the backend will implement them
* by storing the current native offset into MonoMethodVar->live_range_start/end.
*/
- if (cfg->have_liverange_ops && cfg->compute_precise_live_ranges && cfg->comp_done & MONO_COMP_LIVENESS) {
+ if (cfg->backend->have_liverange_ops && cfg->compute_precise_live_ranges && cfg->comp_done & MONO_COMP_LIVENESS) {
for (i = 0; i < cfg->num_varinfo; ++i) {
int vreg = MONO_VARINFO (cfg, i)->vreg;
MonoInst *ins;
#define mono_jit_unlock() mono_mutex_unlock (&jit_mutex)
static mono_mutex_t jit_mutex;
+MonoBackend *current_backend;
+
#ifndef DISABLE_JIT
gpointer
{
MonoInst* ins;
- if (!cfg->have_tls_get)
+ if (!cfg->backend->have_tls_get)
return NULL;
if (offset == -1)
gboolean
mini_tls_get_supported (MonoCompile *cfg, MonoTlsKey key)
{
- if (!cfg->have_tls_get)
+ if (!cfg->backend->have_tls_get)
return FALSE;
if (cfg->compile_aot)
- return cfg->have_tls_get_reg;
+ return cfg->backend->have_tls_get_reg;
else
return mini_get_tls_offset (key) != -1;
}
MonoInst*
mono_create_tls_get (MonoCompile *cfg, MonoTlsKey key)
{
- if (!cfg->have_tls_get)
+ if (!cfg->backend->have_tls_get)
return NULL;
/*
* use a different opcode.
*/
if (cfg->compile_aot) {
- if (cfg->have_tls_get_reg) {
+ if (cfg->backend->have_tls_get_reg) {
MonoInst *ins, *c;
EMIT_NEW_TLS_OFFSETCONST (cfg, c, key);
* Extend the try block backwards to include parts of the previous call
* instruction.
*/
- ei->try_start = (guint8*)ei->try_start - cfg->monitor_enter_adjustment;
+ ei->try_start = (guint8*)ei->try_start - cfg->backend->monitor_enter_adjustment;
}
tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len];
g_assert (tblock);
#endif
static void
-init_compile (MonoCompile *cfg)
+init_backend (MonoBackend *backend)
{
#ifdef MONO_ARCH_NEED_GOT_VAR
- if (cfg->compile_aot)
- cfg->need_got_var = 1;
+ backend->need_got_var = 1;
#endif
#ifdef MONO_ARCH_HAVE_CARD_TABLE_WBARRIER
- cfg->have_card_table_wb = 1;
+ backend->have_card_table_wb = 1;
#endif
#ifdef MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT
- cfg->have_op_generic_class_init = 1;
+ backend->have_op_generic_class_init = 1;
#endif
#ifdef MONO_ARCH_EMULATE_MUL_DIV
- cfg->emulate_mul_div = 1;
+ backend->emulate_mul_div = 1;
#endif
#ifdef MONO_ARCH_EMULATE_DIV
- cfg->emulate_div = 1;
+ backend->emulate_div = 1;
#endif
#if !defined(MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS)
- cfg->emulate_long_shift_opts = 1;
+ backend->emulate_long_shift_opts = 1;
#endif
#ifdef MONO_ARCH_HAVE_OBJC_GET_SELECTOR
- cfg->have_objc_get_selector = 1;
+ backend->have_objc_get_selector = 1;
#endif
#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK
- cfg->have_generalized_imt_thunk = 1;
+ backend->have_generalized_imt_thunk = 1;
#endif
#ifdef MONO_ARCH_GSHARED_SUPPORTED
- cfg->gshared_supported = 1;
+ backend->gshared_supported = 1;
#endif
if (MONO_ARCH_HAVE_TLS_GET)
- cfg->have_tls_get = 1;
+ backend->have_tls_get = 1;
#ifdef MONO_ARCH_HAVE_TLS_GET_REG
- cfg->have_tls_get_reg = 1;
+ backend->have_tls_get_reg = 1;
#endif
if (MONO_ARCH_USE_FPSTACK)
- cfg->use_fpstack = 1;
+ backend->use_fpstack = 1;
#ifdef MONO_ARCH_HAVE_LIVERANGE_OPS
- cfg->have_liverange_ops = 1;
+ backend->have_liverange_ops = 1;
#endif
#ifdef MONO_ARCH_HAVE_OP_TAIL_CALL
- cfg->have_op_tail_call = 1;
+ backend->have_op_tail_call = 1;
#endif
#ifndef MONO_ARCH_MONITOR_ENTER_ADJUSTMENT
- cfg->monitor_enter_adjustment = 1;
+ backend->monitor_enter_adjustment = 1;
#else
- cfg->monitor_enter_adjustment = MONO_ARCH_MONITOR_ENTER_ADJUSTMENT;
+ backend->monitor_enter_adjustment = MONO_ARCH_MONITOR_ENTER_ADJUSTMENT;
#endif
#if defined(__mono_ilp32__)
- cfg->ilp32 = 1;
+ backend->ilp32 = 1;
#endif
#ifdef MONO_ARCH_HAVE_DUMMY_INIT
- cfg->have_dummy_init = 1;
+ backend->have_dummy_init = 1;
#endif
#ifdef MONO_ARCH_DYN_CALL_PARAM_AREA
- cfg->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA;
+ backend->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA;
#endif
}
cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points;
cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points;
cfg->llvm_only = (flags & JIT_FLAG_LLVM_ONLY) != 0;
+ cfg->backend = current_backend;
#ifdef PLATFORM_ANDROID
if (cfg->method->wrapper_type != MONO_WRAPPER_NONE) {
cfg->r4fp = (cfg->opt & MONO_OPT_FLOAT32) ? 1 : 0;
cfg->r4_stack_type = cfg->r4fp ? STACK_R4 : STACK_R8;
- init_compile (cfg);
-
if (cfg->gen_seq_points)
cfg->seq_points = g_ptr_array_new ();
mono_error_init (&cfg->error);
mini_jit_init (void)
{
mono_mutex_init_recursive (&jit_mutex);
+#ifndef DISABLE_JIT
+ current_backend = g_new0 (MonoBackend, 1);
+ init_backend (current_backend);
+#endif
}
void
MONO_OPT_LAST
};
+/*
+ * This structure represents a JIT backend.
+ */
+typedef struct {
+ guint have_card_table_wb : 1;
+ guint have_op_generic_class_init : 1;
+ guint emulate_mul_div : 1;
+ guint emulate_div : 1;
+ guint emulate_long_shift_opts : 1;
+ guint have_objc_get_selector : 1;
+ guint have_generalized_imt_thunk : 1;
+ guint have_tls_get : 1;
+ guint have_tls_get_reg : 1;
+ guint have_liverange_ops: 1;
+ guint have_op_tail_call : 1;
+ guint have_dummy_init : 1;
+ guint gshared_supported : 1;
+ guint use_fpstack : 1;
+ guint ilp32 : 1;
+ int monitor_enter_adjustment;
+ int dyn_call_param_area;
+} MonoBackend;
+
/* Flags for mini_method_compile () */
typedef enum {
/* Whenever to run cctors during JITting */
MonoMethod *method_to_register; /* The method to register in JIT info tables */
MonoGenericContext *generic_context;
+ MonoBackend *backend;
+
/*
* This variable represents the hidden argument holding the vtype
* return address. If the method returns something other than a vtype, or
guint r4fp : 1;
guint llvm_only : 1;
guint need_got_var : 1;
- guint have_card_table_wb : 1;
- guint have_op_generic_class_init : 1;
- guint emulate_mul_div : 1;
- guint emulate_div : 1;
- guint emulate_long_shift_opts : 1;
- guint have_objc_get_selector : 1;
- guint have_generalized_imt_thunk : 1;
- guint have_tls_get : 1;
- guint have_tls_get_reg : 1;
- guint have_liverange_ops: 1;
- guint have_op_tail_call : 1;
- guint have_dummy_init : 1;
- guint gshared_supported : 1;
- guint use_fpstack : 1;
- guint ilp32 : 1;
- int monitor_enter_adjustment;
- int dyn_call_param_area;
int r4_stack_type;
gpointer debug_info;
guint32 lmf_offset;