Statistics
| Branch: | Revision:

root / translate-i386.c @ 4b74fe1f

History | View | Annotate | Download (62.9 kB)

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 GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
398
    [0] = {
399
        gen_op_btw_T0_T1_cc,
400
        gen_op_btsw_T0_T1_cc,
401
        gen_op_btrw_T0_T1_cc,
402
        gen_op_btcw_T0_T1_cc,
403
    },
404
    [1] = {
405
        gen_op_btl_T0_T1_cc,
406
        gen_op_btsl_T0_T1_cc,
407
        gen_op_btrl_T0_T1_cc,
408
        gen_op_btcl_T0_T1_cc,
409
    },
410
};
411

    
412
static GenOpFunc *gen_op_lds_T0_A0[3] = {
413
    gen_op_ldsb_T0_A0,
414
    gen_op_ldsw_T0_A0,
415
};
416

    
417
static GenOpFunc *gen_op_ldu_T0_A0[3] = {
418
    gen_op_ldub_T0_A0,
419
    gen_op_lduw_T0_A0,
420
};
421

    
422
/* sign does not matter */
423
static GenOpFunc *gen_op_ld_T0_A0[3] = {
424
    gen_op_ldub_T0_A0,
425
    gen_op_lduw_T0_A0,
426
    gen_op_ldl_T0_A0,
427
};
428

    
429
static GenOpFunc *gen_op_ld_T1_A0[3] = {
430
    gen_op_ldub_T1_A0,
431
    gen_op_lduw_T1_A0,
432
    gen_op_ldl_T1_A0,
433
};
434

    
435
static GenOpFunc *gen_op_st_T0_A0[3] = {
436
    gen_op_stb_T0_A0,
437
    gen_op_stw_T0_A0,
438
    gen_op_stl_T0_A0,
439
};
440

    
441
static GenOpFunc *gen_op_movs[6] = {
442
    gen_op_movsb,
443
    gen_op_movsw,
444
    gen_op_movsl,
445
    gen_op_rep_movsb,
446
    gen_op_rep_movsw,
447
    gen_op_rep_movsl,
448
};
449

    
450
static GenOpFunc *gen_op_stos[6] = {
451
    gen_op_stosb,
452
    gen_op_stosw,
453
    gen_op_stosl,
454
    gen_op_rep_stosb,
455
    gen_op_rep_stosw,
456
    gen_op_rep_stosl,
457
};
458

    
459
static GenOpFunc *gen_op_lods[6] = {
460
    gen_op_lodsb,
461
    gen_op_lodsw,
462
    gen_op_lodsl,
463
    gen_op_rep_lodsb,
464
    gen_op_rep_lodsw,
465
    gen_op_rep_lodsl,
466
};
467

    
468
static GenOpFunc *gen_op_scas[9] = {
469
    gen_op_scasb,
470
    gen_op_scasw,
471
    gen_op_scasl,
472
    gen_op_repz_scasb,
473
    gen_op_repz_scasw,
474
    gen_op_repz_scasl,
475
    gen_op_repnz_scasb,
476
    gen_op_repnz_scasw,
477
    gen_op_repnz_scasl,
478
};
479

    
480
static GenOpFunc *gen_op_cmps[9] = {
481
    gen_op_cmpsb,
482
    gen_op_cmpsw,
483
    gen_op_cmpsl,
484
    gen_op_repz_cmpsb,
485
    gen_op_repz_cmpsw,
486
    gen_op_repz_cmpsl,
487
    gen_op_repnz_cmpsb,
488
    gen_op_repnz_cmpsw,
489
    gen_op_repnz_cmpsl,
490
};
491

    
492
static GenOpFunc *gen_op_ins[6] = {
493
    gen_op_insb,
494
    gen_op_insw,
495
    gen_op_insl,
496
    gen_op_rep_insb,
497
    gen_op_rep_insw,
498
    gen_op_rep_insl,
499
};
500

    
501

    
502
static GenOpFunc *gen_op_outs[6] = {
503
    gen_op_outsb,
504
    gen_op_outsw,
505
    gen_op_outsl,
506
    gen_op_rep_outsb,
507
    gen_op_rep_outsw,
508
    gen_op_rep_outsl,
509
};
510

    
511
static GenOpFunc *gen_op_in[3] = {
512
    gen_op_inb_T0_T1,
513
    gen_op_inw_T0_T1,
514
    gen_op_inl_T0_T1,
515
};
516

    
517
static GenOpFunc *gen_op_out[3] = {
518
    gen_op_outb_T0_T1,
519
    gen_op_outw_T0_T1,
520
    gen_op_outl_T0_T1,
521
};
522

    
523
enum {
524
    JCC_O,
525
    JCC_B,
526
    JCC_Z,
527
    JCC_BE,
528
    JCC_S,
529
    JCC_P,
530
    JCC_L,
531
    JCC_LE,
532
};
533

    
534
static GenOpFunc2 *gen_jcc_slow[8] = {
535
    gen_op_jo_cc,
536
    gen_op_jb_cc,
537
    gen_op_jz_cc,
538
    gen_op_jbe_cc,
539
    gen_op_js_cc,
540
    gen_op_jp_cc,
541
    gen_op_jl_cc,
542
    gen_op_jle_cc,
543
};
544
    
545
static GenOpFunc2 *gen_jcc_sub[3][8] = {
546
    [OT_BYTE] = {
547
        NULL,
548
        gen_op_jb_subb,
549
        gen_op_jz_subb,
550
        gen_op_jbe_subb,
551
        gen_op_js_subb,
552
        NULL,
553
        gen_op_jl_subb,
554
        gen_op_jle_subb,
555
    },
556
    [OT_WORD] = {
557
        NULL,
558
        gen_op_jb_subw,
559
        gen_op_jz_subw,
560
        gen_op_jbe_subw,
561
        gen_op_js_subw,
562
        NULL,
563
        gen_op_jl_subw,
564
        gen_op_jle_subw,
565
    },
566
    [OT_LONG] = {
567
        NULL,
568
        gen_op_jb_subl,
569
        gen_op_jz_subl,
570
        gen_op_jbe_subl,
571
        gen_op_js_subl,
572
        NULL,
573
        gen_op_jl_subl,
574
        gen_op_jle_subl,
575
    },
576
};
577

    
578
static GenOpFunc *gen_setcc_slow[8] = {
579
    gen_op_seto_T0_cc,
580
    gen_op_setb_T0_cc,
581
    gen_op_setz_T0_cc,
582
    gen_op_setbe_T0_cc,
583
    gen_op_sets_T0_cc,
584
    gen_op_setp_T0_cc,
585
    gen_op_setl_T0_cc,
586
    gen_op_setle_T0_cc,
587
};
588

    
589
static GenOpFunc *gen_setcc_sub[3][8] = {
590
    [OT_BYTE] = {
591
        NULL,
592
        gen_op_setb_T0_subb,
593
        gen_op_setz_T0_subb,
594
        gen_op_setbe_T0_subb,
595
        gen_op_sets_T0_subb,
596
        NULL,
597
        gen_op_setl_T0_subb,
598
        gen_op_setle_T0_subb,
599
    },
600
    [OT_WORD] = {
601
        NULL,
602
        gen_op_setb_T0_subw,
603
        gen_op_setz_T0_subw,
604
        gen_op_setbe_T0_subw,
605
        gen_op_sets_T0_subw,
606
        NULL,
607
        gen_op_setl_T0_subw,
608
        gen_op_setle_T0_subw,
609
    },
610
    [OT_LONG] = {
611
        NULL,
612
        gen_op_setb_T0_subl,
613
        gen_op_setz_T0_subl,
614
        gen_op_setbe_T0_subl,
615
        gen_op_sets_T0_subl,
616
        NULL,
617
        gen_op_setl_T0_subl,
618
        gen_op_setle_T0_subl,
619
    },
620
};
621

    
622
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
623
    gen_op_fadd_ST0_FT0,
624
    gen_op_fmul_ST0_FT0,
625
    gen_op_fcom_ST0_FT0,
626
    gen_op_fcom_ST0_FT0,
627
    gen_op_fsub_ST0_FT0,
628
    gen_op_fsubr_ST0_FT0,
629
    gen_op_fdiv_ST0_FT0,
630
    gen_op_fdivr_ST0_FT0,
631
};
632

    
633
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
634
    gen_op_fadd_STN_ST0,
635
    gen_op_fmul_STN_ST0,
636
    NULL,
637
    NULL,
638
    gen_op_fsub_STN_ST0,
639
    gen_op_fsubr_STN_ST0,
640
    gen_op_fdiv_STN_ST0,
641
    gen_op_fdivr_STN_ST0,
642
};
643

    
644
static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
645
{
646
    if (d != OR_TMP0)
647
        gen_op_mov_TN_reg[ot][0][d]();
648
    if (s != OR_TMP1)
649
        gen_op_mov_TN_reg[ot][1][s]();
650
    if (op == OP_ADCL || op == OP_SBBL) {
651
        if (s1->cc_op != CC_OP_DYNAMIC)
652
            gen_op_set_cc_op(s1->cc_op);
653
        gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
654
        s1->cc_op = CC_OP_DYNAMIC;
655
    } else {
656
        gen_op_arith_T0_T1_cc[op]();
657
        s1->cc_op = cc_op_arithb[op] + ot;
658
    }
659
    if (d != OR_TMP0 && op != OP_CMPL)
660
        gen_op_mov_reg_T0[ot][d]();
661
}
662

    
663
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
664
{
665
    gen_op_movl_T1_im(c);
666
    gen_op(s1, op, ot, d, OR_TMP1);
667
}
668

    
669
static void gen_inc(DisasContext *s1, int ot, int d, int c)
670
{
671
    if (d != OR_TMP0)
672
        gen_op_mov_TN_reg[ot][0][d]();
673
    if (s1->cc_op != CC_OP_DYNAMIC)
674
        gen_op_set_cc_op(s1->cc_op);
675
    if (c > 0) {
676
        gen_op_incl_T0_cc();
677
        s1->cc_op = CC_OP_INCB + ot;
678
    } else {
679
        gen_op_decl_T0_cc();
680
        s1->cc_op = CC_OP_DECB + ot;
681
    }
682
    if (d != OR_TMP0)
683
        gen_op_mov_reg_T0[ot][d]();
684
}
685

    
686
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
687
{
688
    if (d != OR_TMP0)
689
        gen_op_mov_TN_reg[ot][0][d]();
690
    if (s != OR_TMP1)
691
        gen_op_mov_TN_reg[ot][1][s]();
692
    /* for zero counts, flags are not updated, so must do it dynamically */
693
    if (s1->cc_op != CC_OP_DYNAMIC)
694
        gen_op_set_cc_op(s1->cc_op);
695

    
696
    gen_op_shift_T0_T1_cc[ot][op]();
697

    
698
    if (d != OR_TMP0)
699
        gen_op_mov_reg_T0[ot][d]();
700
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
701
}
702

    
703
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
704
{
705
    /* currently not optimized */
706
    gen_op_movl_T1_im(c);
707
    gen_shift(s1, op, ot, d, OR_TMP1);
708
}
709

    
710
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
711
{
712
    int havesib;
713
    int havebase;
714
    int base, disp;
715
    int index = 0;
716
    int scale = 0;
717
    int reg1, reg2, opreg;
718
    int mod, rm, code;
719

    
720
    mod = (modrm >> 6) & 3;
721
    rm = modrm & 7;
722

    
723
    if (s->aflag) {
724

    
725
        havesib = 0;
726
        havebase = 1;
727
        base = rm;
728
        
729
        if (base == 4) {
730
            havesib = 1;
731
            code = ldub(s->pc++);
732
            scale = (code >> 6) & 3;
733
            index = (code >> 3) & 7;
734
            base = code & 7;
735
        }
736

    
737
        switch (mod) {
738
        case 0:
739
            if (base == 5) {
740
                havebase = 0;
741
                disp = ldl(s->pc);
742
                s->pc += 4;
743
            } else {
744
                disp = 0;
745
            }
746
            break;
747
        case 1:
748
            disp = (int8_t)ldub(s->pc++);
749
            break;
750
        default:
751
        case 2:
752
            disp = ldl(s->pc);
753
            s->pc += 4;
754
            break;
755
        }
756

    
757
        reg1 = OR_ZERO;
758
        reg2 = OR_ZERO;
759
          
760
        if (havebase || (havesib && (index != 4 || scale != 0))) {
761
            if (havebase)
762
                reg1 = OR_EAX + base;
763
            if (havesib && index != 4) {
764
                if (havebase)
765
                    reg2 = index + OR_EAX;
766
                else
767
                    reg1 = index + OR_EAX;
768
            }
769
        }
770
        /* XXX: disp only ? */
771
        if (reg2 == OR_ZERO) {
772
            /* op: disp + (reg1 << scale) */
773
            if (reg1 == OR_ZERO) {
774
                gen_op_movl_A0_im(disp);
775
            } else if (scale == 0 && disp == 0) {
776
                gen_op_movl_A0_reg[reg1]();
777
            } else {
778
                gen_op_movl_A0_im(disp);
779
                gen_op_addl_A0_reg_sN[scale][reg1]();
780
            }
781
        } else {
782
            /* op: disp + reg1 + (reg2 << scale) */
783
            if (disp != 0) {
784
                gen_op_movl_A0_im(disp);
785
                gen_op_addl_A0_reg_sN[0][reg1]();
786
            } else {
787
                gen_op_movl_A0_reg[reg1]();
788
            }
789
            gen_op_addl_A0_reg_sN[scale][reg2]();
790
        }
791
    } else {
792
        switch (mod) {
793
        case 0:
794
            if (rm == 6) {
795
                disp = lduw(s->pc);
796
                s->pc += 2;
797
                gen_op_movl_A0_im(disp);
798
                goto no_rm;
799
            } else {
800
                disp = 0;
801
            }
802
            break;
803
        case 1:
804
            disp = (int8_t)ldub(s->pc++);
805
            break;
806
        default:
807
        case 2:
808
            disp = lduw(s->pc);
809
            s->pc += 2;
810
            break;
811
        }
812
        switch(rm) {
813
        case 0:
814
            gen_op_movl_A0_reg[R_EBX]();
815
            gen_op_addl_A0_reg_sN[0][R_ESI]();
816
            break;
817
        case 1:
818
            gen_op_movl_A0_reg[R_EBX]();
819
            gen_op_addl_A0_reg_sN[0][R_EDI]();
820
            break;
821
        case 2:
822
            gen_op_movl_A0_reg[R_EBP]();
823
            gen_op_addl_A0_reg_sN[0][R_ESI]();
824
            break;
825
        case 3:
826
            gen_op_movl_A0_reg[R_EBP]();
827
            gen_op_addl_A0_reg_sN[0][R_EDI]();
828
            break;
829
        case 4:
830
            gen_op_movl_A0_reg[R_ESI]();
831
            break;
832
        case 5:
833
            gen_op_movl_A0_reg[R_EDI]();
834
            break;
835
        case 6:
836
            gen_op_movl_A0_reg[R_EBP]();
837
            break;
838
        default:
839
        case 7:
840
            gen_op_movl_A0_reg[R_EBX]();
841
            break;
842
        }
843
        if (disp != 0)
844
            gen_op_addl_A0_im(disp);
845
        gen_op_andl_A0_ffff();
846
    no_rm: ;
847
    }
848
    opreg = OR_A0;
849
    disp = 0;
850
    *reg_ptr = opreg;
851
    *offset_ptr = disp;
852
}
853

    
854
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
855
   OR_TMP0 */
856
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
857
{
858
    int mod, rm, opreg, disp;
859

    
860
    mod = (modrm >> 6) & 3;
861
    rm = modrm & 7;
862
    if (mod == 3) {
863
        if (is_store) {
864
            if (reg != OR_TMP0)
865
                gen_op_mov_TN_reg[ot][0][reg]();
866
            gen_op_mov_reg_T0[ot][rm]();
867
        } else {
868
            gen_op_mov_TN_reg[ot][0][rm]();
869
            if (reg != OR_TMP0)
870
                gen_op_mov_reg_T0[ot][reg]();
871
        }
872
    } else {
873
        gen_lea_modrm(s, modrm, &opreg, &disp);
874
        if (is_store) {
875
            if (reg != OR_TMP0)
876
                gen_op_mov_TN_reg[ot][0][reg]();
877
            gen_op_st_T0_A0[ot]();
878
        } else {
879
            gen_op_ld_T0_A0[ot]();
880
            if (reg != OR_TMP0)
881
                gen_op_mov_reg_T0[ot][reg]();
882
        }
883
    }
884
}
885

    
886
static inline uint32_t insn_get(DisasContext *s, int ot)
887
{
888
    uint32_t ret;
889

    
890
    switch(ot) {
891
    case OT_BYTE:
892
        ret = ldub(s->pc);
893
        s->pc++;
894
        break;
895
    case OT_WORD:
896
        ret = lduw(s->pc);
897
        s->pc += 2;
898
        break;
899
    default:
900
    case OT_LONG:
901
        ret = ldl(s->pc);
902
        s->pc += 4;
903
        break;
904
    }
905
    return ret;
906
}
907

    
908
static void gen_jcc(DisasContext *s, int b, int val)
909
{
910
    int inv, jcc_op;
911
    GenOpFunc2 *func;
912

    
913
    inv = b & 1;
914
    jcc_op = (b >> 1) & 7;
915
    switch(s->cc_op) {
916
        /* we optimize the cmp/jcc case */
917
    case CC_OP_SUBB:
918
    case CC_OP_SUBW:
919
    case CC_OP_SUBL:
920
        func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
921
        if (!func)
922
            goto slow_jcc;
923
        break;
924
        
925
        /* some jumps are easy to compute */
926
    case CC_OP_ADDB:
927
    case CC_OP_ADDW:
928
    case CC_OP_ADDL:
929
    case CC_OP_ADCB:
930
    case CC_OP_ADCW:
931
    case CC_OP_ADCL:
932
    case CC_OP_SBBB:
933
    case CC_OP_SBBW:
934
    case CC_OP_SBBL:
935
    case CC_OP_LOGICB:
936
    case CC_OP_LOGICW:
937
    case CC_OP_LOGICL:
938
    case CC_OP_INCB:
939
    case CC_OP_INCW:
940
    case CC_OP_INCL:
941
    case CC_OP_DECB:
942
    case CC_OP_DECW:
943
    case CC_OP_DECL:
944
    case CC_OP_SHLB:
945
    case CC_OP_SHLW:
946
    case CC_OP_SHLL:
947
    case CC_OP_SARB:
948
    case CC_OP_SARW:
949
    case CC_OP_SARL:
950
        switch(jcc_op) {
951
        case JCC_Z:
952
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
953
            break;
954
        case JCC_S:
955
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
956
            break;
957
        default:
958
            goto slow_jcc;
959
        }
960
        break;
961
    default:
962
    slow_jcc:
963
        if (s->cc_op != CC_OP_DYNAMIC)
964
            op_set_cc_op(s->cc_op);
965
        func = gen_jcc_slow[jcc_op];
966
        break;
967
    }
968
    if (!inv) {
969
        func(val, (long)s->pc);
970
    } else {
971
        func((long)s->pc, val);
972
    }
973
}
974

    
975
static void gen_setcc(DisasContext *s, int b)
976
{
977
    int inv, jcc_op;
978
    GenOpFunc *func;
979

    
980
    inv = b & 1;
981
    jcc_op = (b >> 1) & 7;
982
    switch(s->cc_op) {
983
        /* we optimize the cmp/jcc case */
984
    case CC_OP_SUBB:
985
    case CC_OP_SUBW:
986
    case CC_OP_SUBL:
987
        func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
988
        if (!func)
989
            goto slow_jcc;
990
        break;
991
        
992
        /* some jumps are easy to compute */
993
    case CC_OP_ADDB:
994
    case CC_OP_ADDW:
995
    case CC_OP_ADDL:
996
    case CC_OP_LOGICB:
997
    case CC_OP_LOGICW:
998
    case CC_OP_LOGICL:
999
    case CC_OP_INCB:
1000
    case CC_OP_INCW:
1001
    case CC_OP_INCL:
1002
    case CC_OP_DECB:
1003
    case CC_OP_DECW:
1004
    case CC_OP_DECL:
1005
    case CC_OP_SHLB:
1006
    case CC_OP_SHLW:
1007
    case CC_OP_SHLL:
1008
        switch(jcc_op) {
1009
        case JCC_Z:
1010
            func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
1011
            break;
1012
        case JCC_S:
1013
            func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
1014
            break;
1015
        default:
1016
            goto slow_jcc;
1017
        }
1018
        break;
1019
    default:
1020
    slow_jcc:
1021
        if (s->cc_op != CC_OP_DYNAMIC)
1022
            op_set_cc_op(s->cc_op);
1023
        func = gen_setcc_slow[jcc_op];
1024
        break;
1025
    }
1026
    func();
1027
    if (inv) {
1028
        gen_op_xor_T0_1();
1029
    }
1030
}
1031

    
1032
/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1033
   is set to true if the instruction sets the PC (last instruction of
1034
   a basic block) */
1035
long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
1036
{
1037
    int b, prefixes, aflag, dflag;
1038
    int shift, ot;
1039
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1040

    
1041
    s->pc = pc_start;
1042
    prefixes = 0;
1043
    aflag = 1;
1044
    dflag = 1;
1045
    //    cur_pc = s->pc; /* for insn generation */
1046
 next_byte:
1047
    b = ldub(s->pc);
1048
    s->pc++;
1049
    /* check prefixes */
1050
    switch (b) {
1051
    case 0xf3:
1052
        prefixes |= PREFIX_REPZ;
1053
        goto next_byte;
1054
    case 0xf2:
1055
        prefixes |= PREFIX_REPNZ;
1056
        goto next_byte;
1057
    case 0xf0:
1058
        prefixes |= PREFIX_LOCK;
1059
        goto next_byte;
1060
    case 0x2e:
1061
        prefixes |= PREFIX_CS;
1062
        goto next_byte;
1063
    case 0x36:
1064
        prefixes |= PREFIX_SS;
1065
        goto next_byte;
1066
    case 0x3e:
1067
        prefixes |= PREFIX_DS;
1068
        goto next_byte;
1069
    case 0x26:
1070
        prefixes |= PREFIX_ES;
1071
        goto next_byte;
1072
    case 0x64:
1073
        prefixes |= PREFIX_FS;
1074
        goto next_byte;
1075
    case 0x65:
1076
        prefixes |= PREFIX_GS;
1077
        goto next_byte;
1078
    case 0x66:
1079
        prefixes |= PREFIX_DATA;
1080
        goto next_byte;
1081
    case 0x67:
1082
        prefixes |= PREFIX_ADR;
1083
        goto next_byte;
1084
    case 0x9b:
1085
        prefixes |= PREFIX_FWAIT;
1086
        goto next_byte;
1087
    }
1088

    
1089
    if (prefixes & PREFIX_DATA)
1090
        dflag ^= 1;
1091
    if (prefixes & PREFIX_ADR)
1092
        aflag ^= 1;
1093

    
1094
    s->prefix = prefixes;
1095
    s->aflag = aflag;
1096
    s->dflag = dflag;
1097

    
1098
    /* now check op code */
1099
 reswitch:
1100
    switch(b) {
1101
    case 0x0f:
1102
        /**************************/
1103
        /* extended op code */
1104
        b = ldub(s->pc++) | 0x100;
1105
        goto reswitch;
1106
        
1107
        /**************************/
1108
        /* arith & logic */
1109
    case 0x00 ... 0x05:
1110
    case 0x08 ... 0x0d:
1111
    case 0x10 ... 0x15:
1112
    case 0x18 ... 0x1d:
1113
    case 0x20 ... 0x25:
1114
    case 0x28 ... 0x2d:
1115
    case 0x30 ... 0x35:
1116
    case 0x38 ... 0x3d:
1117
        {
1118
            int op, f, val;
1119
            op = (b >> 3) & 7;
1120
            f = (b >> 1) & 3;
1121

    
1122
            if ((b & 1) == 0)
1123
                ot = OT_BYTE;
1124
            else
1125
                ot = dflag ? OT_LONG : OT_WORD;
1126
            
1127
            switch(f) {
1128
            case 0: /* OP Ev, Gv */
1129
                modrm = ldub(s->pc++);
1130
                reg = ((modrm >> 3) & 7) + OR_EAX;
1131
                mod = (modrm >> 6) & 3;
1132
                rm = modrm & 7;
1133
                if (mod != 3) {
1134
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1135
                    gen_op_ld_T0_A0[ot]();
1136
                    opreg = OR_TMP0;
1137
                } else {
1138
                    opreg = OR_EAX + rm;
1139
                }
1140
                gen_op(s, op, ot, opreg, reg);
1141
                if (mod != 3 && op != 7) {
1142
                    gen_op_st_T0_A0[ot]();
1143
                }
1144
                break;
1145
            case 1: /* OP Gv, Ev */
1146
                modrm = ldub(s->pc++);
1147
                mod = (modrm >> 6) & 3;
1148
                reg = ((modrm >> 3) & 7) + OR_EAX;
1149
                rm = modrm & 7;
1150
                if (mod != 3) {
1151
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1152
                    gen_op_ld_T1_A0[ot]();
1153
                    opreg = OR_TMP1;
1154
                } else {
1155
                    opreg = OR_EAX + rm;
1156
                }
1157
                gen_op(s, op, ot, reg, opreg);
1158
                break;
1159
            case 2: /* OP A, Iv */
1160
                val = insn_get(s, ot);
1161
                gen_opi(s, op, ot, OR_EAX, val);
1162
                break;
1163
            }
1164
        }
1165
        break;
1166

    
1167
    case 0x80: /* GRP1 */
1168
    case 0x81:
1169
    case 0x83:
1170
        {
1171
            int val;
1172

    
1173
            if ((b & 1) == 0)
1174
                ot = OT_BYTE;
1175
            else
1176
                ot = dflag ? OT_LONG : OT_WORD;
1177
            
1178
            modrm = ldub(s->pc++);
1179
            mod = (modrm >> 6) & 3;
1180
            rm = modrm & 7;
1181
            op = (modrm >> 3) & 7;
1182
            
1183
            if (mod != 3) {
1184
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1185
                gen_op_ld_T0_A0[ot]();
1186
                opreg = OR_TMP0;
1187
            } else {
1188
                opreg = rm + OR_EAX;
1189
            }
1190

    
1191
            switch(b) {
1192
            default:
1193
            case 0x80:
1194
            case 0x81:
1195
                val = insn_get(s, ot);
1196
                break;
1197
            case 0x83:
1198
                val = (int8_t)insn_get(s, OT_BYTE);
1199
                break;
1200
            }
1201

    
1202
            gen_opi(s, op, ot, opreg, val);
1203
            if (op != 7 && mod != 3) {
1204
                gen_op_st_T0_A0[ot]();
1205
            }
1206
        }
1207
        break;
1208

    
1209
        /**************************/
1210
        /* inc, dec, and other misc arith */
1211
    case 0x40 ... 0x47: /* inc Gv */
1212
        ot = dflag ? OT_LONG : OT_WORD;
1213
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
1214
        break;
1215
    case 0x48 ... 0x4f: /* dec Gv */
1216
        ot = dflag ? OT_LONG : OT_WORD;
1217
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
1218
        break;
1219
    case 0xf6: /* GRP3 */
1220
    case 0xf7:
1221
        if ((b & 1) == 0)
1222
            ot = OT_BYTE;
1223
        else
1224
            ot = dflag ? OT_LONG : OT_WORD;
1225

    
1226
        modrm = ldub(s->pc++);
1227
        mod = (modrm >> 6) & 3;
1228
        rm = modrm & 7;
1229
        op = (modrm >> 3) & 7;
1230
        if (mod != 3) {
1231
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1232
            gen_op_ld_T0_A0[ot]();
1233
        } else {
1234
            gen_op_mov_TN_reg[ot][0][rm]();
1235
        }
1236

    
1237
        switch(op) {
1238
        case 0: /* test */
1239
            val = insn_get(s, ot);
1240
            gen_op_movl_T1_im(val);
1241
            gen_op_testl_T0_T1_cc();
1242
            s->cc_op = CC_OP_LOGICB + ot;
1243
            break;
1244
        case 2: /* not */
1245
            gen_op_notl_T0();
1246
            if (mod != 3) {
1247
                gen_op_st_T0_A0[ot]();
1248
            } else {
1249
                gen_op_mov_reg_T0[ot][rm]();
1250
            }
1251
            break;
1252
        case 3: /* neg */
1253
            gen_op_negl_T0_cc();
1254
            if (mod != 3) {
1255
                gen_op_st_T0_A0[ot]();
1256
            } else {
1257
                gen_op_mov_reg_T0[ot][rm]();
1258
            }
1259
            s->cc_op = CC_OP_SUBB + ot;
1260
            break;
1261
        case 4: /* mul */
1262
            switch(ot) {
1263
            case OT_BYTE:
1264
                gen_op_mulb_AL_T0();
1265
                break;
1266
            case OT_WORD:
1267
                gen_op_mulw_AX_T0();
1268
                break;
1269
            default:
1270
            case OT_LONG:
1271
                gen_op_mull_EAX_T0();
1272
                break;
1273
            }
1274
            s->cc_op = CC_OP_MUL;
1275
            break;
1276
        case 5: /* imul */
1277
            switch(ot) {
1278
            case OT_BYTE:
1279
                gen_op_imulb_AL_T0();
1280
                break;
1281
            case OT_WORD:
1282
                gen_op_imulw_AX_T0();
1283
                break;
1284
            default:
1285
            case OT_LONG:
1286
                gen_op_imull_EAX_T0();
1287
                break;
1288
            }
1289
            s->cc_op = CC_OP_MUL;
1290
            break;
1291
        case 6: /* div */
1292
            switch(ot) {
1293
            case OT_BYTE:
1294
                gen_op_divb_AL_T0();
1295
                break;
1296
            case OT_WORD:
1297
                gen_op_divw_AX_T0();
1298
                break;
1299
            default:
1300
            case OT_LONG:
1301
                gen_op_divl_EAX_T0();
1302
                break;
1303
            }
1304
            break;
1305
        case 7: /* idiv */
1306
            switch(ot) {
1307
            case OT_BYTE:
1308
                gen_op_idivb_AL_T0();
1309
                break;
1310
            case OT_WORD:
1311
                gen_op_idivw_AX_T0();
1312
                break;
1313
            default:
1314
            case OT_LONG:
1315
                gen_op_idivl_EAX_T0();
1316
                break;
1317
            }
1318
            break;
1319
        default:
1320
            error("GRP3: bad instruction");
1321
            return -1;
1322
        }
1323
        break;
1324

    
1325
    case 0xfe: /* GRP4 */
1326
    case 0xff: /* GRP5 */
1327
        if ((b & 1) == 0)
1328
            ot = OT_BYTE;
1329
        else
1330
            ot = dflag ? OT_LONG : OT_WORD;
1331

    
1332
        modrm = ldub(s->pc++);
1333
        mod = (modrm >> 6) & 3;
1334
        rm = modrm & 7;
1335
        op = (modrm >> 3) & 7;
1336
        if (op >= 2 && b == 0xfe) {
1337
            error("GRP4: bad instruction");
1338
            return -1;
1339
        }
1340
        if (mod != 3) {
1341
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1342
            gen_op_ld_T0_A0[ot]();
1343
        } else {
1344
            gen_op_mov_TN_reg[ot][0][rm]();
1345
        }
1346

    
1347
        switch(op) {
1348
        case 0: /* inc Ev */
1349
            gen_inc(s, ot, OR_TMP0, 1);
1350
            if (mod != 3)
1351
                gen_op_st_T0_A0[ot]();
1352
            else
1353
                gen_op_mov_reg_T0[ot][rm]();
1354
            break;
1355
        case 1: /* dec Ev */
1356
            gen_inc(s, ot, OR_TMP0, -1);
1357
            if (mod != 3)
1358
                gen_op_st_T0_A0[ot]();
1359
            else
1360
                gen_op_mov_reg_T0[ot][rm]();
1361
            break;
1362
        case 2: /* call Ev */
1363
            gen_op_movl_T1_im((long)s->pc);
1364
            gen_op_pushl_T1();
1365
            gen_op_jmp_T0();
1366
            *is_jmp_ptr = 1;
1367
            break;
1368
        case 4: /* jmp Ev */
1369
            gen_op_jmp_T0();
1370
            *is_jmp_ptr = 1;
1371
            break;
1372
        case 6: /* push Ev */
1373
            gen_op_pushl_T0();
1374
            break;
1375
        default:
1376
            error("GRP5: bad instruction");
1377
            return -1;
1378
        }
1379
        break;
1380

    
1381
    case 0x84: /* test Ev, Gv */
1382
    case 0x85: 
1383
        if ((b & 1) == 0)
1384
            ot = OT_BYTE;
1385
        else
1386
            ot = dflag ? OT_LONG : OT_WORD;
1387

    
1388
        modrm = ldub(s->pc++);
1389
        mod = (modrm >> 6) & 3;
1390
        rm = modrm & 7;
1391
        reg = (modrm >> 3) & 7;
1392
        
1393
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1394
        gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1395
        gen_op_testl_T0_T1_cc();
1396
        s->cc_op = CC_OP_LOGICB + ot;
1397
        break;
1398
        
1399
    case 0xa8: /* test eAX, Iv */
1400
    case 0xa9:
1401
        if ((b & 1) == 0)
1402
            ot = OT_BYTE;
1403
        else
1404
            ot = dflag ? OT_LONG : OT_WORD;
1405
        val = insn_get(s, ot);
1406

    
1407
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
1408
        gen_op_movl_T1_im(val);
1409
        gen_op_testl_T0_T1_cc();
1410
        s->cc_op = CC_OP_LOGICB + ot;
1411
        break;
1412
        
1413
    case 0x98: /* CWDE/CBW */
1414
        if (dflag)
1415
            gen_op_movswl_EAX_AX();
1416
        else
1417
            gen_op_movsbw_AX_AL();
1418
        break;
1419
    case 0x99: /* CDQ/CWD */
1420
        if (dflag)
1421
            gen_op_movslq_EDX_EAX();
1422
        else
1423
            gen_op_movswl_DX_AX();
1424
        break;
1425
    case 0x1af: /* imul Gv, Ev */
1426
    case 0x69: /* imul Gv, Ev, I */
1427
    case 0x6b:
1428
        ot = dflag ? OT_LONG : OT_WORD;
1429
        modrm = ldub(s->pc++);
1430
        reg = ((modrm >> 3) & 7) + OR_EAX;
1431
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1432
        if (b == 0x69) {
1433
            val = insn_get(s, ot);
1434
            gen_op_movl_T1_im(val);
1435
        } else if (b == 0x6b) {
1436
            val = insn_get(s, OT_BYTE);
1437
            gen_op_movl_T1_im(val);
1438
        } else {
1439
            gen_op_mov_TN_reg[ot][1][reg]();
1440
        }
1441

    
1442
        if (ot == OT_LONG) {
1443
            gen_op_imull_T0_T1();
1444
        } else {
1445
            gen_op_imulw_T0_T1();
1446
        }
1447
        gen_op_mov_reg_T0[ot][reg]();
1448
        s->cc_op = CC_OP_MUL;
1449
        break;
1450
        
1451
        /**************************/
1452
        /* push/pop */
1453
    case 0x50 ... 0x57: /* push */
1454
        gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1455
        gen_op_pushl_T0();
1456
        break;
1457
    case 0x58 ... 0x5f: /* pop */
1458
        gen_op_popl_T0();
1459
        gen_op_mov_reg_T0[OT_LONG][b & 7]();
1460
        break;
1461
    case 0x68: /* push Iv */
1462
    case 0x6a:
1463
        ot = dflag ? OT_LONG : OT_WORD;
1464
        if (b == 0x68)
1465
            val = insn_get(s, ot);
1466
        else
1467
            val = (int8_t)insn_get(s, OT_BYTE);
1468
        gen_op_movl_T0_im(val);
1469
        gen_op_pushl_T0();
1470
        break;
1471
    case 0x8f: /* pop Ev */
1472
        ot = dflag ? OT_LONG : OT_WORD;
1473
        modrm = ldub(s->pc++);
1474
        gen_op_popl_T0();
1475
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1476
        break;
1477
    case 0xc9: /* leave */
1478
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1479
        gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1480
        gen_op_popl_T0();
1481
        gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1482
        break;
1483
        /**************************/
1484
        /* mov */
1485
    case 0x88:
1486
    case 0x89: /* mov Gv, Ev */
1487
        if ((b & 1) == 0)
1488
            ot = OT_BYTE;
1489
        else
1490
            ot = dflag ? OT_LONG : OT_WORD;
1491
        modrm = ldub(s->pc++);
1492
        reg = (modrm >> 3) & 7;
1493
        
1494
        /* generate a generic store */
1495
        gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1496
        break;
1497
    case 0xc6:
1498
    case 0xc7: /* mov Ev, Iv */
1499
        if ((b & 1) == 0)
1500
            ot = OT_BYTE;
1501
        else
1502
            ot = dflag ? OT_LONG : OT_WORD;
1503
        modrm = ldub(s->pc++);
1504
        mod = (modrm >> 6) & 3;
1505
        if (mod != 3)
1506
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1507
        val = insn_get(s, ot);
1508
        gen_op_movl_T0_im(val);
1509
        if (mod != 3)
1510
            gen_op_st_T0_A0[ot]();
1511
        else
1512
            gen_op_mov_reg_T0[ot][modrm & 7]();
1513
        break;
1514
    case 0x8a:
1515
    case 0x8b: /* mov Ev, Gv */
1516
        if ((b & 1) == 0)
1517
            ot = OT_BYTE;
1518
        else
1519
            ot = dflag ? OT_LONG : OT_WORD;
1520
        modrm = ldub(s->pc++);
1521
        reg = (modrm >> 3) & 7;
1522
        
1523
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1524
        gen_op_mov_reg_T0[ot][reg]();
1525
        break;
1526

    
1527
    case 0x1b6: /* movzbS Gv, Eb */
1528
    case 0x1b7: /* movzwS Gv, Eb */
1529
    case 0x1be: /* movsbS Gv, Eb */
1530
    case 0x1bf: /* movswS Gv, Eb */
1531
        {
1532
            int d_ot;
1533
            /* d_ot is the size of destination */
1534
            d_ot = dflag + OT_WORD;
1535
            /* ot is the size of source */
1536
            ot = (b & 1) + OT_BYTE;
1537
            modrm = ldub(s->pc++);
1538
            reg = ((modrm >> 3) & 7) + OR_EAX;
1539
            mod = (modrm >> 6) & 3;
1540
            rm = modrm & 7;
1541
            
1542
            if (mod == 3) {
1543
                gen_op_mov_TN_reg[ot][0][rm]();
1544
                switch(ot | (b & 8)) {
1545
                case OT_BYTE:
1546
                    gen_op_movzbl_T0_T0();
1547
                    break;
1548
                case OT_BYTE | 8:
1549
                    gen_op_movsbl_T0_T0();
1550
                    break;
1551
                case OT_WORD:
1552
                    gen_op_movzwl_T0_T0();
1553
                    break;
1554
                default:
1555
                case OT_WORD | 8:
1556
                    gen_op_movswl_T0_T0();
1557
                    break;
1558
                }
1559
                gen_op_mov_reg_T0[d_ot][reg]();
1560
            } else {
1561
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1562
                if (b & 8) {
1563
                    gen_op_lds_T0_A0[ot]();
1564
                } else {
1565
                    gen_op_ldu_T0_A0[ot]();
1566
                }
1567
                gen_op_mov_reg_T0[d_ot][reg]();
1568
            }
1569
        }
1570
        break;
1571

    
1572
    case 0x8d: /* lea */
1573
        ot = dflag ? OT_LONG : OT_WORD;
1574
        modrm = ldub(s->pc++);
1575
        reg = (modrm >> 3) & 7;
1576

    
1577
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1578
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1579
        break;
1580
        
1581
    case 0xa0: /* mov EAX, Ov */
1582
    case 0xa1:
1583
    case 0xa2: /* mov Ov, EAX */
1584
    case 0xa3:
1585
        if ((b & 1) == 0)
1586
            ot = OT_BYTE;
1587
        else
1588
            ot = dflag ? OT_LONG : OT_WORD;
1589
        if (s->aflag)
1590
            offset_addr = insn_get(s, OT_LONG);
1591
        else
1592
            offset_addr = insn_get(s, OT_WORD);
1593
        gen_op_movl_A0_im(offset_addr);
1594
        if ((b & 2) == 0) {
1595
            gen_op_ld_T0_A0[ot]();
1596
            gen_op_mov_reg_T0[ot][R_EAX]();
1597
        } else {
1598
            gen_op_mov_TN_reg[ot][0][R_EAX]();
1599
            gen_op_st_T0_A0[ot]();
1600
        }
1601
        break;
1602

    
1603
    case 0xb0 ... 0xb7: /* mov R, Ib */
1604
        val = insn_get(s, OT_BYTE);
1605
        gen_op_movl_T0_im(val);
1606
        gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1607
        break;
1608
    case 0xb8 ... 0xbf: /* mov R, Iv */
1609
        ot = dflag ? OT_LONG : OT_WORD;
1610
        val = insn_get(s, ot);
1611
        reg = OR_EAX + (b & 7);
1612
        gen_op_movl_T0_im(val);
1613
        gen_op_mov_reg_T0[ot][reg]();
1614
        break;
1615

    
1616
    case 0x91 ... 0x97: /* xchg R, EAX */
1617
        ot = dflag ? OT_LONG : OT_WORD;
1618
        reg = b & 7;
1619
        gen_op_mov_TN_reg[ot][0][reg]();
1620
        gen_op_mov_TN_reg[ot][1][R_EAX]();
1621
        gen_op_mov_reg_T0[ot][R_EAX]();
1622
        gen_op_mov_reg_T1[ot][reg]();
1623
        break;
1624
    case 0x86:
1625
    case 0x87: /* xchg Ev, Gv */
1626
        if ((b & 1) == 0)
1627
            ot = OT_BYTE;
1628
        else
1629
            ot = dflag ? OT_LONG : OT_WORD;
1630
        modrm = ldub(s->pc++);
1631
        reg = (modrm >> 3) & 7;
1632

    
1633
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1634
        gen_op_mov_TN_reg[ot][0][reg]();
1635
        gen_op_ld_T1_A0[ot]();
1636
        gen_op_st_T0_A0[ot]();
1637
        gen_op_mov_reg_T1[ot][reg]();
1638
        break;
1639
        
1640
        /************************/
1641
        /* shifts */
1642
    case 0xc0:
1643
    case 0xc1:
1644
        /* shift Ev,Ib */
1645
        shift = 2;
1646
    grp2:
1647
        {
1648
            if ((b & 1) == 0)
1649
                ot = OT_BYTE;
1650
            else
1651
                ot = dflag ? OT_LONG : OT_WORD;
1652
            
1653
            modrm = ldub(s->pc++);
1654
            mod = (modrm >> 6) & 3;
1655
            rm = modrm & 7;
1656
            op = (modrm >> 3) & 7;
1657
            
1658
            if (mod != 3) {
1659
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1660
                gen_op_ld_T0_A0[ot]();
1661
                opreg = OR_TMP0;
1662
            } else {
1663
                opreg = rm + OR_EAX;
1664
            }
1665

    
1666
            /* simpler op */
1667
            if (shift == 0) {
1668
                gen_shift(s, op, ot, opreg, OR_ECX);
1669
            } else {
1670
                if (shift == 2) {
1671
                    shift = ldub(s->pc++);
1672
                }
1673
                gen_shifti(s, op, ot, opreg, shift);
1674
            }
1675

    
1676
            if (mod != 3) {
1677
                gen_op_st_T0_A0[ot]();
1678
            }
1679
        }
1680
        break;
1681
    case 0xd0:
1682
    case 0xd1:
1683
        /* shift Ev,1 */
1684
        shift = 1;
1685
        goto grp2;
1686
    case 0xd2:
1687
    case 0xd3:
1688
        /* shift Ev,cl */
1689
        shift = 0;
1690
        goto grp2;
1691

    
1692
        /************************/
1693
        /* floats */
1694
    case 0xd8 ... 0xdf: 
1695
        modrm = ldub(s->pc++);
1696
        mod = (modrm >> 6) & 3;
1697
        rm = modrm & 7;
1698
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1699
        
1700
        if (mod != 3) {
1701
            /* memory op */
1702
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1703
            switch(op) {
1704
            case 0x00 ... 0x07: /* fxxxs */
1705
            case 0x10 ... 0x17: /* fixxxl */
1706
            case 0x20 ... 0x27: /* fxxxl */
1707
            case 0x30 ... 0x37: /* fixxx */
1708
                {
1709
                    int op1;
1710
                    op1 = op & 7;
1711

    
1712
                    switch(op >> 4) {
1713
                    case 0:
1714
                        gen_op_flds_FT0_A0();
1715
                        break;
1716
                    case 1:
1717
                        gen_op_fildl_FT0_A0();
1718
                        break;
1719
                    case 2:
1720
                        gen_op_fldl_FT0_A0();
1721
                        break;
1722
                    case 3:
1723
                    default:
1724
                        gen_op_fild_FT0_A0();
1725
                        break;
1726
                    }
1727
                    
1728
                    gen_op_fp_arith_ST0_FT0[op1]();
1729
                    if (op1 == 3) {
1730
                        /* fcomp needs pop */
1731
                        gen_op_fpop();
1732
                    }
1733
                }
1734
                break;
1735
            case 0x08: /* flds */
1736
            case 0x0a: /* fsts */
1737
            case 0x0b: /* fstps */
1738
            case 0x18: /* fildl */
1739
            case 0x1a: /* fistl */
1740
            case 0x1b: /* fistpl */
1741
            case 0x28: /* fldl */
1742
            case 0x2a: /* fstl */
1743
            case 0x2b: /* fstpl */
1744
            case 0x38: /* filds */
1745
            case 0x3a: /* fists */
1746
            case 0x3b: /* fistps */
1747
                
1748
                switch(op & 7) {
1749
                case 0:
1750
                    gen_op_fpush();
1751
                    switch(op >> 4) {
1752
                    case 0:
1753
                        gen_op_flds_ST0_A0();
1754
                        break;
1755
                    case 1:
1756
                        gen_op_fildl_ST0_A0();
1757
                        break;
1758
                    case 2:
1759
                        gen_op_fldl_ST0_A0();
1760
                        break;
1761
                    case 3:
1762
                    default:
1763
                        gen_op_fild_ST0_A0();
1764
                        break;
1765
                    }
1766
                    break;
1767
                default:
1768
                    switch(op >> 4) {
1769
                    case 0:
1770
                        gen_op_fsts_ST0_A0();
1771
                        break;
1772
                    case 1:
1773
                        gen_op_fistl_ST0_A0();
1774
                        break;
1775
                    case 2:
1776
                        gen_op_fstl_ST0_A0();
1777
                        break;
1778
                    case 3:
1779
                    default:
1780
                        gen_op_fist_ST0_A0();
1781
                        break;
1782
                    }
1783
                    if ((op & 7) == 3)
1784
                        gen_op_fpop();
1785
                    break;
1786
                }
1787
                break;
1788
            case 0x0d: /* fldcw mem */
1789
                gen_op_fldcw_A0();
1790
                break;
1791
            case 0x0f: /* fnstcw mem */
1792
                gen_op_fnstcw_A0();
1793
                break;
1794
            case 0x2f: /* fnstsw mem */
1795
                gen_op_fnstsw_A0();
1796
                break;
1797
            case 0x3c: /* fbld */
1798
            case 0x3e: /* fbstp */
1799
                error("float BCD not hanlded");
1800
                return -1;
1801
            case 0x3d: /* fildll */
1802
                gen_op_fpush();
1803
                gen_op_fildll_ST0_A0();
1804
                break;
1805
            case 0x3f: /* fistpll */
1806
                gen_op_fistll_ST0_A0();
1807
                gen_op_fpop();
1808
                break;
1809
            default:
1810
                error("unhandled memory FP [op=0x%02x]\n", op);
1811
                return -1;
1812
            }
1813
        } else {
1814
            /* register float ops */
1815
            opreg = rm;
1816

    
1817
            switch(op) {
1818
            case 0x08: /* fld sti */
1819
                gen_op_fpush();
1820
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
1821
                break;
1822
            case 0x09: /* fxchg sti */
1823
                gen_op_fxchg_ST0_STN((opreg + 1) & 7);
1824
                break;
1825
            case 0x0a: /* grp d9/2 */
1826
                switch(rm) {
1827
                case 0: /* fnop */
1828
                    break;
1829
                default:
1830
                    error("unhandled FP GRP d9/2\n");
1831
                    return -1;
1832
                }
1833
                break;
1834
            case 0x0c: /* grp d9/4 */
1835
                switch(rm) {
1836
                case 0: /* fchs */
1837
                    gen_op_fchs_ST0();
1838
                    break;
1839
                case 1: /* fabs */
1840
                    gen_op_fabs_ST0();
1841
                    break;
1842
                case 4: /* ftst */
1843
                    gen_op_fldz_FT0();
1844
                    gen_op_fcom_ST0_FT0();
1845
                    break;
1846
                case 5: /* fxam */
1847
                    gen_op_fxam_ST0();
1848
                    break;
1849
                default:
1850
                    return -1;
1851
                }
1852
                break;
1853
            case 0x0d: /* grp d9/5 */
1854
                {
1855
                    switch(rm) {
1856
                    case 0:
1857
                        gen_op_fld1_ST0();
1858
                        break;
1859
                    case 1:
1860
                        gen_op_fld2t_ST0();
1861
                        break;
1862
                    case 2:
1863
                        gen_op_fld2e_ST0();
1864
                        break;
1865
                    case 3:
1866
                        gen_op_fldpi_ST0();
1867
                        break;
1868
                    case 4:
1869
                        gen_op_fldlg2_ST0();
1870
                        break;
1871
                    case 5:
1872
                        gen_op_fldln2_ST0();
1873
                        break;
1874
                    case 6:
1875
                        gen_op_fldz_ST0();
1876
                        break;
1877
                    default:
1878
                        return -1;
1879
                    }
1880
                }
1881
                break;
1882
            case 0x0e: /* grp d9/6 */
1883
                switch(rm) {
1884
                case 0: /* f2xm1 */
1885
                    gen_op_f2xm1();
1886
                    break;
1887
                case 1: /* fyl2x */
1888
                    gen_op_fyl2x();
1889
                    break;
1890
                case 2: /* fptan */
1891
                    gen_op_fptan();
1892
                    break;
1893
                case 3: /* fpatan */
1894
                    gen_op_fpatan();
1895
                    break;
1896
                case 4: /* fxtract */
1897
                    gen_op_fxtract();
1898
                    break;
1899
                case 5: /* fprem1 */
1900
                    gen_op_fprem1();
1901
                    break;
1902
                case 6: /* fdecstp */
1903
                    gen_op_fdecstp();
1904
                    break;
1905
                default:
1906
                case 7: /* fincstp */
1907
                    gen_op_fincstp();
1908
                    break;
1909
                }
1910
                break;
1911
            case 0x0f: /* grp d9/7 */
1912
                switch(rm) {
1913
                case 0: /* fprem */
1914
                    gen_op_fprem();
1915
                    break;
1916
                case 1: /* fyl2xp1 */
1917
                    gen_op_fyl2xp1();
1918
                    break;
1919
                case 2: /* fsqrt */
1920
                    gen_op_fsqrt();
1921
                    break;
1922
                case 3: /* fsincos */
1923
                    gen_op_fsincos();
1924
                    break;
1925
                case 5: /* fscale */
1926
                    gen_op_fscale();
1927
                    break;
1928
                case 4: /* frndint */
1929
                    gen_op_frndint();
1930
                    break;
1931
                case 6: /* fsin */
1932
                    gen_op_fsin();
1933
                    break;
1934
                default:
1935
                case 7: /* fcos */
1936
                    gen_op_fcos();
1937
                    break;
1938
                }
1939
                break;
1940
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
1941
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
1942
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
1943
                {
1944
                    int op1;
1945
                    
1946
                    op1 = op & 7;
1947
                    if (op >= 0x20) {
1948
                        gen_op_fp_arith_STN_ST0[op1](opreg);
1949
                    } else {
1950
                        gen_op_fmov_FT0_STN(opreg);
1951
                        gen_op_fp_arith_ST0_FT0[op1]();
1952
                    }
1953
                    if (op >= 0x30)
1954
                        gen_op_fpop();
1955
                }
1956
                break;
1957
            case 0x02: /* fcom */
1958
                gen_op_fmov_FT0_STN(opreg);
1959
                gen_op_fcom_ST0_FT0();
1960
                break;
1961
            case 0x03: /* fcomp */
1962
                gen_op_fmov_FT0_STN(opreg);
1963
                gen_op_fcom_ST0_FT0();
1964
                gen_op_fpop();
1965
                break;
1966
            case 0x15: /* da/5 */
1967
                switch(rm) {
1968
                case 1: /* fucompp */
1969
                    gen_op_fmov_FT0_STN(1);
1970
                    gen_op_fcom_ST0_FT0();
1971
                    gen_op_fpop();
1972
                    gen_op_fpop();
1973
                    break;
1974
                default:
1975
                    return -1;
1976
                }
1977
                break;
1978
            case 0x2a: /* fst sti */
1979
                gen_op_fmov_STN_ST0(opreg);
1980
                break;
1981
            case 0x2b: /* fstp sti */
1982
                gen_op_fmov_STN_ST0(opreg);
1983
                gen_op_fpop();
1984
                break;
1985
            case 0x33: /* de/3 */
1986
                switch(rm) {
1987
                case 1: /* fcompp */
1988
                    gen_op_fmov_FT0_STN(1);
1989
                    gen_op_fcom_ST0_FT0();
1990
                    gen_op_fpop();
1991
                    gen_op_fpop();
1992
                    break;
1993
                default:
1994
                    return -1;
1995
                }
1996
                break;
1997
            case 0x3c: /* df/4 */
1998
                switch(rm) {
1999
#if 0
2000
                case 0:
2001
                    gen_insn3(OP_FNSTS, OR_EAX, OR_ZERO, OR_ZERO);
2002
                    break;
2003
#endif
2004
                default:
2005
                    return -1;
2006
                }
2007
                break;
2008
            default:
2009
                error("unhandled FP\n");
2010
                return -1;
2011
            }
2012
        }
2013
        break;
2014
        /************************/
2015
        /* string ops */
2016
    case 0xa4: /* movsS */
2017
    case 0xa5:
2018
        if ((b & 1) == 0)
2019
            ot = OT_BYTE;
2020
        else
2021
            ot = dflag ? OT_LONG : OT_WORD;
2022
        if (prefixes & PREFIX_REPZ) {
2023
            gen_op_movs[3 + ot]();
2024
        } else {
2025
            gen_op_movs[ot]();
2026
        }
2027
        break;
2028
        
2029
    case 0xaa: /* stosS */
2030
    case 0xab:
2031
        if ((b & 1) == 0)
2032
            ot = OT_BYTE;
2033
        else
2034
            ot = dflag ? OT_LONG : OT_WORD;
2035
        if (prefixes & PREFIX_REPZ) {
2036
            gen_op_stos[3 + ot]();
2037
        } else {
2038
            gen_op_stos[ot]();
2039
        }
2040
        break;
2041
    case 0xac: /* lodsS */
2042
    case 0xad:
2043
        if ((b & 1) == 0)
2044
            ot = OT_BYTE;
2045
        else
2046
            ot = dflag ? OT_LONG : OT_WORD;
2047
        if (prefixes & PREFIX_REPZ) {
2048
            gen_op_lods[3 + ot]();
2049
        } else {
2050
            gen_op_lods[ot]();
2051
        }
2052
        break;
2053
    case 0xae: /* scasS */
2054
    case 0xaf:
2055
        if ((b & 1) == 0)
2056
            ot = OT_BYTE;
2057
        else
2058
            ot = dflag ? OT_LONG : OT_WORD;
2059
        if (prefixes & PREFIX_REPNZ) {
2060
            if (s->cc_op != CC_OP_DYNAMIC)
2061
                gen_op_set_cc_op(s->cc_op);
2062
            gen_op_scas[6 + ot]();
2063
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2064
        } else if (prefixes & PREFIX_REPZ) {
2065
            if (s->cc_op != CC_OP_DYNAMIC)
2066
                gen_op_set_cc_op(s->cc_op);
2067
            gen_op_scas[3 + ot]();
2068
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2069
        } else {
2070
            gen_op_scas[ot]();
2071
            s->cc_op = CC_OP_SUBB + ot;
2072
        }
2073
        break;
2074

    
2075
    case 0xa6: /* cmpsS */
2076
    case 0xa7:
2077
        if ((b & 1) == 0)
2078
            ot = OT_BYTE;
2079
        else
2080
            ot = dflag ? OT_LONG : OT_WORD;
2081
        if (prefixes & PREFIX_REPNZ) {
2082
            if (s->cc_op != CC_OP_DYNAMIC)
2083
                gen_op_set_cc_op(s->cc_op);
2084
            gen_op_cmps[6 + ot]();
2085
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2086
        } else if (prefixes & PREFIX_REPZ) {
2087
            if (s->cc_op != CC_OP_DYNAMIC)
2088
                gen_op_set_cc_op(s->cc_op);
2089
            gen_op_cmps[3 + ot]();
2090
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2091
        } else {
2092
            gen_op_cmps[ot]();
2093
            s->cc_op = CC_OP_SUBB + ot;
2094
        }
2095
        break;
2096
        
2097
        /************************/
2098
        /* port I/O */
2099
    case 0x6c: /* insS */
2100
    case 0x6d:
2101
        if ((b & 1) == 0)
2102
            ot = OT_BYTE;
2103
        else
2104
            ot = dflag ? OT_LONG : OT_WORD;
2105
        if (prefixes & PREFIX_REPZ) {
2106
            gen_op_ins[3 + ot]();
2107
        } else {
2108
            gen_op_ins[ot]();
2109
        }
2110
        break;
2111
    case 0x6e: /* outsS */
2112
    case 0x6f:
2113
        if ((b & 1) == 0)
2114
            ot = OT_BYTE;
2115
        else
2116
            ot = dflag ? OT_LONG : OT_WORD;
2117
        if (prefixes & PREFIX_REPZ) {
2118
            gen_op_outs[3 + ot]();
2119
        } else {
2120
            gen_op_outs[ot]();
2121
        }
2122
        break;
2123
    case 0xe4:
2124
    case 0xe5:
2125
        if ((b & 1) == 0)
2126
            ot = OT_BYTE;
2127
        else
2128
            ot = dflag ? OT_LONG : OT_WORD;
2129
        val = ldub(s->pc++);
2130
        gen_op_movl_T0_im(val);
2131
        gen_op_in[ot]();
2132
        gen_op_mov_reg_T1[ot][R_EAX]();
2133
        break;
2134
    case 0xe6:
2135
    case 0xe7:
2136
        if ((b & 1) == 0)
2137
            ot = OT_BYTE;
2138
        else
2139
            ot = dflag ? OT_LONG : OT_WORD;
2140
        val = ldub(s->pc++);
2141
        gen_op_movl_T0_im(val);
2142
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2143
        gen_op_out[ot]();
2144
        break;
2145
    case 0xec:
2146
    case 0xed:
2147
        if ((b & 1) == 0)
2148
            ot = OT_BYTE;
2149
        else
2150
            ot = dflag ? OT_LONG : OT_WORD;
2151
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2152
        gen_op_in[ot]();
2153
        gen_op_mov_reg_T1[ot][R_EAX]();
2154
        break;
2155
    case 0xee:
2156
    case 0xef:
2157
        if ((b & 1) == 0)
2158
            ot = OT_BYTE;
2159
        else
2160
            ot = dflag ? OT_LONG : OT_WORD;
2161
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2162
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2163
        gen_op_out[ot]();
2164
        break;
2165

    
2166
        /************************/
2167
        /* control */
2168
    case 0xc2: /* ret im */
2169
        /* XXX: handle stack pop ? */
2170
        val = ldsw(s->pc);
2171
        s->pc += 2;
2172
        gen_op_popl_T0();
2173
        gen_op_addl_ESP_im(val);
2174
        gen_op_jmp_T0();
2175
        *is_jmp_ptr = 1;
2176
        break;
2177
    case 0xc3: /* ret */
2178
        gen_op_popl_T0();
2179
        gen_op_jmp_T0();
2180
        *is_jmp_ptr = 1;
2181
        break;
2182
    case 0xe8: /* call */
2183
        val = insn_get(s, OT_LONG);
2184
        val += (long)s->pc;
2185
        gen_op_movl_T1_im((long)s->pc);
2186
        gen_op_pushl_T1();
2187
        gen_op_jmp_im(val);
2188
        *is_jmp_ptr = 1;
2189
        break;
2190
    case 0xe9: /* jmp */
2191
        val = insn_get(s, OT_LONG);
2192
        val += (long)s->pc;
2193
        gen_op_jmp_im(val);
2194
        *is_jmp_ptr = 1;
2195
        break;
2196
    case 0xeb: /* jmp Jb */
2197
        val = (int8_t)insn_get(s, OT_BYTE);
2198
        val += (long)s->pc;
2199
        gen_op_jmp_im(val);
2200
        *is_jmp_ptr = 1;
2201
        break;
2202
    case 0x70 ... 0x7f: /* jcc Jb */
2203
        val = (int8_t)insn_get(s, OT_BYTE);
2204
        val += (long)s->pc;
2205
        goto do_jcc;
2206
    case 0x180 ... 0x18f: /* jcc Jv */
2207
        if (dflag) {
2208
            val = insn_get(s, OT_LONG);
2209
        } else {
2210
            val = (int16_t)insn_get(s, OT_WORD); 
2211
        }
2212
        val += (long)s->pc; /* XXX: fix 16 bit wrap */
2213
    do_jcc:
2214
        gen_jcc(s, b, val);
2215
        *is_jmp_ptr = 1;
2216
        break;
2217

    
2218
    case 0x190 ... 0x19f:
2219
        modrm = ldub(s->pc++);
2220
        gen_setcc(s, b);
2221
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2222
        break;
2223

    
2224
        /************************/
2225
        /* flags */
2226
    case 0x9c: /* pushf */
2227
        gen_op_movl_T0_eflags();
2228
        gen_op_pushl_T0();
2229
        break;
2230
    case 0x9d: /* popf */
2231
        gen_op_popl_T0();
2232
        gen_op_movl_eflags_T0();
2233
        s->cc_op = CC_OP_EFLAGS;
2234
        break;
2235
    case 0x9e: /* sahf */
2236
        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2237
        if (s->cc_op != CC_OP_DYNAMIC)
2238
            op_set_cc_op(s->cc_op);
2239
        gen_op_movb_eflags_T0();
2240
        s->cc_op = CC_OP_EFLAGS;
2241
        break;
2242
    case 0x9f: /* lahf */
2243
        if (s->cc_op != CC_OP_DYNAMIC)
2244
            op_set_cc_op(s->cc_op);
2245
        gen_op_movl_T0_eflags();
2246
        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2247
        break;
2248
    case 0xf5: /* cmc */
2249
        if (s->cc_op != CC_OP_DYNAMIC)
2250
            op_set_cc_op(s->cc_op);
2251
        gen_op_cmc();
2252
        s->cc_op = CC_OP_EFLAGS;
2253
        break;
2254
    case 0xf8: /* clc */
2255
        if (s->cc_op != CC_OP_DYNAMIC)
2256
            op_set_cc_op(s->cc_op);
2257
        gen_op_clc();
2258
        s->cc_op = CC_OP_EFLAGS;
2259
        break;
2260
    case 0xf9: /* stc */
2261
        if (s->cc_op != CC_OP_DYNAMIC)
2262
            op_set_cc_op(s->cc_op);
2263
        gen_op_stc();
2264
        s->cc_op = CC_OP_EFLAGS;
2265
        break;
2266
    case 0xfc: /* cld */
2267
        gen_op_cld();
2268
        break;
2269
    case 0xfd: /* std */
2270
        gen_op_std();
2271
        break;
2272

    
2273
        /************************/
2274
        /* bit operations */
2275
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
2276
        ot = dflag ? OT_LONG : OT_WORD;
2277
        modrm = ldub(s->pc++);
2278
        op = (modrm >> 3) & 7;
2279
        mod = (modrm >> 6) & 3;
2280
        rm = modrm & 7;
2281
        if (mod != 3) {
2282
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2283
            gen_op_ld_T0_A0[ot]();
2284
        } else {
2285
            gen_op_mov_TN_reg[ot][0][rm]();
2286
        }
2287
        /* load shift */
2288
        val = ldub(s->pc++);
2289
        gen_op_movl_T1_im(val);
2290
        if (op < 4)
2291
            return -1;
2292
        op -= 4;
2293
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2294
        s->cc_op = CC_OP_SHLB + ot;
2295
        if (op != 0) {
2296
            if (mod != 3)
2297
                gen_op_st_T0_A0[ot]();
2298
            else
2299
                gen_op_mov_reg_T0[ot][rm]();
2300
        }
2301
        break;
2302
    case 0x1a3: /* bt Gv, Ev */
2303
        op = 0;
2304
        goto do_btx;
2305
    case 0x1ab: /* bts */
2306
        op = 1;
2307
        goto do_btx;
2308
    case 0x1b3: /* btr */
2309
        op = 2;
2310
        goto do_btx;
2311
    case 0x1bb: /* btc */
2312
        op = 3;
2313
    do_btx:
2314
        ot = dflag ? OT_LONG : OT_WORD;
2315
        modrm = ldub(s->pc++);
2316
        reg = (modrm >> 3) & 7;
2317
        mod = (modrm >> 6) & 3;
2318
        rm = modrm & 7;
2319
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
2320
        if (mod != 3) {
2321
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2322
            /* specific case: we need to add a displacement */
2323
            if (ot == OT_WORD)
2324
                gen_op_add_bitw_A0_T1();
2325
            else
2326
                gen_op_add_bitl_A0_T1();
2327
            gen_op_ld_T0_A0[ot]();
2328
        } else {
2329
            gen_op_mov_TN_reg[ot][0][rm]();
2330
        }
2331
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2332
        s->cc_op = CC_OP_SHLB + ot;
2333
        if (op != 0) {
2334
            if (mod != 3)
2335
                gen_op_st_T0_A0[ot]();
2336
            else
2337
                gen_op_mov_reg_T0[ot][rm]();
2338
        }
2339
        break;
2340

    
2341
        /************************/
2342
        /* misc */
2343
    case 0x90: /* nop */
2344
        break;
2345
    case 0xcc: /* int3 */
2346
        gen_op_int3((long)pc_start);
2347
        *is_jmp_ptr = 1;
2348
        break;
2349
    case 0xcd: /* int N */
2350
        val = ldub(s->pc++);
2351
        /* XXX: currently we ignore the interrupt number */
2352
        gen_op_int_im((long)pc_start);
2353
        *is_jmp_ptr = 1;
2354
        break;
2355
    case 0xce: /* into */
2356
        if (s->cc_op != CC_OP_DYNAMIC)
2357
            gen_op_set_cc_op(s->cc_op);
2358
        gen_op_into((long)pc_start, (long)s->pc);
2359
        *is_jmp_ptr = 1;
2360
        break;
2361
    case 0x1c8 ... 0x1cf: /* bswap reg */
2362
      reg = b & 7;
2363
      gen_op_mov_TN_reg[OT_LONG][0][reg]();
2364
      gen_op_bswapl_T0();
2365
      gen_op_mov_reg_T0[OT_LONG][reg]();
2366
      break;
2367
      
2368
#if 0
2369
    case 0x1a2: /* cpuid */
2370
        gen_insn0(OP_ASM);
2371
        break;
2372
#endif
2373
    default:
2374
        error("unknown opcode %x", b);
2375
        return -1;
2376
    }
2377
    return (long)s->pc;
2378
}
2379

    
2380
/* return the next pc */
2381
int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
2382
                     uint8_t *pc_start)
2383
{
2384
    DisasContext dc1, *dc = &dc1;
2385
    int is_jmp;
2386
    long ret;
2387
#ifdef DEBUG_DISAS
2388
    struct disassemble_info disasm_info;
2389
#endif
2390

    
2391
    dc->cc_op = CC_OP_DYNAMIC;
2392
    gen_code_ptr = gen_code_buf;
2393
    gen_start();
2394

    
2395
#ifdef DEBUG_DISAS
2396
    if (loglevel) {
2397
        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
2398
        disasm_info.buffer = pc_start;
2399
        disasm_info.buffer_vma = (unsigned long)pc_start;
2400
        disasm_info.buffer_length = 15;
2401
#if 0        
2402
        disasm_info.flavour = bfd_get_flavour (abfd);
2403
        disasm_info.arch = bfd_get_arch (abfd);
2404
        disasm_info.mach = bfd_get_mach (abfd);
2405
#endif
2406
#ifdef WORDS_BIGENDIAN
2407
        disasm_info.endian = BFD_ENDIAN_BIG;
2408
#else
2409
        disasm_info.endian = BFD_ENDIAN_LITTLE;
2410
#endif        
2411
        fprintf(logfile, "IN:\n");
2412
        fprintf(logfile, "0x%08lx:  ", (long)pc_start);
2413
        print_insn_i386((unsigned long)pc_start, &disasm_info);
2414
        fprintf(logfile, "\n\n");
2415
    }
2416
#endif
2417
    is_jmp = 0;
2418
    ret = disas_insn(dc, pc_start, &is_jmp);
2419
    if (ret == -1) 
2420
        error("unknown instruction at PC=0x%x", pc_start);
2421
    /* we must store the eflags state if it is not already done */
2422
    if (dc->cc_op != CC_OP_DYNAMIC)
2423
        gen_op_set_cc_op(dc->cc_op);
2424
    if (!is_jmp) {
2425
        /* we add an additionnal jmp to update the simulated PC */
2426
        gen_op_jmp_im(ret);
2427
    }
2428
    gen_end();
2429
    *gen_code_size_ptr = gen_code_ptr - gen_code_buf;
2430

    
2431
#ifdef DEBUG_DISAS
2432
    if (loglevel) {
2433
        uint8_t *pc;
2434
        int count;
2435

    
2436
        pc = gen_code_buf;
2437
        disasm_info.buffer = pc;
2438
        disasm_info.buffer_vma = (unsigned long)pc;
2439
        disasm_info.buffer_length = *gen_code_size_ptr;
2440
        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
2441
        while (pc < gen_code_ptr) {
2442
            fprintf(logfile, "0x%08lx:  ", (long)pc);
2443
            count = print_insn_i386((unsigned long)pc, &disasm_info);
2444
            fprintf(logfile, "\n");
2445
            pc += count;
2446
        }
2447
        fprintf(logfile, "\n");
2448
    }
2449
#endif
2450
    return 0;
2451
}
2452

    
2453
CPUX86State *cpu_x86_init(void)
2454
{
2455
    CPUX86State *env;
2456
    int i;
2457

    
2458
    env = malloc(sizeof(CPUX86State));
2459
    if (!env)
2460
        return NULL;
2461
    memset(env, 0, sizeof(CPUX86State));
2462
    /* basic FPU init */
2463
    for(i = 0;i < 8; i++)
2464
        env->fptags[i] = 1;
2465
    env->fpuc = 0x37f;
2466
    /* flags setup */
2467
    env->cc_op = CC_OP_EFLAGS;
2468
    env->df = 1;
2469
    return env;
2470
}
2471

    
2472
void cpu_x86_close(CPUX86State *env)
2473
{
2474
    free(env);
2475
}