* src/vm/jit/jit.h (jitdata): Removed isleafmethod.
[cacao.git] / src / vm / jit / s390 / emit.c
index 40444916b1c1cf05e7dbdf7d7ea4e171c92d64c3..c7d5c0bf5281f85e2db75408c833fb47c941b8ef 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions
+/* src/vm/jit/s390/emit.c - s390 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
-
-   $Id: emit.c 7283 2007-02-04 19:41:14Z pm $
-
 */
 
-#include <assert.h>
-
 #include "config.h"
 
-#include "vm/types.h"
-
-#include "md-abi.h"
-
-#include "vm/jit/s390/codegen.h"
-#include "vm/jit/s390/emit.h"
+#include <assert.h>
+#include <stdint.h>
 
+#include "mm/memory.h"
 #if defined(ENABLE_THREADS)
 # include "threads/native/lock.h"
 #endif
-
 #include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.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-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/patcher-common.h"
 #include "vm/jit/replace.h"
-
-#define __PORTED__
+#include "vm/jit/trace.h"
+#include "vm/jit/s390/codegen.h"
+#include "vm/jit/s390/emit.h"
+#include "vm/jit/s390/md-abi.h"
+#include "vm/types.h"
+#include "vmcore/options.h"
 
 /* emit_load *******************************************************************
 
@@ -61,7 +57,7 @@
 
 *******************************************************************************/
 
-__PORTED__ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
        codegendata *cd;
        s4           disp;
@@ -74,7 +70,7 @@ __PORTED__ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg
        if (IS_INMEMORY(src->flags)) {
                COUNT_SPILLS;
 
-               disp = src->vv.regoff * 4;
+               disp = src->vv.regoff;
 
                if (IS_FLT_DBL_TYPE(src->type)) {
                        if (IS_2_WORD_TYPE(src->type))
@@ -107,7 +103,7 @@ __PORTED__ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg
     
 *******************************************************************************/
 
-__PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata *cd;
 
@@ -120,15 +116,15 @@ __PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst,
 
                if (IS_FLT_DBL_TYPE(dst->type)) {
                        if (IS_2_WORD_TYPE(dst->type))
-                               M_DST(d, REG_SP, dst->vv.regoff * 4);
+                               M_DST(d, REG_SP, dst->vv.regoff);
                        else
-                               M_FST(d, REG_SP, dst->vv.regoff * 4);
+                               M_FST(d, REG_SP, dst->vv.regoff);
                }
                else {
                        if (IS_2_WORD_TYPE(dst->type))
-                               M_LST(d, REG_SP, dst->vv.regoff * 4);
+                               M_LST(d, REG_SP, dst->vv.regoff);
                        else
-                               M_IST(d, REG_SP, dst->vv.regoff * 4);
+                               M_IST(d, REG_SP, dst->vv.regoff);
                }
        }
 }
@@ -140,373 +136,336 @@ __PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst,
 
 *******************************************************************************/
 
-__PORTED__ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
+void emit_copy(jitdata *jd, instruction *iptr)
 {
-       codegendata  *cd;
-       s4            s1, d;
+       codegendata *cd;
+       varinfo     *src;
+       varinfo     *dst;
+       s4           s1, d;
 
        /* get required compiler data */
 
        cd = jd->cd;
 
+       /* 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)) {
 
-               /* 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 ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) {
+                       /* emit nothing, as the value won't be used anyway */
+                       return;
                }
 
-               if (s1 != d) {
-                       if (IS_FLT_DBL_TYPE(src->type))
-                               M_FMOV(s1, d);
-                       else
-                               M_MOV(s1, d);
-               }
+               if (IS_INMEMORY(src->flags) && IS_INMEMORY(dst->flags)) {
+                       if (IS_2_WORD_TYPE(src->type)) {
+                               N_MVC(dst->vv.regoff, 8, REG_SP, src->vv.regoff, REG_SP);
+                       } else {
+                               N_MVC(dst->vv.regoff, 4, REG_SP, src->vv.regoff, REG_SP);
+                       }
+               } else {
 
-               emit_store(jd, iptr, dst, d);
-       }
-}
+                       /* 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)) {
+                               if (IS_FLT_DBL_TYPE(dst->type)) {
+                                       d = codegen_reg_of_var(iptr->opc, dst, REG_FTMP1);
+                               } else {
+                                       if (IS_2_WORD_TYPE(dst->type)) {
+                                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
+                                       } else {
+                                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP1);
+                                       }
+                               }
+                               s1 = emit_load(jd, iptr, src, d);
+                       }
+                       else {
+                               if (IS_FLT_DBL_TYPE(src->type)) {
+                                       s1 = emit_load(jd, iptr, src, REG_FTMP1);
+                               } else {
+                                       if (IS_2_WORD_TYPE(src->type)) {
+                                               s1 = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
+                                       } else {
+                                               s1 = emit_load(jd, iptr, src, REG_ITMP1);
+                                       }
+                               }
+                               d = codegen_reg_of_var(iptr->opc, dst, s1);
+                       }
 
+                       if (s1 != d) {
+                               if (IS_FLT_DBL_TYPE(src->type)) {
+                                       M_FMOV(s1, d);
+                               } else {
+                                       if (IS_2_WORD_TYPE(src->type)) {
+                                               M_LNGMOVE(s1, d);
+                                       } else {
+                                               M_MOV(s1, d);
+                                       }
+                               }
+                       }
 
-void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d)
-{
-#if 0
-       switch (iptr->flags.fields.condition) {
-       case ICMD_IFEQ:
-               M_CMOVEQ(s, d);
-               break;
-       case ICMD_IFNE:
-               M_CMOVNE(s, d);
-               break;
-       case ICMD_IFLT:
-               M_CMOVLT(s, d);
-               break;
-       case ICMD_IFGE:
-               M_CMOVGE(s, d);
-               break;
-       case ICMD_IFGT:
-               M_CMOVGT(s, d);
-               break;
-       case ICMD_IFLE:
-               M_CMOVLE(s, d);
-               break;
+                       emit_store(jd, iptr, dst, d);
+               }
        }
-#endif
 }
 
+/* emit_trap *******************************************************************
 
-/* emit_exception_stubs ********************************************************
-
-   Generates the code for the exception stubs.
+   Emit a trap instruction and return the original machine code.
 
 *******************************************************************************/
 
-void emit_exception_stubs(jitdata *jd)
+uint32_t emit_trap(codegendata *cd)
 {
-       codegendata  *cd;
-       registerdata *rd;
-       exceptionref *er;
-       s4            branchmpc;
-       s4            targetmpc;
-       s4            targetdisp;
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-       rd = jd->rd;
-
-       /* generate exception stubs */
-
-       targetdisp = 0;
-
-       for (er = cd->exceptionrefs; er != NULL; er = er->next) {
-               /* back-patch the branch to this exception code */
-
-               branchmpc = er->branchpos;
-               targetmpc = cd->mcodeptr - cd->mcodebase;
-
-               md_codegen_patch_branch(cd, branchmpc, targetmpc);
-
-               MCODECHECK(512);
-
-               /* Check if the exception is an
-                  ArrayIndexOutOfBoundsException.  If so, move index register
-                  into a4. */
+       uint32_t mcode;
 
-               if (er->reg != -1)
-                       M_MOV(er->reg, rd->argintregs[4]);
+       /* Get machine code which is patched back in later. The
+          trap is 2 bytes long. */
 
-               /* calcuate exception address */
+       mcode = *((u2 *) cd->mcodeptr);
 
-               M_MOV_IMM(0, rd->argintregs[3]);
-               dseg_adddata(cd);
-               M_AADD_IMM32(er->branchpos - 6, rd->argintregs[3]);
+       M_ILL(EXCEPTION_HARDWARE_PATCHER);
 
-               /* move function to call into REG_ITMP3 */
-
-               M_MOV_IMM(er->function, REG_ITMP3);
-
-               if (targetdisp == 0) {
-                       targetdisp = cd->mcodeptr - cd->mcodebase;
-
-                       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 */
-
-                       M_CALL(REG_ITMP3);
-
-                       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));
-               }
-       }
+       return mcode;
 }
 
 
-/* emit_patcher_stubs **********************************************************
+/* emit_verbosecall_enter ******************************************************
 
-   Generates the code for the patcher stubs.
+   Generates the code for the call trace.
 
 *******************************************************************************/
 
-void emit_patcher_stubs(jitdata *jd)
+#if !defined(NDEBUG)
+void emit_verbosecall_enter(jitdata *jd)
 {
-       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 */
-
-       targetdisp = 0;
-
-       for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
-               /* check size of code segment */
+       methodinfo   *m;
+       codeinfo     *code;
+       codegendata  *cd;
+       methoddesc   *md;
+       s4            stackframesize;
+       s4            i, off, disp, s;
 
-               MCODECHECK(512);
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
 
-               /* Get machine code which is patched back in later. A
-                  `call rel32' is 5 bytes long (but read 8 bytes). */
+       md   = m->parseddesc;
 
-               savedmcodeptr = cd->mcodebase + pref->branchpos;
-               mcode = *((u8 *) savedmcodeptr);
+       /* mark trace code */
 
-               /* patch in `call rel32' to call the following code */
+       M_NOP;
 
-               tmpmcodeptr  = cd->mcodeptr;    /* save current mcodeptr              */
-               cd->mcodeptr = savedmcodeptr;   /* set mcodeptr to patch position     */
+       /* allocate stack frame */
 
-               M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
+       stackframesize = 96 + (md->paramcount * 8);
 
-               cd->mcodeptr = tmpmcodeptr;     /* restore the current mcodeptr       */
+       /* for leaf methods we need to store unused argument and temporary registers */
 
-               /* move pointer to java_objectheader onto stack */
+       if (code_is_leafmethod(code)) {
+               stackframesize += (ARG_CNT + TMP_CNT) * 8;
+       }
 
-#if defined(ENABLE_THREADS)
-               /* create a virtual java_objectheader */
+       /* allocate stack frame */
 
-               (void) dseg_add_unique_address(cd, NULL);                  /* flcword */
-               (void) dseg_add_unique_address(cd, lock_get_initial_lock_word());
-               disp = dseg_add_unique_address(cd, NULL);                  /* vftbl   */
+       M_ASUB_IMM(stackframesize, REG_SP);
 
-               emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
-#else
-               M_PUSH_IMM(0);
-#endif
+       /* store argument registers in array */
 
-               /* move machine code bytes and classinfo pointer into registers */
+       off = 96;
 
-               M_MOV_IMM(mcode, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+       for (i = 0; i < md->paramcount; i++) {
+               if (! md->params[i].inmemory) {
+                       s = md->params[i].regoff;
+                       switch (md->paramtypes[i].type) {
+                               case TYPE_INT:
+                               case TYPE_ADR:
+                                       M_IST(s, REG_SP, off);
+                                       break;
+                               case TYPE_LNG:
+                                       M_LST(s, REG_SP, off);
+                                       break;
+                               case TYPE_FLT:
+                                       M_FST(s, REG_SP, off);
+                                       break;
+                               case TYPE_DBL:
+                                       M_DST(s, REG_SP, off);
+                                       break;
+                       }
+               }
+               off += 8;
+       }
 
-               M_MOV_IMM(pref->ref, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+       /* save unused (currently all) argument registers for leaf methods */
+       /* save temporary registers for leaf methods */
 
-               M_MOV_IMM(pref->disp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+       if (code_is_leafmethod(code)) {
 
-               M_MOV_IMM(pref->patcher, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+               for (i = 0; i < INT_ARG_CNT; ++i, off += 8) {
+                       M_IST(abi_registers_integer_argument[i], REG_SP, off);
+               }
 
-               if (targetdisp == 0) {
-                       targetdisp = cd->mcodeptr - cd->mcodebase;
+               for (i = 0; i < FLT_ARG_CNT; ++i, off += 8) {
+                       M_DST(abi_registers_float_argument[i], REG_SP, off);
+               }
 
-                       M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
-                       M_JMP(REG_ITMP3);
+               for (i = 0; i < INT_TMP_CNT; ++i, off += 8) {
+                       M_IST(abi_registers_integer_temporary[i], REG_SP, off);
                }
-               else {
-                       M_JMP_IMM((cd->mcodebase + targetdisp) -
-                                         (cd->mcodeptr + PATCHER_CALL_SIZE));
+
+               for (i = 0; i < FLT_TMP_CNT; ++i, off += 8) {
+                       M_DST(abi_registers_float_temporary[i], REG_SP, off);
                }
        }
-}
-
 
-/* emit_replacement_stubs ******************************************************
+       /* load arguments for trace_java_call_enter */
 
-   Generates the code for the replacement stubs.
+       /* methodinfo */
 
-*******************************************************************************/
-
-void emit_replacement_stubs(jitdata *jd)
-{
-#if 0
-       codegendata *cd;
-       codeinfo    *code;
-       rplpoint    *rplp;
-       s4           disp;
-       s4           i;
+       disp = dseg_add_address(cd, m);
+       M_ALD_DSEG(REG_A0, disp);       
+       /* pointer to argument registers array */
+       M_LDA(REG_A1, REG_SP, 96);
+       /* pointer to on stack arguments */
+       M_LDA(REG_A2, REG_SP, stackframesize + (cd->stackframesize * 8));
 
-       /* get required compiler data */
+       /* call trace_java_call_enter */
 
-       cd   = jd->cd;
-       code = jd->code;
+       disp = dseg_add_functionptr(cd, trace_java_call_enter);
+       M_ALD_DSEG(REG_ITMP2, disp);
+       M_CALL(REG_ITMP2);
 
-       rplp = code->rplpoints;
+       /* restore used argument registers */
+       /* for leaf methods restore all argument and temporary registers */
 
-       for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
-               /* check code segment size */
+       if (code_is_leafmethod(code)) {
+               off = 96 + (8 * md->paramcount);
 
-               MCODECHECK(512);
+               for (i = 0; i < INT_ARG_CNT; ++i, off += 8) {
+                       M_ILD(abi_registers_integer_argument[i], REG_SP, off);
+               }
 
-               /* note start of stub code */
+               for (i = 0; i < FLT_ARG_CNT; ++i, off += 8) {
+                       M_DLD(abi_registers_float_argument[i], REG_SP, off);
+               }
 
-               rplp->outcode = (u1 *) (ptrint) (cd->mcodeptr - cd->mcodebase);
+               for (i = 0; i < INT_TMP_CNT; ++i, off += 8) {
+                       M_ILD(abi_registers_integer_temporary[i], REG_SP, off);
+               }
 
-               /* make machine code for patching */
+               for (i = 0; i < FLT_TMP_CNT; ++i, off += 8) {
+                       M_DLD(abi_registers_float_temporary[i], REG_SP, off);
+               }
+       } else {
+               off = 96;
+
+               for (i = 0; i < md->paramcount; i++) {
+                       if (! md->params[i].inmemory) {
+                               s = md->params[i].regoff;
+                               switch (md->paramtypes[i].type) {
+                                       case TYPE_INT:
+                                       case TYPE_ADR:
+                                               M_ILD(s, REG_SP, off);
+                                               break;
+                                       case TYPE_LNG:
+                                               M_LLD(s, REG_SP, off);
+                                               break;
+                                       case TYPE_FLT:
+                                               M_FLD(s, REG_SP, off);
+                                               break;
+                                       case TYPE_DBL:
+                                               M_DLD(s, REG_SP, off);
+                                               break;
+                               }
+                       }
+                       off += 8;
+               }
+       }
 
-               disp = (ptrint) (rplp->outcode - rplp->pc) - 5;
+       /* remove stack frame */
 
-               rplp->mcode = 0xe9 | ((u8) disp << 8);
+       M_AADD_IMM(stackframesize, REG_SP);
 
-               /* push address of `rplpoint` struct */
-                       
-               M_MOV_IMM(rplp, REG_ITMP3);
-               M_PUSH(REG_ITMP3);
+       /* mark trace code */
 
-               /* jump to replacement function */
+       M_NOP;
 
-               M_MOV_IMM(asm_replacement_out, REG_ITMP3);
-               M_JMP(REG_ITMP3);
-       }
-#endif
 }
-       
+#endif /* !defined(NDEBUG) */
 
-/* emit_verbosecall_enter ******************************************************
+
+/* emit_verbosecall_exit *******************************************************
 
    Generates the code for the call trace.
 
 *******************************************************************************/
 
 #if !defined(NDEBUG)
-void emit_verbosecall_enter(jitdata *jd)
+void emit_verbosecall_exit(jitdata *jd)
 {
        methodinfo   *m;
        codegendata  *cd;
-       registerdata *rd;
-       methoddesc   *md;
-       s4            i, j, k;
-
-       /* get required compiler data */
+       s4            disp;
+       s4            stackframesize;
+       s4            off;
+       s4            t;
 
        m  = jd->m;
        cd = jd->cd;
-       rd = jd->rd;
-
-       md = m->parseddesc;
+       t = m->parseddesc->returntype.type;
 
        /* mark trace code */
 
        M_NOP;
 
-       /* additional +1 is for 16-byte stack alignment */
-
-       M_LSUB_IMM((ARG_CNT + TMP_CNT + 1 + 1) * 8, REG_SP);
-
-       /* save argument registers */
-
-       for (i = 0; i < INT_ARG_CNT; i++)
-               M_LST(rd->argintregs[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);
+       /* allocate stackframe */
 
-       /* save temporary registers for leaf methods */
-
-       if (jd->isleafmethod) {
-               for (i = 0; i < INT_TMP_CNT; i++)
-                       M_LST(rd->tmpintregs[i], REG_SP, (1 + ARG_CNT + i) * 8);
-
-               for (i = 0; i < FLT_TMP_CNT; i++)
-                       M_DST(rd->tmpfltregs[i], REG_SP, (1 + ARG_CNT + INT_TMP_CNT + i) * 8);
-       }
+       stackframesize = 96 + (1 * 8);
+       M_ASUB_IMM(stackframesize, REG_SP);
 
-       /* show integer hex code for float arguments */
+       off = 96;
 
-       for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
-               /* If the paramtype is a float, we have to right shift all
-                  following integer registers. */
-       
-               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]);
+       /* store return values in array */
 
-                       emit_movd_freg_reg(cd, rd->argfltregs[j], rd->argintregs[i]);
-                       j++;
+       if (IS_INT_LNG_TYPE(t)) {
+               if (IS_2_WORD_TYPE(t)) {
+                       M_LST(REG_RESULT_PACKED, REG_SP, off);
+               } else {
+                       M_IST(REG_RESULT, REG_SP, off);
                }
+       } else {
+               M_DST(REG_FRESULT, REG_SP, off);
        }
 
-       M_MOV_IMM(m, REG_ITMP2);
-       M_AST(REG_ITMP2, REG_SP, 0 * 8);
-       M_MOV_IMM(builtin_trace_args, 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);
+       /* call trace_java_call_exit */
 
-       for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
+       disp = dseg_add_address(cd, m);
+       M_ALD_DSEG(REG_A0, disp);
+       M_LDA(REG_A1, REG_SP, off);
+       disp = dseg_add_functionptr(cd, trace_java_call_exit);
+       M_ALD_DSEG(REG_ITMP2, disp);
+       M_CALL(REG_ITMP2);
 
-       /* restore temporary registers for leaf methods */
+       /* restore return value */
 
-       if (jd->isleafmethod) {
-               for (i = 0; i < INT_TMP_CNT; i++)
-                       M_LLD(rd->tmpintregs[i], REG_SP, (1 + ARG_CNT + i) * 8);
-
-               for (i = 0; i < FLT_TMP_CNT; i++)
-                       M_DLD(rd->tmpfltregs[i], REG_SP, (1 + ARG_CNT + INT_TMP_CNT + i) * 8);
+       if (IS_INT_LNG_TYPE(t)) {
+               if (IS_2_WORD_TYPE(t)) {
+                       M_LLD(REG_RESULT_PACKED, REG_SP, off);
+               } else {
+                       M_ILD(REG_RESULT, REG_SP, off);
+               }
+       } else {
+               M_DLD(REG_FRESULT, REG_SP, off);
        }
 
-       M_LADD_IMM((ARG_CNT + TMP_CNT + 1 + 1) * 8, REG_SP);
+       /* remove stackframe */
+
+       M_AADD_IMM(stackframesize, REG_SP);
 
        /* mark trace code */
 
@@ -515,1791 +474,332 @@ void emit_verbosecall_enter(jitdata *jd)
 #endif /* !defined(NDEBUG) */
 
 
-/* emit_verbosecall_exit *******************************************************
+/* emit_load_high **************************************************************
 
-   Generates the code for the call trace.
+   Emits a possible load of the high 32-bits of an operand.
 
 *******************************************************************************/
 
-#if !defined(NDEBUG)
-void emit_verbosecall_exit(jitdata *jd)
+s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
-       methodinfo   *m;
        codegendata  *cd;
-       registerdata *rd;
+       s4            disp;
+       s4            reg;
+
+       assert(src->type == TYPE_LNG);
 
        /* get required compiler data */
 
-       m  = jd->m;
        cd = jd->cd;
-       rd = jd->rd;
-
-       /* mark trace code */
 
-       M_NOP;
+       if (IS_INMEMORY(src->flags)) {
+               COUNT_SPILLS;
 
-       M_ASUB_IMM(2 * 8, REG_SP);
+               disp = src->vv.regoff;
 
-       M_LST(REG_RESULT, REG_SP, 0 * 8);
-       M_DST(REG_FRESULT, REG_SP, 1 * 8);
+               M_ILD(tempreg, REG_SP, disp);
 
-       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]);
+               reg = tempreg;
+       }
+       else
+               reg = GET_HIGH_REG(src->vv.regoff);
 
-       M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
-       M_CALL(REG_ITMP1);
+       return reg;
+}
 
-       M_LLD(REG_RESULT, REG_SP, 0 * 8);
-       M_DLD(REG_FRESULT, REG_SP, 1 * 8);
+/* emit_load_low ***************************************************************
 
-       M_AADD_IMM(2 * 8, REG_SP);
+   Emits a possible load of the low 32-bits of an operand.
 
-       /* mark trace code */
+*******************************************************************************/
 
-       M_NOP;
-}
-#endif /* !defined(NDEBUG) */
+s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+       codegendata  *cd;
+       s4            disp;
+       s4            reg;
 
+       assert(src->type == TYPE_LNG);
 
-/* code generation functions **************************************************/
+       /* get required compiler data */
 
-static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
-{
-       if ((basereg == REG_SP) || (basereg == R12)) {
-               if (disp == 0) {
-                       emit_address_byte(0, dreg, REG_SP);
-                       emit_address_byte(0, REG_SP, REG_SP);
+       cd = jd->cd;
 
-               } else if (IS_IMM8(disp)) {
-                       emit_address_byte(1, dreg, REG_SP);
-                       emit_address_byte(0, REG_SP, REG_SP);
-                       emit_imm8(disp);
+       if (IS_INMEMORY(src->flags)) {
+               COUNT_SPILLS;
 
-               } else {
-                       emit_address_byte(2, dreg, REG_SP);
-                       emit_address_byte(0, REG_SP, REG_SP);
-                       emit_imm32(disp);
-               }
+               disp = src->vv.regoff;
 
-       } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) {
-               emit_address_byte(0,(dreg),(basereg));
+               M_ILD(tempreg, REG_SP, disp + 4);
 
-       } else if ((basereg) == RIP) {
-               emit_address_byte(0, dreg, RBP);
-               emit_imm32(disp);
+               reg = tempreg;
+       }
+       else
+               reg = GET_LOW_REG(src->vv.regoff);
 
-       } else {
-               if (IS_IMM8(disp)) {
-                       emit_address_byte(1, dreg, basereg);
-                       emit_imm8(disp);
+       return reg;
+}
 
+s4 emit_load_s1_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg) {
+       codegendata *cd = jd->cd;
+       s4 reg = emit_load_s1(jd, iptr, tempreg);
+       if (reg == notreg) {
+               if (IS_FLT_DBL_TYPE(VAROP(iptr->s1)->type)) {
+                       M_FMOV(reg, tempreg);
                } else {
-                       emit_address_byte(2, dreg, basereg);
-                       emit_imm32(disp);
+                       M_MOV(reg, tempreg);
                }
+               return tempreg;
+       } else {
+               return reg;
        }
 }
 
-
-static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg)
-{
-       if ((basereg == REG_SP) || (basereg == R12)) {
-               emit_address_byte(2, dreg, REG_SP);
-               emit_address_byte(0, REG_SP, REG_SP);
-               emit_imm32(disp);
-       }
-       else {
-               emit_address_byte(2, dreg, basereg);
-               emit_imm32(disp);
+s4 emit_load_s2_but(jitdata *jd, instruction *iptr, s4 tempreg, s4 notreg) {
+       codegendata *cd = jd->cd;
+       s4 reg = emit_load_s2(jd, iptr, tempreg);
+       if (reg == notreg) {
+               if (IS_FLT_DBL_TYPE(VAROP(iptr->sx.s23.s2)->type)) {
+                       M_FMOV(reg, tempreg);
+               } else {
+                       M_MOV(reg, tempreg);
+               }
+               return tempreg;
+       } else {
+               return reg;
        }
 }
 
-
-static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale)
-{
-       if (basereg == -1) {
-               emit_address_byte(0, reg, 4);
-               emit_address_byte(scale, indexreg, 5);
-               emit_imm32(disp);
-       }
-       else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) {
-               emit_address_byte(0, reg, 4);
-               emit_address_byte(scale, indexreg, basereg);
-       }
-       else if (IS_IMM8(disp)) {
-               emit_address_byte(1, reg, 4);
-               emit_address_byte(scale, indexreg, basereg);
-               emit_imm8(disp);
-       }
-       else {
-               emit_address_byte(2, reg, 4);
-               emit_address_byte(scale, indexreg, basereg);
-               emit_imm32(disp);
+void emit_copy_dst(jitdata *jd, instruction *iptr, s4 dtmpreg) {
+       codegendata *cd;
+       varinfo *dst;
+       cd = jd->cd;
+       dst = VAROP(iptr->dst);
+       if (! IS_INMEMORY(dst->flags)) {
+               if (dst->vv.regoff != dtmpreg) {
+                       if (IS_FLT_DBL_TYPE(dst->type)) {
+                               M_FLTMOVE(dtmpreg, dst->vv.regoff);
+                       } else if (IS_2_WORD_TYPE(dst->type)) {
+                               M_LNGMOVE(dtmpreg, dst->vv.regoff);
+                       } else {
+                               M_INTMOVE(dtmpreg, dst->vv.regoff);
+                       }
+               }
        }
 }
 
+void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt) {
+
+       s4 branchdisp = disp;
+       s4 branchmpc;
+       u1 *ref;
+
+       if (N_VALID_BRANCH(branchdisp)) {
+
+               /* valid displacement */
+
+               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_UNCONDITIONAL:
+                               M_BR(branchdisp);
+                               break;
+                       default:
+                               vm_abort("emit_branch: unknown condition %d", condition);
+               }
+       } else {
 
-void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr)
-{
-       s4 s1, s2, d, d_old;
-       varinfo *v_s1,*v_s2,*v_dst;
-       codegendata *cd;
+               /* If LONGBRANCHES is not set, the flag and the error flag */
 
-       /* get required compiler data */
+               if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
+                       cd->flags |= (CODEGENDATA_FLAG_ERROR |
+                               CODEGENDATA_FLAG_LONGBRANCHES);
+               }
 
-       cd = jd->cd;
+               /* If error flag is set, do nothing. The method has to be recompiled. */
 
-       v_s1  = VAROP(iptr->s1);
-       v_s2  = VAROP(iptr->sx.s23.s2);
-       v_dst = VAROP(iptr->dst);
+               if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) && CODEGENDATA_HAS_FLAG_ERROR(cd)) {
+                       return;
+               }
 
-       s1 = v_s1->vv.regoff;
-       s2 = v_s2->vv.regoff;
-       d  = v_dst->vv.regoff;
+               /* Patch the displacement to branch over the actual branch manually
+                * to not get yet more nops.
+                */
+
+               branchmpc = cd->mcodeptr - cd->mcodebase;
+               ref = cd->mcodeptr;
+
+               switch (condition) {
+                       case BRANCH_EQ:
+                               M_BNE(0);
+                               break;
+                       case BRANCH_NE:
+                               M_BEQ(0);
+                               break;
+                       case BRANCH_LT:
+                               M_BGE(0);
+                               break;
+                       case BRANCH_GE:
+                               M_BLT(0);
+                               break;
+                       case BRANCH_GT:
+                               M_BLE(0);
+                               break;
+                       case BRANCH_LE:
+                               M_BGT(0);
+                               break;
+                       case BRANCH_UNCONDITIONAL:
+                               /* fall through, no displacement to patch */
+                               ref = NULL;
+                               break;
+                       default:
+                               vm_abort("emit_branch: unknown condition %d", condition);
+               }
 
-       M_INTMOVE(RCX, REG_ITMP1);                                    /* save RCX */
+               /* The actual long branch */
 
-       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);
+               disp = dseg_add_s4(cd, branchmpc + disp - N_PV_OFFSET);
+               M_ILD_DSEG(REG_ITMP2, disp);
+               M_AADD(REG_PV, REG_ITMP2);
+               M_JMP(RN, REG_ITMP2);
 
-                       } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_ILD(REG_ITMP2, REG_SP, s1 * 8);
-                               emit_shiftl_reg(cd, shift_op, REG_ITMP2);
-                               M_IST(REG_ITMP2, REG_SP, d * 8);
-                       }
+               /* Patch back the displacement */
 
-               } 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_INTMOVE(REG_ITMP1, RCX);
+               N_BRC_BACK_PATCH(ref);
+       }
+}
 
-                               } else {
-                                       M_IST(s1, REG_SP, d * 8);
-                                       M_ILD(RCX, REG_SP, s2 * 8);
-                               }
+void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) {
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(reg);
+               M_BNE(SZ_BRC + SZ_ILL);
+               M_ILL(EXCEPTION_HARDWARE_ARITHMETIC);
+       }
+}
 
-                       } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_IST(s1, REG_SP, d * 8);
-                       }
+/* emit_arrayindexoutofbounds_check ********************************************
 
-                       emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
+   Emit a ArrayIndexOutOfBoundsException check.
 
-               } 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);
+*******************************************************************************/
 
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_ILD(REG_ITMP2, REG_SP, s1 * 8);
-                               emit_shiftl_reg(cd, shift_op, REG_ITMP2);
-                               M_IST(REG_ITMP2, REG_SP, d * 8);
-                       }
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               /* Size is s4, >= 0
+                * Do unsigned comparison to catch negative indexes.
+                */
+               N_CL(s2, OFFSET(java_array_t, size), RN, s1);
+        M_BLT(SZ_BRC + SZ_ILL);
+               M_ILL2(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
+       }
+}
 
-               } else {
-                       /* s1 may be equal to RCX */
-                       M_IST(s1, REG_SP, d * 8);
-                       M_INTMOVE(s2, RCX);
-                       emit_shiftl_membase(cd, shift_op, REG_SP, d * 8);
-               }
 
-               M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
+/* emit_arraystore_check *******************************************************
 
-       } else {
-               d_old = d;
-               if (d == RCX) {
-                       d = REG_ITMP3;
-               }
-                                       
-               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
-                       M_ILD(RCX, REG_SP, s2 * 8);
-                       M_ILD(d, REG_SP, s1 * 8);
-                       emit_shiftl_reg(cd, shift_op, d);
-
-               } 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);
-                       emit_shiftl_reg(cd, shift_op, d);
-
-               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
-                       M_INTMOVE(s2, RCX);
-                       M_ILD(d, REG_SP, s1 * 8);
-                       emit_shiftl_reg(cd, shift_op, d);
+   Emit an ArrayStoreException check.
 
-               } else {
-                       /* s1 may be equal to RCX */
-                       if (s1 == RCX) {
-                               if (s2 == d) {
-                                       /* d cannot be used to backup s1 since this would
-                                          overwrite s2. */
-                                       M_INTMOVE(s1, REG_ITMP3);
-                                       M_INTMOVE(s2, RCX);
-                                       M_INTMOVE(REG_ITMP3, d);
+*******************************************************************************/
 
-                               } else {
-                                       M_INTMOVE(s1, d);
-                                       M_INTMOVE(s2, RCX);
-                               }
-
-                       } else {
-                               /* d may be equal to s2 */
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       emit_shiftl_reg(cd, shift_op, d);
-               }
-
-               if (d_old == RCX)
-                       M_INTMOVE(REG_ITMP3, RCX);
-               else
-                       M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
+void emit_arraystore_check(codegendata *cd, instruction *iptr)
+{
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(REG_RESULT);
+               M_BNE(SZ_BRC + SZ_ILL);
+               M_ILL(EXCEPTION_HARDWARE_ARRAYSTORE);
        }
 }
 
 
-void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr)
-{
-       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 (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);
-
-                       } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_LLD(REG_ITMP2, REG_SP, s1 * 8);
-                               emit_shift_reg(cd, shift_op, REG_ITMP2);
-                               M_LST(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } 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_INTMOVE(REG_ITMP1, RCX);
-
-                               } else {
-                                       M_LST(s1, REG_SP, d * 8);
-                                       M_ILD(RCX, REG_SP, s2 * 8);
-                               }
-
-                       } else {
-                               M_ILD(RCX, REG_SP, s2 * 8);
-                               M_LST(s1, REG_SP, d * 8);
-                       }
-
-                       emit_shift_membase(cd, shift_op, REG_SP, d * 8);
-
-               } 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);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_LLD(REG_ITMP2, REG_SP, s1 * 8);
-                               emit_shift_reg(cd, shift_op, REG_ITMP2);
-                               M_LST(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else {
-                       /* s1 may be equal to RCX */
-                       M_LST(s1, REG_SP, d * 8);
-                       M_INTMOVE(s2, RCX);
-                       emit_shift_membase(cd, shift_op, REG_SP, d * 8);
-               }
-
-               M_INTMOVE(REG_ITMP1, RCX);                             /* restore RCX */
-
-       } else {
-               d_old = d;
-               if (d == RCX) {
-                       d = REG_ITMP3;
+void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1) {
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               if (reg != RN) {
+                       M_TEST(reg);
                }
-
-               if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
-                       M_ILD(RCX, REG_SP, s2 * 8);
-                       M_LLD(d, REG_SP, s1 * 8);
-                       emit_shift_reg(cd, shift_op, d);
-
-               } 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);
-                       emit_shift_reg(cd, shift_op, d);
-
-               } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) {
-                       M_INTMOVE(s2, RCX);
-                       M_LLD(d, REG_SP, s1 * 8);
-                       emit_shift_reg(cd, shift_op, d);
-
-               } else {
-                       /* s1 may be equal to RCX */
-                       if (s1 == RCX) {
-                               if (s2 == d) {
-                                       /* d cannot be used to backup s1 since this would
-                                          overwrite s2. */
-                                       M_INTMOVE(s1, REG_ITMP3);
-                                       M_INTMOVE(s2, RCX);
-                                       M_INTMOVE(REG_ITMP3, d);
-
-                               } else {
-                                       M_INTMOVE(s1, d);
-                                       M_INTMOVE(s2, RCX);
-                               }
-
-                       } else {
-                               /* d may be equal to s2 */
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       emit_shift_reg(cd, shift_op, d);
+               switch (condition) {
+                       case BRANCH_LE:
+                               M_BGT(SZ_BRC + SZ_ILL);
+                               break;
+                       case BRANCH_EQ:
+                               M_BNE(SZ_BRC + SZ_ILL);
+                               break;
+                       case BRANCH_GT:
+                               M_BLE(SZ_BRC + SZ_ILL);
+                               break;
+                       default:
+                               vm_abort("emit_classcast_check: unknown condition %d", condition);
                }
-
-               if (d_old == RCX)
-                       M_INTMOVE(REG_ITMP3, RCX);
-               else
-                       M_INTMOVE(REG_ITMP1, RCX);                         /* restore RCX */
-       }
-}
-
-
-/* low-level code emitter functions *******************************************/
-
-void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(1,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg)
-{
-       emit_rex(1,0,0,(reg));
-       *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       emit_imm64((imm));
-}
-
-
-void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(0,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       emit_imm32((imm));
-}
-
-
-void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-/*
- * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
- * constant membase immediate length of 32bit
- */
-void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
-{
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-/* ATTENTION: Always emit a REX byte, because the instruction size can
-   be smaller when all register indexes are smaller than 7. */
-void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg)
-{
-       emit_byte_rex((reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       emit_byte_rex((reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       emit_rex(1,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x8b;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       emit_rex(1,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x89;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       emit_byte_rex((reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x88;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
-       emit_rex(1,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_membase(cd, (basereg),(disp),0);
-       emit_imm32((imm));
-}
-
-
-void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
-       emit_rex(1,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_membase32(cd, (basereg),(disp),0);
-       emit_imm32((imm));
-}
-
-
-void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
-       emit_rex(0,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_membase(cd, (basereg),(disp),0);
-       emit_imm32((imm));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) {
-       emit_byte_rex(0,0,(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_membase32(cd, (basereg),(disp),0);
-       emit_imm32((imm));
-}
-
-
-void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xbe;
-       /* XXX: why do reg and dreg have to be exchanged */
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xbf;
-       /* XXX: why do reg and dreg have to be exchanged */
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x63;
-       /* XXX: why do reg and dreg have to be exchanged */
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg)
-{
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xb7;
-       /* XXX: why do reg and dreg have to be exchanged */
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       emit_rex(1,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xbf;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       emit_rex(1,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xbe;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       emit_rex(1,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xb7;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
-{
-       emit_rex(1,0,(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
-       emit_imm32((imm));
-}
-
-
-void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
-{
-       emit_rex(0,0,(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
-       emit_imm32((imm));
-}
-
-
-void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
-{
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,0,(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0xc7;
-       emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
-       emit_imm16((imm));
-}
-
-
-void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale)
-{
-       emit_rex(0,0,(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0xc6;
-       emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale));
-       emit_imm8((imm));
-}
-
-
-/*
- * alu operations
- */
-void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
-{
-       emit_rex(1,(reg),0,(dreg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 1;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
-{
-       emit_rex(0,(reg),0,(dreg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 1;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
-{
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 1;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp)
-{
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 1;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
-{
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 3;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg)
-{
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = (((opc)) << 3) + 3;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
-       if (IS_IMM8(imm)) {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0x83;
-               emit_reg((opc),(dreg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0x81;
-               emit_reg((opc),(dreg));
-               emit_imm32((imm));
-       }
-}
-
-
-void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
-       emit_rex(1,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));
-               *(cd->mcodeptr++) = 0x83;
-               emit_reg((opc),(dreg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(0,0,0,(dreg));
-               *(cd->mcodeptr++) = 0x81;
-               emit_reg((opc),(dreg));
-               emit_imm32((imm));
+               M_ILL2(s1, EXCEPTION_HARDWARE_CLASSCAST);
        }
 }
 
-
-void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (IS_IMM8(imm)) {
-               emit_rex(1,(basereg),0,0);
-               *(cd->mcodeptr++) = 0x83;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm8((imm));
-       } else {
-               emit_rex(1,(basereg),0,0);
-               *(cd->mcodeptr++) = 0x81;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm32((imm));
+void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) {
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(reg);
+               M_BNE(SZ_BRC + SZ_ILL);
+               M_ILL(EXCEPTION_HARDWARE_NULLPOINTER);
        }
 }
 
-
-void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (IS_IMM8(imm)) {
-               emit_rex(0,(basereg),0,0);
-               *(cd->mcodeptr++) = 0x83;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm8((imm));
-       } else {
-               emit_rex(0,(basereg),0,0);
-               *(cd->mcodeptr++) = 0x81;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm32((imm));
+void emit_exception_check(codegendata *cd, instruction *iptr) {
+       if (INSTRUCTION_MUST_CHECK(iptr)) {
+               M_TEST(REG_RESULT);
+               M_BNE(SZ_BRC + SZ_ILL);
+               M_ILL(EXCEPTION_HARDWARE_EXCEPTION);
        }
 }
 
+void emit_restore_pv(codegendata *cd) {
+       s4 offset, offset_imm;
 
-void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(1,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x85;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(0,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x85;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg) {
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(0,(reg));
-       emit_imm32((imm));
-}
-
-
-void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg) {
-       *(cd->mcodeptr++) = 0x66;
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(0,(reg));
-       emit_imm16((imm));
-}
-
-
-void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) {
-       *(cd->mcodeptr++) = 0xf6;
-       emit_reg(0,(reg));
-       emit_imm8((imm));
-}
-
-
-void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
-       emit_rex(1,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8d;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) {
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x8d;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-
-void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp)
-{
-       emit_rex(0,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xff;
-       emit_membase(cd, (basereg),(disp),0);
-}
-
-
-
-void emit_cltd(codegendata *cd) {
-    *(cd->mcodeptr++) = 0x99;
-}
-
-
-void emit_cqto(codegendata *cd) {
-       emit_rex(1,0,0,0);
-       *(cd->mcodeptr++) = 0x99;
-}
-
-
-
-void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xaf;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xaf;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       emit_rex(1,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xaf;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
+       /*
+       N_BASR(REG_PV, RN);
+       disp = (s4) (cd->mcodeptr - cd->mcodebase);
+       M_ASUB_IMM32(disp, REG_ITMP1, REG_PV);
+       */
 
+       /* If the offset from the method start does not fit into an immediate
+        * value, we can't put it into the data segment!
+        */
 
-void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xaf;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
+       /* Displacement from start of method to here */
 
+       offset = (s4) (cd->mcodeptr - cd->mcodebase);
+       offset_imm = -offset - SZ_BASR + N_PV_OFFSET;
 
-void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg) {
-       if (IS_IMM8((imm))) {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0x6b;
-               emit_reg(0,(dreg));
-               emit_imm8((imm));
+       if (N_VALID_IMM(offset_imm)) {
+               /* Get program counter */
+               N_BASR(REG_PV, RN);
+               /* Substract displacement */
+               M_AADD_IMM(offset_imm, REG_PV);
        } else {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0x69;
-               emit_reg(0,(dreg));
-               emit_imm32((imm));
+               /* Save program counter and jump over displacement in instruction flow */
+               N_BRAS(REG_PV, SZ_BRAS + SZ_LONG);
+               /* Place displacement here */
+               /* REG_PV points now exactly to this position */
+               N_LONG(-offset - SZ_BRAS + N_PV_OFFSET);
+               /* Substract *(REG_PV) from REG_PV */
+               N_A(REG_PV, 0, RN, REG_PV);
        }
 }
 
-
-void emit_imul_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
-       if (IS_IMM8((imm))) {
-               emit_rex(1,(dreg),0,(reg));
-               *(cd->mcodeptr++) = 0x6b;
-               emit_reg((dreg),(reg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(1,(dreg),0,(reg));
-               *(cd->mcodeptr++) = 0x69;
-               emit_reg((dreg),(reg));
-               emit_imm32((imm));
-       }
-}
-
-
-void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg) {
-       if (IS_IMM8((imm))) {
-               emit_rex(0,(dreg),0,(reg));
-               *(cd->mcodeptr++) = 0x6b;
-               emit_reg((dreg),(reg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(0,(dreg),0,(reg));
-               *(cd->mcodeptr++) = 0x69;
-               emit_reg((dreg),(reg));
-               emit_imm32((imm));
-       }
-}
-
-
-void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (IS_IMM8((imm))) {
-               emit_rex(1,(dreg),0,(basereg));
-               *(cd->mcodeptr++) = 0x6b;
-               emit_membase(cd, (basereg),(disp),(dreg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(1,(dreg),0,(basereg));
-               *(cd->mcodeptr++) = 0x69;
-               emit_membase(cd, (basereg),(disp),(dreg));
-               emit_imm32((imm));
-       }
-}
-
-
-void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (IS_IMM8((imm))) {
-               emit_rex(0,(dreg),0,(basereg));
-               *(cd->mcodeptr++) = 0x6b;
-               emit_membase(cd, (basereg),(disp),(dreg));
-               emit_imm8((imm));
-       } else {
-               emit_rex(0,(dreg),0,(basereg));
-               *(cd->mcodeptr++) = 0x69;
-               emit_membase(cd, (basereg),(disp),(dreg));
-               emit_imm32((imm));
-       }
-}
-
-
-void emit_idiv_reg(codegendata *cd, s8 reg) {
-       emit_rex(1,0,0,(reg));
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(7,(reg));
-}
-
-
-void emit_idivl_reg(codegendata *cd, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(7,(reg));
-}
-
-
-
-void emit_ret(codegendata *cd) {
-    *(cd->mcodeptr++) = 0xc3;
-}
-
-
-
-/*
- * shift ops
- */
-void emit_shift_reg(codegendata *cd, s8 opc, s8 reg) {
-       emit_rex(1,0,0,(reg));
-       *(cd->mcodeptr++) = 0xd3;
-       emit_reg((opc),(reg));
-}
-
-
-void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0xd3;
-       emit_reg((opc),(reg));
-}
-
-
-void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
-       emit_rex(1,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xd3;
-       emit_membase(cd, (basereg),(disp),(opc));
-}
-
-
-void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
-       emit_rex(0,0,0,(basereg));
-       *(cd->mcodeptr++) = 0xd3;
-       emit_membase(cd, (basereg),(disp),(opc));
-}
-
-
-void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0xd1;
-               emit_reg((opc),(dreg));
-       } else {
-               emit_rex(1,0,0,(dreg));
-               *(cd->mcodeptr++) = 0xc1;
-               emit_reg((opc),(dreg));
-               emit_imm8((imm));
-       }
-}
-
-
-void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               emit_rex(0,0,0,(dreg));
-               *(cd->mcodeptr++) = 0xd1;
-               emit_reg((opc),(dreg));
-       } else {
-               emit_rex(0,0,0,(dreg));
-               *(cd->mcodeptr++) = 0xc1;
-               emit_reg((opc),(dreg));
-               emit_imm8((imm));
-       }
-}
-
-
-void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               emit_rex(1,0,0,(basereg));
-               *(cd->mcodeptr++) = 0xd1;
-               emit_membase(cd, (basereg),(disp),(opc));
-       } else {
-               emit_rex(1,0,0,(basereg));
-               *(cd->mcodeptr++) = 0xc1;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm8((imm));
-       }
-}
-
-
-void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               emit_rex(0,0,0,(basereg));
-               *(cd->mcodeptr++) = 0xd1;
-               emit_membase(cd, (basereg),(disp),(opc));
-       } else {
-               emit_rex(0,0,0,(basereg));
-               *(cd->mcodeptr++) = 0xc1;
-               emit_membase(cd, (basereg),(disp),(opc));
-               emit_imm8((imm));
-       }
-}
-
-
-
-/*
- * jump operations
- */
-void emit_jmp_imm(codegendata *cd, s8 imm) {
-       *(cd->mcodeptr++) = 0xe9;
-       emit_imm32((imm));
-}
-
-
-void emit_jmp_reg(codegendata *cd, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0xff;
-       emit_reg(4,(reg));
-}
-
-
-void emit_jcc(codegendata *cd, s8 opc, s8 imm) {
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = (0x80 + (opc));
-       emit_imm32((imm));
-}
-
-
-
-/*
- * conditional set and move operations
- */
-
-/* we need the rex byte to get all low bytes */
-void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) {
-       *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = (0x90 + (opc));
-       emit_reg(0,(reg));
-}
-
-
-/* we need the rex byte to get all low bytes */
-void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = (0x90 + (opc));
-       emit_membase(cd, (basereg),(disp),0);
-}
-
-
-void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
-{
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = (0x40 + (opc));
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg)
-{
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = (0x40 + (opc));
-       emit_reg((dreg),(reg));
-}
-
-
-
-void emit_neg_reg(codegendata *cd, s8 reg)
-{
-       emit_rex(1,0,0,(reg));
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(3,(reg));
-}
-
-
-void emit_negl_reg(codegendata *cd, s8 reg)
-{
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0xf7;
-       emit_reg(3,(reg));
-}
-
-
-void emit_push_reg(codegendata *cd, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0x50 + (0x07 & (reg));
-}
-
-
-void emit_push_imm(codegendata *cd, s8 imm) {
-       *(cd->mcodeptr++) = 0x68;
-       emit_imm32((imm));
-}
-
-
-void emit_pop_reg(codegendata *cd, s8 reg) {
-       emit_rex(0,0,0,(reg));
-       *(cd->mcodeptr++) = 0x58 + (0x07 & (reg));
-}
-
-
-void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(1,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x87;
-       emit_reg((reg),(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));
-       *(cd->mcodeptr++) = 0xff;
-       emit_reg(2,(reg));
-}
-
-
-void emit_call_imm(codegendata *cd, s8 imm) {
-       *(cd->mcodeptr++) = 0xe8;
-       emit_imm32((imm));
-}
-
-
-void emit_call_mem(codegendata *cd, ptrint mem)
-{
-       *(cd->mcodeptr++) = 0xff;
-       emit_mem(2,(mem));
-}
-
-
-
-/*
- * floating point instructions (SSE2)
- */
-void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x58;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x58;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5a;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(1,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5e;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5e;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(1,(freg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x6e;
-       emit_reg((freg),(reg));
-}
-
-
-void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(1,(freg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x7e;
-       emit_reg((freg),(reg));
-}
-
-
-void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x7e;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x7e;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(1,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x6e;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x6e;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x6e;
-       emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x7e;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0xd6;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x7e;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(reg),0,(dreg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_reg((reg),(dreg));
-}
-
-
-void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_byte_rex((reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_byte_rex((reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_membase32(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_byte_rex((dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_membase32(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
-{
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x12;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
-{
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x13;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-/* Always emit a REX byte, because the instruction size can be smaller when   */
-/* all register indexes are smaller than 7.                                   */
-void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_byte_rex((dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_membase32(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg)
-{
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x12;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp)
-{
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(reg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x13;
-       emit_membase(cd, (basereg),(disp),(reg));
-}
-
-
-void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(reg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x11;
-       emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),(indexreg),(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x10;
-       emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x59;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x59;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf3;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0xf2;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x5c;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2e;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x2e;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x57;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x57;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),0,(reg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x57;
-       emit_reg((dreg),(reg));
-}
-
-
-void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) {
-       *(cd->mcodeptr++) = 0x66;
-       emit_rex(0,(dreg),0,(basereg));
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x57;
-       emit_membase(cd, (basereg),(disp),(dreg));
-}
-
-
-/* system instructions ********************************************************/
-
-void emit_rdtsc(codegendata *cd)
-{
-       *(cd->mcodeptr++) = 0x0f;
-       *(cd->mcodeptr++) = 0x31;
-}
-
-/* emit_load_high **************************************************************
-
-   Emits a possible load of the high 32-bits of an operand.
-
-*******************************************************************************/
-
-s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
-{
-       codegendata  *cd;
-       s4            disp;
-       s4            reg;
-
-       assert(src->type == TYPE_LNG);
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       if (IS_INMEMORY(src->flags)) {
-               COUNT_SPILLS;
-
-               disp = src->vv.regoff * 4;
-
-               M_ILD(tempreg, REG_SP, disp);
-
-               reg = tempreg;
-       }
-       else
-               reg = GET_HIGH_REG(src->vv.regoff);
-
-       return reg;
-}
-
-/* emit_load_low ***************************************************************
-
-   Emits a possible load of the low 32-bits of an operand.
-
-*******************************************************************************/
-
-s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
-{
-       codegendata  *cd;
-       s4            disp;
-       s4            reg;
-
-       assert(src->type == TYPE_LNG);
-
-       /* get required compiler data */
-
-       cd = jd->cd;
-
-       if (IS_INMEMORY(src->flags)) {
-               COUNT_SPILLS;
-
-               disp = src->vv.regoff * 4;
-
-               M_ILD(tempreg, REG_SP, disp + 4);
-
-               reg = tempreg;
-       }
-       else
-               reg = GET_LOW_REG(src->vv.regoff);
-
-       return reg;
-}
-
-/* emit_nullpointer_check ******************************************************
-
-   Emit a NullPointerException check.
-
-*******************************************************************************/
-
-__PORTED__ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
-{
-       if (INSTRUCTION_MUST_CHECK(iptr)) {
-               M_TEST(reg);
-               M_BEQ(0);
-               codegen_add_nullpointerexception_ref(cd);
-       }
-}
-
-/* emit_arrayindexoutofbounds_check ********************************************
-
-   Emit a ArrayIndexOutOfBoundsException check.
-
-*******************************************************************************/
-
-void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
-{
-#if 0
-       if (INSTRUCTION_MUST_CHECK(iptr)) {
-        M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
-        M_ICMP(REG_ITMP3, s2);
-        M_BAE(0);
-        codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
-       }
-#endif
-}
-
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where