/[dynamips]/trunk/x86-codegen.h
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/x86-codegen.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC3/x86-codegen.h
File MIME type: text/plain
File size: 47532 byte(s)
dynamips-0.2.6-RC3

1 dpavlin 1 /*
2     * x86-codegen.h: Macros for generating x86 code
3     *
4     * Authors:
5     * Paolo Molaro (lupus@ximian.com)
6     * Intel Corporation (ORP Project)
7     * Sergey Chaban (serge@wildwestsoftware.com)
8     * Dietmar Maurer (dietmar@ximian.com)
9     * Patrik Torstensson
10     *
11     * Copyright (C) 2000 Intel Corporation. All rights reserved.
12     * Copyright (C) 2001, 2002 Ximian, Inc.
13     */
14    
15     #ifndef X86_H
16     #define X86_H
17     #include <assert.h>
18     /*
19     // x86 register numbers
20     */
21     typedef enum {
22     X86_EAX = 0,
23     X86_ECX = 1,
24     X86_EDX = 2,
25     X86_EBX = 3,
26     X86_ESP = 4,
27     X86_EBP = 5,
28     X86_ESI = 6,
29     X86_EDI = 7,
30     X86_NREG
31     } X86_Reg_No;
32     /*
33     // opcodes for alu instructions
34     */
35     typedef enum {
36     X86_ADD = 0,
37     X86_OR = 1,
38     X86_ADC = 2,
39     X86_SBB = 3,
40     X86_AND = 4,
41     X86_SUB = 5,
42     X86_XOR = 6,
43     X86_CMP = 7,
44     X86_NALU
45     } X86_ALU_Opcode;
46     /*
47     // opcodes for shift instructions
48     */
49     typedef enum {
50     X86_SHLD,
51     X86_SHLR,
52     X86_ROL = 0,
53     X86_ROR = 1,
54     X86_RCL = 2,
55     X86_RCR = 3,
56     X86_SHL = 4,
57     X86_SHR = 5,
58     X86_SAR = 7,
59     X86_NSHIFT = 8
60     } X86_Shift_Opcode;
61     /*
62     // opcodes for floating-point instructions
63     */
64     typedef enum {
65     X86_FADD = 0,
66     X86_FMUL = 1,
67     X86_FCOM = 2,
68     X86_FCOMP = 3,
69     X86_FSUB = 4,
70     X86_FSUBR = 5,
71     X86_FDIV = 6,
72     X86_FDIVR = 7,
73     X86_NFP = 8
74     } X86_FP_Opcode;
75     /*
76     // integer conditions codes
77     */
78     typedef enum {
79     X86_CC_EQ = 0, X86_CC_E = 0, X86_CC_Z = 0,
80     X86_CC_NE = 1, X86_CC_NZ = 1,
81     X86_CC_LT = 2, X86_CC_B = 2, X86_CC_C = 2, X86_CC_NAE = 2,
82     X86_CC_LE = 3, X86_CC_BE = 3, X86_CC_NA = 3,
83     X86_CC_GT = 4, X86_CC_A = 4, X86_CC_NBE = 4,
84     X86_CC_GE = 5, X86_CC_AE = 5, X86_CC_NB = 5, X86_CC_NC = 5,
85     X86_CC_LZ = 6, X86_CC_S = 6,
86     X86_CC_GEZ = 7, X86_CC_NS = 7,
87     X86_CC_P = 8, X86_CC_PE = 8,
88     X86_CC_NP = 9, X86_CC_PO = 9,
89     X86_CC_O = 10,
90     X86_CC_NO = 11,
91     X86_NCC
92     } X86_CC;
93    
94     /* FP status */
95     enum {
96     X86_FP_C0 = 0x100,
97     X86_FP_C1 = 0x200,
98     X86_FP_C2 = 0x400,
99     X86_FP_C3 = 0x4000,
100     X86_FP_CC_MASK = 0x4500
101     };
102    
103     /* FP control word */
104     enum {
105     X86_FPCW_INVOPEX_MASK = 0x1,
106     X86_FPCW_DENOPEX_MASK = 0x2,
107     X86_FPCW_ZERODIV_MASK = 0x4,
108     X86_FPCW_OVFEX_MASK = 0x8,
109     X86_FPCW_UNDFEX_MASK = 0x10,
110     X86_FPCW_PRECEX_MASK = 0x20,
111     X86_FPCW_PRECC_MASK = 0x300,
112     X86_FPCW_ROUNDC_MASK = 0xc00,
113    
114     /* values for precision control */
115     X86_FPCW_PREC_SINGLE = 0,
116     X86_FPCW_PREC_DOUBLE = 0x200,
117     X86_FPCW_PREC_EXTENDED = 0x300,
118    
119     /* values for rounding control */
120     X86_FPCW_ROUND_NEAREST = 0,
121     X86_FPCW_ROUND_DOWN = 0x400,
122     X86_FPCW_ROUND_UP = 0x800,
123     X86_FPCW_ROUND_TOZERO = 0xc00
124     };
125    
126     /*
127     // prefix code
128     */
129     typedef enum {
130     X86_LOCK_PREFIX = 0xF0,
131     X86_REPNZ_PREFIX = 0xF2,
132     X86_REPZ_PREFIX = 0xF3,
133     X86_REP_PREFIX = 0xF3,
134     X86_CS_PREFIX = 0x2E,
135     X86_SS_PREFIX = 0x36,
136     X86_DS_PREFIX = 0x3E,
137     X86_ES_PREFIX = 0x26,
138     X86_FS_PREFIX = 0x64,
139     X86_GS_PREFIX = 0x65,
140     X86_UNLIKELY_PREFIX = 0x2E,
141     X86_LIKELY_PREFIX = 0x3E,
142     X86_OPERAND_PREFIX = 0x66,
143     X86_ADDRESS_PREFIX = 0x67
144     } X86_Prefix;
145    
146     static const unsigned char
147     x86_cc_unsigned_map [X86_NCC] = {
148     0x74, /* eq */
149     0x75, /* ne */
150     0x72, /* lt */
151     0x76, /* le */
152     0x77, /* gt */
153     0x73, /* ge */
154     0x78, /* lz */
155     0x79, /* gez */
156     0x7a, /* p */
157     0x7b, /* np */
158     0x70, /* o */
159     0x71, /* no */
160     };
161    
162     static const unsigned char
163     x86_cc_signed_map [X86_NCC] = {
164     0x74, /* eq */
165     0x75, /* ne */
166     0x7c, /* lt */
167     0x7e, /* le */
168     0x7f, /* gt */
169     0x7d, /* ge */
170     0x78, /* lz */
171     0x79, /* gez */
172     0x7a, /* p */
173     0x7b, /* np */
174     0x70, /* o */
175     0x71, /* no */
176     };
177    
178     typedef union {
179     int val;
180     unsigned char b [4];
181     } x86_imm_buf;
182    
183     #define X86_NOBASEREG (-1)
184    
185     /*
186     // bitvector mask for callee-saved registers
187     */
188     #define X86_ESI_MASK (1<<X86_ESI)
189     #define X86_EDI_MASK (1<<X86_EDI)
190     #define X86_EBX_MASK (1<<X86_EBX)
191     #define X86_EBP_MASK (1<<X86_EBP)
192    
193     #define X86_CALLEE_REGS ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX))
194     #define X86_CALLER_REGS ((1<<X86_EBX) | (1<<X86_EBP) | (1<<X86_ESI) | (1<<X86_EDI))
195     #define X86_BYTE_REGS ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX) | (1<<X86_EBX))
196    
197     #define X86_IS_SCRATCH(reg) (X86_CALLER_REGS & (1 << (reg))) /* X86_EAX, X86_ECX, or X86_EDX */
198     #define X86_IS_CALLEE(reg) (X86_CALLEE_REGS & (1 << (reg))) /* X86_ESI, X86_EDI, X86_EBX, or X86_EBP */
199    
200     #define X86_IS_BYTE_REG(reg) ((reg) < 4)
201    
202     /*
203     // Frame structure:
204     //
205     // +--------------------------------+
206     // | in_arg[0] = var[0] |
207     // | in_arg[1] = var[1] |
208     // | . . . |
209     // | in_arg[n_arg-1] = var[n_arg-1] |
210     // +--------------------------------+
211     // | return IP |
212     // +--------------------------------+
213     // | saved EBP | <-- frame pointer (EBP)
214     // +--------------------------------+
215     // | ... | n_extra
216     // +--------------------------------+
217     // | var[n_arg] |
218     // | var[n_arg+1] | local variables area
219     // | . . . |
220     // | var[n_var-1] |
221     // +--------------------------------+
222     // | |
223     // | |
224     // | spill area | area for spilling mimic stack
225     // | |
226     // +--------------------------------|
227     // | ebx |
228     // | ebp [ESP_Frame only] |
229     // | esi | 0..3 callee-saved regs
230     // | edi | <-- stack pointer (ESP)
231     // +--------------------------------+
232     // | stk0 |
233     // | stk1 | operand stack area/
234     // | . . . | out args
235     // | stkn-1 |
236     // +--------------------------------|
237     //
238     //
239     */
240    
241    
242     /*
243     * useful building blocks
244     */
245     #define x86_modrm_mod(modrm) ((modrm) >> 6)
246     #define x86_modrm_reg(modrm) (((modrm) >> 3) & 0x7)
247     #define x86_modrm_rm(modrm) ((modrm) & 0x7)
248    
249     #define x86_address_byte(inst,m,o,r) do { *(inst)++ = ((((m)&0x03)<<6)|(((o)&0x07)<<3)|(((r)&0x07))); } while (0)
250     #define x86_imm_emit32(inst,imm) \
251     do { \
252     x86_imm_buf imb; imb.val = (int) (imm); \
253     *(inst)++ = imb.b [0]; \
254     *(inst)++ = imb.b [1]; \
255     *(inst)++ = imb.b [2]; \
256     *(inst)++ = imb.b [3]; \
257     } while (0)
258     #define x86_imm_emit16(inst,imm) do { *(short*)(inst) = (imm); (inst) += 2; } while (0)
259     #define x86_imm_emit8(inst,imm) do { *(inst) = (unsigned char)((imm) & 0xff); ++(inst); } while (0)
260     #define x86_is_imm8(imm) (((int)(imm) >= -128 && (int)(imm) <= 127))
261     #define x86_is_imm16(imm) (((int)(imm) >= -(1<<16) && (int)(imm) <= ((1<<16)-1)))
262    
263     #define x86_reg_emit(inst,r,regno) do { x86_address_byte ((inst), 3, (r), (regno)); } while (0)
264     #define x86_reg8_emit(inst,r,regno,is_rh,is_rnoh) do {x86_address_byte ((inst), 3, (is_rh)?((r)|4):(r), (is_rnoh)?((regno)|4):(regno));} while (0)
265     #define x86_regp_emit(inst,r,regno) do { x86_address_byte ((inst), 0, (r), (regno)); } while (0)
266     #define x86_mem_emit(inst,r,disp) do { x86_address_byte ((inst), 0, (r), 5); x86_imm_emit32((inst), (disp)); } while (0)
267    
268     #define x86_membase_emit(inst,r,basereg,disp) do {\
269     if ((basereg) == X86_ESP) { \
270     if ((disp) == 0) { \
271     x86_address_byte ((inst), 0, (r), X86_ESP); \
272     x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
273     } else if (x86_is_imm8((disp))) { \
274     x86_address_byte ((inst), 1, (r), X86_ESP); \
275     x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
276     x86_imm_emit8 ((inst), (disp)); \
277     } else { \
278     x86_address_byte ((inst), 2, (r), X86_ESP); \
279     x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
280     x86_imm_emit32 ((inst), (disp)); \
281     } \
282     break; \
283     } \
284     if ((disp) == 0 && (basereg) != X86_EBP) { \
285     x86_address_byte ((inst), 0, (r), (basereg)); \
286     break; \
287     } \
288     if (x86_is_imm8((disp))) { \
289     x86_address_byte ((inst), 1, (r), (basereg)); \
290     x86_imm_emit8 ((inst), (disp)); \
291     } else { \
292     x86_address_byte ((inst), 2, (r), (basereg)); \
293     x86_imm_emit32 ((inst), (disp)); \
294     } \
295     } while (0)
296    
297     #define x86_memindex_emit(inst,r,basereg,disp,indexreg,shift) \
298     do { \
299     if ((basereg) == X86_NOBASEREG) { \
300     x86_address_byte ((inst), 0, (r), 4); \
301     x86_address_byte ((inst), (shift), (indexreg), 5); \
302     x86_imm_emit32 ((inst), (disp)); \
303     } else if ((disp) == 0 && (basereg) != X86_EBP) { \
304     x86_address_byte ((inst), 0, (r), 4); \
305     x86_address_byte ((inst), (shift), (indexreg), (basereg)); \
306     } else if (x86_is_imm8((disp))) { \
307     x86_address_byte ((inst), 1, (r), 4); \
308     x86_address_byte ((inst), (shift), (indexreg), (basereg)); \
309     x86_imm_emit8 ((inst), (disp)); \
310     } else { \
311     x86_address_byte ((inst), 2, (r), 4); \
312     x86_address_byte ((inst), (shift), (indexreg), 5); \
313     x86_imm_emit32 ((inst), (disp)); \
314     } \
315     } while (0)
316    
317     /*
318     * target is the position in the code where to jump to:
319     * target = code;
320     * .. output loop code...
321     * x86_mov_reg_imm (code, X86_EAX, 0);
322     * loop = code;
323     * x86_loop (code, -1);
324     * ... finish method
325     *
326     * patch displacement
327     * x86_patch (loop, target);
328     *
329     * ins should point at the start of the instruction that encodes a target.
330     * the instruction is inspected for validity and the correct displacement
331     * is inserted.
332     */
333     #define x86_patch(ins,target) \
334     do { \
335     unsigned char* pos = (ins) + 1; \
336     int disp, size = 0; \
337     switch (*(unsigned char*)(ins)) { \
338     case 0xe8: case 0xe9: ++size; break; /* call, jump32 */ \
339     case 0x0f: if (!(*pos >= 0x70 && *pos <= 0x8f)) assert (0); \
340     ++size; ++pos; break; /* prefix for 32-bit disp */ \
341     case 0xe0: case 0xe1: case 0xe2: /* loop */ \
342     case 0xeb: /* jump8 */ \
343     /* conditional jump opcodes */ \
344     case 0x70: case 0x71: case 0x72: case 0x73: \
345     case 0x74: case 0x75: case 0x76: case 0x77: \
346     case 0x78: case 0x79: case 0x7a: case 0x7b: \
347     case 0x7c: case 0x7d: case 0x7e: case 0x7f: \
348     break; \
349     default: assert (0); \
350     } \
351     disp = (target) - pos; \
352     if (size) x86_imm_emit32 (pos, disp - 4); \
353     else if (x86_is_imm8 (disp - 1)) x86_imm_emit8 (pos, disp - 1); \
354     else assert (0); \
355     } while (0)
356    
357     #define x86_breakpoint(inst) \
358     do { \
359     *(inst)++ = 0xcc; \
360     } while (0)
361    
362     #define x86_cld(inst) do { *(inst)++ =(unsigned char)0xfc; } while (0)
363     #define x86_stosb(inst) do { *(inst)++ =(unsigned char)0xaa; } while (0)
364     #define x86_stosl(inst) do { *(inst)++ =(unsigned char)0xab; } while (0)
365     #define x86_stosd(inst) x86_stosl((inst))
366     #define x86_movsb(inst) do { *(inst)++ =(unsigned char)0xa4; } while (0)
367     #define x86_movsl(inst) do { *(inst)++ =(unsigned char)0xa5; } while (0)
368     #define x86_movsd(inst) x86_movsl((inst))
369    
370     #define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while (0)
371    
372     #define x86_bswap(inst,reg) \
373     do { \
374     *(inst)++ = 0x0f; \
375     *(inst)++ = (unsigned char)0xc8 + (reg); \
376     } while (0)
377    
378     #define x86_rdtsc(inst) \
379     do { \
380     *(inst)++ = 0x0f; \
381     *(inst)++ = 0x31; \
382     } while (0)
383    
384     #define x86_cmpxchg_reg_reg(inst,dreg,reg) \
385     do { \
386     *(inst)++ = (unsigned char)0x0f; \
387     *(inst)++ = (unsigned char)0xb1; \
388     x86_reg_emit ((inst), (reg), (dreg)); \
389     } while (0)
390    
391     #define x86_cmpxchg_mem_reg(inst,mem,reg) \
392     do { \
393     *(inst)++ = (unsigned char)0x0f; \
394     *(inst)++ = (unsigned char)0xb1; \
395     x86_mem_emit ((inst), (reg), (mem)); \
396     } while (0)
397    
398     #define x86_cmpxchg_membase_reg(inst,basereg,disp,reg) \
399     do { \
400     *(inst)++ = (unsigned char)0x0f; \
401     *(inst)++ = (unsigned char)0xb1; \
402     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
403     } while (0)
404    
405     #define x86_xchg_reg_reg(inst,dreg,reg,size) \
406     do { \
407     if ((size) == 1) \
408     *(inst)++ = (unsigned char)0x86; \
409     else \
410     *(inst)++ = (unsigned char)0x87; \
411     x86_reg_emit ((inst), (reg), (dreg)); \
412     } while (0)
413    
414     #define x86_xchg_mem_reg(inst,mem,reg,size) \
415     do { \
416     if ((size) == 1) \
417     *(inst)++ = (unsigned char)0x86; \
418     else \
419     *(inst)++ = (unsigned char)0x87; \
420     x86_mem_emit ((inst), (reg), (mem)); \
421     } while (0)
422    
423     #define x86_xchg_membase_reg(inst,basereg,disp,reg,size) \
424     do { \
425     if ((size) == 1) \
426     *(inst)++ = (unsigned char)0x86; \
427     else \
428     *(inst)++ = (unsigned char)0x87; \
429     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
430     } while (0)
431    
432     #define x86_xadd_reg_reg(inst,dreg,reg,size) \
433     do { \
434     *(inst)++ = (unsigned char)0x0F; \
435     if ((size) == 1) \
436     *(inst)++ = (unsigned char)0xC0; \
437     else \
438     *(inst)++ = (unsigned char)0xC1; \
439     x86_reg_emit ((inst), (reg), (dreg)); \
440     } while (0)
441    
442     #define x86_xadd_mem_reg(inst,mem,reg,size) \
443     do { \
444     *(inst)++ = (unsigned char)0x0F; \
445     if ((size) == 1) \
446     *(inst)++ = (unsigned char)0xC0; \
447     else \
448     *(inst)++ = (unsigned char)0xC1; \
449     x86_mem_emit ((inst), (reg), (mem)); \
450     } while (0)
451    
452     #define x86_xadd_membase_reg(inst,basereg,disp,reg,size) \
453     do { \
454     *(inst)++ = (unsigned char)0x0F; \
455     if ((size) == 1) \
456     *(inst)++ = (unsigned char)0xC0; \
457     else \
458     *(inst)++ = (unsigned char)0xC1; \
459     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
460     } while (0)
461    
462     #define x86_inc_mem(inst,mem) \
463     do { \
464     *(inst)++ = (unsigned char)0xff; \
465     x86_mem_emit ((inst), 0, (mem)); \
466     } while (0)
467    
468     #define x86_inc_membase(inst,basereg,disp) \
469     do { \
470     *(inst)++ = (unsigned char)0xff; \
471     x86_membase_emit ((inst), 0, (basereg), (disp)); \
472     } while (0)
473    
474     #define x86_inc_reg(inst,reg) do { *(inst)++ = (unsigned char)0x40 + (reg); } while (0)
475    
476     #define x86_dec_mem(inst,mem) \
477     do { \
478     *(inst)++ = (unsigned char)0xff; \
479     x86_mem_emit ((inst), 1, (mem)); \
480     } while (0)
481    
482     #define x86_dec_membase(inst,basereg,disp) \
483     do { \
484     *(inst)++ = (unsigned char)0xff; \
485     x86_membase_emit ((inst), 1, (basereg), (disp)); \
486     } while (0)
487    
488     #define x86_dec_reg(inst,reg) do { *(inst)++ = (unsigned char)0x48 + (reg); } while (0)
489    
490     #define x86_not_mem(inst,mem) \
491     do { \
492     *(inst)++ = (unsigned char)0xf7; \
493     x86_mem_emit ((inst), 2, (mem)); \
494     } while (0)
495    
496     #define x86_not_membase(inst,basereg,disp) \
497     do { \
498     *(inst)++ = (unsigned char)0xf7; \
499     x86_membase_emit ((inst), 2, (basereg), (disp)); \
500     } while (0)
501    
502     #define x86_not_reg(inst,reg) \
503     do { \
504     *(inst)++ = (unsigned char)0xf7; \
505     x86_reg_emit ((inst), 2, (reg)); \
506     } while (0)
507    
508     #define x86_neg_mem(inst,mem) \
509     do { \
510     *(inst)++ = (unsigned char)0xf7; \
511     x86_mem_emit ((inst), 3, (mem)); \
512     } while (0)
513    
514     #define x86_neg_membase(inst,basereg,disp) \
515     do { \
516     *(inst)++ = (unsigned char)0xf7; \
517     x86_membase_emit ((inst), 3, (basereg), (disp)); \
518     } while (0)
519    
520     #define x86_neg_reg(inst,reg) \
521     do { \
522     *(inst)++ = (unsigned char)0xf7; \
523     x86_reg_emit ((inst), 3, (reg)); \
524     } while (0)
525    
526     #define x86_nop(inst) do { *(inst)++ = (unsigned char)0x90; } while (0)
527    
528     #define x86_alu_reg_imm(inst,opc,reg,imm) \
529     do { \
530     if ((reg) == X86_EAX) { \
531     *(inst)++ = (((unsigned char)(opc)) << 3) + 5; \
532     x86_imm_emit32 ((inst), (imm)); \
533     break; \
534     } \
535     if (x86_is_imm8((imm))) { \
536     *(inst)++ = (unsigned char)0x83; \
537     x86_reg_emit ((inst), (opc), (reg)); \
538     x86_imm_emit8 ((inst), (imm)); \
539     } else { \
540     *(inst)++ = (unsigned char)0x81; \
541     x86_reg_emit ((inst), (opc), (reg)); \
542     x86_imm_emit32 ((inst), (imm)); \
543     } \
544     } while (0)
545    
546     #define x86_alu_mem_imm(inst,opc,mem,imm) \
547     do { \
548     if (x86_is_imm8((imm))) { \
549     *(inst)++ = (unsigned char)0x83; \
550     x86_mem_emit ((inst), (opc), (mem)); \
551     x86_imm_emit8 ((inst), (imm)); \
552     } else { \
553     *(inst)++ = (unsigned char)0x81; \
554     x86_mem_emit ((inst), (opc), (mem)); \
555     x86_imm_emit32 ((inst), (imm)); \
556     } \
557     } while (0)
558    
559     #define x86_alu_membase_imm(inst,opc,basereg,disp,imm) \
560     do { \
561     if (x86_is_imm8((imm))) { \
562     *(inst)++ = (unsigned char)0x83; \
563     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
564     x86_imm_emit8 ((inst), (imm)); \
565     } else { \
566     *(inst)++ = (unsigned char)0x81; \
567     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
568     x86_imm_emit32 ((inst), (imm)); \
569     } \
570     } while (0)
571    
572     #define x86_alu_membase8_imm(inst,opc,basereg,disp,imm) \
573     do { \
574     *(inst)++ = (unsigned char)0x80; \
575     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
576     x86_imm_emit8 ((inst), (imm)); \
577     } while (0)
578    
579     #define x86_alu_mem_reg(inst,opc,mem,reg) \
580     do { \
581     *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
582     x86_mem_emit ((inst), (reg), (mem)); \
583     } while (0)
584    
585     #define x86_alu_membase_reg(inst,opc,basereg,disp,reg) \
586     do { \
587     *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
588     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
589     } while (0)
590    
591     #define x86_alu_reg_reg(inst,opc,dreg,reg) \
592     do { \
593     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
594     x86_reg_emit ((inst), (dreg), (reg)); \
595     } while (0)
596    
597     /**
598     * @x86_alu_reg8_reg8:
599     * Supports ALU operations between two 8-bit registers.
600     * dreg := dreg opc reg
601     * X86_Reg_No enum is used to specify the registers.
602     * Additionally is_*_h flags are used to specify what part
603     * of a given 32-bit register is used - high (TRUE) or low (FALSE).
604     * For example: dreg = X86_EAX, is_dreg_h = TRUE -> use AH
605     */
606     #define x86_alu_reg8_reg8(inst,opc,dreg,reg,is_dreg_h,is_reg_h) \
607     do { \
608     *(inst)++ = (((unsigned char)(opc)) << 3) + 2; \
609     x86_reg8_emit ((inst), (dreg), (reg), (is_dreg_h), (is_reg_h)); \
610     } while (0)
611    
612     #define x86_alu_reg_mem(inst,opc,reg,mem) \
613     do { \
614     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
615     x86_mem_emit ((inst), (reg), (mem)); \
616     } while (0)
617    
618     #define x86_alu_reg_membase(inst,opc,reg,basereg,disp) \
619     do { \
620     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
621     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
622     } while (0)
623    
624     #define x86_test_reg_imm(inst,reg,imm) \
625     do { \
626     if ((reg) == X86_EAX) { \
627     *(inst)++ = (unsigned char)0xa9; \
628     } else { \
629     *(inst)++ = (unsigned char)0xf7; \
630     x86_reg_emit ((inst), 0, (reg)); \
631     } \
632     x86_imm_emit32 ((inst), (imm)); \
633     } while (0)
634    
635     #define x86_test_mem_imm(inst,mem,imm) \
636     do { \
637     *(inst)++ = (unsigned char)0xf7; \
638     x86_mem_emit ((inst), 0, (mem)); \
639     x86_imm_emit32 ((inst), (imm)); \
640     } while (0)
641    
642     #define x86_test_membase_imm(inst,basereg,disp,imm) \
643     do { \
644     *(inst)++ = (unsigned char)0xf7; \
645     x86_membase_emit ((inst), 0, (basereg), (disp)); \
646     x86_imm_emit32 ((inst), (imm)); \
647     } while (0)
648    
649     #define x86_test_reg_reg(inst,dreg,reg) \
650     do { \
651     *(inst)++ = (unsigned char)0x85; \
652     x86_reg_emit ((inst), (reg), (dreg)); \
653     } while (0)
654    
655     #define x86_test_mem_reg(inst,mem,reg) \
656     do { \
657     *(inst)++ = (unsigned char)0x85; \
658     x86_mem_emit ((inst), (reg), (mem)); \
659     } while (0)
660    
661     #define x86_test_membase_reg(inst,basereg,disp,reg) \
662     do { \
663     *(inst)++ = (unsigned char)0x85; \
664     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
665     } while (0)
666    
667     #define x86_shift_reg_imm(inst,opc,reg,imm) \
668     do { \
669     if ((imm) == 1) { \
670     *(inst)++ = (unsigned char)0xd1; \
671     x86_reg_emit ((inst), (opc), (reg)); \
672     } else { \
673     *(inst)++ = (unsigned char)0xc1; \
674     x86_reg_emit ((inst), (opc), (reg)); \
675     x86_imm_emit8 ((inst), (imm)); \
676     } \
677     } while (0)
678    
679     #define x86_shift_mem_imm(inst,opc,mem,imm) \
680     do { \
681     if ((imm) == 1) { \
682     *(inst)++ = (unsigned char)0xd1; \
683     x86_mem_emit ((inst), (opc), (mem)); \
684     } else { \
685     *(inst)++ = (unsigned char)0xc1; \
686     x86_mem_emit ((inst), (opc), (mem)); \
687     x86_imm_emit8 ((inst), (imm)); \
688     } \
689     } while (0)
690    
691     #define x86_shift_membase_imm(inst,opc,basereg,disp,imm) \
692     do { \
693     if ((imm) == 1) { \
694     *(inst)++ = (unsigned char)0xd1; \
695     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
696     } else { \
697     *(inst)++ = (unsigned char)0xc1; \
698     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
699     x86_imm_emit8 ((inst), (imm)); \
700     } \
701     } while (0)
702    
703     #define x86_shift_reg(inst,opc,reg) \
704     do { \
705     *(inst)++ = (unsigned char)0xd3; \
706     x86_reg_emit ((inst), (opc), (reg)); \
707     } while (0)
708    
709     #define x86_shift_mem(inst,opc,mem) \
710     do { \
711     *(inst)++ = (unsigned char)0xd3; \
712     x86_mem_emit ((inst), (opc), (mem)); \
713     } while (0)
714    
715     #define x86_shift_membase(inst,opc,basereg,disp) \
716     do { \
717     *(inst)++ = (unsigned char)0xd3; \
718     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
719     } while (0)
720    
721     /*
722     * Multi op shift missing.
723     */
724    
725     #define x86_shrd_reg(inst,dreg,reg) \
726     do { \
727     *(inst)++ = (unsigned char)0x0f; \
728     *(inst)++ = (unsigned char)0xad; \
729     x86_reg_emit ((inst), (reg), (dreg)); \
730     } while (0)
731    
732     #define x86_shrd_reg_imm(inst,dreg,reg,shamt) \
733     do { \
734     *(inst)++ = (unsigned char)0x0f; \
735     *(inst)++ = (unsigned char)0xac; \
736     x86_reg_emit ((inst), (reg), (dreg)); \
737     x86_imm_emit8 ((inst), (shamt)); \
738     } while (0)
739    
740     #define x86_shld_reg(inst,dreg,reg) \
741     do { \
742     *(inst)++ = (unsigned char)0x0f; \
743     *(inst)++ = (unsigned char)0xa5; \
744     x86_reg_emit ((inst), (reg), (dreg)); \
745     } while (0)
746    
747     #define x86_shld_reg_imm(inst,dreg,reg,shamt) \
748     do { \
749     *(inst)++ = (unsigned char)0x0f; \
750     *(inst)++ = (unsigned char)0xa4; \
751     x86_reg_emit ((inst), (reg), (dreg)); \
752     x86_imm_emit8 ((inst), (shamt)); \
753     } while (0)
754    
755     /*
756     * EDX:EAX = EAX * rm
757     */
758     #define x86_mul_reg(inst,reg,is_signed) \
759     do { \
760     *(inst)++ = (unsigned char)0xf7; \
761     x86_reg_emit ((inst), 4 + ((is_signed) ? 1 : 0), (reg)); \
762     } while (0)
763    
764     #define x86_mul_mem(inst,mem,is_signed) \
765     do { \
766     *(inst)++ = (unsigned char)0xf7; \
767     x86_mem_emit ((inst), 4 + ((is_signed) ? 1 : 0), (mem)); \
768     } while (0)
769    
770     #define x86_mul_membase(inst,basereg,disp,is_signed) \
771     do { \
772     *(inst)++ = (unsigned char)0xf7; \
773     x86_membase_emit ((inst), 4 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
774     } while (0)
775    
776     /*
777     * r *= rm
778     */
779     #define x86_imul_reg_reg(inst,dreg,reg) \
780     do { \
781     *(inst)++ = (unsigned char)0x0f; \
782     *(inst)++ = (unsigned char)0xaf; \
783     x86_reg_emit ((inst), (dreg), (reg)); \
784     } while (0)
785    
786     #define x86_imul_reg_mem(inst,reg,mem) \
787     do { \
788     *(inst)++ = (unsigned char)0x0f; \
789     *(inst)++ = (unsigned char)0xaf; \
790     x86_mem_emit ((inst), (reg), (mem)); \
791     } while (0)
792    
793     #define x86_imul_reg_membase(inst,reg,basereg,disp) \
794     do { \
795     *(inst)++ = (unsigned char)0x0f; \
796     *(inst)++ = (unsigned char)0xaf; \
797     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
798     } while (0)
799    
800     /*
801     * dreg = rm * imm
802     */
803     #define x86_imul_reg_reg_imm(inst,dreg,reg,imm) \
804     do { \
805     if (x86_is_imm8 ((imm))) { \
806     *(inst)++ = (unsigned char)0x6b; \
807     x86_reg_emit ((inst), (dreg), (reg)); \
808     x86_imm_emit8 ((inst), (imm)); \
809     } else { \
810     *(inst)++ = (unsigned char)0x69; \
811     x86_reg_emit ((inst), (dreg), (reg)); \
812     x86_imm_emit32 ((inst), (imm)); \
813     } \
814     } while (0)
815    
816     #define x86_imul_reg_mem_imm(inst,reg,mem,imm) \
817     do { \
818     if (x86_is_imm8 ((imm))) { \
819     *(inst)++ = (unsigned char)0x6b; \
820     x86_mem_emit ((inst), (reg), (mem)); \
821     x86_imm_emit8 ((inst), (imm)); \
822     } else { \
823     *(inst)++ = (unsigned char)0x69; \
824     x86_reg_emit ((inst), (reg), (mem)); \
825     x86_imm_emit32 ((inst), (imm)); \
826     } \
827     } while (0)
828    
829     #define x86_imul_reg_membase_imm(inst,reg,basereg,disp,imm) \
830     do { \
831     if (x86_is_imm8 ((imm))) { \
832     *(inst)++ = (unsigned char)0x6b; \
833     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
834     x86_imm_emit8 ((inst), (imm)); \
835     } else { \
836     *(inst)++ = (unsigned char)0x69; \
837     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
838     x86_imm_emit32 ((inst), (imm)); \
839     } \
840     } while (0)
841    
842     /*
843     * divide EDX:EAX by rm;
844     * eax = quotient, edx = remainder
845     */
846    
847     #define x86_div_reg(inst,reg,is_signed) \
848     do { \
849     *(inst)++ = (unsigned char)0xf7; \
850     x86_reg_emit ((inst), 6 + ((is_signed) ? 1 : 0), (reg)); \
851     } while (0)
852    
853     #define x86_div_mem(inst,mem,is_signed) \
854     do { \
855     *(inst)++ = (unsigned char)0xf7; \
856     x86_mem_emit ((inst), 6 + ((is_signed) ? 1 : 0), (mem)); \
857     } while (0)
858    
859     #define x86_div_membase(inst,basereg,disp,is_signed) \
860     do { \
861     *(inst)++ = (unsigned char)0xf7; \
862     x86_membase_emit ((inst), 6 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
863     } while (0)
864    
865     #define x86_mov_mem_reg(inst,mem,reg,size) \
866     do { \
867     switch ((size)) { \
868     case 1: *(inst)++ = (unsigned char)0x88; break; \
869     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
870     case 4: *(inst)++ = (unsigned char)0x89; break; \
871     default: assert (0); \
872     } \
873     x86_mem_emit ((inst), (reg), (mem)); \
874     } while (0)
875    
876     #define x86_mov_regp_reg(inst,regp,reg,size) \
877     do { \
878     switch ((size)) { \
879     case 1: *(inst)++ = (unsigned char)0x88; break; \
880     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
881     case 4: *(inst)++ = (unsigned char)0x89; break; \
882     default: assert (0); \
883     } \
884     x86_regp_emit ((inst), (reg), (regp)); \
885     } while (0)
886    
887     #define x86_mov_membase_reg(inst,basereg,disp,reg,size) \
888     do { \
889     switch ((size)) { \
890     case 1: *(inst)++ = (unsigned char)0x88; break; \
891     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
892     case 4: *(inst)++ = (unsigned char)0x89; break; \
893     default: assert (0); \
894     } \
895     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
896     } while (0)
897    
898     #define x86_mov_memindex_reg(inst,basereg,disp,indexreg,shift,reg,size) \
899     do { \
900     switch ((size)) { \
901     case 1: *(inst)++ = (unsigned char)0x88; break; \
902     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
903     case 4: *(inst)++ = (unsigned char)0x89; break; \
904     default: assert (0); \
905     } \
906     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
907     } while (0)
908    
909     #define x86_mov_reg_reg(inst,dreg,reg,size) \
910     do { \
911     switch ((size)) { \
912     case 1: *(inst)++ = (unsigned char)0x8a; break; \
913     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
914     case 4: *(inst)++ = (unsigned char)0x8b; break; \
915     default: assert (0); \
916     } \
917     x86_reg_emit ((inst), (dreg), (reg)); \
918     } while (0)
919    
920     #define x86_mov_reg_mem(inst,reg,mem,size) \
921     do { \
922     switch ((size)) { \
923     case 1: *(inst)++ = (unsigned char)0x8a; break; \
924     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
925     case 4: *(inst)++ = (unsigned char)0x8b; break; \
926     default: assert (0); \
927     } \
928     x86_mem_emit ((inst), (reg), (mem)); \
929     } while (0)
930    
931     #define x86_mov_reg_membase(inst,reg,basereg,disp,size) \
932     do { \
933     switch ((size)) { \
934     case 1: *(inst)++ = (unsigned char)0x8a; break; \
935     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
936     case 4: *(inst)++ = (unsigned char)0x8b; break; \
937     default: assert (0); \
938     } \
939     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
940     } while (0)
941    
942     #define x86_mov_reg_memindex(inst,reg,basereg,disp,indexreg,shift,size) \
943     do { \
944     switch ((size)) { \
945     case 1: *(inst)++ = (unsigned char)0x8a; break; \
946     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
947     case 4: *(inst)++ = (unsigned char)0x8b; break; \
948     default: assert (0); \
949     } \
950     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
951     } while (0)
952    
953     /*
954     * Note: x86_clear_reg () chacnges the condition code!
955     */
956     #define x86_clear_reg(inst,reg) x86_alu_reg_reg((inst), X86_XOR, (reg), (reg))
957    
958     #define x86_mov_reg_imm(inst,reg,imm) \
959     do { \
960     *(inst)++ = (unsigned char)0xb8 + (reg); \
961     x86_imm_emit32 ((inst), (imm)); \
962     } while (0)
963    
964     #define x86_mov_mem_imm(inst,mem,imm,size) \
965     do { \
966     if ((size) == 1) { \
967     *(inst)++ = (unsigned char)0xc6; \
968     x86_mem_emit ((inst), 0, (mem)); \
969     x86_imm_emit8 ((inst), (imm)); \
970     } else if ((size) == 2) { \
971     *(inst)++ = (unsigned char)0x66; \
972     *(inst)++ = (unsigned char)0xc7; \
973     x86_mem_emit ((inst), 0, (mem)); \
974     x86_imm_emit16 ((inst), (imm)); \
975     } else { \
976     *(inst)++ = (unsigned char)0xc7; \
977     x86_mem_emit ((inst), 0, (mem)); \
978     x86_imm_emit32 ((inst), (imm)); \
979     } \
980     } while (0)
981    
982     #define x86_mov_membase_imm(inst,basereg,disp,imm,size) \
983     do { \
984     if ((size) == 1) { \
985     *(inst)++ = (unsigned char)0xc6; \
986     x86_membase_emit ((inst), 0, (basereg), (disp)); \
987     x86_imm_emit8 ((inst), (imm)); \
988     } else if ((size) == 2) { \
989     *(inst)++ = (unsigned char)0x66; \
990     *(inst)++ = (unsigned char)0xc7; \
991     x86_membase_emit ((inst), 0, (basereg), (disp)); \
992     x86_imm_emit16 ((inst), (imm)); \
993     } else { \
994     *(inst)++ = (unsigned char)0xc7; \
995     x86_membase_emit ((inst), 0, (basereg), (disp)); \
996     x86_imm_emit32 ((inst), (imm)); \
997     } \
998     } while (0)
999    
1000     #define x86_mov_memindex_imm(inst,basereg,disp,indexreg,shift,imm,size) \
1001     do { \
1002     if ((size) == 1) { \
1003     *(inst)++ = (unsigned char)0xc6; \
1004     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1005     x86_imm_emit8 ((inst), (imm)); \
1006     } else if ((size) == 2) { \
1007     *(inst)++ = (unsigned char)0x66; \
1008     *(inst)++ = (unsigned char)0xc7; \
1009     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1010     x86_imm_emit16 ((inst), (imm)); \
1011     } else { \
1012     *(inst)++ = (unsigned char)0xc7; \
1013     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1014     x86_imm_emit32 ((inst), (imm)); \
1015     } \
1016     } while (0)
1017    
1018     #define x86_lea_mem(inst,reg,mem) \
1019     do { \
1020     *(inst)++ = (unsigned char)0x8d; \
1021     x86_mem_emit ((inst), (reg), (mem)); \
1022     } while (0)
1023    
1024     #define x86_lea_membase(inst,reg,basereg,disp) \
1025     do { \
1026     *(inst)++ = (unsigned char)0x8d; \
1027     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
1028     } while (0)
1029    
1030     #define x86_lea_memindex(inst,reg,basereg,disp,indexreg,shift) \
1031     do { \
1032     *(inst)++ = (unsigned char)0x8d; \
1033     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
1034     } while (0)
1035    
1036     #define x86_widen_reg(inst,dreg,reg,is_signed,is_half) \
1037     do { \
1038     unsigned char op = 0xb6; \
1039     g_assert (is_half || X86_IS_BYTE_REG (reg)); \
1040     *(inst)++ = (unsigned char)0x0f; \
1041     if ((is_signed)) op += 0x08; \
1042     if ((is_half)) op += 0x01; \
1043     *(inst)++ = op; \
1044     x86_reg_emit ((inst), (dreg), (reg)); \
1045     } while (0)
1046    
1047     #define x86_widen_mem(inst,dreg,mem,is_signed,is_half) \
1048     do { \
1049     unsigned char op = 0xb6; \
1050     *(inst)++ = (unsigned char)0x0f; \
1051     if ((is_signed)) op += 0x08; \
1052     if ((is_half)) op += 0x01; \
1053     *(inst)++ = op; \
1054     x86_mem_emit ((inst), (dreg), (mem)); \
1055     } while (0)
1056    
1057     #define x86_widen_membase(inst,dreg,basereg,disp,is_signed,is_half) \
1058     do { \
1059     unsigned char op = 0xb6; \
1060     *(inst)++ = (unsigned char)0x0f; \
1061     if ((is_signed)) op += 0x08; \
1062     if ((is_half)) op += 0x01; \
1063     *(inst)++ = op; \
1064     x86_membase_emit ((inst), (dreg), (basereg), (disp)); \
1065     } while (0)
1066    
1067     #define x86_widen_memindex(inst,dreg,basereg,disp,indexreg,shift,is_signed,is_half) \
1068     do { \
1069     unsigned char op = 0xb6; \
1070     *(inst)++ = (unsigned char)0x0f; \
1071     if ((is_signed)) op += 0x08; \
1072     if ((is_half)) op += 0x01; \
1073     *(inst)++ = op; \
1074     x86_memindex_emit ((inst), (dreg), (basereg), (disp), (indexreg), (shift)); \
1075     } while (0)
1076    
1077     #define x86_cdq(inst) do { *(inst)++ = (unsigned char)0x99; } while (0)
1078     #define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
1079    
1080     #define x86_fp_op_mem(inst,opc,mem,is_double) \
1081     do { \
1082     *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8; \
1083     x86_mem_emit ((inst), (opc), (mem)); \
1084     } while (0)
1085    
1086     #define x86_fp_op_membase(inst,opc,basereg,disp,is_double) \
1087     do { \
1088     *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8; \
1089     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
1090     } while (0)
1091    
1092     #define x86_fp_op(inst,opc,index) \
1093     do { \
1094     *(inst)++ = (unsigned char)0xd8; \
1095     *(inst)++ = (unsigned char)0xc0+((opc)<<3)+((index)&0x07); \
1096     } while (0)
1097    
1098     #define x86_fp_op_reg(inst,opc,index,pop_stack) \
1099     do { \
1100     static const unsigned char map[] = { 0, 1, 2, 3, 5, 4, 7, 6, 8}; \
1101     *(inst)++ = (pop_stack) ? (unsigned char)0xde : (unsigned char)0xdc; \
1102     *(inst)++ = (unsigned char)0xc0+(map[(opc)]<<3)+((index)&0x07); \
1103     } while (0)
1104    
1105     /**
1106     * @x86_fp_int_op_membase
1107     * Supports FPU operations between ST(0) and integer operand in memory.
1108     * Operation encoded using X86_FP_Opcode enum.
1109     * Operand is addressed by [basereg + disp].
1110     * is_int specifies whether operand is int32 (TRUE) or int16 (FALSE).
1111     */
1112     #define x86_fp_int_op_membase(inst,opc,basereg,disp,is_int) \
1113     do { \
1114     *(inst)++ = (is_int) ? (unsigned char)0xda : (unsigned char)0xde; \
1115     x86_membase_emit ((inst), opc, (basereg), (disp)); \
1116     } while (0)
1117    
1118     #define x86_fstp(inst,index) \
1119     do { \
1120     *(inst)++ = (unsigned char)0xdd; \
1121     *(inst)++ = (unsigned char)0xd8+(index); \
1122     } while (0)
1123    
1124     #define x86_fcompp(inst) \
1125     do { \
1126     *(inst)++ = (unsigned char)0xde; \
1127     *(inst)++ = (unsigned char)0xd9; \
1128     } while (0)
1129    
1130     #define x86_fucompp(inst) \
1131     do { \
1132     *(inst)++ = (unsigned char)0xda; \
1133     *(inst)++ = (unsigned char)0xe9; \
1134     } while (0)
1135    
1136     #define x86_fnstsw(inst) \
1137     do { \
1138     *(inst)++ = (unsigned char)0xdf; \
1139     *(inst)++ = (unsigned char)0xe0; \
1140     } while (0)
1141    
1142     #define x86_fnstcw(inst,mem) \
1143     do { \
1144     *(inst)++ = (unsigned char)0xd9; \
1145     x86_mem_emit ((inst), 7, (mem)); \
1146     } while (0)
1147    
1148     #define x86_fnstcw_membase(inst,basereg,disp) \
1149     do { \
1150     *(inst)++ = (unsigned char)0xd9; \
1151     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1152     } while (0)
1153    
1154     #define x86_fldcw(inst,mem) \
1155     do { \
1156     *(inst)++ = (unsigned char)0xd9; \
1157     x86_mem_emit ((inst), 5, (mem)); \
1158     } while (0)
1159    
1160     #define x86_fldcw_membase(inst,basereg,disp) \
1161     do { \
1162     *(inst)++ = (unsigned char)0xd9; \
1163     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1164     } while (0)
1165    
1166     #define x86_fchs(inst) \
1167     do { \
1168     *(inst)++ = (unsigned char)0xd9; \
1169     *(inst)++ = (unsigned char)0xe0; \
1170     } while (0)
1171    
1172     #define x86_frem(inst) \
1173     do { \
1174     *(inst)++ = (unsigned char)0xd9; \
1175     *(inst)++ = (unsigned char)0xf8; \
1176     } while (0)
1177    
1178     #define x86_fxch(inst,index) \
1179     do { \
1180     *(inst)++ = (unsigned char)0xd9; \
1181     *(inst)++ = (unsigned char)0xc8 + ((index) & 0x07); \
1182     } while (0)
1183    
1184     #define x86_fcomi(inst,index) \
1185     do { \
1186     *(inst)++ = (unsigned char)0xdb; \
1187     *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07); \
1188     } while (0)
1189    
1190     #define x86_fcomip(inst,index) \
1191     do { \
1192     *(inst)++ = (unsigned char)0xdf; \
1193     *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07); \
1194     } while (0)
1195    
1196     #define x86_fucomi(inst,index) \
1197     do { \
1198     *(inst)++ = (unsigned char)0xdb; \
1199     *(inst)++ = (unsigned char)0xe8 + ((index) & 0x07); \
1200     } while (0)
1201    
1202     #define x86_fucomip(inst,index) \
1203     do { \
1204     *(inst)++ = (unsigned char)0xdf; \
1205     *(inst)++ = (unsigned char)0xe8 + ((index) & 0x07); \
1206     } while (0)
1207    
1208     #define x86_fld(inst,mem,is_double) \
1209     do { \
1210     *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
1211     x86_mem_emit ((inst), 0, (mem)); \
1212     } while (0)
1213    
1214     #define x86_fld_membase(inst,basereg,disp,is_double) \
1215     do { \
1216     *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
1217     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1218     } while (0)
1219    
1220     #define x86_fld80_mem(inst,mem) \
1221     do { \
1222     *(inst)++ = (unsigned char)0xdb; \
1223     x86_mem_emit ((inst), 5, (mem)); \
1224     } while (0)
1225    
1226     #define x86_fld80_membase(inst,basereg,disp) \
1227     do { \
1228     *(inst)++ = (unsigned char)0xdb; \
1229     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1230     } while (0)
1231    
1232     #define x86_fild(inst,mem,is_long) \
1233     do { \
1234     if ((is_long)) { \
1235     *(inst)++ = (unsigned char)0xdf; \
1236     x86_mem_emit ((inst), 5, (mem)); \
1237     } else { \
1238     *(inst)++ = (unsigned char)0xdb; \
1239     x86_mem_emit ((inst), 0, (mem)); \
1240     } \
1241     } while (0)
1242    
1243     #define x86_fild_membase(inst,basereg,disp,is_long) \
1244     do { \
1245     if ((is_long)) { \
1246     *(inst)++ = (unsigned char)0xdf; \
1247     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1248     } else { \
1249     *(inst)++ = (unsigned char)0xdb; \
1250     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1251     } \
1252     } while (0)
1253    
1254     #define x86_fld_reg(inst,index) \
1255     do { \
1256     *(inst)++ = (unsigned char)0xd9; \
1257     *(inst)++ = (unsigned char)0xc0 + ((index) & 0x07); \
1258     } while (0)
1259    
1260     #define x86_fldz(inst) \
1261     do { \
1262     *(inst)++ = (unsigned char)0xd9; \
1263     *(inst)++ = (unsigned char)0xee; \
1264     } while (0)
1265    
1266     #define x86_fld1(inst) \
1267     do { \
1268     *(inst)++ = (unsigned char)0xd9; \
1269     *(inst)++ = (unsigned char)0xe8; \
1270     } while (0)
1271    
1272     #define x86_fldpi(inst) \
1273     do { \
1274     *(inst)++ = (unsigned char)0xd9; \
1275     *(inst)++ = (unsigned char)0xeb; \
1276     } while (0)
1277    
1278     #define x86_fst(inst,mem,is_double,pop_stack) \
1279     do { \
1280     *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
1281     x86_mem_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (mem)); \
1282     } while (0)
1283    
1284     #define x86_fst_membase(inst,basereg,disp,is_double,pop_stack) \
1285     do { \
1286     *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
1287     x86_membase_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (basereg), (disp)); \
1288     } while (0)
1289    
1290     #define x86_fst80_mem(inst,mem) \
1291     do { \
1292     *(inst)++ = (unsigned char)0xdb; \
1293     x86_mem_emit ((inst), 7, (mem)); \
1294     } while (0)
1295    
1296    
1297     #define x86_fst80_membase(inst,basereg,disp) \
1298     do { \
1299     *(inst)++ = (unsigned char)0xdb; \
1300     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1301     } while (0)
1302    
1303    
1304     #define x86_fist_pop(inst,mem,is_long) \
1305     do { \
1306     if ((is_long)) { \
1307     *(inst)++ = (unsigned char)0xdf; \
1308     x86_mem_emit ((inst), 7, (mem)); \
1309     } else { \
1310     *(inst)++ = (unsigned char)0xdb; \
1311     x86_mem_emit ((inst), 3, (mem)); \
1312     } \
1313     } while (0)
1314    
1315     #define x86_fist_pop_membase(inst,basereg,disp,is_long) \
1316     do { \
1317     if ((is_long)) { \
1318     *(inst)++ = (unsigned char)0xdf; \
1319     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1320     } else { \
1321     *(inst)++ = (unsigned char)0xdb; \
1322     x86_membase_emit ((inst), 3, (basereg), (disp)); \
1323     } \
1324     } while (0)
1325    
1326     #define x86_fstsw(inst) \
1327     do { \
1328     *(inst)++ = (unsigned char)0x9b; \
1329     *(inst)++ = (unsigned char)0xdf; \
1330     *(inst)++ = (unsigned char)0xe0; \
1331     } while (0)
1332    
1333     /**
1334     * @x86_fist_membase
1335     * Converts content of ST(0) to integer and stores it at memory location
1336     * addressed by [basereg + disp].
1337     * is_int specifies whether destination is int32 (TRUE) or int16 (FALSE).
1338     */
1339     #define x86_fist_membase(inst,basereg,disp,is_int) \
1340     do { \
1341     if ((is_int)) { \
1342     *(inst)++ = (unsigned char)0xdb; \
1343     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1344     } else { \
1345     *(inst)++ = (unsigned char)0xdf; \
1346     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1347     } \
1348     } while (0)
1349    
1350    
1351     #define x86_push_reg(inst,reg) \
1352     do { \
1353     *(inst)++ = (unsigned char)0x50 + (reg); \
1354     } while (0)
1355    
1356     #define x86_push_regp(inst,reg) \
1357     do { \
1358     *(inst)++ = (unsigned char)0xff; \
1359     x86_regp_emit ((inst), 6, (reg)); \
1360     } while (0)
1361    
1362     #define x86_push_mem(inst,mem) \
1363     do { \
1364     *(inst)++ = (unsigned char)0xff; \
1365     x86_mem_emit ((inst), 6, (mem)); \
1366     } while (0)
1367    
1368     #define x86_push_membase(inst,basereg,disp) \
1369     do { \
1370     *(inst)++ = (unsigned char)0xff; \
1371     x86_membase_emit ((inst), 6, (basereg), (disp)); \
1372     } while (0)
1373    
1374     #define x86_push_memindex(inst,basereg,disp,indexreg,shift) \
1375     do { \
1376     *(inst)++ = (unsigned char)0xff; \
1377     x86_memindex_emit ((inst), 6, (basereg), (disp), (indexreg), (shift)); \
1378     } while (0)
1379    
1380     #define x86_push_imm_template(inst) x86_push_imm (inst, 0xf0f0f0f0)
1381    
1382     #define x86_push_imm(inst,imm) \
1383     do { \
1384     int _imm = (int) (imm); \
1385     if (x86_is_imm8 (_imm)) { \
1386     *(inst)++ = (unsigned char)0x6A; \
1387     x86_imm_emit8 ((inst), (_imm)); \
1388     } else { \
1389     *(inst)++ = (unsigned char)0x68; \
1390     x86_imm_emit32 ((inst), (_imm)); \
1391     } \
1392     } while (0)
1393    
1394     #define x86_pop_reg(inst,reg) \
1395     do { \
1396     *(inst)++ = (unsigned char)0x58 + (reg); \
1397     } while (0)
1398    
1399     #define x86_pop_mem(inst,mem) \
1400     do { \
1401     *(inst)++ = (unsigned char)0x87; \
1402     x86_mem_emit ((inst), 0, (mem)); \
1403     } while (0)
1404    
1405     #define x86_pop_membase(inst,basereg,disp) \
1406     do { \
1407     *(inst)++ = (unsigned char)0x87; \
1408     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1409     } while (0)
1410    
1411     #define x86_pushad(inst) do { *(inst)++ = (unsigned char)0x60; } while (0)
1412     #define x86_pushfd(inst) do { *(inst)++ = (unsigned char)0x9c; } while (0)
1413     #define x86_popad(inst) do { *(inst)++ = (unsigned char)0x61; } while (0)
1414     #define x86_popfd(inst) do { *(inst)++ = (unsigned char)0x9d; } while (0)
1415    
1416     #define x86_loop(inst,imm) \
1417     do { \
1418     *(inst)++ = (unsigned char)0xe2; \
1419     x86_imm_emit8 ((inst), (imm)); \
1420     } while (0)
1421    
1422     #define x86_loope(inst,imm) \
1423     do { \
1424     *(inst)++ = (unsigned char)0xe1; \
1425     x86_imm_emit8 ((inst), (imm)); \
1426     } while (0)
1427    
1428     #define x86_loopne(inst,imm) \
1429     do { \
1430     *(inst)++ = (unsigned char)0xe0; \
1431     x86_imm_emit8 ((inst), (imm)); \
1432     } while (0)
1433    
1434     #define x86_jump32(inst,imm) \
1435     do { \
1436     *(inst)++ = (unsigned char)0xe9; \
1437     x86_imm_emit32 ((inst), (imm)); \
1438     } while (0)
1439    
1440     #define x86_jump8(inst,imm) \
1441     do { \
1442     *(inst)++ = (unsigned char)0xeb; \
1443     x86_imm_emit8 ((inst), (imm)); \
1444     } while (0)
1445    
1446     #define x86_jump_reg(inst,reg) \
1447     do { \
1448     *(inst)++ = (unsigned char)0xff; \
1449     x86_reg_emit ((inst), 4, (reg)); \
1450     } while (0)
1451    
1452     #define x86_jump_mem(inst,mem) \
1453     do { \
1454     *(inst)++ = (unsigned char)0xff; \
1455     x86_mem_emit ((inst), 4, (mem)); \
1456     } while (0)
1457    
1458     #define x86_jump_membase(inst,basereg,disp) \
1459     do { \
1460     *(inst)++ = (unsigned char)0xff; \
1461     x86_membase_emit ((inst), 4, (basereg), (disp)); \
1462     } while (0)
1463    
1464     /*
1465     * target is a pointer in our buffer.
1466     */
1467     #define x86_jump_code(inst,target) \
1468     do { \
1469     int t = (unsigned char*)(target) - (inst) - 2; \
1470     if (x86_is_imm8(t)) { \
1471     x86_jump8 ((inst), t); \
1472     } else { \
1473     t -= 3; \
1474     x86_jump32 ((inst), t); \
1475     } \
1476     } while (0)
1477    
1478     #define x86_jump_disp(inst,disp) \
1479     do { \
1480     int t = (disp) - 2; \
1481     if (x86_is_imm8(t)) { \
1482     x86_jump8 ((inst), t); \
1483     } else { \
1484     t -= 3; \
1485     x86_jump32 ((inst), t); \
1486     } \
1487     } while (0)
1488    
1489     #define x86_branch8(inst,cond,imm,is_signed) \
1490     do { \
1491     if ((is_signed)) \
1492     *(inst)++ = x86_cc_signed_map [(cond)]; \
1493     else \
1494     *(inst)++ = x86_cc_unsigned_map [(cond)]; \
1495     x86_imm_emit8 ((inst), (imm)); \
1496     } while (0)
1497    
1498     #define x86_branch32(inst,cond,imm,is_signed) \
1499     do { \
1500     *(inst)++ = (unsigned char)0x0f; \
1501     if ((is_signed)) \
1502     *(inst)++ = x86_cc_signed_map [(cond)] + 0x10; \
1503     else \
1504     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x10; \
1505     x86_imm_emit32 ((inst), (imm)); \
1506     } while (0)
1507    
1508     #define x86_branch(inst,cond,target,is_signed) \
1509     do { \
1510     int offset = (target) - (inst) - 2; \
1511     if (x86_is_imm8 ((offset))) \
1512     x86_branch8 ((inst), (cond), offset, (is_signed)); \
1513     else { \
1514     offset -= 4; \
1515     x86_branch32 ((inst), (cond), offset, (is_signed)); \
1516     } \
1517     } while (0)
1518    
1519     #define x86_branch_disp(inst,cond,disp,is_signed) \
1520     do { \
1521     int offset = (disp) - 2; \
1522     if (x86_is_imm8 ((offset))) \
1523     x86_branch8 ((inst), (cond), offset, (is_signed)); \
1524     else { \
1525     offset -= 4; \
1526     x86_branch32 ((inst), (cond), offset, (is_signed)); \
1527     } \
1528     } while (0)
1529    
1530     #define x86_set_reg(inst,cond,reg,is_signed) \
1531     do { \
1532     g_assert (X86_IS_BYTE_REG (reg)); \
1533     *(inst)++ = (unsigned char)0x0f; \
1534     if ((is_signed)) \
1535     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1536     else \
1537     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1538     x86_reg_emit ((inst), 0, (reg)); \
1539     } while (0)
1540    
1541     #define x86_set_mem(inst,cond,mem,is_signed) \
1542     do { \
1543     *(inst)++ = (unsigned char)0x0f; \
1544     if ((is_signed)) \
1545     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1546     else \
1547     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1548     x86_mem_emit ((inst), 0, (mem)); \
1549     } while (0)
1550    
1551     #define x86_set_membase(inst,cond,basereg,disp,is_signed) \
1552     do { \
1553     *(inst)++ = (unsigned char)0x0f; \
1554     if ((is_signed)) \
1555     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1556     else \
1557     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1558     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1559     } while (0)
1560    
1561     #define x86_call_imm(inst,disp) \
1562     do { \
1563     *(inst)++ = (unsigned char)0xe8; \
1564     x86_imm_emit32 ((inst), (int)(disp)); \
1565     } while (0)
1566    
1567     #define x86_call_reg(inst,reg) \
1568     do { \
1569     *(inst)++ = (unsigned char)0xff; \
1570     x86_reg_emit ((inst), 2, (reg)); \
1571     } while (0)
1572    
1573     #define x86_call_mem(inst,mem) \
1574     do { \
1575     *(inst)++ = (unsigned char)0xff; \
1576     x86_mem_emit ((inst), 2, (mem)); \
1577     } while (0)
1578    
1579     #define x86_call_membase(inst,basereg,disp) \
1580     do { \
1581     *(inst)++ = (unsigned char)0xff; \
1582     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1583     } while (0)
1584    
1585     #define x86_call_code(inst,target) \
1586     do { \
1587     int _x86_offset = (unsigned char*)(target) - (inst); \
1588     _x86_offset -= 5; \
1589     x86_call_imm ((inst), _x86_offset); \
1590     } while (0)
1591    
1592     #define x86_ret(inst) do { *(inst)++ = (unsigned char)0xc3; } while (0)
1593    
1594     #define x86_ret_imm(inst,imm) \
1595     do { \
1596     if ((imm) == 0) { \
1597     x86_ret ((inst)); \
1598     } else { \
1599     *(inst)++ = (unsigned char)0xc2; \
1600     x86_imm_emit16 ((inst), (imm)); \
1601     } \
1602     } while (0)
1603    
1604     #define x86_cmov_reg(inst,cond,is_signed,dreg,reg) \
1605     do { \
1606     *(inst)++ = (unsigned char) 0x0f; \
1607     if ((is_signed)) \
1608     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1609     else \
1610     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1611     x86_reg_emit ((inst), (dreg), (reg)); \
1612     } while (0)
1613    
1614     #define x86_cmov_mem(inst,cond,is_signed,reg,mem) \
1615     do { \
1616     *(inst)++ = (unsigned char) 0x0f; \
1617     if ((is_signed)) \
1618     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1619     else \
1620     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1621     x86_mem_emit ((inst), (reg), (mem)); \
1622     } while (0)
1623    
1624     #define x86_cmov_membase(inst,cond,is_signed,reg,basereg,disp) \
1625     do { \
1626     *(inst)++ = (unsigned char) 0x0f; \
1627     if ((is_signed)) \
1628     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1629     else \
1630     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1631     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
1632     } while (0)
1633    
1634     #define x86_enter(inst,framesize) \
1635     do { \
1636     *(inst)++ = (unsigned char)0xc8; \
1637     x86_imm_emit16 ((inst), (framesize)); \
1638     *(inst)++ = 0; \
1639     } while (0)
1640    
1641     #define x86_leave(inst) do { *(inst)++ = (unsigned char)0xc9; } while (0)
1642     #define x86_sahf(inst) do { *(inst)++ = (unsigned char)0x9e; } while (0)
1643    
1644     #define x86_fsin(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfe; } while (0)
1645     #define x86_fcos(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xff; } while (0)
1646     #define x86_fabs(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe1; } while (0)
1647     #define x86_ftst(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe4; } while (0)
1648     #define x86_fxam(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe5; } while (0)
1649     #define x86_fpatan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf3; } while (0)
1650     #define x86_fprem(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf8; } while (0)
1651     #define x86_fprem1(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf5; } while (0)
1652     #define x86_frndint(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfc; } while (0)
1653     #define x86_fsqrt(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfa; } while (0)
1654     #define x86_fptan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf2; } while (0)
1655    
1656     #define x86_padding(inst,size) \
1657     do { \
1658     switch ((size)) { \
1659     case 1: x86_nop ((inst)); break; \
1660     case 2: *(inst)++ = 0x8b; \
1661     *(inst)++ = 0xc0; break; \
1662     case 3: *(inst)++ = 0x8d; *(inst)++ = 0x6d; \
1663     *(inst)++ = 0x00; break; \
1664     case 4: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
1665     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1666     break; \
1667     case 5: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
1668     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1669     x86_nop ((inst)); break; \
1670     case 6: *(inst)++ = 0x8d; *(inst)++ = 0xad; \
1671     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1672     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1673     break; \
1674     case 7: *(inst)++ = 0x8d; *(inst)++ = 0xa4; \
1675     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1676     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1677     *(inst)++ = 0x00; break; \
1678     default: assert (0); \
1679     } \
1680     } while (0)
1681    
1682     #define x86_prolog(inst,frame_size,reg_mask) \
1683     do { \
1684     unsigned i, m = 1; \
1685     x86_enter ((inst), (frame_size)); \
1686     for (i = 0; i < X86_NREG; ++i, m <<= 1) { \
1687     if ((reg_mask) & m) \
1688     x86_push_reg ((inst), i); \
1689     } \
1690     } while (0)
1691    
1692     #define x86_epilog(inst,reg_mask) \
1693     do { \
1694     unsigned i, m = 1 << X86_EDI; \
1695     for (i = X86_EDI; m != 0; i--, m=m>>1) { \
1696     if ((reg_mask) & m) \
1697     x86_pop_reg ((inst), i); \
1698     } \
1699     x86_leave ((inst)); \
1700     x86_ret ((inst)); \
1701     } while (0)
1702    
1703     #endif // X86_H

  ViewVC Help
Powered by ViewVC 1.1.26