Initial import of s390 codegen, codebase is copyed from x86_64.
[cacao.git] / src / vm / jit / s390 / emit.h
diff --git a/src/vm/jit/s390/emit.h b/src/vm/jit/s390/emit.h
new file mode 100644 (file)
index 0000000..fd72bc6
--- /dev/null
@@ -0,0 +1,374 @@
+/* src/vm/jit/x86_64/md-emit.h - machine dependent emit function prototypes
+
+   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
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Christian Thalinger
+
+   Changes:
+
+   $Id: emit.h 7219 2007-01-16 22:18:57Z pm $
+
+*/
+
+
+#ifndef _MD_EMIT_H
+#define _MD_EMIT_H
+
+#include "vm/types.h"
+
+
+/* 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
+
+#if 0
+#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
+#endif
+
+
+/* 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 ********************************************************/
+
+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_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_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_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, s8 opc, s8 imm, s8 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_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_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_ret(codegendata *cd);
+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, s8 opc, s8 reg);
+void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
+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_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_nop(codegendata *cd);
+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);
+
+#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:
+ */