* Authors:
* Paolo Molaro (lupus@ximian.com)
* Dietmar Maurer (dietmar@ximian.com)
+ * Patrik Torstensson
*
* (C) 2003 Ximian, Inc.
*/
static gint lmf_tls_offset = -1;
+#ifdef PLATFORM_WIN32
+/* Under windows, the default pinvoke calling convention is stdcall */
+#define CALLCONV_IS_STDCALL(call_conv) (((call_conv) == MONO_CALL_STDCALL) || ((call_conv) == MONO_CALL_DEFAULT))
+#else
+#define CALLCONV_IS_STDCALL(call_conv) ((call_conv) == MONO_CALL_STDCALL)
+#endif
+
+static gpointer mono_arch_get_lmf_addr (void);
+
const char*
mono_arch_regname (int reg) {
switch (reg) {
static int indent_level = 0;
static void indent (int diff) {
- int v = indent_level;
+ int v;
+ if (diff < 0)
+ indent_level += diff;
+ v = indent_level;
while (v-- > 0) {
printf (". ");
}
- indent_level += diff;
+ if (diff > 0)
+ indent_level += diff;
}
static gboolean enable_trace = TRUE;
int killed_in;
int last_use;
int prev_use;
- int fpflags; /* used to track if we spill/load */
+ int flags; /* used to track fp spill/load */
} RegTrack;
static const char*const * ins_spec = pentium_desc;
}
#endif
-/* flags used in reginfo->fpflags */
-#define MONO_X86_FP_NEEDS_LOAD_SPILL 32
-#define MONO_X86_FP_NEEDS_SPILL 64
-#define MONO_X86_FP_NEEDS_LOAD 128
+/* flags used in reginfo->flags */
+#define MONO_X86_FP_NEEDS_LOAD_SPILL 1
+#define MONO_X86_FP_NEEDS_SPILL 2
+#define MONO_X86_FP_NEEDS_LOAD 4
/*#include "cprop.c"*/
spill = g_list_first (fspill_list);
if (spill && fpcount < MONO_MAX_FREGS) {
- reginfo1 [ins->sreg1].fpflags |= MONO_X86_FP_NEEDS_LOAD;
+ reginfo1 [ins->sreg1].flags |= MONO_X86_FP_NEEDS_LOAD;
fspill_list = g_list_remove (fspill_list, spill->data);
} else
fpcount--;
reginfo2 = reginfof;
spill = g_list_first (fspill_list);
if (spill) {
- reginfo2 [ins->sreg2].fpflags |= MONO_X86_FP_NEEDS_LOAD;
+ reginfo2 [ins->sreg2].flags |= MONO_X86_FP_NEEDS_LOAD;
fspill_list = g_list_remove (fspill_list, spill->data);
if (fpcount >= MONO_MAX_FREGS) {
fspill++;
fspill_list = g_list_prepend (fspill_list, GINT_TO_POINTER(fspill));
- reginfo2 [ins->sreg2].fpflags |= MONO_X86_FP_NEEDS_LOAD_SPILL;
+ reginfo2 [ins->sreg2].flags |= MONO_X86_FP_NEEDS_LOAD_SPILL;
}
} else
fpcount--;
if (spec [MONO_INST_DEST] == 'f') {
reginfod = reginfof;
if (fpcount >= MONO_MAX_FREGS) {
- reginfod [ins->dreg].fpflags |= MONO_X86_FP_NEEDS_SPILL;
+ reginfod [ins->dreg].flags |= MONO_X86_FP_NEEDS_SPILL;
fspill++;
fspill_list = g_list_prepend (fspill_list, GINT_TO_POINTER(fspill));
fpcount--;
/* Track dreg */
if (spec [MONO_INST_DEST] == 'f') {
- if (reginfof [ins->dreg].fpflags & MONO_X86_FP_NEEDS_SPILL) {
+ if (reginfof [ins->dreg].flags & MONO_X86_FP_NEEDS_SPILL) {
GList *spill_node;
MonoInst *store;
spill_node = g_list_first (fspill_list);
/* Track sreg1 */
if (spec [MONO_INST_SRC1] == 'f') {
- if (reginfof [ins->sreg1].fpflags & MONO_X86_FP_NEEDS_LOAD) {
+ if (reginfof [ins->sreg1].flags & MONO_X86_FP_NEEDS_LOAD) {
MonoInst *load;
MonoInst *store = NULL;
- if (reginfof [ins->sreg1].fpflags & MONO_X86_FP_NEEDS_LOAD_SPILL) {
+ if (reginfof [ins->sreg1].flags & MONO_X86_FP_NEEDS_LOAD_SPILL) {
GList *spill_node;
spill_node = g_list_first (fspill_list);
g_assert (spill_node);
}
/* track sreg2 */
if (spec [MONO_INST_SRC2] == 'f') {
- if (reginfof [ins->sreg2].fpflags & MONO_X86_FP_NEEDS_LOAD) {
+ if (reginfof [ins->sreg2].flags & MONO_X86_FP_NEEDS_LOAD) {
MonoInst *load;
MonoInst *store = NULL;
- if (reginfof [ins->sreg2].fpflags & MONO_X86_FP_NEEDS_LOAD_SPILL) {
+ if (reginfof [ins->sreg2].flags & MONO_X86_FP_NEEDS_LOAD_SPILL) {
GList *spill_node;
spill_node = g_list_first (fspill_list);
g_assert (spill_node);
- if (spec [MONO_INST_SRC1] == 'f' && (reginfof [ins->sreg1].fpflags & MONO_X86_FP_NEEDS_LOAD_SPILL))
+ if (spec [MONO_INST_SRC1] == 'f' && (reginfof [ins->sreg1].flags & MONO_X86_FP_NEEDS_LOAD_SPILL))
spill_node = g_list_next (spill_node);
store = create_spilled_store_float (cfg, GPOINTER_TO_INT (spill_node->data), ins->sreg2, ins);
mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, call->fptr);
}
x86_call_code (code, 0);
- if (call->stack_usage && (call->signature->call_convention != MONO_CALL_STDCALL))
+ if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature->call_convention))
x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
break;
case OP_FCALL_REG:
case OP_CALL_REG:
call = (MonoCallInst*)ins;
x86_call_reg (code, ins->sreg1);
- if (call->stack_usage && (call->signature->call_convention != MONO_CALL_STDCALL))
+ if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature->call_convention))
x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
break;
case OP_FCALL_MEMBASE:
case OP_CALL_MEMBASE:
call = (MonoCallInst*)ins;
x86_call_membase (code, ins->sreg1, ins->inst_offset);
- if (call->stack_usage && (call->signature->call_convention != MONO_CALL_STDCALL))
+ if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature->call_convention))
x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage);
break;
case OP_OUTARG:
void
mono_arch_register_lowlevel_calls (void)
{
+ mono_register_jit_icall (mono_arch_get_lmf_addr, "mono_arch_get_lmf_addr", NULL, TRUE);
mono_register_jit_icall (enter_method, "mono_enter_method", NULL, TRUE);
mono_register_jit_icall (leave_method, "mono_leave_method", NULL, TRUE);
}
GSList *list;
/* get the trampoline to the method from the domain */
- target = mono_arch_create_jump_trampoline (patch_info->data.method);
+ target = mono_create_jump_trampoline (domain, patch_info->data.method, TRUE);
if (!domain->jump_target_hash)
domain->jump_target_hash = g_hash_table_new (NULL, NULL);
list = g_hash_table_lookup (domain->jump_target_hash, patch_info->data.method);
x86_mov_reg_membase (code, X86_EAX, X86_EAX, lmf_tls_offset, 4);
}
else {
+#ifdef HAVE_KW_THREAD
+ mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
+ (gpointer)"mono_arch_get_lmf_addr");
+#else
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
(gpointer)"mono_get_lmf_addr");
+#endif
x86_call_code (code, 0);
}
x86_leave (code);
- if (sig->call_convention == MONO_CALL_STDCALL) {
+ if (CALLCONV_IS_STDCALL (sig->call_convention)) {
MonoJitArgumentInfo *arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1));
stack_to_pop = arch_get_argument_info (sig, sig->param_count, arg_info);