X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fx86_64%2Femit.c;h=9c777fb54a558b0545c5177ea11a2fdea6107ae3;hb=35f32713571d45a9b6ebfc1c4c8ffbbab46937a0;hp=17b2cd5a42f9a4f2ac2ee60af4ff2ad4c8d6cdf6;hpb=9485802e10eaa8799469d3e1b27269c6e6f6877f;p=cacao.git diff --git a/src/vm/jit/x86_64/emit.c b/src/vm/jit/x86_64/emit.c index 17b2cd5a4..9c777fb54 100644 --- a/src/vm/jit/x86_64/emit.c +++ b/src/vm/jit/x86_64/emit.c @@ -1,9 +1,7 @@ /* src/vm/jit/x86_64/emit.c - x86_64 code emitter functions - Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -22,76 +20,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Christian Thalinger - - Changes: - - $Id: emit.c 4941 2006-05-23 08:25:14Z twisti $ - */ +#include "config.h" + +#include #include "vm/types.h" #include "md-abi.h" -#include "vm/jit/codegen-common.h" -#include "vm/jit/emit.h" -#include "vm/jit/jit.h" #include "vm/jit/x86_64/codegen.h" -#include "vm/jit/x86_64/md-emit.h" - - -/* code generation functions **************************************************/ - -/* emit_load_s1 **************************************************************** - - Emits a possible load of the first source operand. - -*******************************************************************************/ - -s4 emit_load_s1(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg) -{ - codegendata *cd; - s4 disp; - s4 reg; +#include "vm/jit/x86_64/emit.h" - /* get required compiler data */ +#include "mm/memory.h" - cd = jd->cd; +#include "threads/lock.hpp" - if (src->flags & INMEMORY) { - COUNT_SPILLS; +#include "vm/options.h" - disp = src->regoff * 8; +#include "vm/jit/abi.h" +#include "vm/jit/abi-asm.h" +#include "vm/jit/asmpart.h" +#include "vm/jit/codegen-common.hpp" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/patcher-common.hpp" +#include "vm/jit/replace.hpp" +#include "vm/jit/trace.hpp" +#include "vm/jit/trap.h" - if (IS_FLT_DBL_TYPE(src->type)) { - M_DLD(tempreg, REG_SP, disp); - } else { - if (IS_INT_TYPE(src->type)) - M_ILD(tempreg, REG_SP, disp); - else - M_LLD(tempreg, REG_SP, disp); - } +/* emit_load ******************************************************************* - reg = tempreg; - } else - reg = src->regoff; - - return reg; -} - - -/* emit_load_s2 **************************************************************** - - Emits a possible load of the second source operand. + Emits a possible load of an operand. *******************************************************************************/ -s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg) +s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) { codegendata *cd; s4 disp; @@ -101,63 +67,33 @@ s4 emit_load_s2(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg) cd = jd->cd; - if (src->flags & INMEMORY) { + if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->regoff * 8; - - if (IS_FLT_DBL_TYPE(src->type)) { + disp = src->vv.regoff; + + switch (src->type) { + case TYPE_INT: + M_ILD(tempreg, REG_SP, disp); + break; + case TYPE_LNG: + case TYPE_ADR: + M_LLD(tempreg, REG_SP, disp); + break; + case TYPE_FLT: + M_FLD(tempreg, REG_SP, disp); + break; + case TYPE_DBL: M_DLD(tempreg, REG_SP, disp); - - } else { - if (IS_INT_TYPE(src->type)) - M_ILD(tempreg, REG_SP, disp); - else - M_LLD(tempreg, REG_SP, disp); + break; + default: + vm_abort("emit_load: unknown type %d", src->type); } reg = tempreg; - } else - reg = src->regoff; - - return reg; -} - - -/* emit_load_s3 **************************************************************** - - Emits a possible load of the third source operand. - -*******************************************************************************/ - -s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg) -{ - codegendata *cd; - s4 disp; - s4 reg; - - /* get required compiler data */ - - cd = jd->cd; - - if (src->flags & INMEMORY) { - COUNT_SPILLS; - - disp = src->regoff * 8; - - if (IS_FLT_DBL_TYPE(src->type)) { - M_DLD(tempreg, REG_SP, disp); - - } else { - if (IS_INT_TYPE(src->type)) - M_ILD(tempreg, REG_SP, disp); - else - M_LLD(tempreg, REG_SP, disp); - } - - reg = tempreg; - } else - reg = src->regoff; + } + else + reg = src->vv.regoff; return reg; } @@ -172,80 +108,96 @@ s4 emit_load_s3(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg) *******************************************************************************/ -void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d) +void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) { codegendata *cd; - registerdata *rd; s4 disp; - s4 s; - u2 opcode; /* get required compiler data */ cd = jd->cd; - rd = jd->rd; - - /* do we have to generate a conditional move? */ - - if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) { - /* the passed register d is actually the source register */ - - s = d; - - /* Only pass the opcode to codegen_reg_of_var to get the real - destination register. */ - opcode = iptr->opc & ICMD_OPCODE_MASK; - - /* get the real destination register */ - - d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1); - - /* and emit the conditional move */ - - emit_cmovxx(cd, iptr, s, d); - } - - if (dst->flags & INMEMORY) { + if (IS_INMEMORY(dst->flags)) { COUNT_SPILLS; - disp = dst->regoff * 8; + disp = dst->vv.regoff; - if (IS_FLT_DBL_TYPE(dst->type)) - M_DST(d, REG_SP, disp); - else + switch (dst->type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: M_LST(d, REG_SP, disp); + break; + case TYPE_FLT: + M_FST(d, REG_SP, disp); + break; + case TYPE_DBL: + M_DST(d, REG_SP, disp); + break; + default: + vm_abort("emit_store: unknown type %d", dst->type); + } } } /* emit_copy ******************************************************************* - XXX + Generates a register/memory to register/memory copy. *******************************************************************************/ -void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst) +void emit_copy(jitdata *jd, instruction *iptr) { - codegendata *cd; - registerdata *rd; - s4 s1, d; + codegendata *cd; + varinfo *src; + varinfo *dst; + s4 s1, d; /* get required compiler data */ cd = jd->cd; - rd = jd->rd; - if ((src->regoff != dst->regoff) || + /* get source and destination variables */ + + src = VAROP(iptr->s1); + dst = VAROP(iptr->dst); + + if ((src->vv.regoff != dst->vv.regoff) || ((src->flags ^ dst->flags) & INMEMORY)) { - d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP); - s1 = emit_load_s1(jd, iptr, src, d); + + if ((src->type == TYPE_RET) || (dst->type == TYPE_RET)) { + /* emit nothing, as the value won't be used anyway */ + return; + } + + /* If one of the variables resides in memory, we can eliminate + the register move from/to the temporary register with the + order of getting the destination register and the load. */ + + if (IS_INMEMORY(src->flags)) { + d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP); + s1 = emit_load(jd, iptr, src, d); + } + else { + s1 = emit_load(jd, iptr, src, REG_IFTMP); + d = codegen_reg_of_var(iptr->opc, dst, s1); + } if (s1 != d) { - if (IS_FLT_DBL_TYPE(src->type)) - M_FMOV(s1, d); - else + switch (src->type) { + case TYPE_INT: + case TYPE_LNG: + case TYPE_ADR: M_MOV(s1, d); + break; + case TYPE_FLT: + case TYPE_DBL: + M_FMOV(s1, d); + break; + default: + vm_abort("emit_copy: unknown type %d", src->type); + } } emit_store(jd, iptr, dst, d); @@ -255,7 +207,8 @@ void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst) void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d) { - switch ((iptr->opc & ICMD_CONDITION_MASK) >> 8) { +#if 0 + switch (iptr->flags.fields.condition) { case ICMD_IFEQ: M_CMOVEQ(s, d); break; @@ -275,354 +228,572 @@ void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d) M_CMOVLE(s, d); break; } +#endif } -/* code generation functions **************************************************/ +/* emit_branch ***************************************************************** -void emit_ialu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr) -{ - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - s4 d = iptr->dst->regoff; + Emits the code for conditional and unconditional branchs. - if (iptr->dst->flags & INMEMORY) { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - if (s2 == d) { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); +*******************************************************************************/ - } else if (s1 == d) { - emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alul_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); +void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 options) +{ + s4 branchdisp; - } else { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1); - emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } + /* NOTE: A displacement overflow cannot happen. */ - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - if (s2 == d) { - emit_alul_reg_membase(cd, alu_op, s1, REG_SP, d * 8); + /* check which branch to generate */ - } else { - emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alul_reg_reg(cd, alu_op, s1, REG_ITMP1); - emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } + if (condition == BRANCH_UNCONDITIONAL) { - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - if (s1 == d) { - emit_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8); - - } else { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alul_reg_reg(cd, alu_op, s2, REG_ITMP1); - emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } + /* calculate the different displacements */ - } else { - emit_movl_reg_membase(cd, s1, REG_SP, d * 8); - emit_alul_reg_membase(cd, alu_op, s2, REG_SP, d * 8); + branchdisp = disp - BRANCH_UNCONDITIONAL_SIZE; + + M_JMP_IMM(branchdisp); + } + else { + /* calculate the different displacements */ + + branchdisp = disp - BRANCH_CONDITIONAL_SIZE; + + switch (condition) { + case BRANCH_EQ: + M_BEQ(branchdisp); + break; + case BRANCH_NE: + M_BNE(branchdisp); + break; + case BRANCH_LT: + M_BLT(branchdisp); + break; + case BRANCH_GE: + M_BGE(branchdisp); + break; + case BRANCH_GT: + M_BGT(branchdisp); + break; + case BRANCH_LE: + M_BLE(branchdisp); + break; + case BRANCH_ULT: + M_BULT(branchdisp); + break; + case BRANCH_ULE: + M_BULE(branchdisp); + break; + case BRANCH_UGE: + M_BUGE(branchdisp); + break; + case BRANCH_UGT: + M_BUGT(branchdisp); + break; + default: + vm_abort("emit_branch: unknown condition %d", condition); } + } +} - } else { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, d); - emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d); - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - M_INTMOVE(s1, d); - emit_alul_membase_reg(cd, alu_op, REG_SP, s2 * 8, d); +/* emit_arithmetic_check ******************************************************* - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - M_INTMOVE(s2, d); - emit_alul_membase_reg(cd, alu_op, REG_SP, s1 * 8, d); + Emit an ArithmeticException check. - } else { - if (s2 == d) { - emit_alul_reg_reg(cd, alu_op, s1, d); +*******************************************************************************/ - } else { - M_INTMOVE(s1, d); - emit_alul_reg_reg(cd, alu_op, s2, d); - } - } +void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_TEST(reg); + M_BNE(8); + M_ALD_MEM(reg, TRAP_ArithmeticException); } } -void emit_lalu(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr) +/* emit_arrayindexoutofbounds_check ******************************************** + + Emit a ArrayIndexOutOfBoundsException check. + +*******************************************************************************/ + +void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2) { - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - s4 d = iptr->dst->regoff; + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size)); + M_ICMP(REG_ITMP3, s2); + M_BULT(8); + M_ALD_MEM(s2, TRAP_ArrayIndexOutOfBoundsException); + } +} - if (iptr->dst->flags & INMEMORY) { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - if (s2 == d) { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); - } else if (s1 == d) { - emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); +/* emit_arraystore_check ******************************************************* - } else { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, REG_ITMP1); - emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } + Emit an ArrayStoreException check. - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - if (s2 == d) { - emit_alu_reg_membase(cd, alu_op, s1, REG_SP, d * 8); +*******************************************************************************/ - } else { - emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alu_reg_reg(cd, alu_op, s1, REG_ITMP1); - emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } +void emit_arraystore_check(codegendata *cd, instruction *iptr) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_TEST(REG_RESULT); + M_BNE(8); + M_ALD_MEM(REG_RESULT, TRAP_ArrayStoreException); + } +} - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - if (s1 == d) { - emit_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8); - - } else { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alu_reg_reg(cd, alu_op, s2, REG_ITMP1); - emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } - } else { - emit_mov_reg_membase(cd, s1, REG_SP, d * 8); - emit_alu_reg_membase(cd, alu_op, s2, REG_SP, d * 8); +/* emit_classcast_check ******************************************************** + + Emit a ClassCastException check. + +*******************************************************************************/ + +void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 reg, s4 s1) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + switch (condition) { + case BRANCH_LE: + M_BGT(8); + break; + case BRANCH_GE: + M_BLT(8); + break; + case BRANCH_EQ: + M_BNE(8); + break; + case BRANCH_NE: + M_BEQ(8); + break; + case BRANCH_UGT: + M_BULE(8); + break; + default: + vm_abort("emit_classcast_check: unknown condition %d", condition); } + M_ALD_MEM(s1, TRAP_ClassCastException); + } +} - } else { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, d); - emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d); - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - M_INTMOVE(s1, d); - emit_alu_membase_reg(cd, alu_op, REG_SP, s2 * 8, d); +/* emit_nullpointer_check ****************************************************** - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - M_INTMOVE(s2, d); - emit_alu_membase_reg(cd, alu_op, REG_SP, s1 * 8, d); + Emit a NullPointerException check. - } else { - if (s2 == d) { - emit_alu_reg_reg(cd, alu_op, s1, d); +*******************************************************************************/ - } else { - M_INTMOVE(s1, d); - emit_alu_reg_reg(cd, alu_op, s2, d); - } - } +void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) +{ + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_TEST(reg); + M_BNE(8); + M_ALD_MEM(reg, TRAP_NullPointerException); } } -void emit_ialuconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr) +/* emit_exception_check ******************************************************** + + Emit an Exception check. + +*******************************************************************************/ + +void emit_exception_check(codegendata *cd, instruction *iptr) { - s4 s1 = src->regoff; - s4 d = iptr->dst->regoff; + if (INSTRUCTION_MUST_CHECK(iptr)) { + M_TEST(REG_RESULT); + M_BNE(8); + M_ALD_MEM(REG_RESULT, TRAP_CHECK_EXCEPTION); + } +} - if (iptr->dst->flags & INMEMORY) { - if (src->flags & INMEMORY) { - if (s1 == d) { - emit_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8); - } else { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_alul_imm_reg(cd, alu_op, iptr->val.i, REG_ITMP1); - emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } +/* emit_trap_compiler ********************************************************** - } else { - emit_movl_reg_membase(cd, s1, REG_SP, d * 8); - emit_alul_imm_membase(cd, alu_op, iptr->val.i, REG_SP, d * 8); + Emit a trap instruction which calls the JIT compiler. + +*******************************************************************************/ + +void emit_trap_compiler(codegendata *cd) +{ + M_ALD_MEM(REG_METHODPTR, TRAP_COMPILER); +} + + +/* emit_trap ******************************************************************* + + Emit a trap instruction and return the original machine code. + +*******************************************************************************/ + +uint32_t emit_trap(codegendata *cd) +{ + uint16_t mcode; + + /* Get machine code which is patched back in later. The trap is 2 + bytes long. */ + + mcode = *((uint16_t *) cd->mcodeptr); + + /* XXX This needs to be change to INT3 when the debugging problems + with gdb are resolved. */ + + M_UD2; + + return mcode; +} + + +/* emit_verbosecall_enter ****************************************************** + + Generates the code for the call trace. + +*******************************************************************************/ + +#if !defined(NDEBUG) +void emit_verbosecall_enter(jitdata *jd) +{ + methodinfo *m; + codeinfo *code; + codegendata *cd; + registerdata *rd; + methoddesc *md; + s4 stackframesize; + s4 i, s; + + /* get required compiler data */ + + m = jd->m; + code = jd->code; + cd = jd->cd; + rd = jd->rd; + + md = m->parseddesc; + + /* mark trace code */ + + M_NOP; + + /* keep 16-byte stack alignment */ + + stackframesize = md->paramcount + ARG_CNT + TMP_CNT; + ALIGN_2(stackframesize); + + M_LSUB_IMM(stackframesize * 8, REG_SP); + + /* save argument registers */ + + for (i = 0; i < md->paramcount; i++) { + if (!md->params[i].inmemory) { + s = md->params[i].regoff; + + switch (md->paramtypes[i].type) { + case TYPE_ADR: + case TYPE_INT: + case TYPE_LNG: + M_LST(s, REG_SP, i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(s, REG_SP, i * 8); + break; + } } + } - } else { - if (src->flags & INMEMORY) { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, d); - emit_alul_imm_reg(cd, alu_op, iptr->val.i, d); + /* save all argument and temporary registers for leaf methods */ - } else { -#if 0 - M_INTMOVE(s1, d); - emit_alul_imm_reg(cd, alu_op, iptr->val.i, d); -#else - /* lea addition optimization */ + if (code_is_leafmethod(code)) { + for (i = 0; i < INT_ARG_CNT; i++) + M_LST(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8); - if ((alu_op == ALU_ADD) && (s1 != d)) { - M_ILEA(s1, iptr->val.i, d); + for (i = 0; i < FLT_ARG_CNT; i++) + M_DST(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8); - } else { - M_INTMOVE(s1, d); - emit_alul_imm_reg(cd, alu_op, iptr->val.i, d); + for (i = 0; i < INT_TMP_CNT; i++) + M_LST(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8); + + for (i = 0; i < FLT_TMP_CNT; i++) + M_DST(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8); + } + + M_MOV_IMM(m, REG_A0); + M_MOV(REG_SP, REG_A1); + M_MOV(REG_SP, REG_A2); + M_AADD_IMM((stackframesize + cd->stackframesize + 1) * 8, REG_A2); + M_MOV_IMM(trace_java_call_enter, REG_ITMP1); + M_CALL(REG_ITMP1); + + /* restore argument registers */ + + for (i = 0; i < md->paramcount; i++) { + if (!md->params[i].inmemory) { + s = md->params[i].regoff; + + switch (md->paramtypes[i].type) { + case TYPE_ADR: + case TYPE_INT: + case TYPE_LNG: + M_LLD(s, REG_SP, i * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(s, REG_SP, i * 8); + break; } -#endif } } + + + /* restore all argument and temporary registers for leaf methods */ + + if (code_is_leafmethod(code)) { + for (i = 0; i < INT_ARG_CNT; i++) + M_LLD(abi_registers_integer_argument[i], REG_SP, (md->paramcount + i) * 8); + + for (i = 0; i < FLT_ARG_CNT; i++) + M_DLD(abi_registers_float_argument[i], REG_SP, (md->paramcount + INT_ARG_CNT + i) * 8); + + for (i = 0; i < INT_TMP_CNT; i++) + M_LLD(rd->tmpintregs[i], REG_SP, (md->paramcount + ARG_CNT + i) * 8); + + for (i = 0; i < FLT_TMP_CNT; i++) + M_DLD(rd->tmpfltregs[i], REG_SP, (md->paramcount + ARG_CNT + INT_TMP_CNT + i) * 8); + } + + M_LADD_IMM(stackframesize * 8, REG_SP); + + /* mark trace code */ + + M_NOP; } +#endif /* !defined(NDEBUG) */ + +/* emit_verbosecall_exit ******************************************************* -void emit_laluconst(codegendata *cd, s4 alu_op, stackptr src, instruction *iptr) + Generates the code for the call trace. + +*******************************************************************************/ + +#if !defined(NDEBUG) +void emit_verbosecall_exit(jitdata *jd) { - s4 s1 = src->regoff; - s4 d = iptr->dst->regoff; + methodinfo *m; + codegendata *cd; + registerdata *rd; + methoddesc *md; - if (iptr->dst->flags & INMEMORY) { - if (src->flags & INMEMORY) { - if (s1 == d) { - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8); + /* get required compiler data */ - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); - } + m = jd->m; + cd = jd->cd; + rd = jd->rd; - } else { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); + md = m->parseddesc; - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_reg(cd, alu_op, iptr->val.l, REG_ITMP1); + /* mark trace code */ - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP2); - emit_alu_reg_reg(cd, alu_op, REG_ITMP2, REG_ITMP1); - } - emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } + M_NOP; - } else { - emit_mov_reg_membase(cd, s1, REG_SP, d * 8); + /* keep 16-byte stack alignment */ - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_membase(cd, alu_op, iptr->val.l, REG_SP, d * 8); + M_ASUB_IMM(2 * 8, REG_SP); - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_membase(cd, alu_op, REG_ITMP1, REG_SP, d * 8); - } - } + /* save return value */ - } else { -#if 0 - if (src->flags & INMEMORY) { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, d); + switch (md->returntype.type) { + case TYPE_ADR: + case TYPE_INT: + case TYPE_LNG: + M_LST(REG_RESULT, REG_SP, 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DST(REG_FRESULT, REG_SP, 0 * 8); + break; + } - } else { - M_INTMOVE(s1, d); - } + M_MOV_IMM(m, REG_A0); + M_MOV(REG_SP, REG_A1); + + M_MOV_IMM(trace_java_call_exit, REG_ITMP1); + M_CALL(REG_ITMP1); + + /* restore return value */ + + switch (md->returntype.type) { + case TYPE_ADR: + case TYPE_INT: + case TYPE_LNG: + M_LLD(REG_RESULT, REG_SP, 0 * 8); + break; + case TYPE_FLT: + case TYPE_DBL: + M_DLD(REG_FRESULT, REG_SP, 0 * 8); + break; + } + + M_AADD_IMM(2 * 8, REG_SP); + + /* mark trace code */ + + M_NOP; +} +#endif /* !defined(NDEBUG) */ + + +/* code generation functions **************************************************/ + +static void emit_membase(codegendata *cd, s4 basereg, s4 disp, s4 dreg) +{ + if ((basereg == REG_SP) || (basereg == R12)) { + if (disp == 0) { + emit_address_byte(0, dreg, REG_SP); + emit_address_byte(0, REG_SP, REG_SP); - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_reg(cd, alu_op, iptr->val.l, d); + } else if (IS_IMM8(disp)) { + emit_address_byte(1, dreg, REG_SP); + emit_address_byte(0, REG_SP, REG_SP); + emit_imm8(disp); } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d); + emit_address_byte(2, dreg, REG_SP); + emit_address_byte(0, REG_SP, REG_SP); + emit_imm32(disp); } -#else - if (src->flags & INMEMORY) { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, d); - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_reg(cd, alu_op, iptr->val.l, d); + } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) { + emit_address_byte(0,(dreg),(basereg)); - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d); - } + } else if ((basereg) == RIP) { + emit_address_byte(0, dreg, RBP); + emit_imm32(disp); + + } else { + if (IS_IMM8(disp)) { + emit_address_byte(1, dreg, basereg); + emit_imm8(disp); } else { - if (IS_IMM32(iptr->val.l)) { - /* lea addition optimization */ + emit_address_byte(2, dreg, basereg); + emit_imm32(disp); + } + } +} - if ((alu_op == ALU_ADD) && (s1 != d)) { - M_LLEA(s1, iptr->val.l, d); - } else { - M_INTMOVE(s1, d); - emit_alu_imm_reg(cd, alu_op, iptr->val.l, d); - } +static void emit_membase32(codegendata *cd, s4 basereg, s4 disp, s4 dreg) +{ + if ((basereg == REG_SP) || (basereg == R12)) { + emit_address_byte(2, dreg, REG_SP); + emit_address_byte(0, REG_SP, REG_SP); + emit_imm32(disp); + } + else { + emit_address_byte(2, dreg, basereg); + emit_imm32(disp); + } +} - } else { - M_INTMOVE(s1, d); - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_reg(cd, alu_op, REG_ITMP1, d); - } - } -#endif + +static void emit_memindex(codegendata *cd, s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) +{ + if (basereg == -1) { + emit_address_byte(0, reg, 4); + emit_address_byte(scale, indexreg, 5); + emit_imm32(disp); + } + else if ((disp == 0) && (basereg != RBP) && (basereg != R13)) { + emit_address_byte(0, reg, 4); + emit_address_byte(scale, indexreg, basereg); + } + else if (IS_IMM8(disp)) { + emit_address_byte(1, reg, 4); + emit_address_byte(scale, indexreg, basereg); + emit_imm8(disp); + } + else { + emit_address_byte(2, reg, 4); + emit_address_byte(scale, indexreg, basereg); + emit_imm32(disp); } } -void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) +void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr) { - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - s4 d = iptr->dst->regoff; - s4 d_old; + s4 s1, s2, d, d_old; + varinfo *v_s1,*v_s2,*v_dst; + codegendata *cd; + + /* get required compiler data */ + + cd = jd->cd; + + v_s1 = VAROP(iptr->s1); + v_s2 = VAROP(iptr->sx.s23.s2); + v_dst = VAROP(iptr->dst); + + s1 = v_s1->vv.regoff; + s2 = v_s2->vv.regoff; + d = v_dst->vv.regoff; M_INTMOVE(RCX, REG_ITMP1); /* save RCX */ - if (iptr->dst->flags & INMEMORY) { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + if (IS_INMEMORY(v_dst->flags)) { + if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { if (s1 == d) { - M_ILD(RCX, REG_SP, s2 * 8); - emit_shiftl_membase(cd, shift_op, REG_SP, d * 8); + M_ILD(RCX, REG_SP, s2); + emit_shiftl_membase(cd, shift_op, REG_SP, d); } else { - M_ILD(RCX, REG_SP, s2 * 8); - M_ILD(REG_ITMP2, REG_SP, s1 * 8); + M_ILD(RCX, REG_SP, s2); + M_ILD(REG_ITMP2, REG_SP, s1); emit_shiftl_reg(cd, shift_op, REG_ITMP2); - M_IST(REG_ITMP2, REG_SP, d * 8); + M_IST(REG_ITMP2, REG_SP, d); } - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { + } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) { /* s1 may be equal to RCX */ if (s1 == RCX) { if (s2 == d) { - M_ILD(REG_ITMP1, REG_SP, s2 * 8); - M_IST(s1, REG_SP, d * 8); + M_ILD(REG_ITMP1, REG_SP, s2); + M_IST(s1, REG_SP, d); M_INTMOVE(REG_ITMP1, RCX); } else { - M_IST(s1, REG_SP, d * 8); - M_ILD(RCX, REG_SP, s2 * 8); + M_IST(s1, REG_SP, d); + M_ILD(RCX, REG_SP, s2); } } else { - M_ILD(RCX, REG_SP, s2 * 8); - M_IST(s1, REG_SP, d * 8); + M_ILD(RCX, REG_SP, s2); + M_IST(s1, REG_SP, d); } - emit_shiftl_membase(cd, shift_op, REG_SP, d * 8); + emit_shiftl_membase(cd, shift_op, REG_SP, d); - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { if (s1 == d) { M_INTMOVE(s2, RCX); - emit_shiftl_membase(cd, shift_op, REG_SP, d * 8); + emit_shiftl_membase(cd, shift_op, REG_SP, d); } else { M_INTMOVE(s2, RCX); - M_ILD(REG_ITMP2, REG_SP, s1 * 8); + M_ILD(REG_ITMP2, REG_SP, s1); emit_shiftl_reg(cd, shift_op, REG_ITMP2); - M_IST(REG_ITMP2, REG_SP, d * 8); + M_IST(REG_ITMP2, REG_SP, d); } } else { /* s1 may be equal to RCX */ - M_IST(s1, REG_SP, d * 8); + M_IST(s1, REG_SP, d); M_INTMOVE(s2, RCX); - emit_shiftl_membase(cd, shift_op, REG_SP, d * 8); + emit_shiftl_membase(cd, shift_op, REG_SP, d); } M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */ @@ -633,20 +804,20 @@ void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) d = REG_ITMP3; } - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - M_ILD(RCX, REG_SP, s2 * 8); - M_ILD(d, REG_SP, s1 * 8); + if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { + M_ILD(RCX, REG_SP, s2); + M_ILD(d, REG_SP, s1); emit_shiftl_reg(cd, shift_op, d); - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { + } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) { /* s1 may be equal to RCX */ M_INTMOVE(s1, d); - M_ILD(RCX, REG_SP, s2 * 8); + M_ILD(RCX, REG_SP, s2); emit_shiftl_reg(cd, shift_op, d); - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { M_INTMOVE(s2, RCX); - M_ILD(d, REG_SP, s1 * 8); + M_ILD(d, REG_SP, s1); emit_shiftl_reg(cd, shift_op, d); } else { @@ -680,65 +851,76 @@ void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) } -void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) +void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr) { - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - s4 d = iptr->dst->regoff; - s4 d_old; + s4 s1, s2, d, d_old; + varinfo *v_s1,*v_s2,*v_dst; + codegendata *cd; + + /* get required compiler data */ + + cd = jd->cd; + + v_s1 = VAROP(iptr->s1); + v_s2 = VAROP(iptr->sx.s23.s2); + v_dst = VAROP(iptr->dst); + + s1 = v_s1->vv.regoff; + s2 = v_s2->vv.regoff; + d = v_dst->vv.regoff; M_INTMOVE(RCX, REG_ITMP1); /* save RCX */ - if (iptr->dst->flags & INMEMORY) { - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + if (IS_INMEMORY(v_dst->flags)) { + if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { if (s1 == d) { - M_ILD(RCX, REG_SP, s2 * 8); - emit_shift_membase(cd, shift_op, REG_SP, d * 8); + M_ILD(RCX, REG_SP, s2); + emit_shift_membase(cd, shift_op, REG_SP, d); } else { - M_ILD(RCX, REG_SP, s2 * 8); - M_LLD(REG_ITMP2, REG_SP, s1 * 8); + M_ILD(RCX, REG_SP, s2); + M_LLD(REG_ITMP2, REG_SP, s1); emit_shift_reg(cd, shift_op, REG_ITMP2); - M_LST(REG_ITMP2, REG_SP, d * 8); + M_LST(REG_ITMP2, REG_SP, d); } - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { + } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) { /* s1 may be equal to RCX */ if (s1 == RCX) { if (s2 == d) { - M_ILD(REG_ITMP1, REG_SP, s2 * 8); - M_LST(s1, REG_SP, d * 8); + M_ILD(REG_ITMP1, REG_SP, s2); + M_LST(s1, REG_SP, d); M_INTMOVE(REG_ITMP1, RCX); } else { - M_LST(s1, REG_SP, d * 8); - M_ILD(RCX, REG_SP, s2 * 8); + M_LST(s1, REG_SP, d); + M_ILD(RCX, REG_SP, s2); } } else { - M_ILD(RCX, REG_SP, s2 * 8); - M_LST(s1, REG_SP, d * 8); + M_ILD(RCX, REG_SP, s2); + M_LST(s1, REG_SP, d); } - emit_shift_membase(cd, shift_op, REG_SP, d * 8); + emit_shift_membase(cd, shift_op, REG_SP, d); - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { if (s1 == d) { M_INTMOVE(s2, RCX); - emit_shift_membase(cd, shift_op, REG_SP, d * 8); + emit_shift_membase(cd, shift_op, REG_SP, d); } else { M_INTMOVE(s2, RCX); - M_LLD(REG_ITMP2, REG_SP, s1 * 8); + M_LLD(REG_ITMP2, REG_SP, s1); emit_shift_reg(cd, shift_op, REG_ITMP2); - M_LST(REG_ITMP2, REG_SP, d * 8); + M_LST(REG_ITMP2, REG_SP, d); } } else { /* s1 may be equal to RCX */ - M_LST(s1, REG_SP, d * 8); + M_LST(s1, REG_SP, d); M_INTMOVE(s2, RCX); - emit_shift_membase(cd, shift_op, REG_SP, d * 8); + emit_shift_membase(cd, shift_op, REG_SP, d); } M_INTMOVE(REG_ITMP1, RCX); /* restore RCX */ @@ -749,20 +931,20 @@ void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) d = REG_ITMP3; } - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - M_ILD(RCX, REG_SP, s2 * 8); - M_LLD(d, REG_SP, s1 * 8); + if (IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { + M_ILD(RCX, REG_SP, s2); + M_LLD(d, REG_SP, s1); emit_shift_reg(cd, shift_op, d); - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { + } else if (IS_INMEMORY(v_s2->flags) && !IS_INMEMORY(v_s1->flags)) { /* s1 may be equal to RCX */ M_INTMOVE(s1, d); - M_ILD(RCX, REG_SP, s2 * 8); + M_ILD(RCX, REG_SP, s2); emit_shift_reg(cd, shift_op, d); - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { + } else if (!IS_INMEMORY(v_s2->flags) && IS_INMEMORY(v_s1->flags)) { M_INTMOVE(s2, RCX); - M_LLD(d, REG_SP, s1 * 8); + M_LLD(d, REG_SP, s1); emit_shift_reg(cd, shift_op, d); } else { @@ -796,179 +978,6 @@ void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr) } -void emit_ishiftconst(codegendata *cd, 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) { - emit_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8); - - } else { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1); - emit_movl_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } - - } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) { - emit_movl_membase_reg(cd, REG_SP, s1 * 8, d); - emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, d); - - } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) { - emit_movl_reg_membase(cd, s1, REG_SP, d * 8); - emit_shiftl_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8); - - } else { - M_INTMOVE(s1, d); - emit_shiftl_imm_reg(cd, shift_op, iptr->val.i, d); - } -} - - -void emit_lshiftconst(codegendata *cd, 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) { - emit_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8); - - } else { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, REG_ITMP1); - emit_shift_imm_reg(cd, shift_op, iptr->val.i, REG_ITMP1); - emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, d * 8); - } - - } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) { - emit_mov_membase_reg(cd, REG_SP, s1 * 8, d); - emit_shift_imm_reg(cd, shift_op, iptr->val.i, d); - - } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) { - emit_mov_reg_membase(cd, s1, REG_SP, d * 8); - emit_shift_imm_membase(cd, shift_op, iptr->val.i, REG_SP, d * 8); - - } else { - M_INTMOVE(s1, d); - emit_shift_imm_reg(cd, shift_op, iptr->val.i, d); - } -} - - -void emit_ifcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr) -{ - if (src->flags & INMEMORY) - M_ICMP_IMM_MEMBASE(iptr->val.i, REG_SP, src->regoff * 8); - else { - if (iptr->val.i == 0) - M_ITEST(src->regoff); - else - M_ICMP_IMM(iptr->val.i, src->regoff); - } - - /* If the conditional branch is part of an if-converted block, - don't generate the actual branch. */ - - if ((iptr->opc & ICMD_CONDITION_MASK) == 0) { - emit_jcc(cd, if_op, 0); - codegen_addreference(cd, (basicblock *) iptr->target); - } -} - - -void emit_if_lcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr) -{ - s4 s1 = src->regoff; - - if (src->flags & INMEMORY) { - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_membase(cd, ALU_CMP, iptr->val.l, REG_SP, s1 * 8); - - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8); - } - - } else { - if (iptr->val.l == 0) { - emit_test_reg_reg(cd, s1, s1); - - } else { - if (IS_IMM32(iptr->val.l)) { - emit_alu_imm_reg(cd, ALU_CMP, iptr->val.l, s1); - - } else { - emit_mov_imm_reg(cd, iptr->val.l, REG_ITMP1); - emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP1, s1); - } - } - } - emit_jcc(cd, if_op, 0); - codegen_addreference(cd, (basicblock *) iptr->target); -} - - -/* emit_if_icmpcc ************************************************************** - - Generate ICMD_IF_ICMPxx instructions. - -*******************************************************************************/ - -void emit_if_icmpcc(codegendata *cd, s4 if_op, stackptr src, - instruction *iptr) -{ - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_movl_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alul_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8); - - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - emit_alul_membase_reg(cd, ALU_CMP, REG_SP, s2 * 8, s1); - - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_alul_reg_membase(cd, ALU_CMP, s2, REG_SP, s1 * 8); - - } else { - emit_alul_reg_reg(cd, ALU_CMP, s2, s1); - } - - - /* If the conditional branch is part of an if-converted block, - don't generate the actual branch. */ - - if ((iptr->opc & ICMD_CONDITION_MASK) == 0) { - emit_jcc(cd, if_op, 0); - codegen_addreference(cd, (basicblock *) iptr->target); - } -} - - -void emit_if_lcmpcc(codegendata *cd, s4 if_op, stackptr src, instruction *iptr) -{ - s4 s1 = src->prev->regoff; - s4 s2 = src->regoff; - - if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1); - emit_alu_reg_membase(cd, ALU_CMP, REG_ITMP1, REG_SP, s1 * 8); - - } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) { - emit_alu_membase_reg(cd, ALU_CMP, REG_SP, s2 * 8, s1); - - } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) { - emit_alu_reg_membase(cd, ALU_CMP, s2, REG_SP, s1 * 8); - - } else { - emit_alu_reg_reg(cd, ALU_CMP, s2, s1); - } - emit_jcc(cd, if_op, 0); - codegen_addreference(cd, (basicblock *) iptr->target); -} - - /* low-level code emitter functions *******************************************/ void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg) @@ -1005,7 +1014,7 @@ void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg) { void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -1016,7 +1025,7 @@ void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } @@ -1024,7 +1033,7 @@ void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -1034,28 +1043,28 @@ void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_byte_rex((reg),0,(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x89; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x89; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x89; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -1064,35 +1073,35 @@ void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_byte_rex((reg),0,(basereg)); *(cd->mcodeptr++) = 0x89; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) { emit_rex(1,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) { emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x8b; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) { emit_rex(1,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x89; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) { emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x89; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -1100,21 +1109,21 @@ void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 ind *(cd->mcodeptr++) = 0x66; emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x89; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale) { emit_byte_rex((reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x88; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) { emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_membase((basereg),(disp),0); + emit_membase(cd, (basereg),(disp),0); emit_imm32((imm)); } @@ -1122,7 +1131,7 @@ void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) { void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) { emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_membase32((basereg),(disp),0); + emit_membase32(cd, (basereg),(disp),0); emit_imm32((imm)); } @@ -1130,7 +1139,7 @@ void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) { void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) { emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_membase((basereg),(disp),0); + emit_membase(cd, (basereg),(disp),0); emit_imm32((imm)); } @@ -1140,12 +1149,13 @@ void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp) { void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp) { emit_byte_rex(0,0,(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_membase32((basereg),(disp),0); + emit_membase32(cd, (basereg),(disp),0); emit_imm32((imm)); } -void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { +void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) +{ emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xbe; @@ -1154,15 +1164,8 @@ void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { } -void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { - emit_rex(1,(dreg),0,(basereg)); - *(cd->mcodeptr++) = 0x0f; - *(cd->mcodeptr++) = 0xbe; - emit_membase((basereg),(disp),(dreg)); -} - - -void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { +void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) +{ emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xbf; @@ -1171,15 +1174,8 @@ void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { } -void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { - emit_rex(1,(dreg),0,(basereg)); - *(cd->mcodeptr++) = 0x0f; - *(cd->mcodeptr++) = 0xbf; - emit_membase((basereg),(disp),(dreg)); -} - - -void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { +void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) +{ emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x63; /* XXX: why do reg and dreg have to be exchanged */ @@ -1187,27 +1183,23 @@ void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { } -void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { - emit_rex(1,(dreg),0,(basereg)); - *(cd->mcodeptr++) = 0x63; - emit_membase((basereg),(disp),(dreg)); -} - - -void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg) { +void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg) +{ emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; - *(cd->mcodeptr++) = 0xb7; + *(cd->mcodeptr++) = 0xb6; /* XXX: why do reg and dreg have to be exchanged */ emit_reg((dreg),(reg)); } -void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { - emit_rex(1,(dreg),0,(basereg)); +void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg) +{ + emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xb7; - emit_membase((basereg),(disp),(dreg)); + /* XXX: why do reg and dreg have to be exchanged */ + emit_reg((dreg),(reg)); } @@ -1215,7 +1207,7 @@ void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, emit_rex(1,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xbf; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -1223,7 +1215,7 @@ void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, emit_rex(1,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xbe; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -1231,7 +1223,7 @@ void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, emit_rex(1,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xb7; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -1239,7 +1231,7 @@ void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 inde { emit_rex(1,0,(indexreg),(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_memindex(0,(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale)); emit_imm32((imm)); } @@ -1248,7 +1240,7 @@ void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 ind { emit_rex(0,0,(indexreg),(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_memindex(0,(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale)); emit_imm32((imm)); } @@ -1258,7 +1250,7 @@ void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 ind *(cd->mcodeptr++) = 0x66; emit_rex(0,0,(indexreg),(basereg)); *(cd->mcodeptr++) = 0xc7; - emit_memindex(0,(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale)); emit_imm16((imm)); } @@ -1267,11 +1259,20 @@ void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 ind { emit_rex(0,0,(indexreg),(basereg)); *(cd->mcodeptr++) = 0xc6; - emit_memindex(0,(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, 0,(disp),(basereg),(indexreg),(scale)); emit_imm8((imm)); } +void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg) +{ + emit_rex(1, dreg, 0, 0); + *(cd->mcodeptr++) = 0x8b; + emit_address_byte(0, dreg, 4); + emit_mem(4, disp); +} + + /* * alu operations */ @@ -1291,31 +1292,35 @@ void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) } -void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) { +void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) +{ emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = (((opc)) << 3) + 1; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } -void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) { +void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp) +{ emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = (((opc)) << 3) + 1; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } -void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) { +void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) +{ emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = (((opc)) << 3) + 3; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } -void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) { +void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg) +{ emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = (((opc)) << 3) + 3; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -1334,7 +1339,8 @@ void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) { } -void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) { +void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg) +{ emit_rex(1,0,0,(dreg)); *(cd->mcodeptr++) = 0x81; emit_reg((opc),(dreg)); @@ -1342,6 +1348,15 @@ void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) { } +void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg) +{ + emit_rex(0,0,0,(dreg)); + *(cd->mcodeptr++) = 0x81; + emit_reg((opc),(dreg)); + emit_imm32((imm)); +} + + void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) { if (IS_IMM8(imm)) { emit_rex(0,0,0,(dreg)); @@ -1359,14 +1374,14 @@ void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg) { void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) { if (IS_IMM8(imm)) { - emit_rex(1,(basereg),0,0); + emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0x83; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm8((imm)); } else { - emit_rex(1,(basereg),0,0); + emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0x81; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm32((imm)); } } @@ -1374,18 +1389,31 @@ void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp) { if (IS_IMM8(imm)) { - emit_rex(0,(basereg),0,0); + emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0x83; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm8((imm)); } else { - emit_rex(0,(basereg),0,0); + emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0x81; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm32((imm)); } } +void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) +{ + emit_rex(1,(reg),(indexreg),(basereg)); + *(cd->mcodeptr++) = (((opc)) << 3) + 3; + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); +} + +void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg) +{ + emit_rex(0,(reg),(indexreg),(basereg)); + *(cd->mcodeptr++) = (((opc)) << 3) + 3; + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); +} void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg) { emit_rex(1,(reg),0,(dreg)); @@ -1426,81 +1454,46 @@ void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg) { void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_rex(1,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x8d; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x8d; - emit_membase((basereg),(disp),(reg)); -} - - - -/* - * inc, dec operations - */ -void emit_inc_reg(codegendata *cd, s8 reg) { - emit_rex(1,0,0,(reg)); - *(cd->mcodeptr++) = 0xff; - emit_reg(0,(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } -void emit_incl_reg(codegendata *cd, s8 reg) { - emit_rex(0,0,0,(reg)); +void emit_incl_reg(codegendata *cd, s8 reg) +{ *(cd->mcodeptr++) = 0xff; emit_reg(0,(reg)); } - -void emit_inc_membase(codegendata *cd, s8 basereg, s8 disp) +void emit_incq_reg(codegendata *cd, s8 reg) { - emit_rex(1,0,0,(basereg)); + emit_rex(1,0,0,(reg)); *(cd->mcodeptr++) = 0xff; - emit_membase((basereg),(disp),0); + emit_reg(0,(reg)); } - void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp) { emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0xff; - emit_membase((basereg),(disp),0); -} - - -void emit_dec_reg(codegendata *cd, s8 reg) { - emit_rex(1,0,0,(reg)); - *(cd->mcodeptr++) = 0xff; - emit_reg(1,(reg)); -} - - -void emit_decl_reg(codegendata *cd, s8 reg) { - emit_rex(0,0,0,(reg)); - *(cd->mcodeptr++) = 0xff; - emit_reg(1,(reg)); + emit_membase(cd, (basereg),(disp),0); } - -void emit_dec_membase(codegendata *cd, s8 basereg, s8 disp) { - emit_rex(1,(basereg),0,0); - *(cd->mcodeptr++) = 0xff; - emit_membase((basereg),(disp),1); -} - - -void emit_decl_membase(codegendata *cd, s8 basereg, s8 disp) { - emit_rex(0,(basereg),0,0); +void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp) +{ + emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xff; - emit_membase((basereg),(disp),1); + emit_membase(cd, (basereg),(disp),0); } - void emit_cltd(codegendata *cd) { *(cd->mcodeptr++) = 0x99; } @@ -1533,7 +1526,7 @@ void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(1,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xaf; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -1541,7 +1534,7 @@ void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xaf; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -1594,12 +1587,12 @@ void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 if (IS_IMM8((imm))) { emit_rex(1,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x6b; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); emit_imm8((imm)); } else { emit_rex(1,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x69; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); emit_imm32((imm)); } } @@ -1609,12 +1602,12 @@ void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 if (IS_IMM8((imm))) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x6b; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); emit_imm8((imm)); } else { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x69; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); emit_imm32((imm)); } } @@ -1635,12 +1628,6 @@ void emit_idivl_reg(codegendata *cd, s8 reg) { -void emit_ret(codegendata *cd) { - *(cd->mcodeptr++) = 0xc3; -} - - - /* * shift ops */ @@ -1661,14 +1648,14 @@ void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg) { void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) { emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xd3; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); } void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) { emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0xd3; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); } @@ -1704,11 +1691,11 @@ void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp if ((imm) == 1) { emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xd1; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); } else { emit_rex(1,0,0,(basereg)); *(cd->mcodeptr++) = 0xc1; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm8((imm)); } } @@ -1718,11 +1705,11 @@ void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 dis if ((imm) == 1) { emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0xd1; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); } else { emit_rex(0,0,0,(basereg)); *(cd->mcodeptr++) = 0xc1; - emit_membase((basereg),(disp),(opc)); + emit_membase(cd, (basereg),(disp),(opc)); emit_imm8((imm)); } } @@ -1737,6 +1724,18 @@ void emit_jmp_imm(codegendata *cd, s8 imm) { emit_imm32((imm)); } +/* like emit_jmp_imm but allows 8 bit optimization */ +void emit_jmp_imm2(codegendata *cd, s8 imm) { + if (IS_IMM8(imm)) { + *(cd->mcodeptr++) = 0xeb; + emit_imm8((imm)); + } + else { + *(cd->mcodeptr++) = 0xe9; + emit_imm32((imm)); + } +} + void emit_jmp_reg(codegendata *cd, s8 reg) { emit_rex(0,0,0,(reg)); @@ -1758,7 +1757,8 @@ void emit_jcc(codegendata *cd, s8 opc, s8 imm) { */ /* we need the rex byte to get all low bytes */ -void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) { +void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg) +{ *(cd->mcodeptr++) = (0x40 | (((reg) >> 3) & 0x01)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = (0x90 + (opc)); @@ -1767,15 +1767,16 @@ void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg) { /* we need the rex byte to get all low bytes */ -void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp) { +void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp) +{ *(cd->mcodeptr++) = (0x40 | (((basereg) >> 3) & 0x01)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = (0x90 + (opc)); - emit_membase((basereg),(disp),0); + emit_membase(cd, (basereg),(disp),0); } -void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) +void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg) { emit_rex(1,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; @@ -1784,7 +1785,7 @@ void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) } -void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) +void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg) { emit_rex(0,(dreg),0,(reg)); *(cd->mcodeptr++) = 0x0f; @@ -1793,35 +1794,22 @@ void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg) } - -void emit_neg_reg(codegendata *cd, s8 reg) { +void emit_neg_reg(codegendata *cd, s8 reg) +{ emit_rex(1,0,0,(reg)); *(cd->mcodeptr++) = 0xf7; emit_reg(3,(reg)); } -void emit_negl_reg(codegendata *cd, s8 reg) { +void emit_negl_reg(codegendata *cd, s8 reg) +{ emit_rex(0,0,0,(reg)); *(cd->mcodeptr++) = 0xf7; emit_reg(3,(reg)); } -void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp) { - emit_rex(1,0,0,(basereg)); - *(cd->mcodeptr++) = 0xf7; - emit_membase((basereg),(disp),3); -} - - -void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp) { - emit_rex(0,0,0,(basereg)); - *(cd->mcodeptr++) = 0xf7; - emit_membase((basereg),(disp),3); -} - - void emit_push_reg(codegendata *cd, s8 reg) { emit_rex(0,0,0,(reg)); *(cd->mcodeptr++) = 0x50 + (0x07 & (reg)); @@ -1847,23 +1835,20 @@ void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg) { } -void emit_nop(codegendata *cd) { - *(cd->mcodeptr++) = 0x90; -} - - /* * call instructions */ -void emit_call_reg(codegendata *cd, s8 reg) { - emit_rex(1,0,0,(reg)); +void emit_call_reg(codegendata *cd, s8 reg) +{ + emit_rex(0,0,0,(reg)); *(cd->mcodeptr++) = 0xff; emit_reg(2,(reg)); } -void emit_call_imm(codegendata *cd, s8 imm) { +void emit_call_imm(codegendata *cd, s8 imm) +{ *(cd->mcodeptr++) = 0xe8; emit_imm32((imm)); } @@ -2029,7 +2014,7 @@ void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x7e; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2038,7 +2023,7 @@ void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 ind emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x7e; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -2047,7 +2032,7 @@ void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(1,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x6e; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2056,7 +2041,7 @@ void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x6e; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2065,7 +2050,7 @@ void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s emit_rex(0,(dreg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x6e; - emit_memindex((dreg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale)); } @@ -2083,7 +2068,7 @@ void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0xd6; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2092,7 +2077,7 @@ void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x7e; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2119,7 +2104,7 @@ void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2130,7 +2115,7 @@ void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_byte_rex((reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } @@ -2139,7 +2124,7 @@ void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_rex(0,(reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_membase((basereg),(disp),(reg)); + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2150,7 +2135,7 @@ void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp) { emit_byte_rex((reg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_membase32((basereg),(disp),(reg)); + emit_membase32(cd, (basereg),(disp),(reg)); } @@ -2159,7 +2144,7 @@ void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2170,15 +2155,25 @@ void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_byte_rex((dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_membase32((basereg),(disp),(dreg)); + emit_membase32(cd, (basereg),(disp),(dreg)); } -void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { +void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) +{ emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x12; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); +} + + +void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) +{ + emit_rex(0,(reg),0,(basereg)); + *(cd->mcodeptr++) = 0x0f; + *(cd->mcodeptr++) = 0x13; + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2187,7 +2182,7 @@ void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2198,16 +2193,27 @@ void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_byte_rex((dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_membase32((basereg),(disp),(dreg)); + emit_membase32(cd, (basereg),(disp),(dreg)); } -void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { +void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) +{ *(cd->mcodeptr++) = 0x66; emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x12; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); +} + + +void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp) +{ + *(cd->mcodeptr++) = 0x66; + emit_rex(0,(reg),0,(basereg)); + *(cd->mcodeptr++) = 0x0f; + *(cd->mcodeptr++) = 0x13; + emit_membase(cd, (basereg),(disp),(reg)); } @@ -2216,7 +2222,7 @@ void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 in emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -2225,7 +2231,7 @@ void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 in emit_rex(0,(reg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x11; - emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (reg),(disp),(basereg),(indexreg),(scale)); } @@ -2234,7 +2240,7 @@ void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, emit_rex(0,(dreg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_memindex((dreg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale)); } @@ -2243,7 +2249,7 @@ void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, emit_rex(0,(dreg),(indexreg),(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x10; - emit_memindex((dreg),(disp),(basereg),(indexreg),(scale)); + emit_memindex(cd, (dreg),(disp),(basereg),(indexreg),(scale)); } @@ -2312,7 +2318,7 @@ void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x57; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); } @@ -2330,7 +2336,7 @@ void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg) { emit_rex(0,(dreg),0,(basereg)); *(cd->mcodeptr++) = 0x0f; *(cd->mcodeptr++) = 0x57; - emit_membase((basereg),(disp),(dreg)); + emit_membase(cd, (basereg),(disp),(dreg)); }