Tue Sep 18 13:23:59 CEST 2001 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / arch / x86 / x86-codegen.h
1 /* Copyright (C)  2000 Intel Corporation.  All rights reserved.
2    Copyright (C)  2001 Ximian, Inc. 
3 //
4 // $Header: /home/miguel/third-conversion/public/mono/mono/arch/x86/x86-codegen.h,v 1.9 2001/09/18 07:26:43 lupus Exp $
5 */
6
7 #ifndef X86_H
8 #define X86_H
9 #include <assert.h>
10 /*
11 // x86 register numbers
12 */
13 typedef enum {
14         X86_EAX = 0,
15         X86_ECX = 1,
16         X86_EDX = 2,
17         X86_EBX = 3,
18         X86_ESP = 4,
19         X86_EBP = 5,
20         X86_ESI = 6,
21         X86_EDI = 7,
22         X86_NREG
23 } X86_Reg_No;
24 /*
25 // opcodes for alu instructions
26 */
27 typedef enum {
28         X86_ADD = 0,
29         X86_OR  = 1,
30         X86_ADC = 2,
31         X86_SBB = 3,
32         X86_AND = 4,
33         X86_SUB = 5,
34         X86_XOR = 6,
35         X86_CMP = 7,
36         X86_NALU
37 } X86_ALU_Opcode;
38 /*
39 // opcodes for shift instructions
40 */
41 typedef enum {
42         X86_SHLD,
43         X86_SHLR,
44         X86_SHL = 4,
45         X86_SHR = 5,
46         X86_SAR = 7,
47         X86_NSHIFT = 8
48 } X86_Shift_Opcode;
49 /*
50 // opcodes for floating-point instructions
51 */
52 typedef enum {
53         X86_FADD  = 0,
54         X86_FMUL  = 1,
55         X86_FCOM  = 2,
56         X86_FCOMP = 3,
57         X86_FSUB  = 4,
58         X86_FSUBR = 5,
59         X86_FDIV  = 6,
60         X86_FDIVR = 7,
61         X86_NFP   = 8
62 } X86_FP_Opcode;
63 /*
64 // integer conditions codes
65 */
66 typedef enum {
67         X86_CC_EQ = 0,
68         X86_CC_NE,
69         X86_CC_LT,
70         X86_CC_LE,
71         X86_CC_GT,
72         X86_CC_GE,
73         X86_CC_LZ,
74         X86_CC_GEZ,
75         X86_CC_P,
76         X86_CC_NP,
77         X86_NCC
78 } X86_CC;
79 /*
80 // prefix code
81 */
82 typedef enum {
83         X86_LOCK_PREFIX = 0xF0,
84         X86_REPNZ_PREFIX = 0xF2,
85         X86_REPZ_PREFIX = 0xF3, 
86         X86_REP_PREFIX = 0xF3,
87         X86_CS_PREFIX = 0x2E,
88         X86_SS_PREFIX = 0x36,
89         X86_DS_PREFIX = 0x3E,
90         X86_ES_PREFIX = 0x26,
91         X86_FS_PREFIX = 0x64,
92         X86_GS_PREFIX = 0x65,
93         X86_OPERAND_PREFIX = 0x66,
94         X86_ADDRESS_PREFIX = 0x67
95 } X86_Prefix;
96
97 static const unsigned char 
98 x86_cc_unsigned_map [X86_NCC] = {
99         0x74, /* eq  */
100         0x75, /* ne  */
101         0x72, /* lt  */
102         0x76, /* le  */
103         0x77, /* gt  */
104         0x73, /* ge  */
105         0x78, /* lz  */
106         0x79, /* gez */
107         0x7a, /* p   */
108         0x7b, /* np  */
109 };
110
111 static const unsigned char 
112 x86_cc_signed_map [X86_NCC] = {
113         0x74, /* eq  */
114         0x75, /* ne  */
115         0x7c, /* lt  */
116         0x7e, /* le  */
117         0x7f, /* gt  */
118         0x7d, /* ge  */
119         0x78, /* lz  */
120         0x79, /* gez */
121         0x7a, /* p   */
122         0x7b, /* np  */
123 };
124
125 typedef union {
126         int val;
127         unsigned char b [4];
128 } x86_imm_buf;
129
130 /*
131 // bitvector mask for callee-saved registers
132 */
133 #define X86_ESI_MASK (1<<X86_ESI)
134 #define X86_EDI_MASK (1<<X86_EDI)
135 #define X86_EBX_MASK (1<<X86_EBX)
136 #define X86_EBP_MASK (1<<X86_EBP)
137
138 #define X86_CALLEE_REGS ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX))
139 #define X86_CALLER_REGS ((1<<X86_EBX) | (1<<X86_EBP) | (1<<X86_ESI) | (1<<X86_EDI))
140 #define X86_BYTE_REGS   ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX) | (1<<X86_EBX))
141
142 #define X86_IS_SCRATCH(reg) (X86_CALLER_REGS & (1 << (reg))) /* X86_EAX, X86_ECX, or X86_EDX */
143 #define X86_IS_CALLEE(reg)  (X86_CALLEE_REGS & (1 << (reg)))    /* X86_ESI, X86_EDI, X86_EBX, or X86_EBP */
144
145 /*
146 // Frame structure:
147 //
148 //      +--------------------------------+
149 //      | in_arg[0]       = var[0]           |
150 //      | in_arg[1]           = var[1]       |
151 //      |             . . .                              |
152 //      | in_arg[n_arg-1] = var[n_arg-1] |
153 //      +--------------------------------+
154 //      |       return IP                |
155 //      +--------------------------------+
156 //      |       saved EBP                | <-- frame pointer (EBP)
157 //      +--------------------------------+
158 //      |            ...                 |  n_extra
159 //      +--------------------------------+
160 //      |           var[n_arg]               |
161 //      |           var[n_arg+1]             |  local variables area
162 //      |          . . .                 |
163 //      |           var[n_var-1]             | 
164 //      +--------------------------------+
165 //      |                                            |
166 //      |                                            |  
167 //      |               spill area               | area for spilling mimic stack
168 //      |                                            |
169 //      +--------------------------------|
170 //      |          ebx                   |
171 //      |          ebp [ESP_Frame only]  |
172 //      |              esi                   |  0..3 callee-saved regs
173 //      |          edi                   | <-- stack pointer (ESP)
174 //      +--------------------------------+
175 //      |       stk0                         |
176 //      |       stk1                         |  operand stack area/
177 //      |       . . .                        |  out args
178 //      |       stkn-1                       |
179 //      +--------------------------------|
180 //
181 //
182 */
183
184
185 /*
186  * useful building blocks
187  */
188 #define x86_address_byte(inst,m,o,r) do { *(inst)++ = ((((m)&0x03)<<6)|(((o)&0x07)<<3)|(((r)&0x07))); } while (0)
189 #define x86_imm_emit32(inst,imm)     \
190         do {    \
191                         x86_imm_buf imb; imb.val = (int) (imm); \
192                         *(inst)++ = imb.b [0];  \
193                         *(inst)++ = imb.b [1];  \
194                         *(inst)++ = imb.b [2];  \
195                         *(inst)++ = imb.b [3];  \
196         } while (0)
197 #define x86_imm_emit16(inst,imm)     do { *(short*)(inst) = (imm); (inst) += 2; } while (0)
198 #define x86_imm_emit8(inst,imm)      do { *(inst) = (unsigned char)((imm) & 0xff); ++(inst); } while (0)
199 #define x86_is_imm8(imm)             (((int)(imm) >= -128 && (int)(imm) <= 127))
200 #define x86_is_imm16(imm)            (((int)(imm) >= -(1<<16) && (int)(imm) <= ((1<<16)-1)))
201
202 #define x86_reg_emit(inst,r,regno)   do { x86_address_byte ((inst), 3, (r), (regno)); } while (0)
203 #define x86_regp_emit(inst,r,regno)  do { x86_address_byte ((inst), 0, (r), (regno)); } while (0)
204 #define x86_mem_emit(inst,r,disp)    do { x86_address_byte ((inst), 0, (r), 5); x86_imm_emit32((inst), (disp)); } while (0)
205
206 #define x86_membase_emit(inst,r,basereg,disp)   do {\
207         if ((basereg) == X86_ESP) {     \
208                 if ((disp) == 0) {      \
209                         x86_address_byte ((inst), 0, (r), X86_ESP);     \
210                         x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
211                 } else if (x86_is_imm8((disp))) {       \
212                         x86_address_byte ((inst), 1, (r), X86_ESP);     \
213                         x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
214                         x86_imm_emit8 ((inst), (disp)); \
215                 } else {        \
216                         x86_address_byte ((inst), 2, (r), X86_ESP);     \
217                         x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
218                         x86_imm_emit32 ((inst), (disp));        \
219                 }       \
220                 break;  \
221         }       \
222         if ((disp) == 0 && (basereg) != X86_EBP) {      \
223                 x86_address_byte ((inst), 0, (r), (basereg));   \
224                 break;  \
225         }       \
226         if (x86_is_imm8((disp))) {      \
227                 x86_address_byte ((inst), 1, (r), (basereg));   \
228                 x86_imm_emit8 ((inst), (disp)); \
229         } else {        \
230                 x86_address_byte ((inst), 2, (r), (basereg));   \
231                 x86_imm_emit32 ((inst), (disp));        \
232         }       \
233         } while (0)
234
235 /* 
236  * TODO: memindex_emit 
237  */
238
239 #define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while (0)
240
241 #define x86_rdtsc(inst) \
242         do {    \
243                 *(inst)++ = 0x0f;       \
244                 *(inst)++ = 0x31;       \
245         } while (0)
246
247 #define x86_cmpxchg_reg_reg(inst,dreg,reg)      \
248         do {    \
249                 *(inst)++ = (unsigned char)0x0f;        \
250                 *(inst)++ = (unsigned char)0xb1;        \
251                 x86_reg_emit ((inst), (reg), (dreg));   \
252         } while (0)
253         
254 #define x86_cmpxchg_mem_reg(inst,mem,reg)       \
255         do {    \
256                 *(inst)++ = (unsigned char)0x0f;        \
257                 *(inst)++ = (unsigned char)0xb1;        \
258                 x86_mem_emit ((inst), (reg), (mem));    \
259         } while (0)
260         
261 #define x86_cmpxchg_membase_reg(inst,basereg,disp,reg)  \
262         do {    \
263                 *(inst)++ = (unsigned char)0x0f;        \
264                 *(inst)++ = (unsigned char)0xb1;        \
265                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
266         } while (0)
267
268 #define x86_xchg_reg_reg(inst,dreg,reg,size)    \
269         do {    \
270                 if ((size) == 1)        \
271                         *(inst)++ = (unsigned char)0x86;        \
272                 else    \
273                         *(inst)++ = (unsigned char)0x87;        \
274                 x86_reg_emit ((inst), (reg), (dreg));   \
275         } while (0)
276
277 #define x86_xchg_mem_reg(inst,mem,reg,size)     \
278         do {    \
279                 if ((size) == 1)        \
280                         *(inst)++ = (unsigned char)0x86;        \
281                 else    \
282                         *(inst)++ = (unsigned char)0x87;        \
283                 x86_mem_emit ((inst), (reg), (mem));    \
284         } while (0)
285
286 #define x86_xchg_membase_reg(inst,basereg,disp,reg,size)        \
287         do {    \
288                 if ((size) == 1)        \
289                         *(inst)++ = (unsigned char)0x86;        \
290                 else    \
291                         *(inst)++ = (unsigned char)0x87;        \
292                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
293         } while (0)
294
295 #define x86_inc_mem(inst,mem)   \
296         do {    \
297                 *(inst)++ = (unsigned char)0xff;        \
298                 x86_mem_emit ((inst), 0, (mem));        \
299         } while (0)
300
301 #define x86_inc_membase(inst,basereg,disp)      \
302         do {    \
303                 *(inst)++ = (unsigned char)0xff;        \
304                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
305         } while (0)
306
307 #define x86_inc_reg(inst,reg) do { *(inst)++ = (unsigned char)0x40 + (reg); } while (0)
308
309 #define x86_dec_mem(inst,mem)   \
310         do {    \
311                 *(inst)++ = (unsigned char)0xff;        \
312                 x86_mem_emit ((inst), 1, (mem));        \
313         } while (0)
314
315 #define x86_dec_membase(inst,basereg,disp)      \
316         do {    \
317                 *(inst)++ = (unsigned char)0xff;        \
318                 x86_membase_emit ((inst), 1, (basereg), (disp));        \
319         } while (0)
320
321 #define x86_dec_reg(inst,reg) do { *(inst)++ = (unsigned char)0x48 + (reg); } while (0)
322
323 #define x86_not_mem(inst,mem)   \
324         do {    \
325                 *(inst)++ = (unsigned char)0xf7;        \
326                 x86_mem_emit ((inst), 2, (mem));        \
327         } while (0)
328
329 #define x86_not_membase(inst,basereg,disp)      \
330         do {    \
331                 *(inst)++ = (unsigned char)0xf7;        \
332                 x86_membase_emit ((inst), 2, (basereg), (disp));        \
333         } while (0)
334
335 #define x86_not_reg(inst,reg)   \
336         do {    \
337                 *(inst)++ = (unsigned char)0xf7;        \
338                 x86_reg_emit ((inst), 2, (reg));        \
339         } while (0)
340
341 #define x86_neg_mem(inst,mem)   \
342         do {    \
343                 *(inst)++ = (unsigned char)0xf7;        \
344                 x86_mem_emit ((inst), 3, (mem));        \
345         } while (0)
346
347 #define x86_neg_membase(inst,basereg,disp)      \
348         do {    \
349                 *(inst)++ = (unsigned char)0xf7;        \
350                 x86_membase_emit ((inst), 3, (basereg), (disp));        \
351         } while (0)
352
353 #define x86_neg_reg(inst,reg)   \
354         do {    \
355                 *(inst)++ = (unsigned char)0xf7;        \
356                 x86_reg_emit ((inst), 3, (reg));        \
357         } while (0)
358
359 #define x86_nop(inst) do { *(inst)++ = (unsigned char)0x90; } while (0)
360
361 #define x86_alu_reg_imm(inst,opc,reg,imm)       \
362         do {    \
363                 if ((reg) == X86_EAX) { \
364                         *(inst)++ = (((unsigned char)(opc)) << 3) + 5;  \
365                         x86_imm_emit32 ((inst), (imm)); \
366                         break;  \
367                 }       \
368                 if (x86_is_imm8((imm))) {       \
369                         *(inst)++ = (unsigned char)0x83;        \
370                         x86_reg_emit ((inst), (opc), (reg));    \
371                         x86_imm_emit8 ((inst), (imm));  \
372                 } else {        \
373                         *(inst)++ = (unsigned char)0x81;        \
374                         x86_reg_emit ((inst), (opc), (reg));    \
375                         x86_imm_emit32 ((inst), (imm)); \
376                 }       \
377         } while (0)
378
379 #define x86_alu_mem_imm(inst,opc,mem,imm)       \
380         do {    \
381                 if (x86_is_imm8((imm))) {       \
382                         *(inst)++ = (unsigned char)0x83;        \
383                         x86_mem_emit ((inst), (opc), (mem));    \
384                         x86_imm_emit8 ((inst), (imm));  \
385                 } else {        \
386                         *(inst)++ = (unsigned char)0x81;        \
387                         x86_mem_emit ((inst), (opc), (mem));    \
388                         x86_imm_emit32 ((inst), (imm)); \
389                 }       \
390         } while (0)
391
392 #define x86_alu_membase_imm(inst,opc,basereg,disp,imm)  \
393         do {    \
394                 if (x86_is_imm8((imm))) {       \
395                         *(inst)++ = (unsigned char)0x83;        \
396                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
397                         x86_imm_emit8 ((inst), (imm));  \
398                 } else {        \
399                         *(inst)++ = (unsigned char)0x81;        \
400                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
401                         x86_imm_emit32 ((inst), (imm)); \
402                 }       \
403         } while (0)
404
405 #define x86_alu_mem_reg(inst,opc,mem,reg)       \
406         do {    \
407                 *(inst)++ = (((unsigned char)(opc)) << 3) + 1;  \
408                 x86_mem_emit ((inst), (reg), (mem));    \
409         } while (0)
410
411 #define x86_alu_membase_reg(inst,opc,basereg,disp,reg)  \
412         do {    \
413                 *(inst)++ = (((unsigned char)(opc)) << 3) + 1;  \
414                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
415         } while (0)
416
417 #define x86_alu_reg_reg(inst,opc,dreg,reg)      \
418         do {    \
419                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
420                 x86_reg_emit ((inst), (dreg), (reg));   \
421         } while (0)
422
423 #define x86_alu_reg_mem(inst,opc,reg,mem)       \
424         do {    \
425                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
426                 x86_mem_emit ((inst), (reg), (mem));    \
427         } while (0)
428
429 #define x86_alu_reg_membase(inst,opc,reg,basereg,disp)  \
430         do {    \
431                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
432                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
433         } while (0)
434
435 #define x86_test_reg_imm(inst,reg,imm)  \
436         do {    \
437                 if ((reg) == X86_EAX) { \
438                         *(inst)++ = (unsigned char)0xa9;        \
439                 } else {        \
440                         *(inst)++ = (unsigned char)0xf7;        \
441                         x86_reg_emit ((inst), 0, (reg));        \
442                 }       \
443                 x86_imm_emit32 ((inst), (imm)); \
444         } while (0)
445
446 #define x86_test_mem_imm(inst,mem,imm)  \
447         do {    \
448                 *(inst)++ = (unsigned char)0xf7;        \
449                 x86_mem_emit ((inst), 0, (mem));        \
450                 x86_imm_emit32 ((inst), (imm)); \
451         } while (0)
452
453 #define x86_test_membase_imm(inst,basereg,disp,imm)     \
454         do {    \
455                 *(inst)++ = (unsigned char)0xf7;        \
456                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
457                 x86_imm_emit32 ((inst), (imm)); \
458         } while (0)
459
460 #define x86_test_reg_reg(inst,dreg,reg) \
461         do {    \
462                 *(inst)++ = (unsigned char)0x85;        \
463                 x86_reg_emit ((inst), (reg), (dreg));   \
464         } while (0)
465
466 #define x86_test_mem_reg(inst,mem,reg)  \
467         do {    \
468                 *(inst)++ = (unsigned char)0x85;        \
469                 x86_mem_emit ((inst), (reg), (mem));    \
470         } while (0)
471
472 #define x86_test_membase_reg(inst,basereg,disp,reg)     \
473         do {    \
474                 *(inst)++ = (unsigned char)0x85;        \
475                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
476         } while (0)
477
478 #define x86_shift_reg_imm(inst,opc,reg,imm)     \
479         do {    \
480                 if ((imm) == 1) {       \
481                         *(inst)++ = (unsigned char)0xd1;        \
482                         x86_reg_emit ((inst), (opc), (reg));    \
483                 } else {        \
484                         *(inst)++ = (unsigned char)0xc1;        \
485                         x86_reg_emit ((inst), (opc), (reg));    \
486                         x86_imm_emit8 ((inst), (imm));  \
487                 }       \
488         } while (0)
489
490 #define x86_shift_mem_imm(inst,opc,mem,imm)     \
491         do {    \
492                 if ((imm) == 1) {       \
493                         *(inst)++ = (unsigned char)0xd1;        \
494                         x86_mem_emit ((inst), (opc), (mem));    \
495                 } else {        \
496                         *(inst)++ = (unsigned char)0xc1;        \
497                         x86_mem_emit ((inst), (opc), (mem));    \
498                         x86_imm_emit8 ((inst), (imm));  \
499                 }       \
500         } while (0)
501
502 #define x86_shift_membase_imm(inst,opc,basereg,disp,imm)        \
503         do {    \
504                 if ((imm) == 1) {       \
505                         *(inst)++ = (unsigned char)0xd1;        \
506                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
507                 } else {        \
508                         *(inst)++ = (unsigned char)0xc1;        \
509                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
510                         x86_imm_emit8 ((inst), (imm));  \
511                 }       \
512         } while (0)
513
514 #define x86_shift_reg(inst,opc,reg)     \
515         do {    \
516                 *(inst)++ = (unsigned char)0xd3;        \
517                 x86_reg_emit ((inst), (opc), (reg));    \
518         } while (0)
519
520 #define x86_shift_mem(inst,opc,mem)     \
521         do {    \
522                 *(inst)++ = (unsigned char)0xd3;        \
523                 x86_mem_emit ((inst), (opc), (mem));    \
524         } while (0)
525
526 #define x86_shift_membase(inst,opc,basereg,disp)        \
527         do {    \
528                 *(inst)++ = (unsigned char)0xd3;        \
529                 x86_membase_emit ((inst), (opc), (basereg), (disp));    \
530         } while (0)
531
532 /*
533  * Multi op shift missing.
534  */
535
536 /*
537  * EDX:EAX = EAX * rm
538  */
539 #define x86_mul_reg(inst,reg,is_signed) \
540         do {    \
541                 *(inst)++ = (unsigned char)0xf7;        \
542                 x86_reg_emit ((inst), 4 + ((is_signed) ? 1 : 0), (reg));        \
543         } while (0)
544
545 #define x86_mul_mem(inst,mem,is_signed) \
546         do {    \
547                 *(inst)++ = (unsigned char)0xf7;        \
548                 x86_mem_emit ((inst), 4 + ((is_signed) ? 1 : 0), (mem));        \
549         } while (0)
550
551 #define x86_mul_membase(inst,basereg,disp,is_signed)    \
552         do {    \
553                 *(inst)++ = (unsigned char)0xf7;        \
554                 x86_membase_emit ((inst), 4 + ((is_signed) ? 1 : 0), (basereg), (disp));        \
555         } while (0)
556
557 /*
558  * r *= rm
559  */
560 #define x86_imul_reg_reg(inst,dreg,reg) \
561         do {    \
562                 *(inst)++ = (unsigned char)0x0f;        \
563                 *(inst)++ = (unsigned char)0xaf;        \
564                 x86_reg_emit ((inst), (dreg), (reg));   \
565         } while (0)
566
567 #define x86_imul_reg_mem(inst,reg,mem)  \
568         do {    \
569                 *(inst)++ = (unsigned char)0x0f;        \
570                 *(inst)++ = (unsigned char)0xaf;        \
571                 x86_mem_emit ((inst), (reg), (mem));    \
572         } while (0)
573
574 #define x86_imul_reg_membase(inst,reg,basereg,disp)     \
575         do {    \
576                 *(inst)++ = (unsigned char)0x0f;        \
577                 *(inst)++ = (unsigned char)0xaf;        \
578                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
579         } while (0)
580
581 /*
582  * dreg = rm * imm
583  */
584 #define x86_imul_reg_reg_imm(inst,dreg,reg,imm) \
585         do {    \
586                 if (x86_is_imm8 ((imm))) {      \
587                         *(inst)++ = (unsigned char)0x6b;        \
588                         x86_reg_emit ((inst), (dreg), (reg));   \
589                         x86_imm_emit8 ((inst), (imm));  \
590                 } else {        \
591                         *(inst)++ = (unsigned char)0x69;        \
592                         x86_reg_emit ((inst), (dreg), (reg));   \
593                         x86_imm_emit32 ((inst), (imm)); \
594                 }       \
595         } while (0)
596
597 #define x86_imul_reg_mem_imm(inst,reg,mem,imm)  \
598         do {    \
599                 if (x86_is_imm8 ((imm))) {      \
600                         *(inst)++ = (unsigned char)0x6b;        \
601                         x86_mem_emit ((inst), (reg), (mem));    \
602                         x86_imm_emit8 ((inst), (imm));  \
603                 } else {        \
604                         *(inst)++ = (unsigned char)0x69;        \
605                         x86_reg_emit ((inst), (reg), (mem));    \
606                         x86_imm_emit32 ((inst), (imm)); \
607                 }       \
608         } while (0)
609
610 #define x86_imul_reg_membase_imm(inst,reg,basereg,disp,imm)     \
611         do {    \
612                 if (x86_is_imm8 ((imm))) {      \
613                         *(inst)++ = (unsigned char)0x6b;        \
614                         x86_membase_emit ((inst), (reg), (basereg), (disp));    \
615                         x86_imm_emit8 ((inst), (imm));  \
616                 } else {        \
617                         *(inst)++ = (unsigned char)0x69;        \
618                         x86_membase_emit ((inst), (reg), (basereg), (disp));    \
619                         x86_imm_emit32 ((inst), (imm)); \
620                 }       \
621         } while (0)
622
623 /*
624  * divide EDX:EAX by rm;
625  * eax = quotient, edx = remainder
626  */
627
628 #define x86_div_reg(inst,reg,is_signed) \
629         do {    \
630                 *(inst)++ = (unsigned char)0xf7;        \
631                 x86_reg_emit ((inst), 6 + ((is_signed) ? 1 : 0), (reg));        \
632         } while (0)
633
634 #define x86_div_mem(inst,mem,is_signed) \
635         do {    \
636                 *(inst)++ = (unsigned char)0xf7;        \
637                 x86_mem_emit ((inst), 6 + ((is_signed) ? 1 : 0), (mem));        \
638         } while (0)
639
640 #define x86_div_membase(inst,basereg,disp,is_signed)    \
641         do {    \
642                 *(inst)++ = (unsigned char)0xf7;        \
643                 x86_membase_emit ((inst), 6 + ((is_signed) ? 1 : 0), (basereg), (disp));        \
644         } while (0)
645
646 #define x86_mov_mem_reg(inst,mem,reg,size)      \
647         do {    \
648                 switch ((size)) {       \
649                 case 1: *(inst)++ = (unsigned char)0x88; break; \
650                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
651                 case 4: *(inst)++ = (unsigned char)0x89; break; \
652                 default: assert (0);    \
653                 }       \
654                 x86_mem_emit ((inst), (reg), (mem));    \
655         } while (0)
656
657 #define x86_mov_regp_reg(inst,regp,reg,size)    \
658         do {    \
659                 switch ((size)) {       \
660                 case 1: *(inst)++ = (unsigned char)0x88; break; \
661                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
662                 case 4: *(inst)++ = (unsigned char)0x89; break; \
663                 default: assert (0);    \
664                 }       \
665                 x86_regp_emit ((inst), (reg), (regp));  \
666         } while (0)
667
668 #define x86_mov_membase_reg(inst,basereg,disp,reg,size) \
669         do {    \
670                 switch ((size)) {       \
671                 case 1: *(inst)++ = (unsigned char)0x88; break; \
672                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
673                 case 4: *(inst)++ = (unsigned char)0x89; break; \
674                 default: assert (0);    \
675                 }       \
676                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
677         } while (0)
678
679 #define x86_mov_reg_reg(inst,dreg,reg,size)     \
680         do {    \
681                 switch ((size)) {       \
682                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
683                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
684                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
685                 default: assert (0);    \
686                 }       \
687                 x86_reg_emit ((inst), (dreg), (reg));   \
688         } while (0)
689
690 #define x86_mov_reg_mem(inst,reg,mem,size)      \
691         do {    \
692                 switch ((size)) {       \
693                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
694                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
695                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
696                 default: assert (0);    \
697                 }       \
698                 x86_mem_emit ((inst), (reg), (mem));    \
699         } while (0)
700
701 #define x86_mov_reg_membase(inst,reg,basereg,disp,size) \
702         do {    \
703                 switch ((size)) {       \
704                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
705                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
706                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
707                 default: assert (0);    \
708                 }       \
709                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
710         } while (0)
711
712 #define x86_mov_reg_imm(inst,reg,imm)   \
713         do {    \
714                 if ((imm) == 0) {       \
715                         x86_alu_reg_reg ((inst), X86_XOR, (reg), (reg));        \
716                 } else {        \
717                         *(inst)++ = (unsigned char)0xb8 + (reg);        \
718                         x86_imm_emit32 ((inst), (imm)); \
719                 }       \
720         } while (0)
721
722 #define x86_mov_mem_imm(inst,mem,imm,size)      \
723         do {    \
724                 if ((size) == 1) {      \
725                         *(inst)++ = (unsigned char)0xc6;        \
726                         x86_mem_emit ((inst), 0, (mem));        \
727                         x86_imm_emit8 ((inst), (imm));  \
728                 } else if ((size) == 2) {       \
729                         *(inst)++ = (unsigned char)0x66;        \
730                         *(inst)++ = (unsigned char)0xc7;        \
731                         x86_mem_emit ((inst), 0, (mem));        \
732                         x86_imm_emit16 ((inst), (imm)); \
733                 } else {        \
734                         *(inst)++ = (unsigned char)0xc7;        \
735                         x86_mem_emit ((inst), 0, (mem));        \
736                         x86_imm_emit32 ((inst), (imm)); \
737                 }       \
738         } while (0)
739
740 #define x86_mov_membase_imm(inst,basereg,disp,imm,size) \
741         do {    \
742                 if ((size) == 1) {      \
743                         *(inst)++ = (unsigned char)0xc6;        \
744                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
745                         x86_imm_emit8 ((inst), (imm));  \
746                 } else if ((size) == 2) {       \
747                         *(inst)++ = (unsigned char)0x66;        \
748                         *(inst)++ = (unsigned char)0xc7;        \
749                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
750                         x86_imm_emit16 ((inst), (imm)); \
751                 } else {        \
752                         *(inst)++ = (unsigned char)0xc7;        \
753                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
754                         x86_imm_emit32 ((inst), (imm)); \
755                 }       \
756         } while (0)
757
758 #define x86_lea_mem(inst,reg,mem)       \
759         do {    \
760                 *(inst)++ = (unsigned char)0x8d;        \
761                 x86_mem_emit ((inst), (reg), (mem));    \
762         } while (0)
763
764 #define x86_lea_membase(inst,reg,basereg,disp)  \
765         do {    \
766                 *(inst)++ = (unsigned char)0x8d;        \
767                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
768         } while (0)
769
770 #define x86_widen_reg(inst,dreg,reg,is_signed,is_half)  \
771         do {    \
772                 unsigned char op = 0xb6;        \
773                 *(inst)++ = (unsigned char)0x0f;        \
774                 if ((is_signed)) op += 0x08;    \
775                 if ((is_half)) op += 0x01;      \
776                 *(inst)++ = op; \
777                 x86_reg_emit ((inst), (dreg), (reg));   \
778         } while (0)
779
780 #define x86_widen_mem(inst,dreg,mem,is_signed,is_half)  \
781         do {    \
782                 unsigned char op = 0xb6;        \
783                 *(inst)++ = (unsigned char)0x0f;        \
784                 if ((is_signed)) op += 0x08;    \
785                 if ((is_half)) op += 0x01;      \
786                 *(inst)++ = op; \
787                 x86_mem_emit ((inst), (dreg), (mem));   \
788         } while (0)
789
790 #define x86_widen_membase(inst,dreg,basereg,disp,is_signed,is_half)     \
791         do {    \
792                 unsigned char op = 0xb6;        \
793                 *(inst)++ = (unsigned char)0x0f;        \
794                 if ((is_signed)) op += 0x08;    \
795                 if ((is_half)) op += 0x01;      \
796                 *(inst)++ = op; \
797                 x86_membase_emit ((inst), (dreg), (basereg), (disp));   \
798         } while (0)
799
800 #define x86_cdq(inst)  do { *(inst)++ = (unsigned char)0x99; } while (0)
801 #define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
802
803 #define x86_fp_op_mem(inst,opc,mem,is_double)   \
804         do {    \
805                 *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8;    \
806                 x86_mem_emit ((inst), (opc), (mem));    \
807         } while (0)
808
809 #define x86_fp_op(inst,opc,index)       \
810         do {    \
811                 *(inst)++ = (unsigned char)0xd8;        \
812                 *(inst)++ = (unsigned char)0xc0+((opc)<<3)+((index)&0x07);      \
813         } while (0)
814
815 #define x86_fp_op_reg(inst,opc,index,pop_stack) \
816         do {    \
817                 static const unsigned char map[] = { 0, 1, 2, 3, 5, 4, 7, 6, 8};        \
818                 *(inst)++ = (pop_stack) ? (unsigned char)0xde : (unsigned char)0xdc;    \
819                 *(inst)++ = (unsigned char)0xc0+(map[(opc)]<<3)+((index)&0x07); \
820         } while (0)
821
822 #define x86_fstp(inst,index)    \
823         do {    \
824                 *(inst)++ = (unsigned char)0xdd;        \
825                 *(inst)++ = (unsigned char)0xd8+(index);        \
826         } while (0)
827
828 #define x86_fcompp(inst)        \
829         do {    \
830                 *(inst)++ = (unsigned char)0xde;        \
831                 *(inst)++ = (unsigned char)0xd9;        \
832         } while (0)
833
834 #define x86_fnstsw(inst)        \
835         do {    \
836                 *(inst)++ = (unsigned char)0xdf;        \
837                 *(inst)++ = (unsigned char)0xe0;        \
838         } while (0)
839
840 #define x86_fnstcw(inst,mem)    \
841         do {    \
842                 *(inst)++ = (unsigned char)0xd9;        \
843                 x86_mem_emit ((inst), 7, (mem));        \
844         } while (0)
845
846 #define x86_fnstcw_membase(inst,basereg,disp)   \
847         do {    \
848                 *(inst)++ = (unsigned char)0xd9;        \
849                 x86_membase_emit ((inst), 7, (basereg), (disp));        \
850         } while (0)
851
852 #define x86_fldcw(inst,mem)     \
853         do {    \
854                 *(inst)++ = (unsigned char)0xd9;        \
855                 x86_mem_emit ((inst), 5, (mem));        \
856         } while (0)
857
858 #define x86_fldcw_membase(inst,basereg,disp)    \
859         do {    \
860                 *(inst)++ = (unsigned char)0xd9;        \
861                 x86_membase_emit ((inst), 5, (basereg), (disp));        \
862         } while (0)
863
864 #define x86_fchs(inst)  \
865         do {    \
866                 *(inst)++ = (unsigned char)0xd9;        \
867                 *(inst)++ = (unsigned char)0xe0;        \
868         } while (0)
869
870 #define x86_frem(inst)  \
871         do {    \
872                 *(inst)++ = (unsigned char)0xd9;        \
873                 *(inst)++ = (unsigned char)0xf8;        \
874         } while (0)
875
876 #define x86_fxch(inst,index)    \
877         do {    \
878                 *(inst)++ = (unsigned char)0xd9;        \
879                 *(inst)++ = (unsigned char)0xc8 + ((index) & 0x07);     \
880         } while (0)
881
882 #define x86_fcomip(inst,index)  \
883         do {    \
884                 *(inst)++ = (unsigned char)0xdf;        \
885                 *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07);     \
886         } while (0)
887
888 #define x86_fld(inst,mem,is_double)     \
889         do {    \
890                 *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9;    \
891                 x86_mem_emit ((inst), 0, (mem));        \
892         } while (0)
893
894 #define x86_fld_membase(inst,basereg,disp,is_double)    \
895         do {    \
896                 *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9;    \
897                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
898         } while (0)
899
900 #define x86_fld80(inst,mem)     \
901         do {    \
902                 *(inst)++ = (unsigned char)0xdb;        \
903                 x86_mem_emit ((inst), 5, (mem));        \
904         } while (0)
905
906 #define x86_fld80_membase(inst,basereg,disp)    \
907         do {    \
908                 *(inst)++ = (unsigned char)0xdb;        \
909                 x86_membase_emit ((inst), 5, (basereg), (disp));        \
910         } while (0)
911
912 #define x86_fild(inst,mem,is_long)      \
913         do {    \
914                 if ((is_long)) {        \
915                         *(inst)++ = (unsigned char)0xdf;        \
916                         x86_mem_emit ((inst), 5, (mem));        \
917                 } else {        \
918                         *(inst)++ = (unsigned char)0xdb;        \
919                         x86_mem_emit ((inst), 0, (mem));        \
920                 }       \
921         } while (0)
922
923 #define x86_fild_membase(inst,basereg,disp,is_long)     \
924         do {    \
925                 if ((is_long)) {        \
926                         *(inst)++ = (unsigned char)0xdf;        \
927                         x86_membase_emit ((inst), 5, (basereg), (disp));        \
928                 } else {        \
929                         *(inst)++ = (unsigned char)0xdb;        \
930                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
931                 }       \
932         } while (0)
933
934 #define x86_fld_reg(inst,index) \
935         do {    \
936                 *(inst)++ = (unsigned char)0xd9;        \
937                 *(inst)++ = (unsigned char)0xc0 + ((index) & 0x07);     \
938         } while (0)
939
940 #define x86_fldz(inst)  \
941         do {    \
942                 *(inst)++ = (unsigned char)0xd9;        \
943                 *(inst)++ = (unsigned char)0xee;        \
944         } while (0)
945
946 #define x86_fld1(inst)  \
947         do {    \
948                 *(inst)++ = (unsigned char)0xd9;        \
949                 *(inst)++ = (unsigned char)0xe8;        \
950         } while (0)
951
952 #define x86_fst(inst,mem,is_double,pop_stack)   \
953         do {    \
954                 *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9;     \
955                 x86_mem_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (mem));        \
956         } while (0)
957
958 #define x86_fst_membase(inst,basereg,disp,is_double,pop_stack)  \
959         do {    \
960                 *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9;     \
961                 x86_membase_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (basereg), (disp));        \
962         } while (0)
963
964 #define x86_fist_pop(inst,mem,is_long)  \
965         do {    \
966                 if ((is_long)) {        \
967                         *(inst)++ = (unsigned char)0xdf;        \
968                         x86_mem_emit ((inst), 7, (mem));        \
969                 } else {        \
970                         *(inst)++ = (unsigned char)0xdb;        \
971                         x86_mem_emit ((inst), 3, (mem));        \
972                 }       \
973         } while (0)
974
975 #define x86_fist_pop_membase(inst,basereg,disp,is_long) \
976         do {    \
977                 if ((is_long)) {        \
978                         *(inst)++ = (unsigned char)0xdf;        \
979                         x86_membase_emit ((inst), 7, (basereg), (disp));        \
980                 } else {        \
981                         *(inst)++ = (unsigned char)0xdb;        \
982                         x86_membase_emit ((inst), 3, (basereg), (disp));        \
983                 }       \
984         } while (0)
985
986 #define x86_push_reg(inst,reg)  \
987         do {    \
988                 *(inst)++ = (unsigned char)0x50 + (reg);        \
989         } while (0)
990
991 #define x86_push_regp(inst,reg) \
992         do {    \
993                 *(inst)++ = (unsigned char)0xff;        \
994                 x86_regp_emit ((inst), 6, (reg));       \
995         } while (0)
996
997 #define x86_push_mem(inst,mem)  \
998         do {    \
999                 *(inst)++ = (unsigned char)0xff;        \
1000                 x86_mem_emit ((inst), 6, (mem));        \
1001         } while (0)
1002
1003 #define x86_push_membase(inst,basereg,disp)     \
1004         do {    \
1005                 *(inst)++ = (unsigned char)0xff;        \
1006                 x86_membase_emit ((inst), 6, (basereg), (disp));        \
1007         } while (0)
1008
1009 #define x86_push_imm(inst,imm)  \
1010         do {    \
1011                 *(inst)++ = (unsigned char)0x68;        \
1012                 x86_imm_emit32 ((inst), (imm)); \
1013         } while (0)
1014
1015 #define x86_pop_reg(inst,reg)   \
1016         do {    \
1017                 *(inst)++ = (unsigned char)0x58 + (reg);        \
1018         } while (0)
1019
1020 #define x86_pop_mem(inst,mem)   \
1021         do {    \
1022                 *(inst)++ = (unsigned char)0x87;        \
1023                 x86_mem_emit ((inst), 0, (mem));        \
1024         } while (0)
1025
1026 #define x86_pop_membase(inst,basereg,disp)      \
1027         do {    \
1028                 *(inst)++ = (unsigned char)0x87;        \
1029                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
1030         } while (0)
1031
1032 #define x86_pushad(inst) do { *(inst)++ = (unsigned char)0x60; } while (0)
1033 #define x86_pushfd(inst) do { *(inst)++ = (unsigned char)0x9c; } while (0)
1034 #define x86_popad(inst)  do { *(inst)++ = (unsigned char)0x61; } while (0)
1035 #define x86_popfd(inst)  do { *(inst)++ = (unsigned char)0x9d; } while (0)
1036
1037 #define x86_jump32(inst,imm)    \
1038         do {    \
1039                 *(inst)++ = (unsigned char)0xe9;        \
1040                 x86_imm_emit32 ((inst), (imm)); \
1041         } while (0)
1042
1043 #define x86_jump8(inst,imm)     \
1044         do {    \
1045                 *(inst)++ = (unsigned char)0xeb;        \
1046                 x86_imm_emit8 ((inst), (imm));  \
1047         } while (0)
1048
1049 #define x86_jump_reg(inst,reg)  \
1050         do {    \
1051                 *(inst)++ = (unsigned char)0xff;        \
1052                 x86_reg_emit ((inst), 4, (reg));        \
1053         } while (0)
1054
1055 #define x86_jump_mem(inst,mem)  \
1056         do {    \
1057                 *(inst)++ = (unsigned char)0xff;        \
1058                 x86_mem_emit ((inst), 4, (mem));        \
1059         } while (0)
1060
1061 #define x86_jump_membase(inst,basereg,disp)     \
1062         do {    \
1063                 *(inst)++ = (unsigned char)0xff;        \
1064                 x86_membase_emit ((inst), 4, (basereg), (disp));        \
1065         } while (0)
1066
1067 /*
1068  * target is a pointer in our buffer.
1069  */
1070 #define x86_jump_code(inst,target)      \
1071         do {    \
1072                 int t = (target) - (inst) - 2;  \
1073                 if (x86_is_imm8(t)) {   \
1074                         x86_jump8 ((inst), t);  \
1075                 } else {        \
1076                         t -= 3; \
1077                         x86_jump32 ((inst), t); \
1078                 }       \
1079         } while (0)
1080
1081 #define x86_jump_disp(inst,disp)        \
1082         do {    \
1083                 int t = (disp) - 2;     \
1084                 if (x86_is_imm8(t)) {   \
1085                         x86_jump8 ((inst), t);  \
1086                 } else {        \
1087                         t -= 3; \
1088                         x86_jump32 ((inst), t); \
1089                 }       \
1090         } while (0)
1091
1092 #define x86_branch8(inst,cond,imm,is_signed)    \
1093         do {    \
1094                 if ((is_signed))        \
1095                         *(inst)++ = x86_cc_signed_map [(cond)]; \
1096                 else    \
1097                         *(inst)++ = x86_cc_unsigned_map [(cond)];       \
1098                 x86_imm_emit8 ((inst), (imm));  \
1099         } while (0)
1100
1101 #define x86_branch32(inst,cond,imm,is_signed)   \
1102         do {    \
1103                 *(inst)++ = (unsigned char)0x0f;        \
1104                 if ((is_signed))        \
1105                         *(inst)++ = x86_cc_signed_map [(cond)] + 0x10;  \
1106                 else    \
1107                         *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x10;        \
1108                 x86_imm_emit32 ((inst), (imm)); \
1109         } while (0)
1110
1111 #define x86_branch(inst,cond,target,is_signed)  \
1112         do {    \
1113                 int offset = (target) - (inst) - 2;     \
1114                 if (x86_is_imm8 ((offset)))     \
1115                         x86_branch8 ((inst), (cond), offset, (is_signed));      \
1116                 else {  \
1117                         offset -= 4;    \
1118                         x86_branch32 ((inst), (cond), offset, (is_signed));     \
1119                 }       \
1120         } while (0)
1121
1122 #define x86_branch_disp(inst,cond,disp,is_signed)       \
1123         do {    \
1124                 int offset = (disp) - 2;        \
1125                 if (x86_is_imm8 ((offset)))     \
1126                         x86_branch8 ((inst), (cond), offset, (is_signed));      \
1127                 else {  \
1128                         offset -= 4;    \
1129                         x86_branch32 ((inst), (cond), offset, (is_signed));     \
1130                 }       \
1131         } while (0)
1132
1133 #define x86_call_imm(inst,disp) \
1134         do {    \
1135                 *(inst)++ = (unsigned char)0xe8;        \
1136                 x86_imm_emit32 ((inst), (int)(disp));   \
1137         } while (0)
1138
1139 #define x86_call_reg(inst,reg)  \
1140         do {    \
1141                 *(inst)++ = (unsigned char)0xff;        \
1142                 x86_reg_emit ((inst), 2, (reg));        \
1143         } while (0)
1144
1145 #define x86_call_mem(inst,mem)  \
1146         do {    \
1147                 *(inst)++ = (unsigned char)0xff;        \
1148                 x86_mem_emit ((inst), 2, (mem));        \
1149         } while (0)
1150
1151 #define x86_call_membase(inst,basereg,disp)     \
1152         do {    \
1153                 *(inst)++ = (unsigned char)0xff;        \
1154                 x86_membase_emit ((inst), 2, (basereg), (disp));        \
1155         } while (0)
1156
1157 #define x86_call_code(inst,target)      \
1158         do {    \
1159                 int offset = (unsigned char*)(target) - (inst); \
1160                 offset -= 5;    \
1161                 x86_call_imm ((inst), offset);  \
1162         } while (0)
1163
1164 #define x86_ret(inst) do { *(inst)++ = (unsigned char)0xc3; } while (0)
1165
1166 #define x86_ret_imm(inst,imm)   \
1167         do {    \
1168                 if ((imm) == 0) {       \
1169                         x86_ret ((inst));       \
1170                 } else {        \
1171                         *(inst)++ = (unsigned char)0xc2;        \
1172                         x86_imm_emit16 ((inst), (imm)); \
1173                 }       \
1174         } while (0)
1175
1176 #define x86_cmov_reg(inst,cond,is_signed,dreg,reg)      \
1177         do {    \
1178                 *(inst)++ = (unsigned char) 0x0f;       \
1179                 if ((is_signed))        \
1180                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1181                 else    \
1182                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1183                 x86_reg_emit ((inst), (dreg), (reg));   \
1184         } while (0)
1185
1186 #define x86_cmov_mem(inst,cond,is_signed,reg,mem)       \
1187         do {    \
1188                 *(inst)++ = (unsigned char) 0x0f;       \
1189                 if ((is_signed))        \
1190                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1191                 else    \
1192                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1193                 x86_mem_emit ((inst), (reg), (mem));    \
1194         } while (0)
1195
1196 #define x86_cmov_membase(inst,cond,is_signed,reg,basereg,disp)  \
1197         do {    \
1198                 *(inst)++ = (unsigned char) 0x0f;       \
1199                 if ((is_signed))        \
1200                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1201                 else    \
1202                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1203                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
1204         } while (0)
1205
1206 #define x86_enter(inst,framesize)       \
1207         do {    \
1208                 *(inst)++ = (unsigned char)0xc8;        \
1209                 x86_imm_emit16 ((inst), (framesize));   \
1210                 *(inst)++ = 0;  \
1211         } while (0)
1212         
1213 #define x86_leave(inst) do { *(inst)++ = (unsigned char)0xc9; } while (0)
1214 #define x86_sahf(inst)  do { *(inst)++ = (unsigned char)0x9e; } while (0)
1215
1216 #define x86_fsin(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfe; } while (0)
1217 #define x86_fcos(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xff; } while (0)
1218 #define x86_fabs(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe1; } while (0)
1219 #define x86_fpatan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf3; } while (0)
1220 #define x86_fprem(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf8; } while (0)
1221 #define x86_fprem1(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf5; } while (0)
1222 #define x86_frndint(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfc; } while (0)
1223 #define x86_fsqrt(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfa; } while (0)
1224 #define x86_fptan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf2; } while (0)
1225
1226 #define x86_padding(inst,size)  \
1227         do {    \
1228                 switch ((size)) {       \
1229                 case 1: x86_nop ((inst)); break;        \
1230                 case 2: *(inst)++ = 0x8b;       \
1231                         *(inst)++ = 0xc0; break;        \
1232                 case 3: *(inst)++ = 0x8d; *(inst)++ = 0x6d;     \
1233                         *(inst)++ = 0x00; break;        \
1234                 case 4: *(inst)++ = 0x8d; *(inst)++ = 0x64;     \
1235                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1236                         break;  \
1237                 case 5: *(inst)++ = 0x8d; *(inst)++ = 0x64;     \
1238                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1239                         x86_nop ((inst)); break;        \
1240                 case 6: *(inst)++ = 0x8d; *(inst)++ = 0xad;     \
1241                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1242                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1243                         break;  \
1244                 case 7: *(inst)++ = 0x8d; *(inst)++ = 0xa4;     \
1245                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1246                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1247                         *(inst)++ = 0x00; break;        \
1248                 default: assert (0);    \
1249                 }       \
1250         } while (0)
1251
1252 #define x86_prolog(inst,frame_size,reg_mask)    \
1253         do {    \
1254                 unsigned i, m = 1;      \
1255                 x86_enter ((inst), (frame_size));       \
1256                 for (i = 0; i < X86_NREG; ++i, m <<= 1) {       \
1257                         if ((reg_mask) & m)     \
1258                                 x86_push_reg ((inst), i);       \
1259                 }       \
1260         } while (0)
1261
1262 #define x86_epilog(inst,reg_mask)       \
1263         do {    \
1264                 unsigned i, m = 1 << X86_EDI;   \
1265                 for (i = X86_EDI; m != 0; i--, m=m>>1) {        \
1266                         if ((reg_mask) & m)     \
1267                                 x86_pop_reg ((inst), i);        \
1268                 }       \
1269                 x86_leave ((inst));     \
1270                 x86_ret ((inst));       \
1271         } while (0)
1272
1273 #endif // X86_H