Statistics
| Branch: | Revision:

root / translate-i386.c @ 927f621e

History | View | Annotate | Download (53.3 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 IN_OP_I386
9
#include "cpu-i386.h"
10

    
11
static uint8_t *gen_code_ptr;
12
int __op_param1, __op_param2, __op_param3;
13

    
14
/* supress that */
15
static void error(const char *fmt, ...)
16
{
17
    va_list ap;
18

    
19
    va_start(ap, fmt);
20
    vfprintf(stderr, fmt, ap);
21
    va_end(ap);
22
    exit(1);
23
}
24

    
25
#define PREFIX_REPZ 1
26
#define PREFIX_REPNZ 2
27
#define PREFIX_LOCK 4
28
#define PREFIX_CS 8
29
#define PREFIX_SS 0x10
30
#define PREFIX_DS 0x20
31
#define PREFIX_ES 0x40
32
#define PREFIX_FS 0x80
33
#define PREFIX_GS 0x100
34
#define PREFIX_DATA 0x200
35
#define PREFIX_ADR 0x400
36
#define PREFIX_FWAIT 0x800
37

    
38
typedef struct DisasContext {
39
    /* current insn context */
40
    int prefix;
41
    int aflag, dflag;
42
    uint8_t *pc; /* current pc */
43
    int cc_op; /* current CC operation */
44
    int f_st;
45
} DisasContext;
46

    
47
/* i386 arith/logic operations */
48
enum {
49
    OP_ADDL, 
50
    OP_ORL, 
51
    OP_ADCL, 
52
    OP_SBBL,
53
    OP_ANDL, 
54
    OP_SUBL, 
55
    OP_XORL, 
56
    OP_CMPL,
57
};
58

    
59
/* i386 shift ops */
60
enum {
61
    OP_ROL, 
62
    OP_ROR, 
63
    OP_RCL, 
64
    OP_RCR, 
65
    OP_SHL, 
66
    OP_SHR, 
67
    OP_SHL1, /* undocumented */
68
    OP_SAR = 7,
69
};
70

    
71
#include "op-i386.h"
72

    
73
/* operand size */
74
enum {
75
    OT_BYTE = 0,
76
    OT_WORD,
77
    OT_LONG, 
78
    OT_QUAD,
79
};
80

    
81
enum {
82
    /* I386 int registers */
83
    OR_EAX,   /* MUST be even numbered */
84
    OR_ECX,
85
    OR_EDX,
86
    OR_EBX,
87
    OR_ESP,
88
    OR_EBP,
89
    OR_ESI,
90
    OR_EDI,
91

    
92
    /* I386 float registers */
93
    OR_ST0,
94
    OR_ST1,
95
    OR_ST2,
96
    OR_ST3,
97
    OR_ST4,
98
    OR_ST5,
99
    OR_ST6,
100
    OR_ST7,
101
    OR_TMP0,    /* temporary operand register */
102
    OR_TMP1,
103
    OR_A0, /* temporary register used when doing address evaluation */
104
    OR_EFLAGS,  /* cpu flags */
105
    OR_ITMP0, /* used for byte/word insertion */
106
    OR_ITMP1, /* used for byte/word insertion */
107
    OR_ITMP2, /* used for byte/word insertion */
108
    OR_FTMP0, /* float temporary */
109
    OR_DF,    /* D flag, for string ops */
110
    OR_ZERO, /* fixed zero register */
111
    OR_IM, /* dummy immediate value register */
112
    NB_OREGS,
113
};
114

    
115
#if 0
116
static const double tab_const[7] = {
117
    1.0, 
118
    3.32192809488736234789, /* log2(10) */
119
    M_LOG2E,
120
    M_PI,
121
    0.30102999566398119521, /* log10(2) */
122
    M_LN2,
123
    0.0
124
};
125
#endif
126

    
127
typedef void (GenOpFunc)(void);
128
typedef void (GenOpFunc1)(long);
129
typedef void (GenOpFunc2)(long, long);
130
                    
131
static GenOpFunc *gen_op_mov_reg_T0[3][8] = {
132
    [OT_BYTE] = {
133
        gen_op_movb_EAX_T0,
134
        gen_op_movb_ECX_T0,
135
        gen_op_movb_EDX_T0,
136
        gen_op_movb_EBX_T0,
137
        gen_op_movh_EAX_T0,
138
        gen_op_movh_ECX_T0,
139
        gen_op_movh_EDX_T0,
140
        gen_op_movh_EBX_T0,
141
    },
142
    [OT_WORD] = {
143
        gen_op_movw_EAX_T0,
144
        gen_op_movw_ECX_T0,
145
        gen_op_movw_EDX_T0,
146
        gen_op_movw_EBX_T0,
147
        gen_op_movw_ESP_T0,
148
        gen_op_movw_EBP_T0,
149
        gen_op_movw_ESI_T0,
150
        gen_op_movw_EDI_T0,
151
    },
152
    [OT_LONG] = {
153
        gen_op_movl_EAX_T0,
154
        gen_op_movl_ECX_T0,
155
        gen_op_movl_EDX_T0,
156
        gen_op_movl_EBX_T0,
157
        gen_op_movl_ESP_T0,
158
        gen_op_movl_EBP_T0,
159
        gen_op_movl_ESI_T0,
160
        gen_op_movl_EDI_T0,
161
    },
162
};
163

    
164
static GenOpFunc *gen_op_mov_reg_T1[3][8] = {
165
    [OT_BYTE] = {
166
        gen_op_movb_EAX_T1,
167
        gen_op_movb_ECX_T1,
168
        gen_op_movb_EDX_T1,
169
        gen_op_movb_EBX_T1,
170
        gen_op_movh_EAX_T1,
171
        gen_op_movh_ECX_T1,
172
        gen_op_movh_EDX_T1,
173
        gen_op_movh_EBX_T1,
174
    },
175
    [OT_WORD] = {
176
        gen_op_movw_EAX_T1,
177
        gen_op_movw_ECX_T1,
178
        gen_op_movw_EDX_T1,
179
        gen_op_movw_EBX_T1,
180
        gen_op_movw_ESP_T1,
181
        gen_op_movw_EBP_T1,
182
        gen_op_movw_ESI_T1,
183
        gen_op_movw_EDI_T1,
184
    },
185
    [OT_LONG] = {
186
        gen_op_movl_EAX_T1,
187
        gen_op_movl_ECX_T1,
188
        gen_op_movl_EDX_T1,
189
        gen_op_movl_EBX_T1,
190
        gen_op_movl_ESP_T1,
191
        gen_op_movl_EBP_T1,
192
        gen_op_movl_ESI_T1,
193
        gen_op_movl_EDI_T1,
194
    },
195
};
196

    
197
static GenOpFunc *gen_op_mov_reg_A0[2][8] = {
198
    [0] = {
199
        gen_op_movw_EAX_A0,
200
        gen_op_movw_ECX_A0,
201
        gen_op_movw_EDX_A0,
202
        gen_op_movw_EBX_A0,
203
        gen_op_movw_ESP_A0,
204
        gen_op_movw_EBP_A0,
205
        gen_op_movw_ESI_A0,
206
        gen_op_movw_EDI_A0,
207
    },
208
    [1] = {
209
        gen_op_movl_EAX_A0,
210
        gen_op_movl_ECX_A0,
211
        gen_op_movl_EDX_A0,
212
        gen_op_movl_EBX_A0,
213
        gen_op_movl_ESP_A0,
214
        gen_op_movl_EBP_A0,
215
        gen_op_movl_ESI_A0,
216
        gen_op_movl_EDI_A0,
217
    },
218
};
219

    
220
static GenOpFunc *gen_op_mov_TN_reg[3][2][8] = 
221
{
222
    [OT_BYTE] = {
223
        {
224
            gen_op_movl_T0_EAX,
225
            gen_op_movl_T0_ECX,
226
            gen_op_movl_T0_EDX,
227
            gen_op_movl_T0_EBX,
228
            gen_op_movh_T0_EAX,
229
            gen_op_movh_T0_ECX,
230
            gen_op_movh_T0_EDX,
231
            gen_op_movh_T0_EBX,
232
        },
233
        {
234
            gen_op_movl_T1_EAX,
235
            gen_op_movl_T1_ECX,
236
            gen_op_movl_T1_EDX,
237
            gen_op_movl_T1_EBX,
238
            gen_op_movh_T1_EAX,
239
            gen_op_movh_T1_ECX,
240
            gen_op_movh_T1_EDX,
241
            gen_op_movh_T1_EBX,
242
        },
243
    },
244
    [OT_WORD] = {
245
        {
246
            gen_op_movl_T0_EAX,
247
            gen_op_movl_T0_ECX,
248
            gen_op_movl_T0_EDX,
249
            gen_op_movl_T0_EBX,
250
            gen_op_movl_T0_ESP,
251
            gen_op_movl_T0_EBP,
252
            gen_op_movl_T0_ESI,
253
            gen_op_movl_T0_EDI,
254
        },
255
        {
256
            gen_op_movl_T1_EAX,
257
            gen_op_movl_T1_ECX,
258
            gen_op_movl_T1_EDX,
259
            gen_op_movl_T1_EBX,
260
            gen_op_movl_T1_ESP,
261
            gen_op_movl_T1_EBP,
262
            gen_op_movl_T1_ESI,
263
            gen_op_movl_T1_EDI,
264
        },
265
    },
266
    [OT_LONG] = {
267
        {
268
            gen_op_movl_T0_EAX,
269
            gen_op_movl_T0_ECX,
270
            gen_op_movl_T0_EDX,
271
            gen_op_movl_T0_EBX,
272
            gen_op_movl_T0_ESP,
273
            gen_op_movl_T0_EBP,
274
            gen_op_movl_T0_ESI,
275
            gen_op_movl_T0_EDI,
276
        },
277
        {
278
            gen_op_movl_T1_EAX,
279
            gen_op_movl_T1_ECX,
280
            gen_op_movl_T1_EDX,
281
            gen_op_movl_T1_EBX,
282
            gen_op_movl_T1_ESP,
283
            gen_op_movl_T1_EBP,
284
            gen_op_movl_T1_ESI,
285
            gen_op_movl_T1_EDI,
286
        },
287
    },
288
};
289

    
290
static GenOpFunc *gen_op_movl_A0_reg[8] = {
291
    gen_op_movl_A0_EAX,
292
    gen_op_movl_A0_ECX,
293
    gen_op_movl_A0_EDX,
294
    gen_op_movl_A0_EBX,
295
    gen_op_movl_A0_ESP,
296
    gen_op_movl_A0_EBP,
297
    gen_op_movl_A0_ESI,
298
    gen_op_movl_A0_EDI,
299
};
300

    
301
static GenOpFunc *gen_op_addl_A0_reg_sN[4][8] = {
302
    [0] = {
303
        gen_op_addl_A0_EAX,
304
        gen_op_addl_A0_ECX,
305
        gen_op_addl_A0_EDX,
306
        gen_op_addl_A0_EBX,
307
        gen_op_addl_A0_ESP,
308
        gen_op_addl_A0_EBP,
309
        gen_op_addl_A0_ESI,
310
        gen_op_addl_A0_EDI,
311
    },
312
    [1] = {
313
        gen_op_addl_A0_EAX_s1,
314
        gen_op_addl_A0_ECX_s1,
315
        gen_op_addl_A0_EDX_s1,
316
        gen_op_addl_A0_EBX_s1,
317
        gen_op_addl_A0_ESP_s1,
318
        gen_op_addl_A0_EBP_s1,
319
        gen_op_addl_A0_ESI_s1,
320
        gen_op_addl_A0_EDI_s1,
321
    },
322
    [2] = {
323
        gen_op_addl_A0_EAX_s2,
324
        gen_op_addl_A0_ECX_s2,
325
        gen_op_addl_A0_EDX_s2,
326
        gen_op_addl_A0_EBX_s2,
327
        gen_op_addl_A0_ESP_s2,
328
        gen_op_addl_A0_EBP_s2,
329
        gen_op_addl_A0_ESI_s2,
330
        gen_op_addl_A0_EDI_s2,
331
    },
332
    [3] = {
333
        gen_op_addl_A0_EAX_s3,
334
        gen_op_addl_A0_ECX_s3,
335
        gen_op_addl_A0_EDX_s3,
336
        gen_op_addl_A0_EBX_s3,
337
        gen_op_addl_A0_ESP_s3,
338
        gen_op_addl_A0_EBP_s3,
339
        gen_op_addl_A0_ESI_s3,
340
        gen_op_addl_A0_EDI_s3,
341
    },
342
};
343

    
344
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
345
    gen_op_addl_T0_T1_cc,
346
    gen_op_orl_T0_T1_cc,
347
    gen_op_adcl_T0_T1_cc,
348
    gen_op_sbbl_T0_T1_cc,
349
    gen_op_andl_T0_T1_cc,
350
    gen_op_subl_T0_T1_cc,
351
    gen_op_xorl_T0_T1_cc,
352
    gen_op_cmpl_T0_T1_cc,
353
};
354

    
355
static const int cc_op_arithb[8] = {
356
    CC_OP_ADDB,
357
    CC_OP_LOGICB,
358
    CC_OP_ADDB,
359
    CC_OP_SUBB,
360
    CC_OP_LOGICB,
361
    CC_OP_SUBB,
362
    CC_OP_LOGICB,
363
    CC_OP_SUBB,
364
};
365

    
366
static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
367
    [OT_BYTE] = {
368
        gen_op_rolb_T0_T1_cc,
369
        gen_op_rorb_T0_T1_cc,
370
        gen_op_rclb_T0_T1_cc,
371
        gen_op_rcrb_T0_T1_cc,
372
        gen_op_shlb_T0_T1_cc,
373
        gen_op_shrb_T0_T1_cc,
374
        gen_op_shlb_T0_T1_cc,
375
        gen_op_sarb_T0_T1_cc,
376
    },
377
    [OT_WORD] = {
378
        gen_op_rolw_T0_T1_cc,
379
        gen_op_rorw_T0_T1_cc,
380
        gen_op_rclw_T0_T1_cc,
381
        gen_op_rcrw_T0_T1_cc,
382
        gen_op_shlw_T0_T1_cc,
383
        gen_op_shrw_T0_T1_cc,
384
        gen_op_shlw_T0_T1_cc,
385
        gen_op_sarw_T0_T1_cc,
386
    },
387
    [OT_LONG] = {
388
        gen_op_roll_T0_T1_cc,
389
        gen_op_rorl_T0_T1_cc,
390
        gen_op_rcll_T0_T1_cc,
391
        gen_op_rcrl_T0_T1_cc,
392
        gen_op_shll_T0_T1_cc,
393
        gen_op_shrl_T0_T1_cc,
394
        gen_op_shll_T0_T1_cc,
395
        gen_op_sarl_T0_T1_cc,
396
    },
397
};
398

    
399
static GenOpFunc *gen_op_lds_T0_A0[3] = {
400
    gen_op_ldsb_T0_A0,
401
    gen_op_ldsw_T0_A0,
402
};
403

    
404
static GenOpFunc *gen_op_ldu_T0_A0[3] = {
405
    gen_op_ldub_T0_A0,
406
    gen_op_lduw_T0_A0,
407
};
408

    
409
/* sign does not matter */
410
static GenOpFunc *gen_op_ld_T0_A0[3] = {
411
    gen_op_ldub_T0_A0,
412
    gen_op_lduw_T0_A0,
413
    gen_op_ldl_T0_A0,
414
};
415

    
416
static GenOpFunc *gen_op_ld_T1_A0[3] = {
417
    gen_op_ldub_T1_A0,
418
    gen_op_lduw_T1_A0,
419
    gen_op_ldl_T1_A0,
420
};
421

    
422
static GenOpFunc *gen_op_st_T0_A0[3] = {
423
    gen_op_stb_T0_A0,
424
    gen_op_stw_T0_A0,
425
    gen_op_stl_T0_A0,
426
};
427

    
428
static GenOpFunc *gen_op_movs[6] = {
429
    gen_op_movsb,
430
    gen_op_movsw,
431
    gen_op_movsl,
432
    gen_op_rep_movsb,
433
    gen_op_rep_movsw,
434
    gen_op_rep_movsl,
435
};
436

    
437
static GenOpFunc *gen_op_stos[6] = {
438
    gen_op_stosb,
439
    gen_op_stosw,
440
    gen_op_stosl,
441
    gen_op_rep_stosb,
442
    gen_op_rep_stosw,
443
    gen_op_rep_stosl,
444
};
445

    
446
static GenOpFunc *gen_op_lods[6] = {
447
    gen_op_lodsb,
448
    gen_op_lodsw,
449
    gen_op_lodsl,
450
    gen_op_rep_lodsb,
451
    gen_op_rep_lodsw,
452
    gen_op_rep_lodsl,
453
};
454

    
455
static GenOpFunc *gen_op_scas[9] = {
456
    gen_op_scasb,
457
    gen_op_scasw,
458
    gen_op_scasl,
459
    gen_op_repz_scasb,
460
    gen_op_repz_scasw,
461
    gen_op_repz_scasl,
462
    gen_op_repnz_scasb,
463
    gen_op_repnz_scasw,
464
    gen_op_repnz_scasl,
465
};
466

    
467
static GenOpFunc *gen_op_cmps[9] = {
468
    gen_op_cmpsb,
469
    gen_op_cmpsw,
470
    gen_op_cmpsl,
471
    gen_op_repz_cmpsb,
472
    gen_op_repz_cmpsw,
473
    gen_op_repz_cmpsl,
474
    gen_op_repnz_cmpsb,
475
    gen_op_repnz_cmpsw,
476
    gen_op_repnz_cmpsl,
477
};
478

    
479
static GenOpFunc *gen_op_ins[6] = {
480
    gen_op_insb,
481
    gen_op_insw,
482
    gen_op_insl,
483
    gen_op_rep_insb,
484
    gen_op_rep_insw,
485
    gen_op_rep_insl,
486
};
487

    
488

    
489
static GenOpFunc *gen_op_outs[6] = {
490
    gen_op_outsb,
491
    gen_op_outsw,
492
    gen_op_outsl,
493
    gen_op_rep_outsb,
494
    gen_op_rep_outsw,
495
    gen_op_rep_outsl,
496
};
497

    
498
enum {
499
    JCC_O,
500
    JCC_B,
501
    JCC_Z,
502
    JCC_BE,
503
    JCC_S,
504
    JCC_P,
505
    JCC_L,
506
    JCC_LE,
507
};
508

    
509
static GenOpFunc2 *gen_jcc_slow[8] = {
510
    gen_op_jo_cc,
511
    gen_op_jb_cc,
512
    gen_op_jz_cc,
513
    gen_op_jbe_cc,
514
    gen_op_js_cc,
515
    gen_op_jp_cc,
516
    gen_op_jl_cc,
517
    gen_op_jle_cc,
518
};
519
    
520
static GenOpFunc2 *gen_jcc_sub[3][8] = {
521
    [OT_BYTE] = {
522
        NULL,
523
        gen_op_jb_subb,
524
        gen_op_jz_subb,
525
        gen_op_jbe_subb,
526
        gen_op_js_subb,
527
        NULL,
528
        gen_op_jl_subb,
529
        gen_op_jle_subb,
530
    },
531
    [OT_WORD] = {
532
        NULL,
533
        gen_op_jb_subw,
534
        gen_op_jz_subw,
535
        gen_op_jbe_subw,
536
        gen_op_js_subw,
537
        NULL,
538
        gen_op_jl_subw,
539
        gen_op_jle_subw,
540
    },
541
    [OT_LONG] = {
542
        NULL,
543
        gen_op_jb_subl,
544
        gen_op_jz_subl,
545
        gen_op_jbe_subl,
546
        gen_op_js_subl,
547
        NULL,
548
        gen_op_jl_subl,
549
        gen_op_jle_subl,
550
    },
551
};
552

    
553
static GenOpFunc *gen_setcc_slow[8] = {
554
    gen_op_seto_T0_cc,
555
    gen_op_setb_T0_cc,
556
    gen_op_setz_T0_cc,
557
    gen_op_setbe_T0_cc,
558
    gen_op_sets_T0_cc,
559
    gen_op_setp_T0_cc,
560
    gen_op_setl_T0_cc,
561
    gen_op_setle_T0_cc,
562
};
563

    
564
static GenOpFunc *gen_setcc_sub[3][8] = {
565
    [OT_BYTE] = {
566
        NULL,
567
        gen_op_setb_T0_subb,
568
        gen_op_setz_T0_subb,
569
        gen_op_setbe_T0_subb,
570
        gen_op_sets_T0_subb,
571
        NULL,
572
        gen_op_setl_T0_subb,
573
        gen_op_setle_T0_subb,
574
    },
575
    [OT_WORD] = {
576
        NULL,
577
        gen_op_setb_T0_subw,
578
        gen_op_setz_T0_subw,
579
        gen_op_setbe_T0_subw,
580
        gen_op_sets_T0_subw,
581
        NULL,
582
        gen_op_setl_T0_subw,
583
        gen_op_setle_T0_subw,
584
    },
585
    [OT_LONG] = {
586
        NULL,
587
        gen_op_setb_T0_subl,
588
        gen_op_setz_T0_subl,
589
        gen_op_setbe_T0_subl,
590
        gen_op_sets_T0_subl,
591
        NULL,
592
        gen_op_setl_T0_subl,
593
        gen_op_setle_T0_subl,
594
    },
595
};
596

    
597
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
598
    gen_op_fadd_ST0_FT0,
599
    gen_op_fmul_ST0_FT0,
600
    gen_op_fcom_ST0_FT0,
601
    gen_op_fcom_ST0_FT0,
602
    gen_op_fsub_ST0_FT0,
603
    gen_op_fsubr_ST0_FT0,
604
    gen_op_fdiv_ST0_FT0,
605
    gen_op_fdivr_ST0_FT0,
606
};
607

    
608
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
609
    gen_op_fadd_STN_ST0,
610
    gen_op_fmul_STN_ST0,
611
    NULL,
612
    NULL,
613
    gen_op_fsub_STN_ST0,
614
    gen_op_fsubr_STN_ST0,
615
    gen_op_fdiv_STN_ST0,
616
    gen_op_fdivr_STN_ST0,
617
};
618

    
619
static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
620
{
621
    if (d != OR_TMP0)
622
        gen_op_mov_TN_reg[ot][0][d]();
623
    if (s != OR_TMP1)
624
        gen_op_mov_TN_reg[ot][1][s]();
625
    if ((op == OP_ADCL || op == OP_SBBL) && s1->cc_op != CC_OP_DYNAMIC)
626
        gen_op_set_cc_op(s1->cc_op);
627
    gen_op_arith_T0_T1_cc[op]();
628
    if (d != OR_TMP0 && op != OP_CMPL)
629
        gen_op_mov_reg_T0[ot][d]();
630
    s1->cc_op = cc_op_arithb[op] + ot;
631
}
632

    
633
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
634
{
635
    gen_op1_movl_T1_im(c);
636
    gen_op(s1, op, ot, d, OR_TMP0);
637
}
638

    
639
static void gen_inc(DisasContext *s1, int ot, int d, int c)
640
{
641
    if (d != OR_TMP0)
642
        gen_op_mov_TN_reg[ot][0][d]();
643
    if (s1->cc_op != CC_OP_DYNAMIC)
644
        gen_op_set_cc_op(s1->cc_op);
645
    if (c > 0)
646
        gen_op_incl_T0_cc();
647
    else
648
        gen_op_decl_T0_cc();
649
    if (d != OR_TMP0)
650
        gen_op_mov_reg_T0[ot][d]();
651
}
652

    
653
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
654
{
655
    if (d != OR_TMP0)
656
        gen_op_mov_TN_reg[ot][0][d]();
657
    if (s != OR_TMP1)
658
        gen_op_mov_TN_reg[ot][1][s]();
659
    switch(op) {
660
    case OP_ROL:
661
    case OP_ROR:
662
    case OP_RCL:
663
    case OP_RCR:
664
        /* only C and O are modified, so we must update flags dynamically */
665
        if (s1->cc_op != CC_OP_DYNAMIC)
666
            gen_op_set_cc_op(s1->cc_op);
667
        gen_op_shift_T0_T1_cc[ot][op]();
668
        break;
669
    default:
670
        gen_op_shift_T0_T1_cc[ot][op]();
671
        break;
672
    }
673
    if (d != OR_TMP0)
674
        gen_op_mov_reg_T0[ot][d]();
675
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
676
}
677

    
678
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
679
{
680
    /* currently not optimized */
681
    gen_op1_movl_T1_im(c);
682
    gen_shift(s1, op, ot, d, OR_TMP1);
683
}
684

    
685
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
686
{
687
    int havesib;
688
    int havebase;
689
    int base, disp;
690
    int index = 0;
691
    int scale = 0;
692
    int reg1, reg2, opreg;
693
    int mod, rm, code;
694

    
695
    mod = (modrm >> 6) & 3;
696
    rm = modrm & 7;
697

    
698
    if (s->aflag) {
699

    
700
        havesib = 0;
701
        havebase = 1;
702
        base = rm;
703
        
704
        if (base == 4) {
705
            havesib = 1;
706
            code = ldub(s->pc++);
707
            scale = (code >> 6) & 3;
708
            index = (code >> 3) & 7;
709
            base = code & 7;
710
        }
711

    
712
        switch (mod) {
713
        case 0:
714
            if (base == 5) {
715
                havebase = 0;
716
                disp = ldl(s->pc);
717
                s->pc += 4;
718
            } else {
719
                disp = 0;
720
            }
721
            break;
722
        case 1:
723
            disp = (int8_t)ldub(s->pc++);
724
            break;
725
        default:
726
        case 2:
727
            disp = ldl(s->pc);
728
            s->pc += 4;
729
            break;
730
        }
731

    
732
        reg1 = OR_ZERO;
733
        reg2 = OR_ZERO;
734
          
735
        if (havebase || (havesib && (index != 4 || scale != 0))) {
736
            if (havebase)
737
                reg1 = OR_EAX + base;
738
            if (havesib && index != 4) {
739
                if (havebase)
740
                    reg2 = index + OR_EAX;
741
                else
742
                    reg1 = index + OR_EAX;
743
            }
744
        }
745
        /* XXX: disp only ? */
746
        if (reg2 == OR_ZERO) {
747
            /* op: disp + (reg1 << scale) */
748
            if (reg1 == OR_ZERO) {
749
                gen_op1_movl_A0_im(disp);
750
            } else if (scale == 0 && disp == 0) {
751
                gen_op_movl_A0_reg[reg1]();
752
            } else {
753
                gen_op_addl_A0_reg_sN[scale][reg1]();
754
            }
755
        } else {
756
            /* op: disp + reg1 + (reg2 << scale) */
757
            if (disp != 0) {
758
                gen_op1_movl_A0_im(disp);
759
                gen_op_addl_A0_reg_sN[0][reg1]();
760
            } else {
761
                gen_op_movl_A0_reg[reg1]();
762
            }
763
            gen_op_addl_A0_reg_sN[scale][reg2]();
764
        }
765
        opreg = OR_A0;
766
    } else {
767
        fprintf(stderr, "16 bit addressing not supported\n");
768
        disp = 0;
769
        opreg = 0;
770
    }
771
    *reg_ptr = opreg;
772
    *offset_ptr = disp;
773
}
774

    
775
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
776
   OR_TMP0 */
777
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
778
{
779
    int mod, rm, opreg, disp;
780

    
781
    mod = (modrm >> 6) & 3;
782
    rm = modrm & 7;
783
    if (mod == 3) {
784
        if (is_store) {
785
            if (reg != OR_TMP0)
786
                gen_op_mov_TN_reg[ot][0][reg]();
787
            gen_op_mov_reg_T0[ot][rm]();
788
        } else {
789
            gen_op_mov_TN_reg[ot][0][rm]();
790
            if (reg != OR_TMP0)
791
                gen_op_mov_reg_T0[ot][reg]();
792
        }
793
    } else {
794
        gen_lea_modrm(s, modrm, &opreg, &disp);
795
        if (is_store) {
796
            if (reg != OR_TMP0)
797
                gen_op_mov_TN_reg[ot][0][reg]();
798
            gen_op_st_T0_A0[ot]();
799
        } else {
800
            gen_op_ld_T0_A0[ot]();
801
            if (reg != OR_TMP0)
802
                gen_op_mov_reg_T0[ot][reg]();
803
        }
804
    }
805
}
806

    
807
static inline uint32_t insn_get(DisasContext *s, int ot)
808
{
809
    uint32_t ret;
810

    
811
    switch(ot) {
812
    case OT_BYTE:
813
        ret = ldub(s->pc);
814
        s->pc++;
815
        break;
816
    case OT_WORD:
817
        ret = lduw(s->pc);
818
        s->pc += 2;
819
        break;
820
    default:
821
    case OT_LONG:
822
        ret = ldl(s->pc);
823
        s->pc += 4;
824
        break;
825
    }
826
    return ret;
827
}
828

    
829
static void gen_jcc(DisasContext *s, int b, int val)
830
{
831
    int inv, jcc_op;
832
    GenOpFunc2 *func;
833

    
834
    inv = b & 1;
835
    jcc_op = (b >> 1) & 7;
836
    switch(s->cc_op) {
837
        /* we optimize the cmp/jcc case */
838
    case CC_OP_SUBB:
839
    case CC_OP_SUBW:
840
    case CC_OP_SUBL:
841
        func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
842
        if (!func)
843
            goto slow_jcc;
844
        break;
845
        
846
        /* some jumps are easy to compute */
847
    case CC_OP_ADDB:
848
    case CC_OP_ADDW:
849
    case CC_OP_ADDL:
850
    case CC_OP_LOGICB:
851
    case CC_OP_LOGICW:
852
    case CC_OP_LOGICL:
853
    case CC_OP_INCB:
854
    case CC_OP_INCW:
855
    case CC_OP_INCL:
856
    case CC_OP_DECB:
857
    case CC_OP_DECW:
858
    case CC_OP_DECL:
859
    case CC_OP_SHLB:
860
    case CC_OP_SHLW:
861
    case CC_OP_SHLL:
862
        switch(jcc_op) {
863
        case JCC_Z:
864
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
865
            break;
866
        case JCC_S:
867
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
868
            break;
869
        default:
870
            goto slow_jcc;
871
        }
872
        break;
873
    default:
874
    slow_jcc:
875
        if (s->cc_op != CC_OP_DYNAMIC)
876
            op_set_cc_op(s->cc_op);
877
        func = gen_jcc_slow[jcc_op];
878
        break;
879
    }
880
    if (!inv) {
881
        func(val, (long)s->pc);
882
    } else {
883
        func((long)s->pc, val);
884
    }
885
}
886

    
887
static void gen_setcc(DisasContext *s, int b)
888
{
889
    int inv, jcc_op;
890
    GenOpFunc *func;
891

    
892
    inv = b & 1;
893
    jcc_op = (b >> 1) & 7;
894
    switch(s->cc_op) {
895
        /* we optimize the cmp/jcc case */
896
    case CC_OP_SUBB:
897
    case CC_OP_SUBW:
898
    case CC_OP_SUBL:
899
        func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
900
        if (!func)
901
            goto slow_jcc;
902
        break;
903
        
904
        /* some jumps are easy to compute */
905
    case CC_OP_ADDB:
906
    case CC_OP_ADDW:
907
    case CC_OP_ADDL:
908
    case CC_OP_LOGICB:
909
    case CC_OP_LOGICW:
910
    case CC_OP_LOGICL:
911
    case CC_OP_INCB:
912
    case CC_OP_INCW:
913
    case CC_OP_INCL:
914
    case CC_OP_DECB:
915
    case CC_OP_DECW:
916
    case CC_OP_DECL:
917
    case CC_OP_SHLB:
918
    case CC_OP_SHLW:
919
    case CC_OP_SHLL:
920
        switch(jcc_op) {
921
        case JCC_Z:
922
            func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
923
            break;
924
        case JCC_S:
925
            func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op];
926
            break;
927
        default:
928
            goto slow_jcc;
929
        }
930
        break;
931
    default:
932
    slow_jcc:
933
        if (s->cc_op != CC_OP_DYNAMIC)
934
            op_set_cc_op(s->cc_op);
935
        func = gen_setcc_slow[jcc_op];
936
        break;
937
    }
938
    func();
939
    if (inv) {
940
        gen_op_xor_T0_1();
941
    }
942
}
943

    
944
/* return the size of the intruction. Return -1 if no insn found */
945
int disas_insn(DisasContext *s, uint8_t *pc_start)
946
{
947
    int b, prefixes, aflag, dflag;
948
    int shift, ot;
949
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
950

    
951
    s->pc = pc_start;
952
    prefixes = 0;
953
    aflag = 1;
954
    dflag = 1;
955
    //    cur_pc = s->pc; /* for insn generation */
956
 next_byte:
957
    b = ldub(s->pc);
958
    if (b < 0)
959
        return -1;
960
    s->pc++;
961
    /* check prefixes */
962
    switch (b) {
963
    case 0xf3:
964
        prefixes |= PREFIX_REPZ;
965
        goto next_byte;
966
    case 0xf2:
967
        prefixes |= PREFIX_REPNZ;
968
        goto next_byte;
969
    case 0xf0:
970
        prefixes |= PREFIX_LOCK;
971
        goto next_byte;
972
    case 0x2e:
973
        prefixes |= PREFIX_CS;
974
        goto next_byte;
975
    case 0x36:
976
        prefixes |= PREFIX_SS;
977
        goto next_byte;
978
    case 0x3e:
979
        prefixes |= PREFIX_DS;
980
        goto next_byte;
981
    case 0x26:
982
        prefixes |= PREFIX_ES;
983
        goto next_byte;
984
    case 0x64:
985
        prefixes |= PREFIX_FS;
986
        goto next_byte;
987
    case 0x65:
988
        prefixes |= PREFIX_GS;
989
        goto next_byte;
990
    case 0x66:
991
        prefixes |= PREFIX_DATA;
992
        goto next_byte;
993
    case 0x67:
994
        prefixes |= PREFIX_ADR;
995
        goto next_byte;
996
    case 0x9b:
997
        prefixes |= PREFIX_FWAIT;
998
        goto next_byte;
999
    }
1000

    
1001
    if (prefixes & PREFIX_DATA)
1002
        dflag ^= 1;
1003
    if (prefixes & PREFIX_ADR)
1004
        aflag ^= 1;
1005

    
1006
    s->prefix = prefixes;
1007
    s->aflag = aflag;
1008
    s->dflag = dflag;
1009

    
1010
    /* now check op code */
1011
 reswitch:
1012
    switch(b) {
1013
    case 0x0f:
1014
        /**************************/
1015
        /* extended op code */
1016
        b = ldub(s->pc++) | 0x100;
1017
        goto reswitch;
1018
        
1019
        /**************************/
1020
        /* arith & logic */
1021
    case 0x00 ... 0x05:
1022
    case 0x08 ... 0x0d:
1023
    case 0x10 ... 0x15:
1024
    case 0x18 ... 0x1d:
1025
    case 0x20 ... 0x25:
1026
    case 0x28 ... 0x2d:
1027
    case 0x30 ... 0x35:
1028
    case 0x38 ... 0x3d:
1029
        {
1030
            int op, f, val;
1031
            op = (b >> 3) & 7;
1032
            f = (b >> 1) & 3;
1033

    
1034
            if ((b & 1) == 0)
1035
                ot = OT_BYTE;
1036
            else
1037
                ot = dflag ? OT_LONG : OT_WORD;
1038
            
1039
            switch(f) {
1040
            case 0: /* OP Ev, Gv */
1041
                modrm = ldub(s->pc++);
1042
                reg = ((modrm >> 3) & 7) + OR_EAX;
1043
                mod = (modrm >> 6) & 3;
1044
                rm = modrm & 7;
1045
                if (mod != 3) {
1046
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1047
                    gen_op_ld_T0_A0[ot]();
1048
                    opreg = OR_TMP0;
1049
                } else {
1050
                    opreg = OR_EAX + rm;
1051
                }
1052
                gen_op(s, op, ot, opreg, reg);
1053
                if (mod != 3 && op != 7) {
1054
                    gen_op_st_T0_A0[ot]();
1055
                }
1056
                break;
1057
            case 1: /* OP Gv, Ev */
1058
                modrm = ldub(s->pc++);
1059
                mod = (modrm >> 6) & 3;
1060
                reg = ((modrm >> 3) & 7) + OR_EAX;
1061
                rm = modrm & 7;
1062
                if (mod != 3) {
1063
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1064
                    gen_op_ld_T1_A0[ot]();
1065
                    opreg = OR_TMP1;
1066
                } else {
1067
                    opreg = OR_EAX + rm;
1068
                }
1069
                gen_op(s, op, ot, reg, opreg);
1070
                break;
1071
            case 2: /* OP A, Iv */
1072
                val = insn_get(s, ot);
1073
                gen_opi(s, op, ot, OR_EAX, val);
1074
                break;
1075
            }
1076
        }
1077
        break;
1078

    
1079
    case 0x80: /* GRP1 */
1080
    case 0x81:
1081
    case 0x83:
1082
        {
1083
            int val;
1084

    
1085
            if ((b & 1) == 0)
1086
                ot = OT_BYTE;
1087
            else
1088
                ot = dflag ? OT_LONG : OT_WORD;
1089
            
1090
            modrm = ldub(s->pc++);
1091
            mod = (modrm >> 6) & 3;
1092
            rm = modrm & 7;
1093
            op = (modrm >> 3) & 7;
1094
            
1095
            if (mod != 3) {
1096
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1097
                gen_op_ld_T0_A0[ot]();
1098
                opreg = OR_TMP0;
1099
            } else {
1100
                opreg = rm + OR_EAX;
1101
            }
1102

    
1103
            switch(b) {
1104
            default:
1105
            case 0x80:
1106
            case 0x81:
1107
                val = insn_get(s, ot);
1108
                break;
1109
            case 0x83:
1110
                val = (int8_t)insn_get(s, OT_BYTE);
1111
                break;
1112
            }
1113

    
1114
            gen_opi(s, op, ot, opreg, val);
1115
            if (op != 7 && mod != 3) {
1116
                gen_op_st_T0_A0[ot]();
1117
            }
1118
        }
1119
        break;
1120

    
1121
        /**************************/
1122
        /* inc, dec, and other misc arith */
1123
    case 0x40 ... 0x47: /* inc Gv */
1124
        ot = dflag ? OT_LONG : OT_WORD;
1125
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
1126
        break;
1127
    case 0x48 ... 0x4f: /* dec Gv */
1128
        ot = dflag ? OT_LONG : OT_WORD;
1129
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
1130
        break;
1131
    case 0xf6: /* GRP3 */
1132
    case 0xf7:
1133
        if ((b & 1) == 0)
1134
            ot = OT_BYTE;
1135
        else
1136
            ot = dflag ? OT_LONG : OT_WORD;
1137

    
1138
        modrm = ldub(s->pc++);
1139
        mod = (modrm >> 6) & 3;
1140
        rm = modrm & 7;
1141
        op = (modrm >> 3) & 7;
1142
        if (mod != 3) {
1143
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1144
            gen_op_ld_T0_A0[ot]();
1145
        } else {
1146
            gen_op_mov_TN_reg[ot][0][rm]();
1147
        }
1148

    
1149
        switch(op) {
1150
        case 0: /* test */
1151
            val = insn_get(s, ot);
1152
            gen_op1_movl_T1_im(val);
1153
            gen_op_testl_T0_T1_cc();
1154
            s->cc_op = CC_OP_LOGICB + ot;
1155
            break;
1156
        case 2: /* not */
1157
            gen_op_notl_T0();
1158
            if (mod != 3) {
1159
                gen_op_st_T0_A0[ot]();
1160
            } else {
1161
                gen_op_mov_reg_T0[ot][rm]();
1162
            }
1163
            break;
1164
        case 3: /* neg */
1165
            gen_op_negl_T0_cc();
1166
            if (mod != 3) {
1167
                gen_op_st_T0_A0[ot]();
1168
            } else {
1169
                gen_op_mov_reg_T0[ot][rm]();
1170
            }
1171
            s->cc_op = CC_OP_SUBB + ot;
1172
            break;
1173
        case 4: /* mul */
1174
            switch(ot) {
1175
            case OT_BYTE:
1176
                gen_op_mulb_AL_T0();
1177
                break;
1178
            case OT_WORD:
1179
                gen_op_mulw_AX_T0();
1180
                break;
1181
            default:
1182
            case OT_LONG:
1183
                gen_op_mull_EAX_T0();
1184
                break;
1185
            }
1186
            break;
1187
        case 5: /* imul */
1188
            switch(ot) {
1189
            case OT_BYTE:
1190
                gen_op_imulb_AL_T0();
1191
                break;
1192
            case OT_WORD:
1193
                gen_op_imulw_AX_T0();
1194
                break;
1195
            default:
1196
            case OT_LONG:
1197
                gen_op_imull_EAX_T0();
1198
                break;
1199
            }
1200
            break;
1201
        case 6: /* div */
1202
            switch(ot) {
1203
            case OT_BYTE:
1204
                gen_op_divb_AL_T0();
1205
                break;
1206
            case OT_WORD:
1207
                gen_op_divw_AX_T0();
1208
                break;
1209
            default:
1210
            case OT_LONG:
1211
                gen_op_divl_EAX_T0();
1212
                break;
1213
            }
1214
            break;
1215
        case 7: /* idiv */
1216
            switch(ot) {
1217
            case OT_BYTE:
1218
                gen_op_idivb_AL_T0();
1219
                break;
1220
            case OT_WORD:
1221
                gen_op_idivw_AX_T0();
1222
                break;
1223
            default:
1224
            case OT_LONG:
1225
                gen_op_idivl_EAX_T0();
1226
                break;
1227
            }
1228
            break;
1229
        default:
1230
            error("GRP3: bad instruction");
1231
            return -1;
1232
        }
1233
        break;
1234

    
1235
    case 0xfe: /* GRP4 */
1236
    case 0xff: /* GRP5 */
1237
        if ((b & 1) == 0)
1238
            ot = OT_BYTE;
1239
        else
1240
            ot = dflag ? OT_LONG : OT_WORD;
1241

    
1242
        modrm = ldub(s->pc++);
1243
        mod = (modrm >> 6) & 3;
1244
        rm = modrm & 7;
1245
        op = (modrm >> 3) & 7;
1246
        if (op >= 2 && b == 0xfe) {
1247
            error("GRP4: bad instruction");
1248
            return -1;
1249
        }
1250
        if (mod != 3) {
1251
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1252
            gen_op_ld_T0_A0[ot]();
1253
        } else {
1254
            gen_op_mov_TN_reg[ot][0][rm]();
1255
        }
1256

    
1257
        switch(op) {
1258
        case 0: /* inc Ev */
1259
            gen_inc(s, ot, OR_TMP0, 1);
1260
            if (mod != 3)
1261
                gen_op_st_T0_A0[ot]();
1262
            break;
1263
        case 1: /* dec Ev */
1264
            gen_inc(s, ot, OR_TMP0, -1);
1265
            if (mod != 3)
1266
                gen_op_st_T0_A0[ot]();
1267
            break;
1268
        case 2: /* call Ev */
1269
            gen_op1_movl_T1_im((long)s->pc);
1270
            gen_op_pushl_T1();
1271
            gen_op_jmp_T0();
1272
            break;
1273
        case 4: /* jmp Ev */
1274
            gen_op_jmp_T0();
1275
            break;
1276
        case 6: /* push Ev */
1277
            gen_op_pushl_T0();
1278
            break;
1279
        default:
1280
            error("GRP5: bad instruction");
1281
            return -1;
1282
        }
1283
        break;
1284

    
1285
    case 0x84: /* test Ev, Gv */
1286
    case 0x85: 
1287
        if ((b & 1) == 0)
1288
            ot = OT_BYTE;
1289
        else
1290
            ot = dflag ? OT_LONG : OT_WORD;
1291

    
1292
        modrm = ldub(s->pc++);
1293
        mod = (modrm >> 6) & 3;
1294
        rm = modrm & 7;
1295
        reg = (modrm >> 3) & 7;
1296
        
1297
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1298
        gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1299
        gen_op_testl_T0_T1_cc();
1300
        s->cc_op = CC_OP_LOGICB + ot;
1301
        break;
1302
        
1303
    case 0xa8: /* test eAX, Iv */
1304
    case 0xa9:
1305
        if ((b & 1) == 0)
1306
            ot = OT_BYTE;
1307
        else
1308
            ot = dflag ? OT_LONG : OT_WORD;
1309
        val = insn_get(s, ot);
1310

    
1311
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
1312
        gen_op1_movl_T1_im(val);
1313
        gen_op_testl_T0_T1_cc();
1314
        s->cc_op = CC_OP_LOGICB + ot;
1315
        break;
1316
        
1317
    case 0x98: /* CWDE/CBW */
1318
        if (dflag)
1319
            gen_op_movswl_EAX_AX();
1320
        else
1321
            gen_op_movsbw_AX_AL();
1322
        break;
1323
    case 0x99: /* CDQ/CWD */
1324
        if (dflag)
1325
            gen_op_movslq_EDX_EAX();
1326
        else
1327
            gen_op_movswl_DX_AX();
1328
        break;
1329
    case 0x1af: /* imul Gv, Ev */
1330
    case 0x69: /* imul Gv, Ev, I */
1331
    case 0x6b:
1332
        ot = dflag ? OT_LONG : OT_WORD;
1333
        modrm = ldub(s->pc++);
1334
        reg = ((modrm >> 3) & 7) + OR_EAX;
1335
        
1336
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1337
        if (b == 0x69) {
1338
            val = insn_get(s, ot);
1339
            gen_op1_movl_T1_im(val);
1340
        } else if (b == 0x6b) {
1341
            val = insn_get(s, OT_BYTE);
1342
            gen_op1_movl_T1_im(val);
1343
        } else {
1344
            gen_op_mov_TN_reg[ot][1][reg]();
1345
        }
1346

    
1347
        if (ot == OT_LONG) {
1348
            op_imull_T0_T1();
1349
        } else {
1350
            op_imulw_T0_T1();
1351
        }
1352
        gen_op_mov_reg_T0[ot][reg]();
1353
        break;
1354
        
1355
        /**************************/
1356
        /* push/pop */
1357
    case 0x50 ... 0x57: /* push */
1358
        gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1359
        gen_op_pushl_T0();
1360
        break;
1361
    case 0x58 ... 0x5f: /* pop */
1362
        gen_op_popl_T0();
1363
        gen_op_mov_reg_T0[OT_LONG][b & 7]();
1364
        break;
1365
    case 0x68: /* push Iv */
1366
    case 0x6a:
1367
        ot = dflag ? OT_LONG : OT_WORD;
1368
        if (b == 0x68)
1369
            val = insn_get(s, ot);
1370
        else
1371
            val = (int8_t)insn_get(s, OT_BYTE);
1372
        gen_op1_movl_T0_im(val);
1373
        gen_op_pushl_T0();
1374
        break;
1375
    case 0x8f: /* pop Ev */
1376
        ot = dflag ? OT_LONG : OT_WORD;
1377
        modrm = ldub(s->pc++);
1378
        gen_op_popl_T0();
1379
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1380
        break;
1381
    case 0xc9: /* leave */
1382
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1383
        gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1384
        gen_op_popl_T0();
1385
        gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1386
        break;
1387
        /**************************/
1388
        /* mov */
1389
    case 0x88:
1390
    case 0x89: /* mov Gv, Ev */
1391
        if ((b & 1) == 0)
1392
            ot = OT_BYTE;
1393
        else
1394
            ot = dflag ? OT_LONG : OT_WORD;
1395
        modrm = ldub(s->pc++);
1396
        reg = (modrm >> 3) & 7;
1397
        
1398
        /* generate a generic store */
1399
        gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1400
        break;
1401
    case 0xc6:
1402
    case 0xc7: /* mov Ev, Iv */
1403
        if ((b & 1) == 0)
1404
            ot = OT_BYTE;
1405
        else
1406
            ot = dflag ? OT_LONG : OT_WORD;
1407
        modrm = ldub(s->pc++);
1408
        mod = (modrm >> 6) & 3;
1409

    
1410
        val = insn_get(s, ot);
1411
        gen_op1_movl_T0_im(val);
1412
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1413
        break;
1414
    case 0x8a:
1415
    case 0x8b: /* mov Ev, Gv */
1416
        if ((b & 1) == 0)
1417
            ot = OT_BYTE;
1418
        else
1419
            ot = dflag ? OT_LONG : OT_WORD;
1420
        modrm = ldub(s->pc++);
1421
        reg = (modrm >> 3) & 7;
1422
        
1423
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1424
        gen_op_mov_reg_T0[ot][reg]();
1425
        break;
1426

    
1427
    case 0x1b6: /* movzbS Gv, Eb */
1428
    case 0x1b7: /* movzwS Gv, Eb */
1429
    case 0x1be: /* movsbS Gv, Eb */
1430
    case 0x1bf: /* movswS Gv, Eb */
1431
        {
1432
            int d_ot;
1433
            /* d_ot is the size of destination */
1434
            d_ot = dflag + OT_WORD;
1435
            /* ot is the size of source */
1436
            ot = (b & 1) + OT_BYTE;
1437
            modrm = ldub(s->pc++);
1438
            reg = ((modrm >> 3) & 7) + OR_EAX;
1439
            mod = (modrm >> 6) & 3;
1440
            rm = modrm & 7;
1441
            
1442
            if (mod == 3) {
1443
                gen_op_mov_TN_reg[ot][0][rm]();
1444
                switch(ot | (b & 8)) {
1445
                case OT_BYTE:
1446
                    gen_op_movzbl_T0_T0();
1447
                    break;
1448
                case OT_BYTE | 8:
1449
                    gen_op_movsbl_T0_T0();
1450
                    break;
1451
                case OT_WORD:
1452
                    gen_op_movzwl_T0_T0();
1453
                    break;
1454
                default:
1455
                case OT_WORD | 8:
1456
                    gen_op_movswl_T0_T0();
1457
                    break;
1458
                }
1459
                gen_op_mov_reg_T0[d_ot][reg]();
1460
            } else {
1461
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1462
                if (b & 8) {
1463
                    gen_op_lds_T0_A0[ot]();
1464
                } else {
1465
                    gen_op_ldu_T0_A0[ot]();
1466
                }
1467
                gen_op_mov_reg_T0[d_ot][reg]();
1468
            }
1469
        }
1470
        break;
1471

    
1472
    case 0x8d: /* lea */
1473
        ot = dflag ? OT_LONG : OT_WORD;
1474
        modrm = ldub(s->pc++);
1475
        reg = (modrm >> 3) & 7;
1476

    
1477
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1478
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1479
        break;
1480
        
1481
    case 0xa0: /* mov EAX, Ov */
1482
    case 0xa1:
1483
    case 0xa2: /* mov Ov, EAX */
1484
    case 0xa3:
1485
        if ((b & 1) == 0)
1486
            ot = OT_BYTE;
1487
        else
1488
            ot = dflag ? OT_LONG : OT_WORD;
1489
        if (s->aflag)
1490
            offset_addr = insn_get(s, OT_LONG);
1491
        else
1492
            offset_addr = insn_get(s, OT_WORD);
1493
            
1494
        if ((b & 2) == 0) {
1495
            gen_op_ld_T0_A0[ot]();
1496
            gen_op_mov_reg_T0[ot][R_EAX]();
1497
        } else {
1498
            gen_op_mov_TN_reg[ot][0][R_EAX]();
1499
            gen_op_st_T0_A0[ot]();
1500
        }
1501
        break;
1502

    
1503
    case 0xb0 ... 0xb7: /* mov R, Ib */
1504
        val = insn_get(s, OT_BYTE);
1505
        gen_op1_movl_T0_im(val);
1506
        gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1507
        break;
1508
    case 0xb8 ... 0xbf: /* mov R, Iv */
1509
        ot = dflag ? OT_LONG : OT_WORD;
1510
        val = insn_get(s, ot);
1511
        reg = OR_EAX + (b & 7);
1512
        gen_op1_movl_T0_im(val);
1513
        gen_op_mov_reg_T0[ot][reg]();
1514
        break;
1515

    
1516
    case 0x91 ... 0x97: /* xchg R, EAX */
1517
        ot = dflag ? OT_LONG : OT_WORD;
1518
        reg = b & 7;
1519
        gen_op_mov_TN_reg[ot][0][reg]();
1520
        gen_op_mov_TN_reg[ot][1][R_EAX]();
1521
        gen_op_mov_reg_T0[ot][R_EAX]();
1522
        gen_op_mov_reg_T1[ot][reg]();
1523
        break;
1524
    case 0x86:
1525
    case 0x87: /* xchg Ev, Gv */
1526
        if ((b & 1) == 0)
1527
            ot = OT_BYTE;
1528
        else
1529
            ot = dflag ? OT_LONG : OT_WORD;
1530
        modrm = ldub(s->pc++);
1531
        reg = (modrm >> 3) & 7;
1532

    
1533
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1534
        gen_op_mov_TN_reg[ot][0][reg]();
1535
        gen_op_ld_T1_A0[ot]();
1536
        gen_op_st_T0_A0[ot]();
1537
        gen_op_mov_reg_T1[ot][reg]();
1538
        break;
1539
        
1540
        /************************/
1541
        /* shifts */
1542
    case 0xc0:
1543
    case 0xc1:
1544
        /* shift Ev,Ib */
1545
        shift = 2;
1546
    grp2:
1547
        {
1548
            if ((b & 1) == 0)
1549
                ot = OT_BYTE;
1550
            else
1551
                ot = dflag ? OT_LONG : OT_WORD;
1552
            
1553
            modrm = ldub(s->pc++);
1554
            mod = (modrm >> 6) & 3;
1555
            rm = modrm & 7;
1556
            op = (modrm >> 3) & 7;
1557
            
1558
            if (mod != 3) {
1559
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1560
                gen_op_ld_T0_A0[ot]();
1561
                opreg = OR_TMP0;
1562
            } else {
1563
                opreg = rm + OR_EAX;
1564
            }
1565

    
1566
            /* simpler op */
1567
            if (shift == 0) {
1568
                gen_shift(s, op, ot, opreg, OR_ECX);
1569
            } else {
1570
                if (shift == 2) {
1571
                    shift = ldub(s->pc++);
1572
                }
1573
                gen_shifti(s, op, ot, opreg, shift);
1574
            }
1575

    
1576
            if (mod != 3) {
1577
                gen_op_st_T0_A0[ot]();
1578
            }
1579
        }
1580
        break;
1581
    case 0xd0:
1582
    case 0xd1:
1583
        /* shift Ev,1 */
1584
        shift = 1;
1585
        goto grp2;
1586
    case 0xd2:
1587
    case 0xd3:
1588
        /* shift Ev,cl */
1589
        shift = 0;
1590
        goto grp2;
1591

    
1592
        /************************/
1593
        /* floats */
1594
    case 0xd8 ... 0xdf: 
1595
        modrm = ldub(s->pc++);
1596
        mod = (modrm >> 6) & 3;
1597
        rm = modrm & 7;
1598
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
1599
        
1600
        if (mod != 3) {
1601
            /* memory op */
1602
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1603
            switch(op) {
1604
            case 0x00 ... 0x07: /* fxxxs */
1605
            case 0x10 ... 0x17: /* fixxxl */
1606
            case 0x20 ... 0x27: /* fxxxl */
1607
            case 0x30 ... 0x37: /* fixxx */
1608
                {
1609
                    int op1;
1610
                    op1 = op & 7;
1611

    
1612
                    switch(op >> 4) {
1613
                    case 0:
1614
                        gen_op_flds_FT0_A0();
1615
                        break;
1616
                    case 1:
1617
                        gen_op_fildl_FT0_A0();
1618
                        break;
1619
                    case 2:
1620
                        gen_op_fldl_FT0_A0();
1621
                        break;
1622
                    case 3:
1623
                    default:
1624
                        gen_op_fild_FT0_A0();
1625
                        break;
1626
                    }
1627
                    
1628
                    gen_op_fp_arith_ST0_FT0[op1]();
1629
                    if (op1 == 3) {
1630
                        /* fcomp needs pop */
1631
                        gen_op_fpop();
1632
                    }
1633
                }
1634
                break;
1635
            case 0x08: /* flds */
1636
            case 0x0a: /* fsts */
1637
            case 0x0b: /* fstps */
1638
            case 0x18: /* fildl */
1639
            case 0x1a: /* fistl */
1640
            case 0x1b: /* fistpl */
1641
            case 0x28: /* fldl */
1642
            case 0x2a: /* fstl */
1643
            case 0x2b: /* fstpl */
1644
            case 0x38: /* filds */
1645
            case 0x3a: /* fists */
1646
            case 0x3b: /* fistps */
1647
                
1648
                switch(op & 7) {
1649
                case 0:
1650
                    gen_op_fpush();
1651
                    switch(op >> 4) {
1652
                    case 0:
1653
                        gen_op_flds_ST0_A0();
1654
                        break;
1655
                    case 1:
1656
                        gen_op_fildl_ST0_A0();
1657
                        break;
1658
                    case 2:
1659
                        gen_op_fldl_ST0_A0();
1660
                        break;
1661
                    case 3:
1662
                    default:
1663
                        gen_op_fild_ST0_A0();
1664
                        break;
1665
                    }
1666
                    break;
1667
                default:
1668
                    switch(op >> 4) {
1669
                    case 0:
1670
                        gen_op_fsts_ST0_A0();
1671
                        break;
1672
                    case 1:
1673
                        gen_op_fistl_ST0_A0();
1674
                        break;
1675
                    case 2:
1676
                        gen_op_fstl_ST0_A0();
1677
                        break;
1678
                    case 3:
1679
                    default:
1680
                        gen_op_fist_ST0_A0();
1681
                        break;
1682
                    }
1683
                    if ((op & 7) == 3)
1684
                        gen_op_fpop();
1685
                    break;
1686
                }
1687
                break;
1688
#if 0
1689
            case 0x2f: /* fnstsw mem */
1690
                gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO);
1691
                gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr);
1692
                break;
1693

1694
            case 0x3c: /* fbld */
1695
            case 0x3e: /* fbstp */
1696
                error("float BCD not hanlded");
1697
                return -1;
1698
#endif
1699
            case 0x3d: /* fildll */
1700
                gen_op_fpush();
1701
                gen_op_fildll_ST0_A0();
1702
                break;
1703
            case 0x3f: /* fistpll */
1704
                gen_op_fistll_ST0_A0();
1705
                gen_op_fpop();
1706
                break;
1707
            default:
1708
                error("unhandled memory FP\n");
1709
                return -1;
1710
            }
1711
        } else {
1712
            /* register float ops */
1713
            opreg = rm;
1714

    
1715
            switch(op) {
1716
            case 0x08: /* fld sti */
1717
                gen_op_fpush();
1718
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
1719
                break;
1720
            case 0x09: /* fxchg sti */
1721
                gen_op_fxchg_ST0_STN((opreg + 1) & 7);
1722
                break;
1723
            case 0x0a: /* grp d9/2 */
1724
                switch(rm) {
1725
                case 0: /* fnop */
1726
                    break;
1727
                default:
1728
                    error("unhandled FP GRP d9/2\n");
1729
                    return -1;
1730
                }
1731
                break;
1732
            case 0x0c: /* grp d9/4 */
1733
                switch(rm) {
1734
                case 0: /* fchs */
1735
                    gen_op_fchs_ST0();
1736
                    break;
1737
                case 1: /* fabs */
1738
                    gen_op_fabs_ST0();
1739
                    break;
1740
                case 4: /* ftst */
1741
                    gen_op_fldz_FT0();
1742
                    gen_op_fcom_ST0_FT0();
1743
                    break;
1744
                case 5: /* fxam */
1745
                    gen_op_fxam_ST0();
1746
                    break;
1747
                default:
1748
                    return -1;
1749
                }
1750
                break;
1751
            case 0x0d: /* grp d9/5 */
1752
                {
1753
                    switch(rm) {
1754
                    case 0:
1755
                        gen_op_fld1_ST0();
1756
                        break;
1757
                    case 1:
1758
                        gen_op_fld2t_ST0();
1759
                        break;
1760
                    case 2:
1761
                        gen_op_fld2e_ST0();
1762
                        break;
1763
                    case 3:
1764
                        gen_op_fldpi_ST0();
1765
                        break;
1766
                    case 4:
1767
                        gen_op_fldlg2_ST0();
1768
                        break;
1769
                    case 5:
1770
                        gen_op_fldln2_ST0();
1771
                        break;
1772
                    case 6:
1773
                        gen_op_fldz_ST0();
1774
                        break;
1775
                    default:
1776
                        return -1;
1777
                    }
1778
                }
1779
                break;
1780
            case 0x0e: /* grp d9/6 */
1781
                switch(rm) {
1782
                case 0: /* f2xm1 */
1783
                    gen_op_f2xm1();
1784
                    break;
1785
                case 1: /* fyl2x */
1786
                    gen_op_fyl2x();
1787
                    break;
1788
                case 2: /* fptan */
1789
                    gen_op_fptan();
1790
                    break;
1791
                case 3: /* fpatan */
1792
                    gen_op_fpatan();
1793
                    break;
1794
                case 4: /* fxtract */
1795
                    gen_op_fxtract();
1796
                    break;
1797
                case 5: /* fprem1 */
1798
                    gen_op_fprem1();
1799
                    break;
1800
                case 6: /* fdecstp */
1801
                    gen_op_fdecstp();
1802
                    break;
1803
                default:
1804
                case 7: /* fincstp */
1805
                    gen_op_fincstp();
1806
                    break;
1807
                }
1808
                break;
1809
            case 0x0f: /* grp d9/7 */
1810
                switch(rm) {
1811
                case 0: /* fprem */
1812
                    gen_op_fprem();
1813
                    break;
1814
                case 1: /* fyl2xp1 */
1815
                    gen_op_fyl2xp1();
1816
                    break;
1817
                case 2: /* fsqrt */
1818
                    gen_op_fsqrt();
1819
                    break;
1820
                case 3: /* fsincos */
1821
                    gen_op_fsincos();
1822
                    break;
1823
                case 5: /* fscale */
1824
                    gen_op_fscale();
1825
                    break;
1826
                case 4: /* frndint */
1827
                    gen_op_frndint();
1828
                    break;
1829
                case 6: /* fsin */
1830
                    gen_op_fsin();
1831
                    break;
1832
                default:
1833
                case 7: /* fcos */
1834
                    gen_op_fcos();
1835
                    break;
1836
                }
1837
                break;
1838
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
1839
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
1840
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
1841
                {
1842
                    int op1;
1843
                    
1844
                    op1 = op & 7;
1845
                    if (op >= 0x20) {
1846
                        gen_op_fp_arith_STN_ST0[op1](opreg);
1847
                    } else {
1848
                        gen_op_fmov_FT0_STN(opreg);
1849
                        gen_op_fp_arith_ST0_FT0[op1]();
1850
                    }
1851
                    if (op >= 0x30)
1852
                        gen_op_fpop();
1853
                }
1854
                break;
1855
            case 0x02: /* fcom */
1856
                gen_op_fmov_FT0_STN(opreg);
1857
                gen_op_fcom_ST0_FT0();
1858
                break;
1859
            case 0x03: /* fcomp */
1860
                gen_op_fmov_FT0_STN(opreg);
1861
                gen_op_fcom_ST0_FT0();
1862
                gen_op_fpop();
1863
                break;
1864
            case 0x15: /* da/5 */
1865
                switch(rm) {
1866
                case 1: /* fucompp */
1867
                    gen_op_fmov_FT0_STN(1);
1868
                    gen_op_fcom_ST0_FT0();
1869
                    gen_op_fpop();
1870
                    gen_op_fpop();
1871
                    break;
1872
                default:
1873
                    return -1;
1874
                }
1875
                break;
1876
            case 0x2a: /* fst sti */
1877
                gen_op_fmov_STN_ST0(opreg);
1878
                break;
1879
            case 0x2b: /* fstp sti */
1880
                gen_op_fmov_STN_ST0(opreg);
1881
                gen_op_fpop();
1882
                break;
1883
            case 0x33: /* de/3 */
1884
                switch(rm) {
1885
                case 1: /* fcompp */
1886
                    gen_op_fmov_FT0_STN(1);
1887
                    gen_op_fcom_ST0_FT0();
1888
                    gen_op_fpop();
1889
                    gen_op_fpop();
1890
                    break;
1891
                default:
1892
                    return -1;
1893
                }
1894
                break;
1895
            case 0x3c: /* df/4 */
1896
                switch(rm) {
1897
#if 0
1898
                case 0:
1899
                    gen_insn3(OP_FNSTS, OR_EAX, OR_ZERO, OR_ZERO);
1900
                    break;
1901
#endif
1902
                default:
1903
                    return -1;
1904
                }
1905
                break;
1906
            default:
1907
                error("unhandled FP\n");
1908
                return -1;
1909
            }
1910
        }
1911
        break;
1912
        /************************/
1913
        /* string ops */
1914
    case 0xa4: /* movsS */
1915
    case 0xa5:
1916
        if ((b & 1) == 0)
1917
            ot = OT_BYTE;
1918
        else
1919
            ot = dflag ? OT_LONG : OT_WORD;
1920
        if (prefixes & PREFIX_REPZ) {
1921
            gen_op_movs[3 + ot]();
1922
        } else {
1923
            gen_op_movs[ot]();
1924
        }
1925
        break;
1926
        
1927
    case 0xaa: /* stosS */
1928
    case 0xab:
1929
        if ((b & 1) == 0)
1930
            ot = OT_BYTE;
1931
        else
1932
            ot = dflag ? OT_LONG : OT_WORD;
1933
        if (prefixes & PREFIX_REPZ) {
1934
            gen_op_stos[3 + ot]();
1935
        } else {
1936
            gen_op_stos[ot]();
1937
        }
1938
        break;
1939
    case 0xac: /* lodsS */
1940
    case 0xad:
1941
        if ((b & 1) == 0)
1942
            ot = OT_BYTE;
1943
        else
1944
            ot = dflag ? OT_LONG : OT_WORD;
1945
        if (prefixes & PREFIX_REPZ) {
1946
            gen_op_lods[3 + ot]();
1947
        } else {
1948
            gen_op_lods[ot]();
1949
        }
1950
        break;
1951
    case 0xae: /* scasS */
1952
    case 0xaf:
1953
        if ((b & 1) == 0)
1954
            ot = OT_BYTE;
1955
        else
1956
            ot = dflag ? OT_LONG : OT_WORD;
1957
        if (prefixes & PREFIX_REPNZ) {
1958
            gen_op_scas[6 + ot]();
1959
        } else if (prefixes & PREFIX_REPZ) {
1960
            gen_op_scas[3 + ot]();
1961
        } else {
1962
            gen_op_scas[ot]();
1963
        }
1964
        break;
1965

    
1966
    case 0xa6: /* cmpsS */
1967
    case 0xa7:
1968
        if ((b & 1) == 0)
1969
            ot = OT_BYTE;
1970
        else
1971
            ot = dflag ? OT_LONG : OT_WORD;
1972
        if (prefixes & PREFIX_REPNZ) {
1973
            gen_op_cmps[6 + ot]();
1974
        } else if (prefixes & PREFIX_REPZ) {
1975
            gen_op_cmps[3 + ot]();
1976
        } else {
1977
            gen_op_cmps[ot]();
1978
        }
1979
        break;
1980
        
1981
    case 0x6c: /* insS */
1982
    case 0x6d:
1983
        if ((b & 1) == 0)
1984
            ot = OT_BYTE;
1985
        else
1986
            ot = dflag ? OT_LONG : OT_WORD;
1987
        if (prefixes & PREFIX_REPZ) {
1988
            gen_op_ins[3 + ot]();
1989
        } else {
1990
            gen_op_ins[ot]();
1991
        }
1992
        break;
1993
    case 0x6e: /* outsS */
1994
    case 0x6f:
1995
        if ((b & 1) == 0)
1996
            ot = OT_BYTE;
1997
        else
1998
            ot = dflag ? OT_LONG : OT_WORD;
1999
        if (prefixes & PREFIX_REPZ) {
2000
            gen_op_outs[3 + ot]();
2001
        } else {
2002
            gen_op_outs[ot]();
2003
        }
2004
        break;
2005

    
2006
        /************************/
2007
        /* control */
2008
    case 0xc2: /* ret im */
2009
        /* XXX: handle stack pop ? */
2010
        val = ldsw(s->pc);
2011
        s->pc += 2;
2012
        gen_op_popl_T0();
2013
        gen_op_addl_ESP_im(val);
2014
        gen_op_jmp_T0();
2015
        break;
2016
    case 0xc3: /* ret */
2017
        gen_op_popl_T0();
2018
        gen_op_jmp_T0();
2019
        break;
2020
    case 0xe8: /* call */
2021
        val = insn_get(s, OT_LONG);
2022
        val += (long)s->pc;
2023
        gen_op1_movl_T1_im((long)s->pc);
2024
        gen_op_pushl_T1();
2025
        gen_op_jmp_im(val);
2026
        break;
2027
    case 0xe9: /* jmp */
2028
        val = insn_get(s, OT_LONG);
2029
        val += (long)s->pc;
2030
        gen_op_jmp_im(val);
2031
        break;
2032
    case 0xeb: /* jmp Jb */
2033
        val = (int8_t)insn_get(s, OT_BYTE);
2034
        val += (long)s->pc;
2035
        gen_op_jmp_im(val);
2036
        break;
2037
    case 0x70 ... 0x7f: /* jcc Jb */
2038
        val = (int8_t)insn_get(s, OT_BYTE);
2039
        val += (long)s->pc;
2040
        goto do_jcc;
2041
    case 0x180 ... 0x18f: /* jcc Jv */
2042
        if (dflag) {
2043
            val = insn_get(s, OT_LONG);
2044
        } else {
2045
            val = (int16_t)insn_get(s, OT_WORD); 
2046
        }
2047
        val += (long)s->pc; /* XXX: fix 16 bit wrap */
2048
    do_jcc:
2049
        gen_jcc(s, b, val);
2050
        break;
2051

    
2052
    case 0x190 ... 0x19f:
2053
        modrm = ldub(s->pc++);
2054
        gen_setcc(s, b);
2055
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2056
        break;
2057

    
2058
        /************************/
2059
        /* flags */
2060
    case 0x9c: /* pushf */
2061
        gen_op_movl_T0_eflags();
2062
        gen_op_pushl_T0();
2063
        break;
2064
    case 0x9d: /* popf */
2065
        gen_op_popl_T0();
2066
        gen_op_movl_eflags_T0();
2067
        s->cc_op = CC_OP_EFLAGS;
2068
        break;
2069
    case 0x9e: /* sahf */
2070
        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2071
        if (s->cc_op != CC_OP_DYNAMIC)
2072
            op_set_cc_op(s->cc_op);
2073
        gen_op_movb_eflags_T0();
2074
        s->cc_op = CC_OP_EFLAGS;
2075
        break;
2076
    case 0x9f: /* lahf */
2077
        if (s->cc_op != CC_OP_DYNAMIC)
2078
            op_set_cc_op(s->cc_op);
2079
        gen_op_movl_T0_eflags();
2080
        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2081
        break;
2082
    case 0xf5: /* cmc */
2083
        if (s->cc_op != CC_OP_DYNAMIC)
2084
            op_set_cc_op(s->cc_op);
2085
        gen_op_cmc();
2086
        s->cc_op = CC_OP_EFLAGS;
2087
        break;
2088
    case 0xf8: /* clc */
2089
        if (s->cc_op != CC_OP_DYNAMIC)
2090
            op_set_cc_op(s->cc_op);
2091
        gen_op_clc();
2092
        s->cc_op = CC_OP_EFLAGS;
2093
        break;
2094
    case 0xf9: /* stc */
2095
        if (s->cc_op != CC_OP_DYNAMIC)
2096
            op_set_cc_op(s->cc_op);
2097
        gen_op_stc();
2098
        s->cc_op = CC_OP_EFLAGS;
2099
        break;
2100
    case 0xfc: /* cld */
2101
        gen_op_cld();
2102
        break;
2103
    case 0xfd: /* std */
2104
        gen_op_std();
2105
        break;
2106

    
2107
        /************************/
2108
        /* misc */
2109
    case 0x90: /* nop */
2110
        break;
2111

    
2112
#if 0        
2113
    case 0x1a2: /* cpuid */
2114
        gen_insn0(OP_ASM);
2115
        break;
2116
#endif
2117
    default:
2118
        error("unknown opcode %x", b);
2119
        return -1;
2120
    }
2121
    return (long)s->pc;
2122
}
2123