* src/vm/jit/x86_64/codegen.h: Use multi-byte NOP for code alignment.
[cacao.git] / src / vm / jit / x86_64 / emit.h
1 /* src/vm/jit/x86_64/emit.h - machine dependent emit function prototypes
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #ifndef _MD_EMIT_H
27 #define _MD_EMIT_H
28
29 #include "config.h"
30 #include "vm/types.h"
31
32 #include "vm/jit/codegen-common.hpp"
33 #include "vm/jit/jit.hpp"
34
35
36 /* macros to create code ******************************************************/
37
38 /* immediate data union */
39
40 typedef union {
41     s4 i;
42     s8 l;
43     float f;
44     double d;
45     void *a;
46     u1 b[8];
47 } imm_buf;
48
49
50 /* opcodes for alu instructions */
51
52 #define ALU_ADD      0
53 #define ALU_OR       1
54 #define ALU_ADC      2
55 #define ALU_SBB      3
56 #define ALU_AND      4
57 #define ALU_SUB      5
58 #define ALU_XOR      6
59 #define ALU_CMP      7
60
61
62 #define SHIFT_ROL    0
63 #define SHIFT_ROR    1
64 #define SHIFT_RCL    2
65 #define SHIFT_RCR    3
66 #define SHIFT_SHL    4
67 #define SHIFT_SHR    5
68 #define SHIFT_SAR    7
69
70
71 #define CC_O         0
72 #define CC_NO        1
73 #define CC_B         2
74 #define CC_C         2
75 #define CC_NAE       2
76 #define CC_AE        3
77 #define CC_NB        3
78 #define CC_NC        3
79 #define CC_E         4
80 #define CC_Z         4
81 #define CC_NE        5
82 #define CC_NZ        5
83 #define CC_BE        6
84 #define CC_NA        6
85 #define CC_A         7
86 #define CC_NBE       7
87 #define CC_S         8
88 #define CC_LZ        8
89 #define CC_NS        9
90 #define CC_GEZ       9
91 #define CC_P         0x0a
92 #define CC_PE        0x0a
93 #define CC_NP        0x0b
94 #define CC_PO        0x0b
95 #define CC_L         0x0c
96 #define CC_NGE       0x0c
97 #define CC_GE        0x0d
98 #define CC_NL        0x0d
99 #define CC_LE        0x0e
100 #define CC_NG        0x0e
101 #define CC_G         0x0f
102 #define CC_NLE       0x0f
103
104
105 /* modrm and stuff */
106
107 #define emit_address_byte(mod,reg,rm) \
108     do { \
109         *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | ((rm) & 0x07)); \
110     } while (0);
111
112
113 #define emit_rex(size,reg,index,rm) \
114     do { \
115         if (((size) == 1) || ((reg) > 7) || ((index) > 7) || ((rm) > 7)) \
116             *(cd->mcodeptr++) = (0x40 | (((size) & 0x01) << 3) | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \
117     } while (0)
118
119
120 #define emit_byte_rex(reg,index,rm) \
121     do { \
122         *(cd->mcodeptr++) = (0x40 | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \
123     } while (0)
124
125
126 #define emit_mem(r,disp) \
127     do { \
128         emit_address_byte(0,(r),5); \
129         emit_imm32((disp)); \
130     } while (0)
131
132
133 #define emit_imm8(imm) \
134     do { \
135         *(cd->mcodeptr++) = (u1) ((imm) & 0xff); \
136     } while (0)
137
138
139 #define emit_imm16(imm) \
140     do { \
141         imm_buf imb; \
142         imb.i = (s4) (imm); \
143         *(cd->mcodeptr++) = imb.b[0]; \
144         *(cd->mcodeptr++) = imb.b[1]; \
145     } while (0)
146
147
148 #define emit_imm32(imm) \
149     do { \
150         imm_buf imb; \
151         imb.i = (s4) (imm); \
152         *(cd->mcodeptr++) = imb.b[0]; \
153         *(cd->mcodeptr++) = imb.b[1]; \
154         *(cd->mcodeptr++) = imb.b[2]; \
155         *(cd->mcodeptr++) = imb.b[3]; \
156     } while (0)
157
158
159 #define emit_imm64(imm) \
160     do { \
161         imm_buf imb; \
162         imb.l = (s8) (imm); \
163         *(cd->mcodeptr++) = imb.b[0]; \
164         *(cd->mcodeptr++) = imb.b[1]; \
165         *(cd->mcodeptr++) = imb.b[2]; \
166         *(cd->mcodeptr++) = imb.b[3]; \
167         *(cd->mcodeptr++) = imb.b[4]; \
168         *(cd->mcodeptr++) = imb.b[5]; \
169         *(cd->mcodeptr++) = imb.b[6]; \
170         *(cd->mcodeptr++) = imb.b[7]; \
171     } while (0)
172
173
174 /* convenience macros *********************************************************/
175
176 #define emit_reg(reg,rm)                emit_address_byte(3,(reg),(rm))
177
178
179 /* function prototypes ********************************************************/
180
181 #ifdef __cplusplus
182 extern "C" {
183 #endif
184
185 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d);
186
187
188 /* code generation prototypes */
189
190 void emit_ishift(jitdata *jd, s4 shift_op, instruction *iptr);
191 void emit_lshift(jitdata *jd, s4 shift_op, instruction *iptr);
192
193
194 /* integer instructions */
195
196 void emit_nop(codegendata *cd, int length);
197 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg);
198 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg);
199 void emit_movl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
200 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg);
201 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
202 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
203 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
204 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
205 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
206 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
207 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
208 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
209 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
210 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
211 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
212 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
213 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
214 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
215 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
216 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
217 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
218 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
219 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
220 void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
221 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
222 void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
223 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
224 void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
225 void emit_movzbq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
226 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
227 void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
228 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
229 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
230 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
231 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
232 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
233 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
234 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
235
236 void emit_mov_mem_reg(codegendata *cd, s4 disp, s4 dreg);
237
238 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
239 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
240 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
241 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
242 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
243 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
244 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
245 void emit_alu_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg);
246 void emit_alul_imm32_reg(codegendata *cd, s4 opc, s4 imm, s4 dreg);
247 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
248 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
249 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
250 void emit_alu_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
251 void emit_alul_memindex_reg(codegendata *cd, s8 opc, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
252 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg);
253 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
254 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg);
255 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg);
256 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg);
257 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
258 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
259
260 void emit_incl_reg(codegendata *cd, s8 reg);
261 void emit_incq_reg(codegendata *cd, s8 reg);
262 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp);
263 void emit_incq_membase(codegendata *cd, s8 basereg, s8 disp);
264
265 void emit_cltd(codegendata *cd);
266 void emit_cqto(codegendata *cd);
267 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg);
268 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg);
269 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
270 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
271 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg);
272 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm,s8 reg, s8 dreg);
273 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg);
274 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
275 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
276 void emit_idiv_reg(codegendata *cd, s8 reg);
277 void emit_idivl_reg(codegendata *cd, s8 reg);
278 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg);
279 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg);
280 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
281 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
282 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
283 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
284 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
285 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
286 void emit_jmp_imm(codegendata *cd, s8 imm);
287 void emit_jmp_reg(codegendata *cd, s8 reg);
288 void emit_jcc(codegendata *cd, s8 opc, s8 imm);
289
290 void emit_setcc_reg(codegendata *cd, s4 opc, s4 reg);
291 void emit_setcc_membase(codegendata *cd, s4 opc, s4 basereg, s4 disp);
292
293 void emit_cmovcc_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg);
294 void emit_cmovccl_reg_reg(codegendata *cd, s4 opc, s4 reg, s4 dreg);
295
296 void emit_neg_reg(codegendata *cd, s8 reg);
297 void emit_negl_reg(codegendata *cd, s8 reg);
298 void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp);
299 void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp);
300 void emit_push_reg(codegendata *cd, s8 reg);
301 void emit_push_imm(codegendata *cd, s8 imm);
302 void emit_pop_reg(codegendata *cd, s8 reg);
303 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg);
304 void emit_call_reg(codegendata *cd, s8 reg);
305 void emit_call_imm(codegendata *cd, s8 imm);
306 void emit_call_mem(codegendata *cd, ptrint mem);
307
308
309 /* floating point instructions (SSE2) */
310
311 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
312 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
313 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
314 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
315 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
316 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
317 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
318 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
319 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
320 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
321 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
322 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
323 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
324 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
325 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg);
326 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg);
327 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
328 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
329 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
330 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
331 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
332 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
333 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
334 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
335 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
336 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
337 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
338 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
339 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
340 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
341 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
342 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
343 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
344 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
345 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
346 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
347 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
348 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
349 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
350 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
351 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
352 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
353 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
354 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
355 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
356 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
357 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
358 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
359 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg);
360 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
361 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
362 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
363
364
365 /* system instructions ********************************************************/
366
367 void emit_rdtsc(codegendata *cd);
368 void emit_mfence(codegendata *cd);
369
370
371 /**
372  * Emit code to recompute the procedure vector. This is a nop,
373  * because we do not use a procedure vector.
374  */
375 static inline void emit_recompute_pv(codegendata* cd) {}
376
377
378 #ifdef __cplusplus
379 }
380 #endif
381
382 #endif /* _MD_EMIT_H */
383
384
385 /*
386  * These are local overrides for various environment variables in Emacs.
387  * Please do not remove this and leave it at the end of the file, where
388  * Emacs will automagically detect them.
389  * ---------------------------------------------------------------------
390  * Local variables:
391  * mode: c
392  * indent-tabs-mode: t
393  * c-basic-offset: 4
394  * tab-width: 4
395  * End:
396  * vim:noexpandtab:sw=4:ts=4:
397  */