## 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 $<
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.c 1134 2004-06-05 17:38:00Z twisti $
+ $Id: codegen.c 1266 2004-07-01 20:38:16Z twisti $
*/
#include <signal.h>
#include "types.h"
#include "main.h"
-#include "codegen.h"
-#include "jit.h"
-#include "reg.h"
-#include "parse.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/jit.h"
+#include "jit/reg.h"
+#include "jit/parse.h"
#include "builtin.h"
#include "asmpart.h"
#include "jni.h"
#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 ************************************************/
};
-/* 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
}
-/* 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)
/* 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);
}
-/* 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
-/* 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,
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 $
*/
#ifndef _CODEGEN_H
#define _CODEGEN_H
-#include "jit.h"
+#include "jit/jit.h"
/* x86_64 register numbers */
} 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 **************************************************
void codegen_close();
void dseg_display(s4 *s4ptr);
+void codegen_addreference(basicblock *target, void *branchptr);
+
#endif /* _CODEGEN_H */
* tab-width: 4
* End:
*/
-
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
## 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 $<
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.c 1134 2004-06-05 17:38:00Z twisti $
+ $Id: codegen.c 1266 2004-07-01 20:38:16Z twisti $
*/
#include <signal.h>
#include "types.h"
#include "main.h"
-#include "codegen.h"
-#include "jit.h"
-#include "reg.h"
-#include "parse.h"
+#include "jit/x86_64/codegen.h"
+#include "jit/x86_64/emitfuncs.h"
+#include "jit/jit.h"
+#include "jit/reg.h"
+#include "jit/parse.h"
#include "builtin.h"
#include "asmpart.h"
#include "jni.h"
#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 ************************************************/
};
-/* 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
}
-/* 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)
/* 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);
}
-/* 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
-/* 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,
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 $
*/
#ifndef _CODEGEN_H
#define _CODEGEN_H
-#include "jit.h"
+#include "jit/jit.h"
/* x86_64 register numbers */
} 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 **************************************************
void codegen_close();
void dseg_display(s4 *s4ptr);
+void codegen_addreference(basicblock *target, void *branchptr);
+
#endif /* _CODEGEN_H */
* tab-width: 4
* End:
*/
-
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */