- moved defines into header
authortwisti <none@none>
Thu, 1 Jul 2004 20:38:16 +0000 (20:38 +0000)
committertwisti <none@none>
Thu, 1 Jul 2004 20:38:16 +0000 (20:38 +0000)
- moved code emitting functions into emitfuncs.*

jit/x86_64/Makefile.am
jit/x86_64/codegen.c
jit/x86_64/codegen.h
jit/x86_64/emitfuncs.c [new file with mode: 0644]
jit/x86_64/emitfuncs.h [new file with mode: 0644]
src/vm/jit/x86_64/Makefile.am
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/codegen.h
src/vm/jit/x86_64/emitfuncs.c [new file with mode: 0644]
src/vm/jit/x86_64/emitfuncs.h [new file with mode: 0644]

index ec246afc0c859d23d6e664d12cb636755f119d59..7cdaf5cb8f6a5b50b61c5c9d137966c1d747e52b 100644 (file)
@@ -1,24 +1,26 @@
 ## Process this file with automake to produce Makefile.in
 
-# $Id: Makefile.am 1123 2004-06-03 20:44:56Z twisti $
+# $Id: Makefile.am 1266 2004-07-01 20:38:16Z twisti $
 
 
-INCLUDES = -I$(top_srcdir)/jit
+INCLUDES = -I$(top_srcdir)
 
 EXTRA_DIST = \
        asmpart.S \
-       disass.c \
-       disass.h \
-       native-math.h \
+       bfd.h \
        codegen.c \
        codegen.h \
-       types.h \
        dis-asm.h \
-       bfd.h
+       disass.c \
+       disass.h \
+       emitfuncs.c \
+       emitfuncs.h \
+       native-math.h \
+       types.h
 
 noinst_LIBRARIES = libarch.a
 
-libarch_a_SOURCES = asmpart.S codegen.c disass.c i386-dis.c dis-buf.c
+libarch_a_SOURCES = asmpart.S codegen.c disass.c emitfuncs.c i386-dis.c dis-buf.c
 
 %.o: %.S
        $(COMPILE) -c $<
index f97d0bb624be50e8ce336a0d011432bf5f101f89..4674993b38205270056ff1bde74370c8e21baab4 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 1134 2004-06-05 17:38:00Z twisti $
+   $Id: codegen.c 1266 2004-07-01 20:38:16Z twisti $
 
 */
 
 #include <signal.h>
 #include "types.h"
 #include "main.h"
-#include "codegen.h"
-#include "jit.h"
-#include "reg.h"
-#include "parse.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/jit.h"
+#include "jit/reg.h"
+#include "jit/parse.h"
 #include "builtin.h"
 #include "asmpart.h"
 #include "jni.h"
@@ -49,8 +50,8 @@
 #include "native.h"
 
 /* include independent code generation stuff */
-#include "codegen.inc"
-#include "reg.inc"
+#include "jit/codegen.inc"
+#include "jit/reg.inc"
 
 
 /* register descripton - array ************************************************/
@@ -80,123 +81,6 @@ int nregdescfloat[] = {
 };
 
 
-/* additional functions and macros to generate code ***************************/
-
-#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
-
-
-#ifdef STATISTICS
-#define COUNT_SPILLS count_spills++
-#else
-#define COUNT_SPILLS
-#endif
-
-
-#define CALCOFFSETBYTES(var, reg, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else if ((s4) (val) != 0) (var) += 1; \
-    else if ((reg) == RBP || (reg) == RSP || (reg) == R12 || (reg) == R13) (var) += 1;
-
-
-#define CALCIMMEDIATEBYTES(var, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else (var) += 1;
-
-
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-       if (checknull) { \
-        x86_64_test_reg_reg((objreg), (objreg)); \
-        x86_64_jcc(X86_64_CC_E, 0); \
-           codegen_addxnullrefs(mcodeptr); \
-       }
-
-
-#define gen_div_check(v) \
-    if (checknull) { \
-        if ((v)->flags & INMEMORY) { \
-            x86_64_alu_imm_membase(X86_64_CMP, 0, REG_SP, src->regoff * 8); \
-        } else { \
-            x86_64_test_reg_reg(src->regoff, src->regoff); \
-        } \
-        x86_64_jcc(X86_64_CC_E, 0); \
-        codegen_addxdivrefs(mcodeptr); \
-    }
-
-
-/* MCODECHECK(icnt) */
-
-#define MCODECHECK(icnt) \
-       if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
-
-/* M_INTMOVE:
-    generates an integer-move from register a to b.
-    if a and b are the same int-register, no code will be generated.
-*/ 
-
-#define M_INTMOVE(reg,dreg) \
-    if ((reg) != (dreg)) { \
-        x86_64_mov_reg_reg((reg),(dreg)); \
-    }
-
-
-/* M_FLTMOVE:
-    generates a floating-point-move from register a to b.
-    if a and b are the same float-register, no code will be generated
-*/ 
-
-#define M_FLTMOVE(reg,dreg) \
-    if ((reg) != (dreg)) { \
-        x86_64_movq_reg_reg((reg),(dreg)); \
-    }
-
-
-/* var_to_reg_xxx:
-    this function generates code to fetch data from a pseudo-register
-    into a real register. 
-    If the pseudo-register has actually been assigned to a real 
-    register, no code will be emitted, since following operations
-    can use this register directly.
-    
-    v: pseudoregister to be fetched from
-    tempregnum: temporary register to be used if v is actually spilled to ram
-
-    return: the register number, where the operand can be found after 
-            fetching (this wil be either tempregnum or the register
-            number allready given to v)
-*/
-
-#define var_to_reg_int(regnr,v,tempnr) \
-    if ((v)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        if ((v)->type == TYPE_INT) { \
-            x86_64_movl_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } else { \
-            x86_64_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } \
-        regnr = tempnr; \
-    } else { \
-        regnr = (v)->regoff; \
-    }
-
-
-
-#define var_to_reg_flt(regnr,v,tempnr) \
-    if ((v)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        if ((v)->type == TYPE_FLT) { \
-            x86_64_movlps_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } else { \
-            x86_64_movlpd_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } \
-/*        x86_64_movq_membase_reg(REG_SP, (v)->regoff * 8, tempnr);*/ \
-        regnr = tempnr; \
-    } else { \
-        regnr = (v)->regoff; \
-    }
-
-
 /* reg_of_var:
     This function determines a register, to which the result of an operation
     should go, when it is ultimatively intended to store the result in
@@ -248,31 +132,6 @@ static int reg_of_var(stackptr v, int tempregnum)
 }
 
 
-/* store_reg_to_var_xxx:
-    This function generates the code to store the result of an operation
-    back into a spilled pseudo-variable.
-    If the pseudo-variable has not been spilled in the first place, this 
-    function will generate nothing.
-    
-    v ............ Pseudovariable
-    tempregnum ... Number of the temporary registers as returned by
-                   reg_of_var.
-*/     
-
-#define store_reg_to_var_int(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        x86_64_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
-    }
-
-
-#define store_reg_to_var_flt(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-         COUNT_SPILLS; \
-         x86_64_movq_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
-    }
-
-
 /* NullPointerException signal handler for hardware null pointer check */
 
 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
@@ -2170,13 +2029,6 @@ void codegen()
 
                /* memory operations **************************************************/
 
-#define gen_bound_check \
-    if (checkbounds) { \
-        x86_64_alul_membase_reg(X86_64_CMP, s1, OFFSET(java_arrayheader, size), s2); \
-        x86_64_jcc(X86_64_CC_AE, 0); \
-        codegen_addxboundrefs(mcodeptr, s2); \
-    }
-
                case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., (int) length        */
 
                        var_to_reg_int(s1, src, REG_ITMP1);
@@ -4083,1786 +3935,6 @@ void removenativestub(u1 *stub)
 }
 
 
-/* code generation functions */
-
-void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else if (s1 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_alul_reg_membase(alu_op, s1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alul_reg_reg(alu_op, s1, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
-                                               
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_reg_reg(alu_op, s2, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
-               }
-
-       } else {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s1 * 8, d);
-
-               } else {
-                       if (s2 == d) {
-                               x86_64_alul_reg_reg(alu_op, s1, d);
-
-                       } else {
-                               M_INTMOVE(s1, d);
-                               x86_64_alul_reg_reg(alu_op, s2, d);
-                       }
-               }
-       }
-}
-
-
-
-void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else if (s1 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_alu_reg_membase(alu_op, s1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alu_reg_reg(alu_op, s1, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
-                                               
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_reg_reg(alu_op, s2, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
-               }
-
-       } else {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s1 * 8, d);
-
-               } else {
-                       if (s2 == d) {
-                               x86_64_alu_reg_reg(alu_op, s1, d);
-
-                       } else {
-                               M_INTMOVE(s1, d);
-                               x86_64_alu_reg_reg(alu_op, s2, d);
-                       }
-               }
-       }
-}
-
-
-
-void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if (src->flags & INMEMORY) {
-                       if (s1 == d) {
-                               x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
-               }
-
-       } else {
-               if (src->flags & INMEMORY) {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
-
-               } else {
-                       M_INTMOVE(s1, d);
-                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
-               }
-       }
-}
-
-
-
-void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if (src->flags & INMEMORY) {
-                       if (s1 == d) {
-                               if (x86_64_is_imm32(iptr->val.l)) {
-                                       x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
-
-                               } else {
-                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                                       x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-                               }
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-
-                               if (x86_64_is_imm32(iptr->val.l)) {
-                                       x86_64_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
-
-                               } else {
-                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP2);
-                                       x86_64_alu_reg_reg(alu_op, REG_ITMP2, REG_ITMP1);
-                               }
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-
-                       if (x86_64_is_imm32(iptr->val.l)) {
-                               x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-                       }
-               }
-
-       } else {
-               if (src->flags & INMEMORY) {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-
-               } else {
-                       M_INTMOVE(s1, d);
-               }
-
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_reg(alu_op, iptr->val.l, d);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_reg(alu_op, REG_ITMP1, d);
-               }
-       }
-}
-
-
-
-void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
-                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
-                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-               }
-               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-
-       } else {
-               if (d == RCX) {
-                       d = REG_ITMP3;
-               }
-                                       
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);    /* maybe src is RCX */
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else {
-                       if (s1 == RCX) {
-                               M_INTMOVE(s1, d);
-                               M_INTMOVE(s2, RCX);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       x86_64_shiftl_reg(shift_op, d);
-               }
-
-               if (d == RCX) {
-                       M_INTMOVE(REG_ITMP3, RCX);
-
-               } else {
-                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-               }
-       }
-}
-
-
-
-void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shift_reg(shift_op, REG_ITMP2);
-                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shift_reg(shift_op, REG_ITMP2);
-                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
-               }
-               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-
-       } else {
-               if (d == RCX) {
-                       d = REG_ITMP3;
-               }
-
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);    /* maybe src is RCX */
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else {
-                       if (s1 == RCX) {
-                               M_INTMOVE(s1, d);
-                               M_INTMOVE(s2, RCX);
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       x86_64_shift_reg(shift_op, d);
-               }
-
-               if (d == RCX) {
-                       M_INTMOVE(REG_ITMP3, RCX);
-
-               } else {
-                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-               }
-       }
-}
-
-
-
-void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               if (s1 == d) {
-                       x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-               } else {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                       x86_64_shiftl_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
-                       x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-               }
-
-       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
-               x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
-                               
-       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-               x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-       } else {
-               M_INTMOVE(s1, d);
-               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
-       }
-}
-
-
-
-void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               if (s1 == d) {
-                       x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-               } else {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                       x86_64_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
-                       x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-               }
-
-       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
-               x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
-                               
-       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-               x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-       } else {
-               M_INTMOVE(s1, d);
-               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
-       }
-}
-
-
-
-void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       if (src->flags & INMEMORY) {
-               x86_64_alul_imm_membase(X86_64_CMP, iptr->val.i, REG_SP, src->regoff * 8);
-
-       } else {
-               x86_64_alul_imm_reg(X86_64_CMP, iptr->val.i, src->regoff);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-
-       if (src->flags & INMEMORY) {
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_membase(X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-               }
-
-       } else {
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_reg(X86_64_CMP, iptr->val.l, s1);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_reg(X86_64_CMP, REG_ITMP1, s1);
-               }
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-
-       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-               x86_64_alul_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-
-       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-               x86_64_alul_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
-
-       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_alul_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
-
-       } else {
-               x86_64_alul_reg_reg(X86_64_CMP, s2, s1);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-
-       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-               x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-
-       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-               x86_64_alu_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
-
-       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_alu_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
-
-       } else {
-               x86_64_alu_reg_reg(X86_64_CMP, s2, s1);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-#if 1
-
-/*
- * mov ops
- */
-void x86_64_mov_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_mov_imm_reg(s8 imm, s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       x86_64_emit_imm64((imm));
-}
-
-
-void x86_64_movl_imm_reg(s8 imm, s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-/*
- * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
- * constant membase immediate length of 32bit
- */
-void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_address_byte(2, (reg), (basereg));
-       x86_64_emit_imm32((disp));
-}
-
-
-void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x88;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xc7;
-       x86_64_emit_membase((basereg),(disp),0);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xc7;
-       x86_64_emit_membase((basereg),(disp),0);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_movsbq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movswq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movslq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x63;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x63;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movzwq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-
-/*
- * alu operations
- */
-void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 3;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 3;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(1,(basereg),0,0);
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(basereg),0,0);
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(0,(basereg),0,0);
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(basereg),0,0);
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_test_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x85;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_testl_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x85;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_test_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_testw_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0x66;
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm16((imm));
-}
-
-
-void x86_64_testb_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0xf6;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm8((imm));
-}
-
-
-void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8d;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8d;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-
-/*
- * inc, dec operations
- */
-void x86_64_inc_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(0,(reg));
-}
-
-
-void x86_64_incl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(0,(reg));
-}
-
-
-void x86_64_inc_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_incl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_dec_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(1,(reg));
-}
-
-        
-void x86_64_decl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(1,(reg));
-}
-
-        
-void x86_64_dec_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),1);
-}
-
-
-void x86_64_decl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),1);
-}
-
-
-
-
-void x86_64_cltd() {
-    *(mcodeptr++) = 0x99;
-}
-
-
-void x86_64_cqto() {
-       x86_64_emit_rex(1,0,0,0);
-       *(mcodeptr++) = 0x99;
-}
-
-
-
-void x86_64_imul_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_imull_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_imul_imm_reg(s8 imm, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg(0,(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg(0,(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imul_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,(dreg),0,(reg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(dreg),0,(reg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(0,(dreg),0,(reg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(dreg),0,(reg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(0,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_idiv_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(7,(reg));
-}
-
-
-void x86_64_idivl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(7,(reg));
-}
-
-
-
-void x86_64_ret() {
-    *(mcodeptr++) = 0xc3;
-}
-
-
-
-/*
- * shift ops
- */
-void x86_64_shift_reg(s8 opc, s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_reg((opc),(reg));
-}
-
-
-void x86_64_shiftl_reg(s8 opc, s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_reg((opc),(reg));
-}
-
-
-void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_membase((basereg),(disp),(opc));
-}
-
-
-void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_membase((basereg),(disp),(opc));
-}
-
-
-void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_reg((opc),(dreg));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_reg((opc),(dreg));
-       } else {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(1,0,0,(basereg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-       } else {
-               x86_64_emit_rex(1,0,0,(basereg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(0,0,0,(basereg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-       } else {
-               x86_64_emit_rex(0,0,0,(basereg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-
-/*
- * jump operations
- */
-void x86_64_jmp_imm(s8 imm) {
-       *(mcodeptr++) = 0xe9;
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_jmp_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(4,(reg));
-}
-
-
-void x86_64_jcc(s8 opc, s8 imm) {
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x80 + (opc));
-       x86_64_emit_imm32((imm));
-}
-
-
-
-/*
- * conditional set and move operations
- */
-
-/* we need the rex byte to get all low bytes */
-void x86_64_setcc_reg(s8 opc, s8 reg) {
-       *(mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x90 + (opc));
-       x86_64_emit_reg(0,(reg));
-}
-
-
-/* we need the rex byte to get all low bytes */
-void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp) {
-       *(mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x90 + (opc));
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x40 + (opc));
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x40 + (opc));
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-
-void x86_64_neg_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(3,(reg));
-}
-
-
-void x86_64_negl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(3,(reg));
-}
-
-
-void x86_64_neg_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_membase((basereg),(disp),3);
-}
-
-
-void x86_64_negl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_membase((basereg),(disp),3);
-}
-
-
-
-void x86_64_push_imm(s8 imm) {
-       *(mcodeptr++) = 0x68;
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_pop_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0x58 + (0x07 & (reg));
-}
-
-
-void x86_64_xchg_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x87;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_nop() {
-    *(mcodeptr++) = 0x90;
-}
-
-
-
-/*
- * call instructions
- */
-void x86_64_call_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(2,(reg));
-}
-
-
-void x86_64_call_imm(s8 imm) {
-       *(mcodeptr++) = 0xe8;
-       x86_64_emit_imm32((imm));
-}
-
-
-
-/*
- * floating point instructions (SSE2)
- */
-void x86_64_addsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x58;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_addss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x58;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_divss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_divsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movd_reg_freg(s8 reg, s8 freg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(freg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_reg((freg),(reg));
-}
-
-
-void x86_64_movd_freg_reg(s8 freg, s8 reg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(freg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_reg((freg),(reg));
-}
-
-
-void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xd6;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_movsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x12;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x12;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mulss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x59;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_mulsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x59;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_subss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_subsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorps_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_xorpd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-#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
index 54af3350c42e9aa54b885f95346810aee26229bb..5e6be38965a5dc3cabb35ba19c3d35a0f0e56661 100644 (file)
@@ -1,4 +1,4 @@
-/* jit/i386/codegen.h - code generation macros and definitions for x86_64
+/* jit/x86_64/codegen.h - code generation macros and definitions for x86_64
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
@@ -27,7 +27,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.h 928 2004-02-26 00:18:36Z twisti $
+   $Id: codegen.h 1266 2004-07-01 20:38:16Z twisti $
 
 */
 
@@ -35,7 +35,7 @@
 #ifndef _CODEGEN_H
 #define _CODEGEN_H
 
-#include "jit.h"
+#include "jit/jit.h"
 
 
 /* x86_64 register numbers */
@@ -303,165 +303,154 @@ typedef enum {
     } while (0)
 
 
-/* code generation prototypes */
-
-void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr);
-
-
-/* integer instructions */
-
-void x86_64_mov_reg_reg(s8 reg, s8 dreg);
-void x86_64_mov_imm_reg(s8 imm, s8 reg);
-void x86_64_movl_imm_reg(s8 imm, s8 reg);
-void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp);
-void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp);
-void x86_64_movsbq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movswq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movslq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movzwq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
-void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
-void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
-void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
-void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_test_reg_reg(s8 reg, s8 dreg);
-void x86_64_testl_reg_reg(s8 reg, s8 dreg);
-void x86_64_test_imm_reg(s8 imm, s8 reg);
-void x86_64_testw_imm_reg(s8 imm, s8 reg);
-void x86_64_testb_imm_reg(s8 imm, s8 reg);
-void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_inc_reg(s8 reg);
-void x86_64_incl_reg(s8 reg);
-void x86_64_inc_membase(s8 basereg, s8 disp);
-void x86_64_incl_membase(s8 basereg, s8 disp);
-void x86_64_dec_reg(s8 reg);
-void x86_64_decl_reg(s8 reg);
-void x86_64_dec_membase(s8 basereg, s8 disp);
-void x86_64_decl_membase(s8 basereg, s8 disp);
-void x86_64_cltd();
-void x86_64_cqto();
-void x86_64_imul_reg_reg(s8 reg, s8 dreg);
-void x86_64_imull_reg_reg(s8 reg, s8 dreg);
-void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_imul_imm_reg(s8 imm, s8 dreg);
-void x86_64_imul_imm_reg_reg(s8 imm,s8 reg, s8 dreg);
-void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg);
-void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
-void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
-void x86_64_idiv_reg(s8 reg);
-void x86_64_idivl_reg(s8 reg);
-void x86_64_ret();
-void x86_64_shift_reg(s8 opc, s8 reg);
-void x86_64_shiftl_reg(s8 opc, s8 reg);
-void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_jmp_imm(s8 imm);
-void x86_64_jmp_reg(s8 reg);
-void x86_64_jcc(s8 opc, s8 imm);
-void x86_64_setcc_reg(s8 opc, s8 reg);
-void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_neg_reg(s8 reg);
-void x86_64_negl_reg(s8 reg);
-void x86_64_neg_membase(s8 basereg, s8 disp);
-void x86_64_negl_membase(s8 basereg, s8 disp);
-void x86_64_push_imm(s8 imm);
-void x86_64_pop_reg(s8 reg);
-void x86_64_xchg_reg_reg(s8 reg, s8 dreg);
-void x86_64_nop();
-void x86_64_call_reg(s8 reg);
-void x86_64_call_imm(s8 imm);
-
-
-/* floating point instructions (SSE2) */
-
-void x86_64_addsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_addss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg);
-void x86_64_divss_reg_reg(s8 reg, s8 dreg);
-void x86_64_divsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_movd_reg_freg(s8 reg, s8 freg);
-void x86_64_movd_freg_reg(s8 freg, s8 reg);
-void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_movq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movss_reg_reg(s8 reg, s8 dreg);
-void x86_64_movsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_mulss_reg_reg(s8 reg, s8 dreg);
-void x86_64_mulsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_subss_reg_reg(s8 reg, s8 dreg);
-void x86_64_subsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg);
-void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorps_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_xorpd_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+/* additional functions and macros to generate code ***************************/
+
+#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
+
+
+#ifdef STATISTICS
+#define COUNT_SPILLS count_spills++
+#else
+#define COUNT_SPILLS
+#endif
+
+
+#define CALCOFFSETBYTES(var, reg, val) \
+    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
+    else if ((s4) (val) != 0) (var) += 1; \
+    else if ((reg) == RBP || (reg) == RSP || (reg) == R12 || (reg) == R13) (var) += 1;
+
+
+#define CALCIMMEDIATEBYTES(var, val) \
+    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
+    else (var) += 1;
+
+
+/* gen_nullptr_check(objreg) */
+
+#define gen_nullptr_check(objreg) \
+       if (checknull) { \
+        x86_64_test_reg_reg((objreg), (objreg)); \
+        x86_64_jcc(X86_64_CC_E, 0); \
+           codegen_addxnullrefs(mcodeptr); \
+       }
+
+
+#define gen_bound_check \
+    if (checkbounds) { \
+        x86_64_alul_membase_reg(X86_64_CMP, s1, OFFSET(java_arrayheader, size), s2); \
+        x86_64_jcc(X86_64_CC_AE, 0); \
+        codegen_addxboundrefs(mcodeptr, s2); \
+    }
+
+
+#define gen_div_check(v) \
+    if (checknull) { \
+        if ((v)->flags & INMEMORY) { \
+            x86_64_alu_imm_membase(X86_64_CMP, 0, REG_SP, src->regoff * 8); \
+        } else { \
+            x86_64_test_reg_reg(src->regoff, src->regoff); \
+        } \
+        x86_64_jcc(X86_64_CC_E, 0); \
+        codegen_addxdivrefs(mcodeptr); \
+    }
+
+
+/* MCODECHECK(icnt) */
+
+#define MCODECHECK(icnt) \
+       if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
+
+/* M_INTMOVE:
+    generates an integer-move from register a to b.
+    if a and b are the same int-register, no code will be generated.
+*/ 
+
+#define M_INTMOVE(reg,dreg) \
+    if ((reg) != (dreg)) { \
+        x86_64_mov_reg_reg((reg),(dreg)); \
+    }
+
+
+/* M_FLTMOVE:
+    generates a floating-point-move from register a to b.
+    if a and b are the same float-register, no code will be generated
+*/ 
+
+#define M_FLTMOVE(reg,dreg) \
+    if ((reg) != (dreg)) { \
+        x86_64_movq_reg_reg((reg),(dreg)); \
+    }
+
+
+/* var_to_reg_xxx:
+    this function generates code to fetch data from a pseudo-register
+    into a real register. 
+    If the pseudo-register has actually been assigned to a real 
+    register, no code will be emitted, since following operations
+    can use this register directly.
+    
+    v: pseudoregister to be fetched from
+    tempregnum: temporary register to be used if v is actually spilled to ram
+
+    return: the register number, where the operand can be found after 
+            fetching (this wil be either tempregnum or the register
+            number allready given to v)
+*/
+
+#define var_to_reg_int(regnr,v,tempnr) \
+    if ((v)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        if ((v)->type == TYPE_INT) { \
+            x86_64_movl_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } else { \
+            x86_64_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } \
+        regnr = tempnr; \
+    } else { \
+        regnr = (v)->regoff; \
+    }
+
+
+
+#define var_to_reg_flt(regnr,v,tempnr) \
+    if ((v)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        if ((v)->type == TYPE_FLT) { \
+            x86_64_movlps_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } else { \
+            x86_64_movlpd_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } \
+/*        x86_64_movq_membase_reg(REG_SP, (v)->regoff * 8, tempnr);*/ \
+        regnr = tempnr; \
+    } else { \
+        regnr = (v)->regoff; \
+    }
+
+
+/* store_reg_to_var_xxx:
+    This function generates the code to store the result of an operation
+    back into a spilled pseudo-variable.
+    If the pseudo-variable has not been spilled in the first place, this 
+    function will generate nothing.
+    
+    v ............ Pseudovariable
+    tempregnum ... Number of the temporary registers as returned by
+                   reg_of_var.
+*/     
+
+#define store_reg_to_var_int(sptr, tempregnum) \
+    if ((sptr)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        x86_64_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
+    }
+
+
+#define store_reg_to_var_flt(sptr, tempregnum) \
+    if ((sptr)->flags & INMEMORY) { \
+         COUNT_SPILLS; \
+         x86_64_movq_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
+    }
 
 
 /* function gen_resolvebranch **************************************************
@@ -486,6 +475,8 @@ void codegen();
 void codegen_close();
 void dseg_display(s4 *s4ptr);
 
+void codegen_addreference(basicblock *target, void *branchptr);
+
 #endif /* _CODEGEN_H */
 
 
@@ -501,4 +492,3 @@ void dseg_display(s4 *s4ptr);
  * tab-width: 4
  * End:
  */
-
diff --git a/jit/x86_64/emitfuncs.c b/jit/x86_64/emitfuncs.c
new file mode 100644 (file)
index 0000000..e5b9976
--- /dev/null
@@ -0,0 +1,1828 @@
+/* jit/x86_64/emitfuncs.c - x86_64 code emitter functions
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Institut f. Computersprachen, TU Wien
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
+   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
+   J. Wenninger
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Christian Thalinger
+
+   $Id: emitfuncs.c 1266 2004-07-01 20:38:16Z twisti $
+
+*/
+
+
+#include "jit/jit.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/types.h"
+
+
+/* code generation functions */
+
+void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else if (s1 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_alul_reg_membase(alu_op, s1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alul_reg_reg(alu_op, s1, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
+                                               
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_reg_reg(alu_op, s2, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
+               }
+
+       } else {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s1 * 8, d);
+
+               } else {
+                       if (s2 == d) {
+                               x86_64_alul_reg_reg(alu_op, s1, d);
+
+                       } else {
+                               M_INTMOVE(s1, d);
+                               x86_64_alul_reg_reg(alu_op, s2, d);
+                       }
+               }
+       }
+}
+
+
+
+void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else if (s1 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_alu_reg_membase(alu_op, s1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alu_reg_reg(alu_op, s1, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
+                                               
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_reg_reg(alu_op, s2, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
+               }
+
+       } else {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s1 * 8, d);
+
+               } else {
+                       if (s2 == d) {
+                               x86_64_alu_reg_reg(alu_op, s1, d);
+
+                       } else {
+                               M_INTMOVE(s1, d);
+                               x86_64_alu_reg_reg(alu_op, s2, d);
+                       }
+               }
+       }
+}
+
+
+
+void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if (src->flags & INMEMORY) {
+                       if (s1 == d) {
+                               x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
+               }
+
+       } else {
+               if (src->flags & INMEMORY) {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
+
+               } else {
+                       M_INTMOVE(s1, d);
+                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
+               }
+       }
+}
+
+
+
+void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if (src->flags & INMEMORY) {
+                       if (s1 == d) {
+                               if (x86_64_is_imm32(iptr->val.l)) {
+                                       x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
+
+                               } else {
+                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                                       x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+                               }
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+
+                               if (x86_64_is_imm32(iptr->val.l)) {
+                                       x86_64_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
+
+                               } else {
+                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP2);
+                                       x86_64_alu_reg_reg(alu_op, REG_ITMP2, REG_ITMP1);
+                               }
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+
+                       if (x86_64_is_imm32(iptr->val.l)) {
+                               x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+                       }
+               }
+
+       } else {
+               if (src->flags & INMEMORY) {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+
+               } else {
+                       M_INTMOVE(s1, d);
+               }
+
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_reg(alu_op, iptr->val.l, d);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_reg(alu_op, REG_ITMP1, d);
+               }
+       }
+}
+
+
+
+void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
+                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
+                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+               }
+               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+
+       } else {
+               if (d == RCX) {
+                       d = REG_ITMP3;
+               }
+                                       
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);    /* maybe src is RCX */
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else {
+                       if (s1 == RCX) {
+                               M_INTMOVE(s1, d);
+                               M_INTMOVE(s2, RCX);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               M_INTMOVE(s1, d);
+                       }
+                       x86_64_shiftl_reg(shift_op, d);
+               }
+
+               if (d == RCX) {
+                       M_INTMOVE(REG_ITMP3, RCX);
+
+               } else {
+                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+               }
+       }
+}
+
+
+
+void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shift_reg(shift_op, REG_ITMP2);
+                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shift_reg(shift_op, REG_ITMP2);
+                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
+               }
+               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+
+       } else {
+               if (d == RCX) {
+                       d = REG_ITMP3;
+               }
+
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);    /* maybe src is RCX */
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else {
+                       if (s1 == RCX) {
+                               M_INTMOVE(s1, d);
+                               M_INTMOVE(s2, RCX);
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               M_INTMOVE(s1, d);
+                       }
+                       x86_64_shift_reg(shift_op, d);
+               }
+
+               if (d == RCX) {
+                       M_INTMOVE(REG_ITMP3, RCX);
+
+               } else {
+                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+               }
+       }
+}
+
+
+
+void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               if (s1 == d) {
+                       x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+               } else {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                       x86_64_shiftl_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
+                       x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+               }
+
+       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
+               x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
+                               
+       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+               x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+       } else {
+               M_INTMOVE(s1, d);
+               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
+       }
+}
+
+
+
+void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               if (s1 == d) {
+                       x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+               } else {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                       x86_64_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
+                       x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+               }
+
+       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
+               x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
+                               
+       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+               x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+       } else {
+               M_INTMOVE(s1, d);
+               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
+       }
+}
+
+
+
+void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       if (src->flags & INMEMORY) {
+               x86_64_alul_imm_membase(X86_64_CMP, iptr->val.i, REG_SP, src->regoff * 8);
+
+       } else {
+               x86_64_alul_imm_reg(X86_64_CMP, iptr->val.i, src->regoff);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+
+       if (src->flags & INMEMORY) {
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_membase(X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+               }
+
+       } else {
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_reg(X86_64_CMP, iptr->val.l, s1);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_reg(X86_64_CMP, REG_ITMP1, s1);
+               }
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+
+       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+               x86_64_alul_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+
+       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               x86_64_alul_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
+
+       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_alul_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
+
+       } else {
+               x86_64_alul_reg_reg(X86_64_CMP, s2, s1);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+
+       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+               x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+
+       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               x86_64_alu_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
+
+       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_alu_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
+
+       } else {
+               x86_64_alu_reg_reg(X86_64_CMP, s2, s1);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+/*
+ * mov ops
+ */
+void x86_64_mov_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_mov_imm_reg(s8 imm, s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
+       x86_64_emit_imm64((imm));
+}
+
+
+void x86_64_movl_imm_reg(s8 imm, s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+/*
+ * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
+ * constant membase immediate length of 32bit
+ */
+void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_address_byte(2, (reg), (basereg));
+       x86_64_emit_imm32((disp));
+}
+
+
+void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x88;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xc7;
+       x86_64_emit_membase((basereg),(disp),0);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xc7;
+       x86_64_emit_membase((basereg),(disp),0);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_movsbq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movswq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movslq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x63;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x63;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movzwq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+
+/*
+ * alu operations
+ */
+void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 3;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 3;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(1,(basereg),0,0);
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(basereg),0,0);
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(0,(basereg),0,0);
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(basereg),0,0);
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_test_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x85;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_testl_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x85;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_test_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_testw_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0x66;
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm16((imm));
+}
+
+
+void x86_64_testb_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0xf6;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm8((imm));
+}
+
+
+void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8d;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8d;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+
+/*
+ * inc, dec operations
+ */
+void x86_64_inc_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(0,(reg));
+}
+
+
+void x86_64_incl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(0,(reg));
+}
+
+
+void x86_64_inc_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_incl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_dec_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(1,(reg));
+}
+
+        
+void x86_64_decl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(1,(reg));
+}
+
+        
+void x86_64_dec_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),1);
+}
+
+
+void x86_64_decl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),1);
+}
+
+
+
+
+void x86_64_cltd() {
+    *(mcodeptr++) = 0x99;
+}
+
+
+void x86_64_cqto() {
+       x86_64_emit_rex(1,0,0,0);
+       *(mcodeptr++) = 0x99;
+}
+
+
+
+void x86_64_imul_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_imull_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_imul_imm_reg(s8 imm, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg(0,(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg(0,(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imul_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,(dreg),0,(reg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(dreg),0,(reg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(0,(dreg),0,(reg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(dreg),0,(reg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(0,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_idiv_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(7,(reg));
+}
+
+
+void x86_64_idivl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(7,(reg));
+}
+
+
+
+void x86_64_ret() {
+    *(mcodeptr++) = 0xc3;
+}
+
+
+
+/*
+ * shift ops
+ */
+void x86_64_shift_reg(s8 opc, s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_reg((opc),(reg));
+}
+
+
+void x86_64_shiftl_reg(s8 opc, s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_reg((opc),(reg));
+}
+
+
+void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_membase((basereg),(disp),(opc));
+}
+
+
+void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_membase((basereg),(disp),(opc));
+}
+
+
+void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_reg((opc),(dreg));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_reg((opc),(dreg));
+       } else {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(1,0,0,(basereg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+       } else {
+               x86_64_emit_rex(1,0,0,(basereg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(0,0,0,(basereg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+       } else {
+               x86_64_emit_rex(0,0,0,(basereg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+
+/*
+ * jump operations
+ */
+void x86_64_jmp_imm(s8 imm) {
+       *(mcodeptr++) = 0xe9;
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_jmp_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(4,(reg));
+}
+
+
+void x86_64_jcc(s8 opc, s8 imm) {
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x80 + (opc));
+       x86_64_emit_imm32((imm));
+}
+
+
+
+/*
+ * conditional set and move operations
+ */
+
+/* we need the rex byte to get all low bytes */
+void x86_64_setcc_reg(s8 opc, s8 reg) {
+       *(mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x90 + (opc));
+       x86_64_emit_reg(0,(reg));
+}
+
+
+/* we need the rex byte to get all low bytes */
+void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp) {
+       *(mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x90 + (opc));
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x40 + (opc));
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x40 + (opc));
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+
+void x86_64_neg_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(3,(reg));
+}
+
+
+void x86_64_negl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(3,(reg));
+}
+
+
+void x86_64_neg_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_membase((basereg),(disp),3);
+}
+
+
+void x86_64_negl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_membase((basereg),(disp),3);
+}
+
+
+
+void x86_64_push_imm(s8 imm) {
+       *(mcodeptr++) = 0x68;
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_pop_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0x58 + (0x07 & (reg));
+}
+
+
+void x86_64_xchg_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x87;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_nop() {
+    *(mcodeptr++) = 0x90;
+}
+
+
+
+/*
+ * call instructions
+ */
+void x86_64_call_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(2,(reg));
+}
+
+
+void x86_64_call_imm(s8 imm) {
+       *(mcodeptr++) = 0xe8;
+       x86_64_emit_imm32((imm));
+}
+
+
+
+/*
+ * floating point instructions (SSE2)
+ */
+void x86_64_addsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x58;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_addss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x58;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_divss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_divsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movd_reg_freg(s8 reg, s8 freg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(freg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_reg((freg),(reg));
+}
+
+
+void x86_64_movd_freg_reg(s8 freg, s8 reg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(freg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_reg((freg),(reg));
+}
+
+
+void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xd6;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_movsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x12;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x12;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mulss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x59;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_mulsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x59;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_subss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_subsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorps_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_xorpd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/jit/x86_64/emitfuncs.h b/jit/x86_64/emitfuncs.h
new file mode 100644 (file)
index 0000000..1039e01
--- /dev/null
@@ -0,0 +1,218 @@
+/* jit/x86_64/emitfuncs.h - emit function prototypes
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
+   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
+   P. Tomsich, J. Wenninger
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Andreas Krall
+            Christian Thalinger
+
+   $Id: emitfuncs.h 1266 2004-07-01 20:38:16Z twisti $
+
+*/
+
+
+#ifndef _EMITFUNCS_H
+#define _EMITFUNCS_H
+
+#include "jit/x86_64/types.h"
+
+
+extern u1 *mcodeptr;
+
+
+/* code generation prototypes */
+
+void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr);
+
+
+/* integer instructions */
+
+void x86_64_mov_reg_reg(s8 reg, s8 dreg);
+void x86_64_mov_imm_reg(s8 imm, s8 reg);
+void x86_64_movl_imm_reg(s8 imm, s8 reg);
+void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp);
+void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp);
+void x86_64_movsbq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movswq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movslq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movzwq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
+void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
+void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
+void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
+void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_test_reg_reg(s8 reg, s8 dreg);
+void x86_64_testl_reg_reg(s8 reg, s8 dreg);
+void x86_64_test_imm_reg(s8 imm, s8 reg);
+void x86_64_testw_imm_reg(s8 imm, s8 reg);
+void x86_64_testb_imm_reg(s8 imm, s8 reg);
+void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_inc_reg(s8 reg);
+void x86_64_incl_reg(s8 reg);
+void x86_64_inc_membase(s8 basereg, s8 disp);
+void x86_64_incl_membase(s8 basereg, s8 disp);
+void x86_64_dec_reg(s8 reg);
+void x86_64_decl_reg(s8 reg);
+void x86_64_dec_membase(s8 basereg, s8 disp);
+void x86_64_decl_membase(s8 basereg, s8 disp);
+void x86_64_cltd();
+void x86_64_cqto();
+void x86_64_imul_reg_reg(s8 reg, s8 dreg);
+void x86_64_imull_reg_reg(s8 reg, s8 dreg);
+void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_imul_imm_reg(s8 imm, s8 dreg);
+void x86_64_imul_imm_reg_reg(s8 imm,s8 reg, s8 dreg);
+void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg);
+void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
+void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
+void x86_64_idiv_reg(s8 reg);
+void x86_64_idivl_reg(s8 reg);
+void x86_64_ret();
+void x86_64_shift_reg(s8 opc, s8 reg);
+void x86_64_shiftl_reg(s8 opc, s8 reg);
+void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_jmp_imm(s8 imm);
+void x86_64_jmp_reg(s8 reg);
+void x86_64_jcc(s8 opc, s8 imm);
+void x86_64_setcc_reg(s8 opc, s8 reg);
+void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_neg_reg(s8 reg);
+void x86_64_negl_reg(s8 reg);
+void x86_64_neg_membase(s8 basereg, s8 disp);
+void x86_64_negl_membase(s8 basereg, s8 disp);
+void x86_64_push_imm(s8 imm);
+void x86_64_pop_reg(s8 reg);
+void x86_64_xchg_reg_reg(s8 reg, s8 dreg);
+void x86_64_nop();
+void x86_64_call_reg(s8 reg);
+void x86_64_call_imm(s8 imm);
+
+
+/* floating point instructions (SSE2) */
+
+void x86_64_addsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_addss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg);
+void x86_64_divss_reg_reg(s8 reg, s8 dreg);
+void x86_64_divsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_movd_reg_freg(s8 reg, s8 freg);
+void x86_64_movd_freg_reg(s8 freg, s8 reg);
+void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_movq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movss_reg_reg(s8 reg, s8 dreg);
+void x86_64_movsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_mulss_reg_reg(s8 reg, s8 dreg);
+void x86_64_mulsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_subss_reg_reg(s8 reg, s8 dreg);
+void x86_64_subsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg);
+void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorps_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_xorpd_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+
+#endif /* _EMITFUNCS_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index ec246afc0c859d23d6e664d12cb636755f119d59..7cdaf5cb8f6a5b50b61c5c9d137966c1d747e52b 100644 (file)
@@ -1,24 +1,26 @@
 ## Process this file with automake to produce Makefile.in
 
-# $Id: Makefile.am 1123 2004-06-03 20:44:56Z twisti $
+# $Id: Makefile.am 1266 2004-07-01 20:38:16Z twisti $
 
 
-INCLUDES = -I$(top_srcdir)/jit
+INCLUDES = -I$(top_srcdir)
 
 EXTRA_DIST = \
        asmpart.S \
-       disass.c \
-       disass.h \
-       native-math.h \
+       bfd.h \
        codegen.c \
        codegen.h \
-       types.h \
        dis-asm.h \
-       bfd.h
+       disass.c \
+       disass.h \
+       emitfuncs.c \
+       emitfuncs.h \
+       native-math.h \
+       types.h
 
 noinst_LIBRARIES = libarch.a
 
-libarch_a_SOURCES = asmpart.S codegen.c disass.c i386-dis.c dis-buf.c
+libarch_a_SOURCES = asmpart.S codegen.c disass.c emitfuncs.c i386-dis.c dis-buf.c
 
 %.o: %.S
        $(COMPILE) -c $<
index f97d0bb624be50e8ce336a0d011432bf5f101f89..4674993b38205270056ff1bde74370c8e21baab4 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 1134 2004-06-05 17:38:00Z twisti $
+   $Id: codegen.c 1266 2004-07-01 20:38:16Z twisti $
 
 */
 
 #include <signal.h>
 #include "types.h"
 #include "main.h"
-#include "codegen.h"
-#include "jit.h"
-#include "reg.h"
-#include "parse.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/jit.h"
+#include "jit/reg.h"
+#include "jit/parse.h"
 #include "builtin.h"
 #include "asmpart.h"
 #include "jni.h"
@@ -49,8 +50,8 @@
 #include "native.h"
 
 /* include independent code generation stuff */
-#include "codegen.inc"
-#include "reg.inc"
+#include "jit/codegen.inc"
+#include "jit/reg.inc"
 
 
 /* register descripton - array ************************************************/
@@ -80,123 +81,6 @@ int nregdescfloat[] = {
 };
 
 
-/* additional functions and macros to generate code ***************************/
-
-#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
-
-
-#ifdef STATISTICS
-#define COUNT_SPILLS count_spills++
-#else
-#define COUNT_SPILLS
-#endif
-
-
-#define CALCOFFSETBYTES(var, reg, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else if ((s4) (val) != 0) (var) += 1; \
-    else if ((reg) == RBP || (reg) == RSP || (reg) == R12 || (reg) == R13) (var) += 1;
-
-
-#define CALCIMMEDIATEBYTES(var, val) \
-    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
-    else (var) += 1;
-
-
-/* gen_nullptr_check(objreg) */
-
-#define gen_nullptr_check(objreg) \
-       if (checknull) { \
-        x86_64_test_reg_reg((objreg), (objreg)); \
-        x86_64_jcc(X86_64_CC_E, 0); \
-           codegen_addxnullrefs(mcodeptr); \
-       }
-
-
-#define gen_div_check(v) \
-    if (checknull) { \
-        if ((v)->flags & INMEMORY) { \
-            x86_64_alu_imm_membase(X86_64_CMP, 0, REG_SP, src->regoff * 8); \
-        } else { \
-            x86_64_test_reg_reg(src->regoff, src->regoff); \
-        } \
-        x86_64_jcc(X86_64_CC_E, 0); \
-        codegen_addxdivrefs(mcodeptr); \
-    }
-
-
-/* MCODECHECK(icnt) */
-
-#define MCODECHECK(icnt) \
-       if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
-
-/* M_INTMOVE:
-    generates an integer-move from register a to b.
-    if a and b are the same int-register, no code will be generated.
-*/ 
-
-#define M_INTMOVE(reg,dreg) \
-    if ((reg) != (dreg)) { \
-        x86_64_mov_reg_reg((reg),(dreg)); \
-    }
-
-
-/* M_FLTMOVE:
-    generates a floating-point-move from register a to b.
-    if a and b are the same float-register, no code will be generated
-*/ 
-
-#define M_FLTMOVE(reg,dreg) \
-    if ((reg) != (dreg)) { \
-        x86_64_movq_reg_reg((reg),(dreg)); \
-    }
-
-
-/* var_to_reg_xxx:
-    this function generates code to fetch data from a pseudo-register
-    into a real register. 
-    If the pseudo-register has actually been assigned to a real 
-    register, no code will be emitted, since following operations
-    can use this register directly.
-    
-    v: pseudoregister to be fetched from
-    tempregnum: temporary register to be used if v is actually spilled to ram
-
-    return: the register number, where the operand can be found after 
-            fetching (this wil be either tempregnum or the register
-            number allready given to v)
-*/
-
-#define var_to_reg_int(regnr,v,tempnr) \
-    if ((v)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        if ((v)->type == TYPE_INT) { \
-            x86_64_movl_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } else { \
-            x86_64_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } \
-        regnr = tempnr; \
-    } else { \
-        regnr = (v)->regoff; \
-    }
-
-
-
-#define var_to_reg_flt(regnr,v,tempnr) \
-    if ((v)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        if ((v)->type == TYPE_FLT) { \
-            x86_64_movlps_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } else { \
-            x86_64_movlpd_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
-        } \
-/*        x86_64_movq_membase_reg(REG_SP, (v)->regoff * 8, tempnr);*/ \
-        regnr = tempnr; \
-    } else { \
-        regnr = (v)->regoff; \
-    }
-
-
 /* reg_of_var:
     This function determines a register, to which the result of an operation
     should go, when it is ultimatively intended to store the result in
@@ -248,31 +132,6 @@ static int reg_of_var(stackptr v, int tempregnum)
 }
 
 
-/* store_reg_to_var_xxx:
-    This function generates the code to store the result of an operation
-    back into a spilled pseudo-variable.
-    If the pseudo-variable has not been spilled in the first place, this 
-    function will generate nothing.
-    
-    v ............ Pseudovariable
-    tempregnum ... Number of the temporary registers as returned by
-                   reg_of_var.
-*/     
-
-#define store_reg_to_var_int(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-        COUNT_SPILLS; \
-        x86_64_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
-    }
-
-
-#define store_reg_to_var_flt(sptr, tempregnum) \
-    if ((sptr)->flags & INMEMORY) { \
-         COUNT_SPILLS; \
-         x86_64_movq_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
-    }
-
-
 /* NullPointerException signal handler for hardware null pointer check */
 
 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
@@ -2170,13 +2029,6 @@ void codegen()
 
                /* memory operations **************************************************/
 
-#define gen_bound_check \
-    if (checkbounds) { \
-        x86_64_alul_membase_reg(X86_64_CMP, s1, OFFSET(java_arrayheader, size), s2); \
-        x86_64_jcc(X86_64_CC_AE, 0); \
-        codegen_addxboundrefs(mcodeptr, s2); \
-    }
-
                case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., (int) length        */
 
                        var_to_reg_int(s1, src, REG_ITMP1);
@@ -4083,1786 +3935,6 @@ void removenativestub(u1 *stub)
 }
 
 
-/* code generation functions */
-
-void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else if (s1 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_alul_reg_membase(alu_op, s1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alul_reg_reg(alu_op, s1, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
-                                               
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_reg_reg(alu_op, s2, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
-               }
-
-       } else {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, d);
-                       x86_64_alul_membase_reg(alu_op, REG_SP, s1 * 8, d);
-
-               } else {
-                       if (s2 == d) {
-                               x86_64_alul_reg_reg(alu_op, s1, d);
-
-                       } else {
-                               M_INTMOVE(s1, d);
-                               x86_64_alul_reg_reg(alu_op, s2, d);
-                       }
-               }
-       }
-}
-
-
-
-void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else if (s1 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       if (s2 == d) {
-                               x86_64_alu_reg_membase(alu_op, s1, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-                               x86_64_alu_reg_reg(alu_op, s1, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
-                                               
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alu_reg_reg(alu_op, s2, REG_ITMP1);
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
-               }
-
-       } else {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, d);
-                       x86_64_alu_membase_reg(alu_op, REG_SP, s1 * 8, d);
-
-               } else {
-                       if (s2 == d) {
-                               x86_64_alu_reg_reg(alu_op, s1, d);
-
-                       } else {
-                               M_INTMOVE(s1, d);
-                               x86_64_alu_reg_reg(alu_op, s2, d);
-                       }
-               }
-       }
-}
-
-
-
-void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if (src->flags & INMEMORY) {
-                       if (s1 == d) {
-                               x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                               x86_64_alul_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
-                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
-               }
-
-       } else {
-               if (src->flags & INMEMORY) {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
-
-               } else {
-                       M_INTMOVE(s1, d);
-                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
-               }
-       }
-}
-
-
-
-void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if (iptr->dst->flags & INMEMORY) {
-               if (src->flags & INMEMORY) {
-                       if (s1 == d) {
-                               if (x86_64_is_imm32(iptr->val.l)) {
-                                       x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
-
-                               } else {
-                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                                       x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-                               }
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-
-                               if (x86_64_is_imm32(iptr->val.l)) {
-                                       x86_64_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
-
-                               } else {
-                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP2);
-                                       x86_64_alu_reg_reg(alu_op, REG_ITMP2, REG_ITMP1);
-                               }
-                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-                       }
-
-               } else {
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-
-                       if (x86_64_is_imm32(iptr->val.l)) {
-                               x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
-                       }
-               }
-
-       } else {
-               if (src->flags & INMEMORY) {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-
-               } else {
-                       M_INTMOVE(s1, d);
-               }
-
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_reg(alu_op, iptr->val.l, d);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_reg(alu_op, REG_ITMP1, d);
-               }
-       }
-}
-
-
-
-void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
-                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
-                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
-               }
-               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-
-       } else {
-               if (d == RCX) {
-                       d = REG_ITMP3;
-               }
-                                       
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);    /* maybe src is RCX */
-                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shiftl_reg(shift_op, d);
-
-               } else {
-                       if (s1 == RCX) {
-                               M_INTMOVE(s1, d);
-                               M_INTMOVE(s2, RCX);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       x86_64_shiftl_reg(shift_op, d);
-               }
-
-               if (d == RCX) {
-                       M_INTMOVE(REG_ITMP3, RCX);
-
-               } else {
-                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-               }
-       }
-}
-
-
-
-void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
-       if (iptr->dst->flags & INMEMORY) {
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shift_reg(shift_op, REG_ITMP2);
-                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       if (s1 == d) {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
-
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
-                               x86_64_shift_reg(shift_op, REG_ITMP2);
-                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
-                       }
-
-               } else {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
-               }
-               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-
-       } else {
-               if (d == RCX) {
-                       d = REG_ITMP3;
-               }
-
-               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s1, d);    /* maybe src is RCX */
-                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-                       M_INTMOVE(s2, RCX);
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-                       x86_64_shift_reg(shift_op, d);
-
-               } else {
-                       if (s1 == RCX) {
-                               M_INTMOVE(s1, d);
-                               M_INTMOVE(s2, RCX);
-                       } else {
-                               M_INTMOVE(s2, RCX);
-                               M_INTMOVE(s1, d);
-                       }
-                       x86_64_shift_reg(shift_op, d);
-               }
-
-               if (d == RCX) {
-                       M_INTMOVE(REG_ITMP3, RCX);
-
-               } else {
-                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
-               }
-       }
-}
-
-
-
-void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               if (s1 == d) {
-                       x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-               } else {
-                       x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                       x86_64_shiftl_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
-                       x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
-               }
-
-       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
-               x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
-               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
-                               
-       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               x86_64_movl_reg_membase(s1, REG_SP, d * 8);
-               x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-       } else {
-               M_INTMOVE(s1, d);
-               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
-       }
-}
-
-
-
-void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-       s4 d = iptr->dst->regoff;
-
-       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               if (s1 == d) {
-                       x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-               } else {
-                       x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
-                       x86_64_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
-                       x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
-               }
-
-       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
-               x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
-               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
-                               
-       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
-               x86_64_mov_reg_membase(s1, REG_SP, d * 8);
-               x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
-
-       } else {
-               M_INTMOVE(s1, d);
-               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
-       }
-}
-
-
-
-void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       if (src->flags & INMEMORY) {
-               x86_64_alul_imm_membase(X86_64_CMP, iptr->val.i, REG_SP, src->regoff * 8);
-
-       } else {
-               x86_64_alul_imm_reg(X86_64_CMP, iptr->val.i, src->regoff);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->regoff;
-
-       if (src->flags & INMEMORY) {
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_membase(X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-               }
-
-       } else {
-               if (x86_64_is_imm32(iptr->val.l)) {
-                       x86_64_alu_imm_reg(X86_64_CMP, iptr->val.l, s1);
-
-               } else {
-                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
-                       x86_64_alu_reg_reg(X86_64_CMP, REG_ITMP1, s1);
-               }
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-
-       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-               x86_64_alul_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-
-       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-               x86_64_alul_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
-
-       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_alul_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
-
-       } else {
-               x86_64_alul_reg_reg(X86_64_CMP, s2, s1);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr)
-{
-       s4 s1 = src->prev->regoff;
-       s4 s2 = src->regoff;
-
-       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
-               x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
-
-       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
-               x86_64_alu_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
-
-       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
-               x86_64_alu_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
-
-       } else {
-               x86_64_alu_reg_reg(X86_64_CMP, s2, s1);
-       }
-       x86_64_jcc(if_op, 0);
-       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
-}
-
-
-
-#if 1
-
-/*
- * mov ops
- */
-void x86_64_mov_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_mov_imm_reg(s8 imm, s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       x86_64_emit_imm64((imm));
-}
-
-
-void x86_64_movl_imm_reg(s8 imm, s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-/*
- * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
- * constant membase immediate length of 32bit
- */
-void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_address_byte(2, (reg), (basereg));
-       x86_64_emit_imm32((disp));
-}
-
-
-void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x8b;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x89;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x88;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xc7;
-       x86_64_emit_membase((basereg),(disp),0);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xc7;
-       x86_64_emit_membase((basereg),(disp),0);
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_movsbq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movswq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movslq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x63;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x63;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movzwq_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       /* XXX: why do reg and dreg have to be exchanged */
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbf;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xbe;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
-       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xb7;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-
-/*
- * alu operations
- */
-void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 1;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 3;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = (((opc)) << 3) + 3;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(1,(basereg),0,0);
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(basereg),0,0);
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if (x86_64_is_imm8(imm)) {
-               x86_64_emit_rex(0,(basereg),0,0);
-               *(mcodeptr++) = 0x83;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(basereg),0,0);
-               *(mcodeptr++) = 0x81;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_test_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x85;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_testl_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x85;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_test_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_testw_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0x66;
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm16((imm));
-}
-
-
-void x86_64_testb_imm_reg(s8 imm, s8 reg) {
-       *(mcodeptr++) = 0xf6;
-       x86_64_emit_reg(0,(reg));
-       x86_64_emit_imm8((imm));
-}
-
-
-void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(1,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8d;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg) {
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x8d;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-
-/*
- * inc, dec operations
- */
-void x86_64_inc_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(0,(reg));
-}
-
-
-void x86_64_incl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(0,(reg));
-}
-
-
-void x86_64_inc_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_incl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_dec_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(1,(reg));
-}
-
-        
-void x86_64_decl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(1,(reg));
-}
-
-        
-void x86_64_dec_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),1);
-}
-
-
-void x86_64_decl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,(basereg),0,0);
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_membase((basereg),(disp),1);
-}
-
-
-
-
-void x86_64_cltd() {
-    *(mcodeptr++) = 0x99;
-}
-
-
-void x86_64_cqto() {
-       x86_64_emit_rex(1,0,0,0);
-       *(mcodeptr++) = 0x99;
-}
-
-
-
-void x86_64_imul_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_imull_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xaf;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_imul_imm_reg(s8 imm, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg(0,(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg(0,(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imul_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,(dreg),0,(reg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(dreg),0,(reg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(0,(dreg),0,(reg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(dreg),0,(reg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_reg((dreg),(reg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(1,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(1,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
-       if (x86_64_is_imm8((imm))) {
-               x86_64_emit_rex(0,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x6b;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm8((imm));
-       } else {
-               x86_64_emit_rex(0,(dreg),0,(basereg));
-               *(mcodeptr++) = 0x69;
-               x86_64_emit_membase((basereg),(disp),(dreg));
-               x86_64_emit_imm32((imm));
-       }
-}
-
-
-void x86_64_idiv_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(7,(reg));
-}
-
-
-void x86_64_idivl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(7,(reg));
-}
-
-
-
-void x86_64_ret() {
-    *(mcodeptr++) = 0xc3;
-}
-
-
-
-/*
- * shift ops
- */
-void x86_64_shift_reg(s8 opc, s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_reg((opc),(reg));
-}
-
-
-void x86_64_shiftl_reg(s8 opc, s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_reg((opc),(reg));
-}
-
-
-void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_membase((basereg),(disp),(opc));
-}
-
-
-void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xd3;
-       x86_64_emit_membase((basereg),(disp),(opc));
-}
-
-
-void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_reg((opc),(dreg));
-       } else {
-               x86_64_emit_rex(1,0,0,(dreg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_reg((opc),(dreg));
-       } else {
-               x86_64_emit_rex(0,0,0,(dreg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_reg((opc),(dreg));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(1,0,0,(basereg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-       } else {
-               x86_64_emit_rex(1,0,0,(basereg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
-       if ((imm) == 1) {
-               x86_64_emit_rex(0,0,0,(basereg));
-               *(mcodeptr++) = 0xd1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-       } else {
-               x86_64_emit_rex(0,0,0,(basereg));
-               *(mcodeptr++) = 0xc1;
-               x86_64_emit_membase((basereg),(disp),(opc));
-               x86_64_emit_imm8((imm));
-       }
-}
-
-
-
-/*
- * jump operations
- */
-void x86_64_jmp_imm(s8 imm) {
-       *(mcodeptr++) = 0xe9;
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_jmp_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(4,(reg));
-}
-
-
-void x86_64_jcc(s8 opc, s8 imm) {
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x80 + (opc));
-       x86_64_emit_imm32((imm));
-}
-
-
-
-/*
- * conditional set and move operations
- */
-
-/* we need the rex byte to get all low bytes */
-void x86_64_setcc_reg(s8 opc, s8 reg) {
-       *(mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x90 + (opc));
-       x86_64_emit_reg(0,(reg));
-}
-
-
-/* we need the rex byte to get all low bytes */
-void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp) {
-       *(mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x90 + (opc));
-       x86_64_emit_membase((basereg),(disp),0);
-}
-
-
-void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x40 + (opc));
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = (0x40 + (opc));
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-
-void x86_64_neg_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(3,(reg));
-}
-
-
-void x86_64_negl_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_reg(3,(reg));
-}
-
-
-void x86_64_neg_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(1,0,0,(basereg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_membase((basereg),(disp),3);
-}
-
-
-void x86_64_negl_membase(s8 basereg, s8 disp) {
-       x86_64_emit_rex(0,0,0,(basereg));
-       *(mcodeptr++) = 0xf7;
-       x86_64_emit_membase((basereg),(disp),3);
-}
-
-
-
-void x86_64_push_imm(s8 imm) {
-       *(mcodeptr++) = 0x68;
-       x86_64_emit_imm32((imm));
-}
-
-
-void x86_64_pop_reg(s8 reg) {
-       x86_64_emit_rex(0,0,0,(reg));
-       *(mcodeptr++) = 0x58 + (0x07 & (reg));
-}
-
-
-void x86_64_xchg_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(1,(reg),0,(dreg));
-       *(mcodeptr++) = 0x87;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_nop() {
-    *(mcodeptr++) = 0x90;
-}
-
-
-
-/*
- * call instructions
- */
-void x86_64_call_reg(s8 reg) {
-       x86_64_emit_rex(1,0,0,(reg));
-       *(mcodeptr++) = 0xff;
-       x86_64_emit_reg(2,(reg));
-}
-
-
-void x86_64_call_imm(s8 imm) {
-       *(mcodeptr++) = 0xe8;
-       x86_64_emit_imm32((imm));
-}
-
-
-
-/*
- * floating point instructions (SSE2)
- */
-void x86_64_addsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x58;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_addss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x58;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5a;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(1,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_divss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_divsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movd_reg_freg(s8 reg, s8 freg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(freg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_reg((freg),(reg));
-}
-
-
-void x86_64_movd_freg_reg(s8 freg, s8 reg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(freg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_reg((freg),(reg));
-}
-
-
-void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(1,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x6e;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movq_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0xd6;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x7e;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_movsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),0,(dreg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_reg((reg),(dreg));
-}
-
-
-void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_membase((basereg),(disp),(reg));
-}
-
-
-void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x12;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x12;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x11;
-       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x10;
-       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
-}
-
-
-void x86_64_mulss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x59;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_mulsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x59;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_subss_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf3;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_subsd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0xf2;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x5c;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x2e;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorps_reg_reg(s8 reg, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-
-void x86_64_xorpd_reg_reg(s8 reg, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(reg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_reg((dreg),(reg));
-}
-
-
-void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
-       *(mcodeptr++) = 0x66;
-       x86_64_emit_rex(0,(dreg),0,(basereg));
-       *(mcodeptr++) = 0x0f;
-       *(mcodeptr++) = 0x57;
-       x86_64_emit_membase((basereg),(disp),(dreg));
-}
-
-#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
index 54af3350c42e9aa54b885f95346810aee26229bb..5e6be38965a5dc3cabb35ba19c3d35a0f0e56661 100644 (file)
@@ -1,4 +1,4 @@
-/* jit/i386/codegen.h - code generation macros and definitions for x86_64
+/* jit/x86_64/codegen.h - code generation macros and definitions for x86_64
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
@@ -27,7 +27,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.h 928 2004-02-26 00:18:36Z twisti $
+   $Id: codegen.h 1266 2004-07-01 20:38:16Z twisti $
 
 */
 
@@ -35,7 +35,7 @@
 #ifndef _CODEGEN_H
 #define _CODEGEN_H
 
-#include "jit.h"
+#include "jit/jit.h"
 
 
 /* x86_64 register numbers */
@@ -303,165 +303,154 @@ typedef enum {
     } while (0)
 
 
-/* code generation prototypes */
-
-void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr);
-void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr);
-void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr);
-void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr);
-
-
-/* integer instructions */
-
-void x86_64_mov_reg_reg(s8 reg, s8 dreg);
-void x86_64_mov_imm_reg(s8 imm, s8 reg);
-void x86_64_movl_imm_reg(s8 imm, s8 reg);
-void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp);
-void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp);
-void x86_64_movsbq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movswq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movslq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movzwq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
-void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
-void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
-void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
-void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
-void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_test_reg_reg(s8 reg, s8 dreg);
-void x86_64_testl_reg_reg(s8 reg, s8 dreg);
-void x86_64_test_imm_reg(s8 imm, s8 reg);
-void x86_64_testw_imm_reg(s8 imm, s8 reg);
-void x86_64_testb_imm_reg(s8 imm, s8 reg);
-void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg);
-void x86_64_inc_reg(s8 reg);
-void x86_64_incl_reg(s8 reg);
-void x86_64_inc_membase(s8 basereg, s8 disp);
-void x86_64_incl_membase(s8 basereg, s8 disp);
-void x86_64_dec_reg(s8 reg);
-void x86_64_decl_reg(s8 reg);
-void x86_64_dec_membase(s8 basereg, s8 disp);
-void x86_64_decl_membase(s8 basereg, s8 disp);
-void x86_64_cltd();
-void x86_64_cqto();
-void x86_64_imul_reg_reg(s8 reg, s8 dreg);
-void x86_64_imull_reg_reg(s8 reg, s8 dreg);
-void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_imul_imm_reg(s8 imm, s8 dreg);
-void x86_64_imul_imm_reg_reg(s8 imm,s8 reg, s8 dreg);
-void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg);
-void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
-void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
-void x86_64_idiv_reg(s8 reg);
-void x86_64_idivl_reg(s8 reg);
-void x86_64_ret();
-void x86_64_shift_reg(s8 opc, s8 reg);
-void x86_64_shiftl_reg(s8 opc, s8 reg);
-void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg);
-void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
-void x86_64_jmp_imm(s8 imm);
-void x86_64_jmp_reg(s8 reg);
-void x86_64_jcc(s8 opc, s8 imm);
-void x86_64_setcc_reg(s8 opc, s8 reg);
-void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp);
-void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg);
-void x86_64_neg_reg(s8 reg);
-void x86_64_negl_reg(s8 reg);
-void x86_64_neg_membase(s8 basereg, s8 disp);
-void x86_64_negl_membase(s8 basereg, s8 disp);
-void x86_64_push_imm(s8 imm);
-void x86_64_pop_reg(s8 reg);
-void x86_64_xchg_reg_reg(s8 reg, s8 dreg);
-void x86_64_nop();
-void x86_64_call_reg(s8 reg);
-void x86_64_call_imm(s8 imm);
-
-
-/* floating point instructions (SSE2) */
-
-void x86_64_addsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_addss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg);
-void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg);
-void x86_64_divss_reg_reg(s8 reg, s8 dreg);
-void x86_64_divsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_movd_reg_freg(s8 reg, s8 freg);
-void x86_64_movd_freg_reg(s8 freg, s8 reg);
-void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_movq_reg_reg(s8 reg, s8 dreg);
-void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movss_reg_reg(s8 reg, s8 dreg);
-void x86_64_movsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp);
-void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
-void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
-void x86_64_mulss_reg_reg(s8 reg, s8 dreg);
-void x86_64_mulsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_subss_reg_reg(s8 reg, s8 dreg);
-void x86_64_subsd_reg_reg(s8 reg, s8 dreg);
-void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg);
-void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorps_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg);
-void x86_64_xorpd_reg_reg(s8 reg, s8 dreg);
-void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+/* additional functions and macros to generate code ***************************/
+
+#define BlockPtrOfPC(pc)  ((basicblock *) iptr->target)
+
+
+#ifdef STATISTICS
+#define COUNT_SPILLS count_spills++
+#else
+#define COUNT_SPILLS
+#endif
+
+
+#define CALCOFFSETBYTES(var, reg, val) \
+    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
+    else if ((s4) (val) != 0) (var) += 1; \
+    else if ((reg) == RBP || (reg) == RSP || (reg) == R12 || (reg) == R13) (var) += 1;
+
+
+#define CALCIMMEDIATEBYTES(var, val) \
+    if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
+    else (var) += 1;
+
+
+/* gen_nullptr_check(objreg) */
+
+#define gen_nullptr_check(objreg) \
+       if (checknull) { \
+        x86_64_test_reg_reg((objreg), (objreg)); \
+        x86_64_jcc(X86_64_CC_E, 0); \
+           codegen_addxnullrefs(mcodeptr); \
+       }
+
+
+#define gen_bound_check \
+    if (checkbounds) { \
+        x86_64_alul_membase_reg(X86_64_CMP, s1, OFFSET(java_arrayheader, size), s2); \
+        x86_64_jcc(X86_64_CC_AE, 0); \
+        codegen_addxboundrefs(mcodeptr, s2); \
+    }
+
+
+#define gen_div_check(v) \
+    if (checknull) { \
+        if ((v)->flags & INMEMORY) { \
+            x86_64_alu_imm_membase(X86_64_CMP, 0, REG_SP, src->regoff * 8); \
+        } else { \
+            x86_64_test_reg_reg(src->regoff, src->regoff); \
+        } \
+        x86_64_jcc(X86_64_CC_E, 0); \
+        codegen_addxdivrefs(mcodeptr); \
+    }
+
+
+/* MCODECHECK(icnt) */
+
+#define MCODECHECK(icnt) \
+       if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
+
+/* M_INTMOVE:
+    generates an integer-move from register a to b.
+    if a and b are the same int-register, no code will be generated.
+*/ 
+
+#define M_INTMOVE(reg,dreg) \
+    if ((reg) != (dreg)) { \
+        x86_64_mov_reg_reg((reg),(dreg)); \
+    }
+
+
+/* M_FLTMOVE:
+    generates a floating-point-move from register a to b.
+    if a and b are the same float-register, no code will be generated
+*/ 
+
+#define M_FLTMOVE(reg,dreg) \
+    if ((reg) != (dreg)) { \
+        x86_64_movq_reg_reg((reg),(dreg)); \
+    }
+
+
+/* var_to_reg_xxx:
+    this function generates code to fetch data from a pseudo-register
+    into a real register. 
+    If the pseudo-register has actually been assigned to a real 
+    register, no code will be emitted, since following operations
+    can use this register directly.
+    
+    v: pseudoregister to be fetched from
+    tempregnum: temporary register to be used if v is actually spilled to ram
+
+    return: the register number, where the operand can be found after 
+            fetching (this wil be either tempregnum or the register
+            number allready given to v)
+*/
+
+#define var_to_reg_int(regnr,v,tempnr) \
+    if ((v)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        if ((v)->type == TYPE_INT) { \
+            x86_64_movl_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } else { \
+            x86_64_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } \
+        regnr = tempnr; \
+    } else { \
+        regnr = (v)->regoff; \
+    }
+
+
+
+#define var_to_reg_flt(regnr,v,tempnr) \
+    if ((v)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        if ((v)->type == TYPE_FLT) { \
+            x86_64_movlps_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } else { \
+            x86_64_movlpd_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
+        } \
+/*        x86_64_movq_membase_reg(REG_SP, (v)->regoff * 8, tempnr);*/ \
+        regnr = tempnr; \
+    } else { \
+        regnr = (v)->regoff; \
+    }
+
+
+/* store_reg_to_var_xxx:
+    This function generates the code to store the result of an operation
+    back into a spilled pseudo-variable.
+    If the pseudo-variable has not been spilled in the first place, this 
+    function will generate nothing.
+    
+    v ............ Pseudovariable
+    tempregnum ... Number of the temporary registers as returned by
+                   reg_of_var.
+*/     
+
+#define store_reg_to_var_int(sptr, tempregnum) \
+    if ((sptr)->flags & INMEMORY) { \
+        COUNT_SPILLS; \
+        x86_64_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
+    }
+
+
+#define store_reg_to_var_flt(sptr, tempregnum) \
+    if ((sptr)->flags & INMEMORY) { \
+         COUNT_SPILLS; \
+         x86_64_movq_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
+    }
 
 
 /* function gen_resolvebranch **************************************************
@@ -486,6 +475,8 @@ void codegen();
 void codegen_close();
 void dseg_display(s4 *s4ptr);
 
+void codegen_addreference(basicblock *target, void *branchptr);
+
 #endif /* _CODEGEN_H */
 
 
@@ -501,4 +492,3 @@ void dseg_display(s4 *s4ptr);
  * tab-width: 4
  * End:
  */
-
diff --git a/src/vm/jit/x86_64/emitfuncs.c b/src/vm/jit/x86_64/emitfuncs.c
new file mode 100644 (file)
index 0000000..e5b9976
--- /dev/null
@@ -0,0 +1,1828 @@
+/* jit/x86_64/emitfuncs.c - x86_64 code emitter functions
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Institut f. Computersprachen, TU Wien
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
+   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
+   J. Wenninger
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Christian Thalinger
+
+   $Id: emitfuncs.c 1266 2004-07-01 20:38:16Z twisti $
+
+*/
+
+
+#include "jit/jit.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/types.h"
+
+
+/* code generation functions */
+
+void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else if (s1 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alul_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_alul_reg_membase(alu_op, s1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alul_reg_reg(alu_op, s1, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
+                                               
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_reg_reg(alu_op, s2, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alul_reg_membase(alu_op, s2, REG_SP, d * 8);
+               }
+
+       } else {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, d);
+                       x86_64_alul_membase_reg(alu_op, REG_SP, s1 * 8, d);
+
+               } else {
+                       if (s2 == d) {
+                               x86_64_alul_reg_reg(alu_op, s1, d);
+
+                       } else {
+                               M_INTMOVE(s1, d);
+                               x86_64_alul_reg_reg(alu_op, s2, d);
+                       }
+               }
+       }
+}
+
+
+
+void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else if (s1 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       if (s2 == d) {
+                               x86_64_alu_reg_membase(alu_op, s1, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+                               x86_64_alu_reg_reg(alu_op, s1, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
+                                               
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alu_reg_reg(alu_op, s2, REG_ITMP1);
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alu_reg_membase(alu_op, s2, REG_SP, d * 8);
+               }
+
+       } else {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s2 * 8, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, d);
+                       x86_64_alu_membase_reg(alu_op, REG_SP, s1 * 8, d);
+
+               } else {
+                       if (s2 == d) {
+                               x86_64_alu_reg_reg(alu_op, s1, d);
+
+                       } else {
+                               M_INTMOVE(s1, d);
+                               x86_64_alu_reg_reg(alu_op, s2, d);
+                       }
+               }
+       }
+}
+
+
+
+void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if (src->flags & INMEMORY) {
+                       if (s1 == d) {
+                               x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                               x86_64_alul_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
+                               x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_alul_imm_membase(alu_op, iptr->val.i, REG_SP, d * 8);
+               }
+
+       } else {
+               if (src->flags & INMEMORY) {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
+
+               } else {
+                       M_INTMOVE(s1, d);
+                       x86_64_alul_imm_reg(alu_op, iptr->val.i, d);
+               }
+       }
+}
+
+
+
+void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if (iptr->dst->flags & INMEMORY) {
+               if (src->flags & INMEMORY) {
+                       if (s1 == d) {
+                               if (x86_64_is_imm32(iptr->val.l)) {
+                                       x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
+
+                               } else {
+                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                                       x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+                               }
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+
+                               if (x86_64_is_imm32(iptr->val.l)) {
+                                       x86_64_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
+
+                               } else {
+                                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP2);
+                                       x86_64_alu_reg_reg(alu_op, REG_ITMP2, REG_ITMP1);
+                               }
+                               x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+                       }
+
+               } else {
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+
+                       if (x86_64_is_imm32(iptr->val.l)) {
+                               x86_64_alu_imm_membase(alu_op, iptr->val.l, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                               x86_64_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, d * 8);
+                       }
+               }
+
+       } else {
+               if (src->flags & INMEMORY) {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+
+               } else {
+                       M_INTMOVE(s1, d);
+               }
+
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_reg(alu_op, iptr->val.l, d);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_reg(alu_op, REG_ITMP1, d);
+               }
+       }
+}
+
+
+
+void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
+                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shiftl_reg(shift_op, REG_ITMP2);
+                               x86_64_movl_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shiftl_membase(shift_op, REG_SP, d * 8);
+               }
+               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+
+       } else {
+               if (d == RCX) {
+                       d = REG_ITMP3;
+               }
+                                       
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);    /* maybe src is RCX */
+                       x86_64_movl_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shiftl_reg(shift_op, d);
+
+               } else {
+                       if (s1 == RCX) {
+                               M_INTMOVE(s1, d);
+                               M_INTMOVE(s2, RCX);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               M_INTMOVE(s1, d);
+                       }
+                       x86_64_shiftl_reg(shift_op, d);
+               }
+
+               if (d == RCX) {
+                       M_INTMOVE(REG_ITMP3, RCX);
+
+               } else {
+                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+               }
+       }
+}
+
+
+
+void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       M_INTMOVE(RCX, REG_ITMP1);    /* save RCX */
+       if (iptr->dst->flags & INMEMORY) {
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shift_reg(shift_op, REG_ITMP2);
+                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       if (s1 == d) {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_shift_membase(shift_op, REG_SP, d * 8);
+
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP2);
+                               x86_64_shift_reg(shift_op, REG_ITMP2);
+                               x86_64_mov_reg_membase(REG_ITMP2, REG_SP, d * 8);
+                       }
+
+               } else {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+                       x86_64_shift_membase(shift_op, REG_SP, d * 8);
+               }
+               M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+
+       } else {
+               if (d == RCX) {
+                       d = REG_ITMP3;
+               }
+
+               if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s1, d);    /* maybe src is RCX */
+                       x86_64_mov_membase_reg(REG_SP, s2 * 8, RCX);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+                       M_INTMOVE(s2, RCX);
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+                       x86_64_shift_reg(shift_op, d);
+
+               } else {
+                       if (s1 == RCX) {
+                               M_INTMOVE(s1, d);
+                               M_INTMOVE(s2, RCX);
+                       } else {
+                               M_INTMOVE(s2, RCX);
+                               M_INTMOVE(s1, d);
+                       }
+                       x86_64_shift_reg(shift_op, d);
+               }
+
+               if (d == RCX) {
+                       M_INTMOVE(REG_ITMP3, RCX);
+
+               } else {
+                       M_INTMOVE(REG_ITMP1, RCX);    /* restore RCX */
+               }
+       }
+}
+
+
+
+void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               if (s1 == d) {
+                       x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+               } else {
+                       x86_64_movl_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                       x86_64_shiftl_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
+                       x86_64_movl_reg_membase(REG_ITMP1, REG_SP, d * 8);
+               }
+
+       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
+               x86_64_movl_membase_reg(REG_SP, s1 * 8, d);
+               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
+                               
+       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               x86_64_movl_reg_membase(s1, REG_SP, d * 8);
+               x86_64_shiftl_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+       } else {
+               M_INTMOVE(s1, d);
+               x86_64_shiftl_imm_reg(shift_op, iptr->val.i, d);
+       }
+}
+
+
+
+void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+       s4 d = iptr->dst->regoff;
+
+       if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               if (s1 == d) {
+                       x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+               } else {
+                       x86_64_mov_membase_reg(REG_SP, s1 * 8, REG_ITMP1);
+                       x86_64_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
+                       x86_64_mov_reg_membase(REG_ITMP1, REG_SP, d * 8);
+               }
+
+       } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
+               x86_64_mov_membase_reg(REG_SP, s1 * 8, d);
+               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
+                               
+       } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
+               x86_64_mov_reg_membase(s1, REG_SP, d * 8);
+               x86_64_shift_imm_membase(shift_op, iptr->val.i, REG_SP, d * 8);
+
+       } else {
+               M_INTMOVE(s1, d);
+               x86_64_shift_imm_reg(shift_op, iptr->val.i, d);
+       }
+}
+
+
+
+void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       if (src->flags & INMEMORY) {
+               x86_64_alul_imm_membase(X86_64_CMP, iptr->val.i, REG_SP, src->regoff * 8);
+
+       } else {
+               x86_64_alul_imm_reg(X86_64_CMP, iptr->val.i, src->regoff);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->regoff;
+
+       if (src->flags & INMEMORY) {
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_membase(X86_64_CMP, iptr->val.l, REG_SP, s1 * 8);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+               }
+
+       } else {
+               if (x86_64_is_imm32(iptr->val.l)) {
+                       x86_64_alu_imm_reg(X86_64_CMP, iptr->val.l, s1);
+
+               } else {
+                       x86_64_mov_imm_reg(iptr->val.l, REG_ITMP1);
+                       x86_64_alu_reg_reg(X86_64_CMP, REG_ITMP1, s1);
+               }
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+
+       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_movl_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+               x86_64_alul_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+
+       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               x86_64_alul_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
+
+       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_alul_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
+
+       } else {
+               x86_64_alul_reg_reg(X86_64_CMP, s2, s1);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+
+void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr)
+{
+       s4 s1 = src->prev->regoff;
+       s4 s2 = src->regoff;
+
+       if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_mov_membase_reg(REG_SP, s2 * 8, REG_ITMP1);
+               x86_64_alu_reg_membase(X86_64_CMP, REG_ITMP1, REG_SP, s1 * 8);
+
+       } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
+               x86_64_alu_membase_reg(X86_64_CMP, REG_SP, s2 * 8, s1);
+
+       } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
+               x86_64_alu_reg_membase(X86_64_CMP, s2, REG_SP, s1 * 8);
+
+       } else {
+               x86_64_alu_reg_reg(X86_64_CMP, s2, s1);
+       }
+       x86_64_jcc(if_op, 0);
+       codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
+}
+
+
+/*
+ * mov ops
+ */
+void x86_64_mov_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_mov_imm_reg(s8 imm, s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
+       x86_64_emit_imm64((imm));
+}
+
+
+void x86_64_movl_imm_reg(s8 imm, s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xb8 + ((reg) & 0x07);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+/*
+ * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
+ * constant membase immediate length of 32bit
+ */
+void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_address_byte(2, (reg), (basereg));
+       x86_64_emit_imm32((disp));
+}
+
+
+void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x8b;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x89;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x88;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xc7;
+       x86_64_emit_membase((basereg),(disp),0);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xc7;
+       x86_64_emit_membase((basereg),(disp),0);
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_movsbq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movswq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movslq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x63;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x63;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movzwq_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       /* XXX: why do reg and dreg have to be exchanged */
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbf;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xbe;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) {
+       x86_64_emit_rex(1,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xb7;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+
+/*
+ * alu operations
+ */
+void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 1;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 3;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = (((opc)) << 3) + 3;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(1,(basereg),0,0);
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(basereg),0,0);
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if (x86_64_is_imm8(imm)) {
+               x86_64_emit_rex(0,(basereg),0,0);
+               *(mcodeptr++) = 0x83;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(basereg),0,0);
+               *(mcodeptr++) = 0x81;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_test_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x85;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_testl_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x85;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_test_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_testw_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0x66;
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm16((imm));
+}
+
+
+void x86_64_testb_imm_reg(s8 imm, s8 reg) {
+       *(mcodeptr++) = 0xf6;
+       x86_64_emit_reg(0,(reg));
+       x86_64_emit_imm8((imm));
+}
+
+
+void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(1,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8d;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg) {
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x8d;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+
+/*
+ * inc, dec operations
+ */
+void x86_64_inc_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(0,(reg));
+}
+
+
+void x86_64_incl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(0,(reg));
+}
+
+
+void x86_64_inc_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_incl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_dec_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(1,(reg));
+}
+
+        
+void x86_64_decl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(1,(reg));
+}
+
+        
+void x86_64_dec_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),1);
+}
+
+
+void x86_64_decl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,(basereg),0,0);
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_membase((basereg),(disp),1);
+}
+
+
+
+
+void x86_64_cltd() {
+    *(mcodeptr++) = 0x99;
+}
+
+
+void x86_64_cqto() {
+       x86_64_emit_rex(1,0,0,0);
+       *(mcodeptr++) = 0x99;
+}
+
+
+
+void x86_64_imul_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_imull_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xaf;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_imul_imm_reg(s8 imm, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg(0,(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg(0,(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imul_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,(dreg),0,(reg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(dreg),0,(reg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(0,(dreg),0,(reg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(dreg),0,(reg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_reg((dreg),(reg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(1,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(1,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg) {
+       if (x86_64_is_imm8((imm))) {
+               x86_64_emit_rex(0,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x6b;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm8((imm));
+       } else {
+               x86_64_emit_rex(0,(dreg),0,(basereg));
+               *(mcodeptr++) = 0x69;
+               x86_64_emit_membase((basereg),(disp),(dreg));
+               x86_64_emit_imm32((imm));
+       }
+}
+
+
+void x86_64_idiv_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(7,(reg));
+}
+
+
+void x86_64_idivl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(7,(reg));
+}
+
+
+
+void x86_64_ret() {
+    *(mcodeptr++) = 0xc3;
+}
+
+
+
+/*
+ * shift ops
+ */
+void x86_64_shift_reg(s8 opc, s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_reg((opc),(reg));
+}
+
+
+void x86_64_shiftl_reg(s8 opc, s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_reg((opc),(reg));
+}
+
+
+void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_membase((basereg),(disp),(opc));
+}
+
+
+void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xd3;
+       x86_64_emit_membase((basereg),(disp),(opc));
+}
+
+
+void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_reg((opc),(dreg));
+       } else {
+               x86_64_emit_rex(1,0,0,(dreg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_reg((opc),(dreg));
+       } else {
+               x86_64_emit_rex(0,0,0,(dreg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_reg((opc),(dreg));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(1,0,0,(basereg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+       } else {
+               x86_64_emit_rex(1,0,0,(basereg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp) {
+       if ((imm) == 1) {
+               x86_64_emit_rex(0,0,0,(basereg));
+               *(mcodeptr++) = 0xd1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+       } else {
+               x86_64_emit_rex(0,0,0,(basereg));
+               *(mcodeptr++) = 0xc1;
+               x86_64_emit_membase((basereg),(disp),(opc));
+               x86_64_emit_imm8((imm));
+       }
+}
+
+
+
+/*
+ * jump operations
+ */
+void x86_64_jmp_imm(s8 imm) {
+       *(mcodeptr++) = 0xe9;
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_jmp_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(4,(reg));
+}
+
+
+void x86_64_jcc(s8 opc, s8 imm) {
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x80 + (opc));
+       x86_64_emit_imm32((imm));
+}
+
+
+
+/*
+ * conditional set and move operations
+ */
+
+/* we need the rex byte to get all low bytes */
+void x86_64_setcc_reg(s8 opc, s8 reg) {
+       *(mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x90 + (opc));
+       x86_64_emit_reg(0,(reg));
+}
+
+
+/* we need the rex byte to get all low bytes */
+void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp) {
+       *(mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x90 + (opc));
+       x86_64_emit_membase((basereg),(disp),0);
+}
+
+
+void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x40 + (opc));
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = (0x40 + (opc));
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+
+void x86_64_neg_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(3,(reg));
+}
+
+
+void x86_64_negl_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_reg(3,(reg));
+}
+
+
+void x86_64_neg_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(1,0,0,(basereg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_membase((basereg),(disp),3);
+}
+
+
+void x86_64_negl_membase(s8 basereg, s8 disp) {
+       x86_64_emit_rex(0,0,0,(basereg));
+       *(mcodeptr++) = 0xf7;
+       x86_64_emit_membase((basereg),(disp),3);
+}
+
+
+
+void x86_64_push_imm(s8 imm) {
+       *(mcodeptr++) = 0x68;
+       x86_64_emit_imm32((imm));
+}
+
+
+void x86_64_pop_reg(s8 reg) {
+       x86_64_emit_rex(0,0,0,(reg));
+       *(mcodeptr++) = 0x58 + (0x07 & (reg));
+}
+
+
+void x86_64_xchg_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(1,(reg),0,(dreg));
+       *(mcodeptr++) = 0x87;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_nop() {
+    *(mcodeptr++) = 0x90;
+}
+
+
+
+/*
+ * call instructions
+ */
+void x86_64_call_reg(s8 reg) {
+       x86_64_emit_rex(1,0,0,(reg));
+       *(mcodeptr++) = 0xff;
+       x86_64_emit_reg(2,(reg));
+}
+
+
+void x86_64_call_imm(s8 imm) {
+       *(mcodeptr++) = 0xe8;
+       x86_64_emit_imm32((imm));
+}
+
+
+
+/*
+ * floating point instructions (SSE2)
+ */
+void x86_64_addsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x58;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_addss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x58;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5a;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(1,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_divss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_divsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movd_reg_freg(s8 reg, s8 freg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(freg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_reg((freg),(reg));
+}
+
+
+void x86_64_movd_freg_reg(s8 freg, s8 reg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(freg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_reg((freg),(reg));
+}
+
+
+void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(1,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x6e;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movq_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0xd6;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x7e;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_movsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),0,(dreg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_reg((reg),(dreg));
+}
+
+
+void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_membase((basereg),(disp),(reg));
+}
+
+
+void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x12;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x12;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(reg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x11;
+       x86_64_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),(indexreg),(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x10;
+       x86_64_emit_memindex((dreg),(disp),(basereg),(indexreg),(scale));
+}
+
+
+void x86_64_mulss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x59;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_mulsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x59;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_subss_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf3;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_subsd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0xf2;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x5c;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x2e;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorps_reg_reg(s8 reg, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+void x86_64_xorpd_reg_reg(s8 reg, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(reg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_reg((dreg),(reg));
+}
+
+
+void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg) {
+       *(mcodeptr++) = 0x66;
+       x86_64_emit_rex(0,(dreg),0,(basereg));
+       *(mcodeptr++) = 0x0f;
+       *(mcodeptr++) = 0x57;
+       x86_64_emit_membase((basereg),(disp),(dreg));
+}
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/src/vm/jit/x86_64/emitfuncs.h b/src/vm/jit/x86_64/emitfuncs.h
new file mode 100644 (file)
index 0000000..1039e01
--- /dev/null
@@ -0,0 +1,218 @@
+/* jit/x86_64/emitfuncs.h - emit function prototypes
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
+   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
+   P. Tomsich, J. Wenninger
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Andreas Krall
+            Christian Thalinger
+
+   $Id: emitfuncs.h 1266 2004-07-01 20:38:16Z twisti $
+
+*/
+
+
+#ifndef _EMITFUNCS_H
+#define _EMITFUNCS_H
+
+#include "jit/x86_64/types.h"
+
+
+extern u1 *mcodeptr;
+
+
+/* code generation prototypes */
+
+void x86_64_emit_ialu(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_lalu(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr);
+void x86_64_emit_ishift(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_lshift(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_lshiftconst(s4 shift_op, stackptr src, instruction *iptr);
+void x86_64_emit_ifcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_lcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_icmpcc(s4 if_op, stackptr src, instruction *iptr);
+void x86_64_emit_if_lcmpcc(s4 if_op, stackptr src, instruction *iptr);
+
+
+/* integer instructions */
+
+void x86_64_mov_reg_reg(s8 reg, s8 dreg);
+void x86_64_mov_imm_reg(s8 imm, s8 reg);
+void x86_64_movl_imm_reg(s8 imm, s8 reg);
+void x86_64_mov_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_movl_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_mov_membase32_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_mov_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movl_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_mov_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movl_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_mov_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movl_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movw_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movb_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_mov_imm_membase(s8 imm, s8 basereg, s8 disp);
+void x86_64_movl_imm_membase(s8 imm, s8 basereg, s8 disp);
+void x86_64_movsbq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movsbq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movswq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movswq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movslq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movslq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movzwq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movzwq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movswq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movsbq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_movzwq_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
+void x86_64_alu_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_alul_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_alu_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
+void x86_64_alul_reg_membase(s8 opc, s8 reg, s8 basereg, s8 disp);
+void x86_64_alu_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
+void x86_64_alul_membase_reg(s8 opc, s8 basereg, s8 disp, s8 reg);
+void x86_64_alu_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_alul_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_alu_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_alul_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_test_reg_reg(s8 reg, s8 dreg);
+void x86_64_testl_reg_reg(s8 reg, s8 dreg);
+void x86_64_test_imm_reg(s8 imm, s8 reg);
+void x86_64_testw_imm_reg(s8 imm, s8 reg);
+void x86_64_testb_imm_reg(s8 imm, s8 reg);
+void x86_64_lea_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_leal_membase_reg(s8 basereg, s8 disp, s8 reg);
+void x86_64_inc_reg(s8 reg);
+void x86_64_incl_reg(s8 reg);
+void x86_64_inc_membase(s8 basereg, s8 disp);
+void x86_64_incl_membase(s8 basereg, s8 disp);
+void x86_64_dec_reg(s8 reg);
+void x86_64_decl_reg(s8 reg);
+void x86_64_dec_membase(s8 basereg, s8 disp);
+void x86_64_decl_membase(s8 basereg, s8 disp);
+void x86_64_cltd();
+void x86_64_cqto();
+void x86_64_imul_reg_reg(s8 reg, s8 dreg);
+void x86_64_imull_reg_reg(s8 reg, s8 dreg);
+void x86_64_imul_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_imull_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_imul_imm_reg(s8 imm, s8 dreg);
+void x86_64_imul_imm_reg_reg(s8 imm,s8 reg, s8 dreg);
+void x86_64_imull_imm_reg_reg(s8 imm, s8 reg, s8 dreg);
+void x86_64_imul_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
+void x86_64_imull_imm_membase_reg(s8 imm, s8 basereg, s8 disp, s8 dreg);
+void x86_64_idiv_reg(s8 reg);
+void x86_64_idivl_reg(s8 reg);
+void x86_64_ret();
+void x86_64_shift_reg(s8 opc, s8 reg);
+void x86_64_shiftl_reg(s8 opc, s8 reg);
+void x86_64_shift_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_shiftl_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_shift_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_shiftl_imm_reg(s8 opc, s8 imm, s8 dreg);
+void x86_64_shift_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_shiftl_imm_membase(s8 opc, s8 imm, s8 basereg, s8 disp);
+void x86_64_jmp_imm(s8 imm);
+void x86_64_jmp_reg(s8 reg);
+void x86_64_jcc(s8 opc, s8 imm);
+void x86_64_setcc_reg(s8 opc, s8 reg);
+void x86_64_setcc_membase(s8 opc, s8 basereg, s8 disp);
+void x86_64_cmovcc_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_cmovccl_reg_reg(s8 opc, s8 reg, s8 dreg);
+void x86_64_neg_reg(s8 reg);
+void x86_64_negl_reg(s8 reg);
+void x86_64_neg_membase(s8 basereg, s8 disp);
+void x86_64_negl_membase(s8 basereg, s8 disp);
+void x86_64_push_imm(s8 imm);
+void x86_64_pop_reg(s8 reg);
+void x86_64_xchg_reg_reg(s8 reg, s8 dreg);
+void x86_64_nop();
+void x86_64_call_reg(s8 reg);
+void x86_64_call_imm(s8 imm);
+
+
+/* floating point instructions (SSE2) */
+
+void x86_64_addsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_addss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2ssq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2ss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2sdq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsi2sd_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtss2sd_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvtsd2ss_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttss2siq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttss2si_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttsd2siq_reg_reg(s8 reg, s8 dreg);
+void x86_64_cvttsd2si_reg_reg(s8 reg, s8 dreg);
+void x86_64_divss_reg_reg(s8 reg, s8 dreg);
+void x86_64_divsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_movd_reg_freg(s8 reg, s8 freg);
+void x86_64_movd_freg_reg(s8 freg, s8 reg);
+void x86_64_movd_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movdl_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_movq_reg_reg(s8 reg, s8 dreg);
+void x86_64_movq_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movq_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movss_reg_reg(s8 reg, s8 dreg);
+void x86_64_movsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_movss_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movsd_reg_membase(s8 reg, s8 basereg, s8 disp);
+void x86_64_movss_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movlps_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movsd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movlpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_movss_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movsd_reg_memindex(s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
+void x86_64_movss_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_movsd_memindex_reg(s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
+void x86_64_mulss_reg_reg(s8 reg, s8 dreg);
+void x86_64_mulsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_subss_reg_reg(s8 reg, s8 dreg);
+void x86_64_subsd_reg_reg(s8 reg, s8 dreg);
+void x86_64_ucomiss_reg_reg(s8 reg, s8 dreg);
+void x86_64_ucomisd_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorps_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorps_membase_reg(s8 basereg, s8 disp, s8 dreg);
+void x86_64_xorpd_reg_reg(s8 reg, s8 dreg);
+void x86_64_xorpd_membase_reg(s8 basereg, s8 disp, s8 dreg);
+
+#endif /* _EMITFUNCS_H */
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */