1 /* i386/ngen.h *****************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the machine dependent code generator definitions and macros for an
10 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
11 Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1998/11/04
15 *******************************************************************************/
20 /* see also file calling.doc for explanation of calling conventions */
22 /* preallocated registers *****************************************************/
24 /* integer registers */
26 #define REG_RESULT I386_EAX /* to deliver method results */
27 #define REG_RESULT2 I386_EDX /* to deliver long method results */
29 #define REG_RA 26 /* return address */
30 #define REG_PV 27 /* procedure vector, must be provided by caller */
31 #define REG_METHODPTR 28 /* pointer to the place from where the procedure */
32 /* vector has been fetched */
33 #define REG_ITMP1 I386_EAX /* temporary register */
34 #define REG_ITMP2 I386_EDX /* temporary register and method pointer */
35 #define REG_ITMP3 I386_ECX /* temporary register */
37 #define REG_ITMP1_XPTR I386_EAX /* exception pointer = temporary register 1 */
38 #define REG_ITMP2_XPC I386_EDX /* exception pc = temporary register 2 */
40 #define REG_SP I386_ESP /* stack pointer */
41 #define REG_ZERO 31 /* always zero */
43 /* floating point registers */
45 #define REG_FRESULT 0 /* to deliver floating point method results */
46 #define REG_FTMP1 0 /* temporary floating point register */
47 #define REG_FTMP2 1 /* temporary floating point register */
48 #define REG_FTMP3 2 /* temporary floating point register */
50 #define REG_IFTMP 28 /* temporary integer and floating point register */
52 /* register descripton - array ************************************************/
54 /* #define REG_RES 0 reserved register for OS or code generator */
55 /* #define REG_RET 1 return value register */
56 /* #define REG_EXC 2 exception value register (only old jit) */
57 /* #define REG_SAV 3 (callee) saved register */
58 /* #define REG_TMP 4 scratch temporary register (caller saved) */
59 /* #define REG_ARG 5 argument register (caller saved) */
61 /* #define REG_END -1 last entry in tables */
64 REG_RET, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP,
67 /* for use of reserved registers, see comment above */
69 int nregdescfloat[] = {
70 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
73 /* for use of reserved registers, see comment above */
76 /* parameter allocation mode */
78 int nreg_parammode = PARAMMODE_NUMBERED;
80 /* parameter-registers will be allocated by assigning the
81 1. parameter: int/float-reg 16
82 2. parameter: int/float-reg 17
83 3. parameter: int/float-reg 18 ....
87 /* stackframe-infos ***********************************************************/
89 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
91 /* -> see file 'calling.doc' */
94 /* macros to create code ******************************************************/
96 #define M_OP3(op,fu,a,b,c,const) \
98 printf("M_OP3: %d\n", __LINE__); \
99 *((s4 *) (((s4) mcodeptr)++)) = 0x0F; \
100 *((s4 *) (((s4) mcodeptr)++)) = 0x04; \
103 #define M_FOP3(op,fu,a,b,c) M_OP3(0,0,0,0,0,0)
104 #define M_BRA(op,a,disp) M_OP3(0,0,0,0,0,0)
105 #define M_MEM(op,a,b,disp) M_OP3(0,0,0,0,0,0)
110 * immediate data union
123 * x86 register numbers
138 * opcodes for alu instructions
166 I386_CC_B = 2, I386_CC_C = 2, I386_CC_NAE = 2,
167 I386_CC_BE = 6, I386_CC_NA = 6,
168 I386_CC_AE = 3, I386_CC_NB = 3, I386_CC_NC = 3,
169 I386_CC_E = 4, I386_CC_Z = 4,
170 I386_CC_NE = 5, I386_CC_NZ = 5,
171 I386_CC_A = 7, I386_CC_NBE = 7,
172 I386_CC_S = 8, I386_CC_LZ = 8,
173 I386_CC_NS = 9, I386_CC_GEZ = 9,
174 I386_CC_P = 0x0a, I386_CC_PE = 0x0a,
175 I386_CC_NP = 0x0b, I386_CC_PO = 0x0b,
176 I386_CC_L = 0x0c, I386_CC_NGE = 0x0c,
177 I386_CC_GE = 0x0d, I386_CC_NL = 0x0d,
178 I386_CC_LE = 0x0e, I386_CC_NG = 0x0e,
179 I386_CC_G = 0x0f, I386_CC_NLE = 0x0f,
183 static const unsigned char i386_jcc_map[] = {
207 #define i386_address_byte(mod, reg, rm) \
209 *(((u1 *) mcodeptr)++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07))); \
213 #define i386_emit_reg(reg,rm) \
215 i386_address_byte(3,(reg),(rm)); \
219 #define i386_is_imm8(imm) (((int)(imm) >= -128 && (int)(imm) <= 127))
222 #define i386_emit_imm8(imm) \
224 *(((u1 *) mcodeptr)++) = (u1) ((imm) & 0xff); \
228 #define i386_emit_imm16(imm) \
231 imb.i = (int) (imm); \
232 *(((u1 *) mcodeptr)++) = imb.b[0]; \
233 *(((u1 *) mcodeptr)++) = imb.b[1]; \
237 #define i386_emit_imm32(imm) \
240 imb.i = (int) (imm); \
241 *(((u1 *) mcodeptr)++) = imb.b[0]; \
242 *(((u1 *) mcodeptr)++) = imb.b[1]; \
243 *(((u1 *) mcodeptr)++) = imb.b[2]; \
244 *(((u1 *) mcodeptr)++) = imb.b[3]; \
248 #define i386_emit_float32(imm) \
251 imb.f = (float) (imm); \
252 *(((u1 *) mcodeptr)++) = imb.b[0]; \
253 *(((u1 *) mcodeptr)++) = imb.b[1]; \
254 *(((u1 *) mcodeptr)++) = imb.b[2]; \
255 *(((u1 *) mcodeptr)++) = imb.b[3]; \
259 #define i386_emit_mem(r,disp) \
261 i386_address_byte(0,(r),5); \
262 i386_emit_imm32((disp)); \
266 #define i386_emit_membase(basereg,disp,dreg) \
268 if ((basereg) == I386_ESP) { \
270 i386_address_byte(0, (dreg), I386_ESP); \
271 i386_address_byte(0, I386_ESP, I386_ESP); \
272 } else if (i386_is_imm8((disp))) { \
273 i386_address_byte(1, (dreg), I386_ESP); \
274 i386_address_byte(0, I386_ESP, I386_ESP); \
275 i386_emit_imm8((disp)); \
277 i386_address_byte(2, (dreg), I386_ESP); \
278 i386_address_byte(0, I386_ESP, I386_ESP); \
279 i386_emit_imm32((disp)); \
284 if ((disp) == 0 && (basereg) != I386_EBP) { \
285 i386_address_byte(0, (dreg), (basereg)); \
289 if (i386_is_imm8((disp))) { \
290 i386_address_byte(1, (dreg), (basereg)); \
291 i386_emit_imm8((disp)); \
293 i386_address_byte(2, (dreg), (basereg)); \
294 i386_emit_imm32((disp)); \
298 #define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \
300 if ((basereg) == -1) { \
301 i386_address_byte(0, (reg), 4); \
302 i386_address_byte((scale), (indexreg), 5); \
303 i386_emit_imm32((disp)); \
305 } else if ((disp) == 0 && (basereg) != I386_EBP) { \
306 i386_address_byte(0, (reg), 4); \
307 i386_address_byte((scale), (indexreg), (basereg)); \
309 } else if (i386_is_imm8((disp))) { \
310 i386_address_byte(1, (reg), 4); \
311 i386_address_byte((scale), (indexreg), (basereg)); \
312 i386_emit_imm8 ((disp)); \
315 i386_address_byte(2, (reg), 4); \
316 i386_address_byte((scale), (indexreg), (basereg)); \
317 i386_emit_imm32((disp)); \
326 #define i386_mov_reg_reg(reg,dreg) \
328 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
329 i386_emit_reg((reg),(dreg)); \
333 #define i386_mov_imm_reg(imm,reg) \
335 *(((u1 *) mcodeptr)++) = (u1) 0xb8 + ((reg) & 0x07); \
336 i386_emit_imm32((imm)); \
340 #define i386_mov_float_reg(imm,reg) \
342 *(((u1 *) mcodeptr)++) = (u1) 0xb8 + ((reg) & 0x07); \
343 i386_emit_float32((imm)); \
347 #define i386_mov_reg_mem(reg,mem) \
349 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
350 i386_emit_mem((reg),(mem)); \
354 #define i386_mov_mem_reg(mem,reg) \
356 *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
357 i386_emit_mem((reg),(mem)); \
361 #define i386_mov_membase_reg(basereg,disp,reg) \
363 *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
364 i386_emit_membase((basereg),(disp),(reg)); \
369 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
370 * constant membase immediate length of 32bit
372 #define i386_mov_membase32_reg(basereg,disp,reg) \
374 *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
375 i386_address_byte(2, (reg), (basereg)); \
376 i386_emit_imm32((disp)); \
380 #define i386_movw_membase_reg(basereg,disp,reg) \
382 *(((u1 *) mcodeptr)++) = (u1) 0x66; \
383 i386_mov_membase_reg((basereg),(disp),(reg)); \
387 #define i386_movb_membase_reg(basereg,disp,reg) \
389 *(((u1 *) mcodeptr)++) = (u1) 0x8a; \
390 i386_emit_membase((basereg),(disp),(reg)); \
394 #define i386_mov_reg_membase(reg,basereg,disp) \
396 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
397 i386_emit_membase((basereg),(disp),(reg)); \
401 #define i386_movw_reg_membase(reg,basereg,disp) \
403 *(((u1 *) mcodeptr)++) = (u1) 0x66; \
404 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
405 i386_emit_membase((basereg),(disp),(reg)); \
409 #define i386_movb_reg_membase(reg,basereg,disp) \
411 *(((u1 *) mcodeptr)++) = (u1) 0x88; \
412 i386_emit_membase((basereg),(disp),(reg)); \
416 #define i386_mov_memindex_reg(disp,basereg,indexreg,scale,reg) \
418 *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
419 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
423 #define i386_movw_memindex_reg(disp,basereg,indexreg,scale,reg) \
425 *(((u1 *) mcodeptr)++) = (u1) 0x66; \
426 *(((u1 *) mcodeptr)++) = (u1) 0x8b; \
427 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
431 #define i386_mov_reg_memindex(reg,disp,basereg,indexreg,scale) \
433 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
434 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
438 #define i386_movw_reg_memindex(reg,disp,basereg,indexreg,scale) \
440 *(((u1 *) mcodeptr)++) = (u1) 0x66; \
441 *(((u1 *) mcodeptr)++) = (u1) 0x89; \
442 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
446 #define i386_movb_reg_memindex(reg,disp,basereg,indexreg,scale) \
448 *(((u1 *) mcodeptr)++) = (u1) 0x88; \
449 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
453 #define i386_mov_imm_membase(imm,basereg,disp) \
455 *(((u1 *) mcodeptr)++) = (u1) 0xc7; \
456 i386_emit_membase((basereg),(disp),0); \
457 i386_emit_imm32((imm)); \
461 #define i386_mov_float_membase(imm,basereg,disp) \
463 *(((u1 *) mcodeptr)++) = (u1) 0xc7; \
464 i386_emit_membase((basereg),(disp),0); \
465 i386_emit_float32((imm)); \
469 #define i386_movsbl_reg_reg(reg,dreg) \
471 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
472 *(((u1 *) mcodeptr)++) = (u1) 0xbe; \
473 i386_emit_reg((reg),(dreg)); \
477 #define i386_movswl_reg_reg(reg,dreg) \
479 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
480 *(((u1 *) mcodeptr)++) = (u1) 0xbf; \
481 i386_emit_reg((reg),(dreg)); \
485 #define i386_movsbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
487 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
488 *(((u1 *) mcodeptr)++) = (u1) 0xbe; \
489 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
493 #define i386_movswl_memindex_reg(disp,basereg,indexreg,scale,reg) \
495 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
496 *(((u1 *) mcodeptr)++) = (u1) 0xbf; \
497 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
501 #define i386_movzbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
503 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
504 *(((u1 *) mcodeptr)++) = (u1) 0xb6; \
505 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
509 #define i386_movzwl_memindex_reg(disp,basereg,indexreg,scale,reg) \
511 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
512 *(((u1 *) mcodeptr)++) = (u1) 0xb7; \
513 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
521 #define i386_alu_reg_reg(opc,reg,dreg) \
523 *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 1; \
524 i386_emit_reg((reg),(dreg)); \
528 #define i386_alu_reg_membase(opc,reg,basereg,disp) \
530 *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 1; \
531 i386_emit_membase((basereg),(disp),(reg)); \
535 #define i386_alu_membase_reg(opc,basereg,disp,reg) \
537 *(((u1 *) mcodeptr)++) = (((u1) (opc)) << 3) + 3; \
538 i386_emit_membase((basereg),(disp),(reg)); \
542 #define i386_alu_imm_reg(opc,imm,dreg) \
544 if (i386_is_imm8(imm)) { \
545 *(((u1 *) mcodeptr)++) = (u1) 0x83; \
546 i386_emit_reg((opc),(dreg)); \
547 i386_emit_imm8((imm)); \
549 *(((u1 *) mcodeptr)++) = (u1) 0x81; \
550 i386_emit_reg((opc),(dreg)); \
551 i386_emit_imm32((imm)); \
556 #define i386_alu_imm_membase(opc,imm,basereg,disp) \
558 if (i386_is_imm8(imm)) { \
559 *(((u1 *) mcodeptr)++) = (u1) 0x83; \
560 i386_emit_membase((basereg),(disp),(opc)); \
561 i386_emit_imm8((imm)); \
563 *(((u1 *) mcodeptr)++) = (u1) 0x81; \
564 i386_emit_membase((basereg),(disp),(opc)); \
565 i386_emit_imm32((imm)); \
570 #define i386_test_reg_reg(reg,dreg) \
572 *(((u1 *) mcodeptr)++) = (u1) 0x85; \
573 i386_emit_reg((reg),(dreg)); \
577 #define i386_test_imm_reg(imm,reg) \
579 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
580 i386_emit_reg(0,(reg)); \
581 i386_emit_imm32((imm)); \
585 #define i386_testw_imm_reg(imm,reg) \
587 *(((u1 *) mcodeptr)++) = (u1) 0x66; \
588 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
589 i386_emit_reg(0,(reg)); \
590 i386_emit_imm16((imm)); \
594 #define i386_testb_imm_reg(imm,reg) \
596 *(((u1 *) mcodeptr)++) = (u1) 0xf6; \
597 i386_emit_reg(0,(reg)); \
598 i386_emit_imm8((imm)); \
602 #define i386_shld_reg_reg(reg,dreg) \
604 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
605 *(((u1 *) mcodeptr)++) = (u1) 0xa5; \
606 i386_emit_reg((reg),(dreg)); \
610 #define i386_shld_reg_membase(reg,basereg,disp) \
612 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
613 *(((u1 *) mcodeptr)++) = (u1) 0xa5; \
614 i386_emit_membase((basereg),(disp),(reg)); \
618 #define i386_shrd_reg_reg(reg,dreg) \
620 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
621 *(((u1 *) mcodeptr)++) = (u1) 0xad; \
622 i386_emit_reg((reg),(dreg)); \
626 #define i386_shrd_reg_membase(reg,basereg,disp) \
628 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
629 *(((u1 *) mcodeptr)++) = (u1) 0xad; \
630 i386_emit_membase((basereg),(disp),(reg)); \
636 * inc, dec operations
638 #define i386_inc_reg(reg) \
640 *(((u1 *) mcodeptr)++) = (u1) 0x40 + ((reg) & 0x07); \
644 #define i386_inc_membase(basereg,disp) \
646 *(((u1 *) mcodeptr)++) = (u1) 0xff; \
647 i386_emit_membase((basereg),(disp),0); \
651 #define i386_dec_reg(reg) \
653 *(((u1 *) mcodeptr)++) = (u1) 0x48 + ((reg) & 0x07); \
657 #define i386_dec_membase(basereg,disp) \
659 *(((u1 *) mcodeptr)++) = (u1) 0xff; \
660 i386_emit_membase((basereg),(disp),1); \
666 #define i386_cltd() \
668 *(((u1 *) mcodeptr)++) = (u1) 0x99; \
673 #define i386_imul_reg_reg(reg,dreg) \
675 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
676 *(((u1 *) mcodeptr)++) = (u1) 0xaf; \
677 i386_emit_reg((dreg),(reg)); \
681 #define i386_imul_membase_reg(basereg,disp,dreg) \
683 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
684 *(((u1 *) mcodeptr)++) = (u1) 0xaf; \
685 i386_emit_membase((basereg),(disp),(dreg)); \
689 #define i386_imul_imm_reg(imm,dreg) \
691 if (i386_is_imm8((imm))) { \
692 *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
693 i386_emit_reg(0,(dreg)); \
694 i386_emit_imm8((imm)); \
696 *(((u1 *) mcodeptr)++) = (u1) 0x69; \
697 i386_emit_reg(0,(dreg)); \
698 i386_emit_imm32((imm)); \
703 #define i386_imul_imm_reg_reg(imm,reg,dreg) \
705 if (i386_is_imm8((imm))) { \
706 *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
707 i386_emit_reg((dreg),(reg)); \
708 i386_emit_imm8((imm)); \
710 *(((u1 *) mcodeptr)++) = (u1) 0x69; \
711 i386_emit_reg((dreg),(reg)); \
712 i386_emit_imm32((imm)); \
717 #define i386_imul_imm_membase_reg(imm,basereg,disp,dreg) \
719 if (i386_is_imm8((imm))) { \
720 *(((u1 *) mcodeptr)++) = (u1) 0x6b; \
721 i386_emit_membase((basereg),(disp),(dreg)); \
722 i386_emit_imm8((imm)); \
724 *(((u1 *) mcodeptr)++) = (u1) 0x69; \
725 i386_emit_membase((basereg),(disp),(dreg)); \
726 i386_emit_imm32((imm)); \
731 #define i386_mul_reg(reg) \
733 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
734 i386_emit_reg(4,(reg)); \
738 #define i386_mul_membase(basereg,disp) \
740 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
741 i386_emit_membase((basereg),(disp),4); \
745 #define i386_idiv_reg(reg) \
747 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
748 i386_emit_reg(7,(reg)); \
752 #define i386_idiv_membase(basereg,disp) \
754 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
755 i386_emit_membase((basereg),(disp),7); \
762 *(((u1 *) mcodeptr)++) = (u1) 0xc3; \
766 #define i386_leave() \
768 *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
776 #define i386_shift_reg(opc,reg) \
778 *(((u1 *) mcodeptr)++) = (u1) 0xd3; \
779 i386_emit_reg((opc),(reg)); \
783 #define i386_shift_membase(opc,basereg,disp) \
785 *(((u1 *) mcodeptr)++) = (u1) 0xd3; \
786 i386_emit_membase((basereg),(disp),(opc)); \
790 #define i386_shift_imm_reg(opc,imm,dreg) \
793 *(((u1 *) mcodeptr)++) = (u1) 0xd1; \
794 i386_emit_reg((opc),(dreg)); \
796 *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
797 i386_emit_reg((opc),(dreg)); \
798 i386_emit_imm8((imm)); \
803 #define i386_shift_imm_membase(opc,imm,basereg,disp) \
806 *(((u1 *) mcodeptr)++) = (u1) 0xd1; \
807 i386_emit_membase((basereg),(disp),(opc)); \
809 *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
810 i386_emit_membase((basereg),(disp),(opc)); \
811 i386_emit_imm8((imm)); \
820 #define i386_jmp(imm) \
822 *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
823 i386_emit_imm32((imm)); \
827 #define i386_jmp_reg(reg) \
829 *(((u1 *) mcodeptr)++) = (u1) 0xff; \
830 i386_emit_reg(4,(reg)); \
834 #define i386_jcc(opc,imm) \
836 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
837 *(((u1 *) mcodeptr)++) = (u1) (0x80 + i386_jcc_map[(opc)]); \
838 i386_emit_imm32((imm)); \
844 * conditional set operations
846 #define i386_setcc_reg(opc,reg) \
848 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
849 *(((u1 *) mcodeptr)++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
850 i386_emit_reg(0,(reg)); \
854 #define i386_setcc_membase(opc,basereg,disp) \
856 *(((u1 *) mcodeptr)++) = (u1) 0x0f; \
857 *(((u1 *) mcodeptr)++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
858 i386_emit_membase((basereg),(disp),0); \
863 #define i386_neg_reg(reg) \
865 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
866 i386_emit_reg(3,(reg)); \
870 #define i386_neg_mem(mem) \
872 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
873 i386_emit_mem(3,(mem)); \
877 #define i386_neg_membase(basereg,disp) \
879 *(((u1 *) mcodeptr)++) = (u1) 0xf7; \
880 i386_emit_membase((basereg),(disp),3); \
885 #define i386_push_reg(reg) \
887 *(((u1 *) mcodeptr)++) = (u1) 0x50 + (0x07 & (reg)); \
891 #define i386_push_membase(basereg,disp) \
893 *(((u1 *) mcodeptr)++) = (u1) 0xff; \
894 i386_emit_membase((basereg),(disp),6); \
898 #define i386_push_imm(imm) \
900 *(((u1 *) mcodeptr)++) = (u1) 0x68; \
901 i386_emit_imm32((imm)); \
905 #define i386_pop_reg(reg) \
907 *(((u1 *) mcodeptr)++) = (u1) 0x58 + (0x07 & (reg)); \
913 *(((u1 *) mcodeptr)++) = (u1) 0x90; \
921 #define i386_call_reg(reg) \
923 *(((u1 *) mcodeptr)++) = (u1) 0xff; \
924 i386_emit_reg(2,(reg)); \
928 #define i386_call_imm(imm) \
930 *(((u1 *) mcodeptr)++) = (u1) 0xe8; \
931 i386_emit_imm32((imm)); \
937 * floating point instructions
939 #define i386_fld1() \
941 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
942 *(((u1 *) mcodeptr)++) = (u1) 0xe8; \
946 #define i386_fldz() \
948 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
949 *(((u1 *) mcodeptr)++) = (u1) 0xee; \
953 #define i386_flds_mem(mem) \
955 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
956 i386_emit_mem(0,(mem)); \
960 #define i386_fldl_mem(mem) \
962 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
963 i386_emit_mem(0,(mem)); \
967 #define i386_flds_membase(basereg,disp) \
969 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
970 i386_emit_membase((basereg),(disp),0); \
974 #define i386_fldl_membase(basereg,disp) \
976 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
977 i386_emit_membase((basereg),(disp),0); \
981 #define i386_flds_memindex(disp,basereg,indexreg,scale) \
983 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
984 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
988 #define i386_fldl_memindex(disp,basereg,indexreg,scale) \
990 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
991 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
997 #define i386_fildl_mem(mem) \
999 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1000 i386_emit_mem(0,(mem)); \
1004 #define i386_fildl_membase(basereg,disp) \
1006 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1007 i386_emit_membase((basereg),(disp),0); \
1011 #define i386_fildll_membase(basereg,disp) \
1013 *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
1014 i386_emit_membase((basereg),(disp),5); \
1020 #define i386_fsts_mem(mem) \
1022 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1023 i386_emit_mem(2,(mem)); \
1027 #define i386_fstl_mem(mem) \
1029 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1030 i386_emit_mem(2,(mem)); \
1034 #define i386_fsts_membase(basereg,disp) \
1036 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1037 i386_emit_membase((basereg),(disp),2); \
1041 #define i386_fstl_membase(basereg,disp) \
1043 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1044 i386_emit_membase((basereg),(disp),2); \
1048 #define i386_fsts_memindex(disp,basereg,indexreg,scale) \
1050 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1051 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1055 #define i386_fstl_memindex(disp,basereg,indexreg,scale) \
1057 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1058 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1064 #define i386_fstps_mem(mem) \
1066 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1067 i386_emit_mem(3,(mem)); \
1071 #define i386_fstpl_mem(mem) \
1073 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1074 i386_emit_mem(3,(mem)); \
1078 #define i386_fstps_membase(basereg,disp) \
1080 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1081 i386_emit_membase((basereg),(disp),3); \
1085 #define i386_fstpl_membase(basereg,disp) \
1087 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1088 i386_emit_membase((basereg),(disp),3); \
1094 #define i386_fistpl_mem(mem) \
1096 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1097 i386_emit_mem(3,(mem)); \
1101 #define i386_fistpll_mem(mem) \
1103 *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
1104 i386_emit_mem(7,(mem)); \
1108 #define i386_fistl_membase(basereg,disp) \
1110 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1111 i386_emit_membase((basereg),(disp),2); \
1115 #define i386_fistpl_membase(basereg,disp) \
1117 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1118 i386_emit_membase((basereg),(disp),3); \
1122 #define i386_fistpll_membase(basereg,disp) \
1124 *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
1125 i386_emit_membase((basereg),(disp),7); \
1131 #define i386_fchs() \
1133 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1134 *(((u1 *) mcodeptr)++) = (u1) 0xe0; \
1138 #define i386_faddp() \
1140 *(((u1 *) mcodeptr)++) = (u1) 0xde; \
1141 *(((u1 *) mcodeptr)++) = (u1) 0xc1; \
1145 #define i386_fadds_membase(basereg,disp) \
1147 *(((u1 *) mcodeptr)++) = (u1) 0xd8; \
1148 i386_emit_membase((basereg),(disp),0); \
1152 #define i386_faddl_membase(basereg,disp) \
1154 *(((u1 *) mcodeptr)++) = (u1) 0xdc; \
1155 i386_emit_membase((basereg),(disp),0); \
1159 #define i386_fsubp() \
1161 *(((u1 *) mcodeptr)++) = (u1) 0xde; \
1162 *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
1166 #define i386_fsubs_membase(basereg,disp) \
1168 *(((u1 *) mcodeptr)++) = (u1) 0xd8; \
1169 i386_emit_membase((basereg),(disp),4); \
1173 #define i386_fmulp() \
1175 *(((u1 *) mcodeptr)++) = (u1) 0xde; \
1176 *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
1180 #define i386_fdivp() \
1182 *(((u1 *) mcodeptr)++) = (u1) 0xde; \
1183 *(((u1 *) mcodeptr)++) = (u1) 0xf9; \
1187 #define i386_fxch() \
1189 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1190 *(((u1 *) mcodeptr)++) = (u1) 0xc9; \
1194 #define i386_fxch_reg(reg) \
1196 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1197 *(((u1 *) mcodeptr)++) = (u1) 0xc8 + (0x0f & (reg)); \
1201 #define i386_fprem1() \
1203 *(((u1 *) mcodeptr)++) = (u1) 0xd9; \
1204 *(((u1 *) mcodeptr)++) = (u1) 0xf5; \
1208 #define i386_fucom() \
1210 *(((u1 *) mcodeptr)++) = (u1) 0xdd; \
1211 *(((u1 *) mcodeptr)++) = (u1) 0xe1; \
1215 #define i386_fucompp() \
1217 *(((u1 *) mcodeptr)++) = (u1) 0xda; \
1218 *(((u1 *) mcodeptr)++) = (u1) 0xe9; \
1222 #define i386_fnstsw() \
1224 *(((u1 *) mcodeptr)++) = (u1) 0xdf; \
1225 *(((u1 *) mcodeptr)++) = (u1) 0xe0; \
1229 #define i386_finit() \
1231 *(((u1 *) mcodeptr)++) = (u1) 0x9b; \
1232 *(((u1 *) mcodeptr)++) = (u1) 0xdb; \
1233 *(((u1 *) mcodeptr)++) = (u1) 0xe3; \
1238 /* macros for all used commands (see an Alpha-manual for description) *********/
1240 #define M_LDA(a,b,disp) M_MEM (0x08,a,b,disp) /* low const */
1241 #define M_LDAH(a,b,disp) M_MEM (0x09,a,b,disp) /* high const */
1242 #define M_BLDU(a,b,disp) M_MEM (0x0a,a,b,disp) /* 8 load */
1243 #define M_SLDU(a,b,disp) M_MEM (0x0c,a,b,disp) /* 16 load */
1244 #define M_ILD(a,b,disp) M_MEM (0x28,a,b,disp) /* 32 load */
1245 #define M_LLD(a,b,disp) M_MEM (0x29,a,b,disp) /* 64 load */
1246 #define M_ALD(a,b,disp) M_MEM (0x29,a,b,disp) /* addr load */
1247 #define M_BST(a,b,disp) M_MEM (0x0e,a,b,disp) /* 8 store */
1248 #define M_SST(a,b,disp) M_MEM (0x0d,a,b,disp) /* 16 store */
1249 #define M_IST(a,b,disp) M_MEM (0x2c,a,b,disp) /* 32 store */
1250 #define M_LST(a,b,disp) M_MEM (0x2d,a,b,disp) /* 64 store */
1251 #define M_AST(a,b,disp) M_MEM (0x2d,a,b,disp) /* addr store */
1253 #define M_BSEXT(b,c) M_OP3 (0x1c,0x0,REG_ZERO,b,c,0) /* 8 signext */
1254 #define M_SSEXT(b,c) M_OP3 (0x1c,0x1,REG_ZERO,b,c,0) /* 16 signext */
1256 #define M_BR(disp) M_BRA (0x30,REG_ZERO,disp) /* branch */
1257 #define M_BSR(ra,disp) M_BRA (0x34,ra,disp) /* branch sbr */
1258 #define M_BEQZ(a,disp) M_BRA (0x39,a,disp) /* br a == 0 */
1259 #define M_BLTZ(a,disp) M_BRA (0x3a,a,disp) /* br a < 0 */
1260 #define M_BLEZ(a,disp) M_BRA (0x3b,a,disp) /* br a <= 0 */
1261 #define M_BNEZ(a,disp) M_BRA (0x3d,a,disp) /* br a != 0 */
1262 #define M_BGEZ(a,disp) M_BRA (0x3e,a,disp) /* br a >= 0 */
1263 #define M_BGTZ(a,disp) M_BRA (0x3f,a,disp) /* br a > 0 */
1265 #define M_JMP(a,b) M_MEM (0x1a,a,b,0x0000) /* jump */
1266 #define M_JSR(a,b) M_MEM (0x1a,a,b,0x4000) /* call sbr */
1267 #define M_RET(a,b) M_MEM (0x1a,a,b,0x8000) /* return */
1269 #define M_IADD(a,b,c) M_OP3 (0x10,0x0, a,b,c,0) /* 32 add */
1270 #define M_LADD(a,b,c) M_OP3 (0x10,0x20, a,b,c,0) /* 64 add */
1271 #define M_ISUB(a,b,c) M_OP3 (0x10,0x09, a,b,c,0) /* 32 sub */
1272 #define M_LSUB(a,b,c) M_OP3 (0x10,0x29, a,b,c,0) /* 64 sub */
1273 #define M_IMUL(a,b,c) M_OP3 (0x13,0x00, a,b,c,0) /* 32 mul */
1274 #define M_LMUL(a,b,c) M_OP3 (0x13,0x20, a,b,c,0) /* 64 mul */
1276 #define M_IADD_IMM(a,b,c) M_OP3 (0x10,0x0, a,b,c,1) /* 32 add */
1277 #define M_LADD_IMM(a,b,c) M_OP3 (0x10,0x20, a,b,c,1) /* 64 add */
1278 #define M_ISUB_IMM(a,b,c) M_OP3 (0x10,0x09, a,b,c,1) /* 32 sub */
1279 #define M_LSUB_IMM(a,b,c) M_OP3 (0x10,0x29, a,b,c,1) /* 64 sub */
1280 #define M_IMUL_IMM(a,b,c) M_OP3 (0x13,0x00, a,b,c,1) /* 32 mul */
1281 #define M_LMUL_IMM(a,b,c) M_OP3 (0x13,0x20, a,b,c,1) /* 64 mul */
1283 #define M_CMPEQ(a,b,c) M_OP3 (0x10,0x2d, a,b,c,0) /* c = a == b */
1284 #define M_CMPLT(a,b,c) M_OP3 (0x10,0x4d, a,b,c,0) /* c = a < b */
1285 #define M_CMPLE(a,b,c) M_OP3 (0x10,0x6d, a,b,c,0) /* c = a <= b */
1287 #define M_CMPULE(a,b,c) M_OP3 (0x10,0x3d, a,b,c,0) /* c = a <= b */
1288 #define M_CMPULT(a,b,c) M_OP3 (0x10,0x1d, a,b,c,0) /* c = a <= b */
1290 #define M_CMPEQ_IMM(a,b,c) M_OP3 (0x10,0x2d, a,b,c,1) /* c = a == b */
1291 #define M_CMPLT_IMM(a,b,c) M_OP3 (0x10,0x4d, a,b,c,1) /* c = a < b */
1292 #define M_CMPLE_IMM(a,b,c) M_OP3 (0x10,0x6d, a,b,c,1) /* c = a <= b */
1294 #define M_CMPULE_IMM(a,b,c) M_OP3 (0x10,0x3d, a,b,c,1) /* c = a <= b */
1295 #define M_CMPULT_IMM(a,b,c) M_OP3 (0x10,0x1d, a,b,c,1) /* c = a <= b */
1297 #define M_AND(a,b,c) M_OP3 (0x11,0x00, a,b,c,0) /* c = a & b */
1298 #define M_OR( a,b,c) M_OP3 (0x11,0x20, a,b,c,0) /* c = a | b */
1299 #define M_XOR(a,b,c) M_OP3 (0x11,0x40, a,b,c,0) /* c = a ^ b */
1301 #define M_AND_IMM(a,b,c) M_OP3 (0x11,0x00, a,b,c,1) /* c = a & b */
1302 #define M_OR_IMM( a,b,c) M_OP3 (0x11,0x20, a,b,c,1) /* c = a | b */
1303 #define M_XOR_IMM(a,b,c) M_OP3 (0x11,0x40, a,b,c,1) /* c = a ^ b */
1305 #define M_MOV(a,c) M_OR (a,a,c) /* c = a */
1306 #define M_CLR(c) M_OR (31,31,c) /* c = 0 */
1307 #define M_NOP M_OR (31,31,31) /* ; */
1309 #define M_SLL(a,b,c) M_OP3 (0x12,0x39, a,b,c,0) /* c = a << b */
1310 #define M_SRA(a,b,c) M_OP3 (0x12,0x3c, a,b,c,0) /* c = a >> b */
1311 #define M_SRL(a,b,c) M_OP3 (0x12,0x34, a,b,c,0) /* c = a >>>b */
1313 #define M_SLL_IMM(a,b,c) M_OP3 (0x12,0x39, a,b,c,1) /* c = a << b */
1314 #define M_SRA_IMM(a,b,c) M_OP3 (0x12,0x3c, a,b,c,1) /* c = a >> b */
1315 #define M_SRL_IMM(a,b,c) M_OP3 (0x12,0x34, a,b,c,1) /* c = a >>>b */
1317 #define M_FLD(a,b,disp) M_MEM (0x22,a,b,disp) /* load flt */
1318 #define M_DLD(a,b,disp) M_MEM (0x23,a,b,disp) /* load dbl */
1319 #define M_FST(a,b,disp) M_MEM (0x26,a,b,disp) /* store flt */
1320 #define M_DST(a,b,disp) M_MEM (0x27,a,b,disp) /* store dbl */
1322 #define M_FADD(a,b,c) M_FOP3 (0x16, 0x080, a,b,c) /* flt add */
1323 #define M_DADD(a,b,c) M_FOP3 (0x16, 0x0a0, a,b,c) /* dbl add */
1324 #define M_FSUB(a,b,c) M_FOP3 (0x16, 0x081, a,b,c) /* flt sub */
1325 #define M_DSUB(a,b,c) M_FOP3 (0x16, 0x0a1, a,b,c) /* dbl sub */
1326 #define M_FMUL(a,b,c) M_FOP3 (0x16, 0x082, a,b,c) /* flt mul */
1327 #define M_DMUL(a,b,c) M_FOP3 (0x16, 0x0a2, a,b,c) /* dbl mul */
1328 #define M_FDIV(a,b,c) M_FOP3 (0x16, 0x083, a,b,c) /* flt div */
1329 #define M_DDIV(a,b,c) M_FOP3 (0x16, 0x0a3, a,b,c) /* dbl div */
1331 #define M_FADDS(a,b,c) M_FOP3 (0x16, 0x580, a,b,c) /* flt add */
1332 #define M_DADDS(a,b,c) M_FOP3 (0x16, 0x5a0, a,b,c) /* dbl add */
1333 #define M_FSUBS(a,b,c) M_FOP3 (0x16, 0x581, a,b,c) /* flt sub */
1334 #define M_DSUBS(a,b,c) M_FOP3 (0x16, 0x5a1, a,b,c) /* dbl sub */
1335 #define M_FMULS(a,b,c) M_FOP3 (0x16, 0x582, a,b,c) /* flt mul */
1336 #define M_DMULS(a,b,c) M_FOP3 (0x16, 0x5a2, a,b,c) /* dbl mul */
1337 #define M_FDIVS(a,b,c) M_FOP3 (0x16, 0x583, a,b,c) /* flt div */
1338 #define M_DDIVS(a,b,c) M_FOP3 (0x16, 0x5a3, a,b,c) /* dbl div */
1340 #define M_CVTDF(b,c) M_FOP3 (0x16, 0x0ac, 31,b,c) /* dbl2long */
1341 #define M_CVTLF(b,c) M_FOP3 (0x16, 0x0bc, 31,b,c) /* long2flt */
1342 #define M_CVTLD(b,c) M_FOP3 (0x16, 0x0be, 31,b,c) /* long2dbl */
1343 #define M_CVTDL(b,c) M_FOP3 (0x16, 0x1af, 31,b,c) /* dbl2long */
1344 #define M_CVTDL_C(b,c) M_FOP3 (0x16, 0x12f, 31,b,c) /* dbl2long */
1345 #define M_CVTLI(b,c) M_FOP3 (0x17, 0x130, 31,b,c) /* long2int */
1347 #define M_CVTDFS(b,c) M_FOP3 (0x16, 0x5ac, 31,b,c) /* dbl2long */
1348 #define M_CVTDLS(b,c) M_FOP3 (0x16, 0x5af, 31,b,c) /* dbl2long */
1349 #define M_CVTDL_CS(b,c) M_FOP3 (0x16, 0x52f, 31,b,c) /* dbl2long */
1350 #define M_CVTLIS(b,c) M_FOP3 (0x17, 0x530, 31,b,c) /* long2int */
1352 #define M_FCMPEQ(a,b,c) M_FOP3 (0x16, 0x0a5, a,b,c) /* c = a==b */
1353 #define M_FCMPLT(a,b,c) M_FOP3 (0x16, 0x0a6, a,b,c) /* c = a<b */
1355 #define M_FCMPEQS(a,b,c) M_FOP3 (0x16, 0x5a5, a,b,c) /* c = a==b */
1356 #define M_FCMPLTS(a,b,c) M_FOP3 (0x16, 0x5a6, a,b,c) /* c = a<b */
1358 #define M_FMOV(fa,fb) M_FOP3 (0x17, 0x020, fa,fa,fb) /* b = a */
1359 #define M_FMOVN(fa,fb) M_FOP3 (0x17, 0x021, fa,fa,fb) /* b = -a */
1361 #define M_FNOP M_FMOV (31,31)
1363 #define M_FBEQZ(fa,disp) M_BRA (0x31,fa,disp) /* br a == 0.0*/
1365 /* macros for special commands (see an Alpha-manual for description) **********/
1367 #define M_TRAPB M_MEM (0x18,0,0,0x0000) /* trap barrier*/
1369 #define M_S4ADDL(a,b,c) M_OP3 (0x10,0x02, a,b,c,0) /* c = a*4 + b */
1370 #define M_S4ADDQ(a,b,c) M_OP3 (0x10,0x22, a,b,c,0) /* c = a*4 + b */
1371 #define M_S4SUBL(a,b,c) M_OP3 (0x10,0x0b, a,b,c,0) /* c = a*4 - b */
1372 #define M_S4SUBQ(a,b,c) M_OP3 (0x10,0x2b, a,b,c,0) /* c = a*4 - b */
1373 #define M_S8ADDL(a,b,c) M_OP3 (0x10,0x12, a,b,c,0) /* c = a*8 + b */
1374 #define M_S8ADDQ(a,b,c) M_OP3 (0x10,0x32, a,b,c,0) /* c = a*8 + b */
1375 #define M_S8SUBL(a,b,c) M_OP3 (0x10,0x1b, a,b,c,0) /* c = a*8 - b */
1376 #define M_S8SUBQ(a,b,c) M_OP3 (0x10,0x3b, a,b,c,0) /* c = a*8 - b */
1377 #define M_SAADDQ(a,b,c) M_S8ADDQ(a,b,c) /* c = a*8 + b */
1379 #define M_S4ADDL_IMM(a,b,c) M_OP3 (0x10,0x02, a,b,c,1) /* c = a*4 + b */
1380 #define M_S4ADDQ_IMM(a,b,c) M_OP3 (0x10,0x22, a,b,c,1) /* c = a*4 + b */
1381 #define M_S4SUBL_IMM(a,b,c) M_OP3 (0x10,0x0b, a,b,c,1) /* c = a*4 - b */
1382 #define M_S4SUBQ_IMM(a,b,c) M_OP3 (0x10,0x2b, a,b,c,1) /* c = a*4 - b */
1383 #define M_S8ADDL_IMM(a,b,c) M_OP3 (0x10,0x12, a,b,c,1) /* c = a*8 + b */
1384 #define M_S8ADDQ_IMM(a,b,c) M_OP3 (0x10,0x32, a,b,c,1) /* c = a*8 + b */
1385 #define M_S8SUBL_IMM(a,b,c) M_OP3 (0x10,0x1b, a,b,c,1) /* c = a*8 - b */
1386 #define M_S8SUBQ_IMM(a,b,c) M_OP3 (0x10,0x3b, a,b,c,1) /* c = a*8 - b */
1388 #define M_LLD_U(a,b,disp) M_MEM (0x0b,a,b,disp) /* unalign ld */
1389 #define M_LST_U(a,b,disp) M_MEM (0x0f,a,b,disp) /* unalign st */
1391 #define M_ZAP(a,b,c) M_OP3 (0x12,0x30, a,b,c,0)
1392 #define M_ZAPNOT(a,b,c) M_OP3 (0x12,0x31, a,b,c,0)
1394 #define M_ZAP_IMM(a,b,c) M_OP3 (0x12,0x30, a,b,c,1)
1395 #define M_ZAPNOT_IMM(a,b,c) M_OP3 (0x12,0x31, a,b,c,1)
1397 #define M_BZEXT(a,b) M_ZAPNOT_IMM(a, 0x01, b) /* 8 zeroext */
1398 #define M_CZEXT(a,b) M_ZAPNOT_IMM(a, 0x03, b) /* 16 zeroext */
1399 #define M_IZEXT(a,b) M_ZAPNOT_IMM(a, 0x0f, b) /* 32 zeroext */
1401 #define M_EXTBL(a,b,c) M_OP3 (0x12,0x06, a,b,c,0)
1402 #define M_EXTWL(a,b,c) M_OP3 (0x12,0x16, a,b,c,0)
1403 #define M_EXTLL(a,b,c) M_OP3 (0x12,0x26, a,b,c,0)
1404 #define M_EXTQL(a,b,c) M_OP3 (0x12,0x36, a,b,c,0)
1405 #define M_EXTWH(a,b,c) M_OP3 (0x12,0x5a, a,b,c,0)
1406 #define M_EXTLH(a,b,c) M_OP3 (0x12,0x6a, a,b,c,0)
1407 #define M_EXTQH(a,b,c) M_OP3 (0x12,0x7a, a,b,c,0)
1408 #define M_INSBL(a,b,c) M_OP3 (0x12,0x0b, a,b,c,0)
1409 #define M_INSWL(a,b,c) M_OP3 (0x12,0x1b, a,b,c,0)
1410 #define M_INSLL(a,b,c) M_OP3 (0x12,0x2b, a,b,c,0)
1411 #define M_INSQL(a,b,c) M_OP3 (0x12,0x3b, a,b,c,0)
1412 #define M_INSWH(a,b,c) M_OP3 (0x12,0x57, a,b,c,0)
1413 #define M_INSLH(a,b,c) M_OP3 (0x12,0x67, a,b,c,0)
1414 #define M_INSQH(a,b,c) M_OP3 (0x12,0x77, a,b,c,0)
1415 #define M_MSKBL(a,b,c) M_OP3 (0x12,0x02, a,b,c,0)
1416 #define M_MSKWL(a,b,c) M_OP3 (0x12,0x12, a,b,c,0)
1417 #define M_MSKLL(a,b,c) M_OP3 (0x12,0x22, a,b,c,0)
1418 #define M_MSKQL(a,b,c) M_OP3 (0x12,0x32, a,b,c,0)
1419 #define M_MSKWH(a,b,c) M_OP3 (0x12,0x52, a,b,c,0)
1420 #define M_MSKLH(a,b,c) M_OP3 (0x12,0x62, a,b,c,0)
1421 #define M_MSKQH(a,b,c) M_OP3 (0x12,0x72, a,b,c,0)
1423 #define M_EXTBL_IMM(a,b,c) M_OP3 (0x12,0x06, a,b,c,1)
1424 #define M_EXTWL_IMM(a,b,c) M_OP3 (0x12,0x16, a,b,c,1)
1425 #define M_EXTLL_IMM(a,b,c) M_OP3 (0x12,0x26, a,b,c,1)
1426 #define M_EXTQL_IMM(a,b,c) M_OP3 (0x12,0x36, a,b,c,1)
1427 #define M_EXTWH_IMM(a,b,c) M_OP3 (0x12,0x5a, a,b,c,1)
1428 #define M_EXTLH_IMM(a,b,c) M_OP3 (0x12,0x6a, a,b,c,1)
1429 #define M_EXTQH_IMM(a,b,c) M_OP3 (0x12,0x7a, a,b,c,1)
1430 #define M_INSBL_IMM(a,b,c) M_OP3 (0x12,0x0b, a,b,c,1)
1431 #define M_INSWL_IMM(a,b,c) M_OP3 (0x12,0x1b, a,b,c,1)
1432 #define M_INSLL_IMM(a,b,c) M_OP3 (0x12,0x2b, a,b,c,1)
1433 #define M_INSQL_IMM(a,b,c) M_OP3 (0x12,0x3b, a,b,c,1)
1434 #define M_INSWH_IMM(a,b,c) M_OP3 (0x12,0x57, a,b,c,1)
1435 #define M_INSLH_IMM(a,b,c) M_OP3 (0x12,0x67, a,b,c,1)
1436 #define M_INSQH_IMM(a,b,c) M_OP3 (0x12,0x77, a,b,c,1)
1437 #define M_MSKBL_IMM(a,b,c) M_OP3 (0x12,0x02, a,b,c,1)
1438 #define M_MSKWL_IMM(a,b,c) M_OP3 (0x12,0x12, a,b,c,1)
1439 #define M_MSKLL_IMM(a,b,c) M_OP3 (0x12,0x22, a,b,c,1)
1440 #define M_MSKQL_IMM(a,b,c) M_OP3 (0x12,0x32, a,b,c,1)
1441 #define M_MSKWH_IMM(a,b,c) M_OP3 (0x12,0x52, a,b,c,1)
1442 #define M_MSKLH_IMM(a,b,c) M_OP3 (0x12,0x62, a,b,c,1)
1443 #define M_MSKQH_IMM(a,b,c) M_OP3 (0x12,0x72, a,b,c,1)
1445 #define M_UMULH(a,b,c) M_OP3 (0x13,0x30, a,b,c,0) /* 64 umulh */
1447 #define M_UMULH_IMM(a,b,c) M_OP3 (0x13,0x30, a,b,c,1) /* 64 umulh */
1449 #define M_CMOVEQ(a,b,c) M_OP3 (0x11,0x24, a,b,c,0) /* a==0 ? c=b */
1450 #define M_CMOVNE(a,b,c) M_OP3 (0x11,0x26, a,b,c,0) /* a!=0 ? c=b */
1451 #define M_CMOVLT(a,b,c) M_OP3 (0x11,0x44, a,b,c,0) /* a< 0 ? c=b */
1452 #define M_CMOVGE(a,b,c) M_OP3 (0x11,0x46, a,b,c,0) /* a>=0 ? c=b */
1453 #define M_CMOVLE(a,b,c) M_OP3 (0x11,0x64, a,b,c,0) /* a<=0 ? c=b */
1454 #define M_CMOVGT(a,b,c) M_OP3 (0x11,0x66, a,b,c,0) /* a> 0 ? c=b */
1456 #define M_CMOVEQ_IMM(a,b,c) M_OP3 (0x11,0x24, a,b,c,1) /* a==0 ? c=b */
1457 #define M_CMOVNE_IMM(a,b,c) M_OP3 (0x11,0x26, a,b,c,1) /* a!=0 ? c=b */
1458 #define M_CMOVLT_IMM(a,b,c) M_OP3 (0x11,0x44, a,b,c,1) /* a< 0 ? c=b */
1459 #define M_CMOVGE_IMM(a,b,c) M_OP3 (0x11,0x46, a,b,c,1) /* a>=0 ? c=b */
1460 #define M_CMOVLE_IMM(a,b,c) M_OP3 (0x11,0x64, a,b,c,1) /* a<=0 ? c=b */
1461 #define M_CMOVGT_IMM(a,b,c) M_OP3 (0x11,0x66, a,b,c,1) /* a> 0 ? c=b */
1463 /* macros for unused commands (see an Alpha-manual for description) ***********/
1465 #define M_ANDNOT(a,b,c,const) M_OP3 (0x11,0x08, a,b,c,const) /* c = a &~ b */
1466 #define M_ORNOT(a,b,c,const) M_OP3 (0x11,0x28, a,b,c,const) /* c = a |~ b */
1467 #define M_XORNOT(a,b,c,const) M_OP3 (0x11,0x48, a,b,c,const) /* c = a ^~ b */
1469 #define M_CMPBGE(a,b,c,const) M_OP3 (0x10,0x0f, a,b,c,const)
1471 #define M_FCMPUN(a,b,c) M_FOP3 (0x16, 0x0a4, a,b,c) /* unordered */
1472 #define M_FCMPLE(a,b,c) M_FOP3 (0x16, 0x0a7, a,b,c) /* c = a<=b */
1474 #define M_FCMPUNS(a,b,c) M_FOP3 (0x16, 0x5a4, a,b,c) /* unordered */
1475 #define M_FCMPLES(a,b,c) M_FOP3 (0x16, 0x5a7, a,b,c) /* c = a<=b */
1477 #define M_FBNEZ(fa,disp) M_BRA (0x35,fa,disp)
1478 #define M_FBLEZ(fa,disp) M_BRA (0x33,fa,disp)
1480 #define M_JMP_CO(a,b) M_MEM (0x1a,a,b,0xc000) /* call cosub */
1483 /* function gen_resolvebranch **************************************************
1485 backpatches a branch instruction; Alpha branch instructions are very
1486 regular, so it is only necessary to overwrite some fixed bits in the
1489 parameters: ip ... pointer to instruction after branch (void*)
1490 so ... offset of instruction after branch (s4)
1491 to ... offset of branch target (s4)
1493 *******************************************************************************/
1495 #define gen_resolvebranch(ip,so,to) \
1497 *((s4 *) (((u1 *) (ip)) - 4)) = ((s4) ((to) - (so))); \
1500 #define SOFTNULLPTRCHECK /* soft null pointer check supportet as option */