/* src/vm/jit/x86_64/emit.h - machine dependent emit function prototypes Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _MD_EMIT_H #define _MD_EMIT_H #include "config.h" #include "vm/types.h" #include "vm/jit/codegen-common.hpp" #include "vm/jit/jit.hpp" /* macros to create code ******************************************************/ /* immediate data union */ typedef union { s4 i; s8 l; float f; double d; void *a; u1 b[8]; } imm_buf; /* opcodes for alu instructions */ #define ALU_ADD 0 #define ALU_OR 1 #define ALU_ADC 2 #define ALU_SBB 3 #define ALU_AND 4 #define ALU_SUB 5 #define ALU_XOR 6 #define ALU_CMP 7 #define SHIFT_ROL 0 #define SHIFT_ROR 1 #define SHIFT_RCL 2 #define SHIFT_RCR 3 #define SHIFT_SHL 4 #define SHIFT_SHR 5 #define SHIFT_SAR 7 #define CC_O 0 #define CC_NO 1 #define CC_B 2 #define CC_C 2 #define CC_NAE 2 #define CC_AE 3 #define CC_NB 3 #define CC_NC 3 #define CC_E 4 #define CC_Z 4 #define CC_NE 5 #define CC_NZ 5 #define CC_BE 6 #define CC_NA 6 #define CC_A 7 #define CC_NBE 7 #define CC_S 8 #define CC_LZ 8 #define CC_NS 9 #define CC_GEZ 9 #define CC_P 0x0a #define CC_PE 0x0a #define CC_NP 0x0b #define CC_PO 0x0b #define CC_L 0x0c #define CC_NGE 0x0c #define CC_GE 0x0d #define CC_NL 0x0d #define CC_LE 0x0e #define CC_NG 0x0e #define CC_G 0x0f #define CC_NLE 0x0f /* modrm and stuff */ #define emit_address_byte(mod,reg,rm) \ do { \ *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | ((rm) & 0x07)); \ } while (0); #define emit_rex(size,reg,index,rm) \ do { \ if (((size) == 1) || ((reg) > 7) || ((index) > 7) || ((rm) > 7)) \ *(cd->mcodeptr++) = (0x40 | (((size) & 0x01) << 3) | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \ } while (0) #define emit_byte_rex(reg,index,rm) \ do { \ *(cd->mcodeptr++) = (0x40 | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \ } while (0) #define emit_mem(r,disp) \ do { \ emit_address_byte(0,(r),5); \ emit_imm32((disp)); \ } while (0) #define emit_imm8(imm) \ do { \ *(cd->mcodeptr++) = (u1) ((imm) & 0xff); \ } while (0) #define emit_imm16(imm) \ do { \ imm_buf imb; \ imb.i = (s4) (imm); \ *(cd->mcodeptr++) = imb.b[0]; \ *(cd->mcodeptr++) = imb.b[1]; \ } while (0) #define emit_imm32(imm) \ do { \ imm_buf imb; \ imb.i = (s4) (imm); \ *(cd->mcodeptr++) = imb.b[0]; \ *(cd->mcodeptr++) = imb.b[1]; \ *(cd->mcodeptr++) = imb.b[2]; \ *(cd->mcodeptr++) = imb.b[3]; \ } while (0) #define emit_imm64(imm) \ do { \ imm_buf imb; \ imb.l = (s8) (imm); \ *(cd->mcodeptr++) = imb.b[0]; \ *(cd->mcodeptr++) = imb.b[1]; \ *(cd->mcodeptr++) = imb.b[2]; \ *(cd->mcodeptr++) = imb.b[3]; \ *(cd->mcodeptr++) = imb.b[4]; \ *(cd->mcodeptr++) = imb.b[5]; \ *(cd->mcodeptr++) = imb.b[6]; \ *(cd->mcodeptr++) = imb.b[7]; \ } while (0) /* convenience macros *********************************************************/ #define emit_reg(reg,rm) emit_address_byte(3,(reg),(rm)) /* function prototypes ********************************************************/ #ifdef __cplusplus extern "C" { #endif void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d); /* code generation prototypes */ void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr); void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr); /* integer instructions */ void emit_nop(codegendata *cd, int length); void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg); void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg); 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); void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg); void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg); void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp); 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); void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); 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); 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); void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale); void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale); void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale); void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale); void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg); void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg); 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_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp); void emit_alu_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); void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg); void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg); void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg); 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); void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp); void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg); void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg); void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg); void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg); void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg); void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg); void emit_incl_reg(codegendata *cd, s8 reg); void emit_incq_reg(codegendata *cd, s8 reg); void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp); void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp); void emit_cltd(codegendata *cd); void emit_cqto(codegendata *cd); void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg); void emit_imul_imm_reg_reg(codegendata *cd, s8 imm,s8 reg, s8 dreg); void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg); void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg); void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg); void emit_idiv_reg(codegendata *cd, s8 reg); void emit_idivl_reg(codegendata *cd, s8 reg); void emit_shift_reg(codegendata *cd, s8 opc, s8 reg); void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg); void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp); void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp); void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg); void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg); void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp); void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp); void emit_jmp_imm(codegendata *cd, s8 imm); void emit_jmp_reg(codegendata *cd, s8 reg); void emit_jcc(codegendata *cd, s8 opc, s8 imm); void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg); void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp); void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg); void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg); void emit_neg_reg(codegendata *cd, s8 reg); void emit_negl_reg(codegendata *cd, s8 reg); void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp); void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp); void emit_push_reg(codegendata *cd, s8 reg); void emit_push_imm(codegendata *cd, s8 imm); void emit_pop_reg(codegendata *cd, s8 reg); void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_call_reg(codegendata *cd, s8 reg); void emit_call_imm(codegendata *cd, s8 imm); void emit_call_mem(codegendata *cd, ptrint mem); /* floating point instructions (SSE2) */ void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg); void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg); void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg); void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp); void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale); void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg); void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg); void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg); void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg); /* system instructions ********************************************************/ void emit_rdtsc(codegendata *cd); void emit_mfence(codegendata *cd); /** * Emit code to recompute the procedure vector. This is a nop, * because we do not use a procedure vector. */ static inline void emit_recompute_pv(codegendata* cd) {} void emit_arbitrary_nop(codegendata *cd, int disp); #ifdef __cplusplus } #endif #endif /* _MD_EMIT_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: * vim:noexpandtab:sw=4:ts=4: */