1 /* src/vm/jit/x86_64/md-emit.h - machine dependent emit function prototypes
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: md-emit.h 4943 2006-05-23 08:51:33Z twisti $
42 /* macros to create code ******************************************************/
44 /* immediate data union */
56 /* opcodes for alu instructions */
111 #define IS_IMM8(imm) \
112 (((long) (imm) >= -128) && ((long) (imm) <= 127))
115 #define IS_IMM32(imm) \
116 (((long) (imm) >= (-2147483647-1)) && ((long) (imm) <= 2147483647))
119 /* modrm and stuff */
121 #define emit_address_byte(mod,reg,rm) \
122 *(cd->mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | ((rm) & 0x07));
125 #define emit_reg(reg,rm) \
126 emit_address_byte(3,(reg),(rm));
129 #define emit_rex(size,reg,index,rm) \
130 if (((size) == 1) || ((reg) > 7) || ((index) > 7) || ((rm) > 7)) { \
131 *(cd->mcodeptr++) = (0x40 | (((size) & 0x01) << 3) | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01)); \
135 #define emit_byte_rex(reg,index,rm) \
136 *(cd->mcodeptr++) = (0x40 | ((((reg) >> 3) & 0x01) << 2) | ((((index) >> 3) & 0x01) << 1) | (((rm) >> 3) & 0x01));
139 #define emit_mem(r,disp) \
141 emit_address_byte(0,(r),5); \
142 emit_imm32((disp)); \
146 #define emit_membase32(basereg,disp,dreg) \
148 if ((basereg) == REG_SP || (basereg) == R12) { \
149 emit_address_byte(2,(dreg),REG_SP); \
150 emit_address_byte(0,REG_SP,REG_SP); \
151 emit_imm32((disp)); \
153 emit_address_byte(2,(dreg),(basereg)); \
154 emit_imm32((disp)); \
159 #define emit_memindex(reg,disp,basereg,indexreg,scale) \
161 if ((basereg) == -1) { \
162 emit_address_byte(0,(reg),4); \
163 emit_address_byte((scale),(indexreg),5); \
164 emit_imm32((disp)); \
166 } else if ((disp) == 0 && (basereg) != RBP && (basereg) != R13) { \
167 emit_address_byte(0,(reg),4); \
168 emit_address_byte((scale),(indexreg),(basereg)); \
170 } else if (IS_IMM8((disp))) { \
171 emit_address_byte(1,(reg),4); \
172 emit_address_byte((scale),(indexreg),(basereg)); \
173 emit_imm8 ((disp)); \
176 emit_address_byte(2,(reg),4); \
177 emit_address_byte((scale),(indexreg),(basereg)); \
178 emit_imm32((disp)); \
183 #define emit_imm8(imm) \
184 *(cd->mcodeptr++) = (u1) ((imm) & 0xff);
187 #define emit_imm16(imm) \
190 imb.i = (s4) (imm); \
191 *(cd->mcodeptr++) = imb.b[0]; \
192 *(cd->mcodeptr++) = imb.b[1]; \
196 #define emit_imm32(imm) \
199 imb.i = (s4) (imm); \
200 *(cd->mcodeptr++) = imb.b[0]; \
201 *(cd->mcodeptr++) = imb.b[1]; \
202 *(cd->mcodeptr++) = imb.b[2]; \
203 *(cd->mcodeptr++) = imb.b[3]; \
207 #define emit_imm64(imm) \
210 imb.l = (s8) (imm); \
211 *(cd->mcodeptr++) = imb.b[0]; \
212 *(cd->mcodeptr++) = imb.b[1]; \
213 *(cd->mcodeptr++) = imb.b[2]; \
214 *(cd->mcodeptr++) = imb.b[3]; \
215 *(cd->mcodeptr++) = imb.b[4]; \
216 *(cd->mcodeptr++) = imb.b[5]; \
217 *(cd->mcodeptr++) = imb.b[6]; \
218 *(cd->mcodeptr++) = imb.b[7]; \
222 /* function prototypes ********************************************************/
224 void emit_cmovxx(codegendata *cd, instruction *iptr, s4 s, s4 d);
227 /* code generation prototypes */
229 void emit_ishift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr);
230 void emit_lshift(codegendata *cd, s4 shift_op, stackptr src, instruction *iptr);
233 /* integer instructions */
235 void emit_mov_reg_reg(codegendata *cd, s8 reg, s8 dreg);
236 void emit_mov_imm_reg(codegendata *cd, s8 imm, s8 reg);
237 void emit_movl_imm_reg(codegendata *cd, s8 imm, s8 reg);
238 void emit_mov_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
239 void emit_mov_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
240 void emit_movl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
241 void emit_movl_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
242 void emit_mov_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
243 void emit_mov_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
244 void emit_movl_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
245 void emit_movl_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
246 void emit_mov_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
247 void emit_movl_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
248 void emit_mov_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
249 void emit_movl_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
250 void emit_movw_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
251 void emit_movb_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
252 void emit_mov_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
253 void emit_mov_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
254 void emit_movl_imm_membase(codegendata *cd, s8 imm, s8 basereg, s8 disp);
255 void emit_movl_imm_membase32(codegendata *cd, s8 imm, s8 basereg, s8 disp);
256 void emit_movsbq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
257 void emit_movsbq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
258 void emit_movswq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
259 void emit_movswq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
260 void emit_movslq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
261 void emit_movslq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
262 void emit_movzwq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
263 void emit_movzwq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
264 void emit_movswq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
265 void emit_movsbq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
266 void emit_movzwq_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 reg);
267 void emit_mov_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
268 void emit_movl_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
269 void emit_movw_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
270 void emit_movb_imm_memindex(codegendata *cd, s4 imm, s4 disp, s4 basereg, s4 indexreg, s4 scale);
271 void emit_alu_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
272 void emit_alul_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
273 void emit_alu_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
274 void emit_alul_reg_membase(codegendata *cd, s8 opc, s8 reg, s8 basereg, s8 disp);
275 void emit_alu_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
276 void emit_alul_membase_reg(codegendata *cd, s8 opc, s8 basereg, s8 disp, s8 reg);
277 void emit_alu_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
278 void emit_alu_imm32_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
279 void emit_alul_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
280 void emit_alu_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
281 void emit_alul_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
282 void emit_test_reg_reg(codegendata *cd, s8 reg, s8 dreg);
283 void emit_testl_reg_reg(codegendata *cd, s8 reg, s8 dreg);
284 void emit_test_imm_reg(codegendata *cd, s8 imm, s8 reg);
285 void emit_testw_imm_reg(codegendata *cd, s8 imm, s8 reg);
286 void emit_testb_imm_reg(codegendata *cd, s8 imm, s8 reg);
287 void emit_lea_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
288 void emit_leal_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 reg);
290 void emit_incl_membase(codegendata *cd, s8 basereg, s8 disp);
292 void emit_cltd(codegendata *cd);
293 void emit_cqto(codegendata *cd);
294 void emit_imul_reg_reg(codegendata *cd, s8 reg, s8 dreg);
295 void emit_imull_reg_reg(codegendata *cd, s8 reg, s8 dreg);
296 void emit_imul_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
297 void emit_imull_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
298 void emit_imul_imm_reg(codegendata *cd, s8 imm, s8 dreg);
299 void emit_imul_imm_reg_reg(codegendata *cd, s8 imm,s8 reg, s8 dreg);
300 void emit_imull_imm_reg_reg(codegendata *cd, s8 imm, s8 reg, s8 dreg);
301 void emit_imul_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
302 void emit_imull_imm_membase_reg(codegendata *cd, s8 imm, s8 basereg, s8 disp, s8 dreg);
303 void emit_idiv_reg(codegendata *cd, s8 reg);
304 void emit_idivl_reg(codegendata *cd, s8 reg);
305 void emit_ret(codegendata *cd);
306 void emit_shift_reg(codegendata *cd, s8 opc, s8 reg);
307 void emit_shiftl_reg(codegendata *cd, s8 opc, s8 reg);
308 void emit_shift_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
309 void emit_shiftl_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
310 void emit_shift_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
311 void emit_shiftl_imm_reg(codegendata *cd, s8 opc, s8 imm, s8 dreg);
312 void emit_shift_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
313 void emit_shiftl_imm_membase(codegendata *cd, s8 opc, s8 imm, s8 basereg, s8 disp);
314 void emit_jmp_imm(codegendata *cd, s8 imm);
315 void emit_jmp_reg(codegendata *cd, s8 reg);
316 void emit_jcc(codegendata *cd, s8 opc, s8 imm);
317 void emit_setcc_reg(codegendata *cd, s8 opc, s8 reg);
318 void emit_setcc_membase(codegendata *cd, s8 opc, s8 basereg, s8 disp);
319 void emit_cmovcc_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
320 void emit_cmovccl_reg_reg(codegendata *cd, s8 opc, s8 reg, s8 dreg);
321 void emit_neg_reg(codegendata *cd, s8 reg);
322 void emit_negl_reg(codegendata *cd, s8 reg);
323 void emit_neg_membase(codegendata *cd, s8 basereg, s8 disp);
324 void emit_negl_membase(codegendata *cd, s8 basereg, s8 disp);
325 void emit_push_reg(codegendata *cd, s8 reg);
326 void emit_push_imm(codegendata *cd, s8 imm);
327 void emit_pop_reg(codegendata *cd, s8 reg);
328 void emit_xchg_reg_reg(codegendata *cd, s8 reg, s8 dreg);
329 void emit_nop(codegendata *cd);
330 void emit_call_reg(codegendata *cd, s8 reg);
331 void emit_call_imm(codegendata *cd, s8 imm);
332 void emit_call_mem(codegendata *cd, ptrint mem);
335 /* floating point instructions (SSE2) */
337 void emit_addsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
338 void emit_addss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
339 void emit_cvtsi2ssq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
340 void emit_cvtsi2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
341 void emit_cvtsi2sdq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
342 void emit_cvtsi2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
343 void emit_cvtss2sd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
344 void emit_cvtsd2ss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
345 void emit_cvttss2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
346 void emit_cvttss2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
347 void emit_cvttsd2siq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
348 void emit_cvttsd2si_reg_reg(codegendata *cd, s8 reg, s8 dreg);
349 void emit_divss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
350 void emit_divsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
351 void emit_movd_reg_freg(codegendata *cd, s8 reg, s8 freg);
352 void emit_movd_freg_reg(codegendata *cd, s8 freg, s8 reg);
353 void emit_movd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
354 void emit_movd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
355 void emit_movd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
356 void emit_movdl_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
357 void emit_movd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
358 void emit_movq_reg_reg(codegendata *cd, s8 reg, s8 dreg);
359 void emit_movq_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
360 void emit_movq_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
361 void emit_movss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
362 void emit_movsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
363 void emit_movss_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
364 void emit_movss_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
365 void emit_movsd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
366 void emit_movsd_reg_membase32(codegendata *cd, s8 reg, s8 basereg, s8 disp);
367 void emit_movss_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
368 void emit_movss_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
369 void emit_movlps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
370 void emit_movlps_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
371 void emit_movsd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
372 void emit_movsd_membase32_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
373 void emit_movlpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
374 void emit_movlpd_reg_membase(codegendata *cd, s8 reg, s8 basereg, s8 disp);
375 void emit_movss_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
376 void emit_movsd_reg_memindex(codegendata *cd, s8 reg, s8 disp, s8 basereg, s8 indexreg, s8 scale);
377 void emit_movss_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
378 void emit_movsd_memindex_reg(codegendata *cd, s8 disp, s8 basereg, s8 indexreg, s8 scale, s8 dreg);
379 void emit_mulss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
380 void emit_mulsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
381 void emit_subss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
382 void emit_subsd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
383 void emit_ucomiss_reg_reg(codegendata *cd, s8 reg, s8 dreg);
384 void emit_ucomisd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
385 void emit_xorps_reg_reg(codegendata *cd, s8 reg, s8 dreg);
386 void emit_xorps_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
387 void emit_xorpd_reg_reg(codegendata *cd, s8 reg, s8 dreg);
388 void emit_xorpd_membase_reg(codegendata *cd, s8 basereg, s8 disp, s8 dreg);
391 /* system instructions ********************************************************/
393 void emit_rdtsc(codegendata *cd);
395 #endif /* _MD_EMIT_H */
399 * These are local overrides for various environment variables in Emacs.
400 * Please do not remove this and leave it at the end of the file, where
401 * Emacs will automagically detect them.
402 * ---------------------------------------------------------------------
405 * indent-tabs-mode: t