{
MonoMethod *method = cfg->method;
MonoMethodHeader *header = ((MonoMethodNormal *)method)->header;
- int i, j, k;
+ int i, j, k, alloc_size;
x86_push_reg (cfg->code, X86_EBP);
x86_mov_reg_reg (cfg->code, X86_EBP, X86_ESP, 4);
- if (cfg->locals_size)
- x86_alu_reg_imm (cfg->code, X86_SUB, X86_ESP, cfg->locals_size);
+ alloc_size = cfg->locals_size;
- if (mono_regset_reg_used (cfg->rs, X86_EBX))
+ if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
x86_push_reg (cfg->code, X86_EBX);
+ alloc_size -= 4;
+ }
- if (mono_regset_reg_used (cfg->rs, X86_EDI))
+ if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
x86_push_reg (cfg->code, X86_EDI);
+ alloc_size -= 4;
+ }
- if (mono_regset_reg_used (cfg->rs, X86_ESI))
+ if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
x86_push_reg (cfg->code, X86_ESI);
+ alloc_size -= 4;
+ }
+
+ if (alloc_size)
+ x86_alu_reg_imm (cfg->code, X86_SUB, X86_ESP, alloc_size);
if (mono_jit_trace_calls) {
x86_push_reg (cfg->code, X86_EBP);
int size = - offset;
int inited = 0;
+ /* do not clear caller saved registers */
+ size -= 12;
+
for (i = 0; i < header->num_locals; ++i) {
MonoVarInfo *rv = &VARINFO (cfg, cfg->locals_start_index + i);
static void
arch_emit_epilogue (MonoFlowGraph *cfg)
{
- int pos = 4;
+ int pos;
/*
* note: with trace and profiling the value on the FP stack may get clobbered.
*/
x86_pop_reg (cfg->code, X86_EAX);
}
+ pos = -4;
if (mono_regset_reg_used (cfg->rs, X86_EBX)) {
- x86_mov_reg_membase (cfg->code, X86_EBX, X86_EBP, - (cfg->locals_size + pos), 4);
- pos += 4;
+ x86_mov_reg_membase (cfg->code, X86_EBX, X86_EBP, pos, 4);
+ pos -= 4;
}
if (mono_regset_reg_used (cfg->rs, X86_EDI)) {
- x86_mov_reg_membase (cfg->code, X86_EDI, X86_EBP, - (cfg->locals_size + pos), 4);
- pos += 4;
+ x86_mov_reg_membase (cfg->code, X86_EDI, X86_EBP, pos, 4);
+ pos -= 4;
}
if (mono_regset_reg_used (cfg->rs, X86_ESI)) {
- x86_mov_reg_membase (cfg->code, X86_ESI, X86_EBP, - (cfg->locals_size + pos), 4);
- pos += 4;
+ x86_mov_reg_membase (cfg->code, X86_ESI, X86_EBP, pos, 4);
+ pos -= 4;
}
x86_leave (cfg->code);
if (ji) { /* we are inside managed code */
MonoMethod *m = ji->method;
- int offset = 2;
+ int offset;
if (ji->num_clauses) {
int i;
/* continue unwinding */
+ offset = -1;
/* restore caller saved registers */
if (ji->used_regs & X86_ESI_MASK) {
- ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
- offset++;
+ ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
+ offset--;
}
if (ji->used_regs & X86_EDI_MASK) {
ctx->SC_EDI = *((int *)ctx->SC_EBP + offset);
- offset++;
+ offset--;
}
if (ji->used_regs & X86_EBX_MASK) {
- ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
+ ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
}
ctx->SC_ESP = ctx->SC_EBP;
cfg->method = method;
cfg->mp = mp;
+ /* reserve space for caller saved registers */
+ /* fixme: this is arch dependent */
+ cfg->locals_size = 12;
+
/* fixme: we should also consider loader optimisation attributes */
cfg->share_code = mono_jit_share_code;
cfg->bblocks = bblocks;
cfg->block_count = block_count;
+ for (i = 0; i < header->num_clauses; ++i) {
+ MonoBBlock *sbb, *tbb;
+ clause = &header->clauses [i];
+ sbb = &cfg->bblocks [bcinfo [clause->try_offset].block_id];
+ tbb = &cfg->bblocks [bcinfo [clause->handler_offset].block_id];
+ g_assert (sbb && tbb);
+ sbb->succ = g_list_prepend (sbb->succ, tbb);
+ }
+
ip = header->code;
end = ip + header->code_size;
bb = NULL;