convert several x86 instructions at the same time
[qemu] / translate-i386.c
1 #include <stdarg.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <inttypes.h>
6 #include <assert.h>
7
8 #define DEBUG_DISAS
9
10 #define IN_OP_I386
11 #include "cpu-i386.h"
12
13 /* dump all code */
14 #ifdef DEBUG_DISAS
15 #include "dis-asm.h"
16 #endif
17
18 static uint8_t *gen_code_ptr;
19 int __op_param1, __op_param2, __op_param3;
20
21 extern FILE *logfile;
22 extern int loglevel;
23
24 /* supress that */
25 static void error(const char *fmt, ...)
26 {
27     va_list ap;
28
29     va_start(ap, fmt);
30     fprintf(stderr, "\n");
31     vfprintf(stderr, fmt, ap);
32     fprintf(stderr, "\n");
33     va_end(ap);
34     exit(1);
35 }
36
37 #define PREFIX_REPZ 1
38 #define PREFIX_REPNZ 2
39 #define PREFIX_LOCK 4
40 #define PREFIX_CS 8
41 #define PREFIX_SS 0x10
42 #define PREFIX_DS 0x20
43 #define PREFIX_ES 0x40
44 #define PREFIX_FS 0x80
45 #define PREFIX_GS 0x100
46 #define PREFIX_DATA 0x200
47 #define PREFIX_ADR 0x400
48 #define PREFIX_FWAIT 0x800
49
50 typedef struct DisasContext {
51     /* current insn context */
52     int prefix;
53     int aflag, dflag;
54     uint8_t *pc; /* current pc */
55     int cc_op; /* current CC operation */
56     int f_st;
57 } DisasContext;
58
59 /* i386 arith/logic operations */
60 enum {
61     OP_ADDL, 
62     OP_ORL, 
63     OP_ADCL, 
64     OP_SBBL,
65     OP_ANDL, 
66     OP_SUBL, 
67     OP_XORL, 
68     OP_CMPL,
69 };
70
71 /* i386 shift ops */
72 enum {
73     OP_ROL, 
74     OP_ROR, 
75     OP_RCL, 
76     OP_RCR, 
77     OP_SHL, 
78     OP_SHR, 
79     OP_SHL1, /* undocumented */
80     OP_SAR = 7,
81 };
82
83 #include "op-i386.h"
84
85 /* operand size */
86 enum {
87     OT_BYTE = 0,
88     OT_WORD,
89     OT_LONG, 
90     OT_QUAD,
91 };
92
93 enum {
94     /* I386 int registers */
95     OR_EAX,   /* MUST be even numbered */
96     OR_ECX,
97     OR_EDX,
98     OR_EBX,
99     OR_ESP,
100     OR_EBP,
101     OR_ESI,
102     OR_EDI,
103     OR_TMP0,    /* temporary operand register */
104     OR_TMP1,
105     OR_A0, /* temporary register used when doing address evaluation */
106     OR_ZERO, /* fixed zero register */
107     NB_OREGS,
108 };
109
110 typedef void (GenOpFunc)(void);
111 typedef void (GenOpFunc1)(long);
112 typedef void (GenOpFunc2)(long, long);
113                     
114 static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
115     [OT_BYTE] = {
116         gen_op_movb_EAX_T0,
117         gen_op_movb_ECX_T0,
118         gen_op_movb_EDX_T0,
119         gen_op_movb_EBX_T0,
120         gen_op_movh_EAX_T0,
121         gen_op_movh_ECX_T0,
122         gen_op_movh_EDX_T0,
123         gen_op_movh_EBX_T0,
124     },
125     [OT_WORD] = {
126         gen_op_movw_EAX_T0,
127         gen_op_movw_ECX_T0,
128         gen_op_movw_EDX_T0,
129         gen_op_movw_EBX_T0,
130         gen_op_movw_ESP_T0,
131         gen_op_movw_EBP_T0,
132         gen_op_movw_ESI_T0,
133         gen_op_movw_EDI_T0,
134     },
135     [OT_LONG] = {
136         gen_op_movl_EAX_T0,
137         gen_op_movl_ECX_T0,
138         gen_op_movl_EDX_T0,
139         gen_op_movl_EBX_T0,
140         gen_op_movl_ESP_T0,
141         gen_op_movl_EBP_T0,
142         gen_op_movl_ESI_T0,
143         gen_op_movl_EDI_T0,
144     },
145 };
146
147 static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
148     [OT_BYTE] = {
149         gen_op_movb_EAX_T1,
150         gen_op_movb_ECX_T1,
151         gen_op_movb_EDX_T1,
152         gen_op_movb_EBX_T1,
153         gen_op_movh_EAX_T1,
154         gen_op_movh_ECX_T1,
155         gen_op_movh_EDX_T1,
156         gen_op_movh_EBX_T1,
157     },
158     [OT_WORD] = {
159         gen_op_movw_EAX_T1,
160         gen_op_movw_ECX_T1,
161         gen_op_movw_EDX_T1,
162         gen_op_movw_EBX_T1,
163         gen_op_movw_ESP_T1,
164         gen_op_movw_EBP_T1,
165         gen_op_movw_ESI_T1,
166         gen_op_movw_EDI_T1,
167     },
168     [OT_LONG] = {
169         gen_op_movl_EAX_T1,
170         gen_op_movl_ECX_T1,
171         gen_op_movl_EDX_T1,
172         gen_op_movl_EBX_T1,
173         gen_op_movl_ESP_T1,
174         gen_op_movl_EBP_T1,
175         gen_op_movl_ESI_T1,
176         gen_op_movl_EDI_T1,
177     },
178 };
179
180 static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
181     [0] = {
182         gen_op_movw_EAX_A0,
183         gen_op_movw_ECX_A0,
184         gen_op_movw_EDX_A0,
185         gen_op_movw_EBX_A0,
186         gen_op_movw_ESP_A0,
187         gen_op_movw_EBP_A0,
188         gen_op_movw_ESI_A0,
189         gen_op_movw_EDI_A0,
190     },
191     [1] = {
192         gen_op_movl_EAX_A0,
193         gen_op_movl_ECX_A0,
194         gen_op_movl_EDX_A0,
195         gen_op_movl_EBX_A0,
196         gen_op_movl_ESP_A0,
197         gen_op_movl_EBP_A0,
198         gen_op_movl_ESI_A0,
199         gen_op_movl_EDI_A0,
200     },
201 };
202
203 static GenOpFunc *gen_op_mov_TN_reg[3][2][8] = 
204 {
205     [OT_BYTE] = {
206         {
207             gen_op_movl_T0_EAX,
208             gen_op_movl_T0_ECX,
209             gen_op_movl_T0_EDX,
210             gen_op_movl_T0_EBX,
211             gen_op_movh_T0_EAX,
212             gen_op_movh_T0_ECX,
213             gen_op_movh_T0_EDX,
214             gen_op_movh_T0_EBX,
215         },
216         {
217             gen_op_movl_T1_EAX,
218             gen_op_movl_T1_ECX,
219             gen_op_movl_T1_EDX,
220             gen_op_movl_T1_EBX,
221             gen_op_movh_T1_EAX,
222             gen_op_movh_T1_ECX,
223             gen_op_movh_T1_EDX,
224             gen_op_movh_T1_EBX,
225         },
226     },
227     [OT_WORD] = {
228         {
229             gen_op_movl_T0_EAX,
230             gen_op_movl_T0_ECX,
231             gen_op_movl_T0_EDX,
232             gen_op_movl_T0_EBX,
233             gen_op_movl_T0_ESP,
234             gen_op_movl_T0_EBP,
235             gen_op_movl_T0_ESI,
236             gen_op_movl_T0_EDI,
237         },
238         {
239             gen_op_movl_T1_EAX,
240             gen_op_movl_T1_ECX,
241             gen_op_movl_T1_EDX,
242             gen_op_movl_T1_EBX,
243             gen_op_movl_T1_ESP,
244             gen_op_movl_T1_EBP,
245             gen_op_movl_T1_ESI,
246             gen_op_movl_T1_EDI,
247         },
248     },
249     [OT_LONG] = {
250         {
251             gen_op_movl_T0_EAX,
252             gen_op_movl_T0_ECX,
253             gen_op_movl_T0_EDX,
254             gen_op_movl_T0_EBX,
255             gen_op_movl_T0_ESP,
256             gen_op_movl_T0_EBP,
257             gen_op_movl_T0_ESI,
258             gen_op_movl_T0_EDI,
259         },
260         {
261             gen_op_movl_T1_EAX,
262             gen_op_movl_T1_ECX,
263             gen_op_movl_T1_EDX,
264             gen_op_movl_T1_EBX,
265             gen_op_movl_T1_ESP,
266             gen_op_movl_T1_EBP,
267             gen_op_movl_T1_ESI,
268             gen_op_movl_T1_EDI,
269         },
270     },
271 };
272
273 static GenOpFunc *gen_op_movl_A0_reg[8] = {
274     gen_op_movl_A0_EAX,
275     gen_op_movl_A0_ECX,
276     gen_op_movl_A0_EDX,
277     gen_op_movl_A0_EBX,
278     gen_op_movl_A0_ESP,
279     gen_op_movl_A0_EBP,
280     gen_op_movl_A0_ESI,
281     gen_op_movl_A0_EDI,
282 };
283
284 static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
285     [0] = {
286         gen_op_addl_A0_EAX,
287         gen_op_addl_A0_ECX,
288         gen_op_addl_A0_EDX,
289         gen_op_addl_A0_EBX,
290         gen_op_addl_A0_ESP,
291         gen_op_addl_A0_EBP,
292         gen_op_addl_A0_ESI,
293         gen_op_addl_A0_EDI,
294     },
295     [1] = {
296         gen_op_addl_A0_EAX_s1,
297         gen_op_addl_A0_ECX_s1,
298         gen_op_addl_A0_EDX_s1,
299         gen_op_addl_A0_EBX_s1,
300         gen_op_addl_A0_ESP_s1,
301         gen_op_addl_A0_EBP_s1,
302         gen_op_addl_A0_ESI_s1,
303         gen_op_addl_A0_EDI_s1,
304     },
305     [2] = {
306         gen_op_addl_A0_EAX_s2,
307         gen_op_addl_A0_ECX_s2,
308         gen_op_addl_A0_EDX_s2,
309         gen_op_addl_A0_EBX_s2,
310         gen_op_addl_A0_ESP_s2,
311         gen_op_addl_A0_EBP_s2,
312         gen_op_addl_A0_ESI_s2,
313         gen_op_addl_A0_EDI_s2,
314     },
315     [3] = {
316         gen_op_addl_A0_EAX_s3,
317         gen_op_addl_A0_ECX_s3,
318         gen_op_addl_A0_EDX_s3,
319         gen_op_addl_A0_EBX_s3,
320         gen_op_addl_A0_ESP_s3,
321         gen_op_addl_A0_EBP_s3,
322         gen_op_addl_A0_ESI_s3,
323         gen_op_addl_A0_EDI_s3,
324     },
325 };
326
327 static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
328     gen_op_addl_T0_T1_cc,
329     gen_op_orl_T0_T1_cc,
330     NULL,
331     NULL,
332     gen_op_andl_T0_T1_cc,
333     gen_op_subl_T0_T1_cc,
334     gen_op_xorl_T0_T1_cc,
335     gen_op_cmpl_T0_T1_cc,
336 };
337
338 static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
339     [OT_BYTE] = {
340         gen_op_adcb_T0_T1_cc,
341         gen_op_sbbb_T0_T1_cc,
342     },
343     [OT_WORD] = {
344         gen_op_adcw_T0_T1_cc,
345         gen_op_sbbw_T0_T1_cc,
346     },
347     [OT_LONG] = {
348         gen_op_adcl_T0_T1_cc,
349         gen_op_sbbl_T0_T1_cc,
350     },
351 };
352
353 static const int cc_op_arithb[8] = {
354     CC_OP_ADDB,
355     CC_OP_LOGICB,
356     CC_OP_ADDB,
357     CC_OP_SUBB,
358     CC_OP_LOGICB,
359     CC_OP_SUBB,
360     CC_OP_LOGICB,
361     CC_OP_SUBB,
362 };
363
364 static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
365     [OT_BYTE] = {
366         gen_op_rolb_T0_T1_cc,
367         gen_op_rorb_T0_T1_cc,
368         gen_op_rclb_T0_T1_cc,
369         gen_op_rcrb_T0_T1_cc,
370         gen_op_shlb_T0_T1_cc,
371         gen_op_shrb_T0_T1_cc,
372         gen_op_shlb_T0_T1_cc,
373         gen_op_sarb_T0_T1_cc,
374     },
375     [OT_WORD] = {
376         gen_op_rolw_T0_T1_cc,
377         gen_op_rorw_T0_T1_cc,
378         gen_op_rclw_T0_T1_cc,
379         gen_op_rcrw_T0_T1_cc,
380         gen_op_shlw_T0_T1_cc,
381         gen_op_shrw_T0_T1_cc,
382         gen_op_shlw_T0_T1_cc,
383         gen_op_sarw_T0_T1_cc,
384     },
385     [OT_LONG] = {
386         gen_op_roll_T0_T1_cc,
387         gen_op_rorl_T0_T1_cc,
388         gen_op_rcll_T0_T1_cc,
389         gen_op_rcrl_T0_T1_cc,
390         gen_op_shll_T0_T1_cc,
391         gen_op_shrl_T0_T1_cc,
392         gen_op_shll_T0_T1_cc,
393         gen_op_sarl_T0_T1_cc,
394     },
395 };
396
397 static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
398     [0] = {
399         gen_op_shldw_T0_T1_im_cc,
400         gen_op_shrdw_T0_T1_im_cc,
401     },
402     [1] = {
403         gen_op_shldl_T0_T1_im_cc,
404         gen_op_shrdl_T0_T1_im_cc,
405     },
406 };
407
408 static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
409     [0] = {
410         gen_op_shldw_T0_T1_ECX_cc,
411         gen_op_shrdw_T0_T1_ECX_cc,
412     },
413     [1] = {
414         gen_op_shldl_T0_T1_ECX_cc,
415         gen_op_shrdl_T0_T1_ECX_cc,
416     },
417 };
418
419 static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
420     [0] = {
421         gen_op_btw_T0_T1_cc,
422         gen_op_btsw_T0_T1_cc,
423         gen_op_btrw_T0_T1_cc,
424         gen_op_btcw_T0_T1_cc,
425     },
426     [1] = {
427         gen_op_btl_T0_T1_cc,
428         gen_op_btsl_T0_T1_cc,
429         gen_op_btrl_T0_T1_cc,
430         gen_op_btcl_T0_T1_cc,
431     },
432 };
433
434 static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
435     [0] = {
436         gen_op_bsfw_T0_cc,
437         gen_op_bsrw_T0_cc,
438     },
439     [1] = {
440         gen_op_bsfl_T0_cc,
441         gen_op_bsrl_T0_cc,
442     },
443 };
444
445 static GenOpFunc *gen_op_lds_T0_A0[3] = {
446     gen_op_ldsb_T0_A0,
447     gen_op_ldsw_T0_A0,
448 };
449
450 static GenOpFunc *gen_op_ldu_T0_A0[3] = {
451     gen_op_ldub_T0_A0,
452     gen_op_lduw_T0_A0,
453 };
454
455 /* sign does not matter */
456 static GenOpFunc *gen_op_ld_T0_A0[3] = {
457     gen_op_ldub_T0_A0,
458     gen_op_lduw_T0_A0,
459     gen_op_ldl_T0_A0,
460 };
461
462 static GenOpFunc *gen_op_ld_T1_A0[3] = {
463     gen_op_ldub_T1_A0,
464     gen_op_lduw_T1_A0,
465     gen_op_ldl_T1_A0,
466 };
467
468 static GenOpFunc *gen_op_st_T0_A0[3] = {
469     gen_op_stb_T0_A0,
470     gen_op_stw_T0_A0,
471     gen_op_stl_T0_A0,
472 };
473
474 static GenOpFunc *gen_op_movs[6] = {
475     gen_op_movsb,
476     gen_op_movsw,
477     gen_op_movsl,
478     gen_op_rep_movsb,
479     gen_op_rep_movsw,
480     gen_op_rep_movsl,
481 };
482
483 static GenOpFunc *gen_op_stos[6] = {
484     gen_op_stosb,
485     gen_op_stosw,
486     gen_op_stosl,
487     gen_op_rep_stosb,
488     gen_op_rep_stosw,
489     gen_op_rep_stosl,
490 };
491
492 static GenOpFunc *gen_op_lods[6] = {
493     gen_op_lodsb,
494     gen_op_lodsw,
495     gen_op_lodsl,
496     gen_op_rep_lodsb,
497     gen_op_rep_lodsw,
498     gen_op_rep_lodsl,
499 };
500
501 static GenOpFunc *gen_op_scas[9] = {
502     gen_op_scasb,
503     gen_op_scasw,
504     gen_op_scasl,
505     gen_op_repz_scasb,
506     gen_op_repz_scasw,
507     gen_op_repz_scasl,
508     gen_op_repnz_scasb,
509     gen_op_repnz_scasw,
510     gen_op_repnz_scasl,
511 };
512
513 static GenOpFunc *gen_op_cmps[9] = {
514     gen_op_cmpsb,
515     gen_op_cmpsw,
516     gen_op_cmpsl,
517     gen_op_repz_cmpsb,
518     gen_op_repz_cmpsw,
519     gen_op_repz_cmpsl,
520     gen_op_repnz_cmpsb,
521     gen_op_repnz_cmpsw,
522     gen_op_repnz_cmpsl,
523 };
524
525 static GenOpFunc *gen_op_ins[6] = {
526     gen_op_insb,
527     gen_op_insw,
528     gen_op_insl,
529     gen_op_rep_insb,
530     gen_op_rep_insw,
531     gen_op_rep_insl,
532 };
533
534
535 static GenOpFunc *gen_op_outs[6] = {
536     gen_op_outsb,
537     gen_op_outsw,
538     gen_op_outsl,
539     gen_op_rep_outsb,
540     gen_op_rep_outsw,
541     gen_op_rep_outsl,
542 };
543
544 static GenOpFunc *gen_op_in[3] = {
545     gen_op_inb_T0_T1,
546     gen_op_inw_T0_T1,
547     gen_op_inl_T0_T1,
548 };
549
550 static GenOpFunc *gen_op_out[3] = {
551     gen_op_outb_T0_T1,
552     gen_op_outw_T0_T1,
553     gen_op_outl_T0_T1,
554 };
555
556 enum {
557     JCC_O,
558     JCC_B,
559     JCC_Z,
560     JCC_BE,
561     JCC_S,
562     JCC_P,
563     JCC_L,
564     JCC_LE,
565 };
566
567 static GenOpFunc2 *gen_jcc_slow[8] = {
568     gen_op_jo_cc,
569     gen_op_jb_cc,
570     gen_op_jz_cc,
571     gen_op_jbe_cc,
572     gen_op_js_cc,
573     gen_op_jp_cc,
574     gen_op_jl_cc,
575     gen_op_jle_cc,
576 };
577     
578 static GenOpFunc2 *gen_jcc_sub[3][8] = {
579     [OT_BYTE] = {
580         NULL,
581         gen_op_jb_subb,
582         gen_op_jz_subb,
583         gen_op_jbe_subb,
584         gen_op_js_subb,
585         NULL,
586         gen_op_jl_subb,
587         gen_op_jle_subb,
588     },
589     [OT_WORD] = {
590         NULL,
591         gen_op_jb_subw,
592         gen_op_jz_subw,
593         gen_op_jbe_subw,
594         gen_op_js_subw,
595         NULL,
596         gen_op_jl_subw,
597         gen_op_jle_subw,
598     },
599     [OT_LONG] = {
600         NULL,
601         gen_op_jb_subl,
602         gen_op_jz_subl,
603         gen_op_jbe_subl,
604         gen_op_js_subl,
605         NULL,
606         gen_op_jl_subl,
607         gen_op_jle_subl,
608     },
609 };
610
611 static GenOpFunc *gen_setcc_slow[8] = {
612     gen_op_seto_T0_cc,
613     gen_op_setb_T0_cc,
614     gen_op_setz_T0_cc,
615     gen_op_setbe_T0_cc,
616     gen_op_sets_T0_cc,
617     gen_op_setp_T0_cc,
618     gen_op_setl_T0_cc,
619     gen_op_setle_T0_cc,
620 };
621
622 static GenOpFunc *gen_setcc_sub[3][8] = {
623     [OT_BYTE] = {
624         NULL,
625         gen_op_setb_T0_subb,
626         gen_op_setz_T0_subb,
627         gen_op_setbe_T0_subb,
628         gen_op_sets_T0_subb,
629         NULL,
630         gen_op_setl_T0_subb,
631         gen_op_setle_T0_subb,
632     },
633     [OT_WORD] = {
634         NULL,
635         gen_op_setb_T0_subw,
636         gen_op_setz_T0_subw,
637         gen_op_setbe_T0_subw,
638         gen_op_sets_T0_subw,
639         NULL,
640         gen_op_setl_T0_subw,
641         gen_op_setle_T0_subw,
642     },
643     [OT_LONG] = {
644         NULL,
645         gen_op_setb_T0_subl,
646         gen_op_setz_T0_subl,
647         gen_op_setbe_T0_subl,
648         gen_op_sets_T0_subl,
649         NULL,
650         gen_op_setl_T0_subl,
651         gen_op_setle_T0_subl,
652     },
653 };
654
655 static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
656     gen_op_fadd_ST0_FT0,
657     gen_op_fmul_ST0_FT0,
658     gen_op_fcom_ST0_FT0,
659     gen_op_fcom_ST0_FT0,
660     gen_op_fsub_ST0_FT0,
661     gen_op_fsubr_ST0_FT0,
662     gen_op_fdiv_ST0_FT0,
663     gen_op_fdivr_ST0_FT0,
664 };
665
666 /* NOTE the exception in "r" op ordering */
667 static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
668     gen_op_fadd_STN_ST0,
669     gen_op_fmul_STN_ST0,
670     NULL,
671     NULL,
672     gen_op_fsubr_STN_ST0,
673     gen_op_fsub_STN_ST0,
674     gen_op_fdivr_STN_ST0,
675     gen_op_fdiv_STN_ST0,
676 };
677
678 static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
679 {
680     if (d != OR_TMP0)
681         gen_op_mov_TN_reg[ot][0][d]();
682     if (s != OR_TMP1)
683         gen_op_mov_TN_reg[ot][1][s]();
684     if (op == OP_ADCL || op == OP_SBBL) {
685         if (s1->cc_op != CC_OP_DYNAMIC)
686             gen_op_set_cc_op(s1->cc_op);
687         gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
688         s1->cc_op = CC_OP_DYNAMIC;
689     } else {
690         gen_op_arith_T0_T1_cc[op]();
691         s1->cc_op = cc_op_arithb[op] + ot;
692     }
693     if (d != OR_TMP0 && op != OP_CMPL)
694         gen_op_mov_reg_T0[ot][d]();
695 }
696
697 static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
698 {
699     gen_op_movl_T1_im(c);
700     gen_op(s1, op, ot, d, OR_TMP1);
701 }
702
703 static void gen_inc(DisasContext *s1, int ot, int d, int c)
704 {
705     if (d != OR_TMP0)
706         gen_op_mov_TN_reg[ot][0][d]();
707     if (s1->cc_op != CC_OP_DYNAMIC)
708         gen_op_set_cc_op(s1->cc_op);
709     if (c > 0) {
710         gen_op_incl_T0_cc();
711         s1->cc_op = CC_OP_INCB + ot;
712     } else {
713         gen_op_decl_T0_cc();
714         s1->cc_op = CC_OP_DECB + ot;
715     }
716     if (d != OR_TMP0)
717         gen_op_mov_reg_T0[ot][d]();
718 }
719
720 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
721 {
722     if (d != OR_TMP0)
723         gen_op_mov_TN_reg[ot][0][d]();
724     if (s != OR_TMP1)
725         gen_op_mov_TN_reg[ot][1][s]();
726     /* for zero counts, flags are not updated, so must do it dynamically */
727     if (s1->cc_op != CC_OP_DYNAMIC)
728         gen_op_set_cc_op(s1->cc_op);
729
730     gen_op_shift_T0_T1_cc[ot][op]();
731
732     if (d != OR_TMP0)
733         gen_op_mov_reg_T0[ot][d]();
734     s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
735 }
736
737 static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
738 {
739     /* currently not optimized */
740     gen_op_movl_T1_im(c);
741     gen_shift(s1, op, ot, d, OR_TMP1);
742 }
743
744 static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
745 {
746     int havesib;
747     int havebase;
748     int base, disp;
749     int index = 0;
750     int scale = 0;
751     int reg1, reg2, opreg;
752     int mod, rm, code;
753
754     mod = (modrm >> 6) & 3;
755     rm = modrm & 7;
756
757     if (s->aflag) {
758
759         havesib = 0;
760         havebase = 1;
761         base = rm;
762         
763         if (base == 4) {
764             havesib = 1;
765             code = ldub(s->pc++);
766             scale = (code >> 6) & 3;
767             index = (code >> 3) & 7;
768             base = code & 7;
769         }
770
771         switch (mod) {
772         case 0:
773             if (base == 5) {
774                 havebase = 0;
775                 disp = ldl(s->pc);
776                 s->pc += 4;
777             } else {
778                 disp = 0;
779             }
780             break;
781         case 1:
782             disp = (int8_t)ldub(s->pc++);
783             break;
784         default:
785         case 2:
786             disp = ldl(s->pc);
787             s->pc += 4;
788             break;
789         }
790
791         reg1 = OR_ZERO;
792         reg2 = OR_ZERO;
793           
794         if (havebase || (havesib && (index != 4 || scale != 0))) {
795             if (havebase)
796                 reg1 = OR_EAX + base;
797             if (havesib && index != 4) {
798                 if (havebase)
799                     reg2 = index + OR_EAX;
800                 else
801                     reg1 = index + OR_EAX;
802             }
803         }
804         /* XXX: disp only ? */
805         if (reg2 == OR_ZERO) {
806             /* op: disp + (reg1 << scale) */
807             if (reg1 == OR_ZERO) {
808                 gen_op_movl_A0_im(disp);
809             } else if (scale == 0 && disp == 0) {
810                 gen_op_movl_A0_reg[reg1]();
811             } else {
812                 gen_op_movl_A0_im(disp);
813                 gen_op_addl_A0_reg_sN[scale][reg1]();
814             }
815         } else {
816             /* op: disp + reg1 + (reg2 << scale) */
817             if (disp != 0) {
818                 gen_op_movl_A0_im(disp);
819                 gen_op_addl_A0_reg_sN[0][reg1]();
820             } else {
821                 gen_op_movl_A0_reg[reg1]();
822             }
823             gen_op_addl_A0_reg_sN[scale][reg2]();
824         }
825     } else {
826         switch (mod) {
827         case 0:
828             if (rm == 6) {
829                 disp = lduw(s->pc);
830                 s->pc += 2;
831                 gen_op_movl_A0_im(disp);
832                 goto no_rm;
833             } else {
834                 disp = 0;
835             }
836             break;
837         case 1:
838             disp = (int8_t)ldub(s->pc++);
839             break;
840         default:
841         case 2:
842             disp = lduw(s->pc);
843             s->pc += 2;
844             break;
845         }
846         switch(rm) {
847         case 0:
848             gen_op_movl_A0_reg[R_EBX]();
849             gen_op_addl_A0_reg_sN[0][R_ESI]();
850             break;
851         case 1:
852             gen_op_movl_A0_reg[R_EBX]();
853             gen_op_addl_A0_reg_sN[0][R_EDI]();
854             break;
855         case 2:
856             gen_op_movl_A0_reg[R_EBP]();
857             gen_op_addl_A0_reg_sN[0][R_ESI]();
858             break;
859         case 3:
860             gen_op_movl_A0_reg[R_EBP]();
861             gen_op_addl_A0_reg_sN[0][R_EDI]();
862             break;
863         case 4:
864             gen_op_movl_A0_reg[R_ESI]();
865             break;
866         case 5:
867             gen_op_movl_A0_reg[R_EDI]();
868             break;
869         case 6:
870             gen_op_movl_A0_reg[R_EBP]();
871             break;
872         default:
873         case 7:
874             gen_op_movl_A0_reg[R_EBX]();
875             break;
876         }
877         if (disp != 0)
878             gen_op_addl_A0_im(disp);
879         gen_op_andl_A0_ffff();
880     no_rm: ;
881     }
882     opreg = OR_A0;
883     disp = 0;
884     *reg_ptr = opreg;
885     *offset_ptr = disp;
886 }
887
888 /* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
889    OR_TMP0 */
890 static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
891 {
892     int mod, rm, opreg, disp;
893
894     mod = (modrm >> 6) & 3;
895     rm = modrm & 7;
896     if (mod == 3) {
897         if (is_store) {
898             if (reg != OR_TMP0)
899                 gen_op_mov_TN_reg[ot][0][reg]();
900             gen_op_mov_reg_T0[ot][rm]();
901         } else {
902             gen_op_mov_TN_reg[ot][0][rm]();
903             if (reg != OR_TMP0)
904                 gen_op_mov_reg_T0[ot][reg]();
905         }
906     } else {
907         gen_lea_modrm(s, modrm, &opreg, &disp);
908         if (is_store) {
909             if (reg != OR_TMP0)
910                 gen_op_mov_TN_reg[ot][0][reg]();
911             gen_op_st_T0_A0[ot]();
912         } else {
913             gen_op_ld_T0_A0[ot]();
914             if (reg != OR_TMP0)
915                 gen_op_mov_reg_T0[ot][reg]();
916         }
917     }
918 }
919
920 static inline uint32_t insn_get(DisasContext *s, int ot)
921 {
922     uint32_t ret;
923
924     switch(ot) {
925     case OT_BYTE:
926         ret = ldub(s->pc);
927         s->pc++;
928         break;
929     case OT_WORD:
930         ret = lduw(s->pc);
931         s->pc += 2;
932         break;
933     default:
934     case OT_LONG:
935         ret = ldl(s->pc);
936         s->pc += 4;
937         break;
938     }
939     return ret;
940 }
941
942 static void gen_jcc(DisasContext *s, int b, int val)
943 {
944     int inv, jcc_op;
945     GenOpFunc2 *func;
946
947     inv = b & 1;
948     jcc_op = (b >> 1) & 7;
949     switch(s->cc_op) {
950         /* we optimize the cmp/jcc case */
951     case CC_OP_SUBB:
952     case CC_OP_SUBW:
953     case CC_OP_SUBL:
954         func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
955         if (!func)
956             goto slow_jcc;
957         break;
958         
959         /* some jumps are easy to compute */
960     case CC_OP_ADDB:
961     case CC_OP_ADDW:
962     case CC_OP_ADDL:
963     case CC_OP_ADCB:
964     case CC_OP_ADCW:
965     case CC_OP_ADCL:
966     case CC_OP_SBBB:
967     case CC_OP_SBBW:
968     case CC_OP_SBBL:
969     case CC_OP_LOGICB:
970     case CC_OP_LOGICW:
971     case CC_OP_LOGICL:
972     case CC_OP_INCB:
973     case CC_OP_INCW:
974     case CC_OP_INCL:
975     case CC_OP_DECB:
976     case CC_OP_DECW:
977     case CC_OP_DECL:
978     case CC_OP_SHLB:
979     case CC_OP_SHLW:
980     case CC_OP_SHLL:
981     case CC_OP_SARB:
982     case CC_OP_SARW:
983     case CC_OP_SARL:
984         switch(jcc_op) {
985         case JCC_Z:
986             func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
987             break;
988         case JCC_S:
989             func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
990             break;
991         default:
992             goto slow_jcc;
993         }
994         break;
995     default:
996     slow_jcc:
997         if (s->cc_op != CC_OP_DYNAMIC)
998             gen_op_set_cc_op(s->cc_op);
999         func = gen_jcc_slow[jcc_op];
1000         break;
1001     }
1002     if (!inv) {
1003         func(val, (long)s->pc);
1004     } else {
1005         func((long)s->pc, val);
1006     }
1007 }
1008
1009 static void gen_setcc(DisasContext *s, int b)
1010 {
1011     int inv, jcc_op;
1012     GenOpFunc *func;
1013
1014     inv = b & 1;
1015     jcc_op = (b >> 1) & 7;
1016     switch(s->cc_op) {
1017         /* we optimize the cmp/jcc case */
1018     case CC_OP_SUBB:
1019     case CC_OP_SUBW:
1020     case CC_OP_SUBL:
1021         func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1022         if (!func)
1023             goto slow_jcc;
1024         break;
1025         
1026         /* some jumps are easy to compute */
1027     case CC_OP_ADDB:
1028     case CC_OP_ADDW:
1029     case CC_OP_ADDL:
1030     case CC_OP_LOGICB:
1031     case CC_OP_LOGICW:
1032     case CC_OP_LOGICL:
1033     case CC_OP_INCB:
1034     case CC_OP_INCW:
1035     case CC_OP_INCL:
1036     case CC_OP_DECB:
1037     case CC_OP_DECW:
1038     case CC_OP_DECL:
1039     case CC_OP_SHLB:
1040     case CC_OP_SHLW:
1041     case CC_OP_SHLL:
1042         switch(jcc_op) {
1043         case JCC_Z:
1044             func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1045             break;
1046         case JCC_S:
1047             func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1048             break;
1049         default:
1050             goto slow_jcc;
1051         }
1052         break;
1053     default:
1054     slow_jcc:
1055         if (s->cc_op != CC_OP_DYNAMIC)
1056             gen_op_set_cc_op(s->cc_op);
1057         func = gen_setcc_slow[jcc_op];
1058         break;
1059     }
1060     func();
1061     if (inv) {
1062         gen_op_xor_T0_1();
1063     }
1064 }
1065
1066 /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1067    is set to true if the instruction sets the PC (last instruction of
1068    a basic block) */
1069 long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
1070 {
1071     int b, prefixes, aflag, dflag;
1072     int shift, ot;
1073     int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1074
1075     s->pc = pc_start;
1076     prefixes = 0;
1077     aflag = 1;
1078     dflag = 1;
1079     //    cur_pc = s->pc; /* for insn generation */
1080  next_byte:
1081     b = ldub(s->pc);
1082     s->pc++;
1083     /* check prefixes */
1084     switch (b) {
1085     case 0xf3:
1086         prefixes |= PREFIX_REPZ;
1087         goto next_byte;
1088     case 0xf2:
1089         prefixes |= PREFIX_REPNZ;
1090         goto next_byte;
1091     case 0xf0:
1092         prefixes |= PREFIX_LOCK;
1093         goto next_byte;
1094     case 0x2e:
1095         prefixes |= PREFIX_CS;
1096         goto next_byte;
1097     case 0x36:
1098         prefixes |= PREFIX_SS;
1099         goto next_byte;
1100     case 0x3e:
1101         prefixes |= PREFIX_DS;
1102         goto next_byte;
1103     case 0x26:
1104         prefixes |= PREFIX_ES;
1105         goto next_byte;
1106     case 0x64:
1107         prefixes |= PREFIX_FS;
1108         goto next_byte;
1109     case 0x65:
1110         prefixes |= PREFIX_GS;
1111         goto next_byte;
1112     case 0x66:
1113         prefixes |= PREFIX_DATA;
1114         goto next_byte;
1115     case 0x67:
1116         prefixes |= PREFIX_ADR;
1117         goto next_byte;
1118     case 0x9b:
1119         prefixes |= PREFIX_FWAIT;
1120         goto next_byte;
1121     }
1122
1123     if (prefixes & PREFIX_DATA)
1124         dflag ^= 1;
1125     if (prefixes & PREFIX_ADR)
1126         aflag ^= 1;
1127
1128     s->prefix = prefixes;
1129     s->aflag = aflag;
1130     s->dflag = dflag;
1131
1132     /* now check op code */
1133  reswitch:
1134     switch(b) {
1135     case 0x0f:
1136         /**************************/
1137         /* extended op code */
1138         b = ldub(s->pc++) | 0x100;
1139         goto reswitch;
1140         
1141         /**************************/
1142         /* arith & logic */
1143     case 0x00 ... 0x05:
1144     case 0x08 ... 0x0d:
1145     case 0x10 ... 0x15:
1146     case 0x18 ... 0x1d:
1147     case 0x20 ... 0x25:
1148     case 0x28 ... 0x2d:
1149     case 0x30 ... 0x35:
1150     case 0x38 ... 0x3d:
1151         {
1152             int op, f, val;
1153             op = (b >> 3) & 7;
1154             f = (b >> 1) & 3;
1155
1156             if ((b & 1) == 0)
1157                 ot = OT_BYTE;
1158             else
1159                 ot = dflag ? OT_LONG : OT_WORD;
1160             
1161             switch(f) {
1162             case 0: /* OP Ev, Gv */
1163                 modrm = ldub(s->pc++);
1164                 reg = ((modrm >> 3) & 7) + OR_EAX;
1165                 mod = (modrm >> 6) & 3;
1166                 rm = modrm & 7;
1167                 if (mod != 3) {
1168                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1169                     gen_op_ld_T0_A0[ot]();
1170                     opreg = OR_TMP0;
1171                 } else {
1172                     opreg = OR_EAX + rm;
1173                 }
1174                 gen_op(s, op, ot, opreg, reg);
1175                 if (mod != 3 && op != 7) {
1176                     gen_op_st_T0_A0[ot]();
1177                 }
1178                 break;
1179             case 1: /* OP Gv, Ev */
1180                 modrm = ldub(s->pc++);
1181                 mod = (modrm >> 6) & 3;
1182                 reg = ((modrm >> 3) & 7) + OR_EAX;
1183                 rm = modrm & 7;
1184                 if (mod != 3) {
1185                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1186                     gen_op_ld_T1_A0[ot]();
1187                     opreg = OR_TMP1;
1188                 } else {
1189                     opreg = OR_EAX + rm;
1190                 }
1191                 gen_op(s, op, ot, reg, opreg);
1192                 break;
1193             case 2: /* OP A, Iv */
1194                 val = insn_get(s, ot);
1195                 gen_opi(s, op, ot, OR_EAX, val);
1196                 break;
1197             }
1198         }
1199         break;
1200
1201     case 0x80: /* GRP1 */
1202     case 0x81:
1203     case 0x83:
1204         {
1205             int val;
1206
1207             if ((b & 1) == 0)
1208                 ot = OT_BYTE;
1209             else
1210                 ot = dflag ? OT_LONG : OT_WORD;
1211             
1212             modrm = ldub(s->pc++);
1213             mod = (modrm >> 6) & 3;
1214             rm = modrm & 7;
1215             op = (modrm >> 3) & 7;
1216             
1217             if (mod != 3) {
1218                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1219                 gen_op_ld_T0_A0[ot]();
1220                 opreg = OR_TMP0;
1221             } else {
1222                 opreg = rm + OR_EAX;
1223             }
1224
1225             switch(b) {
1226             default:
1227             case 0x80:
1228             case 0x81:
1229                 val = insn_get(s, ot);
1230                 break;
1231             case 0x83:
1232                 val = (int8_t)insn_get(s, OT_BYTE);
1233                 break;
1234             }
1235
1236             gen_opi(s, op, ot, opreg, val);
1237             if (op != 7 && mod != 3) {
1238                 gen_op_st_T0_A0[ot]();
1239             }
1240         }
1241         break;
1242
1243         /**************************/
1244         /* inc, dec, and other misc arith */
1245     case 0x40 ... 0x47: /* inc Gv */
1246         ot = dflag ? OT_LONG : OT_WORD;
1247         gen_inc(s, ot, OR_EAX + (b & 7), 1);
1248         break;
1249     case 0x48 ... 0x4f: /* dec Gv */
1250         ot = dflag ? OT_LONG : OT_WORD;
1251         gen_inc(s, ot, OR_EAX + (b & 7), -1);
1252         break;
1253     case 0xf6: /* GRP3 */
1254     case 0xf7:
1255         if ((b & 1) == 0)
1256             ot = OT_BYTE;
1257         else
1258             ot = dflag ? OT_LONG : OT_WORD;
1259
1260         modrm = ldub(s->pc++);
1261         mod = (modrm >> 6) & 3;
1262         rm = modrm & 7;
1263         op = (modrm >> 3) & 7;
1264         if (mod != 3) {
1265             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1266             gen_op_ld_T0_A0[ot]();
1267         } else {
1268             gen_op_mov_TN_reg[ot][0][rm]();
1269         }
1270
1271         switch(op) {
1272         case 0: /* test */
1273             val = insn_get(s, ot);
1274             gen_op_movl_T1_im(val);
1275             gen_op_testl_T0_T1_cc();
1276             s->cc_op = CC_OP_LOGICB + ot;
1277             break;
1278         case 2: /* not */
1279             gen_op_notl_T0();
1280             if (mod != 3) {
1281                 gen_op_st_T0_A0[ot]();
1282             } else {
1283                 gen_op_mov_reg_T0[ot][rm]();
1284             }
1285             break;
1286         case 3: /* neg */
1287             gen_op_negl_T0_cc();
1288             if (mod != 3) {
1289                 gen_op_st_T0_A0[ot]();
1290             } else {
1291                 gen_op_mov_reg_T0[ot][rm]();
1292             }
1293             s->cc_op = CC_OP_SUBB + ot;
1294             break;
1295         case 4: /* mul */
1296             switch(ot) {
1297             case OT_BYTE:
1298                 gen_op_mulb_AL_T0();
1299                 break;
1300             case OT_WORD:
1301                 gen_op_mulw_AX_T0();
1302                 break;
1303             default:
1304             case OT_LONG:
1305                 gen_op_mull_EAX_T0();
1306                 break;
1307             }
1308             s->cc_op = CC_OP_MUL;
1309             break;
1310         case 5: /* imul */
1311             switch(ot) {
1312             case OT_BYTE:
1313                 gen_op_imulb_AL_T0();
1314                 break;
1315             case OT_WORD:
1316                 gen_op_imulw_AX_T0();
1317                 break;
1318             default:
1319             case OT_LONG:
1320                 gen_op_imull_EAX_T0();
1321                 break;
1322             }
1323             s->cc_op = CC_OP_MUL;
1324             break;
1325         case 6: /* div */
1326             switch(ot) {
1327             case OT_BYTE:
1328                 gen_op_divb_AL_T0();
1329                 break;
1330             case OT_WORD:
1331                 gen_op_divw_AX_T0();
1332                 break;
1333             default:
1334             case OT_LONG:
1335                 gen_op_divl_EAX_T0();
1336                 break;
1337             }
1338             break;
1339         case 7: /* idiv */
1340             switch(ot) {
1341             case OT_BYTE:
1342                 gen_op_idivb_AL_T0();
1343                 break;
1344             case OT_WORD:
1345                 gen_op_idivw_AX_T0();
1346                 break;
1347             default:
1348             case OT_LONG:
1349                 gen_op_idivl_EAX_T0();
1350                 break;
1351             }
1352             break;
1353         default:
1354             error("GRP3: bad instruction");
1355             return -1;
1356         }
1357         break;
1358
1359     case 0xfe: /* GRP4 */
1360     case 0xff: /* GRP5 */
1361         if ((b & 1) == 0)
1362             ot = OT_BYTE;
1363         else
1364             ot = dflag ? OT_LONG : OT_WORD;
1365
1366         modrm = ldub(s->pc++);
1367         mod = (modrm >> 6) & 3;
1368         rm = modrm & 7;
1369         op = (modrm >> 3) & 7;
1370         if (op >= 2 && b == 0xfe) {
1371             error("GRP4: bad instruction");
1372             return -1;
1373         }
1374         if (mod != 3) {
1375             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1376             gen_op_ld_T0_A0[ot]();
1377         } else {
1378             gen_op_mov_TN_reg[ot][0][rm]();
1379         }
1380
1381         switch(op) {
1382         case 0: /* inc Ev */
1383             gen_inc(s, ot, OR_TMP0, 1);
1384             if (mod != 3)
1385                 gen_op_st_T0_A0[ot]();
1386             else
1387                 gen_op_mov_reg_T0[ot][rm]();
1388             break;
1389         case 1: /* dec Ev */
1390             gen_inc(s, ot, OR_TMP0, -1);
1391             if (mod != 3)
1392                 gen_op_st_T0_A0[ot]();
1393             else
1394                 gen_op_mov_reg_T0[ot][rm]();
1395             break;
1396         case 2: /* call Ev */
1397             gen_op_movl_T1_im((long)s->pc);
1398             gen_op_pushl_T1();
1399             gen_op_jmp_T0();
1400             *is_jmp_ptr = 1;
1401             break;
1402         case 4: /* jmp Ev */
1403             gen_op_jmp_T0();
1404             *is_jmp_ptr = 1;
1405             break;
1406         case 6: /* push Ev */
1407             gen_op_pushl_T0();
1408             break;
1409         default:
1410             error("GRP5: bad instruction");
1411             return -1;
1412         }
1413         break;
1414
1415     case 0x84: /* test Ev, Gv */
1416     case 0x85: 
1417         if ((b & 1) == 0)
1418             ot = OT_BYTE;
1419         else
1420             ot = dflag ? OT_LONG : OT_WORD;
1421
1422         modrm = ldub(s->pc++);
1423         mod = (modrm >> 6) & 3;
1424         rm = modrm & 7;
1425         reg = (modrm >> 3) & 7;
1426         
1427         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1428         gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1429         gen_op_testl_T0_T1_cc();
1430         s->cc_op = CC_OP_LOGICB + ot;
1431         break;
1432         
1433     case 0xa8: /* test eAX, Iv */
1434     case 0xa9:
1435         if ((b & 1) == 0)
1436             ot = OT_BYTE;
1437         else
1438             ot = dflag ? OT_LONG : OT_WORD;
1439         val = insn_get(s, ot);
1440
1441         gen_op_mov_TN_reg[ot][0][OR_EAX]();
1442         gen_op_movl_T1_im(val);
1443         gen_op_testl_T0_T1_cc();
1444         s->cc_op = CC_OP_LOGICB + ot;
1445         break;
1446         
1447     case 0x98: /* CWDE/CBW */
1448         if (dflag)
1449             gen_op_movswl_EAX_AX();
1450         else
1451             gen_op_movsbw_AX_AL();
1452         break;
1453     case 0x99: /* CDQ/CWD */
1454         if (dflag)
1455             gen_op_movslq_EDX_EAX();
1456         else
1457             gen_op_movswl_DX_AX();
1458         break;
1459     case 0x1af: /* imul Gv, Ev */
1460     case 0x69: /* imul Gv, Ev, I */
1461     case 0x6b:
1462         ot = dflag ? OT_LONG : OT_WORD;
1463         modrm = ldub(s->pc++);
1464         reg = ((modrm >> 3) & 7) + OR_EAX;
1465         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1466         if (b == 0x69) {
1467             val = insn_get(s, ot);
1468             gen_op_movl_T1_im(val);
1469         } else if (b == 0x6b) {
1470             val = insn_get(s, OT_BYTE);
1471             gen_op_movl_T1_im(val);
1472         } else {
1473             gen_op_mov_TN_reg[ot][1][reg]();
1474         }
1475
1476         if (ot == OT_LONG) {
1477             gen_op_imull_T0_T1();
1478         } else {
1479             gen_op_imulw_T0_T1();
1480         }
1481         gen_op_mov_reg_T0[ot][reg]();
1482         s->cc_op = CC_OP_MUL;
1483         break;
1484         
1485         /**************************/
1486         /* push/pop */
1487     case 0x50 ... 0x57: /* push */
1488         gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1489         gen_op_pushl_T0();
1490         break;
1491     case 0x58 ... 0x5f: /* pop */
1492         gen_op_popl_T0();
1493         gen_op_mov_reg_T0[OT_LONG][b & 7]();
1494         break;
1495     case 0x68: /* push Iv */
1496     case 0x6a:
1497         ot = dflag ? OT_LONG : OT_WORD;
1498         if (b == 0x68)
1499             val = insn_get(s, ot);
1500         else
1501             val = (int8_t)insn_get(s, OT_BYTE);
1502         gen_op_movl_T0_im(val);
1503         gen_op_pushl_T0();
1504         break;
1505     case 0x8f: /* pop Ev */
1506         ot = dflag ? OT_LONG : OT_WORD;
1507         modrm = ldub(s->pc++);
1508         gen_op_popl_T0();
1509         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1510         break;
1511     case 0xc9: /* leave */
1512         gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1513         gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1514         gen_op_popl_T0();
1515         gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1516         break;
1517         /**************************/
1518         /* mov */
1519     case 0x88:
1520     case 0x89: /* mov Gv, Ev */
1521         if ((b & 1) == 0)
1522             ot = OT_BYTE;
1523         else
1524             ot = dflag ? OT_LONG : OT_WORD;
1525         modrm = ldub(s->pc++);
1526         reg = (modrm >> 3) & 7;
1527         
1528         /* generate a generic store */
1529         gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1530         break;
1531     case 0xc6:
1532     case 0xc7: /* mov Ev, Iv */
1533         if ((b & 1) == 0)
1534             ot = OT_BYTE;
1535         else
1536             ot = dflag ? OT_LONG : OT_WORD;
1537         modrm = ldub(s->pc++);
1538         mod = (modrm >> 6) & 3;
1539         if (mod != 3)
1540             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1541         val = insn_get(s, ot);
1542         gen_op_movl_T0_im(val);
1543         if (mod != 3)
1544             gen_op_st_T0_A0[ot]();
1545         else
1546             gen_op_mov_reg_T0[ot][modrm & 7]();
1547         break;
1548     case 0x8a:
1549     case 0x8b: /* mov Ev, Gv */
1550         if ((b & 1) == 0)
1551             ot = OT_BYTE;
1552         else
1553             ot = dflag ? OT_LONG : OT_WORD;
1554         modrm = ldub(s->pc++);
1555         reg = (modrm >> 3) & 7;
1556         
1557         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1558         gen_op_mov_reg_T0[ot][reg]();
1559         break;
1560
1561     case 0x1b6: /* movzbS Gv, Eb */
1562     case 0x1b7: /* movzwS Gv, Eb */
1563     case 0x1be: /* movsbS Gv, Eb */
1564     case 0x1bf: /* movswS Gv, Eb */
1565         {
1566             int d_ot;
1567             /* d_ot is the size of destination */
1568             d_ot = dflag + OT_WORD;
1569             /* ot is the size of source */
1570             ot = (b & 1) + OT_BYTE;
1571             modrm = ldub(s->pc++);
1572             reg = ((modrm >> 3) & 7) + OR_EAX;
1573             mod = (modrm >> 6) & 3;
1574             rm = modrm & 7;
1575             
1576             if (mod == 3) {
1577                 gen_op_mov_TN_reg[ot][0][rm]();
1578                 switch(ot | (b & 8)) {
1579                 case OT_BYTE:
1580                     gen_op_movzbl_T0_T0();
1581                     break;
1582                 case OT_BYTE | 8:
1583                     gen_op_movsbl_T0_T0();
1584                     break;
1585                 case OT_WORD:
1586                     gen_op_movzwl_T0_T0();
1587                     break;
1588                 default:
1589                 case OT_WORD | 8:
1590                     gen_op_movswl_T0_T0();
1591                     break;
1592                 }
1593                 gen_op_mov_reg_T0[d_ot][reg]();
1594             } else {
1595                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1596                 if (b & 8) {
1597                     gen_op_lds_T0_A0[ot]();
1598                 } else {
1599                     gen_op_ldu_T0_A0[ot]();
1600                 }
1601                 gen_op_mov_reg_T0[d_ot][reg]();
1602             }
1603         }
1604         break;
1605
1606     case 0x8d: /* lea */
1607         ot = dflag ? OT_LONG : OT_WORD;
1608         modrm = ldub(s->pc++);
1609         reg = (modrm >> 3) & 7;
1610
1611         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1612         gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1613         break;
1614         
1615     case 0xa0: /* mov EAX, Ov */
1616     case 0xa1:
1617     case 0xa2: /* mov Ov, EAX */
1618     case 0xa3:
1619         if ((b & 1) == 0)
1620             ot = OT_BYTE;
1621         else
1622             ot = dflag ? OT_LONG : OT_WORD;
1623         if (s->aflag)
1624             offset_addr = insn_get(s, OT_LONG);
1625         else
1626             offset_addr = insn_get(s, OT_WORD);
1627         gen_op_movl_A0_im(offset_addr);
1628         if ((b & 2) == 0) {
1629             gen_op_ld_T0_A0[ot]();
1630             gen_op_mov_reg_T0[ot][R_EAX]();
1631         } else {
1632             gen_op_mov_TN_reg[ot][0][R_EAX]();
1633             gen_op_st_T0_A0[ot]();
1634         }
1635         break;
1636
1637     case 0xb0 ... 0xb7: /* mov R, Ib */
1638         val = insn_get(s, OT_BYTE);
1639         gen_op_movl_T0_im(val);
1640         gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1641         break;
1642     case 0xb8 ... 0xbf: /* mov R, Iv */
1643         ot = dflag ? OT_LONG : OT_WORD;
1644         val = insn_get(s, ot);
1645         reg = OR_EAX + (b & 7);
1646         gen_op_movl_T0_im(val);
1647         gen_op_mov_reg_T0[ot][reg]();
1648         break;
1649
1650     case 0x91 ... 0x97: /* xchg R, EAX */
1651         ot = dflag ? OT_LONG : OT_WORD;
1652         reg = b & 7;
1653         gen_op_mov_TN_reg[ot][0][reg]();
1654         gen_op_mov_TN_reg[ot][1][R_EAX]();
1655         gen_op_mov_reg_T0[ot][R_EAX]();
1656         gen_op_mov_reg_T1[ot][reg]();
1657         break;
1658     case 0x86:
1659     case 0x87: /* xchg Ev, Gv */
1660         if ((b & 1) == 0)
1661             ot = OT_BYTE;
1662         else
1663             ot = dflag ? OT_LONG : OT_WORD;
1664         modrm = ldub(s->pc++);
1665         reg = (modrm >> 3) & 7;
1666
1667         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1668         gen_op_mov_TN_reg[ot][0][reg]();
1669         gen_op_ld_T1_A0[ot]();
1670         gen_op_st_T0_A0[ot]();
1671         gen_op_mov_reg_T1[ot][reg]();
1672         break;
1673         
1674         /************************/
1675         /* shifts */
1676     case 0xc0:
1677     case 0xc1:
1678         /* shift Ev,Ib */
1679         shift = 2;
1680     grp2:
1681         {
1682             if ((b & 1) == 0)
1683                 ot = OT_BYTE;
1684             else
1685                 ot = dflag ? OT_LONG : OT_WORD;
1686             
1687             modrm = ldub(s->pc++);
1688             mod = (modrm >> 6) & 3;
1689             rm = modrm & 7;
1690             op = (modrm >> 3) & 7;
1691             
1692             if (mod != 3) {
1693                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1694                 gen_op_ld_T0_A0[ot]();
1695                 opreg = OR_TMP0;
1696             } else {
1697                 opreg = rm + OR_EAX;
1698             }
1699
1700             /* simpler op */
1701             if (shift == 0) {
1702                 gen_shift(s, op, ot, opreg, OR_ECX);
1703             } else {
1704                 if (shift == 2) {
1705                     shift = ldub(s->pc++);
1706                 }
1707                 gen_shifti(s, op, ot, opreg, shift);
1708             }
1709
1710             if (mod != 3) {
1711                 gen_op_st_T0_A0[ot]();
1712             }
1713         }
1714         break;
1715     case 0xd0:
1716     case 0xd1:
1717         /* shift Ev,1 */
1718         shift = 1;
1719         goto grp2;
1720     case 0xd2:
1721     case 0xd3:
1722         /* shift Ev,cl */
1723         shift = 0;
1724         goto grp2;
1725
1726     case 0x1a4: /* shld imm */
1727         op = 0;
1728         shift = 1;
1729         goto do_shiftd;
1730     case 0x1a5: /* shld cl */
1731         op = 0;
1732         shift = 0;
1733         goto do_shiftd;
1734     case 0x1ac: /* shrd imm */
1735         op = 1;
1736         shift = 1;
1737         goto do_shiftd;
1738     case 0x1ad: /* shrd cl */
1739         op = 1;
1740         shift = 0;
1741     do_shiftd:
1742         ot = dflag ? OT_LONG : OT_WORD;
1743         modrm = ldub(s->pc++);
1744         mod = (modrm >> 6) & 3;
1745         rm = modrm & 7;
1746         reg = (modrm >> 3) & 7;
1747         
1748         if (mod != 3) {
1749             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1750             gen_op_ld_T0_A0[ot]();
1751         } else {
1752             gen_op_mov_TN_reg[ot][0][rm]();
1753         }
1754         gen_op_mov_TN_reg[ot][1][reg]();
1755         
1756         if (shift) {
1757             val = ldub(s->pc++);
1758             val &= 0x1f;
1759             if (val) {
1760                 gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
1761                 if (op == 0 && ot != OT_WORD)
1762                     s->cc_op = CC_OP_SHLB + ot;
1763                 else
1764                     s->cc_op = CC_OP_SARB + ot;
1765             }
1766         } else {
1767             if (s->cc_op != CC_OP_DYNAMIC)
1768                 gen_op_set_cc_op(s->cc_op);
1769             gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
1770             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1771         }
1772         if (mod != 3) {
1773             gen_op_st_T0_A0[ot]();
1774         } else {
1775             gen_op_mov_reg_T0[ot][rm]();
1776         }
1777         break;
1778
1779         /************************/
1780         /* floats */
1781     case 0xd8 ... 0xdf: 
1782         modrm = ldub(s->pc++);
1783         mod = (modrm >> 6) & 3;
1784         rm = modrm & 7;
1785         op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1786         
1787         if (mod != 3) {
1788             /* memory op */
1789             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1790             switch(op) {
1791             case 0x00 ... 0x07: /* fxxxs */
1792             case 0x10 ... 0x17: /* fixxxl */
1793             case 0x20 ... 0x27: /* fxxxl */
1794             case 0x30 ... 0x37: /* fixxx */
1795                 {
1796                     int op1;
1797                     op1 = op & 7;
1798
1799                     switch(op >> 4) {
1800                     case 0:
1801                         gen_op_flds_FT0_A0();
1802                         break;
1803                     case 1:
1804                         gen_op_fildl_FT0_A0();
1805                         break;
1806                     case 2:
1807                         gen_op_fldl_FT0_A0();
1808                         break;
1809                     case 3:
1810                     default:
1811                         gen_op_fild_FT0_A0();
1812                         break;
1813                     }
1814                     
1815                     gen_op_fp_arith_ST0_FT0[op1]();
1816                     if (op1 == 3) {
1817                         /* fcomp needs pop */
1818                         gen_op_fpop();
1819                     }
1820                 }
1821                 break;
1822             case 0x08: /* flds */
1823             case 0x0a: /* fsts */
1824             case 0x0b: /* fstps */
1825             case 0x18: /* fildl */
1826             case 0x1a: /* fistl */
1827             case 0x1b: /* fistpl */
1828             case 0x28: /* fldl */
1829             case 0x2a: /* fstl */
1830             case 0x2b: /* fstpl */
1831             case 0x38: /* filds */
1832             case 0x3a: /* fists */
1833             case 0x3b: /* fistps */
1834                 
1835                 switch(op & 7) {
1836                 case 0:
1837                     gen_op_fpush();
1838                     switch(op >> 4) {
1839                     case 0:
1840                         gen_op_flds_ST0_A0();
1841                         break;
1842                     case 1:
1843                         gen_op_fildl_ST0_A0();
1844                         break;
1845                     case 2:
1846                         gen_op_fldl_ST0_A0();
1847                         break;
1848                     case 3:
1849                     default:
1850                         gen_op_fild_ST0_A0();
1851                         break;
1852                     }
1853                     break;
1854                 default:
1855                     switch(op >> 4) {
1856                     case 0:
1857                         gen_op_fsts_ST0_A0();
1858                         break;
1859                     case 1:
1860                         gen_op_fistl_ST0_A0();
1861                         break;
1862                     case 2:
1863                         gen_op_fstl_ST0_A0();
1864                         break;
1865                     case 3:
1866                     default:
1867                         gen_op_fist_ST0_A0();
1868                         break;
1869                     }
1870                     if ((op & 7) == 3)
1871                         gen_op_fpop();
1872                     break;
1873                 }
1874                 break;
1875             case 0x0d: /* fldcw mem */
1876                 gen_op_fldcw_A0();
1877                 break;
1878             case 0x0f: /* fnstcw mem */
1879                 gen_op_fnstcw_A0();
1880                 break;
1881             case 0x1d: /* fldt mem */
1882                 gen_op_fpush();
1883                 gen_op_fldt_ST0_A0();
1884                 break;
1885             case 0x1f: /* fstpt mem */
1886                 gen_op_fstt_ST0_A0();
1887                 gen_op_fpop();
1888                 break;
1889             case 0x2f: /* fnstsw mem */
1890                 gen_op_fnstsw_A0();
1891                 break;
1892             case 0x3c: /* fbld */
1893                 gen_op_fpush();
1894                 gen_op_fbld_ST0_A0();
1895                 break;
1896             case 0x3e: /* fbstp */
1897                 gen_op_fbst_ST0_A0();
1898                 gen_op_fpop();
1899                 break;
1900             case 0x3d: /* fildll */
1901                 gen_op_fpush();
1902                 gen_op_fildll_ST0_A0();
1903                 break;
1904             case 0x3f: /* fistpll */
1905                 gen_op_fistll_ST0_A0();
1906                 gen_op_fpop();
1907                 break;
1908             default:
1909                 error("unhandled FPm [op=0x%02x]\n", op);
1910                 return -1;
1911             }
1912         } else {
1913             /* register float ops */
1914             opreg = rm;
1915
1916             switch(op) {
1917             case 0x08: /* fld sti */
1918                 gen_op_fpush();
1919                 gen_op_fmov_ST0_STN((opreg + 1) & 7);
1920                 break;
1921             case 0x09: /* fxchg sti */
1922                 gen_op_fxchg_ST0_STN(opreg);
1923                 break;
1924             case 0x0a: /* grp d9/2 */
1925                 switch(rm) {
1926                 case 0: /* fnop */
1927                     break;
1928                 default:
1929                     error("unhandled FP GRP d9/2\n");
1930                     return -1;
1931                 }
1932                 break;
1933             case 0x0c: /* grp d9/4 */
1934                 switch(rm) {
1935                 case 0: /* fchs */
1936                     gen_op_fchs_ST0();
1937                     break;
1938                 case 1: /* fabs */
1939                     gen_op_fabs_ST0();
1940                     break;
1941                 case 4: /* ftst */
1942                     gen_op_fldz_FT0();
1943                     gen_op_fcom_ST0_FT0();
1944                     break;
1945                 case 5: /* fxam */
1946                     gen_op_fxam_ST0();
1947                     break;
1948                 default:
1949                     return -1;
1950                 }
1951                 break;
1952             case 0x0d: /* grp d9/5 */
1953                 {
1954                     switch(rm) {
1955                     case 0:
1956                         gen_op_fpush();
1957                         gen_op_fld1_ST0();
1958                         break;
1959                     case 1:
1960                         gen_op_fpush();
1961                         gen_op_fldl2t_ST0();
1962                         break;
1963                     case 2:
1964                         gen_op_fpush();
1965                         gen_op_fldl2e_ST0();
1966                         break;
1967                     case 3:
1968                         gen_op_fpush();
1969                         gen_op_fldpi_ST0();
1970                         break;
1971                     case 4:
1972                         gen_op_fpush();
1973                         gen_op_fldlg2_ST0();
1974                         break;
1975                     case 5:
1976                         gen_op_fpush();
1977                         gen_op_fldln2_ST0();
1978                         break;
1979                     case 6:
1980                         gen_op_fpush();
1981                         gen_op_fldz_ST0();
1982                         break;
1983                     default:
1984                         return -1;
1985                     }
1986                 }
1987                 break;
1988             case 0x0e: /* grp d9/6 */
1989                 switch(rm) {
1990                 case 0: /* f2xm1 */
1991                     gen_op_f2xm1();
1992                     break;
1993                 case 1: /* fyl2x */
1994                     gen_op_fyl2x();
1995                     break;
1996                 case 2: /* fptan */
1997                     gen_op_fptan();
1998                     break;
1999                 case 3: /* fpatan */
2000                     gen_op_fpatan();
2001                     break;
2002                 case 4: /* fxtract */
2003                     gen_op_fxtract();
2004                     break;
2005                 case 5: /* fprem1 */
2006                     gen_op_fprem1();
2007                     break;
2008                 case 6: /* fdecstp */
2009                     gen_op_fdecstp();
2010                     break;
2011                 default:
2012                 case 7: /* fincstp */
2013                     gen_op_fincstp();
2014                     break;
2015                 }
2016                 break;
2017             case 0x0f: /* grp d9/7 */
2018                 switch(rm) {
2019                 case 0: /* fprem */
2020                     gen_op_fprem();
2021                     break;
2022                 case 1: /* fyl2xp1 */
2023                     gen_op_fyl2xp1();
2024                     break;
2025                 case 2: /* fsqrt */
2026                     gen_op_fsqrt();
2027                     break;
2028                 case 3: /* fsincos */
2029                     gen_op_fsincos();
2030                     break;
2031                 case 5: /* fscale */
2032                     gen_op_fscale();
2033                     break;
2034                 case 4: /* frndint */
2035                     gen_op_frndint();
2036                     break;
2037                 case 6: /* fsin */
2038                     gen_op_fsin();
2039                     break;
2040                 default:
2041                 case 7: /* fcos */
2042                     gen_op_fcos();
2043                     break;
2044                 }
2045                 break;
2046             case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
2047             case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
2048             case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
2049                 {
2050                     int op1;
2051                     
2052                     op1 = op & 7;
2053                     if (op >= 0x20) {
2054                         gen_op_fp_arith_STN_ST0[op1](opreg);
2055                         if (op >= 0x30)
2056                             gen_op_fpop();
2057                     } else {
2058                         gen_op_fmov_FT0_STN(opreg);
2059                         gen_op_fp_arith_ST0_FT0[op1]();
2060                     }
2061                 }
2062                 break;
2063             case 0x02: /* fcom */
2064                 gen_op_fmov_FT0_STN(opreg);
2065                 gen_op_fcom_ST0_FT0();
2066                 break;
2067             case 0x03: /* fcomp */
2068                 gen_op_fmov_FT0_STN(opreg);
2069                 gen_op_fcom_ST0_FT0();
2070                 gen_op_fpop();
2071                 break;
2072             case 0x15: /* da/5 */
2073                 switch(rm) {
2074                 case 1: /* fucompp */
2075                     gen_op_fmov_FT0_STN(1);
2076                     gen_op_fucom_ST0_FT0();
2077                     gen_op_fpop();
2078                     gen_op_fpop();
2079                     break;
2080                 default:
2081                     return -1;
2082                 }
2083                 break;
2084             case 0x2a: /* fst sti */
2085                 gen_op_fmov_STN_ST0(opreg);
2086                 break;
2087             case 0x2b: /* fstp sti */
2088                 gen_op_fmov_STN_ST0(opreg);
2089                 gen_op_fpop();
2090                 break;
2091             case 0x2c: /* fucom st(i) */
2092                 gen_op_fmov_FT0_STN(opreg);
2093                 gen_op_fucom_ST0_FT0();
2094                 break;
2095             case 0x2d: /* fucomp st(i) */
2096                 gen_op_fmov_FT0_STN(opreg);
2097                 gen_op_fucom_ST0_FT0();
2098                 gen_op_fpop();
2099                 break;
2100             case 0x33: /* de/3 */
2101                 switch(rm) {
2102                 case 1: /* fcompp */
2103                     gen_op_fmov_FT0_STN(1);
2104                     gen_op_fcom_ST0_FT0();
2105                     gen_op_fpop();
2106                     gen_op_fpop();
2107                     break;
2108                 default:
2109                     return -1;
2110                 }
2111                 break;
2112             case 0x3c: /* df/4 */
2113                 switch(rm) {
2114                 case 0:
2115                     gen_op_fnstsw_EAX();
2116                     break;
2117                 default:
2118                     error("unhandled FP %x df/4\n", rm);
2119                     return -1;
2120                 }
2121                 break;
2122             default:
2123                 error("unhandled FPr [op=0x%x]\n", op);
2124                 return -1;
2125             }
2126         }
2127         break;
2128         /************************/
2129         /* string ops */
2130     case 0xa4: /* movsS */
2131     case 0xa5:
2132         if ((b & 1) == 0)
2133             ot = OT_BYTE;
2134         else
2135             ot = dflag ? OT_LONG : OT_WORD;
2136         if (prefixes & PREFIX_REPZ) {
2137             gen_op_movs[3 + ot]();
2138         } else {
2139             gen_op_movs[ot]();
2140         }
2141         break;
2142         
2143     case 0xaa: /* stosS */
2144     case 0xab:
2145         if ((b & 1) == 0)
2146             ot = OT_BYTE;
2147         else
2148             ot = dflag ? OT_LONG : OT_WORD;
2149         if (prefixes & PREFIX_REPZ) {
2150             gen_op_stos[3 + ot]();
2151         } else {
2152             gen_op_stos[ot]();
2153         }
2154         break;
2155     case 0xac: /* lodsS */
2156     case 0xad:
2157         if ((b & 1) == 0)
2158             ot = OT_BYTE;
2159         else
2160             ot = dflag ? OT_LONG : OT_WORD;
2161         if (prefixes & PREFIX_REPZ) {
2162             gen_op_lods[3 + ot]();
2163         } else {
2164             gen_op_lods[ot]();
2165         }
2166         break;
2167     case 0xae: /* scasS */
2168     case 0xaf:
2169         if ((b & 1) == 0)
2170             ot = OT_BYTE;
2171         else
2172             ot = dflag ? OT_LONG : OT_WORD;
2173         if (prefixes & PREFIX_REPNZ) {
2174             if (s->cc_op != CC_OP_DYNAMIC)
2175                 gen_op_set_cc_op(s->cc_op);
2176             gen_op_scas[6 + ot]();
2177             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2178         } else if (prefixes & PREFIX_REPZ) {
2179             if (s->cc_op != CC_OP_DYNAMIC)
2180                 gen_op_set_cc_op(s->cc_op);
2181             gen_op_scas[3 + ot]();
2182             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2183         } else {
2184             gen_op_scas[ot]();
2185             s->cc_op = CC_OP_SUBB + ot;
2186         }
2187         break;
2188
2189     case 0xa6: /* cmpsS */
2190     case 0xa7:
2191         if ((b & 1) == 0)
2192             ot = OT_BYTE;
2193         else
2194             ot = dflag ? OT_LONG : OT_WORD;
2195         if (prefixes & PREFIX_REPNZ) {
2196             if (s->cc_op != CC_OP_DYNAMIC)
2197                 gen_op_set_cc_op(s->cc_op);
2198             gen_op_cmps[6 + ot]();
2199             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2200         } else if (prefixes & PREFIX_REPZ) {
2201             if (s->cc_op != CC_OP_DYNAMIC)
2202                 gen_op_set_cc_op(s->cc_op);
2203             gen_op_cmps[3 + ot]();
2204             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2205         } else {
2206             gen_op_cmps[ot]();
2207             s->cc_op = CC_OP_SUBB + ot;
2208         }
2209         break;
2210         
2211         /************************/
2212         /* port I/O */
2213     case 0x6c: /* insS */
2214     case 0x6d:
2215         if ((b & 1) == 0)
2216             ot = OT_BYTE;
2217         else
2218             ot = dflag ? OT_LONG : OT_WORD;
2219         if (prefixes & PREFIX_REPZ) {
2220             gen_op_ins[3 + ot]();
2221         } else {
2222             gen_op_ins[ot]();
2223         }
2224         break;
2225     case 0x6e: /* outsS */
2226     case 0x6f:
2227         if ((b & 1) == 0)
2228             ot = OT_BYTE;
2229         else
2230             ot = dflag ? OT_LONG : OT_WORD;
2231         if (prefixes & PREFIX_REPZ) {
2232             gen_op_outs[3 + ot]();
2233         } else {
2234             gen_op_outs[ot]();
2235         }
2236         break;
2237     case 0xe4:
2238     case 0xe5:
2239         if ((b & 1) == 0)
2240             ot = OT_BYTE;
2241         else
2242             ot = dflag ? OT_LONG : OT_WORD;
2243         val = ldub(s->pc++);
2244         gen_op_movl_T0_im(val);
2245         gen_op_in[ot]();
2246         gen_op_mov_reg_T1[ot][R_EAX]();
2247         break;
2248     case 0xe6:
2249     case 0xe7:
2250         if ((b & 1) == 0)
2251             ot = OT_BYTE;
2252         else
2253             ot = dflag ? OT_LONG : OT_WORD;
2254         val = ldub(s->pc++);
2255         gen_op_movl_T0_im(val);
2256         gen_op_mov_TN_reg[ot][1][R_EAX]();
2257         gen_op_out[ot]();
2258         break;
2259     case 0xec:
2260     case 0xed:
2261         if ((b & 1) == 0)
2262             ot = OT_BYTE;
2263         else
2264             ot = dflag ? OT_LONG : OT_WORD;
2265         gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2266         gen_op_in[ot]();
2267         gen_op_mov_reg_T1[ot][R_EAX]();
2268         break;
2269     case 0xee:
2270     case 0xef:
2271         if ((b & 1) == 0)
2272             ot = OT_BYTE;
2273         else
2274             ot = dflag ? OT_LONG : OT_WORD;
2275         gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2276         gen_op_mov_TN_reg[ot][1][R_EAX]();
2277         gen_op_out[ot]();
2278         break;
2279
2280         /************************/
2281         /* control */
2282     case 0xc2: /* ret im */
2283         /* XXX: handle stack pop ? */
2284         val = ldsw(s->pc);
2285         s->pc += 2;
2286         gen_op_popl_T0();
2287         gen_op_addl_ESP_im(val);
2288         gen_op_jmp_T0();
2289         *is_jmp_ptr = 1;
2290         break;
2291     case 0xc3: /* ret */
2292         gen_op_popl_T0();
2293         gen_op_jmp_T0();
2294         *is_jmp_ptr = 1;
2295         break;
2296     case 0xe8: /* call */
2297         val = insn_get(s, OT_LONG);
2298         val += (long)s->pc;
2299         gen_op_movl_T1_im((long)s->pc);
2300         gen_op_pushl_T1();
2301         gen_op_jmp_im(val);
2302         *is_jmp_ptr = 1;
2303         break;
2304     case 0xe9: /* jmp */
2305         val = insn_get(s, OT_LONG);
2306         val += (long)s->pc;
2307         gen_op_jmp_im(val);
2308         *is_jmp_ptr = 1;
2309         break;
2310     case 0xeb: /* jmp Jb */
2311         val = (int8_t)insn_get(s, OT_BYTE);
2312         val += (long)s->pc;
2313         gen_op_jmp_im(val);
2314         *is_jmp_ptr = 1;
2315         break;
2316     case 0x70 ... 0x7f: /* jcc Jb */
2317         val = (int8_t)insn_get(s, OT_BYTE);
2318         val += (long)s->pc;
2319         goto do_jcc;
2320     case 0x180 ... 0x18f: /* jcc Jv */
2321         if (dflag) {
2322             val = insn_get(s, OT_LONG);
2323         } else {
2324             val = (int16_t)insn_get(s, OT_WORD); 
2325         }
2326         val += (long)s->pc; /* XXX: fix 16 bit wrap */
2327     do_jcc:
2328         gen_jcc(s, b, val);
2329         *is_jmp_ptr = 1;
2330         break;
2331
2332     case 0x190 ... 0x19f:
2333         modrm = ldub(s->pc++);
2334         gen_setcc(s, b);
2335         gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2336         break;
2337
2338         /************************/
2339         /* flags */
2340     case 0x9c: /* pushf */
2341         if (s->cc_op != CC_OP_DYNAMIC)
2342             gen_op_set_cc_op(s->cc_op);
2343         gen_op_movl_T0_eflags();
2344         gen_op_pushl_T0();
2345         break;
2346     case 0x9d: /* popf */
2347         gen_op_popl_T0();
2348         gen_op_movl_eflags_T0();
2349         s->cc_op = CC_OP_EFLAGS;
2350         break;
2351     case 0x9e: /* sahf */
2352         gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2353         if (s->cc_op != CC_OP_DYNAMIC)
2354             gen_op_set_cc_op(s->cc_op);
2355         gen_op_movb_eflags_T0();
2356         s->cc_op = CC_OP_EFLAGS;
2357         break;
2358     case 0x9f: /* lahf */
2359         if (s->cc_op != CC_OP_DYNAMIC)
2360             gen_op_set_cc_op(s->cc_op);
2361         gen_op_movl_T0_eflags();
2362         gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2363         break;
2364     case 0xf5: /* cmc */
2365         if (s->cc_op != CC_OP_DYNAMIC)
2366             gen_op_set_cc_op(s->cc_op);
2367         gen_op_cmc();
2368         s->cc_op = CC_OP_EFLAGS;
2369         break;
2370     case 0xf8: /* clc */
2371         if (s->cc_op != CC_OP_DYNAMIC)
2372             gen_op_set_cc_op(s->cc_op);
2373         gen_op_clc();
2374         s->cc_op = CC_OP_EFLAGS;
2375         break;
2376     case 0xf9: /* stc */
2377         if (s->cc_op != CC_OP_DYNAMIC)
2378             gen_op_set_cc_op(s->cc_op);
2379         gen_op_stc();
2380         s->cc_op = CC_OP_EFLAGS;
2381         break;
2382     case 0xfc: /* cld */
2383         gen_op_cld();
2384         break;
2385     case 0xfd: /* std */
2386         gen_op_std();
2387         break;
2388
2389         /************************/
2390         /* bit operations */
2391     case 0x1ba: /* bt/bts/btr/btc Gv, im */
2392         ot = dflag ? OT_LONG : OT_WORD;
2393         modrm = ldub(s->pc++);
2394         op = (modrm >> 3) & 7;
2395         mod = (modrm >> 6) & 3;
2396         rm = modrm & 7;
2397         if (mod != 3) {
2398             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2399             gen_op_ld_T0_A0[ot]();
2400         } else {
2401             gen_op_mov_TN_reg[ot][0][rm]();
2402         }
2403         /* load shift */
2404         val = ldub(s->pc++);
2405         gen_op_movl_T1_im(val);
2406         if (op < 4)
2407             return -1;
2408         op -= 4;
2409         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2410         s->cc_op = CC_OP_SARB + ot;
2411         if (op != 0) {
2412             if (mod != 3)
2413                 gen_op_st_T0_A0[ot]();
2414             else
2415                 gen_op_mov_reg_T0[ot][rm]();
2416         }
2417         break;
2418     case 0x1a3: /* bt Gv, Ev */
2419         op = 0;
2420         goto do_btx;
2421     case 0x1ab: /* bts */
2422         op = 1;
2423         goto do_btx;
2424     case 0x1b3: /* btr */
2425         op = 2;
2426         goto do_btx;
2427     case 0x1bb: /* btc */
2428         op = 3;
2429     do_btx:
2430         ot = dflag ? OT_LONG : OT_WORD;
2431         modrm = ldub(s->pc++);
2432         reg = (modrm >> 3) & 7;
2433         mod = (modrm >> 6) & 3;
2434         rm = modrm & 7;
2435         gen_op_mov_TN_reg[OT_LONG][1][reg]();
2436         if (mod != 3) {
2437             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2438             /* specific case: we need to add a displacement */
2439             if (ot == OT_WORD)
2440                 gen_op_add_bitw_A0_T1();
2441             else
2442                 gen_op_add_bitl_A0_T1();
2443             gen_op_ld_T0_A0[ot]();
2444         } else {
2445             gen_op_mov_TN_reg[ot][0][rm]();
2446         }
2447         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2448         s->cc_op = CC_OP_SARB + ot;
2449         if (op != 0) {
2450             if (mod != 3)
2451                 gen_op_st_T0_A0[ot]();
2452             else
2453                 gen_op_mov_reg_T0[ot][rm]();
2454         }
2455         break;
2456     case 0x1bc: /* bsf */
2457     case 0x1bd: /* bsr */
2458         ot = dflag ? OT_LONG : OT_WORD;
2459         modrm = ldub(s->pc++);
2460         reg = (modrm >> 3) & 7;
2461         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2462         gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
2463         /* NOTE: we always write back the result. Intel doc says it is
2464            undefined if T0 == 0 */
2465         gen_op_mov_reg_T0[ot][reg]();
2466         s->cc_op = CC_OP_LOGICB + ot;
2467         break;
2468         /************************/
2469         /* misc */
2470     case 0x90: /* nop */
2471         break;
2472     case 0xcc: /* int3 */
2473         gen_op_int3((long)pc_start);
2474         *is_jmp_ptr = 1;
2475         break;
2476     case 0xcd: /* int N */
2477         val = ldub(s->pc++);
2478         /* XXX: currently we ignore the interrupt number */
2479         gen_op_int_im((long)pc_start);
2480         *is_jmp_ptr = 1;
2481         break;
2482     case 0xce: /* into */
2483         if (s->cc_op != CC_OP_DYNAMIC)
2484             gen_op_set_cc_op(s->cc_op);
2485         gen_op_into((long)pc_start, (long)s->pc);
2486         *is_jmp_ptr = 1;
2487         break;
2488     case 0x1c8 ... 0x1cf: /* bswap reg */
2489       reg = b & 7;
2490       gen_op_mov_TN_reg[OT_LONG][0][reg]();
2491       gen_op_bswapl_T0();
2492       gen_op_mov_reg_T0[OT_LONG][reg]();
2493       break;
2494       
2495 #if 0
2496     case 0x1a2: /* cpuid */
2497         gen_insn0(OP_ASM);
2498         break;
2499 #endif
2500     default:
2501         error("unknown opcode %x", b);
2502         return -1;
2503     }
2504     return (long)s->pc;
2505 }
2506
2507 /* return the next pc */
2508 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 
2509                      int *gen_code_size_ptr, uint8_t *pc_start)
2510 {
2511     DisasContext dc1, *dc = &dc1;
2512     uint8_t *gen_code_end, *pc_ptr;
2513     int is_jmp;
2514     long ret;
2515 #ifdef DEBUG_DISAS
2516     struct disassemble_info disasm_info;
2517 #endif
2518
2519     dc->cc_op = CC_OP_DYNAMIC;
2520     gen_code_ptr = gen_code_buf;
2521     gen_code_end = gen_code_buf + max_code_size - 4096;
2522     gen_start();
2523
2524     is_jmp = 0;
2525     pc_ptr = pc_start;
2526     do {
2527         ret = disas_insn(dc, pc_ptr, &is_jmp);
2528         if (ret == -1) 
2529             error("unknown instruction at PC=0x%x B=%02x %02x", 
2530                   pc_ptr, pc_ptr[0], pc_ptr[1]);
2531         pc_ptr = (void *)ret;
2532     } while (!is_jmp && gen_code_ptr < gen_code_end);
2533     /* we must store the eflags state if it is not already done */
2534     if (dc->cc_op != CC_OP_DYNAMIC)
2535         gen_op_set_cc_op(dc->cc_op);
2536     if (!is_jmp) {
2537         /* we add an additionnal jmp to update the simulated PC */
2538         gen_op_jmp_im(ret);
2539     }
2540     gen_end();
2541     *gen_code_size_ptr = gen_code_ptr - gen_code_buf;
2542
2543 #ifdef DEBUG_DISAS
2544     if (loglevel) {
2545         uint8_t *pc;
2546         int count;
2547
2548         INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
2549 #if 0        
2550         disasm_info.flavour = bfd_get_flavour (abfd);
2551         disasm_info.arch = bfd_get_arch (abfd);
2552         disasm_info.mach = bfd_get_mach (abfd);
2553 #endif
2554 #ifdef WORDS_BIGENDIAN
2555         disasm_info.endian = BFD_ENDIAN_BIG;
2556 #else
2557         disasm_info.endian = BFD_ENDIAN_LITTLE;
2558 #endif        
2559         fprintf(logfile, "IN:\n");
2560         disasm_info.buffer = pc_start;
2561         disasm_info.buffer_vma = (unsigned long)pc_start;
2562         disasm_info.buffer_length = pc_ptr - pc_start;
2563         pc = pc_start;
2564         while (pc < pc_ptr) {
2565             fprintf(logfile, "0x%08lx:  ", (long)pc);
2566             count = print_insn_i386((unsigned long)pc, &disasm_info);
2567             fprintf(logfile, "\n");
2568             pc += count;
2569         }
2570         fprintf(logfile, "\n");
2571         
2572         pc = gen_code_buf;
2573         disasm_info.buffer = pc;
2574         disasm_info.buffer_vma = (unsigned long)pc;
2575         disasm_info.buffer_length = *gen_code_size_ptr;
2576         fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
2577         while (pc < gen_code_ptr) {
2578             fprintf(logfile, "0x%08lx:  ", (long)pc);
2579             count = print_insn_i386((unsigned long)pc, &disasm_info);
2580             fprintf(logfile, "\n");
2581             pc += count;
2582         }
2583         fprintf(logfile, "\n");
2584     }
2585 #endif
2586     return 0;
2587 }
2588
2589 CPUX86State *cpu_x86_init(void)
2590 {
2591     CPUX86State *env;
2592     int i;
2593
2594     env = malloc(sizeof(CPUX86State));
2595     if (!env)
2596         return NULL;
2597     memset(env, 0, sizeof(CPUX86State));
2598     /* basic FPU init */
2599     for(i = 0;i < 8; i++)
2600         env->fptags[i] = 1;
2601     env->fpuc = 0x37f;
2602     /* flags setup */
2603     env->cc_op = CC_OP_EFLAGS;
2604     env->df = 1;
2605     return env;
2606 }
2607
2608 void cpu_x86_close(CPUX86State *env)
2609 {
2610     free(env);
2611 }