Major file restructuring.
[cacao.git] / jit / i386 / codegen.h
1 /* jit/i386/codegen.h - code generation macros and definitions for i386
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Christian Thalinger
29
30    $Id: codegen.h 557 2003-11-02 22:51:59Z twisti $
31
32 */
33
34
35 #ifndef _CODEGEN_H
36 #define _CODEGEN_H
37
38 #include "jit.h"
39
40
41 /* define x86 register numbers */
42 #define I386_EAX    0
43 #define I386_ECX    1
44 #define I386_EDX    2
45 #define I386_EBX    3
46 #define I386_ESP    4
47 #define I386_EBP    5
48 #define I386_ESI    6
49 #define I386_EDI    7
50
51
52 /* preallocated registers *****************************************************/
53
54 /* integer registers */
55   
56 #define REG_RESULT      I386_EAX /* to deliver method results                 */
57 #define REG_RESULT2     I386_EDX /* to deliver long method results            */
58
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                        */
62
63 #define REG_NULL        -1       /* used for reg_of_var where d is not needed */
64
65 #define REG_ITMP1_XPTR  I386_EAX /* exception pointer = temporary register 1  */
66 #define REG_ITMP2_XPC   I386_EDX /* exception pc = temporary register 2       */
67
68 #define REG_SP          I386_ESP /* stack pointer                             */
69
70 /* floating point registers */
71
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             */
76
77 /* register descripton - array ************************************************/
78
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)               */
85
86 /* #define REG_END   -1        last entry in tables */
87
88 int nregdescint[] = {
89     REG_RET, REG_RES, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_TMP, REG_TMP,
90     REG_END };
91
92 /* for use of reserved registers, see comment above */
93
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,
99     REG_END };
100
101 /* for use of reserved registers, see comment above */
102
103
104 /* stackframe-infos ***********************************************************/
105
106 int parentargs_base; /* offset in stackframe for the parameter from the caller*/
107
108 /* -> see file 'calling.doc' */
109
110
111 static u1 fpu_in_24bit_mode = 0;
112
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 */
115
116 static u4 subnormal_bias1[3] = { 0x00000000, 0x80000000, 0x03ff };    /* 2^(-15360) */
117 static u4 subnormal_bias2[3] = { 0x00000000, 0x80000000, 0x7bff };    /* 2^(+15360) */
118
119
120 /* macros to create code ******************************************************/
121
122 /*
123  * immediate data union
124  */
125 typedef union {
126     s4 i;
127     s8 l;
128     float f;
129     double d;
130     void *a;
131     u1 b[8];
132 } i386_imm_buf;
133
134
135 typedef enum {
136     I386_AL = 0,
137     I386_CL = 1,
138     I386_DL = 2,
139     I386_BL = 3,
140     I386_AH = 4,
141     I386_CH = 5,
142     I386_DH = 6,
143     I386_BH = 7,
144     I386_NREGB
145 } I386_RegB_No;
146
147
148 /*
149  * opcodes for alu instructions
150  */
151 typedef enum {
152     I386_ADD = 0,
153     I386_OR  = 1,
154     I386_ADC = 2,
155     I386_SBB = 3,
156     I386_AND = 4,
157     I386_SUB = 5,
158     I386_XOR = 6,
159     I386_CMP = 7,
160     I386_NALU
161 } I386_ALU_Opcode;
162
163 typedef enum {
164     I386_ROL = 0,
165     I386_ROR = 1,
166     I386_RCL = 2,
167     I386_RCR = 3,
168     I386_SHL = 4,
169     I386_SHR = 5,
170     I386_SAR = 7,
171     I386_NSHIFT = 8
172 } I386_Shift_Opcode;
173
174 typedef enum {
175     I386_CC_O = 0,
176     I386_CC_NO = 1,
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,
191     I386_NCC
192 } I386_CC;
193
194 static const unsigned char i386_jcc_map[] = {
195     0x00, /* o  */
196     0x01, /* no */
197     0x02, /* b, lt  */
198     0x03, /* ae */
199     0x04, /* e  */
200     0x05, /* ne */
201     0x06, /* be */
202     0x07, /* a  */
203     0x08, /* s  */
204     0x09, /* ns */
205     0x0a, /* p  */
206     0x0b, /* np */
207     0x0c, /* l  */
208     0x0d, /* ge */
209     0x0e, /* le */
210     0x0f  /* g  */
211 };
212
213
214
215 /*
216  * modrm and stuff
217  */
218 #define i386_address_byte(mod, reg, rm) \
219     *(mcodeptr++) = ((((mod) & 0x03) << 6) | (((reg) & 0x07) << 3) | (((rm) & 0x07)));
220
221
222 #define i386_emit_reg(reg,rm) \
223     i386_address_byte(3,(reg),(rm));
224
225
226 #define i386_is_imm8(imm) \
227     (((int)(imm) >= -128 && (int)(imm) <= 127))
228
229
230 #define i386_emit_imm8(imm) \
231     *(mcodeptr++) = (u1) ((imm) & 0xff);
232
233
234 #define i386_emit_imm16(imm) \
235     do { \
236         i386_imm_buf imb; \
237         imb.i = (int) (imm); \
238         *(mcodeptr++) = imb.b[0]; \
239         *(mcodeptr++) = imb.b[1]; \
240     } while (0)
241
242
243 #define i386_emit_imm32(imm) \
244     do { \
245         i386_imm_buf imb; \
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]; \
251     } while (0)
252
253
254 #define i386_emit_mem(r,disp) \
255     do { \
256         i386_address_byte(0,(r),5); \
257         i386_emit_imm32((disp)); \
258     } while (0)
259
260
261 #define i386_emit_membase(basereg,disp,dreg) \
262     do { \
263         if ((basereg) == I386_ESP) { \
264             if ((disp) == 0) { \
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)); \
271             } else { \
272                 i386_address_byte(2, (dreg), I386_ESP); \
273                 i386_address_byte(0, I386_ESP, I386_ESP); \
274                 i386_emit_imm32((disp)); \
275             } \
276             break; \
277         } \
278         \
279         if ((disp) == 0 && (basereg) != I386_EBP) { \
280             i386_address_byte(0, (dreg), (basereg)); \
281             break; \
282         } \
283         \
284         if (i386_is_imm8((disp))) { \
285             i386_address_byte(1, (dreg), (basereg)); \
286             i386_emit_imm8((disp)); \
287         } else { \
288             i386_address_byte(2, (dreg), (basereg)); \
289             i386_emit_imm32((disp)); \
290         } \
291     } while (0)
292
293
294 #define i386_emit_memindex(reg,disp,basereg,indexreg,scale) \
295     do { \
296         if ((basereg) == -1) { \
297             i386_address_byte(0, (reg), 4); \
298             i386_address_byte((scale), (indexreg), 5); \
299             i386_emit_imm32((disp)); \
300         \
301         } else if ((disp) == 0 && (basereg) != I386_EBP) { \
302             i386_address_byte(0, (reg), 4); \
303             i386_address_byte((scale), (indexreg), (basereg)); \
304         \
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)); \
309         \
310         } else { \
311             i386_address_byte(2, (reg), 4); \
312             i386_address_byte((scale), (indexreg), (basereg)); \
313             i386_emit_imm32((disp)); \
314         }    \
315      } while (0)
316
317
318
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);
326
327
328
329 #if 0
330
331 /*
332  * mov ops
333  */
334 #define i386_mov_reg_reg(reg,dreg) \
335     do { \
336         *(mcodeptr++) = (u1) 0x89; \
337         i386_emit_reg((reg),(dreg)); \
338     } while (0)
339
340
341 #define i386_mov_imm_reg(imm,reg) \
342     do { \
343         *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07); \
344         i386_emit_imm32((imm)); \
345     } while (0)
346
347
348 #define i386_movb_imm_reg(imm,reg) \
349     do { \
350         *(mcodeptr++) = (u1) 0xc6; \
351         i386_emit_reg(0,(reg)); \
352         i386_emit_imm8((imm)); \
353     } while (0)
354
355
356 #define i386_mov_float_reg(imm,reg) \
357     do { \
358         *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07); \
359         i386_emit_float32((imm)); \
360     } while (0)
361
362
363 #define i386_mov_reg_mem(reg,mem) \
364     do { \
365         *(mcodeptr++) = (u1) 0x89; \
366         i386_emit_mem((reg),(mem)); \
367     } while (0)
368
369
370 #define i386_mov_mem_reg(mem,reg) \
371     do { \
372         *(mcodeptr++) = (u1) 0x8b; \
373         i386_emit_mem((reg),(mem)); \
374     } while (0)
375
376
377 #define i386_mov_membase_reg(basereg,disp,reg) \
378     do { \
379         *(mcodeptr++) = (u1) 0x8b; \
380         i386_emit_membase((basereg),(disp),(reg)); \
381     } while (0)
382
383
384 /*
385  * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
386  * constant membase immediate length of 32bit
387  */
388 #define i386_mov_membase32_reg(basereg,disp,reg) \
389     do { \
390         *(mcodeptr++) = (u1) 0x8b; \
391         i386_address_byte(2, (reg), (basereg)); \
392         i386_emit_imm32((disp)); \
393     } while (0)
394
395
396 #define i386_movw_membase_reg(basereg,disp,reg) \
397     do { \
398         *(mcodeptr++) = (u1) 0x66; \
399         i386_mov_membase_reg((basereg),(disp),(reg)); \
400     } while (0)
401
402
403 #define i386_movb_membase_reg(basereg,disp,reg) \
404     do { \
405         *(mcodeptr++) = (u1) 0x8a; \
406         i386_emit_membase((basereg),(disp),(reg)); \
407     } while (0)
408
409
410 #define i386_mov_reg_membase(reg,basereg,disp) \
411     do { \
412         *(mcodeptr++) = (u1) 0x89; \
413         i386_emit_membase((basereg),(disp),(reg)); \
414     } while (0)
415
416
417 #define i386_movw_reg_membase(reg,basereg,disp) \
418     do { \
419         *(mcodeptr++) = (u1) 0x66; \
420         *(mcodeptr++) = (u1) 0x89; \
421         i386_emit_membase((basereg),(disp),(reg)); \
422     } while (0)
423
424
425 #define i386_movb_reg_membase(reg,basereg,disp) \
426     do { \
427         *(mcodeptr++) = (u1) 0x88; \
428         i386_emit_membase((basereg),(disp),(reg)); \
429     } while (0)
430
431
432 #define i386_mov_memindex_reg(disp,basereg,indexreg,scale,reg) \
433     do { \
434         *(mcodeptr++) = (u1) 0x8b; \
435         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
436     } while (0)
437
438
439 #define i386_movw_memindex_reg(disp,basereg,indexreg,scale,reg) \
440     do { \
441         *(mcodeptr++) = (u1) 0x66; \
442         *(mcodeptr++) = (u1) 0x8b; \
443         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
444     } while (0)
445
446
447 #define i386_movb_memindex_reg(disp,basereg,indexreg,scale,reg) \
448     do { \
449         *(mcodeptr++) = (u1) 0x8a; \
450         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
451     } while (0)
452
453
454 #define i386_mov_reg_memindex(reg,disp,basereg,indexreg,scale) \
455     do { \
456         *(mcodeptr++) = (u1) 0x89; \
457         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
458     } while (0)
459
460
461 #define i386_movw_reg_memindex(reg,disp,basereg,indexreg,scale) \
462     do { \
463         *(mcodeptr++) = (u1) 0x66; \
464         *(mcodeptr++) = (u1) 0x89; \
465         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
466     } while (0)
467
468
469 #define i386_movb_reg_memindex(reg,disp,basereg,indexreg,scale) \
470     do { \
471         *(mcodeptr++) = (u1) 0x88; \
472         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
473     } while (0)
474
475
476 #define i386_mov_imm_membase(imm,basereg,disp) \
477     do { \
478         *(mcodeptr++) = (u1) 0xc7; \
479         i386_emit_membase((basereg),(disp),0); \
480         i386_emit_imm32((imm)); \
481     } while (0)
482
483
484 #define i386_mov_float_membase(imm,basereg,disp) \
485     do { \
486         *(mcodeptr++) = (u1) 0xc7; \
487         i386_emit_membase((basereg),(disp),0); \
488         i386_emit_float32((imm)); \
489     } while (0)
490
491
492 #define i386_mov_double_low_membase(imm,basereg,disp) \
493     do { \
494         *(mcodeptr++) = (u1) 0xc7; \
495         i386_emit_membase((basereg),(disp),0); \
496         i386_emit_double64_low((imm)); \
497     } while (0)
498
499
500 #define i386_mov_double_high_membase(imm,basereg,disp) \
501     do { \
502         *(mcodeptr++) = (u1) 0xc7; \
503         i386_emit_membase((basereg),(disp),0); \
504         i386_emit_double64_high((imm)); \
505     } while (0)
506
507
508 #define i386_movsbl_reg_reg(reg,dreg) \
509     do { \
510         *(mcodeptr++) = (u1) 0x0f; \
511         *(mcodeptr++) = (u1) 0xbe; \
512         i386_emit_reg((reg),(dreg)); \
513     } while (0)
514
515
516 #define i386_movswl_reg_reg(reg,dreg) \
517     do { \
518         *(mcodeptr++) = (u1) 0x0f; \
519         *(mcodeptr++) = (u1) 0xbf; \
520         i386_emit_reg((reg),(dreg)); \
521     } while (0)
522
523
524 #define i386_movzbl_reg_reg(reg,dreg) \
525     do { \
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)); \
530     } while (0)
531
532
533 #define i386_movzwl_reg_reg(reg,dreg) \
534     do { \
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)); \
539     } while (0)
540
541
542 #define i386_movsbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
543     do { \
544         *(mcodeptr++) = (u1) 0x0f; \
545         *(mcodeptr++) = (u1) 0xbe; \
546         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
547     } while (0)
548
549
550 #define i386_movswl_memindex_reg(disp,basereg,indexreg,scale,reg) \
551     do { \
552         *(mcodeptr++) = (u1) 0x0f; \
553         *(mcodeptr++) = (u1) 0xbf; \
554         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
555     } while (0)
556
557
558 #define i386_movzbl_memindex_reg(disp,basereg,indexreg,scale,reg) \
559     do { \
560         *(mcodeptr++) = (u1) 0x0f; \
561         *(mcodeptr++) = (u1) 0xb6; \
562         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
563     } while (0)
564
565
566 #define i386_movzwl_memindex_reg(disp,basereg,indexreg,scale,reg) \
567     do { \
568         *(mcodeptr++) = (u1) 0x0f; \
569         *(mcodeptr++) = (u1) 0xb7; \
570         i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale)); \
571     } while (0)
572
573
574
575 /*
576  * alu operations
577  */
578 #define i386_alu_reg_reg(opc,reg,dreg) \
579     do { \
580         *(mcodeptr++) = (((u1) (opc)) << 3) + 1; \
581         i386_emit_reg((reg),(dreg)); \
582     } while (0)
583
584
585 #define i386_alu_reg_membase(opc,reg,basereg,disp) \
586     do { \
587         *(mcodeptr++) = (((u1) (opc)) << 3) + 1; \
588         i386_emit_membase((basereg),(disp),(reg)); \
589     } while (0)
590
591
592 #define i386_alu_membase_reg(opc,basereg,disp,reg) \
593     do { \
594         *(mcodeptr++) = (((u1) (opc)) << 3) + 3; \
595         i386_emit_membase((basereg),(disp),(reg)); \
596     } while (0)
597
598
599 #define i386_alu_imm_reg(opc,imm,dreg) \
600     do { \
601         if (i386_is_imm8(imm)) { \
602             *(mcodeptr++) = (u1) 0x83; \
603             i386_emit_reg((opc),(dreg)); \
604             i386_emit_imm8((imm)); \
605         } else { \
606             *(mcodeptr++) = (u1) 0x81; \
607             i386_emit_reg((opc),(dreg)); \
608             i386_emit_imm32((imm)); \
609         } \
610     } while (0)
611
612
613 #define i386_alu_imm_membase(opc,imm,basereg,disp) \
614     do { \
615         if (i386_is_imm8(imm)) { \
616             *(mcodeptr++) = (u1) 0x83; \
617             i386_emit_membase((basereg),(disp),(opc)); \
618             i386_emit_imm8((imm)); \
619         } else { \
620             *(mcodeptr++) = (u1) 0x81; \
621             i386_emit_membase((basereg),(disp),(opc)); \
622             i386_emit_imm32((imm)); \
623         } \
624     } while (0)
625
626
627 #define i386_test_reg_reg(reg,dreg) \
628     do { \
629         *(mcodeptr++) = (u1) 0x85; \
630         i386_emit_reg((reg),(dreg)); \
631     } while (0)
632
633
634 #define i386_test_imm_reg(imm,reg) \
635     do { \
636         *(mcodeptr++) = (u1) 0xf7; \
637         i386_emit_reg(0,(reg)); \
638         i386_emit_imm32((imm)); \
639     } while (0)
640
641
642 #define i386_testw_imm_reg(imm,reg) \
643     do { \
644         *(mcodeptr++) = (u1) 0x66; \
645         *(mcodeptr++) = (u1) 0xf7; \
646         i386_emit_reg(0,(reg)); \
647         i386_emit_imm16((imm)); \
648     } while (0)
649
650
651 #define i386_testb_imm_reg(imm,reg) \
652     do { \
653         *(mcodeptr++) = (u1) 0xf6; \
654         i386_emit_reg(0,(reg)); \
655         i386_emit_imm8((imm)); \
656     } while (0)
657
658
659
660 /*
661  * inc, dec operations
662  */
663 #define i386_inc_reg(reg) \
664     *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
665
666
667 #define i386_inc_membase(basereg,disp) \
668     do { \
669         *(mcodeptr++) = (u1) 0xff; \
670         i386_emit_membase((basereg),(disp),0); \
671     } while (0)
672
673
674 #define i386_dec_reg(reg) \
675     *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
676
677         
678 #define i386_dec_membase(basereg,disp) \
679     do { \
680         *(mcodeptr++) = (u1) 0xff; \
681         i386_emit_membase((basereg),(disp),1); \
682     } while (0)
683
684
685
686
687 #define i386_cltd() \
688     *(mcodeptr++) = (u1) 0x99;
689
690
691
692 #define i386_imul_reg_reg(reg,dreg) \
693     do { \
694         *(mcodeptr++) = (u1) 0x0f; \
695         *(mcodeptr++) = (u1) 0xaf; \
696         i386_emit_reg((dreg),(reg)); \
697     } while (0)
698
699
700 #define i386_imul_membase_reg(basereg,disp,dreg) \
701     do { \
702         *(mcodeptr++) = (u1) 0x0f; \
703         *(mcodeptr++) = (u1) 0xaf; \
704         i386_emit_membase((basereg),(disp),(dreg)); \
705     } while (0)
706
707
708 #define i386_imul_imm_reg(imm,dreg) \
709     do { \
710         if (i386_is_imm8((imm))) { \
711             *(mcodeptr++) = (u1) 0x6b; \
712             i386_emit_reg(0,(dreg)); \
713             i386_emit_imm8((imm)); \
714         } else { \
715             *(mcodeptr++) = (u1) 0x69; \
716             i386_emit_reg(0,(dreg)); \
717             i386_emit_imm32((imm)); \
718         } \
719     } while (0)
720
721
722 #define i386_imul_imm_reg_reg(imm,reg,dreg) \
723     do { \
724         if (i386_is_imm8((imm))) { \
725             *(mcodeptr++) = (u1) 0x6b; \
726             i386_emit_reg((dreg),(reg)); \
727             i386_emit_imm8((imm)); \
728         } else { \
729             *(mcodeptr++) = (u1) 0x69; \
730             i386_emit_reg((dreg),(reg)); \
731             i386_emit_imm32((imm)); \
732         } \
733     } while (0)
734
735
736 #define i386_imul_imm_membase_reg(imm,basereg,disp,dreg) \
737     do { \
738         if (i386_is_imm8((imm))) { \
739             *(mcodeptr++) = (u1) 0x6b; \
740             i386_emit_membase((basereg),(disp),(dreg)); \
741             i386_emit_imm8((imm)); \
742         } else { \
743             *(mcodeptr++) = (u1) 0x69; \
744             i386_emit_membase((basereg),(disp),(dreg)); \
745             i386_emit_imm32((imm)); \
746         } \
747     } while (0)
748
749
750 #define i386_mul_reg(reg) \
751     do { \
752         *(mcodeptr++) = (u1) 0xf7; \
753         i386_emit_reg(4,(reg)); \
754     } while (0)
755
756
757 #define i386_mul_membase(basereg,disp) \
758     do { \
759         *(mcodeptr++) = (u1) 0xf7; \
760         i386_emit_membase((basereg),(disp),4); \
761     } while (0)
762
763
764 #define i386_idiv_reg(reg) \
765     do { \
766         *(mcodeptr++) = (u1) 0xf7; \
767         i386_emit_reg(7,(reg)); \
768     } while (0)
769
770
771 #define i386_idiv_membase(basereg,disp) \
772     do { \
773         *(mcodeptr++) = (u1) 0xf7; \
774         i386_emit_membase((basereg),(disp),7); \
775     } while (0)
776
777
778
779 #define i386_ret() \
780     *(mcodeptr++) = (u1) 0xc3;
781
782
783 #define i386_leave() \
784     *(mcodeptr++) = (u1) 0xc9;
785
786
787
788 /*
789  * shift ops
790  */
791 #define i386_shift_reg(opc,reg) \
792     do { \
793         *(mcodeptr++) = (u1) 0xd3; \
794         i386_emit_reg((opc),(reg)); \
795     } while (0)
796
797
798 #define i386_shift_membase(opc,basereg,disp) \
799     do { \
800         *(mcodeptr++) = (u1) 0xd3; \
801         i386_emit_membase((basereg),(disp),(opc)); \
802     } while (0)
803
804
805 #define i386_shift_imm_reg(opc,imm,dreg) \
806     do { \
807         if ((imm) == 1) { \
808             *(mcodeptr++) = (u1) 0xd1; \
809             i386_emit_reg((opc),(dreg)); \
810         } else { \
811             *(mcodeptr++) = (u1) 0xc1; \
812             i386_emit_reg((opc),(dreg)); \
813             i386_emit_imm8((imm)); \
814         } \
815     } while (0)
816
817
818 #define i386_shift_imm_membase(opc,imm,basereg,disp) \
819     do { \
820         if ((imm) == 1) { \
821             *(mcodeptr++) = (u1) 0xd1; \
822             i386_emit_membase((basereg),(disp),(opc)); \
823         } else { \
824             *(mcodeptr++) = (u1) 0xc1; \
825             i386_emit_membase((basereg),(disp),(opc)); \
826             i386_emit_imm8((imm)); \
827         } \
828     } while (0)
829
830
831 #define i386_shld_reg_reg(reg,dreg) \
832     do { \
833         *(mcodeptr++) = (u1) 0x0f; \
834         *(mcodeptr++) = (u1) 0xa5; \
835         i386_emit_reg((reg),(dreg)); \
836     } while (0)
837
838
839 #define i386_shld_imm_reg_reg(imm,reg,dreg) \
840     do { \
841         *(mcodeptr++) = (u1) 0x0f; \
842         *(mcodeptr++) = (u1) 0xa4; \
843         i386_emit_reg((reg),(dreg)); \
844         i386_emit_imm8((imm)); \
845     } while (0)
846
847
848 #define i386_shld_reg_membase(reg,basereg,disp) \
849     do { \
850         *(mcodeptr++) = (u1) 0x0f; \
851         *(mcodeptr++) = (u1) 0xa5; \
852         i386_emit_membase((basereg),(disp),(reg)); \
853     } while (0)
854
855
856 #define i386_shrd_reg_reg(reg,dreg) \
857     do { \
858         *(mcodeptr++) = (u1) 0x0f; \
859         *(mcodeptr++) = (u1) 0xad; \
860         i386_emit_reg((reg),(dreg)); \
861     } while (0)
862
863
864 #define i386_shrd_imm_reg_reg(imm,reg,dreg) \
865     do { \
866         *(mcodeptr++) = (u1) 0x0f; \
867         *(mcodeptr++) = (u1) 0xac; \
868         i386_emit_reg((reg),(dreg)); \
869         i386_emit_imm8((imm)); \
870     } while (0)
871
872
873 #define i386_shrd_reg_membase(reg,basereg,disp) \
874     do { \
875         *(mcodeptr++) = (u1) 0x0f; \
876         *(mcodeptr++) = (u1) 0xad; \
877         i386_emit_membase((basereg),(disp),(reg)); \
878     } while (0)
879
880
881
882 /*
883  * jump operations
884  */
885 #define i386_jmp_imm(imm) \
886     do { \
887         *(mcodeptr++) = (u1) 0xe9; \
888         i386_emit_imm32((imm)); \
889     } while (0)
890
891
892 #define i386_jmp_reg(reg) \
893     do { \
894         *(mcodeptr++) = (u1) 0xff; \
895         i386_emit_reg(4,(reg)); \
896     } while (0)
897
898
899 #define i386_jcc(opc,imm) \
900     do { \
901         *(mcodeptr++) = (u1) 0x0f; \
902         *(mcodeptr++) = (u1) (0x80 + i386_jcc_map[(opc)]); \
903         i386_emit_imm32((imm)); \
904     } while (0)
905
906
907
908 /*
909  * conditional set operations
910  */
911 #define i386_setcc_reg(opc,reg) \
912     do { \
913         *(mcodeptr++) = (u1) 0x0f; \
914         *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
915         i386_emit_reg(0,(reg)); \
916     } while (0)
917
918
919 #define i386_setcc_membase(opc,basereg,disp) \
920     do { \
921         *(mcodeptr++) = (u1) 0x0f; \
922         *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]); \
923         i386_emit_membase((basereg),(disp),0); \
924     } while (0)
925
926
927
928 #define i386_neg_reg(reg) \
929     do { \
930         *(mcodeptr++) = (u1) 0xf7; \
931         i386_emit_reg(3,(reg)); \
932     } while (0)
933
934
935 #define i386_neg_mem(mem) \
936     do { \
937         *(mcodeptr++) = (u1) 0xf7; \
938         i386_emit_mem(3,(mem)); \
939     } while (0)
940
941
942 #define i386_neg_membase(basereg,disp) \
943     do { \
944         *(mcodeptr++) = (u1) 0xf7; \
945         i386_emit_membase((basereg),(disp),3); \
946     } while (0)
947
948
949
950 #define i386_push_reg(reg) \
951     *(mcodeptr++) = (u1) 0x50 + (0x07 & (reg));
952
953
954 #define i386_push_membase(basereg,disp) \
955     do { \
956         *(mcodeptr++) = (u1) 0xff; \
957         i386_emit_membase((basereg),(disp),6); \
958     } while (0)
959
960
961 #define i386_push_imm(imm) \
962     do { \
963         *(mcodeptr++) = (u1) 0x68; \
964         i386_emit_imm32((imm)); \
965     } while (0)
966
967
968 #define i386_pop_reg(reg) \
969     *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
970
971
972 #define i386_nop() \
973     *(mcodeptr++) = (u1) 0x90;
974
975
976
977 /*
978  * call instructions
979  */
980 #define i386_call_reg(reg) \
981     do { \
982         *(mcodeptr++) = (u1) 0xff; \
983         i386_emit_reg(2,(reg)); \
984     } while (0)
985
986
987 #define i386_call_imm(imm) \
988     do { \
989         *(mcodeptr++) = (u1) 0xe8; \
990         i386_emit_imm32((imm)); \
991     } while (0)
992
993
994
995 /*
996  * floating point instructions
997  */
998 #define i386_fld1() \
999     do { \
1000         *(mcodeptr++) = (u1) 0xd9; \
1001         *(mcodeptr++) = (u1) 0xe8; \
1002     } while (0)
1003
1004
1005 #define i386_fldz() \
1006     do { \
1007         *(mcodeptr++) = (u1) 0xd9; \
1008         *(mcodeptr++) = (u1) 0xee; \
1009     } while (0)
1010
1011
1012 #define i386_fld_reg(reg) \
1013     do { \
1014         *(mcodeptr++) = (u1) 0xd9; \
1015         *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg)); \
1016     } while (0)
1017
1018
1019 #define i386_flds_mem(mem) \
1020     do { \
1021         *(mcodeptr++) = (u1) 0xd9; \
1022         i386_emit_mem(0,(mem)); \
1023     } while (0)
1024
1025
1026 #define i386_fldl_mem(mem) \
1027     do { \
1028         *(mcodeptr++) = (u1) 0xdd; \
1029         i386_emit_mem(0,(mem)); \
1030     } while (0)
1031
1032
1033 #define i386_fldt_mem(mem) \
1034     do { \
1035         *(mcodeptr++) = (u1) 0xdb; \
1036         i386_emit_mem(5,(mem)); \
1037     } while (0)
1038
1039
1040 #define i386_flds_membase(basereg,disp) \
1041     do { \
1042         *(mcodeptr++) = (u1) 0xd9; \
1043         i386_emit_membase((basereg),(disp),0); \
1044     } while (0)
1045
1046
1047 #define i386_fldl_membase(basereg,disp) \
1048     do { \
1049         *(mcodeptr++) = (u1) 0xdd; \
1050         i386_emit_membase((basereg),(disp),0); \
1051     } while (0)
1052
1053
1054 #define i386_fldt_membase(basereg,disp) \
1055     do { \
1056         *(mcodeptr++) = (u1) 0xdb; \
1057         i386_emit_membase((basereg),(disp),5); \
1058     } while (0)
1059
1060
1061 #define i386_flds_memindex(disp,basereg,indexreg,scale) \
1062     do { \
1063         *(mcodeptr++) = (u1) 0xd9; \
1064         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
1065     } while (0)
1066
1067
1068 #define i386_fldl_memindex(disp,basereg,indexreg,scale) \
1069     do { \
1070         *(mcodeptr++) = (u1) 0xdd; \
1071         i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale)); \
1072     } while (0)
1073
1074
1075
1076
1077 #define i386_fildl_mem(mem) \
1078     do { \
1079         *(mcodeptr++) = (u1) 0xdb; \
1080         i386_emit_mem(0,(mem)); \
1081     } while (0)
1082
1083
1084 #define i386_fildl_membase(basereg,disp) \
1085     do { \
1086         *(mcodeptr++) = (u1) 0xdb; \
1087         i386_emit_membase((basereg),(disp),0); \
1088     } while (0)
1089
1090
1091 #define i386_fildll_membase(basereg,disp) \
1092     do { \
1093         *(mcodeptr++) = (u1) 0xdf; \
1094         i386_emit_membase((basereg),(disp),5); \
1095     } while (0)
1096
1097
1098
1099
1100 #define i386_fst_reg(reg) \
1101     do { \
1102         *(mcodeptr++) = (u1) 0xdd; \
1103         *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg)); \
1104     } while (0)
1105
1106
1107 #define i386_fsts_mem(mem) \
1108     do { \
1109         *(mcodeptr++) = (u1) 0xd9; \
1110         i386_emit_mem(2,(mem)); \
1111     } while (0)
1112
1113
1114 #define i386_fstl_mem(mem) \
1115     do { \
1116         *(mcodeptr++) = (u1) 0xdd; \
1117         i386_emit_mem(2,(mem)); \
1118     } while (0)
1119
1120
1121 #define i386_fsts_membase(basereg,disp) \
1122     do { \
1123         *(mcodeptr++) = (u1) 0xd9; \
1124         i386_emit_membase((basereg),(disp),2); \
1125     } while (0)
1126
1127
1128 #define i386_fstl_membase(basereg,disp) \
1129     do { \
1130         *(mcodeptr++) = (u1) 0xdd; \
1131         i386_emit_membase((basereg),(disp),2); \
1132     } while (0)
1133
1134
1135 #define i386_fsts_memindex(disp,basereg,indexreg,scale) \
1136     do { \
1137         *(mcodeptr++) = (u1) 0xd9; \
1138         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1139     } while (0)
1140
1141
1142 #define i386_fstl_memindex(disp,basereg,indexreg,scale) \
1143     do { \
1144         *(mcodeptr++) = (u1) 0xdd; \
1145         i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale)); \
1146     } while (0)
1147
1148
1149
1150
1151 #define i386_fstp_reg(reg) \
1152     do { \
1153         *(mcodeptr++) = (u1) 0xdd; \
1154         *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg)); \
1155     } while (0)
1156
1157
1158 #define i386_fstps_mem(mem) \
1159     do { \
1160         *(mcodeptr++) = (u1) 0xd9; \
1161         i386_emit_mem(3,(mem)); \
1162     } while (0)
1163
1164
1165 #define i386_fstpl_mem(mem) \
1166     do { \
1167         *(mcodeptr++) = (u1) 0xdd; \
1168         i386_emit_mem(3,(mem)); \
1169     } while (0)
1170
1171
1172 #define i386_fstps_membase(basereg,disp) \
1173     do { \
1174         *(mcodeptr++) = (u1) 0xd9; \
1175         i386_emit_membase((basereg),(disp),3); \
1176     } while (0)
1177
1178
1179 #define i386_fstpl_membase(basereg,disp) \
1180     do { \
1181         *(mcodeptr++) = (u1) 0xdd; \
1182         i386_emit_membase((basereg),(disp),3); \
1183     } while (0)
1184
1185
1186 #define i386_fstpt_membase(basereg,disp) \
1187     do { \
1188         *(mcodeptr++) = (u1) 0xdb; \
1189         i386_emit_membase((basereg),(disp),7); \
1190     } while (0)
1191
1192
1193 #define i386_fstps_memindex(disp,basereg,indexreg,scale) \
1194     do { \
1195         *(mcodeptr++) = (u1) 0xd9; \
1196         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale)); \
1197     } while (0)
1198
1199
1200 #define i386_fstpl_memindex(disp,basereg,indexreg,scale) \
1201     do { \
1202         *(mcodeptr++) = (u1) 0xdd; \
1203         i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale)); \
1204     } while (0)
1205
1206
1207
1208
1209 #define i386_fistpl_mem(mem) \
1210     do { \
1211         *(mcodeptr++) = (u1) 0xdb; \
1212         i386_emit_mem(3,(mem)); \
1213     } while (0)
1214
1215
1216 #define i386_fistpll_mem(mem) \
1217     do { \
1218         *(mcodeptr++) = (u1) 0xdf; \
1219         i386_emit_mem(7,(mem)); \
1220     } while (0)
1221
1222
1223 #define i386_fistl_membase(basereg,disp) \
1224     do { \
1225         *(mcodeptr++) = (u1) 0xdb; \
1226         i386_emit_membase((basereg),(disp),2); \
1227     } while (0)
1228
1229
1230 #define i386_fistpl_membase(basereg,disp) \
1231     do { \
1232         *(mcodeptr++) = (u1) 0xdb; \
1233         i386_emit_membase((basereg),(disp),3); \
1234     } while (0)
1235
1236
1237 #define i386_fistpll_membase(basereg,disp) \
1238     do { \
1239         *(mcodeptr++) = (u1) 0xdf; \
1240         i386_emit_membase((basereg),(disp),7); \
1241     } while (0)
1242
1243
1244
1245
1246 #define i386_fchs() \
1247     do { \
1248         *(mcodeptr++) = (u1) 0xd9; \
1249         *(mcodeptr++) = (u1) 0xe0; \
1250     } while (0)
1251
1252
1253 #define i386_faddp() \
1254     do { \
1255         *(mcodeptr++) = (u1) 0xde; \
1256         *(mcodeptr++) = (u1) 0xc1; \
1257     } while (0)
1258
1259
1260 #define i386_fadd_reg_st(reg) \
1261     do { \
1262         *(mcodeptr++) = (u1) 0xd8; \
1263         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1264     } while (0)
1265
1266
1267 #define i386_fadd_st_reg(reg) \
1268     do { \
1269         *(mcodeptr++) = (u1) 0xdc; \
1270         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1271     } while (0)
1272
1273
1274 #define i386_faddp_st_reg(reg) \
1275     do { \
1276         *(mcodeptr++) = (u1) 0xde; \
1277         *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg)); \
1278     } while (0)
1279
1280
1281 #define i386_fadds_membase(basereg,disp) \
1282     do { \
1283         *(mcodeptr++) = (u1) 0xd8; \
1284         i386_emit_membase((basereg),(disp),0); \
1285     } while (0)
1286
1287
1288 #define i386_faddl_membase(basereg,disp) \
1289     do { \
1290         *(mcodeptr++) = (u1) 0xdc; \
1291         i386_emit_membase((basereg),(disp),0); \
1292     } while (0)
1293
1294
1295 #define i386_fsub_reg_st(reg) \
1296     do { \
1297         *(mcodeptr++) = (u1) 0xd8; \
1298         *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg)); \
1299     } while (0)
1300
1301
1302 #define i386_fsub_st_reg(reg) \
1303     do { \
1304         *(mcodeptr++) = (u1) 0xdc; \
1305         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1306     } while (0)
1307
1308
1309 #define i386_fsubp_st_reg(reg) \
1310     do { \
1311         *(mcodeptr++) = (u1) 0xde; \
1312         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1313     } while (0)
1314
1315
1316 #define i386_fsubp() \
1317     do { \
1318         *(mcodeptr++) = (u1) 0xde; \
1319         *(mcodeptr++) = (u1) 0xe9; \
1320     } while (0)
1321
1322
1323 #define i386_fsubs_membase(basereg,disp) \
1324     do { \
1325         *(mcodeptr++) = (u1) 0xd8; \
1326         i386_emit_membase((basereg),(disp),4); \
1327     } while (0)
1328
1329
1330 #define i386_fsubl_membase(basereg,disp) \
1331     do { \
1332         *(mcodeptr++) = (u1) 0xdc; \
1333         i386_emit_membase((basereg),(disp),4); \
1334     } while (0)
1335
1336
1337 #define i386_fmul_reg_st(reg) \
1338     do { \
1339         *(mcodeptr++) = (u1) 0xd8; \
1340         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1341     } while (0)
1342
1343
1344 #define i386_fmul_st_reg(reg) \
1345     do { \
1346         *(mcodeptr++) = (u1) 0xdc; \
1347         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1348     } while (0)
1349
1350
1351 #define i386_fmulp() \
1352     do { \
1353         *(mcodeptr++) = (u1) 0xde; \
1354         *(mcodeptr++) = (u1) 0xc9; \
1355     } while (0)
1356
1357
1358 #define i386_fmulp_st_reg(reg) \
1359     do { \
1360         *(mcodeptr++) = (u1) 0xde; \
1361         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1362     } while (0)
1363
1364
1365 #define i386_fmuls_membase(basereg,disp) \
1366     do { \
1367         *(mcodeptr++) = (u1) 0xd8; \
1368         i386_emit_membase((basereg),(disp),1); \
1369     } while (0)
1370
1371
1372 #define i386_fmull_membase(basereg,disp) \
1373     do { \
1374         *(mcodeptr++) = (u1) 0xdc; \
1375         i386_emit_membase((basereg),(disp),1); \
1376     } while (0)
1377
1378
1379 #define i386_fdiv_reg_st(reg) \
1380     do { \
1381         *(mcodeptr++) = (u1) 0xd8; \
1382         *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg)); \
1383     } while (0)
1384
1385
1386 #define i386_fdiv_st_reg(reg) \
1387     do { \
1388         *(mcodeptr++) = (u1) 0xdc; \
1389         *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg)); \
1390     } while (0)
1391
1392
1393 #define i386_fdivp() \
1394     do { \
1395         *(mcodeptr++) = (u1) 0xde; \
1396         *(mcodeptr++) = (u1) 0xf9; \
1397     } while (0)
1398
1399
1400 #define i386_fdivp_st_reg(reg) \
1401     do { \
1402         *(mcodeptr++) = (u1) 0xde; \
1403         *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg)); \
1404     } while (0)
1405
1406
1407 #define i386_fxch() \
1408     do { \
1409         *(mcodeptr++) = (u1) 0xd9; \
1410         *(mcodeptr++) = (u1) 0xc9; \
1411     } while (0)
1412
1413
1414 #define i386_fxch_reg(reg) \
1415     do { \
1416         *(mcodeptr++) = (u1) 0xd9; \
1417         *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg)); \
1418     } while (0)
1419
1420
1421 #define i386_fprem() \
1422     do { \
1423         *(mcodeptr++) = (u1) 0xd9; \
1424         *(mcodeptr++) = (u1) 0xf8; \
1425     } while (0)
1426
1427
1428 #define i386_fprem1() \
1429     do { \
1430         *(mcodeptr++) = (u1) 0xd9; \
1431         *(mcodeptr++) = (u1) 0xf5; \
1432     } while (0)
1433
1434
1435 #define i386_fucom() \
1436     do { \
1437         *(mcodeptr++) = (u1) 0xdd; \
1438         *(mcodeptr++) = (u1) 0xe1; \
1439     } while (0)
1440
1441
1442 #define i386_fucom_reg(reg) \
1443     do { \
1444         *(mcodeptr++) = (u1) 0xdd; \
1445         *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg)); \
1446     } while (0)
1447
1448
1449 #define i386_fucomp_reg(reg) \
1450     do { \
1451         *(mcodeptr++) = (u1) 0xdd; \
1452         *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg)); \
1453     } while (0)
1454
1455
1456 #define i386_fucompp() \
1457     do { \
1458         *(mcodeptr++) = (u1) 0xda; \
1459         *(mcodeptr++) = (u1) 0xe9; \
1460     } while (0)
1461
1462
1463 #define i386_fnstsw() \
1464     do { \
1465         *(mcodeptr++) = (u1) 0xdf; \
1466         *(mcodeptr++) = (u1) 0xe0; \
1467     } while (0)
1468
1469
1470 #define i386_sahf() \
1471     *(mcodeptr++) = (u1) 0x9e;
1472
1473
1474 #define i386_finit() \
1475     do { \
1476         *(mcodeptr++) = (u1) 0x9b; \
1477         *(mcodeptr++) = (u1) 0xdb; \
1478         *(mcodeptr++) = (u1) 0xe3; \
1479     } while (0)
1480
1481
1482 #define i386_fldcw_mem(mem) \
1483     do { \
1484         *(mcodeptr++) = (u1) 0xd9; \
1485         i386_emit_mem(5,(mem)); \
1486     } while (0)
1487
1488
1489 #define i386_fldcw_membase(basereg,disp) \
1490     do { \
1491         *(mcodeptr++) = (u1) 0xd9; \
1492         i386_emit_membase((basereg),(disp),5); \
1493     } while (0)
1494
1495
1496 #define i386_wait() \
1497     *(mcodeptr++) = (u1) 0x9b;
1498
1499
1500 #define i386_ffree_reg(reg) \
1501     do { \
1502         *(mcodeptr++) = (u1) 0xdd; \
1503         *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg)); \
1504     } while (0)
1505
1506
1507 #define i386_fdecstp() \
1508     do { \
1509         *(mcodeptr++) = (u1) 0xd9; \
1510         *(mcodeptr++) = (u1) 0xf6; \
1511     } while (0)
1512
1513
1514 #define i386_fincstp() \
1515     do { \
1516         *(mcodeptr++) = (u1) 0xd9; \
1517         *(mcodeptr++) = (u1) 0xf7; \
1518     } while (0)
1519
1520 #else
1521
1522 /*
1523  * integer instructions
1524  */
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);
1550 void i386_cltd();
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);
1558 void i386_ret();
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);
1578 void i386_nop();
1579 void i386_call_reg(s4 reg);
1580 void i386_call_imm(s4 imm);
1581
1582
1583
1584 /*
1585  * floating point instructions
1586  */
1587 void i386_fld1();
1588 void i386_fldz();
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);
1611 void i386_fchs();
1612 void i386_faddp();
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);
1621 void i386_fsubp();
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);
1626 void i386_fmulp();
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);
1632 void i386_fdivp();
1633 void i386_fdivp_st_reg(s4 reg);
1634 void i386_fxch();
1635 void i386_fxch_reg(s4 reg);
1636 void i386_fprem();
1637 void i386_fprem1();
1638 void i386_fucom();
1639 void i386_fucom_reg(s4 reg);
1640 void i386_fucomp_reg(s4 reg);
1641 void i386_fucompp();
1642 void i386_fnstsw();
1643 void i386_sahf();
1644 void i386_finit();
1645 void i386_fldcw_mem(s4 mem);
1646 void i386_fldcw_membase(s4 basereg, s4 disp);
1647 void i386_wait();
1648 void i386_ffree_reg(s4 reg);
1649 void i386_fdecstp();
1650 void i386_fincstp();
1651
1652 #endif
1653
1654
1655
1656 /* function gen_resolvebranch **************************************************
1657
1658     backpatches a branch instruction
1659
1660     parameters: ip ... pointer to instruction after branch (void*)
1661                 so ... offset of instruction after branch  (s4)
1662                 to ... offset of branch target             (s4)
1663
1664 *******************************************************************************/
1665
1666 #define gen_resolvebranch(ip,so,to) \
1667     *((void **) ((ip) - 4)) = (void **) ((to) - (so));
1668
1669 #endif /* _CODEGEN_H */
1670
1671
1672 /*
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  * ---------------------------------------------------------------------
1677  * Local variables:
1678  * mode: c
1679  * indent-tabs-mode: t
1680  * c-basic-offset: 4
1681  * tab-width: 4
1682  * End:
1683  */