* src/vm/jit/x86_64/emit.c (emit_trap_compiler): Fixed comment.
[cacao.git] / src / vm / jit / x86_64 / emit.c
index 50839403995f7a26ae27dcf64c515bc139746109..d0f940a16124e8a2f4ba84ae2474f1ab1dd7e8ea 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes:
-
-   $Id: emit.c 5288 2006-09-04 15:48:16Z twisti $
-
 */
 
 #include "config.h"
 
+#include <assert.h>
+
 #include "vm/types.h"
 
 #include "md-abi.h"
 
 #include "vm/jit/x86_64/codegen.h"
-#include "vm/jit/x86_64/md-emit.h"
+#include "vm/jit/x86_64/emit.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "mm/memory.h"
+
+#include "threads/lock-common.h"
 
 #include "vm/builtin.h"
+#include "vm/exceptions.h"
+
+#include "vm/jit/abi.h"
 #include "vm/jit/abi-asm.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
-#include "vm/jit/emit.h"
+#include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
 
+#include "vmcore/options.h"
 
-/* code generation functions **************************************************/
 
 /* emit_load *******************************************************************
 
 
 *******************************************************************************/
 
-s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
-{
-       codegendata  *cd;
-       s4            disp;
-       s4            reg;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
-
-               disp = src->regoff * 8;
-
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-
-               } else {
-                       if (IS_INT_TYPE(src->type))
-                               M_ILD(tempreg, REG_SP, disp);
-                       else
-                               M_LLD(tempreg, REG_SP, disp);
-               }
-
-               reg = tempreg;
-       } else
-               reg = src->regoff;
-
-       return reg;
-}
-
-
-/* emit_load_s1 ****************************************************************
-
-   Emits a possible load of the first source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
-{
-       codegendata  *cd;
-       s4            disp;
-       s4            reg;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
-
-               disp = src->regoff * 8;
-
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-
-               } else {
-                       if (IS_INT_TYPE(src->type))
-                               M_ILD(tempreg, REG_SP, disp);
-                       else
-                               M_LLD(tempreg, REG_SP, disp);
-               }
-
-               reg = tempreg;
-       } else
-               reg = src->regoff;
-
-       return reg;
-}
-
-
-/* emit_load_s2 ****************************************************************
-
-   Emits a possible load of the second source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -156,69 +70,33 @@ s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
        cd = jd->cd;
 
-       if (src->flags & INMEMORY) {
+       if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
-               disp = src->regoff * 8;
-
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-
-               } else {
-                       if (IS_INT_TYPE(src->type))
-                               M_ILD(tempreg, REG_SP, disp);
-                       else
-                               M_LLD(tempreg, REG_SP, disp);
+               disp = src->vv.regoff;
+
+               switch (src->type) {
+               case TYPE_INT:
+                       M_ILD(tempreg, REG_SP, disp);
+                       break;
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       M_LLD(tempreg, REG_SP, disp);
+                       break;
+               case TYPE_FLT:
+                       M_FLD(tempreg, REG_SP, disp);
+                       break;
+               case TYPE_DBL:
+                       M_DLD(tempreg, REG_SP, disp);
+                       break;
+               default:
+                       vm_abort("emit_load: unknown type %d", src->type);
                }
 
                reg = tempreg;
-       } else
-               reg = src->regoff;
-
-       return reg;
-}
-
-
-/* emit_load_s3 ****************************************************************
-
-   Emits a possible load of the third source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
-{
-       codegendata  *cd;
-       s4            disp;
-       s4            reg;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       if (src->flags & INMEMORY) {
-               COUNT_SPILLS;
-
-               disp = src->regoff * 8;
-
-               if (IS_FLT_DBL_TYPE(src->type)) {
-                       if (IS_2_WORD_TYPE(src->type))
-                               M_DLD(tempreg, REG_SP, disp);
-                       else
-                               M_FLD(tempreg, REG_SP, disp);
-
-               } else {
-                       if (IS_INT_TYPE(src->type))
-                               M_ILD(tempreg, REG_SP, disp);
-                       else
-                               M_LLD(tempreg, REG_SP, disp);
-               }
-
-               reg = tempreg;
-       } else
-               reg = src->regoff;
+       }
+       else
+               reg = src->vv.regoff;
 
        return reg;
 }
@@ -233,10 +111,9 @@ s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
     
 *******************************************************************************/
 
-void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
-       registerdata *rd;
        s4            disp;
 #if 0
        s4            s;
@@ -246,7 +123,6 @@ void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
        /* get required compiler data */
 
        cd = jd->cd;
-       rd = jd->rd;
 
 #if 0
        /* do we have to generate a conditional move? */
@@ -271,50 +147,87 @@ void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
        }
 #endif
 
-       if (dst->flags & INMEMORY) {
+       if (IS_INMEMORY(dst->flags)) {
                COUNT_SPILLS;
 
-               disp = dst->regoff * 8;
+               disp = dst->vv.regoff;
 
-               if (IS_FLT_DBL_TYPE(dst->type)) {
-                       if (IS_2_WORD_TYPE(dst->type))
-                               M_DST(d, REG_SP, disp);
-                       else
-                               M_FST(d, REG_SP, disp);
-
-               } else
+               switch (dst->type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
                        M_LST(d, REG_SP, disp);
+                       break;
+               case TYPE_FLT:
+                       M_FST(d, REG_SP, disp);
+                       break;
+               case TYPE_DBL:
+                       M_DST(d, REG_SP, disp);
+                       break;
+               default:
+                       vm_abort("emit_store: unknown type %d", dst->type);
+               }
        }
 }
 
 
 /* emit_copy *******************************************************************
 
-   XXX
+   Generates a register/memory to register/memory copy.
 
 *******************************************************************************/
 
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
+void emit_copy(jitdata *jd, instruction *iptr)
 {
-       codegendata  *cd;
-       registerdata *rd;
-       s4            s1, d;
+       codegendata *cd;
+       varinfo     *src;
+       varinfo     *dst;
+       s4           s1, d;
 
        /* get required compiler data */
 
        cd = jd->cd;
-       rd = jd->rd;
 
-       if ((src->regoff != dst->regoff) ||
+       /* get source and destination variables */
+
+       src = VAROP(iptr->s1);
+       dst = VAROP(iptr->dst);
+
+       if ((src->vv.regoff != dst->vv.regoff) ||
                ((src->flags ^ dst->flags) & INMEMORY)) {
-               d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
-               s1 = emit_load_s1(jd, iptr, src, d);
+
+               if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
+                       /* emit nothing, as the value won't be used anyway */
+                       return;
+               }
+
+               /* If one of the variables resides in memory, we can eliminate
+                  the register move from/to the temporary register with the
+                  order of getting the destination register and the load. */
+
+               if (IS_INMEMORY(src->flags)) {
+                       d  = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
+                       s1 = emit_load(jd, iptr, src, d);
+               }
+               else {
+                       s1 = emit_load(jd, iptr, src, REG_IFTMP);
+                       d  = codegen_reg_of_var(iptr->opc, dst, s1);
+               }
 
                if (s1 != d) {
-                       if (IS_FLT_DBL_TYPE(src->type))
-                               M_FMOV(s1, d);
-                       else
+                       switch (src->type) {
+                       case TYPE_INT:
+                       case TYPE_LNG:
+                       case TYPE_ADR:
                                M_MOV(s1, d);
+                               break;
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               M_FMOV(s1, d);
+                               break;
+                       default:
+                               vm_abort("emit_copy: unknown type %d", src->type);
+                       }
                }
 
                emit_store(jd, iptr, dst, d);
@@ -349,213 +262,214 @@ void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
 }
 
 
-/* emit_exception_stubs ********************************************************
+/* emit_branch *****************************************************************
 
-   Generates the code for the exception stubs.
+   Emits the code for conditional and unconditional branchs.
 
 *******************************************************************************/
 
-void emit_exception_stubs(jitdata *jd)
+void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options)
 {
-       codegendata  *cd;
-       registerdata *rd;
-       exceptionref *eref;
-       s4           targetdisp;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-       rd = jd->rd;
-
-       /* generate exception stubs */
-
-       targetdisp = 0;
+       s4 branchdisp;
 
-       for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
-               gen_resolvebranch(cd->mcodebase + eref->branchpos, 
-                                                 eref->branchpos,
-                                                 cd->mcodeptr - cd->mcodebase);
+       /* NOTE: A displacement overflow cannot happen. */
 
-               MCODECHECK(512);
+       /* check which branch to generate */
 
-               /* Check if the exception is an
-                  ArrayIndexOutOfBoundsException.  If so, move index register
-                  into a4. */
+       if (condition == BRANCH_UNCONDITIONAL) {
 
-               if (eref->reg != -1)
-                       M_MOV(eref->reg, rd->argintregs[4]);
+               /* calculate the different displacements */
 
-               /* calcuate exception address */
+               branchdisp = disp - BRANCH_UNCONDITIONAL_SIZE;
 
-               M_MOV_IMM(0, rd->argintregs[3]);
-               dseg_adddata(cd);
-               M_AADD_IMM32(eref->branchpos - 6, rd->argintregs[3]);
-
-               /* move function to call into REG_ITMP3 */
-
-               M_MOV_IMM(eref->function, REG_ITMP3);
-
-               if (targetdisp == 0) {
-                       targetdisp = cd->mcodeptr - cd->mcodebase;
+               M_JMP_IMM(branchdisp);
+       }
+       else {
+               /* calculate the different displacements */
+
+               branchdisp = disp - BRANCH_CONDITIONAL_SIZE;
+
+               switch (condition) {
+               case BRANCH_EQ:
+                       M_BEQ(branchdisp);
+                       break;
+               case BRANCH_NE:
+                       M_BNE(branchdisp);
+                       break;
+               case BRANCH_LT:
+                       M_BLT(branchdisp);
+                       break;
+               case BRANCH_GE:
+                       M_BGE(branchdisp);
+                       break;
+               case BRANCH_GT:
+                       M_BGT(branchdisp);
+                       break;
+               case BRANCH_LE:
+                       M_BLE(branchdisp);
+                       break;
+               case BRANCH_ULT:
+                       M_BULT(branchdisp);
+                       break;
+               case BRANCH_ULE:
+                       M_BULE(branchdisp);
+                       break;
+               case BRANCH_UGE:
+                       M_BUGE(branchdisp);
+                       break;
+               case BRANCH_UGT:
+                       M_BUGT(branchdisp);
+                       break;
+               default:
+                       vm_abort("emit_branch: unknown condition %d", condition);
+               }
+       }
+}
 
-                       emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), rd->argintregs[0]);
-                       M_MOV(REG_SP, rd->argintregs[1]);
-                       M_ALD(rd->argintregs[2], REG_SP, cd->stackframesize * 8);
 
-                       M_ASUB_IMM(2 * 8, REG_SP);
-                       M_AST(rd->argintregs[3], REG_SP, 0 * 8);             /* store XPC */
+/* emit_arithmetic_check *******************************************************
 
-                       M_CALL(REG_ITMP3);
+   Emit an ArithmeticException check.
 
-                       M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
-                       M_AADD_IMM(2 * 8, REG_SP);
+*******************************************************************************/
 
-                       M_MOV_IMM(asm_handle_exception, REG_ITMP3);
-                       M_JMP(REG_ITMP3);
-               }
-               else {
-                       M_JMP_IMM((cd->mcodebase + targetdisp) -
-                                         (cd->mcodeptr + PATCHER_CALL_SIZE));
-               }
+void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(reg);
+               M_BNE(8);
+               M_ALD_MEM(reg, EXCEPTION_HARDWARE_ARITHMETIC);
        }
 }
 
 
-/* emit_patcher_stubs **********************************************************
+/* emit_arrayindexoutofbounds_check ********************************************
 
-   Generates the code for the patcher stubs.
+   Emit a ArrayIndexOutOfBoundsException check.
 
 *******************************************************************************/
 
-void emit_patcher_stubs(jitdata *jd)
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
 {
-       codegendata *cd;
-       patchref    *pref;
-       u8           mcode;
-       u1          *savedmcodeptr;
-       u1          *tmpmcodeptr;
-       s4           targetdisp;
-       s4           disp;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       /* generate code patching stub call code */
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+        M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
+        M_ICMP(REG_ITMP3, s2);
+               M_BULT(8);
+               M_ALD_MEM(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+       }
+}
 
-       targetdisp = 0;
 
-       for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
-               /* check size of code segment */
+/* emit_arraystore_check *******************************************************
 
-               MCODECHECK(512);
+   Emit an ArrayStoreException check.
 
-               /* Get machine code which is patched back in later. A
-                  `call rel32' is 5 bytes long (but read 8 bytes). */
+*******************************************************************************/
 
-               savedmcodeptr = cd->mcodebase + pref->branchpos;
-               mcode = *((u8 *) savedmcodeptr);
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(REG_RESULT);
+               M_BNE(8);
+               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_ARRAYSTORE);
+       }
+}
 
-               /* patch in `call rel32' to call the following code */
 
-               tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr              */
-               cd->mcodeptr = savedmcodeptr;   /* set mcodeptr to patch position     */
+/* emit_classcast_check ********************************************************
 
-               M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
+   Emit a ClassCastException check.
 
-               cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr       */
+*******************************************************************************/
 
-               /* move pointer to java_objectheader onto stack */
+void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               switch (condition) {
+               case BRANCH_LE:
+                       M_BGT(8);
+                       break;
+               case BRANCH_EQ:
+                       M_BNE(8);
+                       break;
+               case BRANCH_UGT:
+                       M_BULE(8);
+                       break;
+               default:
+                       vm_abort("emit_classcast_check: unknown condition %d", condition);
+               }
+               M_ALD_MEM(s1, EXCEPTION_HARDWARE_CLASSCAST);
+       }
+}
 
-#if defined(ENABLE_THREADS)
-               /* create a virtual java_objectheader */
 
-               (void) dseg_addaddress(cd, NULL);                          /* flcword */
-               (void) dseg_addaddress(cd, lock_get_initial_lock_word());
-               disp = dseg_addaddress(cd, NULL);                          /* vftbl   */
+/* emit_nullpointer_check ******************************************************
 
-               emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
-#else
-               M_PUSH_IMM(0);
-#endif
+   Emit a NullPointerException check.
 
-               /* move machine code bytes and classinfo pointer into registers */
+*******************************************************************************/
 
-               M_MOV_IMM(mcode, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(reg);
+               M_BNE(8);
+               M_ALD_MEM(reg, EXCEPTION_HARDWARE_NULLPOINTER);
+       }
+}
 
-               M_MOV_IMM(pref->ref, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
 
-               M_MOV_IMM(pref->disp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+/* emit_exception_check ********************************************************
 
-               M_MOV_IMM(pref->patcher, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+   Emit an Exception check.
 
-               if (targetdisp == 0) {
-                       targetdisp = cd->mcodeptr - cd->mcodebase;
+*******************************************************************************/
 
-                       M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
-                       M_JMP(REG_ITMP3);
-               }
-               else {
-                       M_JMP_IMM((cd->mcodebase + targetdisp) -
-                                         (cd->mcodeptr + PATCHER_CALL_SIZE));
-               }
+void emit_exception_check(codegendata *cd, instruction *iptr)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(REG_RESULT);
+               M_BNE(8);
+               M_ALD_MEM(REG_RESULT, EXCEPTION_HARDWARE_EXCEPTION);
        }
 }
 
 
-/* emit_replacement_stubs ******************************************************
+/* emit_trap_compiler **********************************************************
 
-   Generates the code for the replacement stubs.
+   Emit a trap instruction which calls the JIT compiler.
 
 *******************************************************************************/
 
-void emit_replacement_stubs(jitdata *jd)
+void emit_trap_compiler(codegendata *cd)
 {
-       codegendata *cd;
-       codeinfo    *code;
-       rplpoint    *rplp;
-       s4           disp;
-       s4           i;
-
-       /* get required compiler data */
-
-       cd   = jd->cd;
-       code = jd->code;
-
-       rplp = code->rplpoints;
+       M_ALD_MEM(REG_METHODPTR, EXCEPTION_HARDWARE_COMPILER);
+}
 
-       for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
-               /* check code segment size */
 
-               MCODECHECK(512);
+/* emit_trap *******************************************************************
 
-               /* note start of stub code */
+   Emit a trap instruction and return the original machine code.
 
-               rplp->outcode = (u1 *) (ptrint) (cd->mcodeptr - cd->mcodebase);
+*******************************************************************************/
 
-               /* make machine code for patching */
+uint32_t emit_trap(codegendata *cd)
+{
+       uint16_t mcode;
 
-               disp = (ptrint) (rplp->outcode - rplp->pc) - 5;
+       /* Get machine code which is patched back in later. The trap is 2
+          bytes long. */
 
-               rplp->mcode = 0xe9 | ((u8) disp << 8);
+       mcode = *((uint16_t *) cd->mcodeptr);
 
-               /* push address of `rplpoint` struct */
-                       
-               M_MOV_IMM(rplp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+       /* XXX This needs to be change to INT3 when the debugging problems
+          with gdb are resolved. */
 
-               /* jump to replacement function */
+       M_UD2;
 
-               M_MOV_IMM(asm_replacement_out, REG_ITMP3);
-               M_JMP(REG_ITMP3);
-       }
+       return mcode;
 }
-       
+
 
 /* emit_verbosecall_enter ******************************************************
 
@@ -591,10 +505,10 @@ void emit_verbosecall_enter(jitdata *jd)
        /* save argument registers */
 
        for (i = 0; i < INT_ARG_CNT; i++)
-               M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
+               M_LST(abi_registers_integer_argument[i], REG_SP, (1 + i) * 8);
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
+               M_DST(abi_registers_float_argument[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
 
        /* save temporary registers for leaf methods */
 
@@ -614,25 +528,27 @@ void emit_verbosecall_enter(jitdata *jd)
        
                if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
                        for (k = INT_ARG_CNT - 2; k >= i; k--)
-                               M_MOV(rd->argintregs[k], rd->argintregs[k + 1]);
+                               M_MOV(abi_registers_integer_argument[k],
+                                         abi_registers_integer_argument[k + 1]);
 
-                       emit_movd_freg_reg(cd, rd->argfltregs[j], rd->argintregs[i]);
+                       emit_movd_freg_reg(cd, abi_registers_float_argument[j],
+                                                          abi_registers_integer_argument[i]);
                        j++;
                }
        }
 
        M_MOV_IMM(m, REG_ITMP2);
        M_AST(REG_ITMP2, REG_SP, 0 * 8);
-       M_MOV_IMM(builtin_trace_args, REG_ITMP1);
+       M_MOV_IMM(builtin_verbosecall_enter, REG_ITMP1);
        M_CALL(REG_ITMP1);
 
        /* restore argument registers */
 
        for (i = 0; i < INT_ARG_CNT; i++)
-               M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
+               M_LLD(abi_registers_integer_argument[i], REG_SP, (1 + i) * 8);
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
+               M_DLD(abi_registers_float_argument[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
 
        /* restore temporary registers for leaf methods */
 
@@ -681,12 +597,12 @@ void emit_verbosecall_exit(jitdata *jd)
        M_LST(REG_RESULT, REG_SP, 0 * 8);
        M_DST(REG_FRESULT, REG_SP, 1 * 8);
 
-       M_MOV_IMM(m, rd->argintregs[0]);
-       M_MOV(REG_RESULT, rd->argintregs[1]);
-       M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
-       M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
+       M_INTMOVE(REG_RESULT, REG_A0);
+       M_FLTMOVE(REG_FRESULT, REG_FA0);
+       M_FLTMOVE(REG_FRESULT, REG_FA1);
+       M_MOV_IMM(m, REG_A1);
 
-       M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
+       M_MOV_IMM(builtin_verbosecall_exit, REG_ITMP1);
        M_CALL(REG_ITMP1);
 
        M_LLD(REG_RESULT, REG_SP, 0 * 8);
@@ -779,65 +695,76 @@ static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 index
 }
 
 
-void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
+void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
 {
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-       s4 d_old;
+       s4 s1, s2, d, d_old;
+       varinfo *v_s1,*v_s2,*v_dst;
+       codegendata *cd;
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       v_s1  = VAROP(iptr->s1);
+       v_s2  = VAROP(iptr->sx.s23.s2);
+       v_dst = VAROP(iptr->dst);
+
+       s1 = v_s1->vv.regoff;
+       s2 = v_s2->vv.regoff;
+       d  = v_dst->vv.regoff;
 
        M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
 
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+       if (IS_INMEMORY(v_dst->flags)) {
+               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        if (s1 == d) {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               emit_shiftl_membase(cd, shift_op, REG_SP, d);
 
                        } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_ILD(REG_ITMP2, REG_SP, s1 * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               M_ILD(REG_ITMP2, REG_SP, s1);
                                emit_shiftl_reg(cd, shift_op, REG_ITMP2);
-                               M_IST(REG_ITMP2, REG_SP, d * 8);
+                               M_IST(REG_ITMP2, REG_SP, d);
                        }
 
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
                        /* s1 may be equal to RCX */
                        if (s1 == RCX) {
                                if (s2 == d) {
-                                       M_ILD(REG_ITMP1, REG_SP, s2 * 8);
-                                       M_IST(s1, REG_SP, d * 8);
+                                       M_ILD(REG_ITMP1, REG_SP, s2);
+                                       M_IST(s1, REG_SP, d);
                                        M_INTMOVE(REG_ITMP1, RCX);
 
                                } else {
-                                       M_IST(s1, REG_SP, d * 8);
-                                       M_ILD(RCX, REG_SP, s2 * 8);
+                                       M_IST(s1, REG_SP, d);
+                                       M_ILD(RCX, REG_SP, s2);
                                }
 
                        } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_IST(s1, REG_SP, d * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               M_IST(s1, REG_SP, d);
                        }
 
-                       emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
+                       emit_shiftl_membase(cd, shift_op, REG_SP, d);
 
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        if (s1 == d) {
                                M_INTMOVE(s2, RCX);
-                               emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
+                               emit_shiftl_membase(cd, shift_op, REG_SP, d);
 
                        } else {
                                M_INTMOVE(s2, RCX);
-                               M_ILD(REG_ITMP2, REG_SP, s1 * 8);
+                               M_ILD(REG_ITMP2, REG_SP, s1);
                                emit_shiftl_reg(cd, shift_op, REG_ITMP2);
-                               M_IST(REG_ITMP2, REG_SP, d * 8);
+                               M_IST(REG_ITMP2, REG_SP, d);
                        }
 
                } else {
                        /* s1 may be equal to RCX */
-                       M_IST(s1, REG_SP, d * 8);
+                       M_IST(s1, REG_SP, d);
                        M_INTMOVE(s2, RCX);
-                       emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
+                       emit_shiftl_membase(cd, shift_op, REG_SP, d);
                }
 
                M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
@@ -848,20 +775,20 @@ void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
                        d = REG_ITMP3;
                }
                                        
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_ILD(RCX, REG_SP, s2 * 8);
-                       M_ILD(d, REG_SP, s1 * 8);
+               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
+                       M_ILD(RCX, REG_SP, s2);
+                       M_ILD(d, REG_SP, s1);
                        emit_shiftl_reg(cd, shift_op, d);
 
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
                        /* s1 may be equal to RCX */
                        M_INTMOVE(s1, d);
-                       M_ILD(RCX, REG_SP, s2 * 8);
+                       M_ILD(RCX, REG_SP, s2);
                        emit_shiftl_reg(cd, shift_op, d);
 
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        M_INTMOVE(s2, RCX);
-                       M_ILD(d, REG_SP, s1 * 8);
+                       M_ILD(d, REG_SP, s1);
                        emit_shiftl_reg(cd, shift_op, d);
 
                } else {
@@ -895,65 +822,76 @@ void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
 }
 
 
-void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
+void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
 {
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-       s4 d_old;
+       s4 s1, s2, d, d_old;
+       varinfo *v_s1,*v_s2,*v_dst;
+       codegendata *cd;
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       v_s1  = VAROP(iptr->s1);
+       v_s2  = VAROP(iptr->sx.s23.s2);
+       v_dst = VAROP(iptr->dst);
+
+       s1 = v_s1->vv.regoff;
+       s2 = v_s2->vv.regoff;
+       d  = v_dst->vv.regoff;
        
        M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
 
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+       if (IS_INMEMORY(v_dst->flags)) {
+               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        if (s1 == d) {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               emit_shift_membase(cd, shift_op, REG_SP, d * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               emit_shift_membase(cd, shift_op, REG_SP, d);
 
                        } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_LLD(REG_ITMP2, REG_SP, s1 * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               M_LLD(REG_ITMP2, REG_SP, s1);
                                emit_shift_reg(cd, shift_op, REG_ITMP2);
-                               M_LST(REG_ITMP2, REG_SP, d * 8);
+                               M_LST(REG_ITMP2, REG_SP, d);
                        }
 
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
                        /* s1 may be equal to RCX */
                        if (s1 == RCX) {
                                if (s2 == d) {
-                                       M_ILD(REG_ITMP1, REG_SP, s2 * 8);
-                                       M_LST(s1, REG_SP, d * 8);
+                                       M_ILD(REG_ITMP1, REG_SP, s2);
+                                       M_LST(s1, REG_SP, d);
                                        M_INTMOVE(REG_ITMP1, RCX);
 
                                } else {
-                                       M_LST(s1, REG_SP, d * 8);
-                                       M_ILD(RCX, REG_SP, s2 * 8);
+                                       M_LST(s1, REG_SP, d);
+                                       M_ILD(RCX, REG_SP, s2);
                                }
 
                        } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_LST(s1, REG_SP, d * 8);
+                               M_ILD(RCX, REG_SP, s2);
+                               M_LST(s1, REG_SP, d);
                        }
 
-                       emit_shift_membase(cd, shift_op, REG_SP, d * 8);
+                       emit_shift_membase(cd, shift_op, REG_SP, d);
 
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        if (s1 == d) {
                                M_INTMOVE(s2, RCX);
-                               emit_shift_membase(cd, shift_op, REG_SP, d * 8);
+                               emit_shift_membase(cd, shift_op, REG_SP, d);
 
                        } else {
                                M_INTMOVE(s2, RCX);
-                               M_LLD(REG_ITMP2, REG_SP, s1 * 8);
+                               M_LLD(REG_ITMP2, REG_SP, s1);
                                emit_shift_reg(cd, shift_op, REG_ITMP2);
-                               M_LST(REG_ITMP2, REG_SP, d * 8);
+                               M_LST(REG_ITMP2, REG_SP, d);
                        }
 
                } else {
                        /* s1 may be equal to RCX */
-                       M_LST(s1, REG_SP, d * 8);
+                       M_LST(s1, REG_SP, d);
                        M_INTMOVE(s2, RCX);
-                       emit_shift_membase(cd, shift_op, REG_SP, d * 8);
+                       emit_shift_membase(cd, shift_op, REG_SP, d);
                }
 
                M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
@@ -964,20 +902,20 @@ void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr)
                        d = REG_ITMP3;
                }
 
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_ILD(RCX, REG_SP, s2 * 8);
-                       M_LLD(d, REG_SP, s1 * 8);
+               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
+                       M_ILD(RCX, REG_SP, s2);
+                       M_LLD(d, REG_SP, s1);
                        emit_shift_reg(cd, shift_op, d);
 
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) {
                        /* s1 may be equal to RCX */
                        M_INTMOVE(s1, d);
-                       M_ILD(RCX, REG_SP, s2 * 8);
+                       M_ILD(RCX, REG_SP, s2);
                        emit_shift_reg(cd, shift_op, d);
 
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
                        M_INTMOVE(s2, RCX);
-                       M_LLD(d, REG_SP, s1 * 8);
+                       M_LLD(d, REG_SP, s1);
                        emit_shift_reg(cd, shift_op, d);
 
                } else {
@@ -1287,6 +1225,15 @@ void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 ind
 }
 
 
+void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg)
+{
+       emit_rex(1, dreg, 0, 0);
+       *(cd->mcodeptr++) = 0x8b;
+       emit_address_byte(0, dreg, 4);
+       emit_mem(4, disp);
+}
+
+
 /*
  * alu operations
  */
@@ -1353,7 +1300,8 @@ void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
 }
 
 
-void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
+void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
+{
        emit_rex(1,0,0,(dreg));
        *(cd->mcodeptr++) = 0x81;
        emit_reg((opc),(dreg));
@@ -1361,6 +1309,15 @@ void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
 }
 
 
+void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg)
+{
+       emit_rex(0,0,0,(dreg));
+       *(cd->mcodeptr++) = 0x81;
+       emit_reg((opc),(dreg));
+       emit_imm32((imm));
+}
+
+
 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
        if (IS_IMM8(imm)) {
                emit_rex(0,0,0,(dreg));
@@ -1600,12 +1557,6 @@ void emit_idivl_reg(codegendata *cd, s8 reg) {
 
 
 
-void emit_ret(codegendata *cd) {
-    *(cd->mcodeptr++) = 0xc3;
-}
-
-
-
 /*
  * shift ops
  */
@@ -1723,7 +1674,8 @@ void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
  */
 
 /* we need the rex byte to get all low bytes */
-void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
+void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg)
+{
        *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
        *(cd->mcodeptr++) = 0x0f;
        *(cd->mcodeptr++) = (0x90 + (opc));
@@ -1732,7 +1684,8 @@ void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
 
 
 /* we need the rex byte to get all low bytes */
-void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
+void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp)
+{
        *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
        *(cd->mcodeptr++) = 0x0f;
        *(cd->mcodeptr++) = (0x90 + (opc));
@@ -1740,7 +1693,7 @@ void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
 }
 
 
-void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
+void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
 {
        emit_rex(1,(dreg),0,(reg));
        *(cd->mcodeptr++) = 0x0f;
@@ -1749,7 +1702,7 @@ void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
 }
 
 
-void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
+void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg)
 {
        emit_rex(0,(dreg),0,(reg));
        *(cd->mcodeptr++) = 0x0f;
@@ -1758,7 +1711,6 @@ void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
 }
 
 
-
 void emit_neg_reg(codegendata *cd, s8 reg)
 {
        emit_rex(1,0,0,(reg));
@@ -1800,23 +1752,20 @@ void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
 }
 
 
-void emit_nop(codegendata *cd) {
-    *(cd->mcodeptr++) = 0x90;
-}
-
-
 
 /*
  * call instructions
  */
-void emit_call_reg(codegendata *cd, s8 reg) {
-       emit_rex(1,0,0,(reg));
+void emit_call_reg(codegendata *cd, s8 reg)
+{
+       emit_rex(0,0,0,(reg));
        *(cd->mcodeptr++) = 0xff;
        emit_reg(2,(reg));
 }
 
 
-void emit_call_imm(codegendata *cd, s8 imm) {
+void emit_call_imm(codegendata *cd, s8 imm)
+{
        *(cd->mcodeptr++) = 0xe8;
        emit_imm32((imm));
 }