1 /* jit/i386/codegen.h - code generation macros and definitions for i386
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 $Id: codegen.h 557 2003-11-02 22:51:59Z twisti $
41 /* define x86 register numbers */
52 /* preallocated registers *****************************************************/
54 /* integer registers */
56 #define REG_RESULT I386_EAX /* to deliver method results */
57 #define REG_RESULT2 I386_EDX /* to deliver long method results */
59 #define REG_ITMP1 I386_EAX /* temporary register */
60 #define REG_ITMP2 I386_EDX /* temporary register and method pointer */
61 #define REG_ITMP3 I386_ECX /* temporary register */
63 #define REG_NULL -1 /* used for reg_of_var where d is not needed */
65 #define REG_ITMP1_XPTR I386_EAX /* exception pointer = temporary register 1 */
66 #define REG_ITMP2_XPC I386_EDX /* exception pc = temporary register 2 */
68 #define REG_SP I386_ESP /* stack pointer */
70 /* floating point registers */
72 #define REG_FRESULT 0 /* to deliver floating point method results */
73 #define REG_FTMP1 6 /* temporary floating point register */
74 #define REG_FTMP2 7 /* temporary floating point register */
75 #define REG_FTMP3 7 /* temporary floating point register */
77 /* register descripton - array ************************************************/
79 /* #define REG_RES 0 reserved register for OS or code generator */
80 /* #define REG_RET 1 return value register */
81 /* #define REG_EXC 2 exception value register (only old jit) */
82 /* #define REG_SAV 3 (callee) saved register */
83 /* #define REG_TMP 4 scratch temporary register (caller saved) */
84 /* #define REG_ARG 5 argument register (caller saved) */
86 /* #define REG_END -1 last entry in tables */
89 REG_RET, REG_RES, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_TMP, REG_TMP,
92 /* for use of reserved registers, see comment above */
94 int nregdescfloat[] = {
95 /* rounding problems with callee saved registers */
96 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
97 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
98 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
101 /* for use of reserved registers, see comment above */
104 /* stackframe-infos ***********************************************************/
106 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
108 /* -> see file 'calling.doc' */
111 static u1 fpu_in_24bit_mode = 0;
113 static u2 fpu_ctrlwrd_24bit = 0x007f; /* Round to nearest, 24-bit mode, exceptions masked */
114 static u2 fpu_ctrlwrd_53bit = 0x027f; /* Round to nearest, 53-bit mode, exceptions masked */
116 static u4 subnormal_bias1[3] = { 0x00000000, 0x80000000, 0x03ff }; /* 2^(-15360) */
117 static u4 subnormal_bias2[3] = { 0x00000000, 0x80000000, 0x7bff }; /* 2^(+15360) */
120 /* macros to create code ******************************************************/
123 * immediate data union
149 * opcodes for alu instructions
177 I386_CC_B = 2, I386_CC_C = 2, I386_CC_NAE = 2,
178 I386_CC_BE = 6, I386_CC_NA = 6,
179 I386_CC_AE = 3, I386_CC_NB = 3, I386_CC_NC = 3,
180 I386_CC_E = 4, I386_CC_Z = 4,
181 I386_CC_NE = 5, I386_CC_NZ = 5,
182 I386_CC_A = 7, I386_CC_NBE = 7,
183 I386_CC_S = 8, I386_CC_LZ = 8,
184 I386_CC_NS = 9, I386_CC_GEZ = 9,
185 I386_CC_P = 0x0a, I386_CC_PE = 0x0a,
186 I386_CC_NP = 0x0b, I386_CC_PO = 0x0b,
187 I386_CC_L = 0x0c, I386_CC_NGE = 0x0c,
188 I386_CC_GE = 0x0d, I386_CC_NL = 0x0d,
189 I386_CC_LE = 0x0e, I386_CC_NG = 0x0e,
190 I386_CC_G = 0x0f, I386_CC_NLE = 0x0f,
194 static const unsigned char i386_jcc_map[] = {
218 #define i386_address_byte(mod, reg, rm) \
219 *(mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07)));
222 #define i386_emit_reg(reg,rm) \
223 i386_address_byte(3,(reg),(rm));
226 #define i386_is_imm8(imm) \
227 (((int)(imm) >= -128 && (int)(imm) <= 127))
230 #define i386_emit_imm8(imm) \
231 *(mcodeptr++) = (u1) ((imm) & 0xff);
234 #define i386_emit_imm16(imm) \
237 imb.i = (int) (imm); \
238 *(mcodeptr++) = imb.b[0]; \
239 *(mcodeptr++) = imb.b[1]; \
243 #define i386_emit_imm32(imm) \
246 imb.i = (int) (imm); \
247 *(mcodeptr++) = imb.b[0]; \
248 *(mcodeptr++) = imb.b[1]; \
249 *(mcodeptr++) = imb.b[2]; \
250 *(mcodeptr++) = imb.b[3]; \
254 #define i386_emit_mem(r,disp) \
256 i386_address_byte(0,(r),5); \
257 i386_emit_imm32((disp)); \
261 #define i386_emit_membase(basereg,disp,dreg) \
263 if ((basereg) == I386_ESP) { \
265 i386_address_byte(0, (dreg), I386_ESP); \
266 i386_address_byte(0, I386_ESP, I386_ESP); \
267 } else if (i386_is_imm8((disp))) { \
268 i386_address_byte(1, (dreg), I386_ESP); \
269 i386_address_byte(0, I386_ESP, I386_ESP); \
270 i386_emit_imm8((disp)); \
272 i386_address_byte(2, (dreg), I386_ESP); \
273 i386_address_byte(0, I386_ESP, I386_ESP); \
274 i386_emit_imm32((disp)); \
279 if ((disp) == 0 && (basereg) != I386_EBP) { \
280 i386_address_byte(0, (dreg), (basereg)); \
284 if (i386_is_imm8((disp))) { \
285 i386_address_byte(1, (dreg), (basereg)); \
286 i386_emit_imm8((disp)); \
288 i386_address_byte(2, (dreg), (basereg)); \
289 i386_emit_imm32((disp)); \
294 #define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \
296 if ((basereg) == -1) { \
297 i386_address_byte(0, (reg), 4); \
298 i386_address_byte((scale), (indexreg), 5); \
299 i386_emit_imm32((disp)); \
301 } else if ((disp) == 0 && (basereg) != I386_EBP) { \
302 i386_address_byte(0, (reg), 4); \
303 i386_address_byte((scale), (indexreg), (basereg)); \
305 } else if (i386_is_imm8((disp))) { \
306 i386_address_byte(1, (reg), 4); \
307 i386_address_byte((scale), (indexreg), (basereg)); \
308 i386_emit_imm8 ((disp)); \
311 i386_address_byte(2, (reg), 4); \
312 i386_address_byte((scale), (indexreg), (basereg)); \
313 i386_emit_imm32((disp)); \
319 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr);
320 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr);
321 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr);
322 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr);
323 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr);
324 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr);
325 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr);
334 #define i386_mov_reg_reg(reg,dreg) \
336 *(mcodeptr++) = (u1) 0x89; \
337 i386_emit_reg((reg),(dreg)); \
341 #define i386_mov_imm_reg(imm,reg) \
343 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07); \
344 i386_emit_imm32((imm)); \
348 #define i386_movb_imm_reg(imm,reg) \
350 *(mcodeptr++) = (u1) 0xc6; \
351 i386_emit_reg(0,(reg)); \
352 i386_emit_imm8((imm)); \
356 #define i386_mov_float_reg(imm,reg) \
358 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07); \
359 i386_emit_float32((imm)); \
363 #define i386_mov_reg_mem(reg,mem) \
365 *(mcodeptr++) = (u1) 0x89; \
366 i386_emit_mem((reg),(mem)); \
370 #define i386_mov_mem_reg(mem,reg) \
372 *(mcodeptr++) = (u1) 0x8b; \
373 i386_emit_mem((reg),(mem)); \
377 #define i386_mov_membase_reg(basereg,disp,reg) \
379 *(mcodeptr++) = (u1) 0x8b; \
380 i386_emit_membase((basereg),(disp),(reg)); \
385 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
386 * constant membase immediate length of 32bit
388 #define i386_mov_membase32_reg(basereg,disp,reg) \
390 *(mcodeptr++) = (u1) 0x8b; \
391 i386_address_byte(2, (reg), (basereg)); \
392 i386_emit_imm32((disp)); \
396 #define i386_movw_membase_reg(basereg,disp,reg) \
398 *(mcodeptr++) = (u1) 0x66; \
399 i386_mov_membase_reg((basereg),(disp),(reg)); \
403 #define i386_movb_membase_reg(basereg,disp,reg) \
405 *(mcodeptr++) = (u1) 0x8a; \
406 i386_emit_membase((basereg),(disp),(reg)); \
410 #define i386_mov_reg_membase(reg,basereg,disp) \
412 *(mcodeptr++) = (u1) 0x89; \
413 i386_emit_membase((basereg),(disp),(reg)); \
417 #define i386_movw_reg_membase(reg,basereg,disp) \
419 *(mcodeptr++) = (u1) 0x66; \
420 *(mcodeptr++) = (u1) 0x89; \
421 i386_emit_membase((basereg),(disp),(reg)); \
425 #define i386_movb_reg_membase(reg,basereg,disp) \
427 *(mcodeptr++) = (u1) 0x88; \
428 i386_emit_membase((basereg),(disp),(reg)); \
432 #define i386_mov_memindex_reg(disp,basereg,indexreg,scale,reg) \
434 *(mcodeptr++) = (u1) 0x8b; \
435 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
439 #define i386_movw_memindex_reg(disp,basereg,indexreg,scale,reg) \
441 *(mcodeptr++) = (u1) 0x66; \
442 *(mcodeptr++) = (u1) 0x8b; \
443 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
447 #define i386_movb_memindex_reg(disp,basereg,indexreg,scale,reg) \
449 *(mcodeptr++) = (u1) 0x8a; \
450 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
454 #define i386_mov_reg_memindex(reg,disp,basereg,indexreg,scale) \
456 *(mcodeptr++) = (u1) 0x89; \
457 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
461 #define i386_movw_reg_memindex(reg,disp,basereg,indexreg,scale) \
463 *(mcodeptr++) = (u1) 0x66; \
464 *(mcodeptr++) = (u1) 0x89; \
465 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
469 #define i386_movb_reg_memindex(reg,disp,basereg,indexreg,scale) \
471 *(mcodeptr++) = (u1) 0x88; \
472 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
476 #define i386_mov_imm_membase(imm,basereg,disp) \
478 *(mcodeptr++) = (u1) 0xc7; \
479 i386_emit_membase((basereg),(disp),0); \
480 i386_emit_imm32((imm)); \
484 #define i386_mov_float_membase(imm,basereg,disp) \
486 *(mcodeptr++) = (u1) 0xc7; \
487 i386_emit_membase((basereg),(disp),0); \
488 i386_emit_float32((imm)); \
492 #define i386_mov_double_low_membase(imm,basereg,disp) \
494 *(mcodeptr++) = (u1) 0xc7; \
495 i386_emit_membase((basereg),(disp),0); \
496 i386_emit_double64_low((imm)); \
500 #define i386_mov_double_high_membase(imm,basereg,disp) \
502 *(mcodeptr++) = (u1) 0xc7; \
503 i386_emit_membase((basereg),(disp),0); \
504 i386_emit_double64_high((imm)); \
508 #define i386_movsbl_reg_reg(reg,dreg) \
510 *(mcodeptr++) = (u1) 0x0f; \
511 *(mcodeptr++) = (u1) 0xbe; \
512 i386_emit_reg((reg),(dreg)); \
516 #define i386_movswl_reg_reg(reg,dreg) \
518 *(mcodeptr++) = (u1) 0x0f; \
519 *(mcodeptr++) = (u1) 0xbf; \
520 i386_emit_reg((reg),(dreg)); \
524 #define i386_movzbl_reg_reg(reg,dreg) \
526 *(mcodeptr++) = (u1) 0x0f; \
527 *(mcodeptr++) = (u1) 0xb6; \
528 /* XXX: why do reg and dreg have to be exchanged */ \
529 i386_emit_reg((dreg),(reg)); \
533 #define i386_movzwl_reg_reg(reg,dreg) \
535 *(mcodeptr++) = (u1) 0x0f; \
536 *(mcodeptr++) = (u1) 0xb7; \
537 /* XXX: why do reg and dreg have to be exchanged */ \
538 i386_emit_reg((dreg),(reg)); \
542 #define i386_movsbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
544 *(mcodeptr++) = (u1) 0x0f; \
545 *(mcodeptr++) = (u1) 0xbe; \
546 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
550 #define i386_movswl_memindex_reg(disp,basereg,indexreg,scale,reg) \
552 *(mcodeptr++) = (u1) 0x0f; \
553 *(mcodeptr++) = (u1) 0xbf; \
554 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
558 #define i386_movzbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
560 *(mcodeptr++) = (u1) 0x0f; \
561 *(mcodeptr++) = (u1) 0xb6; \
562 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
566 #define i386_movzwl_memindex_reg(disp,basereg,indexreg,scale,reg) \
568 *(mcodeptr++) = (u1) 0x0f; \
569 *(mcodeptr++) = (u1) 0xb7; \
570 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
578 #define i386_alu_reg_reg(opc,reg,dreg) \
580 *(mcodeptr++) = (((u1) (opc)) << 3) + 1; \
581 i386_emit_reg((reg),(dreg)); \
585 #define i386_alu_reg_membase(opc,reg,basereg,disp) \
587 *(mcodeptr++) = (((u1) (opc)) << 3) + 1; \
588 i386_emit_membase((basereg),(disp),(reg)); \
592 #define i386_alu_membase_reg(opc,basereg,disp,reg) \
594 *(mcodeptr++) = (((u1) (opc)) << 3) + 3; \
595 i386_emit_membase((basereg),(disp),(reg)); \
599 #define i386_alu_imm_reg(opc,imm,dreg) \
601 if (i386_is_imm8(imm)) { \
602 *(mcodeptr++) = (u1) 0x83; \
603 i386_emit_reg((opc),(dreg)); \
604 i386_emit_imm8((imm)); \
606 *(mcodeptr++) = (u1) 0x81; \
607 i386_emit_reg((opc),(dreg)); \
608 i386_emit_imm32((imm)); \
613 #define i386_alu_imm_membase(opc,imm,basereg,disp) \
615 if (i386_is_imm8(imm)) { \
616 *(mcodeptr++) = (u1) 0x83; \
617 i386_emit_membase((basereg),(disp),(opc)); \
618 i386_emit_imm8((imm)); \
620 *(mcodeptr++) = (u1) 0x81; \
621 i386_emit_membase((basereg),(disp),(opc)); \
622 i386_emit_imm32((imm)); \
627 #define i386_test_reg_reg(reg,dreg) \
629 *(mcodeptr++) = (u1) 0x85; \
630 i386_emit_reg((reg),(dreg)); \
634 #define i386_test_imm_reg(imm,reg) \
636 *(mcodeptr++) = (u1) 0xf7; \
637 i386_emit_reg(0,(reg)); \
638 i386_emit_imm32((imm)); \
642 #define i386_testw_imm_reg(imm,reg) \
644 *(mcodeptr++) = (u1) 0x66; \
645 *(mcodeptr++) = (u1) 0xf7; \
646 i386_emit_reg(0,(reg)); \
647 i386_emit_imm16((imm)); \
651 #define i386_testb_imm_reg(imm,reg) \
653 *(mcodeptr++) = (u1) 0xf6; \
654 i386_emit_reg(0,(reg)); \
655 i386_emit_imm8((imm)); \
661 * inc, dec operations
663 #define i386_inc_reg(reg) \
664 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
667 #define i386_inc_membase(basereg,disp) \
669 *(mcodeptr++) = (u1) 0xff; \
670 i386_emit_membase((basereg),(disp),0); \
674 #define i386_dec_reg(reg) \
675 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
678 #define i386_dec_membase(basereg,disp) \
680 *(mcodeptr++) = (u1) 0xff; \
681 i386_emit_membase((basereg),(disp),1); \
687 #define i386_cltd() \
688 *(mcodeptr++) = (u1) 0x99;
692 #define i386_imul_reg_reg(reg,dreg) \
694 *(mcodeptr++) = (u1) 0x0f; \
695 *(mcodeptr++) = (u1) 0xaf; \
696 i386_emit_reg((dreg),(reg)); \
700 #define i386_imul_membase_reg(basereg,disp,dreg) \
702 *(mcodeptr++) = (u1) 0x0f; \
703 *(mcodeptr++) = (u1) 0xaf; \
704 i386_emit_membase((basereg),(disp),(dreg)); \
708 #define i386_imul_imm_reg(imm,dreg) \
710 if (i386_is_imm8((imm))) { \
711 *(mcodeptr++) = (u1) 0x6b; \
712 i386_emit_reg(0,(dreg)); \
713 i386_emit_imm8((imm)); \
715 *(mcodeptr++) = (u1) 0x69; \
716 i386_emit_reg(0,(dreg)); \
717 i386_emit_imm32((imm)); \
722 #define i386_imul_imm_reg_reg(imm,reg,dreg) \
724 if (i386_is_imm8((imm))) { \
725 *(mcodeptr++) = (u1) 0x6b; \
726 i386_emit_reg((dreg),(reg)); \
727 i386_emit_imm8((imm)); \
729 *(mcodeptr++) = (u1) 0x69; \
730 i386_emit_reg((dreg),(reg)); \
731 i386_emit_imm32((imm)); \
736 #define i386_imul_imm_membase_reg(imm,basereg,disp,dreg) \
738 if (i386_is_imm8((imm))) { \
739 *(mcodeptr++) = (u1) 0x6b; \
740 i386_emit_membase((basereg),(disp),(dreg)); \
741 i386_emit_imm8((imm)); \
743 *(mcodeptr++) = (u1) 0x69; \
744 i386_emit_membase((basereg),(disp),(dreg)); \
745 i386_emit_imm32((imm)); \
750 #define i386_mul_reg(reg) \
752 *(mcodeptr++) = (u1) 0xf7; \
753 i386_emit_reg(4,(reg)); \
757 #define i386_mul_membase(basereg,disp) \
759 *(mcodeptr++) = (u1) 0xf7; \
760 i386_emit_membase((basereg),(disp),4); \
764 #define i386_idiv_reg(reg) \
766 *(mcodeptr++) = (u1) 0xf7; \
767 i386_emit_reg(7,(reg)); \
771 #define i386_idiv_membase(basereg,disp) \
773 *(mcodeptr++) = (u1) 0xf7; \
774 i386_emit_membase((basereg),(disp),7); \
780 *(mcodeptr++) = (u1) 0xc3;
783 #define i386_leave() \
784 *(mcodeptr++) = (u1) 0xc9;
791 #define i386_shift_reg(opc,reg) \
793 *(mcodeptr++) = (u1) 0xd3; \
794 i386_emit_reg((opc),(reg)); \
798 #define i386_shift_membase(opc,basereg,disp) \
800 *(mcodeptr++) = (u1) 0xd3; \
801 i386_emit_membase((basereg),(disp),(opc)); \
805 #define i386_shift_imm_reg(opc,imm,dreg) \
808 *(mcodeptr++) = (u1) 0xd1; \
809 i386_emit_reg((opc),(dreg)); \
811 *(mcodeptr++) = (u1) 0xc1; \
812 i386_emit_reg((opc),(dreg)); \
813 i386_emit_imm8((imm)); \
818 #define i386_shift_imm_membase(opc,imm,basereg,disp) \
821 *(mcodeptr++) = (u1) 0xd1; \
822 i386_emit_membase((basereg),(disp),(opc)); \
824 *(mcodeptr++) = (u1) 0xc1; \
825 i386_emit_membase((basereg),(disp),(opc)); \
826 i386_emit_imm8((imm)); \
831 #define i386_shld_reg_reg(reg,dreg) \
833 *(mcodeptr++) = (u1) 0x0f; \
834 *(mcodeptr++) = (u1) 0xa5; \
835 i386_emit_reg((reg),(dreg)); \
839 #define i386_shld_imm_reg_reg(imm,reg,dreg) \
841 *(mcodeptr++) = (u1) 0x0f; \
842 *(mcodeptr++) = (u1) 0xa4; \
843 i386_emit_reg((reg),(dreg)); \
844 i386_emit_imm8((imm)); \
848 #define i386_shld_reg_membase(reg,basereg,disp) \
850 *(mcodeptr++) = (u1) 0x0f; \
851 *(mcodeptr++) = (u1) 0xa5; \
852 i386_emit_membase((basereg),(disp),(reg)); \
856 #define i386_shrd_reg_reg(reg,dreg) \
858 *(mcodeptr++) = (u1) 0x0f; \
859 *(mcodeptr++) = (u1) 0xad; \
860 i386_emit_reg((reg),(dreg)); \
864 #define i386_shrd_imm_reg_reg(imm,reg,dreg) \
866 *(mcodeptr++) = (u1) 0x0f; \
867 *(mcodeptr++) = (u1) 0xac; \
868 i386_emit_reg((reg),(dreg)); \
869 i386_emit_imm8((imm)); \
873 #define i386_shrd_reg_membase(reg,basereg,disp) \
875 *(mcodeptr++) = (u1) 0x0f; \
876 *(mcodeptr++) = (u1) 0xad; \
877 i386_emit_membase((basereg),(disp),(reg)); \
885 #define i386_jmp_imm(imm) \
887 *(mcodeptr++) = (u1) 0xe9; \
888 i386_emit_imm32((imm)); \
892 #define i386_jmp_reg(reg) \
894 *(mcodeptr++) = (u1) 0xff; \
895 i386_emit_reg(4,(reg)); \
899 #define i386_jcc(opc,imm) \
901 *(mcodeptr++) = (u1) 0x0f; \
902 *(mcodeptr++) = (u1) (0x80 + i386_jcc_map[(opc)]); \
903 i386_emit_imm32((imm)); \
909 * conditional set operations
911 #define i386_setcc_reg(opc,reg) \
913 *(mcodeptr++) = (u1) 0x0f; \
914 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
915 i386_emit_reg(0,(reg)); \
919 #define i386_setcc_membase(opc,basereg,disp) \
921 *(mcodeptr++) = (u1) 0x0f; \
922 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
923 i386_emit_membase((basereg),(disp),0); \
928 #define i386_neg_reg(reg) \
930 *(mcodeptr++) = (u1) 0xf7; \
931 i386_emit_reg(3,(reg)); \
935 #define i386_neg_mem(mem) \
937 *(mcodeptr++) = (u1) 0xf7; \
938 i386_emit_mem(3,(mem)); \
942 #define i386_neg_membase(basereg,disp) \
944 *(mcodeptr++) = (u1) 0xf7; \
945 i386_emit_membase((basereg),(disp),3); \
950 #define i386_push_reg(reg) \
951 *(mcodeptr++) = (u1) 0x50 + (0x07 & (reg));
954 #define i386_push_membase(basereg,disp) \
956 *(mcodeptr++) = (u1) 0xff; \
957 i386_emit_membase((basereg),(disp),6); \
961 #define i386_push_imm(imm) \
963 *(mcodeptr++) = (u1) 0x68; \
964 i386_emit_imm32((imm)); \
968 #define i386_pop_reg(reg) \
969 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
973 *(mcodeptr++) = (u1) 0x90;
980 #define i386_call_reg(reg) \
982 *(mcodeptr++) = (u1) 0xff; \
983 i386_emit_reg(2,(reg)); \
987 #define i386_call_imm(imm) \
989 *(mcodeptr++) = (u1) 0xe8; \
990 i386_emit_imm32((imm)); \
996 * floating point instructions
998 #define i386_fld1() \
1000 *(mcodeptr++) = (u1) 0xd9; \
1001 *(mcodeptr++) = (u1) 0xe8; \
1005 #define i386_fldz() \
1007 *(mcodeptr++) = (u1) 0xd9; \
1008 *(mcodeptr++) = (u1) 0xee; \
1012 #define i386_fld_reg(reg) \
1014 *(mcodeptr++) = (u1) 0xd9; \
1015 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg)); \
1019 #define i386_flds_mem(mem) \
1021 *(mcodeptr++) = (u1) 0xd9; \
1022 i386_emit_mem(0,(mem)); \
1026 #define i386_fldl_mem(mem) \
1028 *(mcodeptr++) = (u1) 0xdd; \
1029 i386_emit_mem(0,(mem)); \
1033 #define i386_fldt_mem(mem) \
1035 *(mcodeptr++) = (u1) 0xdb; \
1036 i386_emit_mem(5,(mem)); \
1040 #define i386_flds_membase(basereg,disp) \
1042 *(mcodeptr++) = (u1) 0xd9; \
1043 i386_emit_membase((basereg),(disp),0); \
1047 #define i386_fldl_membase(basereg,disp) \
1049 *(mcodeptr++) = (u1) 0xdd; \
1050 i386_emit_membase((basereg),(disp),0); \
1054 #define i386_fldt_membase(basereg,disp) \
1056 *(mcodeptr++) = (u1) 0xdb; \
1057 i386_emit_membase((basereg),(disp),5); \
1061 #define i386_flds_memindex(disp,basereg,indexreg,scale) \
1063 *(mcodeptr++) = (u1) 0xd9; \
1064 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
1068 #define i386_fldl_memindex(disp,basereg,indexreg,scale) \
1070 *(mcodeptr++) = (u1) 0xdd; \
1071 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
1077 #define i386_fildl_mem(mem) \
1079 *(mcodeptr++) = (u1) 0xdb; \
1080 i386_emit_mem(0,(mem)); \
1084 #define i386_fildl_membase(basereg,disp) \
1086 *(mcodeptr++) = (u1) 0xdb; \
1087 i386_emit_membase((basereg),(disp),0); \
1091 #define i386_fildll_membase(basereg,disp) \
1093 *(mcodeptr++) = (u1) 0xdf; \
1094 i386_emit_membase((basereg),(disp),5); \
1100 #define i386_fst_reg(reg) \
1102 *(mcodeptr++) = (u1) 0xdd; \
1103 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg)); \
1107 #define i386_fsts_mem(mem) \
1109 *(mcodeptr++) = (u1) 0xd9; \
1110 i386_emit_mem(2,(mem)); \
1114 #define i386_fstl_mem(mem) \
1116 *(mcodeptr++) = (u1) 0xdd; \
1117 i386_emit_mem(2,(mem)); \
1121 #define i386_fsts_membase(basereg,disp) \
1123 *(mcodeptr++) = (u1) 0xd9; \
1124 i386_emit_membase((basereg),(disp),2); \
1128 #define i386_fstl_membase(basereg,disp) \
1130 *(mcodeptr++) = (u1) 0xdd; \
1131 i386_emit_membase((basereg),(disp),2); \
1135 #define i386_fsts_memindex(disp,basereg,indexreg,scale) \
1137 *(mcodeptr++) = (u1) 0xd9; \
1138 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1142 #define i386_fstl_memindex(disp,basereg,indexreg,scale) \
1144 *(mcodeptr++) = (u1) 0xdd; \
1145 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1151 #define i386_fstp_reg(reg) \
1153 *(mcodeptr++) = (u1) 0xdd; \
1154 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg)); \
1158 #define i386_fstps_mem(mem) \
1160 *(mcodeptr++) = (u1) 0xd9; \
1161 i386_emit_mem(3,(mem)); \
1165 #define i386_fstpl_mem(mem) \
1167 *(mcodeptr++) = (u1) 0xdd; \
1168 i386_emit_mem(3,(mem)); \
1172 #define i386_fstps_membase(basereg,disp) \
1174 *(mcodeptr++) = (u1) 0xd9; \
1175 i386_emit_membase((basereg),(disp),3); \
1179 #define i386_fstpl_membase(basereg,disp) \
1181 *(mcodeptr++) = (u1) 0xdd; \
1182 i386_emit_membase((basereg),(disp),3); \
1186 #define i386_fstpt_membase(basereg,disp) \
1188 *(mcodeptr++) = (u1) 0xdb; \
1189 i386_emit_membase((basereg),(disp),7); \
1193 #define i386_fstps_memindex(disp,basereg,indexreg,scale) \
1195 *(mcodeptr++) = (u1) 0xd9; \
1196 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale)); \
1200 #define i386_fstpl_memindex(disp,basereg,indexreg,scale) \
1202 *(mcodeptr++) = (u1) 0xdd; \
1203 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale)); \
1209 #define i386_fistpl_mem(mem) \
1211 *(mcodeptr++) = (u1) 0xdb; \
1212 i386_emit_mem(3,(mem)); \
1216 #define i386_fistpll_mem(mem) \
1218 *(mcodeptr++) = (u1) 0xdf; \
1219 i386_emit_mem(7,(mem)); \
1223 #define i386_fistl_membase(basereg,disp) \
1225 *(mcodeptr++) = (u1) 0xdb; \
1226 i386_emit_membase((basereg),(disp),2); \
1230 #define i386_fistpl_membase(basereg,disp) \
1232 *(mcodeptr++) = (u1) 0xdb; \
1233 i386_emit_membase((basereg),(disp),3); \
1237 #define i386_fistpll_membase(basereg,disp) \
1239 *(mcodeptr++) = (u1) 0xdf; \
1240 i386_emit_membase((basereg),(disp),7); \
1246 #define i386_fchs() \
1248 *(mcodeptr++) = (u1) 0xd9; \
1249 *(mcodeptr++) = (u1) 0xe0; \
1253 #define i386_faddp() \
1255 *(mcodeptr++) = (u1) 0xde; \
1256 *(mcodeptr++) = (u1) 0xc1; \
1260 #define i386_fadd_reg_st(reg) \
1262 *(mcodeptr++) = (u1) 0xd8; \
1263 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1267 #define i386_fadd_st_reg(reg) \
1269 *(mcodeptr++) = (u1) 0xdc; \
1270 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1274 #define i386_faddp_st_reg(reg) \
1276 *(mcodeptr++) = (u1) 0xde; \
1277 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1281 #define i386_fadds_membase(basereg,disp) \
1283 *(mcodeptr++) = (u1) 0xd8; \
1284 i386_emit_membase((basereg),(disp),0); \
1288 #define i386_faddl_membase(basereg,disp) \
1290 *(mcodeptr++) = (u1) 0xdc; \
1291 i386_emit_membase((basereg),(disp),0); \
1295 #define i386_fsub_reg_st(reg) \
1297 *(mcodeptr++) = (u1) 0xd8; \
1298 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg)); \
1302 #define i386_fsub_st_reg(reg) \
1304 *(mcodeptr++) = (u1) 0xdc; \
1305 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1309 #define i386_fsubp_st_reg(reg) \
1311 *(mcodeptr++) = (u1) 0xde; \
1312 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1316 #define i386_fsubp() \
1318 *(mcodeptr++) = (u1) 0xde; \
1319 *(mcodeptr++) = (u1) 0xe9; \
1323 #define i386_fsubs_membase(basereg,disp) \
1325 *(mcodeptr++) = (u1) 0xd8; \
1326 i386_emit_membase((basereg),(disp),4); \
1330 #define i386_fsubl_membase(basereg,disp) \
1332 *(mcodeptr++) = (u1) 0xdc; \
1333 i386_emit_membase((basereg),(disp),4); \
1337 #define i386_fmul_reg_st(reg) \
1339 *(mcodeptr++) = (u1) 0xd8; \
1340 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1344 #define i386_fmul_st_reg(reg) \
1346 *(mcodeptr++) = (u1) 0xdc; \
1347 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1351 #define i386_fmulp() \
1353 *(mcodeptr++) = (u1) 0xde; \
1354 *(mcodeptr++) = (u1) 0xc9; \
1358 #define i386_fmulp_st_reg(reg) \
1360 *(mcodeptr++) = (u1) 0xde; \
1361 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1365 #define i386_fmuls_membase(basereg,disp) \
1367 *(mcodeptr++) = (u1) 0xd8; \
1368 i386_emit_membase((basereg),(disp),1); \
1372 #define i386_fmull_membase(basereg,disp) \
1374 *(mcodeptr++) = (u1) 0xdc; \
1375 i386_emit_membase((basereg),(disp),1); \
1379 #define i386_fdiv_reg_st(reg) \
1381 *(mcodeptr++) = (u1) 0xd8; \
1382 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg)); \
1386 #define i386_fdiv_st_reg(reg) \
1388 *(mcodeptr++) = (u1) 0xdc; \
1389 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg)); \
1393 #define i386_fdivp() \
1395 *(mcodeptr++) = (u1) 0xde; \
1396 *(mcodeptr++) = (u1) 0xf9; \
1400 #define i386_fdivp_st_reg(reg) \
1402 *(mcodeptr++) = (u1) 0xde; \
1403 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg)); \
1407 #define i386_fxch() \
1409 *(mcodeptr++) = (u1) 0xd9; \
1410 *(mcodeptr++) = (u1) 0xc9; \
1414 #define i386_fxch_reg(reg) \
1416 *(mcodeptr++) = (u1) 0xd9; \
1417 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1421 #define i386_fprem() \
1423 *(mcodeptr++) = (u1) 0xd9; \
1424 *(mcodeptr++) = (u1) 0xf8; \
1428 #define i386_fprem1() \
1430 *(mcodeptr++) = (u1) 0xd9; \
1431 *(mcodeptr++) = (u1) 0xf5; \
1435 #define i386_fucom() \
1437 *(mcodeptr++) = (u1) 0xdd; \
1438 *(mcodeptr++) = (u1) 0xe1; \
1442 #define i386_fucom_reg(reg) \
1444 *(mcodeptr++) = (u1) 0xdd; \
1445 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg)); \
1449 #define i386_fucomp_reg(reg) \
1451 *(mcodeptr++) = (u1) 0xdd; \
1452 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1456 #define i386_fucompp() \
1458 *(mcodeptr++) = (u1) 0xda; \
1459 *(mcodeptr++) = (u1) 0xe9; \
1463 #define i386_fnstsw() \
1465 *(mcodeptr++) = (u1) 0xdf; \
1466 *(mcodeptr++) = (u1) 0xe0; \
1470 #define i386_sahf() \
1471 *(mcodeptr++) = (u1) 0x9e;
1474 #define i386_finit() \
1476 *(mcodeptr++) = (u1) 0x9b; \
1477 *(mcodeptr++) = (u1) 0xdb; \
1478 *(mcodeptr++) = (u1) 0xe3; \
1482 #define i386_fldcw_mem(mem) \
1484 *(mcodeptr++) = (u1) 0xd9; \
1485 i386_emit_mem(5,(mem)); \
1489 #define i386_fldcw_membase(basereg,disp) \
1491 *(mcodeptr++) = (u1) 0xd9; \
1492 i386_emit_membase((basereg),(disp),5); \
1496 #define i386_wait() \
1497 *(mcodeptr++) = (u1) 0x9b;
1500 #define i386_ffree_reg(reg) \
1502 *(mcodeptr++) = (u1) 0xdd; \
1503 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg)); \
1507 #define i386_fdecstp() \
1509 *(mcodeptr++) = (u1) 0xd9; \
1510 *(mcodeptr++) = (u1) 0xf6; \
1514 #define i386_fincstp() \
1516 *(mcodeptr++) = (u1) 0xd9; \
1517 *(mcodeptr++) = (u1) 0xf7; \
1523 * integer instructions
1525 void i386_mov_reg_reg(s4 reg, s4 dreg);
1526 void i386_mov_imm_reg(s4 imm, s4 dreg);
1527 void i386_movb_imm_reg(s4 imm, s4 dreg);
1528 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg);
1529 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg);
1530 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp);
1531 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg);
1532 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale);
1533 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale);
1534 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale);
1535 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp);
1536 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg);
1537 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg);
1538 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg);
1539 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg);
1540 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp);
1541 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg);
1542 void i386_alu_imm_reg(s4 opc, s4 imm, s4 reg);
1543 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp);
1544 void i386_test_reg_reg(s4 reg, s4 dreg);
1545 void i386_test_imm_reg(s4 imm, s4 dreg);
1546 void i386_inc_reg(s4 reg);
1547 void i386_inc_membase(s4 basereg, s4 disp);
1548 void i386_dec_reg(s4 reg);
1549 void i386_dec_membase(s4 basereg, s4 disp);
1551 void i386_imul_reg_reg(s4 reg, s4 dreg);
1552 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg);
1553 void i386_imul_imm_reg(s4 imm, s4 reg);
1554 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg);
1555 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg);
1556 void i386_mul_membase(s4 basereg, s4 disp);
1557 void i386_idiv_reg(s4 reg);
1559 void i386_shift_reg(s4 opc, s4 reg);
1560 void i386_shift_membase(s4 opc, s4 basereg, s4 disp);
1561 void i386_shift_imm_reg(s4 opc, s4 imm, s4 reg);
1562 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp);
1563 void i386_shld_reg_reg(s4 reg, s4 dreg);
1564 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg);
1565 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp);
1566 void i386_shrd_reg_reg(s4 reg, s4 dreg);
1567 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg);
1568 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp);
1569 void i386_jmp_imm(s4 imm);
1570 void i386_jmp_reg(s4 reg);
1571 void i386_jcc(s4 opc, s4 imm);
1572 void i386_setcc_reg(s4 opc, s4 reg);
1573 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp);
1574 void i386_neg_reg(s4 reg);
1575 void i386_neg_membase(s4 basereg, s4 disp);
1576 void i386_push_imm(s4 imm);
1577 void i386_pop_reg(s4 reg);
1579 void i386_call_reg(s4 reg);
1580 void i386_call_imm(s4 imm);
1585 * floating point instructions
1589 void i386_fld_reg(s4 reg);
1590 void i386_flds_membase(s4 basereg, s4 disp);
1591 void i386_fldl_membase(s4 basereg, s4 disp);
1592 void i386_fldt_membase(s4 basereg, s4 disp);
1593 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1594 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1595 void i386_fildl_membase(s4 basereg, s4 disp);
1596 void i386_fildll_membase(s4 basereg, s4 disp);
1597 void i386_fst_reg(s4 reg);
1598 void i386_fsts_membase(s4 basereg, s4 disp);
1599 void i386_fstl_membase(s4 basereg, s4 disp);
1600 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1601 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1602 void i386_fstp_reg(s4 reg);
1603 void i386_fstps_membase(s4 basereg, s4 disp);
1604 void i386_fstpl_membase(s4 basereg, s4 disp);
1605 void i386_fstpt_membase(s4 basereg, s4 disp);
1606 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1607 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale);
1608 void i386_fistl_membase(s4 basereg, s4 disp);
1609 void i386_fistpl_membase(s4 basereg, s4 disp);
1610 void i386_fistpll_membase(s4 basereg, s4 disp);
1613 void i386_fadd_reg_st(s4 reg);
1614 void i386_fadd_st_reg(s4 reg);
1615 void i386_faddp_st_reg(s4 reg);
1616 void i386_fadds_membase(s4 basereg, s4 disp);
1617 void i386_faddl_membase(s4 basereg, s4 disp);
1618 void i386_fsub_reg_st(s4 reg);
1619 void i386_fsub_st_reg(s4 reg);
1620 void i386_fsubp_st_reg(s4 reg);
1622 void i386_fsubs_membase(s4 basereg, s4 disp);
1623 void i386_fsubl_membase(s4 basereg, s4 disp);
1624 void i386_fmul_reg_st(s4 reg);
1625 void i386_fmul_st_reg(s4 reg);
1627 void i386_fmulp_st_reg(s4 reg);
1628 void i386_fmuls_membase(s4 basereg, s4 disp);
1629 void i386_fmull_membase(s4 basereg, s4 disp);
1630 void i386_fdiv_reg_st(s4 reg);
1631 void i386_fdiv_st_reg(s4 reg);
1633 void i386_fdivp_st_reg(s4 reg);
1635 void i386_fxch_reg(s4 reg);
1639 void i386_fucom_reg(s4 reg);
1640 void i386_fucomp_reg(s4 reg);
1641 void i386_fucompp();
1645 void i386_fldcw_mem(s4 mem);
1646 void i386_fldcw_membase(s4 basereg, s4 disp);
1648 void i386_ffree_reg(s4 reg);
1649 void i386_fdecstp();
1650 void i386_fincstp();
1656 /* function gen_resolvebranch **************************************************
1658 backpatches a branch instruction
1660 parameters: ip ... pointer to instruction after branch (void*)
1661 so ... offset of instruction after branch (s4)
1662 to ... offset of branch target (s4)
1664 *******************************************************************************/
1666 #define gen_resolvebranch(ip,so,to) \
1667 *((void **) ((ip) - 4)) = (void **) ((to) - (so));
1669 #endif /* _CODEGEN_H */
1673 * These are local overrides for various environment variables in Emacs.
1674 * Please do not remove this and leave it at the end of the file, where
1675 * Emacs will automagically detect them.
1676 * ---------------------------------------------------------------------
1679 * indent-tabs-mode: t