etmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Tue, 11 Dec 2001 11:16:20 +0000 (11:16 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Tue, 11 Dec 2001 11:16:20 +0000 (11:16 -0000)
* x86.brg: use position indepentent code if possible.

* x86.brg (EMIT_COND_EXCEPTION): new macro.

* emit-x86.c (mono_emit_cfg): impl. variable code buffer size

* jit.c (mono_analyze_flow): use g_malloc0 o allocate large bcinfo
blocks.
(mono_analyze_flow): use g_malloc0 o allocate large bblocks array.

svn path=/trunk/mono/; revision=1553

mono/jit/ChangeLog
mono/jit/TODO
mono/jit/emit-x86.c
mono/jit/jit.c
mono/jit/jit.h
mono/jit/x86.brg

index 16f1b7ea17f90df78628c85fbefd12c9544cf057..42ec63991609da10dfc0a92e446cb29e276050a8 100644 (file)
@@ -1,5 +1,17 @@
+2001-12-11  Dietmar Maurer  <dietmar@ximian.com>
+
+       * x86.brg: use position indepentent code if possible. 
+
+       * x86.brg (EMIT_COND_EXCEPTION): new macro.
+
+       * emit-x86.c (mono_emit_cfg): impl. variable code buffer size
+
 2001-12-10  Dietmar Maurer  <dietmar@ximian.com>
 
+       * jit.c (mono_analyze_flow): use g_malloc0 o allocate large bcinfo
+       blocks.
+       (mono_analyze_flow): use g_malloc0 o allocate large bblocks array.
+
        * x86.brg (stmt): added opt. for STIND_R4/STIND_R8
 
 2001-12-07  Dietmar Maurer  <dietmar@ximian.com>
index c7bcbaaeb1c7d6295c8ecfaa4474924479ae4934..deae2f38ff2ff9f7ecb31ad71675aa92b4c59099 100644 (file)
@@ -1,17 +1,18 @@
 * impl. marshalling attributes for pinvoke
 * raise exceptions everywhere
 * implement all those CONV and CONV_OVF opcodes
-* impl. value type: simple thing works already
 * exceptions: handle exceptions inside unmanaged code
 * exceptions: save/restore floating point state
 * implement all floating point instruction in x86.brg, we also need to check
   the floating branch instruction - some of them seems to be wrong, we need to
   write better tests for that.
 * correctly align value types on the stack and in arrays
-* enum types can have several base types (not only int32)
 * document the functions and variables in the JIT 
 * implement a register set for FP registers (just count register usage on x86)
 
+* inline all calls in System.Math::*, we should use coprozessor instructions
+  directly whenever possible. 
+
 * Calling conventions:
 
        Implement fast call
@@ -25,4 +26,4 @@
 * thread does not work with the jit (mcs/tests/test-19.cs)??
 
 * use short jump opcodes where possible (for backward jumps), will give better
-  performance. 
\ No newline at end of file
+  performance. 
index eb3f4eeee37fb40bcdfc4c65ed046edda1591d65..9f53890deefb68fe1bf8fd615e50fd88081c5ed8 100644 (file)
@@ -243,7 +243,8 @@ arch_emit_prologue (MonoFlowGraph *cfg)
        if (mono_jit_trace_calls) {
                x86_push_reg (cfg->code, X86_EBP);
                x86_push_imm (cfg->code, cfg->method);
-               x86_call_code (cfg->code, enter_method);
+               x86_mov_reg_imm (cfg->code, X86_EAX, enter_method);
+               x86_call_reg (cfg->code, X86_EAX);
                x86_alu_reg_imm (cfg->code, X86_ADD, X86_ESP, 8);
        }
 }
@@ -264,7 +265,8 @@ arch_emit_epilogue (MonoFlowGraph *cfg)
                x86_push_reg (cfg->code, X86_EAX);
                x86_push_reg (cfg->code, X86_EDX);
                x86_push_imm (cfg->code, cfg->method);
-               x86_call_code (cfg->code, leave_method);
+               x86_mov_reg_imm (cfg->code, X86_EAX, leave_method);
+               x86_call_reg (cfg->code, X86_EAX);
                x86_alu_reg_imm (cfg->code, X86_ADD, X86_ESP, 4);
                x86_pop_reg (cfg->code, X86_EDX);
                x86_pop_reg (cfg->code, X86_EAX);
@@ -643,22 +645,35 @@ arch_allocate_regs (MonoFlowGraph *cfg)
 }
 
 static void
-tree_emit (int goal, MonoFlowGraph *s, MBTree *tree) 
+tree_emit (int goal, MonoFlowGraph *cfg, MBTree *tree) 
 {
        MBTree *kids[10];
        int i, ern = mono_burg_rule (tree->state, goal);
        guint16 *nts = mono_burg_nts [ern];
        MBEmitFunc emit;
+       int offset;
 
        mono_burg_kids (tree, ern, kids);
 
        for (i = 0; nts [i]; i++) 
-               tree_emit (nts [i], s, kids [i]);
+               tree_emit (nts [i], cfg, kids [i]);
 
-       tree->addr = s->code - s->start;
+       tree->addr = offset = cfg->code - cfg->start;
+
+       // we assume an instruction uses a maximum of 128 bytes
+       if ((cfg->code_size - offset) <= 128) {
+               int add = MIN ((cfg->code_size * 2), 1024);
+
+               cfg->code_size += add;
+               cfg->start = g_realloc (cfg->start, cfg->code_size);
+               g_assert (cfg->start);
+               cfg->code = cfg->start + offset;
+       }
 
        if ((emit = mono_burg_func [ern]))
-               emit (tree, s);
+               emit (tree, cfg);
+
+       g_assert ((cfg->code - cfg->start) < cfg->code_size);
 }
 
 static void
@@ -675,6 +690,7 @@ mono_emit_cfg (MonoFlowGraph *cfg)
          
                for (j = 0; j < top; j++) {
                        MBTree *t1 = (MBTree *) g_ptr_array_index (forest, j);
+                       
                        tree_emit (1, cfg, t1);
                }
        }
@@ -843,7 +859,7 @@ arch_compile_method (MonoMethod *method)
        } else {
                MonoMethodHeader *header = ((MonoMethodNormal *)method)->header;
                MonoJitInfo *ji = g_new0 (MonoJitInfo, 1);
-
+               
                cfg = mono_cfg_new (method, mp);
 
                mono_analyze_flow (cfg);
@@ -854,15 +870,13 @@ arch_compile_method (MonoMethod *method)
                if (cfg->invalid)
                        return NULL;
        
-               cfg->code = NULL;
                cfg->rs = mono_regset_new (X86_NREG);
                mono_regset_reserve_reg (cfg->rs, X86_ESP);
                mono_regset_reserve_reg (cfg->rs, X86_EBP);
 
-               // fixme: remove limitation to 8192 bytes
-               ji->code_size = 8192*2;
-               method->addr = cfg->start = cfg->code = g_malloc (ji->code_size);
-               
+               cfg->code_size = 256;
+               cfg->start = cfg->code = g_malloc (cfg->code_size);
+
                if (match_debug_method (method))
                        x86_breakpoint (cfg->code);
 
@@ -887,12 +901,10 @@ arch_compile_method (MonoMethod *method)
                cfg->locals_size &= ~7;
 
                arch_emit_prologue (cfg);
-
                mono_emit_cfg (cfg);
+               arch_emit_epilogue (cfg);               
 
-               arch_emit_epilogue (cfg);
-
-               g_assert ((cfg->code - cfg->start) < ji->code_size);
+               method->addr = cfg->start;
 
                mono_compute_branches (cfg);
                
@@ -902,6 +914,7 @@ arch_compile_method (MonoMethod *method)
                if (mono_debug_handle)
                        mono_debug_add_method (mono_debug_handle, cfg);
 
+               ji->code_size = cfg->code - cfg->start;
                ji->used_regs = cfg->rs->used_mask;
                ji->method = method;
                ji->code_start = method->addr;
index dd311a9ceadc5de5d6d92ba81dc8b9d4cb05d5ca..09877670454428c201c6057e3becbfbb257951b5 100644 (file)
@@ -1026,6 +1026,12 @@ mono_cfg_free (MonoFlowGraph *cfg)
                g_ptr_array_free (cfg->bblocks [i].forest, TRUE);
        }
 
+       if (cfg->bcinfo)
+               g_free (cfg->bcinfo);
+
+       if (cfg->bblocks)
+               g_free (cfg->bblocks);
+
        g_array_free (cfg->varinfo, TRUE);
 }
 
@@ -1083,7 +1089,6 @@ void
 mono_analyze_flow (MonoFlowGraph *cfg)
 {
        MonoMethod *method = cfg->method;
-       MonoMemPool *mp = cfg->mp;
        register const unsigned char *ip, *end;
        MonoMethodHeader *header;
        MonoBytecodeInfo *bcinfo;
@@ -1094,7 +1099,7 @@ mono_analyze_flow (MonoFlowGraph *cfg)
 
        header = ((MonoMethodNormal *)method)->header;
 
-       bcinfo = mono_mempool_alloc0 (mp, header->code_size * sizeof (MonoBytecodeInfo));
+       bcinfo = g_malloc0 (header->code_size * sizeof (MonoBytecodeInfo));
        bcinfo [0].is_block_start = 1;
        block_count = 1;
        block_end = FALSE;
@@ -1378,7 +1383,7 @@ mono_analyze_flow (MonoFlowGraph *cfg)
 
        g_assert (block_count);
 
-       bb = bblocks  = mono_mempool_alloc0 (mp, sizeof (MonoBBlock) * block_count);
+       bb = bblocks  = g_malloc0 (sizeof (MonoBBlock) * block_count);
 
        block_count = 0;
        bblocks [0].reached = 1;
index 342b9227457f80d473a2a389e677c8417d59dd37..211280e0aa22d243bbbba0ab8c9efa4921c7f480 100644 (file)
@@ -66,6 +66,7 @@ typedef struct {
        MonoMemPool      *mp;
        guint8           *start;
        guint8           *code;
+       gint32            code_size;
        MonoRegSet       *rs;
        guint32           epilog;
        guint32           args_start_index;
index a0d2ae8b28267482b9bf777c84fecff9f97ef8bf..b171fa744729e76a7e1c378290df562d0d9bec16 100644 (file)
@@ -117,7 +117,8 @@ x86_push_reg (s->code, X86_ECX); \
 x86_push_reg (s->code, reg); \
 x86_push_imm (s->code, reg); \
 x86_push_imm (s->code, text " %d %p\n"); \
-x86_call_code (s->code, printf); \
+x86_mov_reg_imm (s->code, X86_EAX, printf); \
+x86_call_reg (s->code, X86_EAX); \
 x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 3*4); \
 x86_pop_reg (s->code, X86_ECX); \
 x86_pop_reg (s->code, X86_EDX); \
@@ -140,6 +141,15 @@ x86_pop_reg (s->code, X86_EAX);
                x86_imm_emit32 ((inst), (disp));               \
        } while (0)
 
+/* emit an exception if condition is fail */
+#define EMIT_COND_EXCEPTION(cond, exc)                                       \
+        do {                                                                 \
+               x86_branch8 (s->code, cond, 12, TRUE);                       \
+               x86_mov_reg_imm (s->code, X86_ECX, exc);                     \
+               x86_mov_reg_imm (s->code, X86_EAX, get_throw_exception ());  \
+               x86_call_reg (s->code, X86_EAX);                             \
+       } while (0); 
+
 %%
 
 #
@@ -274,6 +284,8 @@ reg: EXCEPTION {
 }
 
 stmt: THROW (reg) {
+       tree->is_jump = TRUE;
+
        if (tree->left->reg1 != X86_ECX)
                x86_mov_reg_reg (s->code, X86_ECX, tree->left->reg1, 4);
 
@@ -283,6 +295,8 @@ stmt: THROW (reg) {
 stmt: RETHROW {
        int offset = g_array_index (s->varinfo, MonoVarInfo, tree->data.i).offset;
 
+       tree->is_jump = TRUE;
+
        x86_mov_reg_membase (s->code, X86_ECX, X86_EBP, offset, 4);
 
        x86_call_code (s->code, get_throw_exception ());
@@ -290,7 +304,7 @@ stmt: RETHROW {
 
 stmt: HANDLER {
        gint32 addr = tree->data.bb->addr - tree->addr - 5;
-       tree->is_jump = 1;    
+       tree->is_jump = TRUE;    
        x86_call_imm (s->code, addr); 
 }
 
@@ -564,9 +578,7 @@ reg: CONV_I4 (reg) {
 
 reg: CONV_OVF_U4 (reg) {
        x86_test_reg_imm (s->code, tree->left->reg1, 0x8000000);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
@@ -574,12 +586,11 @@ reg: CONV_OVF_U4 (reg) {
 reg: CONV_OVF_I1 (reg) {
        /* probe value to be within -128 to 127 */
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 127);
-       x86_branch8 (s->code, X86_CC_LE, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
-       
+       EMIT_COND_EXCEPTION (X86_CC_LE, get_exception_overflow ());     
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, -128);
-       x86_branch8 (s->code, X86_CC_LT, -17, TRUE);
+       // fixme: check that branch distance
+       g_assert_not_reached ();
+       x86_branch8 (s->code, X86_CC_LT, -19, TRUE);
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
@@ -587,9 +598,7 @@ reg: CONV_OVF_I1 (reg) {
 reg: CONV_OVF_I1_UN (reg) {
        /* probe values between 0 to 128 */
        x86_test_reg_imm (s->code, tree->left->reg1, 0xffffff80);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());     
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);     
 }
@@ -597,22 +606,18 @@ reg: CONV_OVF_I1_UN (reg) {
 reg: CONV_OVF_U1 (reg) {
        /* probe value to be within 0 to 255 */
        x86_test_reg_imm (s->code, tree->left->reg1, 0xffffff00);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());     
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);     
 }
 
 reg: CONV_OVF_I2 (reg) {
        /* Probe value to be within -32768 and 32767 */
-
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 32767);
-       x86_branch8 (s->code, X86_CC_LE, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
-
+       EMIT_COND_EXCEPTION (X86_CC_LE, get_exception_overflow ());     
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, -32768);
+       // fixme: check branch
+       g_assert_not_reached ();
        x86_branch8 (s->code, X86_CC_LT, -17, TRUE);
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
@@ -621,9 +626,7 @@ reg: CONV_OVF_I2 (reg) {
 reg: CONV_OVF_U2 (reg) {
        /* Probe value to be within 0 and 65535 */
        x86_test_reg_imm (s->code, tree->left->reg1, 0xffff0000);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());     
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);     
 }
@@ -631,9 +634,7 @@ reg: CONV_OVF_U2 (reg) {
 reg: CONV_OVF_I2_UN (reg) {
        /* Convert uint value into short, value within 0 and 32767 */
        x86_test_reg_imm (s->code, tree->left->reg1, 0xffff8000);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());     
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);     
 }
@@ -837,7 +838,8 @@ reg: NEWARR (reg) {
 
        x86_push_reg (s->code, tree->left->reg1);
        x86_push_imm (s->code, tree->data.p);
-       x86_call_code (s->code, mono_array_new);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_array_new);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, sizeof (gpointer) + 4);
 
        x86_pop_reg (s->code, X86_EDX);
@@ -855,7 +857,8 @@ reg: NEWOBJ {
        x86_push_reg (s->code, X86_EDX);
 
        x86_push_imm (s->code, tree->data.klass);
-       x86_call_code (s->code, mono_object_new);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_object_new);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, sizeof (gpointer));
 
        x86_pop_reg (s->code, X86_EDX);
@@ -880,40 +883,22 @@ reg: NEWSTRUCT {
 }
 
 reg: UNBOX (reg) {
-       guint8 *start = s->code, *l1, *l2, *l3, *le;
-       int i;
-
-       tree->is_jump = TRUE;
-       l1 = l2 = l3 = le = NULL;
-
-       for (i = 0; i < 2; i++) {
-               s->code = start;
-
-               if (tree->reg1 != tree->left->reg1)
-                       x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
+       if (tree->reg1 != tree->left->reg1)
+               x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 
-               x86_alu_reg_imm (s->code, X86_CMP, tree->reg1, 0);
-               x86_branch8 (s->code, X86_CC_NE, l2 - l1, FALSE);
-               l1 = s->code;
-               x86_mov_reg_imm (s->code, X86_ECX, get_exception_null_reference ());
-               x86_call_code (s->code, get_throw_exception ());
-               l2 = s->code;
-               x86_alu_membase_imm (s->code, X86_CMP, tree->reg1, 0, ((int)(tree->data.klass)));
-               x86_branch8 (s->code, X86_CC_EQ, le - l3, FALSE);
-               l3 = s->code;
-               x86_mov_reg_imm (s->code, X86_ECX, get_exception_invalid_cast ());
-               x86_call_code (s->code, get_throw_exception ());
-               le = s->code;
-               x86_alu_reg_imm (s->code, X86_ADD, tree->reg1, sizeof (MonoObject));
-       }
+       x86_alu_reg_imm (s->code, X86_CMP, tree->reg1, 0);
+       EMIT_COND_EXCEPTION (X86_CC_NE, get_exception_null_reference ());       
+       x86_alu_membase_imm (s->code, X86_CMP, tree->reg1, 0, ((int)(tree->data.klass)));
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_invalid_cast ()); 
+       x86_alu_reg_imm (s->code, X86_ADD, tree->reg1, sizeof (MonoObject));
 }
 
 reg: CASTCLASS (reg) {
-       guint8 *start = s->code, *l1, *l2, *l3, *l4, *le;
+       guint8 *start = s->code, *l1, *l2, *le;
        int i;
 
        tree->is_jump = TRUE;
-       l1 = l2 = l3 = l4 = le = NULL;
+       l1 = l2 = le = NULL;
 
        for (i = 0; i < 2; i++) {
                s->code = start;
@@ -929,18 +914,14 @@ reg: CASTCLASS (reg) {
 
                x86_push_imm (s->code, tree->data.klass);
                x86_push_reg (s->code, tree->left->reg1);
-               x86_call_code (s->code, mono_object_isinst);
+               x86_mov_reg_imm (s->code, X86_EAX, mono_object_isinst);
+               x86_call_reg (s->code, X86_EAX);
                x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
                x86_pop_reg (s->code, X86_EDX);
                x86_pop_reg (s->code, X86_ECX);
 
                x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0);
-               x86_branch8 (s->code, X86_CC_NE, le - l3, FALSE);
-               l3 = s->code;
-
-               x86_mov_reg_imm (s->code, X86_ECX, get_exception_invalid_cast ());
-               x86_call_code (s->code, get_throw_exception ());
-
+               EMIT_COND_EXCEPTION (X86_CC_NE, get_exception_invalid_cast ()); 
                le = s->code;
 
        }
@@ -954,7 +935,8 @@ reg: ISINST (reg) {
 
        x86_push_imm (s->code, tree->data.klass);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_object_isinst);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_object_isinst);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
 
        x86_pop_reg (s->code, X86_EDX);
@@ -1085,7 +1067,7 @@ stmt: POP (reg)
 
 stmt: BR {
        gint32 addr = tree->data.bb->addr - tree->addr - 5;
-       tree->is_jump = 1;    
+       tree->is_jump = TRUE;    
        
        x86_jump32 (s->code, addr); 
 }
@@ -1093,7 +1075,7 @@ stmt: BR {
 stmt: BLT (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LT, tree->data.bb->addr - offset, TRUE); 
@@ -1102,7 +1084,7 @@ stmt: BLT (reg, reg) 1 {
 stmt: BLT (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LT, tree->data.bb->addr - offset, TRUE); 
@@ -1111,7 +1093,7 @@ stmt: BLT (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BLT_UN (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LT, tree->data.bb->addr - offset, FALSE); 
@@ -1120,7 +1102,7 @@ stmt: BLT_UN (reg, reg) 1 {
 stmt: BLT_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LT, tree->data.bb->addr - offset, FALSE); 
@@ -1129,7 +1111,7 @@ stmt: BLT_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BGT (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GT, tree->data.bb->addr - offset, TRUE); 
@@ -1138,7 +1120,7 @@ stmt: BGT (reg, reg) 1 {
 stmt: BGT (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GT, tree->data.bb->addr - offset, TRUE); 
@@ -1147,7 +1129,7 @@ stmt: BGT (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BGT_UN (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GT, tree->data.bb->addr - offset, FALSE); 
@@ -1156,7 +1138,7 @@ stmt: BGT_UN (reg, reg) 1 {
 stmt: BGT_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GT, tree->data.bb->addr - offset, FALSE); 
@@ -1165,7 +1147,7 @@ stmt: BGT_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BEQ (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, TRUE);
@@ -1174,7 +1156,7 @@ stmt: BEQ (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BEQ (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, TRUE);
@@ -1183,7 +1165,7 @@ stmt: BEQ (reg, reg) 1 {
 stmt: BNE_UN (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
@@ -1192,7 +1174,7 @@ stmt: BNE_UN (reg, reg) 1 {
 stmt: BNE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
@@ -1201,7 +1183,7 @@ stmt: BNE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BGE (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GE, tree->data.bb->addr - offset, TRUE);
@@ -1210,7 +1192,7 @@ stmt: BGE (reg, reg) 1 {
 stmt: BGE (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GE, tree->data.bb->addr - offset, TRUE);
@@ -1219,7 +1201,7 @@ stmt: BGE (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BGE_UN (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GE, tree->data.bb->addr - offset, FALSE);
@@ -1228,7 +1210,7 @@ stmt: BGE_UN (reg, reg) 1 {
 stmt: BGE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_GE, tree->data.bb->addr - offset, FALSE);
@@ -1237,7 +1219,7 @@ stmt: BGE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BLE (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LE, tree->data.bb->addr - offset, TRUE);
@@ -1246,7 +1228,7 @@ stmt: BLE (reg, reg) 1 {
 stmt: BLE (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LE, tree->data.bb->addr - offset, TRUE);
@@ -1255,7 +1237,7 @@ stmt: BLE (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BLE_UN (reg, reg) 1 {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LE, tree->data.bb->addr - offset, FALSE);
@@ -1264,7 +1246,7 @@ stmt: BLE_UN (reg, reg) 1 {
 stmt: BLE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_LE, tree->data.bb->addr - offset, FALSE);
@@ -1273,7 +1255,7 @@ stmt: BLE_UN (reg, CONST_I4) "MB_USE_OPT1(0)" {
 stmt: BRTRUE (reg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, TRUE);
@@ -1282,7 +1264,7 @@ stmt: BRTRUE (reg) {
 stmt: BRFALSE (reg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
        offset = 6 + s->code - s->start;
        x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, TRUE);
@@ -1297,14 +1279,14 @@ stmt: RET (reg) {
                x86_mov_reg_reg (s->code, X86_EAX, tree->left->reg1, 4);
 
        if (!tree->last_instr) {
-               tree->is_jump = 1;
+               tree->is_jump = TRUE;
                x86_jump32 (s->code, s->epilog - 5);      
        }
 }
 
 stmt: RET_VOID {
        if (!tree->last_instr) {
-               tree->is_jump = 1;
+               tree->is_jump = TRUE;
                x86_jump32 (s->code, s->epilog - 5);
        } 
 }
@@ -1322,7 +1304,8 @@ stmt: ARG_STRING (reg) {
        x86_push_reg (s->code, X86_EDX);
 
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_string_to_utf8);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_string_to_utf8);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 4);
        
        x86_mov_membase_reg (s->code, X86_ESP, 12, X86_EAX, 4);
@@ -1559,7 +1542,7 @@ stmt: SWITCH (reg) {
        guint32 offset;
        guint32 *jt = (guint32 *)tree->data.p;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, jt [0]);
        offset = 6 + (guint32)s->code;
@@ -1590,17 +1573,18 @@ reg: CONV_OVF_I4 (lreg){
        
        /* We are not negative (no top bit set, check for our top word to be zero */
        x86_test_reg_reg (s->code, tree->left->reg2, tree->left->reg2);
-       x86_branch8 (s->code, X86_CC_EQ, 15, TRUE);
+       x86_branch8 (s->code, X86_CC_EQ, 17, TRUE);
 
        /* throw exception */
        x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       x86_mov_reg_imm (s->code, X86_EAX, get_throw_exception ()); 
+       x86_call_reg (s->code, X86_EAX); 
        
        /* our top bit is set, check that top word is 0xfffffff */
        x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg2, 0xffffffff);
 
        /* nope, emit exception */
-       x86_branch8 (s->code, X86_CC_NE, -15, TRUE);
+       x86_branch8 (s->code, X86_CC_NE, -17, TRUE);
 
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
@@ -1609,11 +1593,7 @@ reg: CONV_OVF_I4 (lreg){
 reg: CONV_OVF_U4 (lreg) {
        /* top word must be 0 */
        x86_test_reg_reg (s->code, tree->left->reg2, tree->left->reg2);
-       x86_branch8 (s->code, X86_CC_EQ, 15, TRUE);
-
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
-
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
@@ -1656,7 +1636,8 @@ lreg: CONV_U8 (CONST_I4) 1 {
 lreg: CONV_OVF_U8 (CONST_I4) {
        if (tree->left->data.i < 0){
                x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-               x86_call_code (s->code, get_throw_exception ());
+               x86_mov_reg_imm (s->code, X86_EAX, get_throw_exception ()); 
+               x86_call_reg (s->code, X86_EAX);                            
        } else {
                x86_mov_reg_imm (s->code, tree->reg1, tree->left->data.i);
                x86_alu_reg_reg (s->code, X86_XOR, tree->reg2, tree->reg2);
@@ -1670,9 +1651,7 @@ lreg: CONV_OVF_I8_UN (CONST_I4) {
 
 lreg: CONV_OVF_U8 (reg) {
        x86_test_reg_imm (s->code, tree->left->reg1, 0x8000000);
-       x86_branch8 (s->code, X86_CC_EQ, 10, TRUE);
-       x86_mov_reg_imm (s->code, X86_ECX, get_exception_overflow ());
-       x86_call_code (s->code, get_throw_exception ());
+       EMIT_COND_EXCEPTION (X86_CC_EQ, get_exception_overflow ());
 
        if (tree->reg1 != tree->left->reg1)
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
@@ -1823,7 +1802,8 @@ lreg: MUL (lreg, lreg) {
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_llmult);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_llmult);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 16);
 
        if (mono_regset_reg_used (s->rs, X86_ECX))
@@ -1838,7 +1818,8 @@ lreg: DIV (lreg, lreg) {
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_lldiv);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_lldiv);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 16);
 
        if (mono_regset_reg_used (s->rs, X86_ECX))
@@ -1853,7 +1834,8 @@ lreg: REM (lreg, lreg) {
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_llrem);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_llrem);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 16);
 
        if (mono_regset_reg_used (s->rs, X86_ECX))
@@ -1868,7 +1850,8 @@ lreg: DIV_UN (lreg, lreg) {
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_lldiv_un);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_lldiv_un);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 16);
 
        if (mono_regset_reg_used (s->rs, X86_ECX))
@@ -1883,7 +1866,8 @@ lreg: REM_UN (lreg, lreg) {
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg2);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, mono_llrem_un);
+       x86_mov_reg_imm (s->code, X86_EAX, mono_llrem_un);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 16);
 
        if (mono_regset_reg_used (s->rs, X86_ECX))
@@ -1934,7 +1918,7 @@ stmt: RET (lreg) {
        }
 
        if (!tree->last_instr) {
-               tree->is_jump = 1;
+               tree->is_jump = TRUE;
                x86_jump32 (s->code, s->epilog - 5);      
        }
 }
@@ -1949,7 +1933,7 @@ stmt: BEQ (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -1965,7 +1949,7 @@ stmt: BEQ (lreg, lreg) {
 stmt: BNE_UN (lreg, lreg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1);
        offset = 6 + s->code - s->start;
@@ -1979,7 +1963,7 @@ stmt: BGE (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -1999,7 +1983,7 @@ stmt: BGE_UN (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2019,7 +2003,7 @@ stmt: BGT (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2039,7 +2023,7 @@ stmt: BGT_UN (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2059,7 +2043,7 @@ stmt: BLT (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2079,7 +2063,7 @@ stmt: BLT_UN (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2099,7 +2083,7 @@ stmt: BLE (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2119,7 +2103,7 @@ stmt: BLE_UN (lreg, lreg) {
        guint8 *start = s->code;
        gint32 o1, o2, oe, i;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
 
        for (i = 0; i < 2; i ++) {
                s->code = start;
@@ -2283,7 +2267,7 @@ stmt: ARG_R8 (freg) {
 stmt: BEQ (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2295,7 +2279,7 @@ stmt: BEQ (freg, freg) {
 stmt: BNE_UN (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2307,7 +2291,7 @@ stmt: BNE_UN (freg, freg) {
 stmt: BLT (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2318,7 +2302,7 @@ stmt: BLT (freg, freg) {
 stmt: BLT_UN (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2329,7 +2313,7 @@ stmt: BLT_UN (freg, freg) {
 stmt: BGE_UN (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2340,7 +2324,7 @@ stmt: BGE_UN (freg, freg) {
 stmt: BGT_UN (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2352,7 +2336,7 @@ stmt: BGT_UN (freg, freg) {
 stmt: BLE_UN (freg, freg) {
        gint32 offset;
 
-       tree->is_jump = 1;
+       tree->is_jump = TRUE;
        x86_fcompp (s->code);
        x86_fnstsw (s->code);
        x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
@@ -2444,7 +2428,7 @@ freg: CALL_R8 (this, VFUNC_ADDR) {
 stmt: RET (freg) {
 
        if (!tree->last_instr) {
-               tree->is_jump = 1;
+               tree->is_jump = TRUE;
                x86_jump32 (s->code, s->epilog - 5);      
        }
 }
@@ -2465,7 +2449,8 @@ stmt: STIND_OBJ (reg, reg) {
        x86_push_imm (s->code, tree->data.i);
        x86_push_reg (s->code, tree->right->reg1);
        x86_push_reg (s->code, tree->left->reg1);
-       x86_call_code (s->code, MEMCOPY);
+       x86_mov_reg_imm (s->code, X86_EAX, MEMCOPY);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
 
        x86_pop_reg (s->code, X86_ECX);
@@ -2498,7 +2483,8 @@ stmt: ARG_OBJ (reg) {
        x86_lea_membase (s->code, X86_EAX, X86_ESP, 5*4);
        x86_push_reg (s->code, X86_EAX);
 
-       x86_call_code (s->code, MEMCOPY);
+       x86_mov_reg_imm (s->code, X86_EAX, MEMCOPY);
+       x86_call_reg (s->code, X86_EAX);
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
 
        x86_pop_reg (s->code, X86_ECX);
@@ -2513,11 +2499,13 @@ stmt: RET_OBJ (reg) {
        x86_push_reg (s->code, tree->left->reg1);
        x86_push_membase (s->code, X86_EBP, 8);
 
-       x86_call_code (s->code, MEMCOPY);
+       x86_mov_reg_imm (s->code, X86_EAX, MEMCOPY);
+       x86_call_reg (s->code, X86_EAX);
+
        x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
 
        if (!tree->last_instr) {
-               tree->is_jump = 1;
+               tree->is_jump = TRUE;
                x86_jump32 (s->code, s->epilog - 5);      
        }
 }