X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fi386%2Fcodegen.h;h=375154c059cd69940cf299ad122852a867126257;hb=2ab77f5d50859fe9849586d1be0382fb61856b8f;hp=b2e2592717cdbf5da989edffe14c4edfb86057d8;hpb=3163afd729387f4c336311b81878ae45fcfc306c;p=cacao.git diff --git a/src/vm/jit/i386/codegen.h b/src/vm/jit/i386/codegen.h index b2e259271..375154c05 100644 --- a/src/vm/jit/i386/codegen.h +++ b/src/vm/jit/i386/codegen.h @@ -1,9 +1,7 @@ /* src/vm/jit/i386/codegen.h - code generation macros and definitions for i386 - 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,15 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Andreas Krall - Christian Thalinger - - Changes: - - $Id: codegen.h 4366 2006-01-23 16:03:50Z twisti $ - */ @@ -38,12 +27,11 @@ #define _CODEGEN_H #include "config.h" - -#include - #include "vm/types.h" -#include "vm/jit/jit.h" +#include "vm/jit/i386/emit.h" + +#include "vm/jit/jit.hpp" #if defined(ENABLE_LSRA) @@ -51,10 +39,6 @@ # define LSRA_USES_REG_RES #endif -/* some defines ***************************************************************/ - -#define PATCHER_CALL_SIZE 5 /* size in bytes of a patcher call */ - /* additional functions and macros to generate code ***************************/ @@ -69,462 +53,281 @@ else (var) += 1; -/* gen_nullptr_check(objreg) */ - -#define gen_nullptr_check(objreg) \ - if (checknull) { \ - i386_test_reg_reg(cd, (objreg), (objreg)); \ - i386_jcc(cd, I386_CC_E, 0); \ - codegen_addxnullrefs(cd, cd->mcodeptr); \ - } - -#define gen_bound_check \ - if (checkbounds) { \ - i386_alu_membase_reg(cd, ALU_CMP, s1, OFFSET(java_arrayheader, size), s2); \ - i386_jcc(cd, I386_CC_AE, 0); \ - codegen_addxboundrefs(cd, cd->mcodeptr, s2); \ - } - -#define gen_div_check(v) \ - if (checknull) { \ - if ((v)->flags & INMEMORY) { \ - i386_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4); \ - } else { \ - i386_test_reg_reg(cd, src->regoff, src->regoff); \ - } \ - i386_jcc(cd, I386_CC_E, 0); \ - codegen_addxdivrefs(cd, cd->mcodeptr); \ - } +#define ALIGNCODENOP \ + do { \ + for (s1 = 0; s1 < (s4) (((ptrint) cd->mcodeptr) & 7); s1++) \ + M_NOP; \ + } while (0) /* MCODECHECK(icnt) */ #define MCODECHECK(icnt) \ - if ((cd->mcodeptr + (icnt)) > (u1 *) cd->mcodeend) \ - cd->mcodeptr = (u1 *) codegen_increase(cd, cd->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. -*/ + do { \ + if ((cd->mcodeptr + (icnt)) > (u1 *) cd->mcodeend) \ + codegen_increase(cd); \ + } while (0) -#define M_INTMOVE(reg,dreg) \ - if ((reg) != (dreg)) { \ - i386_mov_reg_reg(cd, (reg),(dreg)); \ - } +#define M_FMOV(reg,dreg) \ + do { \ + log_text("M_FMOV"); \ + assert(0); \ + } while (0) -/* 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_DMOV(a,b) M_FMOV(a,b) -#define M_FLTMOVE(reg,dreg) \ +#define ICONST(d,c) \ do { \ - log_text("M_FLTMOVE"); \ - assert(0); \ + if ((c) == 0) \ + M_CLR(d); \ + else \ + M_MOV_IMM((c), d); \ } while (0) -#define M_LNGMEMMOVE(reg,dreg) \ +#define LCONST(d,c) \ do { \ - i386_mov_membase_reg(cd, REG_SP, (reg) * 4, REG_ITMP1); \ - i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (dreg) * 4); \ - i386_mov_membase_reg(cd, REG_SP, (reg) * 4 + 4, REG_ITMP1); \ - i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (dreg) * 4 + 4); \ + if ((c) == 0) { \ + M_CLR(GET_LOW_REG(d)); \ + M_CLR(GET_HIGH_REG(d)); \ + } else { \ + M_MOV_IMM((c), GET_LOW_REG(d)); \ + M_MOV_IMM((c) >> 32, GET_HIGH_REG(d)); \ + } \ } while (0) -/* 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 +/* branch defines *************************************************************/ - 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 BRANCH_UNCONDITIONAL_SIZE 5 /* size in bytes of a branch */ +#define BRANCH_CONDITIONAL_SIZE 6 /* size in bytes of a branch */ -#define var_to_reg_int(regnr,v,tempnr) \ - if ((v)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_mov_membase_reg(cd, REG_SP, (v)->regoff * 4, tempnr); \ - regnr = tempnr; \ - } else { \ - regnr = (v)->regoff; \ - } +#define BRANCH_NOPS \ + do { \ + M_NOP; \ + M_NOP; \ + M_NOP; \ + M_NOP; \ + M_NOP; \ + M_NOP; \ + } while (0) +/* patcher defines ************************************************************/ + +#define PATCHER_CALL_SIZE 2 /* size in bytes of a patcher call */ + +#define PATCHER_NOPS \ + do { \ + M_NOP; \ + M_NOP; \ + } while (0) -#define var_to_reg_flt(regnr,v,tempnr) \ - if ((v)->type == TYPE_FLT) { \ - if ((v)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_flds_membase(cd, REG_SP, (v)->regoff * 4); \ - fpu_st_offset++; \ - regnr = tempnr; \ - } else { \ - i386_fld_reg(cd, (v)->regoff + fpu_st_offset); \ - fpu_st_offset++; \ - regnr = (v)->regoff; \ - } \ - } else { \ - if ((v)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_fldl_membase(cd, REG_SP, (v)->regoff * 4); \ - fpu_st_offset++; \ - regnr = tempnr; \ - } else { \ - i386_fld_reg(cd, (v)->regoff + fpu_st_offset); \ - fpu_st_offset++; \ - regnr = (v)->regoff; \ - } \ - } - -#define NEW_var_to_reg_flt(regnr,v,tempnr) \ - if ((v)->type == TYPE_FLT) { \ - if ((v)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_flds_membase(cd, REG_SP, (v)->regoff * 4); \ - fpu_st_offset++; \ - regnr = tempnr; \ - } else { \ - regnr = (v)->regoff; \ - } \ - } else { \ - if ((v)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_fldl_membase(cd, REG_SP, (v)->regoff * 4); \ - fpu_st_offset++; \ - 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; \ - i386_mov_reg_membase(cd, tempregnum, REG_SP, (sptr)->regoff * 4); \ - } - - -#define store_reg_to_var_flt(sptr, tempregnum) \ - if ((sptr)->type == TYPE_FLT) { \ - if ((sptr)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_fstps_membase(cd, REG_SP, (sptr)->regoff * 4); \ - fpu_st_offset--; \ - } else { \ -/* i386_fxch_reg((sptr)->regoff);*/ \ - i386_fstp_reg(cd, (sptr)->regoff + fpu_st_offset); \ - fpu_st_offset--; \ - } \ - } else { \ - if ((sptr)->flags & INMEMORY) { \ - COUNT_SPILLS; \ - i386_fstpl_membase(cd, REG_SP, (sptr)->regoff * 4); \ - fpu_st_offset--; \ - } else { \ -/* i386_fxch_reg((sptr)->regoff);*/ \ - i386_fstp_reg(cd, (sptr)->regoff + fpu_st_offset); \ - fpu_st_offset--; \ - } \ - } - - -#define M_COPY(from,to) \ - d = reg_of_var(rd, to, REG_ITMP1); \ - if ((from->regoff != to->regoff) || \ - ((from->flags ^ to->flags) & INMEMORY)) { \ - if (IS_FLT_DBL_TYPE(from->type)) { \ - var_to_reg_flt(s1, from, d); \ - /*M_FLTMOVE(s1, d);*/ \ - store_reg_to_var_flt(to, d); \ - } else { \ - if (!IS_2_WORD_TYPE(from->type)) { \ - if (to->flags & INMEMORY) { \ - if (from->flags & INMEMORY) { \ - i386_mov_membase_reg(cd, REG_SP, from->regoff * 4, REG_ITMP1); \ - i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, to->regoff * 4); \ - } else { \ - i386_mov_reg_membase(cd, from->regoff, REG_SP, to->regoff * 4); \ - } \ - } else { \ - if (from->flags & INMEMORY) { \ - i386_mov_membase_reg(cd, REG_SP, from->regoff * 4, to->regoff); \ - } else { \ - i386_mov_reg_reg(cd, from->regoff, to->regoff); \ - } \ - } \ - } else { \ - M_LNGMEMMOVE(from->regoff, to->regoff); \ - } \ - } \ - } /* macros to create code ******************************************************/ -typedef enum { - REG_AL = 0, - REG_CL = 1, - REG_DL = 2, - REG_BL = 3, - REG_AH = 4, - REG_CH = 5, - REG_DH = 6, - REG_BH = 7, - REG_NREGB -} I386_RegB_No; - - -/* opcodes for alu instructions */ - -typedef enum { - ALU_ADD = 0, - ALU_OR = 1, - ALU_ADC = 2, - ALU_SBB = 3, - ALU_AND = 4, - ALU_SUB = 5, - ALU_XOR = 6, - ALU_CMP = 7, - ALU_NALU -} I386_ALU_Opcode; - -typedef enum { - I386_ROL = 0, - I386_ROR = 1, - I386_RCL = 2, - I386_RCR = 3, - I386_SHL = 4, - I386_SHR = 5, - I386_SAR = 7, - I386_NSHIFT = 8 -} I386_Shift_Opcode; - -typedef enum { - I386_CC_O = 0, - I386_CC_NO = 1, - I386_CC_B = 2, I386_CC_C = 2, I386_CC_NAE = 2, - I386_CC_BE = 6, I386_CC_NA = 6, - I386_CC_AE = 3, I386_CC_NB = 3, I386_CC_NC = 3, - I386_CC_E = 4, I386_CC_Z = 4, - I386_CC_NE = 5, I386_CC_NZ = 5, - I386_CC_A = 7, I386_CC_NBE = 7, - I386_CC_S = 8, I386_CC_LZ = 8, - I386_CC_NS = 9, I386_CC_GEZ = 9, - I386_CC_P = 0x0a, I386_CC_PE = 0x0a, - I386_CC_NP = 0x0b, I386_CC_PO = 0x0b, - I386_CC_L = 0x0c, I386_CC_NGE = 0x0c, - I386_CC_GE = 0x0d, I386_CC_NL = 0x0d, - I386_CC_LE = 0x0e, I386_CC_NG = 0x0e, - I386_CC_G = 0x0f, I386_CC_NLE = 0x0f, - I386_NCC -} I386_CC; - - -/* modrm and stuff */ - -#define i386_address_byte(mod,reg,rm) \ - *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07))); - - -#define i386_emit_reg(reg,rm) \ - i386_address_byte(3,(reg),(rm)); - - -#define i386_is_imm8(imm) \ - (((int)(imm) >= -128 && (int)(imm) <= 127)) - - -#define i386_emit_imm8(imm) \ - *(cd->mcodeptr++) = (u1) ((imm) & 0xff); - - -#define i386_emit_imm16(imm) \ +#define M_BYTE1(a) \ do { \ - imm_union imb; \ - imb.i = (int) (imm); \ - *(cd->mcodeptr++) = imb.b[0]; \ - *(cd->mcodeptr++) = imb.b[1]; \ + *(cd->mcodeptr) = (a); \ + cd->mcodeptr++; \ } while (0) -#define i386_emit_imm32(imm) \ +#define M_BYTE2(a, b) \ do { \ - imm_union imb; \ - imb.i = (int) (imm); \ - *(cd->mcodeptr++) = imb.b[0]; \ - *(cd->mcodeptr++) = imb.b[1]; \ - *(cd->mcodeptr++) = imb.b[2]; \ - *(cd->mcodeptr++) = imb.b[3]; \ + M_BYTE1(a); \ + M_BYTE1(b); \ } while (0) -#define i386_emit_mem(r,mem) \ +#define M_ILD(a,b,disp) emit_mov_membase_reg(cd, (b), (disp), (a)) +#define M_ILD32(a,b,disp) emit_mov_membase32_reg(cd, (b), (disp), (a)) + +#define M_ALD(a,b,disp) M_ILD(a,b,disp) +#define M_ALD32(a,b,disp) M_ILD32(a,b,disp) + +#define M_ALD_MEM(a,disp) emit_mov_mem_reg(cd, (disp), (a)) + +#define M_ALD_MEM_GET_OPC(p) (*(p)) +#define M_ALD_MEM_GET_MOD(p) (((*(p + 1)) >> 6) & 0x03) +#define M_ALD_MEM_GET_REG(p) (((*(p + 1)) >> 3) & 0x07) +#define M_ALD_MEM_GET_RM(p) (((*(p + 1)) ) & 0x07) +#define M_ALD_MEM_GET_DISP(p) (*((u4 *) (p + 2))) + +#define M_LLD(a,b,disp) \ do { \ - i386_address_byte(0,(r),5); \ - i386_emit_imm32((mem)); \ + M_ILD(GET_LOW_REG(a),b,disp); \ + M_ILD(GET_HIGH_REG(a),b,disp + 4); \ } while (0) - -#define i386_emit_membase(basereg,disp,dreg) \ +#define M_LLD32(a,b,disp) \ do { \ - if ((basereg) == ESP) { \ - if ((disp) == 0) { \ - i386_address_byte(0, (dreg), ESP); \ - i386_address_byte(0, ESP, ESP); \ - } else if (i386_is_imm8((disp))) { \ - i386_address_byte(1, (dreg), ESP); \ - i386_address_byte(0, ESP, ESP); \ - i386_emit_imm8((disp)); \ - } else { \ - i386_address_byte(2, (dreg), ESP); \ - i386_address_byte(0, ESP, ESP); \ - i386_emit_imm32((disp)); \ - } \ - break; \ - } \ - \ - if ((disp) == 0 && (basereg) != EBP) { \ - i386_address_byte(0, (dreg), (basereg)); \ - break; \ - } \ - \ - if (i386_is_imm8((disp))) { \ - i386_address_byte(1, (dreg), (basereg)); \ - i386_emit_imm8((disp)); \ - } else { \ - i386_address_byte(2, (dreg), (basereg)); \ - i386_emit_imm32((disp)); \ - } \ + M_ILD32(GET_LOW_REG(a),b,disp); \ + M_ILD32(GET_HIGH_REG(a),b,disp + 4); \ } while (0) +#define M_IST(a,b,disp) emit_mov_reg_membase(cd, (a), (b), (disp)) +#define M_IST_IMM(a,b,disp) emit_mov_imm_membase(cd, (u4) (a), (b), (disp)) +#define M_AST(a,b,disp) M_IST(a,b,disp) +#define M_AST_IMM(a,b,disp) M_IST_IMM(a,b,disp) + +#define M_IST32(a,b,disp) emit_mov_reg_membase32(cd, (a), (b), (disp)) +#define M_IST32_IMM(a,b,disp) emit_mov_imm_membase32(cd, (u4) (a), (b), (disp)) -#define i386_emit_membase32(basereg,disp,dreg) \ +#define M_LST(a,b,disp) \ do { \ - if ((basereg) == ESP) { \ - i386_address_byte(2, (dreg), ESP); \ - i386_address_byte(0, ESP, ESP); \ - i386_emit_imm32((disp)); \ - } else { \ - i386_address_byte(2, (dreg), (basereg)); \ - i386_emit_imm32((disp)); \ - } \ + M_IST(GET_LOW_REG(a),b,disp); \ + M_IST(GET_HIGH_REG(a),b,disp + 4); \ } while (0) +#define M_LST32(a,b,disp) \ + do { \ + M_IST32(GET_LOW_REG(a),b,disp); \ + M_IST32(GET_HIGH_REG(a),b,disp + 4); \ + } while (0) -#define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \ +#define M_LST_IMM(a,b,disp) \ do { \ - if ((basereg) == -1) { \ - i386_address_byte(0, (reg), 4); \ - i386_address_byte((scale), (indexreg), 5); \ - i386_emit_imm32((disp)); \ - \ - } else if ((disp) == 0 && (basereg) != EBP) { \ - i386_address_byte(0, (reg), 4); \ - i386_address_byte((scale), (indexreg), (basereg)); \ - \ - } else if (i386_is_imm8((disp))) { \ - i386_address_byte(1, (reg), 4); \ - i386_address_byte((scale), (indexreg), (basereg)); \ - i386_emit_imm8 ((disp)); \ - \ - } else { \ - i386_address_byte(2, (reg), 4); \ - i386_address_byte((scale), (indexreg), (basereg)); \ - i386_emit_imm32((disp)); \ - } \ - } while (0) + M_IST_IMM(a,b,disp); \ + M_IST_IMM(a >> 32,b,disp + 4); \ + } while (0) +#define M_LST32_IMM(a,b,disp) \ + do { \ + M_IST32_IMM(a,b,disp); \ + M_IST32_IMM(a >> 32,b,disp + 4); \ + } while (0) -/* macros to create code ******************************************************/ +#define M_IADD(a,b) emit_alu_reg_reg(cd, ALU_ADD, (a), (b)) +#define M_ISUB(a,b) emit_alu_reg_reg(cd, ALU_SUB, (a), (b)) +#define M_IMUL(a,b) emit_imul_reg_reg(cd, (a), (b)) +#define M_IDIV(a) emit_idiv_reg(cd, (a)) -#define M_ILD(a,b,disp) i386_mov_membase_reg(cd, (b), (disp), (a)) -#define M_ALD(a,b,disp) M_ILD(a,b,disp) +#define M_MUL(a) emit_mul_reg(cd, (a)) -#define M_IST(a,b,disp) i386_mov_reg_membase(cd, (a), (b), (disp)) -#define M_IST_IMM(a,b,disp) i386_mov_imm_membase(cd, (a), (b), (disp)) -#define M_AST(a,b,disp) M_IST(a,b,disp) -#define M_AST_IMM(a,b,disp) M_IST_IMM(a,b,disp) +#define M_IADD_IMM(a,b) emit_alu_imm_reg(cd, ALU_ADD, (a), (b)) +#define M_ISUB_IMM(a,b) emit_alu_imm_reg(cd, ALU_SUB, (a), (b)) +#define M_IMUL_IMM(a,b,c) emit_imul_imm_reg_reg(cd, (b), (a), (c)) + +#define M_IADD_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_ADD, (a), (b)) +#define M_ISUB_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_SUB, (a), (b)) + +#define M_IADD_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_ADD, (a), (b), (c)) + +#define M_ISUB_IMM_MEMABS(a,b) emit_alu_imm_memabs(cd, ALU_SUB, (a), (b)) -#define M_IADD_IMM(a,b) i386_alu_imm_reg(cd, ALU_ADD, (a), (b)) -#define M_IADD_IMM32(a,b) i386_alu_imm32_reg(cd, ALU_ADD, (a), (b)) -#define M_ISUB_IMM(a,b) i386_alu_imm_reg(cd, ALU_SUB, (a), (b)) +#define M_IINC(a) emit_inc_reg(cd, (a)) + +#define M_IADDC(a,b) emit_alu_reg_reg(cd, ALU_ADC, (a), (b)) +#define M_ISUBB(a,b) emit_alu_reg_reg(cd, ALU_SBB, (a), (b)) + +#define M_IADDC_IMM(a,b) emit_alu_imm_reg(cd, ALU_ADC, (a), (b)) +#define M_ISUBB_IMM(a,b) emit_alu_imm_reg(cd, ALU_SBB, (a), (b)) #define M_AADD_IMM(a,b) M_IADD_IMM(a,b) #define M_AADD_IMM32(a,b) M_IADD_IMM32(a,b) #define M_ASUB_IMM(a,b) M_ISUB_IMM(a,b) -#define M_OR_MEMBASE(a,b,c) i386_alu_membase_reg(cd, ALU_OR, (a), (b), (c)) -#define M_XOR(a,b) i386_alu_reg_reg(cd, ALU_XOR, (a), (b)) +#define M_NEG(a) emit_neg_reg(cd, (a)) + +#define M_AND(a,b) emit_alu_reg_reg(cd, ALU_AND, (a), (b)) +#define M_OR(a,b) emit_alu_reg_reg(cd, ALU_OR, (a), (b)) +#define M_XOR(a,b) emit_alu_reg_reg(cd, ALU_XOR, (a), (b)) + +#define M_AND_IMM(a,b) emit_alu_imm_reg(cd, ALU_AND, (a), (b)) +#define M_OR_IMM(a,b) emit_alu_imm_reg(cd, ALU_OR, (a), (b)) +#define M_XOR_IMM(a,b) emit_alu_imm_reg(cd, ALU_XOR, (a), (b)) + +#define M_AND_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_AND, (a), (b)) + #define M_CLR(a) M_XOR(a,a) -#define M_PUSH(a) i386_push_reg(cd, (a)) -#define M_PUSH_IMM(a) i386_push_imm(cd, (a)) -#define M_POP(a) i386_pop_reg(cd, (a)) +#define M_PUSH(a) emit_push_reg(cd, (a)) +#define M_PUSH_IMM(a) emit_push_imm(cd, (s4) (a)) +#define M_POP(a) emit_pop_reg(cd, (a)) + +#define M_MOV(a,b) emit_mov_reg_reg(cd, (a), (b)) +#define M_MOV_IMM(a,b) emit_mov_imm_reg(cd, (u4) (a), (b)) +#define M_MOV_IMM2(a,b) emit_mov_imm2_reg(cd, (u4) (a), (b)) + +#define M_TEST(a) emit_test_reg_reg(cd, (a), (a)) +#define M_TEST_IMM(a,b) emit_test_imm_reg(cd, (a), (b)) + +#define M_CMP(a,b) emit_alu_reg_reg(cd, ALU_CMP, (a), (b)) +#define M_CMP_MEMBASE(a,b,c) emit_alu_membase_reg(cd, ALU_CMP, (a), (b), (c)) +#define M_CMP_MEMINDEX(a,b,c,d,e) emit_alu_memindex_reg(cd, ALU_CMP, (b), (a), (c), (d), (e)) + +#define M_CMP_IMM(a,b) emit_alu_imm_reg(cd, ALU_CMP, (a), (b)) +#define M_CMP_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_CMP, (a), (b), (c)) + +#define M_CMP_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_CMP, (a), (b)) + +#define M_BSEXT(a,b) emit_movsbl_reg_reg(cd, (a), (b)) +#define M_SSEXT(a,b) emit_movswl_reg_reg(cd, (a), (b)) + +#define M_BZEXT(a,b) emit_movzbl_reg_reg(cd, (a), (b)) +#define M_CZEXT(a,b) emit_movzwl_reg_reg(cd, (a), (b)) + +#define M_CLTD M_BYTE1(0x99) + +#define M_SLL(a) emit_shift_reg(cd, SHIFT_SHL, (a)) +#define M_SRA(a) emit_shift_reg(cd, SHIFT_SAR, (a)) +#define M_SRL(a) emit_shift_reg(cd, SHIFT_SHR, (a)) -#define M_MOV(a,b) i386_mov_reg_reg(cd, (a), (b)) -#define M_MOV_IMM(a,b) i386_mov_imm_reg(cd, (a), (b)) +#define M_SLL_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SHL, (a), (b)) +#define M_SRA_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SAR, (a), (b)) +#define M_SRL_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SHR, (a), (b)) -#define M_TEST(a) i386_test_reg_reg(cd, (a), (a)) +#define M_SLLD(a,b) emit_shld_reg_reg(cd, (a), (b)) +#define M_SRLD(a,b) emit_shrd_reg_reg(cd, (a), (b)) -#define M_CALL(a) i386_call_reg(cd, (a)) -#define M_CALL_IMM(a) i386_call_imm(cd, (a)) -#define M_RET i386_ret(cd) +#define M_SLLD_IMM(a,b,c) emit_shld_imm_reg_reg(cd, (a), (b), (c)) +#define M_SRLD_IMM(a,b,c) emit_shrd_imm_reg_reg(cd, (a), (b), (c)) -#define M_BEQ(a) i386_jcc(cd, I386_CC_E, (a)) -#define M_BNE(a) i386_jcc(cd, I386_CC_NE, (a)) -#define M_BLT(a) i386_jcc(cd, I386_CC_L, (a)) -#define M_BLE(a) i386_jcc(cd, I386_CC_LE, (a)) -#define M_BGE(a) i386_jcc(cd, I386_CC_GE, (a)) -#define M_BGT(a) i386_jcc(cd, I386_CC_G, (a)) +#define M_CALL(a) emit_call_reg(cd, (a)) +#define M_CALL_IMM(a) emit_call_imm(cd, (a)) +#define M_RET M_BYTE1(0xc3) -#define M_BBE(a) i386_jcc(cd, I386_CC_BE, (a)) -#define M_BAE(a) i386_jcc(cd, I386_CC_AE, (a)) +#define M_ACMP(a,b) M_CMP(a,b) -#define M_JMP(a) i386_jmp_reg(cd, (a)) -#define M_JMP_IMM(a) i386_jmp_imm(cd, (a)) +#define M_ICMP(a,b) M_CMP(a,b) +#define M_ICMP_IMM(a,b) emit_alu_imm_reg(cd, ALU_CMP, (a), (b)) -#define M_NOP i386_nop(cd) +#define M_BEQ(a) emit_jcc(cd, CC_E, (a)) +#define M_BNE(a) emit_jcc(cd, CC_NE, (a)) +#define M_BLT(a) emit_jcc(cd, CC_L, (a)) +#define M_BLE(a) emit_jcc(cd, CC_LE, (a)) +#define M_BGE(a) emit_jcc(cd, CC_GE, (a)) +#define M_BGT(a) emit_jcc(cd, CC_G, (a)) +#define M_BB(a) emit_jcc(cd, CC_B, (a)) +#define M_BBE(a) emit_jcc(cd, CC_BE, (a)) +#define M_BAE(a) emit_jcc(cd, CC_AE, (a)) +#define M_BA(a) emit_jcc(cd, CC_A, (a)) +#define M_BNS(a) emit_jcc(cd, CC_NS, (a)) +#define M_BS(a) emit_jcc(cd, CC_S, (a)) -/* function gen_resolvebranch ************************************************** +#define M_SETE(a) emit_setcc_reg(cd, CC_E, (a)) - backpatches a branch instruction +#define M_JMP(a) emit_jmp_reg(cd, (a)) +#define M_JMP_IMM(a) emit_jmp_imm(cd, (a)) - parameters: ip ... pointer to instruction after branch (void*) - so ... offset of instruction after branch (s4) - to ... offset of branch target (s4) +#define M_NOP M_BYTE1(0x90) +#define M_UD2 M_BYTE2(0x0f, 0x0b) -*******************************************************************************/ -#define gen_resolvebranch(ip,so,to) \ - *((void **) ((ip) - 4)) = (void **) ((to) - (so)); +#define M_FLD(a,b,disp) emit_flds_membase(cd, (b), (disp)) +#define M_DLD(a,b,disp) emit_fldl_membase(cd, (b), (disp)) +#define M_FLD32(a,b,disp) emit_flds_membase32(cd, (b), (disp)) +#define M_DLD32(a,b,disp) emit_fldl_membase32(cd, (b), (disp)) -/* function prototypes */ +#define M_FST(a,b,disp) emit_fstps_membase(cd, (b), (disp)) +#define M_DST(a,b,disp) emit_fstpl_membase(cd, (b), (disp)) -void thread_restartcriticalsection(ucontext_t *); +#define M_FSTNP(a,b,disp) emit_fsts_membase(cd, (b), (disp)) +#define M_DSTNP(a,b,disp) emit_fstl_membase(cd, (b), (disp)) #endif /* _CODEGEN_H */