/[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 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/x86-codegen.h
File MIME type: text/plain
File size: 47599 byte(s)
dynamips-0.2.7-RC1

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 dpavlin 7 #define x86_clc(inst) do { *(inst)++ =(unsigned char)0xf8; } while (0)
363 dpavlin 1 #define x86_cld(inst) do { *(inst)++ =(unsigned char)0xfc; } while (0)
364     #define x86_stosb(inst) do { *(inst)++ =(unsigned char)0xaa; } while (0)
365     #define x86_stosl(inst) do { *(inst)++ =(unsigned char)0xab; } while (0)
366     #define x86_stosd(inst) x86_stosl((inst))
367     #define x86_movsb(inst) do { *(inst)++ =(unsigned char)0xa4; } while (0)
368     #define x86_movsl(inst) do { *(inst)++ =(unsigned char)0xa5; } while (0)
369     #define x86_movsd(inst) x86_movsl((inst))
370    
371     #define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while (0)
372    
373     #define x86_bswap(inst,reg) \
374     do { \
375     *(inst)++ = 0x0f; \
376     *(inst)++ = (unsigned char)0xc8 + (reg); \
377     } while (0)
378    
379     #define x86_rdtsc(inst) \
380     do { \
381     *(inst)++ = 0x0f; \
382     *(inst)++ = 0x31; \
383     } while (0)
384    
385     #define x86_cmpxchg_reg_reg(inst,dreg,reg) \
386     do { \
387     *(inst)++ = (unsigned char)0x0f; \
388     *(inst)++ = (unsigned char)0xb1; \
389     x86_reg_emit ((inst), (reg), (dreg)); \
390     } while (0)
391    
392     #define x86_cmpxchg_mem_reg(inst,mem,reg) \
393     do { \
394     *(inst)++ = (unsigned char)0x0f; \
395     *(inst)++ = (unsigned char)0xb1; \
396     x86_mem_emit ((inst), (reg), (mem)); \
397     } while (0)
398    
399     #define x86_cmpxchg_membase_reg(inst,basereg,disp,reg) \
400     do { \
401     *(inst)++ = (unsigned char)0x0f; \
402     *(inst)++ = (unsigned char)0xb1; \
403     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
404     } while (0)
405    
406     #define x86_xchg_reg_reg(inst,dreg,reg,size) \
407     do { \
408     if ((size) == 1) \
409     *(inst)++ = (unsigned char)0x86; \
410     else \
411     *(inst)++ = (unsigned char)0x87; \
412     x86_reg_emit ((inst), (reg), (dreg)); \
413     } while (0)
414    
415     #define x86_xchg_mem_reg(inst,mem,reg,size) \
416     do { \
417     if ((size) == 1) \
418     *(inst)++ = (unsigned char)0x86; \
419     else \
420     *(inst)++ = (unsigned char)0x87; \
421     x86_mem_emit ((inst), (reg), (mem)); \
422     } while (0)
423    
424     #define x86_xchg_membase_reg(inst,basereg,disp,reg,size) \
425     do { \
426     if ((size) == 1) \
427     *(inst)++ = (unsigned char)0x86; \
428     else \
429     *(inst)++ = (unsigned char)0x87; \
430     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
431     } while (0)
432    
433     #define x86_xadd_reg_reg(inst,dreg,reg,size) \
434     do { \
435     *(inst)++ = (unsigned char)0x0F; \
436     if ((size) == 1) \
437     *(inst)++ = (unsigned char)0xC0; \
438     else \
439     *(inst)++ = (unsigned char)0xC1; \
440     x86_reg_emit ((inst), (reg), (dreg)); \
441     } while (0)
442    
443     #define x86_xadd_mem_reg(inst,mem,reg,size) \
444     do { \
445     *(inst)++ = (unsigned char)0x0F; \
446     if ((size) == 1) \
447     *(inst)++ = (unsigned char)0xC0; \
448     else \
449     *(inst)++ = (unsigned char)0xC1; \
450     x86_mem_emit ((inst), (reg), (mem)); \
451     } while (0)
452    
453     #define x86_xadd_membase_reg(inst,basereg,disp,reg,size) \
454     do { \
455     *(inst)++ = (unsigned char)0x0F; \
456     if ((size) == 1) \
457     *(inst)++ = (unsigned char)0xC0; \
458     else \
459     *(inst)++ = (unsigned char)0xC1; \
460     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
461     } while (0)
462    
463     #define x86_inc_mem(inst,mem) \
464     do { \
465     *(inst)++ = (unsigned char)0xff; \
466     x86_mem_emit ((inst), 0, (mem)); \
467     } while (0)
468    
469     #define x86_inc_membase(inst,basereg,disp) \
470     do { \
471     *(inst)++ = (unsigned char)0xff; \
472     x86_membase_emit ((inst), 0, (basereg), (disp)); \
473     } while (0)
474    
475     #define x86_inc_reg(inst,reg) do { *(inst)++ = (unsigned char)0x40 + (reg); } while (0)
476    
477     #define x86_dec_mem(inst,mem) \
478     do { \
479     *(inst)++ = (unsigned char)0xff; \
480     x86_mem_emit ((inst), 1, (mem)); \
481     } while (0)
482    
483     #define x86_dec_membase(inst,basereg,disp) \
484     do { \
485     *(inst)++ = (unsigned char)0xff; \
486     x86_membase_emit ((inst), 1, (basereg), (disp)); \
487     } while (0)
488    
489     #define x86_dec_reg(inst,reg) do { *(inst)++ = (unsigned char)0x48 + (reg); } while (0)
490    
491     #define x86_not_mem(inst,mem) \
492     do { \
493     *(inst)++ = (unsigned char)0xf7; \
494     x86_mem_emit ((inst), 2, (mem)); \
495     } while (0)
496    
497     #define x86_not_membase(inst,basereg,disp) \
498     do { \
499     *(inst)++ = (unsigned char)0xf7; \
500     x86_membase_emit ((inst), 2, (basereg), (disp)); \
501     } while (0)
502    
503     #define x86_not_reg(inst,reg) \
504     do { \
505     *(inst)++ = (unsigned char)0xf7; \
506     x86_reg_emit ((inst), 2, (reg)); \
507     } while (0)
508    
509     #define x86_neg_mem(inst,mem) \
510     do { \
511     *(inst)++ = (unsigned char)0xf7; \
512     x86_mem_emit ((inst), 3, (mem)); \
513     } while (0)
514    
515     #define x86_neg_membase(inst,basereg,disp) \
516     do { \
517     *(inst)++ = (unsigned char)0xf7; \
518     x86_membase_emit ((inst), 3, (basereg), (disp)); \
519     } while (0)
520    
521     #define x86_neg_reg(inst,reg) \
522     do { \
523     *(inst)++ = (unsigned char)0xf7; \
524     x86_reg_emit ((inst), 3, (reg)); \
525     } while (0)
526    
527     #define x86_nop(inst) do { *(inst)++ = (unsigned char)0x90; } while (0)
528    
529     #define x86_alu_reg_imm(inst,opc,reg,imm) \
530     do { \
531     if ((reg) == X86_EAX) { \
532     *(inst)++ = (((unsigned char)(opc)) << 3) + 5; \
533     x86_imm_emit32 ((inst), (imm)); \
534     break; \
535     } \
536     if (x86_is_imm8((imm))) { \
537     *(inst)++ = (unsigned char)0x83; \
538     x86_reg_emit ((inst), (opc), (reg)); \
539     x86_imm_emit8 ((inst), (imm)); \
540     } else { \
541     *(inst)++ = (unsigned char)0x81; \
542     x86_reg_emit ((inst), (opc), (reg)); \
543     x86_imm_emit32 ((inst), (imm)); \
544     } \
545     } while (0)
546    
547     #define x86_alu_mem_imm(inst,opc,mem,imm) \
548     do { \
549     if (x86_is_imm8((imm))) { \
550     *(inst)++ = (unsigned char)0x83; \
551     x86_mem_emit ((inst), (opc), (mem)); \
552     x86_imm_emit8 ((inst), (imm)); \
553     } else { \
554     *(inst)++ = (unsigned char)0x81; \
555     x86_mem_emit ((inst), (opc), (mem)); \
556     x86_imm_emit32 ((inst), (imm)); \
557     } \
558     } while (0)
559    
560     #define x86_alu_membase_imm(inst,opc,basereg,disp,imm) \
561     do { \
562     if (x86_is_imm8((imm))) { \
563     *(inst)++ = (unsigned char)0x83; \
564     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
565     x86_imm_emit8 ((inst), (imm)); \
566     } else { \
567     *(inst)++ = (unsigned char)0x81; \
568     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
569     x86_imm_emit32 ((inst), (imm)); \
570     } \
571     } while (0)
572    
573     #define x86_alu_membase8_imm(inst,opc,basereg,disp,imm) \
574     do { \
575     *(inst)++ = (unsigned char)0x80; \
576     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
577     x86_imm_emit8 ((inst), (imm)); \
578     } while (0)
579    
580     #define x86_alu_mem_reg(inst,opc,mem,reg) \
581     do { \
582     *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
583     x86_mem_emit ((inst), (reg), (mem)); \
584     } while (0)
585    
586     #define x86_alu_membase_reg(inst,opc,basereg,disp,reg) \
587     do { \
588     *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
589     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
590     } while (0)
591    
592     #define x86_alu_reg_reg(inst,opc,dreg,reg) \
593     do { \
594     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
595     x86_reg_emit ((inst), (dreg), (reg)); \
596     } while (0)
597    
598     /**
599     * @x86_alu_reg8_reg8:
600     * Supports ALU operations between two 8-bit registers.
601     * dreg := dreg opc reg
602     * X86_Reg_No enum is used to specify the registers.
603     * Additionally is_*_h flags are used to specify what part
604     * of a given 32-bit register is used - high (TRUE) or low (FALSE).
605     * For example: dreg = X86_EAX, is_dreg_h = TRUE -> use AH
606     */
607     #define x86_alu_reg8_reg8(inst,opc,dreg,reg,is_dreg_h,is_reg_h) \
608     do { \
609     *(inst)++ = (((unsigned char)(opc)) << 3) + 2; \
610     x86_reg8_emit ((inst), (dreg), (reg), (is_dreg_h), (is_reg_h)); \
611     } while (0)
612    
613     #define x86_alu_reg_mem(inst,opc,reg,mem) \
614     do { \
615     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
616     x86_mem_emit ((inst), (reg), (mem)); \
617     } while (0)
618    
619     #define x86_alu_reg_membase(inst,opc,reg,basereg,disp) \
620     do { \
621     *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
622     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
623     } while (0)
624    
625     #define x86_test_reg_imm(inst,reg,imm) \
626     do { \
627     if ((reg) == X86_EAX) { \
628     *(inst)++ = (unsigned char)0xa9; \
629     } else { \
630     *(inst)++ = (unsigned char)0xf7; \
631     x86_reg_emit ((inst), 0, (reg)); \
632     } \
633     x86_imm_emit32 ((inst), (imm)); \
634     } while (0)
635    
636     #define x86_test_mem_imm(inst,mem,imm) \
637     do { \
638     *(inst)++ = (unsigned char)0xf7; \
639     x86_mem_emit ((inst), 0, (mem)); \
640     x86_imm_emit32 ((inst), (imm)); \
641     } while (0)
642    
643     #define x86_test_membase_imm(inst,basereg,disp,imm) \
644     do { \
645     *(inst)++ = (unsigned char)0xf7; \
646     x86_membase_emit ((inst), 0, (basereg), (disp)); \
647     x86_imm_emit32 ((inst), (imm)); \
648     } while (0)
649    
650     #define x86_test_reg_reg(inst,dreg,reg) \
651     do { \
652     *(inst)++ = (unsigned char)0x85; \
653     x86_reg_emit ((inst), (reg), (dreg)); \
654     } while (0)
655    
656     #define x86_test_mem_reg(inst,mem,reg) \
657     do { \
658     *(inst)++ = (unsigned char)0x85; \
659     x86_mem_emit ((inst), (reg), (mem)); \
660     } while (0)
661    
662     #define x86_test_membase_reg(inst,basereg,disp,reg) \
663     do { \
664     *(inst)++ = (unsigned char)0x85; \
665     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
666     } while (0)
667    
668     #define x86_shift_reg_imm(inst,opc,reg,imm) \
669     do { \
670     if ((imm) == 1) { \
671     *(inst)++ = (unsigned char)0xd1; \
672     x86_reg_emit ((inst), (opc), (reg)); \
673     } else { \
674     *(inst)++ = (unsigned char)0xc1; \
675     x86_reg_emit ((inst), (opc), (reg)); \
676     x86_imm_emit8 ((inst), (imm)); \
677     } \
678     } while (0)
679    
680     #define x86_shift_mem_imm(inst,opc,mem,imm) \
681     do { \
682     if ((imm) == 1) { \
683     *(inst)++ = (unsigned char)0xd1; \
684     x86_mem_emit ((inst), (opc), (mem)); \
685     } else { \
686     *(inst)++ = (unsigned char)0xc1; \
687     x86_mem_emit ((inst), (opc), (mem)); \
688     x86_imm_emit8 ((inst), (imm)); \
689     } \
690     } while (0)
691    
692     #define x86_shift_membase_imm(inst,opc,basereg,disp,imm) \
693     do { \
694     if ((imm) == 1) { \
695     *(inst)++ = (unsigned char)0xd1; \
696     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
697     } else { \
698     *(inst)++ = (unsigned char)0xc1; \
699     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
700     x86_imm_emit8 ((inst), (imm)); \
701     } \
702     } while (0)
703    
704     #define x86_shift_reg(inst,opc,reg) \
705     do { \
706     *(inst)++ = (unsigned char)0xd3; \
707     x86_reg_emit ((inst), (opc), (reg)); \
708     } while (0)
709    
710     #define x86_shift_mem(inst,opc,mem) \
711     do { \
712     *(inst)++ = (unsigned char)0xd3; \
713     x86_mem_emit ((inst), (opc), (mem)); \
714     } while (0)
715    
716     #define x86_shift_membase(inst,opc,basereg,disp) \
717     do { \
718     *(inst)++ = (unsigned char)0xd3; \
719     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
720     } while (0)
721    
722     /*
723     * Multi op shift missing.
724     */
725    
726     #define x86_shrd_reg(inst,dreg,reg) \
727     do { \
728     *(inst)++ = (unsigned char)0x0f; \
729     *(inst)++ = (unsigned char)0xad; \
730     x86_reg_emit ((inst), (reg), (dreg)); \
731     } while (0)
732    
733     #define x86_shrd_reg_imm(inst,dreg,reg,shamt) \
734     do { \
735     *(inst)++ = (unsigned char)0x0f; \
736     *(inst)++ = (unsigned char)0xac; \
737     x86_reg_emit ((inst), (reg), (dreg)); \
738     x86_imm_emit8 ((inst), (shamt)); \
739     } while (0)
740    
741     #define x86_shld_reg(inst,dreg,reg) \
742     do { \
743     *(inst)++ = (unsigned char)0x0f; \
744     *(inst)++ = (unsigned char)0xa5; \
745     x86_reg_emit ((inst), (reg), (dreg)); \
746     } while (0)
747    
748     #define x86_shld_reg_imm(inst,dreg,reg,shamt) \
749     do { \
750     *(inst)++ = (unsigned char)0x0f; \
751     *(inst)++ = (unsigned char)0xa4; \
752     x86_reg_emit ((inst), (reg), (dreg)); \
753     x86_imm_emit8 ((inst), (shamt)); \
754     } while (0)
755    
756     /*
757     * EDX:EAX = EAX * rm
758     */
759     #define x86_mul_reg(inst,reg,is_signed) \
760     do { \
761     *(inst)++ = (unsigned char)0xf7; \
762     x86_reg_emit ((inst), 4 + ((is_signed) ? 1 : 0), (reg)); \
763     } while (0)
764    
765     #define x86_mul_mem(inst,mem,is_signed) \
766     do { \
767     *(inst)++ = (unsigned char)0xf7; \
768     x86_mem_emit ((inst), 4 + ((is_signed) ? 1 : 0), (mem)); \
769     } while (0)
770    
771     #define x86_mul_membase(inst,basereg,disp,is_signed) \
772     do { \
773     *(inst)++ = (unsigned char)0xf7; \
774     x86_membase_emit ((inst), 4 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
775     } while (0)
776    
777     /*
778     * r *= rm
779     */
780     #define x86_imul_reg_reg(inst,dreg,reg) \
781     do { \
782     *(inst)++ = (unsigned char)0x0f; \
783     *(inst)++ = (unsigned char)0xaf; \
784     x86_reg_emit ((inst), (dreg), (reg)); \
785     } while (0)
786    
787     #define x86_imul_reg_mem(inst,reg,mem) \
788     do { \
789     *(inst)++ = (unsigned char)0x0f; \
790     *(inst)++ = (unsigned char)0xaf; \
791     x86_mem_emit ((inst), (reg), (mem)); \
792     } while (0)
793    
794     #define x86_imul_reg_membase(inst,reg,basereg,disp) \
795     do { \
796     *(inst)++ = (unsigned char)0x0f; \
797     *(inst)++ = (unsigned char)0xaf; \
798     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
799     } while (0)
800    
801     /*
802     * dreg = rm * imm
803     */
804     #define x86_imul_reg_reg_imm(inst,dreg,reg,imm) \
805     do { \
806     if (x86_is_imm8 ((imm))) { \
807     *(inst)++ = (unsigned char)0x6b; \
808     x86_reg_emit ((inst), (dreg), (reg)); \
809     x86_imm_emit8 ((inst), (imm)); \
810     } else { \
811     *(inst)++ = (unsigned char)0x69; \
812     x86_reg_emit ((inst), (dreg), (reg)); \
813     x86_imm_emit32 ((inst), (imm)); \
814     } \
815     } while (0)
816    
817     #define x86_imul_reg_mem_imm(inst,reg,mem,imm) \
818     do { \
819     if (x86_is_imm8 ((imm))) { \
820     *(inst)++ = (unsigned char)0x6b; \
821     x86_mem_emit ((inst), (reg), (mem)); \
822     x86_imm_emit8 ((inst), (imm)); \
823     } else { \
824     *(inst)++ = (unsigned char)0x69; \
825     x86_reg_emit ((inst), (reg), (mem)); \
826     x86_imm_emit32 ((inst), (imm)); \
827     } \
828     } while (0)
829    
830     #define x86_imul_reg_membase_imm(inst,reg,basereg,disp,imm) \
831     do { \
832     if (x86_is_imm8 ((imm))) { \
833     *(inst)++ = (unsigned char)0x6b; \
834     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
835     x86_imm_emit8 ((inst), (imm)); \
836     } else { \
837     *(inst)++ = (unsigned char)0x69; \
838     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
839     x86_imm_emit32 ((inst), (imm)); \
840     } \
841     } while (0)
842    
843     /*
844     * divide EDX:EAX by rm;
845     * eax = quotient, edx = remainder
846     */
847    
848     #define x86_div_reg(inst,reg,is_signed) \
849     do { \
850     *(inst)++ = (unsigned char)0xf7; \
851     x86_reg_emit ((inst), 6 + ((is_signed) ? 1 : 0), (reg)); \
852     } while (0)
853    
854     #define x86_div_mem(inst,mem,is_signed) \
855     do { \
856     *(inst)++ = (unsigned char)0xf7; \
857     x86_mem_emit ((inst), 6 + ((is_signed) ? 1 : 0), (mem)); \
858     } while (0)
859    
860     #define x86_div_membase(inst,basereg,disp,is_signed) \
861     do { \
862     *(inst)++ = (unsigned char)0xf7; \
863     x86_membase_emit ((inst), 6 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
864     } while (0)
865    
866     #define x86_mov_mem_reg(inst,mem,reg,size) \
867     do { \
868     switch ((size)) { \
869     case 1: *(inst)++ = (unsigned char)0x88; break; \
870     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
871     case 4: *(inst)++ = (unsigned char)0x89; break; \
872     default: assert (0); \
873     } \
874     x86_mem_emit ((inst), (reg), (mem)); \
875     } while (0)
876    
877     #define x86_mov_regp_reg(inst,regp,reg,size) \
878     do { \
879     switch ((size)) { \
880     case 1: *(inst)++ = (unsigned char)0x88; break; \
881     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
882     case 4: *(inst)++ = (unsigned char)0x89; break; \
883     default: assert (0); \
884     } \
885     x86_regp_emit ((inst), (reg), (regp)); \
886     } while (0)
887    
888     #define x86_mov_membase_reg(inst,basereg,disp,reg,size) \
889     do { \
890     switch ((size)) { \
891     case 1: *(inst)++ = (unsigned char)0x88; break; \
892     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
893     case 4: *(inst)++ = (unsigned char)0x89; break; \
894     default: assert (0); \
895     } \
896     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
897     } while (0)
898    
899     #define x86_mov_memindex_reg(inst,basereg,disp,indexreg,shift,reg,size) \
900     do { \
901     switch ((size)) { \
902     case 1: *(inst)++ = (unsigned char)0x88; break; \
903     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
904     case 4: *(inst)++ = (unsigned char)0x89; break; \
905     default: assert (0); \
906     } \
907     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
908     } while (0)
909    
910     #define x86_mov_reg_reg(inst,dreg,reg,size) \
911     do { \
912     switch ((size)) { \
913     case 1: *(inst)++ = (unsigned char)0x8a; break; \
914     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
915     case 4: *(inst)++ = (unsigned char)0x8b; break; \
916     default: assert (0); \
917     } \
918     x86_reg_emit ((inst), (dreg), (reg)); \
919     } while (0)
920    
921     #define x86_mov_reg_mem(inst,reg,mem,size) \
922     do { \
923     switch ((size)) { \
924     case 1: *(inst)++ = (unsigned char)0x8a; break; \
925     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
926     case 4: *(inst)++ = (unsigned char)0x8b; break; \
927     default: assert (0); \
928     } \
929     x86_mem_emit ((inst), (reg), (mem)); \
930     } while (0)
931    
932     #define x86_mov_reg_membase(inst,reg,basereg,disp,size) \
933     do { \
934     switch ((size)) { \
935     case 1: *(inst)++ = (unsigned char)0x8a; break; \
936     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
937     case 4: *(inst)++ = (unsigned char)0x8b; break; \
938     default: assert (0); \
939     } \
940     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
941     } while (0)
942    
943     #define x86_mov_reg_memindex(inst,reg,basereg,disp,indexreg,shift,size) \
944     do { \
945     switch ((size)) { \
946     case 1: *(inst)++ = (unsigned char)0x8a; break; \
947     case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
948     case 4: *(inst)++ = (unsigned char)0x8b; break; \
949     default: assert (0); \
950     } \
951     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
952     } while (0)
953    
954     /*
955     * Note: x86_clear_reg () chacnges the condition code!
956     */
957     #define x86_clear_reg(inst,reg) x86_alu_reg_reg((inst), X86_XOR, (reg), (reg))
958    
959     #define x86_mov_reg_imm(inst,reg,imm) \
960     do { \
961     *(inst)++ = (unsigned char)0xb8 + (reg); \
962     x86_imm_emit32 ((inst), (imm)); \
963     } while (0)
964    
965     #define x86_mov_mem_imm(inst,mem,imm,size) \
966     do { \
967     if ((size) == 1) { \
968     *(inst)++ = (unsigned char)0xc6; \
969     x86_mem_emit ((inst), 0, (mem)); \
970     x86_imm_emit8 ((inst), (imm)); \
971     } else if ((size) == 2) { \
972     *(inst)++ = (unsigned char)0x66; \
973     *(inst)++ = (unsigned char)0xc7; \
974     x86_mem_emit ((inst), 0, (mem)); \
975     x86_imm_emit16 ((inst), (imm)); \
976     } else { \
977     *(inst)++ = (unsigned char)0xc7; \
978     x86_mem_emit ((inst), 0, (mem)); \
979     x86_imm_emit32 ((inst), (imm)); \
980     } \
981     } while (0)
982    
983     #define x86_mov_membase_imm(inst,basereg,disp,imm,size) \
984     do { \
985     if ((size) == 1) { \
986     *(inst)++ = (unsigned char)0xc6; \
987     x86_membase_emit ((inst), 0, (basereg), (disp)); \
988     x86_imm_emit8 ((inst), (imm)); \
989     } else if ((size) == 2) { \
990     *(inst)++ = (unsigned char)0x66; \
991     *(inst)++ = (unsigned char)0xc7; \
992     x86_membase_emit ((inst), 0, (basereg), (disp)); \
993     x86_imm_emit16 ((inst), (imm)); \
994     } else { \
995     *(inst)++ = (unsigned char)0xc7; \
996     x86_membase_emit ((inst), 0, (basereg), (disp)); \
997     x86_imm_emit32 ((inst), (imm)); \
998     } \
999     } while (0)
1000    
1001     #define x86_mov_memindex_imm(inst,basereg,disp,indexreg,shift,imm,size) \
1002     do { \
1003     if ((size) == 1) { \
1004     *(inst)++ = (unsigned char)0xc6; \
1005     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1006     x86_imm_emit8 ((inst), (imm)); \
1007     } else if ((size) == 2) { \
1008     *(inst)++ = (unsigned char)0x66; \
1009     *(inst)++ = (unsigned char)0xc7; \
1010     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1011     x86_imm_emit16 ((inst), (imm)); \
1012     } else { \
1013     *(inst)++ = (unsigned char)0xc7; \
1014     x86_memindex_emit ((inst), 0, (basereg), (disp), (indexreg), (shift)); \
1015     x86_imm_emit32 ((inst), (imm)); \
1016     } \
1017     } while (0)
1018    
1019     #define x86_lea_mem(inst,reg,mem) \
1020     do { \
1021     *(inst)++ = (unsigned char)0x8d; \
1022     x86_mem_emit ((inst), (reg), (mem)); \
1023     } while (0)
1024    
1025     #define x86_lea_membase(inst,reg,basereg,disp) \
1026     do { \
1027     *(inst)++ = (unsigned char)0x8d; \
1028     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
1029     } while (0)
1030    
1031     #define x86_lea_memindex(inst,reg,basereg,disp,indexreg,shift) \
1032     do { \
1033     *(inst)++ = (unsigned char)0x8d; \
1034     x86_memindex_emit ((inst), (reg), (basereg), (disp), (indexreg), (shift)); \
1035     } while (0)
1036    
1037     #define x86_widen_reg(inst,dreg,reg,is_signed,is_half) \
1038     do { \
1039     unsigned char op = 0xb6; \
1040 dpavlin 7 assert (is_half || X86_IS_BYTE_REG (reg)); \
1041 dpavlin 1 *(inst)++ = (unsigned char)0x0f; \
1042     if ((is_signed)) op += 0x08; \
1043     if ((is_half)) op += 0x01; \
1044     *(inst)++ = op; \
1045     x86_reg_emit ((inst), (dreg), (reg)); \
1046     } while (0)
1047    
1048     #define x86_widen_mem(inst,dreg,mem,is_signed,is_half) \
1049     do { \
1050     unsigned char op = 0xb6; \
1051     *(inst)++ = (unsigned char)0x0f; \
1052     if ((is_signed)) op += 0x08; \
1053     if ((is_half)) op += 0x01; \
1054     *(inst)++ = op; \
1055     x86_mem_emit ((inst), (dreg), (mem)); \
1056     } while (0)
1057    
1058     #define x86_widen_membase(inst,dreg,basereg,disp,is_signed,is_half) \
1059     do { \
1060     unsigned char op = 0xb6; \
1061     *(inst)++ = (unsigned char)0x0f; \
1062     if ((is_signed)) op += 0x08; \
1063     if ((is_half)) op += 0x01; \
1064     *(inst)++ = op; \
1065     x86_membase_emit ((inst), (dreg), (basereg), (disp)); \
1066     } while (0)
1067    
1068     #define x86_widen_memindex(inst,dreg,basereg,disp,indexreg,shift,is_signed,is_half) \
1069     do { \
1070     unsigned char op = 0xb6; \
1071     *(inst)++ = (unsigned char)0x0f; \
1072     if ((is_signed)) op += 0x08; \
1073     if ((is_half)) op += 0x01; \
1074     *(inst)++ = op; \
1075     x86_memindex_emit ((inst), (dreg), (basereg), (disp), (indexreg), (shift)); \
1076     } while (0)
1077    
1078     #define x86_cdq(inst) do { *(inst)++ = (unsigned char)0x99; } while (0)
1079     #define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
1080    
1081     #define x86_fp_op_mem(inst,opc,mem,is_double) \
1082     do { \
1083     *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8; \
1084     x86_mem_emit ((inst), (opc), (mem)); \
1085     } while (0)
1086    
1087     #define x86_fp_op_membase(inst,opc,basereg,disp,is_double) \
1088     do { \
1089     *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8; \
1090     x86_membase_emit ((inst), (opc), (basereg), (disp)); \
1091     } while (0)
1092    
1093     #define x86_fp_op(inst,opc,index) \
1094     do { \
1095     *(inst)++ = (unsigned char)0xd8; \
1096     *(inst)++ = (unsigned char)0xc0+((opc)<<3)+((index)&0x07); \
1097     } while (0)
1098    
1099     #define x86_fp_op_reg(inst,opc,index,pop_stack) \
1100     do { \
1101     static const unsigned char map[] = { 0, 1, 2, 3, 5, 4, 7, 6, 8}; \
1102     *(inst)++ = (pop_stack) ? (unsigned char)0xde : (unsigned char)0xdc; \
1103     *(inst)++ = (unsigned char)0xc0+(map[(opc)]<<3)+((index)&0x07); \
1104     } while (0)
1105    
1106     /**
1107     * @x86_fp_int_op_membase
1108     * Supports FPU operations between ST(0) and integer operand in memory.
1109     * Operation encoded using X86_FP_Opcode enum.
1110     * Operand is addressed by [basereg + disp].
1111     * is_int specifies whether operand is int32 (TRUE) or int16 (FALSE).
1112     */
1113     #define x86_fp_int_op_membase(inst,opc,basereg,disp,is_int) \
1114     do { \
1115     *(inst)++ = (is_int) ? (unsigned char)0xda : (unsigned char)0xde; \
1116     x86_membase_emit ((inst), opc, (basereg), (disp)); \
1117     } while (0)
1118    
1119     #define x86_fstp(inst,index) \
1120     do { \
1121     *(inst)++ = (unsigned char)0xdd; \
1122     *(inst)++ = (unsigned char)0xd8+(index); \
1123     } while (0)
1124    
1125     #define x86_fcompp(inst) \
1126     do { \
1127     *(inst)++ = (unsigned char)0xde; \
1128     *(inst)++ = (unsigned char)0xd9; \
1129     } while (0)
1130    
1131     #define x86_fucompp(inst) \
1132     do { \
1133     *(inst)++ = (unsigned char)0xda; \
1134     *(inst)++ = (unsigned char)0xe9; \
1135     } while (0)
1136    
1137     #define x86_fnstsw(inst) \
1138     do { \
1139     *(inst)++ = (unsigned char)0xdf; \
1140     *(inst)++ = (unsigned char)0xe0; \
1141     } while (0)
1142    
1143     #define x86_fnstcw(inst,mem) \
1144     do { \
1145     *(inst)++ = (unsigned char)0xd9; \
1146     x86_mem_emit ((inst), 7, (mem)); \
1147     } while (0)
1148    
1149     #define x86_fnstcw_membase(inst,basereg,disp) \
1150     do { \
1151     *(inst)++ = (unsigned char)0xd9; \
1152     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1153     } while (0)
1154    
1155     #define x86_fldcw(inst,mem) \
1156     do { \
1157     *(inst)++ = (unsigned char)0xd9; \
1158     x86_mem_emit ((inst), 5, (mem)); \
1159     } while (0)
1160    
1161     #define x86_fldcw_membase(inst,basereg,disp) \
1162     do { \
1163     *(inst)++ = (unsigned char)0xd9; \
1164     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1165     } while (0)
1166    
1167     #define x86_fchs(inst) \
1168     do { \
1169     *(inst)++ = (unsigned char)0xd9; \
1170     *(inst)++ = (unsigned char)0xe0; \
1171     } while (0)
1172    
1173     #define x86_frem(inst) \
1174     do { \
1175     *(inst)++ = (unsigned char)0xd9; \
1176     *(inst)++ = (unsigned char)0xf8; \
1177     } while (0)
1178    
1179     #define x86_fxch(inst,index) \
1180     do { \
1181     *(inst)++ = (unsigned char)0xd9; \
1182     *(inst)++ = (unsigned char)0xc8 + ((index) & 0x07); \
1183     } while (0)
1184    
1185     #define x86_fcomi(inst,index) \
1186     do { \
1187     *(inst)++ = (unsigned char)0xdb; \
1188     *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07); \
1189     } while (0)
1190    
1191     #define x86_fcomip(inst,index) \
1192     do { \
1193     *(inst)++ = (unsigned char)0xdf; \
1194     *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07); \
1195     } while (0)
1196    
1197     #define x86_fucomi(inst,index) \
1198     do { \
1199     *(inst)++ = (unsigned char)0xdb; \
1200     *(inst)++ = (unsigned char)0xe8 + ((index) & 0x07); \
1201     } while (0)
1202    
1203     #define x86_fucomip(inst,index) \
1204     do { \
1205     *(inst)++ = (unsigned char)0xdf; \
1206     *(inst)++ = (unsigned char)0xe8 + ((index) & 0x07); \
1207     } while (0)
1208    
1209     #define x86_fld(inst,mem,is_double) \
1210     do { \
1211     *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
1212     x86_mem_emit ((inst), 0, (mem)); \
1213     } while (0)
1214    
1215     #define x86_fld_membase(inst,basereg,disp,is_double) \
1216     do { \
1217     *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
1218     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1219     } while (0)
1220    
1221     #define x86_fld80_mem(inst,mem) \
1222     do { \
1223     *(inst)++ = (unsigned char)0xdb; \
1224     x86_mem_emit ((inst), 5, (mem)); \
1225     } while (0)
1226    
1227     #define x86_fld80_membase(inst,basereg,disp) \
1228     do { \
1229     *(inst)++ = (unsigned char)0xdb; \
1230     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1231     } while (0)
1232    
1233     #define x86_fild(inst,mem,is_long) \
1234     do { \
1235     if ((is_long)) { \
1236     *(inst)++ = (unsigned char)0xdf; \
1237     x86_mem_emit ((inst), 5, (mem)); \
1238     } else { \
1239     *(inst)++ = (unsigned char)0xdb; \
1240     x86_mem_emit ((inst), 0, (mem)); \
1241     } \
1242     } while (0)
1243    
1244     #define x86_fild_membase(inst,basereg,disp,is_long) \
1245     do { \
1246     if ((is_long)) { \
1247     *(inst)++ = (unsigned char)0xdf; \
1248     x86_membase_emit ((inst), 5, (basereg), (disp)); \
1249     } else { \
1250     *(inst)++ = (unsigned char)0xdb; \
1251     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1252     } \
1253     } while (0)
1254    
1255     #define x86_fld_reg(inst,index) \
1256     do { \
1257     *(inst)++ = (unsigned char)0xd9; \
1258     *(inst)++ = (unsigned char)0xc0 + ((index) & 0x07); \
1259     } while (0)
1260    
1261     #define x86_fldz(inst) \
1262     do { \
1263     *(inst)++ = (unsigned char)0xd9; \
1264     *(inst)++ = (unsigned char)0xee; \
1265     } while (0)
1266    
1267     #define x86_fld1(inst) \
1268     do { \
1269     *(inst)++ = (unsigned char)0xd9; \
1270     *(inst)++ = (unsigned char)0xe8; \
1271     } while (0)
1272    
1273     #define x86_fldpi(inst) \
1274     do { \
1275     *(inst)++ = (unsigned char)0xd9; \
1276     *(inst)++ = (unsigned char)0xeb; \
1277     } while (0)
1278    
1279     #define x86_fst(inst,mem,is_double,pop_stack) \
1280     do { \
1281     *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
1282     x86_mem_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (mem)); \
1283     } while (0)
1284    
1285     #define x86_fst_membase(inst,basereg,disp,is_double,pop_stack) \
1286     do { \
1287     *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
1288     x86_membase_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (basereg), (disp)); \
1289     } while (0)
1290    
1291     #define x86_fst80_mem(inst,mem) \
1292     do { \
1293     *(inst)++ = (unsigned char)0xdb; \
1294     x86_mem_emit ((inst), 7, (mem)); \
1295     } while (0)
1296    
1297    
1298     #define x86_fst80_membase(inst,basereg,disp) \
1299     do { \
1300     *(inst)++ = (unsigned char)0xdb; \
1301     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1302     } while (0)
1303    
1304    
1305     #define x86_fist_pop(inst,mem,is_long) \
1306     do { \
1307     if ((is_long)) { \
1308     *(inst)++ = (unsigned char)0xdf; \
1309     x86_mem_emit ((inst), 7, (mem)); \
1310     } else { \
1311     *(inst)++ = (unsigned char)0xdb; \
1312     x86_mem_emit ((inst), 3, (mem)); \
1313     } \
1314     } while (0)
1315    
1316     #define x86_fist_pop_membase(inst,basereg,disp,is_long) \
1317     do { \
1318     if ((is_long)) { \
1319     *(inst)++ = (unsigned char)0xdf; \
1320     x86_membase_emit ((inst), 7, (basereg), (disp)); \
1321     } else { \
1322     *(inst)++ = (unsigned char)0xdb; \
1323     x86_membase_emit ((inst), 3, (basereg), (disp)); \
1324     } \
1325     } while (0)
1326    
1327     #define x86_fstsw(inst) \
1328     do { \
1329     *(inst)++ = (unsigned char)0x9b; \
1330     *(inst)++ = (unsigned char)0xdf; \
1331     *(inst)++ = (unsigned char)0xe0; \
1332     } while (0)
1333    
1334     /**
1335     * @x86_fist_membase
1336     * Converts content of ST(0) to integer and stores it at memory location
1337     * addressed by [basereg + disp].
1338     * is_int specifies whether destination is int32 (TRUE) or int16 (FALSE).
1339     */
1340     #define x86_fist_membase(inst,basereg,disp,is_int) \
1341     do { \
1342     if ((is_int)) { \
1343     *(inst)++ = (unsigned char)0xdb; \
1344     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1345     } else { \
1346     *(inst)++ = (unsigned char)0xdf; \
1347     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1348     } \
1349     } while (0)
1350    
1351    
1352     #define x86_push_reg(inst,reg) \
1353     do { \
1354     *(inst)++ = (unsigned char)0x50 + (reg); \
1355     } while (0)
1356    
1357     #define x86_push_regp(inst,reg) \
1358     do { \
1359     *(inst)++ = (unsigned char)0xff; \
1360     x86_regp_emit ((inst), 6, (reg)); \
1361     } while (0)
1362    
1363     #define x86_push_mem(inst,mem) \
1364     do { \
1365     *(inst)++ = (unsigned char)0xff; \
1366     x86_mem_emit ((inst), 6, (mem)); \
1367     } while (0)
1368    
1369     #define x86_push_membase(inst,basereg,disp) \
1370     do { \
1371     *(inst)++ = (unsigned char)0xff; \
1372     x86_membase_emit ((inst), 6, (basereg), (disp)); \
1373     } while (0)
1374    
1375     #define x86_push_memindex(inst,basereg,disp,indexreg,shift) \
1376     do { \
1377     *(inst)++ = (unsigned char)0xff; \
1378     x86_memindex_emit ((inst), 6, (basereg), (disp), (indexreg), (shift)); \
1379     } while (0)
1380    
1381     #define x86_push_imm_template(inst) x86_push_imm (inst, 0xf0f0f0f0)
1382    
1383     #define x86_push_imm(inst,imm) \
1384     do { \
1385     int _imm = (int) (imm); \
1386     if (x86_is_imm8 (_imm)) { \
1387     *(inst)++ = (unsigned char)0x6A; \
1388     x86_imm_emit8 ((inst), (_imm)); \
1389     } else { \
1390     *(inst)++ = (unsigned char)0x68; \
1391     x86_imm_emit32 ((inst), (_imm)); \
1392     } \
1393     } while (0)
1394    
1395     #define x86_pop_reg(inst,reg) \
1396     do { \
1397     *(inst)++ = (unsigned char)0x58 + (reg); \
1398     } while (0)
1399    
1400     #define x86_pop_mem(inst,mem) \
1401     do { \
1402     *(inst)++ = (unsigned char)0x87; \
1403     x86_mem_emit ((inst), 0, (mem)); \
1404     } while (0)
1405    
1406     #define x86_pop_membase(inst,basereg,disp) \
1407     do { \
1408     *(inst)++ = (unsigned char)0x87; \
1409     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1410     } while (0)
1411    
1412     #define x86_pushad(inst) do { *(inst)++ = (unsigned char)0x60; } while (0)
1413     #define x86_pushfd(inst) do { *(inst)++ = (unsigned char)0x9c; } while (0)
1414     #define x86_popad(inst) do { *(inst)++ = (unsigned char)0x61; } while (0)
1415     #define x86_popfd(inst) do { *(inst)++ = (unsigned char)0x9d; } while (0)
1416    
1417     #define x86_loop(inst,imm) \
1418     do { \
1419     *(inst)++ = (unsigned char)0xe2; \
1420     x86_imm_emit8 ((inst), (imm)); \
1421     } while (0)
1422    
1423     #define x86_loope(inst,imm) \
1424     do { \
1425     *(inst)++ = (unsigned char)0xe1; \
1426     x86_imm_emit8 ((inst), (imm)); \
1427     } while (0)
1428    
1429     #define x86_loopne(inst,imm) \
1430     do { \
1431     *(inst)++ = (unsigned char)0xe0; \
1432     x86_imm_emit8 ((inst), (imm)); \
1433     } while (0)
1434    
1435     #define x86_jump32(inst,imm) \
1436     do { \
1437     *(inst)++ = (unsigned char)0xe9; \
1438     x86_imm_emit32 ((inst), (imm)); \
1439     } while (0)
1440    
1441     #define x86_jump8(inst,imm) \
1442     do { \
1443     *(inst)++ = (unsigned char)0xeb; \
1444     x86_imm_emit8 ((inst), (imm)); \
1445     } while (0)
1446    
1447     #define x86_jump_reg(inst,reg) \
1448     do { \
1449     *(inst)++ = (unsigned char)0xff; \
1450     x86_reg_emit ((inst), 4, (reg)); \
1451     } while (0)
1452    
1453     #define x86_jump_mem(inst,mem) \
1454     do { \
1455     *(inst)++ = (unsigned char)0xff; \
1456     x86_mem_emit ((inst), 4, (mem)); \
1457     } while (0)
1458    
1459     #define x86_jump_membase(inst,basereg,disp) \
1460     do { \
1461     *(inst)++ = (unsigned char)0xff; \
1462     x86_membase_emit ((inst), 4, (basereg), (disp)); \
1463     } while (0)
1464    
1465     /*
1466     * target is a pointer in our buffer.
1467     */
1468     #define x86_jump_code(inst,target) \
1469     do { \
1470     int t = (unsigned char*)(target) - (inst) - 2; \
1471     if (x86_is_imm8(t)) { \
1472     x86_jump8 ((inst), t); \
1473     } else { \
1474     t -= 3; \
1475     x86_jump32 ((inst), t); \
1476     } \
1477     } while (0)
1478    
1479     #define x86_jump_disp(inst,disp) \
1480     do { \
1481     int t = (disp) - 2; \
1482     if (x86_is_imm8(t)) { \
1483     x86_jump8 ((inst), t); \
1484     } else { \
1485     t -= 3; \
1486     x86_jump32 ((inst), t); \
1487     } \
1488     } while (0)
1489    
1490     #define x86_branch8(inst,cond,imm,is_signed) \
1491     do { \
1492     if ((is_signed)) \
1493     *(inst)++ = x86_cc_signed_map [(cond)]; \
1494     else \
1495     *(inst)++ = x86_cc_unsigned_map [(cond)]; \
1496     x86_imm_emit8 ((inst), (imm)); \
1497     } while (0)
1498    
1499     #define x86_branch32(inst,cond,imm,is_signed) \
1500     do { \
1501     *(inst)++ = (unsigned char)0x0f; \
1502     if ((is_signed)) \
1503     *(inst)++ = x86_cc_signed_map [(cond)] + 0x10; \
1504     else \
1505     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x10; \
1506     x86_imm_emit32 ((inst), (imm)); \
1507     } while (0)
1508    
1509     #define x86_branch(inst,cond,target,is_signed) \
1510     do { \
1511     int offset = (target) - (inst) - 2; \
1512     if (x86_is_imm8 ((offset))) \
1513     x86_branch8 ((inst), (cond), offset, (is_signed)); \
1514     else { \
1515     offset -= 4; \
1516     x86_branch32 ((inst), (cond), offset, (is_signed)); \
1517     } \
1518     } while (0)
1519    
1520     #define x86_branch_disp(inst,cond,disp,is_signed) \
1521     do { \
1522     int offset = (disp) - 2; \
1523     if (x86_is_imm8 ((offset))) \
1524     x86_branch8 ((inst), (cond), offset, (is_signed)); \
1525     else { \
1526     offset -= 4; \
1527     x86_branch32 ((inst), (cond), offset, (is_signed)); \
1528     } \
1529     } while (0)
1530    
1531     #define x86_set_reg(inst,cond,reg,is_signed) \
1532     do { \
1533 dpavlin 7 assert (X86_IS_BYTE_REG (reg)); \
1534 dpavlin 1 *(inst)++ = (unsigned char)0x0f; \
1535     if ((is_signed)) \
1536     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1537     else \
1538     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1539     x86_reg_emit ((inst), 0, (reg)); \
1540     } while (0)
1541    
1542     #define x86_set_mem(inst,cond,mem,is_signed) \
1543     do { \
1544     *(inst)++ = (unsigned char)0x0f; \
1545     if ((is_signed)) \
1546     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1547     else \
1548     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1549     x86_mem_emit ((inst), 0, (mem)); \
1550     } while (0)
1551    
1552     #define x86_set_membase(inst,cond,basereg,disp,is_signed) \
1553     do { \
1554     *(inst)++ = (unsigned char)0x0f; \
1555     if ((is_signed)) \
1556     *(inst)++ = x86_cc_signed_map [(cond)] + 0x20; \
1557     else \
1558     *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x20; \
1559     x86_membase_emit ((inst), 0, (basereg), (disp)); \
1560     } while (0)
1561    
1562     #define x86_call_imm(inst,disp) \
1563     do { \
1564     *(inst)++ = (unsigned char)0xe8; \
1565     x86_imm_emit32 ((inst), (int)(disp)); \
1566     } while (0)
1567    
1568     #define x86_call_reg(inst,reg) \
1569     do { \
1570     *(inst)++ = (unsigned char)0xff; \
1571     x86_reg_emit ((inst), 2, (reg)); \
1572     } while (0)
1573    
1574     #define x86_call_mem(inst,mem) \
1575     do { \
1576     *(inst)++ = (unsigned char)0xff; \
1577     x86_mem_emit ((inst), 2, (mem)); \
1578     } while (0)
1579    
1580     #define x86_call_membase(inst,basereg,disp) \
1581     do { \
1582     *(inst)++ = (unsigned char)0xff; \
1583     x86_membase_emit ((inst), 2, (basereg), (disp)); \
1584     } while (0)
1585    
1586     #define x86_call_code(inst,target) \
1587     do { \
1588     int _x86_offset = (unsigned char*)(target) - (inst); \
1589     _x86_offset -= 5; \
1590     x86_call_imm ((inst), _x86_offset); \
1591     } while (0)
1592    
1593     #define x86_ret(inst) do { *(inst)++ = (unsigned char)0xc3; } while (0)
1594    
1595     #define x86_ret_imm(inst,imm) \
1596     do { \
1597     if ((imm) == 0) { \
1598     x86_ret ((inst)); \
1599     } else { \
1600     *(inst)++ = (unsigned char)0xc2; \
1601     x86_imm_emit16 ((inst), (imm)); \
1602     } \
1603     } while (0)
1604    
1605     #define x86_cmov_reg(inst,cond,is_signed,dreg,reg) \
1606     do { \
1607     *(inst)++ = (unsigned char) 0x0f; \
1608     if ((is_signed)) \
1609     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1610     else \
1611     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1612     x86_reg_emit ((inst), (dreg), (reg)); \
1613     } while (0)
1614    
1615     #define x86_cmov_mem(inst,cond,is_signed,reg,mem) \
1616     do { \
1617     *(inst)++ = (unsigned char) 0x0f; \
1618     if ((is_signed)) \
1619     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1620     else \
1621     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1622     x86_mem_emit ((inst), (reg), (mem)); \
1623     } while (0)
1624    
1625     #define x86_cmov_membase(inst,cond,is_signed,reg,basereg,disp) \
1626     do { \
1627     *(inst)++ = (unsigned char) 0x0f; \
1628     if ((is_signed)) \
1629     *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
1630     else \
1631     *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
1632     x86_membase_emit ((inst), (reg), (basereg), (disp)); \
1633     } while (0)
1634    
1635     #define x86_enter(inst,framesize) \
1636     do { \
1637     *(inst)++ = (unsigned char)0xc8; \
1638     x86_imm_emit16 ((inst), (framesize)); \
1639     *(inst)++ = 0; \
1640     } while (0)
1641    
1642     #define x86_leave(inst) do { *(inst)++ = (unsigned char)0xc9; } while (0)
1643     #define x86_sahf(inst) do { *(inst)++ = (unsigned char)0x9e; } while (0)
1644    
1645     #define x86_fsin(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfe; } while (0)
1646     #define x86_fcos(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xff; } while (0)
1647     #define x86_fabs(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe1; } while (0)
1648     #define x86_ftst(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe4; } while (0)
1649     #define x86_fxam(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe5; } while (0)
1650     #define x86_fpatan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf3; } while (0)
1651     #define x86_fprem(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf8; } while (0)
1652     #define x86_fprem1(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf5; } while (0)
1653     #define x86_frndint(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfc; } while (0)
1654     #define x86_fsqrt(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfa; } while (0)
1655     #define x86_fptan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf2; } while (0)
1656    
1657     #define x86_padding(inst,size) \
1658     do { \
1659     switch ((size)) { \
1660     case 1: x86_nop ((inst)); break; \
1661     case 2: *(inst)++ = 0x8b; \
1662     *(inst)++ = 0xc0; break; \
1663     case 3: *(inst)++ = 0x8d; *(inst)++ = 0x6d; \
1664     *(inst)++ = 0x00; break; \
1665     case 4: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
1666     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1667     break; \
1668     case 5: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
1669     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1670     x86_nop ((inst)); break; \
1671     case 6: *(inst)++ = 0x8d; *(inst)++ = 0xad; \
1672     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1673     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1674     break; \
1675     case 7: *(inst)++ = 0x8d; *(inst)++ = 0xa4; \
1676     *(inst)++ = 0x24; *(inst)++ = 0x00; \
1677     *(inst)++ = 0x00; *(inst)++ = 0x00; \
1678     *(inst)++ = 0x00; break; \
1679     default: assert (0); \
1680     } \
1681     } while (0)
1682    
1683     #define x86_prolog(inst,frame_size,reg_mask) \
1684     do { \
1685     unsigned i, m = 1; \
1686     x86_enter ((inst), (frame_size)); \
1687     for (i = 0; i < X86_NREG; ++i, m <<= 1) { \
1688     if ((reg_mask) & m) \
1689     x86_push_reg ((inst), i); \
1690     } \
1691     } while (0)
1692    
1693     #define x86_epilog(inst,reg_mask) \
1694     do { \
1695     unsigned i, m = 1 << X86_EDI; \
1696     for (i = X86_EDI; m != 0; i--, m=m>>1) { \
1697     if ((reg_mask) & m) \
1698     x86_pop_reg ((inst), i); \
1699     } \
1700     x86_leave ((inst)); \
1701     x86_ret ((inst)); \
1702     } while (0)
1703    
1704     #endif // X86_H

  ViewVC Help
Powered by ViewVC 1.1.26