Wed Sep 26 16:29:36 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.11 2001/09/26 10:33:18 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 #define x86_memindex_emit(inst,r,basereg,disp,indexreg,shift)   \
236         do {    \
237                 if ((disp) == 0 && (basereg) != X86_EBP) {      \
238                         x86_address_byte ((inst), 0, (r), 4);   \
239                         x86_address_byte ((inst), (shift), (indexreg), (basereg));      \
240                 } else if (x86_is_imm8((disp))) {       \
241                         x86_address_byte ((inst), 1, (r), 4);   \
242                         x86_address_byte ((inst), (shift), (indexreg), (basereg));      \
243                         x86_imm_emit8 ((inst), (disp)); \
244                 } else {        \
245                         x86_address_byte ((inst), 2, (r), 4);   \
246                         x86_address_byte ((inst), (shift), (indexreg), (basereg));      \
247                         x86_imm_emit32 ((inst), (disp));        \
248                 }       \
249         } while (0)
250
251 #define x86_breakpoint(inst) \
252         do {    \
253                 *(inst)++ = 0xcc;       \
254         } while (0)
255
256 #define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while (0)
257
258 #define x86_rdtsc(inst) \
259         do {    \
260                 *(inst)++ = 0x0f;       \
261                 *(inst)++ = 0x31;       \
262         } while (0)
263
264 #define x86_cmpxchg_reg_reg(inst,dreg,reg)      \
265         do {    \
266                 *(inst)++ = (unsigned char)0x0f;        \
267                 *(inst)++ = (unsigned char)0xb1;        \
268                 x86_reg_emit ((inst), (reg), (dreg));   \
269         } while (0)
270         
271 #define x86_cmpxchg_mem_reg(inst,mem,reg)       \
272         do {    \
273                 *(inst)++ = (unsigned char)0x0f;        \
274                 *(inst)++ = (unsigned char)0xb1;        \
275                 x86_mem_emit ((inst), (reg), (mem));    \
276         } while (0)
277         
278 #define x86_cmpxchg_membase_reg(inst,basereg,disp,reg)  \
279         do {    \
280                 *(inst)++ = (unsigned char)0x0f;        \
281                 *(inst)++ = (unsigned char)0xb1;        \
282                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
283         } while (0)
284
285 #define x86_xchg_reg_reg(inst,dreg,reg,size)    \
286         do {    \
287                 if ((size) == 1)        \
288                         *(inst)++ = (unsigned char)0x86;        \
289                 else    \
290                         *(inst)++ = (unsigned char)0x87;        \
291                 x86_reg_emit ((inst), (reg), (dreg));   \
292         } while (0)
293
294 #define x86_xchg_mem_reg(inst,mem,reg,size)     \
295         do {    \
296                 if ((size) == 1)        \
297                         *(inst)++ = (unsigned char)0x86;        \
298                 else    \
299                         *(inst)++ = (unsigned char)0x87;        \
300                 x86_mem_emit ((inst), (reg), (mem));    \
301         } while (0)
302
303 #define x86_xchg_membase_reg(inst,basereg,disp,reg,size)        \
304         do {    \
305                 if ((size) == 1)        \
306                         *(inst)++ = (unsigned char)0x86;        \
307                 else    \
308                         *(inst)++ = (unsigned char)0x87;        \
309                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
310         } while (0)
311
312 #define x86_inc_mem(inst,mem)   \
313         do {    \
314                 *(inst)++ = (unsigned char)0xff;        \
315                 x86_mem_emit ((inst), 0, (mem));        \
316         } while (0)
317
318 #define x86_inc_membase(inst,basereg,disp)      \
319         do {    \
320                 *(inst)++ = (unsigned char)0xff;        \
321                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
322         } while (0)
323
324 #define x86_inc_reg(inst,reg) do { *(inst)++ = (unsigned char)0x40 + (reg); } while (0)
325
326 #define x86_dec_mem(inst,mem)   \
327         do {    \
328                 *(inst)++ = (unsigned char)0xff;        \
329                 x86_mem_emit ((inst), 1, (mem));        \
330         } while (0)
331
332 #define x86_dec_membase(inst,basereg,disp)      \
333         do {    \
334                 *(inst)++ = (unsigned char)0xff;        \
335                 x86_membase_emit ((inst), 1, (basereg), (disp));        \
336         } while (0)
337
338 #define x86_dec_reg(inst,reg) do { *(inst)++ = (unsigned char)0x48 + (reg); } while (0)
339
340 #define x86_not_mem(inst,mem)   \
341         do {    \
342                 *(inst)++ = (unsigned char)0xf7;        \
343                 x86_mem_emit ((inst), 2, (mem));        \
344         } while (0)
345
346 #define x86_not_membase(inst,basereg,disp)      \
347         do {    \
348                 *(inst)++ = (unsigned char)0xf7;        \
349                 x86_membase_emit ((inst), 2, (basereg), (disp));        \
350         } while (0)
351
352 #define x86_not_reg(inst,reg)   \
353         do {    \
354                 *(inst)++ = (unsigned char)0xf7;        \
355                 x86_reg_emit ((inst), 2, (reg));        \
356         } while (0)
357
358 #define x86_neg_mem(inst,mem)   \
359         do {    \
360                 *(inst)++ = (unsigned char)0xf7;        \
361                 x86_mem_emit ((inst), 3, (mem));        \
362         } while (0)
363
364 #define x86_neg_membase(inst,basereg,disp)      \
365         do {    \
366                 *(inst)++ = (unsigned char)0xf7;        \
367                 x86_membase_emit ((inst), 3, (basereg), (disp));        \
368         } while (0)
369
370 #define x86_neg_reg(inst,reg)   \
371         do {    \
372                 *(inst)++ = (unsigned char)0xf7;        \
373                 x86_reg_emit ((inst), 3, (reg));        \
374         } while (0)
375
376 #define x86_nop(inst) do { *(inst)++ = (unsigned char)0x90; } while (0)
377
378 #define x86_alu_reg_imm(inst,opc,reg,imm)       \
379         do {    \
380                 if ((reg) == X86_EAX) { \
381                         *(inst)++ = (((unsigned char)(opc)) << 3) + 5;  \
382                         x86_imm_emit32 ((inst), (imm)); \
383                         break;  \
384                 }       \
385                 if (x86_is_imm8((imm))) {       \
386                         *(inst)++ = (unsigned char)0x83;        \
387                         x86_reg_emit ((inst), (opc), (reg));    \
388                         x86_imm_emit8 ((inst), (imm));  \
389                 } else {        \
390                         *(inst)++ = (unsigned char)0x81;        \
391                         x86_reg_emit ((inst), (opc), (reg));    \
392                         x86_imm_emit32 ((inst), (imm)); \
393                 }       \
394         } while (0)
395
396 #define x86_alu_mem_imm(inst,opc,mem,imm)       \
397         do {    \
398                 if (x86_is_imm8((imm))) {       \
399                         *(inst)++ = (unsigned char)0x83;        \
400                         x86_mem_emit ((inst), (opc), (mem));    \
401                         x86_imm_emit8 ((inst), (imm));  \
402                 } else {        \
403                         *(inst)++ = (unsigned char)0x81;        \
404                         x86_mem_emit ((inst), (opc), (mem));    \
405                         x86_imm_emit32 ((inst), (imm)); \
406                 }       \
407         } while (0)
408
409 #define x86_alu_membase_imm(inst,opc,basereg,disp,imm)  \
410         do {    \
411                 if (x86_is_imm8((imm))) {       \
412                         *(inst)++ = (unsigned char)0x83;        \
413                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
414                         x86_imm_emit8 ((inst), (imm));  \
415                 } else {        \
416                         *(inst)++ = (unsigned char)0x81;        \
417                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
418                         x86_imm_emit32 ((inst), (imm)); \
419                 }       \
420         } while (0)
421
422 #define x86_alu_mem_reg(inst,opc,mem,reg)       \
423         do {    \
424                 *(inst)++ = (((unsigned char)(opc)) << 3) + 1;  \
425                 x86_mem_emit ((inst), (reg), (mem));    \
426         } while (0)
427
428 #define x86_alu_membase_reg(inst,opc,basereg,disp,reg)  \
429         do {    \
430                 *(inst)++ = (((unsigned char)(opc)) << 3) + 1;  \
431                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
432         } while (0)
433
434 #define x86_alu_reg_reg(inst,opc,dreg,reg)      \
435         do {    \
436                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
437                 x86_reg_emit ((inst), (dreg), (reg));   \
438         } while (0)
439
440 #define x86_alu_reg_mem(inst,opc,reg,mem)       \
441         do {    \
442                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
443                 x86_mem_emit ((inst), (reg), (mem));    \
444         } while (0)
445
446 #define x86_alu_reg_membase(inst,opc,reg,basereg,disp)  \
447         do {    \
448                 *(inst)++ = (((unsigned char)(opc)) << 3) + 3;  \
449                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
450         } while (0)
451
452 #define x86_test_reg_imm(inst,reg,imm)  \
453         do {    \
454                 if ((reg) == X86_EAX) { \
455                         *(inst)++ = (unsigned char)0xa9;        \
456                 } else {        \
457                         *(inst)++ = (unsigned char)0xf7;        \
458                         x86_reg_emit ((inst), 0, (reg));        \
459                 }       \
460                 x86_imm_emit32 ((inst), (imm)); \
461         } while (0)
462
463 #define x86_test_mem_imm(inst,mem,imm)  \
464         do {    \
465                 *(inst)++ = (unsigned char)0xf7;        \
466                 x86_mem_emit ((inst), 0, (mem));        \
467                 x86_imm_emit32 ((inst), (imm)); \
468         } while (0)
469
470 #define x86_test_membase_imm(inst,basereg,disp,imm)     \
471         do {    \
472                 *(inst)++ = (unsigned char)0xf7;        \
473                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
474                 x86_imm_emit32 ((inst), (imm)); \
475         } while (0)
476
477 #define x86_test_reg_reg(inst,dreg,reg) \
478         do {    \
479                 *(inst)++ = (unsigned char)0x85;        \
480                 x86_reg_emit ((inst), (reg), (dreg));   \
481         } while (0)
482
483 #define x86_test_mem_reg(inst,mem,reg)  \
484         do {    \
485                 *(inst)++ = (unsigned char)0x85;        \
486                 x86_mem_emit ((inst), (reg), (mem));    \
487         } while (0)
488
489 #define x86_test_membase_reg(inst,basereg,disp,reg)     \
490         do {    \
491                 *(inst)++ = (unsigned char)0x85;        \
492                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
493         } while (0)
494
495 #define x86_shift_reg_imm(inst,opc,reg,imm)     \
496         do {    \
497                 if ((imm) == 1) {       \
498                         *(inst)++ = (unsigned char)0xd1;        \
499                         x86_reg_emit ((inst), (opc), (reg));    \
500                 } else {        \
501                         *(inst)++ = (unsigned char)0xc1;        \
502                         x86_reg_emit ((inst), (opc), (reg));    \
503                         x86_imm_emit8 ((inst), (imm));  \
504                 }       \
505         } while (0)
506
507 #define x86_shift_mem_imm(inst,opc,mem,imm)     \
508         do {    \
509                 if ((imm) == 1) {       \
510                         *(inst)++ = (unsigned char)0xd1;        \
511                         x86_mem_emit ((inst), (opc), (mem));    \
512                 } else {        \
513                         *(inst)++ = (unsigned char)0xc1;        \
514                         x86_mem_emit ((inst), (opc), (mem));    \
515                         x86_imm_emit8 ((inst), (imm));  \
516                 }       \
517         } while (0)
518
519 #define x86_shift_membase_imm(inst,opc,basereg,disp,imm)        \
520         do {    \
521                 if ((imm) == 1) {       \
522                         *(inst)++ = (unsigned char)0xd1;        \
523                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
524                 } else {        \
525                         *(inst)++ = (unsigned char)0xc1;        \
526                         x86_membase_emit ((inst), (opc), (basereg), (disp));    \
527                         x86_imm_emit8 ((inst), (imm));  \
528                 }       \
529         } while (0)
530
531 #define x86_shift_reg(inst,opc,reg)     \
532         do {    \
533                 *(inst)++ = (unsigned char)0xd3;        \
534                 x86_reg_emit ((inst), (opc), (reg));    \
535         } while (0)
536
537 #define x86_shift_mem(inst,opc,mem)     \
538         do {    \
539                 *(inst)++ = (unsigned char)0xd3;        \
540                 x86_mem_emit ((inst), (opc), (mem));    \
541         } while (0)
542
543 #define x86_shift_membase(inst,opc,basereg,disp)        \
544         do {    \
545                 *(inst)++ = (unsigned char)0xd3;        \
546                 x86_membase_emit ((inst), (opc), (basereg), (disp));    \
547         } while (0)
548
549 /*
550  * Multi op shift missing.
551  */
552
553 /*
554  * EDX:EAX = EAX * rm
555  */
556 #define x86_mul_reg(inst,reg,is_signed) \
557         do {    \
558                 *(inst)++ = (unsigned char)0xf7;        \
559                 x86_reg_emit ((inst), 4 + ((is_signed) ? 1 : 0), (reg));        \
560         } while (0)
561
562 #define x86_mul_mem(inst,mem,is_signed) \
563         do {    \
564                 *(inst)++ = (unsigned char)0xf7;        \
565                 x86_mem_emit ((inst), 4 + ((is_signed) ? 1 : 0), (mem));        \
566         } while (0)
567
568 #define x86_mul_membase(inst,basereg,disp,is_signed)    \
569         do {    \
570                 *(inst)++ = (unsigned char)0xf7;        \
571                 x86_membase_emit ((inst), 4 + ((is_signed) ? 1 : 0), (basereg), (disp));        \
572         } while (0)
573
574 /*
575  * r *= rm
576  */
577 #define x86_imul_reg_reg(inst,dreg,reg) \
578         do {    \
579                 *(inst)++ = (unsigned char)0x0f;        \
580                 *(inst)++ = (unsigned char)0xaf;        \
581                 x86_reg_emit ((inst), (dreg), (reg));   \
582         } while (0)
583
584 #define x86_imul_reg_mem(inst,reg,mem)  \
585         do {    \
586                 *(inst)++ = (unsigned char)0x0f;        \
587                 *(inst)++ = (unsigned char)0xaf;        \
588                 x86_mem_emit ((inst), (reg), (mem));    \
589         } while (0)
590
591 #define x86_imul_reg_membase(inst,reg,basereg,disp)     \
592         do {    \
593                 *(inst)++ = (unsigned char)0x0f;        \
594                 *(inst)++ = (unsigned char)0xaf;        \
595                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
596         } while (0)
597
598 /*
599  * dreg = rm * imm
600  */
601 #define x86_imul_reg_reg_imm(inst,dreg,reg,imm) \
602         do {    \
603                 if (x86_is_imm8 ((imm))) {      \
604                         *(inst)++ = (unsigned char)0x6b;        \
605                         x86_reg_emit ((inst), (dreg), (reg));   \
606                         x86_imm_emit8 ((inst), (imm));  \
607                 } else {        \
608                         *(inst)++ = (unsigned char)0x69;        \
609                         x86_reg_emit ((inst), (dreg), (reg));   \
610                         x86_imm_emit32 ((inst), (imm)); \
611                 }       \
612         } while (0)
613
614 #define x86_imul_reg_mem_imm(inst,reg,mem,imm)  \
615         do {    \
616                 if (x86_is_imm8 ((imm))) {      \
617                         *(inst)++ = (unsigned char)0x6b;        \
618                         x86_mem_emit ((inst), (reg), (mem));    \
619                         x86_imm_emit8 ((inst), (imm));  \
620                 } else {        \
621                         *(inst)++ = (unsigned char)0x69;        \
622                         x86_reg_emit ((inst), (reg), (mem));    \
623                         x86_imm_emit32 ((inst), (imm)); \
624                 }       \
625         } while (0)
626
627 #define x86_imul_reg_membase_imm(inst,reg,basereg,disp,imm)     \
628         do {    \
629                 if (x86_is_imm8 ((imm))) {      \
630                         *(inst)++ = (unsigned char)0x6b;        \
631                         x86_membase_emit ((inst), (reg), (basereg), (disp));    \
632                         x86_imm_emit8 ((inst), (imm));  \
633                 } else {        \
634                         *(inst)++ = (unsigned char)0x69;        \
635                         x86_membase_emit ((inst), (reg), (basereg), (disp));    \
636                         x86_imm_emit32 ((inst), (imm)); \
637                 }       \
638         } while (0)
639
640 /*
641  * divide EDX:EAX by rm;
642  * eax = quotient, edx = remainder
643  */
644
645 #define x86_div_reg(inst,reg,is_signed) \
646         do {    \
647                 *(inst)++ = (unsigned char)0xf7;        \
648                 x86_reg_emit ((inst), 6 + ((is_signed) ? 1 : 0), (reg));        \
649         } while (0)
650
651 #define x86_div_mem(inst,mem,is_signed) \
652         do {    \
653                 *(inst)++ = (unsigned char)0xf7;        \
654                 x86_mem_emit ((inst), 6 + ((is_signed) ? 1 : 0), (mem));        \
655         } while (0)
656
657 #define x86_div_membase(inst,basereg,disp,is_signed)    \
658         do {    \
659                 *(inst)++ = (unsigned char)0xf7;        \
660                 x86_membase_emit ((inst), 6 + ((is_signed) ? 1 : 0), (basereg), (disp));        \
661         } while (0)
662
663 #define x86_mov_mem_reg(inst,mem,reg,size)      \
664         do {    \
665                 switch ((size)) {       \
666                 case 1: *(inst)++ = (unsigned char)0x88; break; \
667                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
668                 case 4: *(inst)++ = (unsigned char)0x89; break; \
669                 default: assert (0);    \
670                 }       \
671                 x86_mem_emit ((inst), (reg), (mem));    \
672         } while (0)
673
674 #define x86_mov_regp_reg(inst,regp,reg,size)    \
675         do {    \
676                 switch ((size)) {       \
677                 case 1: *(inst)++ = (unsigned char)0x88; break; \
678                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
679                 case 4: *(inst)++ = (unsigned char)0x89; break; \
680                 default: assert (0);    \
681                 }       \
682                 x86_regp_emit ((inst), (reg), (regp));  \
683         } while (0)
684
685 #define x86_mov_membase_reg(inst,basereg,disp,reg,size) \
686         do {    \
687                 switch ((size)) {       \
688                 case 1: *(inst)++ = (unsigned char)0x88; break; \
689                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
690                 case 4: *(inst)++ = (unsigned char)0x89; break; \
691                 default: assert (0);    \
692                 }       \
693                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
694         } while (0)
695
696 #define x86_mov_memindex_reg(inst,basereg,disp,indexreg,shift,reg,size) \
697         do {    \
698                 switch ((size)) {       \
699                 case 1: *(inst)++ = (unsigned char)0x88; break; \
700                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
701                 case 4: *(inst)++ = (unsigned char)0x89; break; \
702                 default: assert (0);    \
703                 }       \
704                 x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift));      \
705         } while (0)
706
707 #define x86_mov_reg_reg(inst,dreg,reg,size)     \
708         do {    \
709                 switch ((size)) {       \
710                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
711                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
712                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
713                 default: assert (0);    \
714                 }       \
715                 x86_reg_emit ((inst), (dreg), (reg));   \
716         } while (0)
717
718 #define x86_mov_reg_mem(inst,reg,mem,size)      \
719         do {    \
720                 switch ((size)) {       \
721                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
722                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
723                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
724                 default: assert (0);    \
725                 }       \
726                 x86_mem_emit ((inst), (reg), (mem));    \
727         } while (0)
728
729 #define x86_mov_reg_membase(inst,reg,basereg,disp,size) \
730         do {    \
731                 switch ((size)) {       \
732                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
733                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
734                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
735                 default: assert (0);    \
736                 }       \
737                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
738         } while (0)
739
740 #define x86_mov_reg_memindex(inst,reg,basereg,disp,indexreg,shift,size) \
741         do {    \
742                 switch ((size)) {       \
743                 case 1: *(inst)++ = (unsigned char)0x8a; break; \
744                 case 2: *(inst)++ = (unsigned char)0x66; /* fall through */     \
745                 case 4: *(inst)++ = (unsigned char)0x8b; break; \
746                 default: assert (0);    \
747                 }       \
748                 x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift));      \
749         } while (0)
750
751 #define x86_mov_reg_imm(inst,reg,imm)   \
752         do {    \
753                 if ((imm) == 0) {       \
754                         x86_alu_reg_reg ((inst), X86_XOR, (reg), (reg));        \
755                 } else {        \
756                         *(inst)++ = (unsigned char)0xb8 + (reg);        \
757                         x86_imm_emit32 ((inst), (imm)); \
758                 }       \
759         } while (0)
760
761 #define x86_mov_mem_imm(inst,mem,imm,size)      \
762         do {    \
763                 if ((size) == 1) {      \
764                         *(inst)++ = (unsigned char)0xc6;        \
765                         x86_mem_emit ((inst), 0, (mem));        \
766                         x86_imm_emit8 ((inst), (imm));  \
767                 } else if ((size) == 2) {       \
768                         *(inst)++ = (unsigned char)0x66;        \
769                         *(inst)++ = (unsigned char)0xc7;        \
770                         x86_mem_emit ((inst), 0, (mem));        \
771                         x86_imm_emit16 ((inst), (imm)); \
772                 } else {        \
773                         *(inst)++ = (unsigned char)0xc7;        \
774                         x86_mem_emit ((inst), 0, (mem));        \
775                         x86_imm_emit32 ((inst), (imm)); \
776                 }       \
777         } while (0)
778
779 #define x86_mov_membase_imm(inst,basereg,disp,imm,size) \
780         do {    \
781                 if ((size) == 1) {      \
782                         *(inst)++ = (unsigned char)0xc6;        \
783                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
784                         x86_imm_emit8 ((inst), (imm));  \
785                 } else if ((size) == 2) {       \
786                         *(inst)++ = (unsigned char)0x66;        \
787                         *(inst)++ = (unsigned char)0xc7;        \
788                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
789                         x86_imm_emit16 ((inst), (imm)); \
790                 } else {        \
791                         *(inst)++ = (unsigned char)0xc7;        \
792                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
793                         x86_imm_emit32 ((inst), (imm)); \
794                 }       \
795         } while (0)
796
797 #define x86_lea_mem(inst,reg,mem)       \
798         do {    \
799                 *(inst)++ = (unsigned char)0x8d;        \
800                 x86_mem_emit ((inst), (reg), (mem));    \
801         } while (0)
802
803 #define x86_lea_membase(inst,reg,basereg,disp)  \
804         do {    \
805                 *(inst)++ = (unsigned char)0x8d;        \
806                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
807         } while (0)
808
809 #define x86_widen_reg(inst,dreg,reg,is_signed,is_half)  \
810         do {    \
811                 unsigned char op = 0xb6;        \
812                 *(inst)++ = (unsigned char)0x0f;        \
813                 if ((is_signed)) op += 0x08;    \
814                 if ((is_half)) op += 0x01;      \
815                 *(inst)++ = op; \
816                 x86_reg_emit ((inst), (dreg), (reg));   \
817         } while (0)
818
819 #define x86_widen_mem(inst,dreg,mem,is_signed,is_half)  \
820         do {    \
821                 unsigned char op = 0xb6;        \
822                 *(inst)++ = (unsigned char)0x0f;        \
823                 if ((is_signed)) op += 0x08;    \
824                 if ((is_half)) op += 0x01;      \
825                 *(inst)++ = op; \
826                 x86_mem_emit ((inst), (dreg), (mem));   \
827         } while (0)
828
829 #define x86_widen_membase(inst,dreg,basereg,disp,is_signed,is_half)     \
830         do {    \
831                 unsigned char op = 0xb6;        \
832                 *(inst)++ = (unsigned char)0x0f;        \
833                 if ((is_signed)) op += 0x08;    \
834                 if ((is_half)) op += 0x01;      \
835                 *(inst)++ = op; \
836                 x86_membase_emit ((inst), (dreg), (basereg), (disp));   \
837         } while (0)
838
839 #define x86_cdq(inst)  do { *(inst)++ = (unsigned char)0x99; } while (0)
840 #define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
841
842 #define x86_fp_op_mem(inst,opc,mem,is_double)   \
843         do {    \
844                 *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8;    \
845                 x86_mem_emit ((inst), (opc), (mem));    \
846         } while (0)
847
848 #define x86_fp_op(inst,opc,index)       \
849         do {    \
850                 *(inst)++ = (unsigned char)0xd8;        \
851                 *(inst)++ = (unsigned char)0xc0+((opc)<<3)+((index)&0x07);      \
852         } while (0)
853
854 #define x86_fp_op_reg(inst,opc,index,pop_stack) \
855         do {    \
856                 static const unsigned char map[] = { 0, 1, 2, 3, 5, 4, 7, 6, 8};        \
857                 *(inst)++ = (pop_stack) ? (unsigned char)0xde : (unsigned char)0xdc;    \
858                 *(inst)++ = (unsigned char)0xc0+(map[(opc)]<<3)+((index)&0x07); \
859         } while (0)
860
861 #define x86_fstp(inst,index)    \
862         do {    \
863                 *(inst)++ = (unsigned char)0xdd;        \
864                 *(inst)++ = (unsigned char)0xd8+(index);        \
865         } while (0)
866
867 #define x86_fcompp(inst)        \
868         do {    \
869                 *(inst)++ = (unsigned char)0xde;        \
870                 *(inst)++ = (unsigned char)0xd9;        \
871         } while (0)
872
873 #define x86_fnstsw(inst)        \
874         do {    \
875                 *(inst)++ = (unsigned char)0xdf;        \
876                 *(inst)++ = (unsigned char)0xe0;        \
877         } while (0)
878
879 #define x86_fnstcw(inst,mem)    \
880         do {    \
881                 *(inst)++ = (unsigned char)0xd9;        \
882                 x86_mem_emit ((inst), 7, (mem));        \
883         } while (0)
884
885 #define x86_fnstcw_membase(inst,basereg,disp)   \
886         do {    \
887                 *(inst)++ = (unsigned char)0xd9;        \
888                 x86_membase_emit ((inst), 7, (basereg), (disp));        \
889         } while (0)
890
891 #define x86_fldcw(inst,mem)     \
892         do {    \
893                 *(inst)++ = (unsigned char)0xd9;        \
894                 x86_mem_emit ((inst), 5, (mem));        \
895         } while (0)
896
897 #define x86_fldcw_membase(inst,basereg,disp)    \
898         do {    \
899                 *(inst)++ = (unsigned char)0xd9;        \
900                 x86_membase_emit ((inst), 5, (basereg), (disp));        \
901         } while (0)
902
903 #define x86_fchs(inst)  \
904         do {    \
905                 *(inst)++ = (unsigned char)0xd9;        \
906                 *(inst)++ = (unsigned char)0xe0;        \
907         } while (0)
908
909 #define x86_frem(inst)  \
910         do {    \
911                 *(inst)++ = (unsigned char)0xd9;        \
912                 *(inst)++ = (unsigned char)0xf8;        \
913         } while (0)
914
915 #define x86_fxch(inst,index)    \
916         do {    \
917                 *(inst)++ = (unsigned char)0xd9;        \
918                 *(inst)++ = (unsigned char)0xc8 + ((index) & 0x07);     \
919         } while (0)
920
921 #define x86_fcomip(inst,index)  \
922         do {    \
923                 *(inst)++ = (unsigned char)0xdf;        \
924                 *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07);     \
925         } while (0)
926
927 #define x86_fld(inst,mem,is_double)     \
928         do {    \
929                 *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9;    \
930                 x86_mem_emit ((inst), 0, (mem));        \
931         } while (0)
932
933 #define x86_fld_membase(inst,basereg,disp,is_double)    \
934         do {    \
935                 *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9;    \
936                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
937         } while (0)
938
939 #define x86_fld80(inst,mem)     \
940         do {    \
941                 *(inst)++ = (unsigned char)0xdb;        \
942                 x86_mem_emit ((inst), 5, (mem));        \
943         } while (0)
944
945 #define x86_fld80_membase(inst,basereg,disp)    \
946         do {    \
947                 *(inst)++ = (unsigned char)0xdb;        \
948                 x86_membase_emit ((inst), 5, (basereg), (disp));        \
949         } while (0)
950
951 #define x86_fild(inst,mem,is_long)      \
952         do {    \
953                 if ((is_long)) {        \
954                         *(inst)++ = (unsigned char)0xdf;        \
955                         x86_mem_emit ((inst), 5, (mem));        \
956                 } else {        \
957                         *(inst)++ = (unsigned char)0xdb;        \
958                         x86_mem_emit ((inst), 0, (mem));        \
959                 }       \
960         } while (0)
961
962 #define x86_fild_membase(inst,basereg,disp,is_long)     \
963         do {    \
964                 if ((is_long)) {        \
965                         *(inst)++ = (unsigned char)0xdf;        \
966                         x86_membase_emit ((inst), 5, (basereg), (disp));        \
967                 } else {        \
968                         *(inst)++ = (unsigned char)0xdb;        \
969                         x86_membase_emit ((inst), 0, (basereg), (disp));        \
970                 }       \
971         } while (0)
972
973 #define x86_fld_reg(inst,index) \
974         do {    \
975                 *(inst)++ = (unsigned char)0xd9;        \
976                 *(inst)++ = (unsigned char)0xc0 + ((index) & 0x07);     \
977         } while (0)
978
979 #define x86_fldz(inst)  \
980         do {    \
981                 *(inst)++ = (unsigned char)0xd9;        \
982                 *(inst)++ = (unsigned char)0xee;        \
983         } while (0)
984
985 #define x86_fld1(inst)  \
986         do {    \
987                 *(inst)++ = (unsigned char)0xd9;        \
988                 *(inst)++ = (unsigned char)0xe8;        \
989         } while (0)
990
991 #define x86_fst(inst,mem,is_double,pop_stack)   \
992         do {    \
993                 *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9;     \
994                 x86_mem_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (mem));        \
995         } while (0)
996
997 #define x86_fst_membase(inst,basereg,disp,is_double,pop_stack)  \
998         do {    \
999                 *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9;     \
1000                 x86_membase_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (basereg), (disp));        \
1001         } while (0)
1002
1003 #define x86_fist_pop(inst,mem,is_long)  \
1004         do {    \
1005                 if ((is_long)) {        \
1006                         *(inst)++ = (unsigned char)0xdf;        \
1007                         x86_mem_emit ((inst), 7, (mem));        \
1008                 } else {        \
1009                         *(inst)++ = (unsigned char)0xdb;        \
1010                         x86_mem_emit ((inst), 3, (mem));        \
1011                 }       \
1012         } while (0)
1013
1014 #define x86_fist_pop_membase(inst,basereg,disp,is_long) \
1015         do {    \
1016                 if ((is_long)) {        \
1017                         *(inst)++ = (unsigned char)0xdf;        \
1018                         x86_membase_emit ((inst), 7, (basereg), (disp));        \
1019                 } else {        \
1020                         *(inst)++ = (unsigned char)0xdb;        \
1021                         x86_membase_emit ((inst), 3, (basereg), (disp));        \
1022                 }       \
1023         } while (0)
1024
1025 #define x86_push_reg(inst,reg)  \
1026         do {    \
1027                 *(inst)++ = (unsigned char)0x50 + (reg);        \
1028         } while (0)
1029
1030 #define x86_push_regp(inst,reg) \
1031         do {    \
1032                 *(inst)++ = (unsigned char)0xff;        \
1033                 x86_regp_emit ((inst), 6, (reg));       \
1034         } while (0)
1035
1036 #define x86_push_mem(inst,mem)  \
1037         do {    \
1038                 *(inst)++ = (unsigned char)0xff;        \
1039                 x86_mem_emit ((inst), 6, (mem));        \
1040         } while (0)
1041
1042 #define x86_push_membase(inst,basereg,disp)     \
1043         do {    \
1044                 *(inst)++ = (unsigned char)0xff;        \
1045                 x86_membase_emit ((inst), 6, (basereg), (disp));        \
1046         } while (0)
1047
1048 #define x86_push_imm(inst,imm)  \
1049         do {    \
1050                 *(inst)++ = (unsigned char)0x68;        \
1051                 x86_imm_emit32 ((inst), (imm)); \
1052         } while (0)
1053
1054 #define x86_pop_reg(inst,reg)   \
1055         do {    \
1056                 *(inst)++ = (unsigned char)0x58 + (reg);        \
1057         } while (0)
1058
1059 #define x86_pop_mem(inst,mem)   \
1060         do {    \
1061                 *(inst)++ = (unsigned char)0x87;        \
1062                 x86_mem_emit ((inst), 0, (mem));        \
1063         } while (0)
1064
1065 #define x86_pop_membase(inst,basereg,disp)      \
1066         do {    \
1067                 *(inst)++ = (unsigned char)0x87;        \
1068                 x86_membase_emit ((inst), 0, (basereg), (disp));        \
1069         } while (0)
1070
1071 #define x86_pushad(inst) do { *(inst)++ = (unsigned char)0x60; } while (0)
1072 #define x86_pushfd(inst) do { *(inst)++ = (unsigned char)0x9c; } while (0)
1073 #define x86_popad(inst)  do { *(inst)++ = (unsigned char)0x61; } while (0)
1074 #define x86_popfd(inst)  do { *(inst)++ = (unsigned char)0x9d; } while (0)
1075
1076 #define x86_jump32(inst,imm)    \
1077         do {    \
1078                 *(inst)++ = (unsigned char)0xe9;        \
1079                 x86_imm_emit32 ((inst), (imm)); \
1080         } while (0)
1081
1082 #define x86_jump8(inst,imm)     \
1083         do {    \
1084                 *(inst)++ = (unsigned char)0xeb;        \
1085                 x86_imm_emit8 ((inst), (imm));  \
1086         } while (0)
1087
1088 #define x86_jump_reg(inst,reg)  \
1089         do {    \
1090                 *(inst)++ = (unsigned char)0xff;        \
1091                 x86_reg_emit ((inst), 4, (reg));        \
1092         } while (0)
1093
1094 #define x86_jump_mem(inst,mem)  \
1095         do {    \
1096                 *(inst)++ = (unsigned char)0xff;        \
1097                 x86_mem_emit ((inst), 4, (mem));        \
1098         } while (0)
1099
1100 #define x86_jump_membase(inst,basereg,disp)     \
1101         do {    \
1102                 *(inst)++ = (unsigned char)0xff;        \
1103                 x86_membase_emit ((inst), 4, (basereg), (disp));        \
1104         } while (0)
1105
1106 /*
1107  * target is a pointer in our buffer.
1108  */
1109 #define x86_jump_code(inst,target)      \
1110         do {    \
1111                 int t = (target) - (inst) - 2;  \
1112                 if (x86_is_imm8(t)) {   \
1113                         x86_jump8 ((inst), t);  \
1114                 } else {        \
1115                         t -= 3; \
1116                         x86_jump32 ((inst), t); \
1117                 }       \
1118         } while (0)
1119
1120 #define x86_jump_disp(inst,disp)        \
1121         do {    \
1122                 int t = (disp) - 2;     \
1123                 if (x86_is_imm8(t)) {   \
1124                         x86_jump8 ((inst), t);  \
1125                 } else {        \
1126                         t -= 3; \
1127                         x86_jump32 ((inst), t); \
1128                 }       \
1129         } while (0)
1130
1131 #define x86_branch8(inst,cond,imm,is_signed)    \
1132         do {    \
1133                 if ((is_signed))        \
1134                         *(inst)++ = x86_cc_signed_map [(cond)]; \
1135                 else    \
1136                         *(inst)++ = x86_cc_unsigned_map [(cond)];       \
1137                 x86_imm_emit8 ((inst), (imm));  \
1138         } while (0)
1139
1140 #define x86_branch32(inst,cond,imm,is_signed)   \
1141         do {    \
1142                 *(inst)++ = (unsigned char)0x0f;        \
1143                 if ((is_signed))        \
1144                         *(inst)++ = x86_cc_signed_map [(cond)] + 0x10;  \
1145                 else    \
1146                         *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x10;        \
1147                 x86_imm_emit32 ((inst), (imm)); \
1148         } while (0)
1149
1150 #define x86_branch(inst,cond,target,is_signed)  \
1151         do {    \
1152                 int offset = (target) - (inst) - 2;     \
1153                 if (x86_is_imm8 ((offset)))     \
1154                         x86_branch8 ((inst), (cond), offset, (is_signed));      \
1155                 else {  \
1156                         offset -= 4;    \
1157                         x86_branch32 ((inst), (cond), offset, (is_signed));     \
1158                 }       \
1159         } while (0)
1160
1161 #define x86_branch_disp(inst,cond,disp,is_signed)       \
1162         do {    \
1163                 int offset = (disp) - 2;        \
1164                 if (x86_is_imm8 ((offset)))     \
1165                         x86_branch8 ((inst), (cond), offset, (is_signed));      \
1166                 else {  \
1167                         offset -= 4;    \
1168                         x86_branch32 ((inst), (cond), offset, (is_signed));     \
1169                 }       \
1170         } while (0)
1171
1172 #define x86_call_imm(inst,disp) \
1173         do {    \
1174                 *(inst)++ = (unsigned char)0xe8;        \
1175                 x86_imm_emit32 ((inst), (int)(disp));   \
1176         } while (0)
1177
1178 #define x86_call_reg(inst,reg)  \
1179         do {    \
1180                 *(inst)++ = (unsigned char)0xff;        \
1181                 x86_reg_emit ((inst), 2, (reg));        \
1182         } while (0)
1183
1184 #define x86_call_mem(inst,mem)  \
1185         do {    \
1186                 *(inst)++ = (unsigned char)0xff;        \
1187                 x86_mem_emit ((inst), 2, (mem));        \
1188         } while (0)
1189
1190 #define x86_call_membase(inst,basereg,disp)     \
1191         do {    \
1192                 *(inst)++ = (unsigned char)0xff;        \
1193                 x86_membase_emit ((inst), 2, (basereg), (disp));        \
1194         } while (0)
1195
1196 #define x86_call_code(inst,target)      \
1197         do {    \
1198                 int offset = (unsigned char*)(target) - (inst); \
1199                 offset -= 5;    \
1200                 x86_call_imm ((inst), offset);  \
1201         } while (0)
1202
1203 #define x86_ret(inst) do { *(inst)++ = (unsigned char)0xc3; } while (0)
1204
1205 #define x86_ret_imm(inst,imm)   \
1206         do {    \
1207                 if ((imm) == 0) {       \
1208                         x86_ret ((inst));       \
1209                 } else {        \
1210                         *(inst)++ = (unsigned char)0xc2;        \
1211                         x86_imm_emit16 ((inst), (imm)); \
1212                 }       \
1213         } while (0)
1214
1215 #define x86_cmov_reg(inst,cond,is_signed,dreg,reg)      \
1216         do {    \
1217                 *(inst)++ = (unsigned char) 0x0f;       \
1218                 if ((is_signed))        \
1219                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1220                 else    \
1221                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1222                 x86_reg_emit ((inst), (dreg), (reg));   \
1223         } while (0)
1224
1225 #define x86_cmov_mem(inst,cond,is_signed,reg,mem)       \
1226         do {    \
1227                 *(inst)++ = (unsigned char) 0x0f;       \
1228                 if ((is_signed))        \
1229                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1230                 else    \
1231                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1232                 x86_mem_emit ((inst), (reg), (mem));    \
1233         } while (0)
1234
1235 #define x86_cmov_membase(inst,cond,is_signed,reg,basereg,disp)  \
1236         do {    \
1237                 *(inst)++ = (unsigned char) 0x0f;       \
1238                 if ((is_signed))        \
1239                         *(inst)++ = x86_cc_signed_map [(cond)] - 0x30;  \
1240                 else    \
1241                         *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30;        \
1242                 x86_membase_emit ((inst), (reg), (basereg), (disp));    \
1243         } while (0)
1244
1245 #define x86_enter(inst,framesize)       \
1246         do {    \
1247                 *(inst)++ = (unsigned char)0xc8;        \
1248                 x86_imm_emit16 ((inst), (framesize));   \
1249                 *(inst)++ = 0;  \
1250         } while (0)
1251         
1252 #define x86_leave(inst) do { *(inst)++ = (unsigned char)0xc9; } while (0)
1253 #define x86_sahf(inst)  do { *(inst)++ = (unsigned char)0x9e; } while (0)
1254
1255 #define x86_fsin(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfe; } while (0)
1256 #define x86_fcos(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xff; } while (0)
1257 #define x86_fabs(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe1; } while (0)
1258 #define x86_fpatan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf3; } while (0)
1259 #define x86_fprem(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf8; } while (0)
1260 #define x86_fprem1(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf5; } while (0)
1261 #define x86_frndint(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfc; } while (0)
1262 #define x86_fsqrt(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfa; } while (0)
1263 #define x86_fptan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf2; } while (0)
1264
1265 #define x86_padding(inst,size)  \
1266         do {    \
1267                 switch ((size)) {       \
1268                 case 1: x86_nop ((inst)); break;        \
1269                 case 2: *(inst)++ = 0x8b;       \
1270                         *(inst)++ = 0xc0; break;        \
1271                 case 3: *(inst)++ = 0x8d; *(inst)++ = 0x6d;     \
1272                         *(inst)++ = 0x00; break;        \
1273                 case 4: *(inst)++ = 0x8d; *(inst)++ = 0x64;     \
1274                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1275                         break;  \
1276                 case 5: *(inst)++ = 0x8d; *(inst)++ = 0x64;     \
1277                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1278                         x86_nop ((inst)); break;        \
1279                 case 6: *(inst)++ = 0x8d; *(inst)++ = 0xad;     \
1280                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1281                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1282                         break;  \
1283                 case 7: *(inst)++ = 0x8d; *(inst)++ = 0xa4;     \
1284                         *(inst)++ = 0x24; *(inst)++ = 0x00;     \
1285                         *(inst)++ = 0x00; *(inst)++ = 0x00;     \
1286                         *(inst)++ = 0x00; break;        \
1287                 default: assert (0);    \
1288                 }       \
1289         } while (0)
1290
1291 #define x86_prolog(inst,frame_size,reg_mask)    \
1292         do {    \
1293                 unsigned i, m = 1;      \
1294                 x86_enter ((inst), (frame_size));       \
1295                 for (i = 0; i < X86_NREG; ++i, m <<= 1) {       \
1296                         if ((reg_mask) & m)     \
1297                                 x86_push_reg ((inst), i);       \
1298                 }       \
1299         } while (0)
1300
1301 #define x86_epilog(inst,reg_mask)       \
1302         do {    \
1303                 unsigned i, m = 1 << X86_EDI;   \
1304                 for (i = X86_EDI; m != 0; i--, m=m>>1) {        \
1305                         if ((reg_mask) & m)     \
1306                                 x86_pop_reg ((inst), i);        \
1307                 }       \
1308                 x86_leave ((inst));     \
1309                 x86_ret ((inst));       \
1310         } while (0)
1311
1312 #endif // X86_H