From 3a74e50c3f6f6372e2ae224437c12b1e653d5920 Mon Sep 17 00:00:00 2001 From: twisti Date: Thu, 1 Jul 2004 20:38:16 +0000 Subject: [PATCH] - moved defines into header - moved code emitting functions into emitfuncs.* --- jit/x86_64/Makefile.am | 18 +- jit/x86_64/codegen.c | 1944 +-------------------------------- jit/x86_64/codegen.h | 316 +++--- jit/x86_64/emitfuncs.c | 1828 +++++++++++++++++++++++++++++++ jit/x86_64/emitfuncs.h | 218 ++++ src/vm/jit/x86_64/Makefile.am | 18 +- src/vm/jit/x86_64/codegen.c | 1944 +-------------------------------- src/vm/jit/x86_64/codegen.h | 316 +++--- src/vm/jit/x86_64/emitfuncs.c | 1828 +++++++++++++++++++++++++++++++ src/vm/jit/x86_64/emitfuncs.h | 218 ++++ 10 files changed, 4434 insertions(+), 4214 deletions(-) create mode 100644 jit/x86_64/emitfuncs.c create mode 100644 jit/x86_64/emitfuncs.h create mode 100644 src/vm/jit/x86_64/emitfuncs.c create mode 100644 src/vm/jit/x86_64/emitfuncs.h diff --git a/jit/x86_64/Makefile.am b/jit/x86_64/Makefile.am index ec246afc0..7cdaf5cb8 100644 --- a/jit/x86_64/Makefile.am +++ b/jit/x86_64/Makefile.am @@ -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 $< diff --git a/jit/x86_64/codegen.c b/jit/x86_64/codegen.c index f97d0bb62..4674993b3 100644 --- a/jit/x86_64/codegen.c +++ b/jit/x86_64/codegen.c @@ -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 $ */ @@ -37,10 +37,11 @@ #include #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 diff --git a/jit/x86_64/codegen.h b/jit/x86_64/codegen.h index 54af3350c..5e6be3896 100644 --- a/jit/x86_64/codegen.h +++ b/jit/x86_64/codegen.h @@ -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 index 000000000..e5b9976ff --- /dev/null +++ b/jit/x86_64/emitfuncs.c @@ -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 index 000000000..1039e01be --- /dev/null +++ b/jit/x86_64/emitfuncs.h @@ -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: + */ diff --git a/src/vm/jit/x86_64/Makefile.am b/src/vm/jit/x86_64/Makefile.am index ec246afc0..7cdaf5cb8 100644 --- a/src/vm/jit/x86_64/Makefile.am +++ b/src/vm/jit/x86_64/Makefile.am @@ -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 $< diff --git a/src/vm/jit/x86_64/codegen.c b/src/vm/jit/x86_64/codegen.c index f97d0bb62..4674993b3 100644 --- a/src/vm/jit/x86_64/codegen.c +++ b/src/vm/jit/x86_64/codegen.c @@ -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 $ */ @@ -37,10 +37,11 @@ #include #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 diff --git a/src/vm/jit/x86_64/codegen.h b/src/vm/jit/x86_64/codegen.h index 54af3350c..5e6be3896 100644 --- a/src/vm/jit/x86_64/codegen.h +++ b/src/vm/jit/x86_64/codegen.h @@ -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 index 000000000..e5b9976ff --- /dev/null +++ b/src/vm/jit/x86_64/emitfuncs.c @@ -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 index 000000000..1039e01be --- /dev/null +++ b/src/vm/jit/x86_64/emitfuncs.h @@ -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: + */ -- 2.25.1