Statistics
| Branch: | Revision:

root / translate-i386.c @ dc99065b

History | View | Annotate | Download (88.4 kB)

1
/*
2
 *  i386 translation
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <assert.h>
26

    
27
#define DEBUG_DISAS
28

    
29
#define IN_OP_I386
30
#include "cpu-i386.h"
31

    
32
/* dump all code */
33
#ifdef DEBUG_DISAS
34
#include "dis-asm.h"
35
#endif
36

    
37
#ifndef offsetof
38
#define offsetof(type, field) ((size_t) &((type *)0)->field)
39
#endif
40

    
41
static uint16_t *gen_opc_ptr;
42
static uint32_t *gen_opparam_ptr;
43
int __op_param1, __op_param2, __op_param3;
44

    
45
extern FILE *logfile;
46
extern int loglevel;
47

    
48
#define PREFIX_REPZ 1
49
#define PREFIX_REPNZ 2
50
#define PREFIX_LOCK 4
51
#define PREFIX_CS 8
52
#define PREFIX_SS 0x10
53
#define PREFIX_DS 0x20
54
#define PREFIX_ES 0x40
55
#define PREFIX_FS 0x80
56
#define PREFIX_GS 0x100
57
#define PREFIX_DATA 0x200
58
#define PREFIX_ADR 0x400
59
#define PREFIX_FWAIT 0x800
60

    
61
typedef struct DisasContext {
62
    /* current insn context */
63
    int prefix;
64
    int aflag, dflag;
65
    uint8_t *pc; /* current pc */
66
    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
67
                   static state change (stop translation) */
68
    /* current block context */
69
    int code32; /* 32 bit code segment */
70
    int cc_op;  /* current CC operation */
71
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
72
    int f_st;   /* currently unused */
73
} DisasContext;
74

    
75
/* i386 arith/logic operations */
76
enum {
77
    OP_ADDL, 
78
    OP_ORL, 
79
    OP_ADCL, 
80
    OP_SBBL,
81
    OP_ANDL, 
82
    OP_SUBL, 
83
    OP_XORL, 
84
    OP_CMPL,
85
};
86

    
87
/* i386 shift ops */
88
enum {
89
    OP_ROL, 
90
    OP_ROR, 
91
    OP_RCL, 
92
    OP_RCR, 
93
    OP_SHL, 
94
    OP_SHR, 
95
    OP_SHL1, /* undocumented */
96
    OP_SAR = 7,
97
};
98

    
99
enum {
100
#define DEF(s) INDEX_op_ ## s,
101
#include "opc-i386.h"
102
#undef DEF
103
    NB_OPS,
104
};
105

    
106
#include "op-i386.h"
107

    
108
/* operand size */
109
enum {
110
    OT_BYTE = 0,
111
    OT_WORD,
112
    OT_LONG, 
113
    OT_QUAD,
114
};
115

    
116
enum {
117
    /* I386 int registers */
118
    OR_EAX,   /* MUST be even numbered */
119
    OR_ECX,
120
    OR_EDX,
121
    OR_EBX,
122
    OR_ESP,
123
    OR_EBP,
124
    OR_ESI,
125
    OR_EDI,
126
    OR_TMP0,    /* temporary operand register */
127
    OR_TMP1,
128
    OR_A0, /* temporary register used when doing address evaluation */
129
    OR_ZERO, /* fixed zero register */
130
    NB_OREGS,
131
};
132

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

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

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

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

    
296
static GenOpFunc *gen_op_movl_A0_reg[8] = {
297
    gen_op_movl_A0_EAX,
298
    gen_op_movl_A0_ECX,
299
    gen_op_movl_A0_EDX,
300
    gen_op_movl_A0_EBX,
301
    gen_op_movl_A0_ESP,
302
    gen_op_movl_A0_EBP,
303
    gen_op_movl_A0_ESI,
304
    gen_op_movl_A0_EDI,
305
};
306

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

    
350
static GenOpFunc *gen_op_cmov_reg_T1_T0[2][8] = {
351
    [0] = {
352
        gen_op_cmovw_EAX_T1_T0,
353
        gen_op_cmovw_ECX_T1_T0,
354
        gen_op_cmovw_EDX_T1_T0,
355
        gen_op_cmovw_EBX_T1_T0,
356
        gen_op_cmovw_ESP_T1_T0,
357
        gen_op_cmovw_EBP_T1_T0,
358
        gen_op_cmovw_ESI_T1_T0,
359
        gen_op_cmovw_EDI_T1_T0,
360
    },
361
    [1] = {
362
        gen_op_cmovl_EAX_T1_T0,
363
        gen_op_cmovl_ECX_T1_T0,
364
        gen_op_cmovl_EDX_T1_T0,
365
        gen_op_cmovl_EBX_T1_T0,
366
        gen_op_cmovl_ESP_T1_T0,
367
        gen_op_cmovl_EBP_T1_T0,
368
        gen_op_cmovl_ESI_T1_T0,
369
        gen_op_cmovl_EDI_T1_T0,
370
    },
371
};
372

    
373
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
374
    gen_op_addl_T0_T1_cc,
375
    gen_op_orl_T0_T1_cc,
376
    NULL,
377
    NULL,
378
    gen_op_andl_T0_T1_cc,
379
    gen_op_subl_T0_T1_cc,
380
    gen_op_xorl_T0_T1_cc,
381
    gen_op_cmpl_T0_T1_cc,
382
};
383

    
384
static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
385
    [OT_BYTE] = {
386
        gen_op_adcb_T0_T1_cc,
387
        gen_op_sbbb_T0_T1_cc,
388
    },
389
    [OT_WORD] = {
390
        gen_op_adcw_T0_T1_cc,
391
        gen_op_sbbw_T0_T1_cc,
392
    },
393
    [OT_LONG] = {
394
        gen_op_adcl_T0_T1_cc,
395
        gen_op_sbbl_T0_T1_cc,
396
    },
397
};
398

    
399
static const int cc_op_arithb[8] = {
400
    CC_OP_ADDB,
401
    CC_OP_LOGICB,
402
    CC_OP_ADDB,
403
    CC_OP_SUBB,
404
    CC_OP_LOGICB,
405
    CC_OP_SUBB,
406
    CC_OP_LOGICB,
407
    CC_OP_SUBB,
408
};
409

    
410
static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[3] = {
411
    gen_op_cmpxchgb_T0_T1_EAX_cc,
412
    gen_op_cmpxchgw_T0_T1_EAX_cc,
413
    gen_op_cmpxchgl_T0_T1_EAX_cc,
414
};
415

    
416
static GenOpFunc *gen_op_shift_T0_T1_cc[3][8] = {
417
    [OT_BYTE] = {
418
        gen_op_rolb_T0_T1_cc,
419
        gen_op_rorb_T0_T1_cc,
420
        gen_op_rclb_T0_T1_cc,
421
        gen_op_rcrb_T0_T1_cc,
422
        gen_op_shlb_T0_T1_cc,
423
        gen_op_shrb_T0_T1_cc,
424
        gen_op_shlb_T0_T1_cc,
425
        gen_op_sarb_T0_T1_cc,
426
    },
427
    [OT_WORD] = {
428
        gen_op_rolw_T0_T1_cc,
429
        gen_op_rorw_T0_T1_cc,
430
        gen_op_rclw_T0_T1_cc,
431
        gen_op_rcrw_T0_T1_cc,
432
        gen_op_shlw_T0_T1_cc,
433
        gen_op_shrw_T0_T1_cc,
434
        gen_op_shlw_T0_T1_cc,
435
        gen_op_sarw_T0_T1_cc,
436
    },
437
    [OT_LONG] = {
438
        gen_op_roll_T0_T1_cc,
439
        gen_op_rorl_T0_T1_cc,
440
        gen_op_rcll_T0_T1_cc,
441
        gen_op_rcrl_T0_T1_cc,
442
        gen_op_shll_T0_T1_cc,
443
        gen_op_shrl_T0_T1_cc,
444
        gen_op_shll_T0_T1_cc,
445
        gen_op_sarl_T0_T1_cc,
446
    },
447
};
448

    
449
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[2][2] = {
450
    [0] = {
451
        gen_op_shldw_T0_T1_im_cc,
452
        gen_op_shrdw_T0_T1_im_cc,
453
    },
454
    [1] = {
455
        gen_op_shldl_T0_T1_im_cc,
456
        gen_op_shrdl_T0_T1_im_cc,
457
    },
458
};
459

    
460
static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[2][2] = {
461
    [0] = {
462
        gen_op_shldw_T0_T1_ECX_cc,
463
        gen_op_shrdw_T0_T1_ECX_cc,
464
    },
465
    [1] = {
466
        gen_op_shldl_T0_T1_ECX_cc,
467
        gen_op_shrdl_T0_T1_ECX_cc,
468
    },
469
};
470

    
471
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
472
    [0] = {
473
        gen_op_btw_T0_T1_cc,
474
        gen_op_btsw_T0_T1_cc,
475
        gen_op_btrw_T0_T1_cc,
476
        gen_op_btcw_T0_T1_cc,
477
    },
478
    [1] = {
479
        gen_op_btl_T0_T1_cc,
480
        gen_op_btsl_T0_T1_cc,
481
        gen_op_btrl_T0_T1_cc,
482
        gen_op_btcl_T0_T1_cc,
483
    },
484
};
485

    
486
static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
487
    [0] = {
488
        gen_op_bsfw_T0_cc,
489
        gen_op_bsrw_T0_cc,
490
    },
491
    [1] = {
492
        gen_op_bsfl_T0_cc,
493
        gen_op_bsrl_T0_cc,
494
    },
495
};
496

    
497
static GenOpFunc *gen_op_lds_T0_A0[3] = {
498
    gen_op_ldsb_T0_A0,
499
    gen_op_ldsw_T0_A0,
500
};
501

    
502
static GenOpFunc *gen_op_ldu_T0_A0[3] = {
503
    gen_op_ldub_T0_A0,
504
    gen_op_lduw_T0_A0,
505
};
506

    
507
/* sign does not matter */
508
static GenOpFunc *gen_op_ld_T0_A0[3] = {
509
    gen_op_ldub_T0_A0,
510
    gen_op_lduw_T0_A0,
511
    gen_op_ldl_T0_A0,
512
};
513

    
514
static GenOpFunc *gen_op_ld_T1_A0[3] = {
515
    gen_op_ldub_T1_A0,
516
    gen_op_lduw_T1_A0,
517
    gen_op_ldl_T1_A0,
518
};
519

    
520
static GenOpFunc *gen_op_st_T0_A0[3] = {
521
    gen_op_stb_T0_A0,
522
    gen_op_stw_T0_A0,
523
    gen_op_stl_T0_A0,
524
};
525

    
526
static GenOpFunc *gen_op_movs[6] = {
527
    gen_op_movsb,
528
    gen_op_movsw,
529
    gen_op_movsl,
530
    gen_op_rep_movsb,
531
    gen_op_rep_movsw,
532
    gen_op_rep_movsl,
533
};
534

    
535
static GenOpFunc *gen_op_stos[6] = {
536
    gen_op_stosb,
537
    gen_op_stosw,
538
    gen_op_stosl,
539
    gen_op_rep_stosb,
540
    gen_op_rep_stosw,
541
    gen_op_rep_stosl,
542
};
543

    
544
static GenOpFunc *gen_op_lods[6] = {
545
    gen_op_lodsb,
546
    gen_op_lodsw,
547
    gen_op_lodsl,
548
    gen_op_rep_lodsb,
549
    gen_op_rep_lodsw,
550
    gen_op_rep_lodsl,
551
};
552

    
553
static GenOpFunc *gen_op_scas[9] = {
554
    gen_op_scasb,
555
    gen_op_scasw,
556
    gen_op_scasl,
557
    gen_op_repz_scasb,
558
    gen_op_repz_scasw,
559
    gen_op_repz_scasl,
560
    gen_op_repnz_scasb,
561
    gen_op_repnz_scasw,
562
    gen_op_repnz_scasl,
563
};
564

    
565
static GenOpFunc *gen_op_cmps[9] = {
566
    gen_op_cmpsb,
567
    gen_op_cmpsw,
568
    gen_op_cmpsl,
569
    gen_op_repz_cmpsb,
570
    gen_op_repz_cmpsw,
571
    gen_op_repz_cmpsl,
572
    gen_op_repnz_cmpsb,
573
    gen_op_repnz_cmpsw,
574
    gen_op_repnz_cmpsl,
575
};
576

    
577
static GenOpFunc *gen_op_ins[6] = {
578
    gen_op_insb,
579
    gen_op_insw,
580
    gen_op_insl,
581
    gen_op_rep_insb,
582
    gen_op_rep_insw,
583
    gen_op_rep_insl,
584
};
585

    
586

    
587
static GenOpFunc *gen_op_outs[6] = {
588
    gen_op_outsb,
589
    gen_op_outsw,
590
    gen_op_outsl,
591
    gen_op_rep_outsb,
592
    gen_op_rep_outsw,
593
    gen_op_rep_outsl,
594
};
595

    
596
static GenOpFunc *gen_op_in[3] = {
597
    gen_op_inb_T0_T1,
598
    gen_op_inw_T0_T1,
599
    gen_op_inl_T0_T1,
600
};
601

    
602
static GenOpFunc *gen_op_out[3] = {
603
    gen_op_outb_T0_T1,
604
    gen_op_outw_T0_T1,
605
    gen_op_outl_T0_T1,
606
};
607

    
608
enum {
609
    JCC_O,
610
    JCC_B,
611
    JCC_Z,
612
    JCC_BE,
613
    JCC_S,
614
    JCC_P,
615
    JCC_L,
616
    JCC_LE,
617
};
618

    
619
static GenOpFunc2 *gen_jcc_slow[8] = {
620
    gen_op_jo_cc,
621
    gen_op_jb_cc,
622
    gen_op_jz_cc,
623
    gen_op_jbe_cc,
624
    gen_op_js_cc,
625
    gen_op_jp_cc,
626
    gen_op_jl_cc,
627
    gen_op_jle_cc,
628
};
629
    
630
static GenOpFunc2 *gen_jcc_sub[3][8] = {
631
    [OT_BYTE] = {
632
        NULL,
633
        gen_op_jb_subb,
634
        gen_op_jz_subb,
635
        gen_op_jbe_subb,
636
        gen_op_js_subb,
637
        NULL,
638
        gen_op_jl_subb,
639
        gen_op_jle_subb,
640
    },
641
    [OT_WORD] = {
642
        NULL,
643
        gen_op_jb_subw,
644
        gen_op_jz_subw,
645
        gen_op_jbe_subw,
646
        gen_op_js_subw,
647
        NULL,
648
        gen_op_jl_subw,
649
        gen_op_jle_subw,
650
    },
651
    [OT_LONG] = {
652
        NULL,
653
        gen_op_jb_subl,
654
        gen_op_jz_subl,
655
        gen_op_jbe_subl,
656
        gen_op_js_subl,
657
        NULL,
658
        gen_op_jl_subl,
659
        gen_op_jle_subl,
660
    },
661
};
662
static GenOpFunc2 *gen_op_loop[2][4] = {
663
    [0] = {
664
        gen_op_loopnzw,
665
        gen_op_loopzw,
666
        gen_op_loopw,
667
        gen_op_jecxzw,
668
    },
669
    [1] = {
670
        gen_op_loopnzl,
671
        gen_op_loopzl,
672
        gen_op_loopl,
673
        gen_op_jecxzl,
674
    },
675
};
676

    
677
static GenOpFunc *gen_setcc_slow[8] = {
678
    gen_op_seto_T0_cc,
679
    gen_op_setb_T0_cc,
680
    gen_op_setz_T0_cc,
681
    gen_op_setbe_T0_cc,
682
    gen_op_sets_T0_cc,
683
    gen_op_setp_T0_cc,
684
    gen_op_setl_T0_cc,
685
    gen_op_setle_T0_cc,
686
};
687

    
688
static GenOpFunc *gen_setcc_sub[3][8] = {
689
    [OT_BYTE] = {
690
        NULL,
691
        gen_op_setb_T0_subb,
692
        gen_op_setz_T0_subb,
693
        gen_op_setbe_T0_subb,
694
        gen_op_sets_T0_subb,
695
        NULL,
696
        gen_op_setl_T0_subb,
697
        gen_op_setle_T0_subb,
698
    },
699
    [OT_WORD] = {
700
        NULL,
701
        gen_op_setb_T0_subw,
702
        gen_op_setz_T0_subw,
703
        gen_op_setbe_T0_subw,
704
        gen_op_sets_T0_subw,
705
        NULL,
706
        gen_op_setl_T0_subw,
707
        gen_op_setle_T0_subw,
708
    },
709
    [OT_LONG] = {
710
        NULL,
711
        gen_op_setb_T0_subl,
712
        gen_op_setz_T0_subl,
713
        gen_op_setbe_T0_subl,
714
        gen_op_sets_T0_subl,
715
        NULL,
716
        gen_op_setl_T0_subl,
717
        gen_op_setle_T0_subl,
718
    },
719
};
720

    
721
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
722
    gen_op_fadd_ST0_FT0,
723
    gen_op_fmul_ST0_FT0,
724
    gen_op_fcom_ST0_FT0,
725
    gen_op_fcom_ST0_FT0,
726
    gen_op_fsub_ST0_FT0,
727
    gen_op_fsubr_ST0_FT0,
728
    gen_op_fdiv_ST0_FT0,
729
    gen_op_fdivr_ST0_FT0,
730
};
731

    
732
/* NOTE the exception in "r" op ordering */
733
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
734
    gen_op_fadd_STN_ST0,
735
    gen_op_fmul_STN_ST0,
736
    NULL,
737
    NULL,
738
    gen_op_fsubr_STN_ST0,
739
    gen_op_fsub_STN_ST0,
740
    gen_op_fdivr_STN_ST0,
741
    gen_op_fdiv_STN_ST0,
742
};
743

    
744
static void gen_op(DisasContext *s1, int op, int ot, int d, int s)
745
{
746
    if (d != OR_TMP0)
747
        gen_op_mov_TN_reg[ot][0][d]();
748
    if (s != OR_TMP1)
749
        gen_op_mov_TN_reg[ot][1][s]();
750
    if (op == OP_ADCL || op == OP_SBBL) {
751
        if (s1->cc_op != CC_OP_DYNAMIC)
752
            gen_op_set_cc_op(s1->cc_op);
753
        gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
754
        s1->cc_op = CC_OP_DYNAMIC;
755
    } else {
756
        gen_op_arith_T0_T1_cc[op]();
757
        s1->cc_op = cc_op_arithb[op] + ot;
758
    }
759
    if (d != OR_TMP0 && op != OP_CMPL)
760
        gen_op_mov_reg_T0[ot][d]();
761
}
762

    
763
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
764
{
765
    gen_op_movl_T1_im(c);
766
    gen_op(s1, op, ot, d, OR_TMP1);
767
}
768

    
769
static void gen_inc(DisasContext *s1, int ot, int d, int c)
770
{
771
    if (d != OR_TMP0)
772
        gen_op_mov_TN_reg[ot][0][d]();
773
    if (s1->cc_op != CC_OP_DYNAMIC)
774
        gen_op_set_cc_op(s1->cc_op);
775
    if (c > 0) {
776
        gen_op_incl_T0_cc();
777
        s1->cc_op = CC_OP_INCB + ot;
778
    } else {
779
        gen_op_decl_T0_cc();
780
        s1->cc_op = CC_OP_DECB + ot;
781
    }
782
    if (d != OR_TMP0)
783
        gen_op_mov_reg_T0[ot][d]();
784
}
785

    
786
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
787
{
788
    if (d != OR_TMP0)
789
        gen_op_mov_TN_reg[ot][0][d]();
790
    if (s != OR_TMP1)
791
        gen_op_mov_TN_reg[ot][1][s]();
792
    /* for zero counts, flags are not updated, so must do it dynamically */
793
    if (s1->cc_op != CC_OP_DYNAMIC)
794
        gen_op_set_cc_op(s1->cc_op);
795

    
796
    gen_op_shift_T0_T1_cc[ot][op]();
797

    
798
    if (d != OR_TMP0)
799
        gen_op_mov_reg_T0[ot][d]();
800
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
801
}
802

    
803
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
804
{
805
    /* currently not optimized */
806
    gen_op_movl_T1_im(c);
807
    gen_shift(s1, op, ot, d, OR_TMP1);
808
}
809

    
810
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
811
{
812
    int havesib;
813
    int base, disp;
814
    int index;
815
    int scale;
816
    int opreg;
817
    int mod, rm, code, override, must_add_seg;
818

    
819
    /* XXX: add a generation time variable to tell if base == 0 in DS/ES/SS */
820
    override = -1;
821
    must_add_seg = s->addseg;
822
    if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
823
                     PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
824
        if (s->prefix & PREFIX_ES)
825
            override = R_ES;
826
        else if (s->prefix & PREFIX_CS)
827
            override = R_CS;
828
        else if (s->prefix & PREFIX_SS)
829
            override = R_SS;
830
        else if (s->prefix & PREFIX_DS)
831
            override = R_DS;
832
        else if (s->prefix & PREFIX_FS)
833
            override = R_FS;
834
        else
835
            override = R_GS;
836
        must_add_seg = 1;
837
    }
838

    
839
    mod = (modrm >> 6) & 3;
840
    rm = modrm & 7;
841

    
842
    if (s->aflag) {
843

    
844
        havesib = 0;
845
        base = rm;
846
        index = 0;
847
        scale = 0;
848
        
849
        if (base == 4) {
850
            havesib = 1;
851
            code = ldub(s->pc++);
852
            scale = (code >> 6) & 3;
853
            index = (code >> 3) & 7;
854
            base = code & 7;
855
        }
856

    
857
        switch (mod) {
858
        case 0:
859
            if (base == 5) {
860
                base = -1;
861
                disp = ldl(s->pc);
862
                s->pc += 4;
863
            } else {
864
                disp = 0;
865
            }
866
            break;
867
        case 1:
868
            disp = (int8_t)ldub(s->pc++);
869
            break;
870
        default:
871
        case 2:
872
            disp = ldl(s->pc);
873
            s->pc += 4;
874
            break;
875
        }
876
        
877
        if (base >= 0) {
878
            gen_op_movl_A0_reg[base]();
879
            if (disp != 0)
880
                gen_op_addl_A0_im(disp);
881
        } else {
882
            gen_op_movl_A0_im(disp);
883
        }
884
        if (havesib && (index != 4 || scale != 0)) {
885
            gen_op_addl_A0_reg_sN[scale][index]();
886
        }
887
        if (must_add_seg) {
888
            if (override < 0) {
889
                if (base == R_EBP || base == R_ESP)
890
                    override = R_SS;
891
                else
892
                    override = R_DS;
893
            }
894
            gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
895
        }
896
    } else {
897
        switch (mod) {
898
        case 0:
899
            if (rm == 6) {
900
                disp = lduw(s->pc);
901
                s->pc += 2;
902
                gen_op_movl_A0_im(disp);
903
                rm = 0; /* avoid SS override */
904
                goto no_rm;
905
            } else {
906
                disp = 0;
907
            }
908
            break;
909
        case 1:
910
            disp = (int8_t)ldub(s->pc++);
911
            break;
912
        default:
913
        case 2:
914
            disp = lduw(s->pc);
915
            s->pc += 2;
916
            break;
917
        }
918
        switch(rm) {
919
        case 0:
920
            gen_op_movl_A0_reg[R_EBX]();
921
            gen_op_addl_A0_reg_sN[0][R_ESI]();
922
            break;
923
        case 1:
924
            gen_op_movl_A0_reg[R_EBX]();
925
            gen_op_addl_A0_reg_sN[0][R_EDI]();
926
            break;
927
        case 2:
928
            gen_op_movl_A0_reg[R_EBP]();
929
            gen_op_addl_A0_reg_sN[0][R_ESI]();
930
            break;
931
        case 3:
932
            gen_op_movl_A0_reg[R_EBP]();
933
            gen_op_addl_A0_reg_sN[0][R_EDI]();
934
            break;
935
        case 4:
936
            gen_op_movl_A0_reg[R_ESI]();
937
            break;
938
        case 5:
939
            gen_op_movl_A0_reg[R_EDI]();
940
            break;
941
        case 6:
942
            gen_op_movl_A0_reg[R_EBP]();
943
            break;
944
        default:
945
        case 7:
946
            gen_op_movl_A0_reg[R_EBX]();
947
            break;
948
        }
949
        if (disp != 0)
950
            gen_op_addl_A0_im(disp);
951
        gen_op_andl_A0_ffff();
952
    no_rm:
953
        if (must_add_seg) {
954
            if (override < 0) {
955
                if (rm == 2 || rm == 3 || rm == 6)
956
                    override = R_SS;
957
                else
958
                    override = R_DS;
959
            }
960
            gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
961
        }
962
    }
963

    
964
    opreg = OR_A0;
965
    disp = 0;
966
    *reg_ptr = opreg;
967
    *offset_ptr = disp;
968
}
969

    
970
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
971
   OR_TMP0 */
972
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
973
{
974
    int mod, rm, opreg, disp;
975

    
976
    mod = (modrm >> 6) & 3;
977
    rm = modrm & 7;
978
    if (mod == 3) {
979
        if (is_store) {
980
            if (reg != OR_TMP0)
981
                gen_op_mov_TN_reg[ot][0][reg]();
982
            gen_op_mov_reg_T0[ot][rm]();
983
        } else {
984
            gen_op_mov_TN_reg[ot][0][rm]();
985
            if (reg != OR_TMP0)
986
                gen_op_mov_reg_T0[ot][reg]();
987
        }
988
    } else {
989
        gen_lea_modrm(s, modrm, &opreg, &disp);
990
        if (is_store) {
991
            if (reg != OR_TMP0)
992
                gen_op_mov_TN_reg[ot][0][reg]();
993
            gen_op_st_T0_A0[ot]();
994
        } else {
995
            gen_op_ld_T0_A0[ot]();
996
            if (reg != OR_TMP0)
997
                gen_op_mov_reg_T0[ot][reg]();
998
        }
999
    }
1000
}
1001

    
1002
static inline uint32_t insn_get(DisasContext *s, int ot)
1003
{
1004
    uint32_t ret;
1005

    
1006
    switch(ot) {
1007
    case OT_BYTE:
1008
        ret = ldub(s->pc);
1009
        s->pc++;
1010
        break;
1011
    case OT_WORD:
1012
        ret = lduw(s->pc);
1013
        s->pc += 2;
1014
        break;
1015
    default:
1016
    case OT_LONG:
1017
        ret = ldl(s->pc);
1018
        s->pc += 4;
1019
        break;
1020
    }
1021
    return ret;
1022
}
1023

    
1024
static void gen_jcc(DisasContext *s, int b, int val)
1025
{
1026
    int inv, jcc_op;
1027
    GenOpFunc2 *func;
1028

    
1029
    inv = b & 1;
1030
    jcc_op = (b >> 1) & 7;
1031
    switch(s->cc_op) {
1032
        /* we optimize the cmp/jcc case */
1033
    case CC_OP_SUBB:
1034
    case CC_OP_SUBW:
1035
    case CC_OP_SUBL:
1036
        func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1037
        if (!func)
1038
            goto slow_jcc;
1039
        break;
1040
        
1041
        /* some jumps are easy to compute */
1042
    case CC_OP_ADDB:
1043
    case CC_OP_ADDW:
1044
    case CC_OP_ADDL:
1045
    case CC_OP_ADCB:
1046
    case CC_OP_ADCW:
1047
    case CC_OP_ADCL:
1048
    case CC_OP_SBBB:
1049
    case CC_OP_SBBW:
1050
    case CC_OP_SBBL:
1051
    case CC_OP_LOGICB:
1052
    case CC_OP_LOGICW:
1053
    case CC_OP_LOGICL:
1054
    case CC_OP_INCB:
1055
    case CC_OP_INCW:
1056
    case CC_OP_INCL:
1057
    case CC_OP_DECB:
1058
    case CC_OP_DECW:
1059
    case CC_OP_DECL:
1060
    case CC_OP_SHLB:
1061
    case CC_OP_SHLW:
1062
    case CC_OP_SHLL:
1063
    case CC_OP_SARB:
1064
    case CC_OP_SARW:
1065
    case CC_OP_SARL:
1066
        switch(jcc_op) {
1067
        case JCC_Z:
1068
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1069
            break;
1070
        case JCC_S:
1071
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1072
            break;
1073
        default:
1074
            goto slow_jcc;
1075
        }
1076
        break;
1077
    default:
1078
    slow_jcc:
1079
        if (s->cc_op != CC_OP_DYNAMIC)
1080
            gen_op_set_cc_op(s->cc_op);
1081
        func = gen_jcc_slow[jcc_op];
1082
        break;
1083
    }
1084
    if (!inv) {
1085
        func(val, (long)s->pc);
1086
    } else {
1087
        func((long)s->pc, val);
1088
    }
1089
}
1090

    
1091
static void gen_setcc(DisasContext *s, int b)
1092
{
1093
    int inv, jcc_op;
1094
    GenOpFunc *func;
1095

    
1096
    inv = b & 1;
1097
    jcc_op = (b >> 1) & 7;
1098
    switch(s->cc_op) {
1099
        /* we optimize the cmp/jcc case */
1100
    case CC_OP_SUBB:
1101
    case CC_OP_SUBW:
1102
    case CC_OP_SUBL:
1103
        func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1104
        if (!func)
1105
            goto slow_jcc;
1106
        break;
1107
        
1108
        /* some jumps are easy to compute */
1109
    case CC_OP_ADDB:
1110
    case CC_OP_ADDW:
1111
    case CC_OP_ADDL:
1112
    case CC_OP_LOGICB:
1113
    case CC_OP_LOGICW:
1114
    case CC_OP_LOGICL:
1115
    case CC_OP_INCB:
1116
    case CC_OP_INCW:
1117
    case CC_OP_INCL:
1118
    case CC_OP_DECB:
1119
    case CC_OP_DECW:
1120
    case CC_OP_DECL:
1121
    case CC_OP_SHLB:
1122
    case CC_OP_SHLW:
1123
    case CC_OP_SHLL:
1124
        switch(jcc_op) {
1125
        case JCC_Z:
1126
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1127
            break;
1128
        case JCC_S:
1129
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
1130
            break;
1131
        default:
1132
            goto slow_jcc;
1133
        }
1134
        break;
1135
    default:
1136
    slow_jcc:
1137
        if (s->cc_op != CC_OP_DYNAMIC)
1138
            gen_op_set_cc_op(s->cc_op);
1139
        func = gen_setcc_slow[jcc_op];
1140
        break;
1141
    }
1142
    func();
1143
    if (inv) {
1144
        gen_op_xor_T0_1();
1145
    }
1146
}
1147

    
1148
/* move T0 to seg_reg and compute if the CPU state may change */
1149
void gen_movl_seg_T0(DisasContext *s, int seg_reg)
1150
{
1151
    gen_op_movl_seg_T0(seg_reg);
1152
    if (!s->addseg && seg_reg < R_FS)
1153
        s->is_jmp = 2; /* abort translation because the register may
1154
                          have a non zero base */
1155
}
1156

    
1157
/* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1158
   is set to true if the instruction sets the PC (last instruction of
1159
   a basic block) */
1160
long disas_insn(DisasContext *s, uint8_t *pc_start)
1161
{
1162
    int b, prefixes, aflag, dflag;
1163
    int shift, ot;
1164
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
1165

    
1166
    s->pc = pc_start;
1167
    prefixes = 0;
1168
    aflag = s->code32;
1169
    dflag = s->code32;
1170
    //    cur_pc = s->pc; /* for insn generation */
1171
 next_byte:
1172
    b = ldub(s->pc);
1173
    s->pc++;
1174
    /* check prefixes */
1175
    switch (b) {
1176
    case 0xf3:
1177
        prefixes |= PREFIX_REPZ;
1178
        goto next_byte;
1179
    case 0xf2:
1180
        prefixes |= PREFIX_REPNZ;
1181
        goto next_byte;
1182
    case 0xf0:
1183
        prefixes |= PREFIX_LOCK;
1184
        goto next_byte;
1185
    case 0x2e:
1186
        prefixes |= PREFIX_CS;
1187
        goto next_byte;
1188
    case 0x36:
1189
        prefixes |= PREFIX_SS;
1190
        goto next_byte;
1191
    case 0x3e:
1192
        prefixes |= PREFIX_DS;
1193
        goto next_byte;
1194
    case 0x26:
1195
        prefixes |= PREFIX_ES;
1196
        goto next_byte;
1197
    case 0x64:
1198
        prefixes |= PREFIX_FS;
1199
        goto next_byte;
1200
    case 0x65:
1201
        prefixes |= PREFIX_GS;
1202
        goto next_byte;
1203
    case 0x66:
1204
        prefixes |= PREFIX_DATA;
1205
        goto next_byte;
1206
    case 0x67:
1207
        prefixes |= PREFIX_ADR;
1208
        goto next_byte;
1209
    case 0x9b:
1210
        prefixes |= PREFIX_FWAIT;
1211
        goto next_byte;
1212
    }
1213

    
1214
    if (prefixes & PREFIX_DATA)
1215
        dflag ^= 1;
1216
    if (prefixes & PREFIX_ADR)
1217
        aflag ^= 1;
1218

    
1219
    s->prefix = prefixes;
1220
    s->aflag = aflag;
1221
    s->dflag = dflag;
1222

    
1223
    /* now check op code */
1224
 reswitch:
1225
    switch(b) {
1226
    case 0x0f:
1227
        /**************************/
1228
        /* extended op code */
1229
        b = ldub(s->pc++) | 0x100;
1230
        goto reswitch;
1231
        
1232
        /**************************/
1233
        /* arith & logic */
1234
    case 0x00 ... 0x05:
1235
    case 0x08 ... 0x0d:
1236
    case 0x10 ... 0x15:
1237
    case 0x18 ... 0x1d:
1238
    case 0x20 ... 0x25:
1239
    case 0x28 ... 0x2d:
1240
    case 0x30 ... 0x35:
1241
    case 0x38 ... 0x3d:
1242
        {
1243
            int op, f, val;
1244
            op = (b >> 3) & 7;
1245
            f = (b >> 1) & 3;
1246

    
1247
            if ((b & 1) == 0)
1248
                ot = OT_BYTE;
1249
            else
1250
                ot = dflag ? OT_LONG : OT_WORD;
1251
            
1252
            switch(f) {
1253
            case 0: /* OP Ev, Gv */
1254
                modrm = ldub(s->pc++);
1255
                reg = ((modrm >> 3) & 7) + OR_EAX;
1256
                mod = (modrm >> 6) & 3;
1257
                rm = modrm & 7;
1258
                if (mod != 3) {
1259
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1260
                    gen_op_ld_T0_A0[ot]();
1261
                    opreg = OR_TMP0;
1262
                } else {
1263
                    opreg = OR_EAX + rm;
1264
                }
1265
                gen_op(s, op, ot, opreg, reg);
1266
                if (mod != 3 && op != 7) {
1267
                    gen_op_st_T0_A0[ot]();
1268
                }
1269
                break;
1270
            case 1: /* OP Gv, Ev */
1271
                modrm = ldub(s->pc++);
1272
                mod = (modrm >> 6) & 3;
1273
                reg = ((modrm >> 3) & 7) + OR_EAX;
1274
                rm = modrm & 7;
1275
                if (mod != 3) {
1276
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1277
                    gen_op_ld_T1_A0[ot]();
1278
                    opreg = OR_TMP1;
1279
                } else {
1280
                    opreg = OR_EAX + rm;
1281
                }
1282
                gen_op(s, op, ot, reg, opreg);
1283
                break;
1284
            case 2: /* OP A, Iv */
1285
                val = insn_get(s, ot);
1286
                gen_opi(s, op, ot, OR_EAX, val);
1287
                break;
1288
            }
1289
        }
1290
        break;
1291

    
1292
    case 0x80: /* GRP1 */
1293
    case 0x81:
1294
    case 0x83:
1295
        {
1296
            int val;
1297

    
1298
            if ((b & 1) == 0)
1299
                ot = OT_BYTE;
1300
            else
1301
                ot = dflag ? OT_LONG : OT_WORD;
1302
            
1303
            modrm = ldub(s->pc++);
1304
            mod = (modrm >> 6) & 3;
1305
            rm = modrm & 7;
1306
            op = (modrm >> 3) & 7;
1307
            
1308
            if (mod != 3) {
1309
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1310
                gen_op_ld_T0_A0[ot]();
1311
                opreg = OR_TMP0;
1312
            } else {
1313
                opreg = rm + OR_EAX;
1314
            }
1315

    
1316
            switch(b) {
1317
            default:
1318
            case 0x80:
1319
            case 0x81:
1320
                val = insn_get(s, ot);
1321
                break;
1322
            case 0x83:
1323
                val = (int8_t)insn_get(s, OT_BYTE);
1324
                break;
1325
            }
1326

    
1327
            gen_opi(s, op, ot, opreg, val);
1328
            if (op != 7 && mod != 3) {
1329
                gen_op_st_T0_A0[ot]();
1330
            }
1331
        }
1332
        break;
1333

    
1334
        /**************************/
1335
        /* inc, dec, and other misc arith */
1336
    case 0x40 ... 0x47: /* inc Gv */
1337
        ot = dflag ? OT_LONG : OT_WORD;
1338
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
1339
        break;
1340
    case 0x48 ... 0x4f: /* dec Gv */
1341
        ot = dflag ? OT_LONG : OT_WORD;
1342
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
1343
        break;
1344
    case 0xf6: /* GRP3 */
1345
    case 0xf7:
1346
        if ((b & 1) == 0)
1347
            ot = OT_BYTE;
1348
        else
1349
            ot = dflag ? OT_LONG : OT_WORD;
1350

    
1351
        modrm = ldub(s->pc++);
1352
        mod = (modrm >> 6) & 3;
1353
        rm = modrm & 7;
1354
        op = (modrm >> 3) & 7;
1355
        if (mod != 3) {
1356
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1357
            gen_op_ld_T0_A0[ot]();
1358
        } else {
1359
            gen_op_mov_TN_reg[ot][0][rm]();
1360
        }
1361

    
1362
        switch(op) {
1363
        case 0: /* test */
1364
            val = insn_get(s, ot);
1365
            gen_op_movl_T1_im(val);
1366
            gen_op_testl_T0_T1_cc();
1367
            s->cc_op = CC_OP_LOGICB + ot;
1368
            break;
1369
        case 2: /* not */
1370
            gen_op_notl_T0();
1371
            if (mod != 3) {
1372
                gen_op_st_T0_A0[ot]();
1373
            } else {
1374
                gen_op_mov_reg_T0[ot][rm]();
1375
            }
1376
            break;
1377
        case 3: /* neg */
1378
            gen_op_negl_T0_cc();
1379
            if (mod != 3) {
1380
                gen_op_st_T0_A0[ot]();
1381
            } else {
1382
                gen_op_mov_reg_T0[ot][rm]();
1383
            }
1384
            s->cc_op = CC_OP_SUBB + ot;
1385
            break;
1386
        case 4: /* mul */
1387
            switch(ot) {
1388
            case OT_BYTE:
1389
                gen_op_mulb_AL_T0();
1390
                break;
1391
            case OT_WORD:
1392
                gen_op_mulw_AX_T0();
1393
                break;
1394
            default:
1395
            case OT_LONG:
1396
                gen_op_mull_EAX_T0();
1397
                break;
1398
            }
1399
            s->cc_op = CC_OP_MUL;
1400
            break;
1401
        case 5: /* imul */
1402
            switch(ot) {
1403
            case OT_BYTE:
1404
                gen_op_imulb_AL_T0();
1405
                break;
1406
            case OT_WORD:
1407
                gen_op_imulw_AX_T0();
1408
                break;
1409
            default:
1410
            case OT_LONG:
1411
                gen_op_imull_EAX_T0();
1412
                break;
1413
            }
1414
            s->cc_op = CC_OP_MUL;
1415
            break;
1416
        case 6: /* div */
1417
            switch(ot) {
1418
            case OT_BYTE:
1419
                gen_op_divb_AL_T0();
1420
                break;
1421
            case OT_WORD:
1422
                gen_op_divw_AX_T0();
1423
                break;
1424
            default:
1425
            case OT_LONG:
1426
                gen_op_divl_EAX_T0();
1427
                break;
1428
            }
1429
            break;
1430
        case 7: /* idiv */
1431
            switch(ot) {
1432
            case OT_BYTE:
1433
                gen_op_idivb_AL_T0();
1434
                break;
1435
            case OT_WORD:
1436
                gen_op_idivw_AX_T0();
1437
                break;
1438
            default:
1439
            case OT_LONG:
1440
                gen_op_idivl_EAX_T0();
1441
                break;
1442
            }
1443
            break;
1444
        default:
1445
            goto illegal_op;
1446
        }
1447
        break;
1448

    
1449
    case 0xfe: /* GRP4 */
1450
    case 0xff: /* GRP5 */
1451
        if ((b & 1) == 0)
1452
            ot = OT_BYTE;
1453
        else
1454
            ot = dflag ? OT_LONG : OT_WORD;
1455

    
1456
        modrm = ldub(s->pc++);
1457
        mod = (modrm >> 6) & 3;
1458
        rm = modrm & 7;
1459
        op = (modrm >> 3) & 7;
1460
        if (op >= 2 && b == 0xfe) {
1461
            goto illegal_op;
1462
        }
1463
        if (mod != 3) {
1464
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1465
            gen_op_ld_T0_A0[ot]();
1466
        } else {
1467
            gen_op_mov_TN_reg[ot][0][rm]();
1468
        }
1469

    
1470
        switch(op) {
1471
        case 0: /* inc Ev */
1472
            gen_inc(s, ot, OR_TMP0, 1);
1473
            if (mod != 3)
1474
                gen_op_st_T0_A0[ot]();
1475
            else
1476
                gen_op_mov_reg_T0[ot][rm]();
1477
            break;
1478
        case 1: /* dec Ev */
1479
            gen_inc(s, ot, OR_TMP0, -1);
1480
            if (mod != 3)
1481
                gen_op_st_T0_A0[ot]();
1482
            else
1483
                gen_op_mov_reg_T0[ot][rm]();
1484
            break;
1485
        case 2: /* call Ev */
1486
            gen_op_movl_T1_im((long)s->pc);
1487
            gen_op_pushl_T1();
1488
            gen_op_jmp_T0();
1489
            s->is_jmp = 1;
1490
            break;
1491
        case 4: /* jmp Ev */
1492
            gen_op_jmp_T0();
1493
            s->is_jmp = 1;
1494
            break;
1495
        case 6: /* push Ev */
1496
            gen_op_pushl_T0();
1497
            break;
1498
        default:
1499
            goto illegal_op;
1500
        }
1501
        break;
1502

    
1503
    case 0x84: /* test Ev, Gv */
1504
    case 0x85: 
1505
        if ((b & 1) == 0)
1506
            ot = OT_BYTE;
1507
        else
1508
            ot = dflag ? OT_LONG : OT_WORD;
1509

    
1510
        modrm = ldub(s->pc++);
1511
        mod = (modrm >> 6) & 3;
1512
        rm = modrm & 7;
1513
        reg = (modrm >> 3) & 7;
1514
        
1515
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1516
        gen_op_mov_TN_reg[ot][1][reg + OR_EAX]();
1517
        gen_op_testl_T0_T1_cc();
1518
        s->cc_op = CC_OP_LOGICB + ot;
1519
        break;
1520
        
1521
    case 0xa8: /* test eAX, Iv */
1522
    case 0xa9:
1523
        if ((b & 1) == 0)
1524
            ot = OT_BYTE;
1525
        else
1526
            ot = dflag ? OT_LONG : OT_WORD;
1527
        val = insn_get(s, ot);
1528

    
1529
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
1530
        gen_op_movl_T1_im(val);
1531
        gen_op_testl_T0_T1_cc();
1532
        s->cc_op = CC_OP_LOGICB + ot;
1533
        break;
1534
        
1535
    case 0x98: /* CWDE/CBW */
1536
        if (dflag)
1537
            gen_op_movswl_EAX_AX();
1538
        else
1539
            gen_op_movsbw_AX_AL();
1540
        break;
1541
    case 0x99: /* CDQ/CWD */
1542
        if (dflag)
1543
            gen_op_movslq_EDX_EAX();
1544
        else
1545
            gen_op_movswl_DX_AX();
1546
        break;
1547
    case 0x1af: /* imul Gv, Ev */
1548
    case 0x69: /* imul Gv, Ev, I */
1549
    case 0x6b:
1550
        ot = dflag ? OT_LONG : OT_WORD;
1551
        modrm = ldub(s->pc++);
1552
        reg = ((modrm >> 3) & 7) + OR_EAX;
1553
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1554
        if (b == 0x69) {
1555
            val = insn_get(s, ot);
1556
            gen_op_movl_T1_im(val);
1557
        } else if (b == 0x6b) {
1558
            val = insn_get(s, OT_BYTE);
1559
            gen_op_movl_T1_im(val);
1560
        } else {
1561
            gen_op_mov_TN_reg[ot][1][reg]();
1562
        }
1563

    
1564
        if (ot == OT_LONG) {
1565
            gen_op_imull_T0_T1();
1566
        } else {
1567
            gen_op_imulw_T0_T1();
1568
        }
1569
        gen_op_mov_reg_T0[ot][reg]();
1570
        s->cc_op = CC_OP_MUL;
1571
        break;
1572
    case 0x1c0:
1573
    case 0x1c1: /* xadd Ev, Gv */
1574
        if ((b & 1) == 0)
1575
            ot = OT_BYTE;
1576
        else
1577
            ot = dflag ? OT_LONG : OT_WORD;
1578
        modrm = ldub(s->pc++);
1579
        reg = (modrm >> 3) & 7;
1580
        mod = (modrm >> 6) & 3;
1581
        if (mod == 3) {
1582
            rm = modrm & 7;
1583
            gen_op_mov_TN_reg[ot][0][reg]();
1584
            gen_op_mov_TN_reg[ot][1][rm]();
1585
            gen_op_addl_T0_T1_cc();
1586
            gen_op_mov_reg_T0[ot][rm]();
1587
            gen_op_mov_reg_T1[ot][reg]();
1588
        } else {
1589
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1590
            gen_op_mov_TN_reg[ot][0][reg]();
1591
            gen_op_ld_T1_A0[ot]();
1592
            gen_op_addl_T0_T1_cc();
1593
            gen_op_st_T0_A0[ot]();
1594
            gen_op_mov_reg_T1[ot][reg]();
1595
        }
1596
        s->cc_op = CC_OP_ADDB + ot;
1597
        break;
1598
    case 0x1b0:
1599
    case 0x1b1: /* cmpxchg Ev, Gv */
1600
        if ((b & 1) == 0)
1601
            ot = OT_BYTE;
1602
        else
1603
            ot = dflag ? OT_LONG : OT_WORD;
1604
        modrm = ldub(s->pc++);
1605
        reg = (modrm >> 3) & 7;
1606
        mod = (modrm >> 6) & 3;
1607
        gen_op_mov_TN_reg[ot][1][reg]();
1608
        if (mod == 3) {
1609
            rm = modrm & 7;
1610
            gen_op_mov_TN_reg[ot][0][rm]();
1611
            gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
1612
            gen_op_mov_reg_T0[ot][rm]();
1613
        } else {
1614
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1615
            gen_op_ld_T0_A0[ot]();
1616
            gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
1617
            gen_op_st_T0_A0[ot]();
1618
        }
1619
        s->cc_op = CC_OP_SUBB + ot;
1620
        break;
1621
        
1622
        /**************************/
1623
        /* push/pop */
1624
    case 0x50 ... 0x57: /* push */
1625
        gen_op_mov_TN_reg[OT_LONG][0][b & 7]();
1626
        gen_op_pushl_T0();
1627
        break;
1628
    case 0x58 ... 0x5f: /* pop */
1629
        gen_op_popl_T0();
1630
        gen_op_mov_reg_T0[OT_LONG][b & 7]();
1631
        break;
1632
    case 0x60: /* pusha */
1633
        if (s->dflag)
1634
            gen_op_pushal();
1635
        else
1636
            gen_op_pushaw();
1637
        break;
1638
    case 0x61: /* popa */
1639
        if (s->dflag)
1640
            gen_op_popal();
1641
        else
1642
            gen_op_popaw();
1643
        break;
1644
    case 0x68: /* push Iv */
1645
    case 0x6a:
1646
        ot = dflag ? OT_LONG : OT_WORD;
1647
        if (b == 0x68)
1648
            val = insn_get(s, ot);
1649
        else
1650
            val = (int8_t)insn_get(s, OT_BYTE);
1651
        gen_op_movl_T0_im(val);
1652
        gen_op_pushl_T0();
1653
        break;
1654
    case 0x8f: /* pop Ev */
1655
        ot = dflag ? OT_LONG : OT_WORD;
1656
        modrm = ldub(s->pc++);
1657
        gen_op_popl_T0();
1658
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1659
        break;
1660
    case 0xc8: /* enter */
1661
        {
1662
            int level;
1663
            val = lduw(s->pc);
1664
            s->pc += 2;
1665
            level = ldub(s->pc++);
1666
            level &= 0x1f;
1667
            gen_op_enterl(val, level);
1668
        }
1669
        break;
1670
    case 0xc9: /* leave */
1671
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1672
        gen_op_mov_reg_T0[OT_LONG][R_ESP]();
1673
        gen_op_popl_T0();
1674
        gen_op_mov_reg_T0[OT_LONG][R_EBP]();
1675
        break;
1676
    case 0x06: /* push es */
1677
    case 0x0e: /* push cs */
1678
    case 0x16: /* push ss */
1679
    case 0x1e: /* push ds */
1680
        gen_op_movl_T0_seg(b >> 3);
1681
        gen_op_pushl_T0();
1682
        break;
1683
    case 0x1a0: /* push fs */
1684
    case 0x1a8: /* push gs */
1685
        gen_op_movl_T0_seg(((b >> 3) & 7) + R_FS);
1686
        gen_op_pushl_T0();
1687
        break;
1688
    case 0x07: /* pop es */
1689
    case 0x17: /* pop ss */
1690
    case 0x1f: /* pop ds */
1691
        gen_op_popl_T0();
1692
        gen_movl_seg_T0(s, b >> 3);
1693
        break;
1694
    case 0x1a1: /* pop fs */
1695
    case 0x1a9: /* pop gs */
1696
        gen_op_popl_T0();
1697
        gen_movl_seg_T0(s, ((b >> 3) & 7) + R_FS);
1698
        break;
1699

    
1700
        /**************************/
1701
        /* mov */
1702
    case 0x88:
1703
    case 0x89: /* mov Gv, Ev */
1704
        if ((b & 1) == 0)
1705
            ot = OT_BYTE;
1706
        else
1707
            ot = dflag ? OT_LONG : OT_WORD;
1708
        modrm = ldub(s->pc++);
1709
        reg = (modrm >> 3) & 7;
1710
        
1711
        /* generate a generic store */
1712
        gen_ldst_modrm(s, modrm, ot, OR_EAX + reg, 1);
1713
        break;
1714
    case 0xc6:
1715
    case 0xc7: /* mov Ev, Iv */
1716
        if ((b & 1) == 0)
1717
            ot = OT_BYTE;
1718
        else
1719
            ot = dflag ? OT_LONG : OT_WORD;
1720
        modrm = ldub(s->pc++);
1721
        mod = (modrm >> 6) & 3;
1722
        if (mod != 3)
1723
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1724
        val = insn_get(s, ot);
1725
        gen_op_movl_T0_im(val);
1726
        if (mod != 3)
1727
            gen_op_st_T0_A0[ot]();
1728
        else
1729
            gen_op_mov_reg_T0[ot][modrm & 7]();
1730
        break;
1731
    case 0x8a:
1732
    case 0x8b: /* mov Ev, Gv */
1733
        if ((b & 1) == 0)
1734
            ot = OT_BYTE;
1735
        else
1736
            ot = dflag ? OT_LONG : OT_WORD;
1737
        modrm = ldub(s->pc++);
1738
        reg = (modrm >> 3) & 7;
1739
        
1740
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1741
        gen_op_mov_reg_T0[ot][reg]();
1742
        break;
1743
    case 0x8e: /* mov seg, Gv */
1744
        ot = dflag ? OT_LONG : OT_WORD;
1745
        modrm = ldub(s->pc++);
1746
        reg = (modrm >> 3) & 7;
1747
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1748
        if (reg >= 6)
1749
            goto illegal_op;
1750
        gen_movl_seg_T0(s, reg);
1751
        break;
1752
    case 0x8c: /* mov Gv, seg */
1753
        ot = dflag ? OT_LONG : OT_WORD;
1754
        modrm = ldub(s->pc++);
1755
        reg = (modrm >> 3) & 7;
1756
        if (reg >= 6)
1757
            goto illegal_op;
1758
        gen_op_movl_T0_seg(reg);
1759
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
1760
        break;
1761

    
1762
    case 0x1b6: /* movzbS Gv, Eb */
1763
    case 0x1b7: /* movzwS Gv, Eb */
1764
    case 0x1be: /* movsbS Gv, Eb */
1765
    case 0x1bf: /* movswS Gv, Eb */
1766
        {
1767
            int d_ot;
1768
            /* d_ot is the size of destination */
1769
            d_ot = dflag + OT_WORD;
1770
            /* ot is the size of source */
1771
            ot = (b & 1) + OT_BYTE;
1772
            modrm = ldub(s->pc++);
1773
            reg = ((modrm >> 3) & 7) + OR_EAX;
1774
            mod = (modrm >> 6) & 3;
1775
            rm = modrm & 7;
1776
            
1777
            if (mod == 3) {
1778
                gen_op_mov_TN_reg[ot][0][rm]();
1779
                switch(ot | (b & 8)) {
1780
                case OT_BYTE:
1781
                    gen_op_movzbl_T0_T0();
1782
                    break;
1783
                case OT_BYTE | 8:
1784
                    gen_op_movsbl_T0_T0();
1785
                    break;
1786
                case OT_WORD:
1787
                    gen_op_movzwl_T0_T0();
1788
                    break;
1789
                default:
1790
                case OT_WORD | 8:
1791
                    gen_op_movswl_T0_T0();
1792
                    break;
1793
                }
1794
                gen_op_mov_reg_T0[d_ot][reg]();
1795
            } else {
1796
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1797
                if (b & 8) {
1798
                    gen_op_lds_T0_A0[ot]();
1799
                } else {
1800
                    gen_op_ldu_T0_A0[ot]();
1801
                }
1802
                gen_op_mov_reg_T0[d_ot][reg]();
1803
            }
1804
        }
1805
        break;
1806

    
1807
    case 0x8d: /* lea */
1808
        ot = dflag ? OT_LONG : OT_WORD;
1809
        modrm = ldub(s->pc++);
1810
        reg = (modrm >> 3) & 7;
1811
        /* we must ensure that no segment is added */
1812
        s->prefix &= ~(PREFIX_CS | PREFIX_SS | PREFIX_DS | 
1813
                       PREFIX_ES | PREFIX_FS | PREFIX_GS);
1814
        val = s->addseg;
1815
        s->addseg = 0;
1816
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1817
        s->addseg = val;
1818
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
1819
        break;
1820
        
1821
    case 0xa0: /* mov EAX, Ov */
1822
    case 0xa1:
1823
    case 0xa2: /* mov Ov, EAX */
1824
    case 0xa3:
1825
        if ((b & 1) == 0)
1826
            ot = OT_BYTE;
1827
        else
1828
            ot = dflag ? OT_LONG : OT_WORD;
1829
        if (s->aflag)
1830
            offset_addr = insn_get(s, OT_LONG);
1831
        else
1832
            offset_addr = insn_get(s, OT_WORD);
1833
        gen_op_movl_A0_im(offset_addr);
1834
        /* handle override */
1835
        /* XXX: factorize that */
1836
        {
1837
            int override, must_add_seg;
1838
            override = R_DS;
1839
            must_add_seg = s->addseg;
1840
            if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
1841
                             PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
1842
                if (s->prefix & PREFIX_ES)
1843
                    override = R_ES;
1844
                else if (s->prefix & PREFIX_CS)
1845
                    override = R_CS;
1846
                else if (s->prefix & PREFIX_SS)
1847
                    override = R_SS;
1848
                else if (s->prefix & PREFIX_DS)
1849
                    override = R_DS;
1850
                else if (s->prefix & PREFIX_FS)
1851
                    override = R_FS;
1852
                else
1853
                    override = R_GS;
1854
                must_add_seg = 1;
1855
            }
1856
            if (must_add_seg) {
1857
                gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
1858
            }
1859
        }
1860
        if ((b & 2) == 0) {
1861
            gen_op_ld_T0_A0[ot]();
1862
            gen_op_mov_reg_T0[ot][R_EAX]();
1863
        } else {
1864
            gen_op_mov_TN_reg[ot][0][R_EAX]();
1865
            gen_op_st_T0_A0[ot]();
1866
        }
1867
        break;
1868

    
1869
    case 0xb0 ... 0xb7: /* mov R, Ib */
1870
        val = insn_get(s, OT_BYTE);
1871
        gen_op_movl_T0_im(val);
1872
        gen_op_mov_reg_T0[OT_BYTE][b & 7]();
1873
        break;
1874
    case 0xb8 ... 0xbf: /* mov R, Iv */
1875
        ot = dflag ? OT_LONG : OT_WORD;
1876
        val = insn_get(s, ot);
1877
        reg = OR_EAX + (b & 7);
1878
        gen_op_movl_T0_im(val);
1879
        gen_op_mov_reg_T0[ot][reg]();
1880
        break;
1881

    
1882
    case 0x91 ... 0x97: /* xchg R, EAX */
1883
        ot = dflag ? OT_LONG : OT_WORD;
1884
        reg = b & 7;
1885
        rm = R_EAX;
1886
        goto do_xchg_reg;
1887
    case 0x86:
1888
    case 0x87: /* xchg Ev, Gv */
1889
        if ((b & 1) == 0)
1890
            ot = OT_BYTE;
1891
        else
1892
            ot = dflag ? OT_LONG : OT_WORD;
1893
        modrm = ldub(s->pc++);
1894
        reg = (modrm >> 3) & 7;
1895
        mod = (modrm >> 6) & 3;
1896
        if (mod == 3) {
1897
            rm = modrm & 7;
1898
        do_xchg_reg:
1899
            gen_op_mov_TN_reg[ot][0][reg]();
1900
            gen_op_mov_TN_reg[ot][1][rm]();
1901
            gen_op_mov_reg_T0[ot][rm]();
1902
            gen_op_mov_reg_T1[ot][reg]();
1903
        } else {
1904
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1905
            gen_op_mov_TN_reg[ot][0][reg]();
1906
            gen_op_ld_T1_A0[ot]();
1907
            gen_op_st_T0_A0[ot]();
1908
            gen_op_mov_reg_T1[ot][reg]();
1909
        }
1910
        break;
1911
    case 0xc4: /* les Gv */
1912
        op = R_ES;
1913
        goto do_lxx;
1914
    case 0xc5: /* lds Gv */
1915
        op = R_DS;
1916
        goto do_lxx;
1917
    case 0x1b2: /* lss Gv */
1918
        op = R_SS;
1919
        goto do_lxx;
1920
    case 0x1b4: /* lfs Gv */
1921
        op = R_FS;
1922
        goto do_lxx;
1923
    case 0x1b5: /* lgs Gv */
1924
        op = R_GS;
1925
    do_lxx:
1926
        ot = dflag ? OT_LONG : OT_WORD;
1927
        modrm = ldub(s->pc++);
1928
        reg = (modrm >> 3) & 7;
1929
        mod = (modrm >> 6) & 3;
1930
        if (mod == 3)
1931
            goto illegal_op;
1932
        gen_op_ld_T1_A0[ot]();
1933
        gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1934
        /* load the segment first to handle exceptions properly */
1935
        gen_op_lduw_T0_A0();
1936
        gen_movl_seg_T0(s, op);
1937
        /* then put the data */
1938
        gen_op_mov_reg_T1[ot][reg]();
1939
        break;
1940
        
1941
        /************************/
1942
        /* shifts */
1943
    case 0xc0:
1944
    case 0xc1:
1945
        /* shift Ev,Ib */
1946
        shift = 2;
1947
    grp2:
1948
        {
1949
            if ((b & 1) == 0)
1950
                ot = OT_BYTE;
1951
            else
1952
                ot = dflag ? OT_LONG : OT_WORD;
1953
            
1954
            modrm = ldub(s->pc++);
1955
            mod = (modrm >> 6) & 3;
1956
            rm = modrm & 7;
1957
            op = (modrm >> 3) & 7;
1958
            
1959
            if (mod != 3) {
1960
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1961
                gen_op_ld_T0_A0[ot]();
1962
                opreg = OR_TMP0;
1963
            } else {
1964
                opreg = rm + OR_EAX;
1965
            }
1966

    
1967
            /* simpler op */
1968
            if (shift == 0) {
1969
                gen_shift(s, op, ot, opreg, OR_ECX);
1970
            } else {
1971
                if (shift == 2) {
1972
                    shift = ldub(s->pc++);
1973
                }
1974
                gen_shifti(s, op, ot, opreg, shift);
1975
            }
1976

    
1977
            if (mod != 3) {
1978
                gen_op_st_T0_A0[ot]();
1979
            }
1980
        }
1981
        break;
1982
    case 0xd0:
1983
    case 0xd1:
1984
        /* shift Ev,1 */
1985
        shift = 1;
1986
        goto grp2;
1987
    case 0xd2:
1988
    case 0xd3:
1989
        /* shift Ev,cl */
1990
        shift = 0;
1991
        goto grp2;
1992

    
1993
    case 0x1a4: /* shld imm */
1994
        op = 0;
1995
        shift = 1;
1996
        goto do_shiftd;
1997
    case 0x1a5: /* shld cl */
1998
        op = 0;
1999
        shift = 0;
2000
        goto do_shiftd;
2001
    case 0x1ac: /* shrd imm */
2002
        op = 1;
2003
        shift = 1;
2004
        goto do_shiftd;
2005
    case 0x1ad: /* shrd cl */
2006
        op = 1;
2007
        shift = 0;
2008
    do_shiftd:
2009
        ot = dflag ? OT_LONG : OT_WORD;
2010
        modrm = ldub(s->pc++);
2011
        mod = (modrm >> 6) & 3;
2012
        rm = modrm & 7;
2013
        reg = (modrm >> 3) & 7;
2014
        
2015
        if (mod != 3) {
2016
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2017
            gen_op_ld_T0_A0[ot]();
2018
        } else {
2019
            gen_op_mov_TN_reg[ot][0][rm]();
2020
        }
2021
        gen_op_mov_TN_reg[ot][1][reg]();
2022
        
2023
        if (shift) {
2024
            val = ldub(s->pc++);
2025
            val &= 0x1f;
2026
            if (val) {
2027
                gen_op_shiftd_T0_T1_im_cc[ot - OT_WORD][op](val);
2028
                if (op == 0 && ot != OT_WORD)
2029
                    s->cc_op = CC_OP_SHLB + ot;
2030
                else
2031
                    s->cc_op = CC_OP_SARB + ot;
2032
            }
2033
        } else {
2034
            if (s->cc_op != CC_OP_DYNAMIC)
2035
                gen_op_set_cc_op(s->cc_op);
2036
            gen_op_shiftd_T0_T1_ECX_cc[ot - OT_WORD][op]();
2037
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2038
        }
2039
        if (mod != 3) {
2040
            gen_op_st_T0_A0[ot]();
2041
        } else {
2042
            gen_op_mov_reg_T0[ot][rm]();
2043
        }
2044
        break;
2045

    
2046
        /************************/
2047
        /* floats */
2048
    case 0xd8 ... 0xdf: 
2049
        modrm = ldub(s->pc++);
2050
        mod = (modrm >> 6) & 3;
2051
        rm = modrm & 7;
2052
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
2053
        
2054
        if (mod != 3) {
2055
            /* memory op */
2056
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2057
            switch(op) {
2058
            case 0x00 ... 0x07: /* fxxxs */
2059
            case 0x10 ... 0x17: /* fixxxl */
2060
            case 0x20 ... 0x27: /* fxxxl */
2061
            case 0x30 ... 0x37: /* fixxx */
2062
                {
2063
                    int op1;
2064
                    op1 = op & 7;
2065

    
2066
                    switch(op >> 4) {
2067
                    case 0:
2068
                        gen_op_flds_FT0_A0();
2069
                        break;
2070
                    case 1:
2071
                        gen_op_fildl_FT0_A0();
2072
                        break;
2073
                    case 2:
2074
                        gen_op_fldl_FT0_A0();
2075
                        break;
2076
                    case 3:
2077
                    default:
2078
                        gen_op_fild_FT0_A0();
2079
                        break;
2080
                    }
2081
                    
2082
                    gen_op_fp_arith_ST0_FT0[op1]();
2083
                    if (op1 == 3) {
2084
                        /* fcomp needs pop */
2085
                        gen_op_fpop();
2086
                    }
2087
                }
2088
                break;
2089
            case 0x08: /* flds */
2090
            case 0x0a: /* fsts */
2091
            case 0x0b: /* fstps */
2092
            case 0x18: /* fildl */
2093
            case 0x1a: /* fistl */
2094
            case 0x1b: /* fistpl */
2095
            case 0x28: /* fldl */
2096
            case 0x2a: /* fstl */
2097
            case 0x2b: /* fstpl */
2098
            case 0x38: /* filds */
2099
            case 0x3a: /* fists */
2100
            case 0x3b: /* fistps */
2101
                
2102
                switch(op & 7) {
2103
                case 0:
2104
                    gen_op_fpush();
2105
                    switch(op >> 4) {
2106
                    case 0:
2107
                        gen_op_flds_ST0_A0();
2108
                        break;
2109
                    case 1:
2110
                        gen_op_fildl_ST0_A0();
2111
                        break;
2112
                    case 2:
2113
                        gen_op_fldl_ST0_A0();
2114
                        break;
2115
                    case 3:
2116
                    default:
2117
                        gen_op_fild_ST0_A0();
2118
                        break;
2119
                    }
2120
                    break;
2121
                default:
2122
                    switch(op >> 4) {
2123
                    case 0:
2124
                        gen_op_fsts_ST0_A0();
2125
                        break;
2126
                    case 1:
2127
                        gen_op_fistl_ST0_A0();
2128
                        break;
2129
                    case 2:
2130
                        gen_op_fstl_ST0_A0();
2131
                        break;
2132
                    case 3:
2133
                    default:
2134
                        gen_op_fist_ST0_A0();
2135
                        break;
2136
                    }
2137
                    if ((op & 7) == 3)
2138
                        gen_op_fpop();
2139
                    break;
2140
                }
2141
                break;
2142
            case 0x0d: /* fldcw mem */
2143
                gen_op_fldcw_A0();
2144
                break;
2145
            case 0x0f: /* fnstcw mem */
2146
                gen_op_fnstcw_A0();
2147
                break;
2148
            case 0x1d: /* fldt mem */
2149
                gen_op_fpush();
2150
                gen_op_fldt_ST0_A0();
2151
                break;
2152
            case 0x1f: /* fstpt mem */
2153
                gen_op_fstt_ST0_A0();
2154
                gen_op_fpop();
2155
                break;
2156
            case 0x2f: /* fnstsw mem */
2157
                gen_op_fnstsw_A0();
2158
                break;
2159
            case 0x3c: /* fbld */
2160
                gen_op_fpush();
2161
                gen_op_fbld_ST0_A0();
2162
                break;
2163
            case 0x3e: /* fbstp */
2164
                gen_op_fbst_ST0_A0();
2165
                gen_op_fpop();
2166
                break;
2167
            case 0x3d: /* fildll */
2168
                gen_op_fpush();
2169
                gen_op_fildll_ST0_A0();
2170
                break;
2171
            case 0x3f: /* fistpll */
2172
                gen_op_fistll_ST0_A0();
2173
                gen_op_fpop();
2174
                break;
2175
            default:
2176
                goto illegal_op;
2177
            }
2178
        } else {
2179
            /* register float ops */
2180
            opreg = rm;
2181

    
2182
            switch(op) {
2183
            case 0x08: /* fld sti */
2184
                gen_op_fpush();
2185
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
2186
                break;
2187
            case 0x09: /* fxchg sti */
2188
                gen_op_fxchg_ST0_STN(opreg);
2189
                break;
2190
            case 0x0a: /* grp d9/2 */
2191
                switch(rm) {
2192
                case 0: /* fnop */
2193
                    break;
2194
                default:
2195
                    goto illegal_op;
2196
                }
2197
                break;
2198
            case 0x0c: /* grp d9/4 */
2199
                switch(rm) {
2200
                case 0: /* fchs */
2201
                    gen_op_fchs_ST0();
2202
                    break;
2203
                case 1: /* fabs */
2204
                    gen_op_fabs_ST0();
2205
                    break;
2206
                case 4: /* ftst */
2207
                    gen_op_fldz_FT0();
2208
                    gen_op_fcom_ST0_FT0();
2209
                    break;
2210
                case 5: /* fxam */
2211
                    gen_op_fxam_ST0();
2212
                    break;
2213
                default:
2214
                    goto illegal_op;
2215
                }
2216
                break;
2217
            case 0x0d: /* grp d9/5 */
2218
                {
2219
                    switch(rm) {
2220
                    case 0:
2221
                        gen_op_fpush();
2222
                        gen_op_fld1_ST0();
2223
                        break;
2224
                    case 1:
2225
                        gen_op_fpush();
2226
                        gen_op_fldl2t_ST0();
2227
                        break;
2228
                    case 2:
2229
                        gen_op_fpush();
2230
                        gen_op_fldl2e_ST0();
2231
                        break;
2232
                    case 3:
2233
                        gen_op_fpush();
2234
                        gen_op_fldpi_ST0();
2235
                        break;
2236
                    case 4:
2237
                        gen_op_fpush();
2238
                        gen_op_fldlg2_ST0();
2239
                        break;
2240
                    case 5:
2241
                        gen_op_fpush();
2242
                        gen_op_fldln2_ST0();
2243
                        break;
2244
                    case 6:
2245
                        gen_op_fpush();
2246
                        gen_op_fldz_ST0();
2247
                        break;
2248
                    default:
2249
                        goto illegal_op;
2250
                    }
2251
                }
2252
                break;
2253
            case 0x0e: /* grp d9/6 */
2254
                switch(rm) {
2255
                case 0: /* f2xm1 */
2256
                    gen_op_f2xm1();
2257
                    break;
2258
                case 1: /* fyl2x */
2259
                    gen_op_fyl2x();
2260
                    break;
2261
                case 2: /* fptan */
2262
                    gen_op_fptan();
2263
                    break;
2264
                case 3: /* fpatan */
2265
                    gen_op_fpatan();
2266
                    break;
2267
                case 4: /* fxtract */
2268
                    gen_op_fxtract();
2269
                    break;
2270
                case 5: /* fprem1 */
2271
                    gen_op_fprem1();
2272
                    break;
2273
                case 6: /* fdecstp */
2274
                    gen_op_fdecstp();
2275
                    break;
2276
                default:
2277
                case 7: /* fincstp */
2278
                    gen_op_fincstp();
2279
                    break;
2280
                }
2281
                break;
2282
            case 0x0f: /* grp d9/7 */
2283
                switch(rm) {
2284
                case 0: /* fprem */
2285
                    gen_op_fprem();
2286
                    break;
2287
                case 1: /* fyl2xp1 */
2288
                    gen_op_fyl2xp1();
2289
                    break;
2290
                case 2: /* fsqrt */
2291
                    gen_op_fsqrt();
2292
                    break;
2293
                case 3: /* fsincos */
2294
                    gen_op_fsincos();
2295
                    break;
2296
                case 5: /* fscale */
2297
                    gen_op_fscale();
2298
                    break;
2299
                case 4: /* frndint */
2300
                    gen_op_frndint();
2301
                    break;
2302
                case 6: /* fsin */
2303
                    gen_op_fsin();
2304
                    break;
2305
                default:
2306
                case 7: /* fcos */
2307
                    gen_op_fcos();
2308
                    break;
2309
                }
2310
                break;
2311
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
2312
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
2313
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
2314
                {
2315
                    int op1;
2316
                    
2317
                    op1 = op & 7;
2318
                    if (op >= 0x20) {
2319
                        gen_op_fp_arith_STN_ST0[op1](opreg);
2320
                        if (op >= 0x30)
2321
                            gen_op_fpop();
2322
                    } else {
2323
                        gen_op_fmov_FT0_STN(opreg);
2324
                        gen_op_fp_arith_ST0_FT0[op1]();
2325
                    }
2326
                }
2327
                break;
2328
            case 0x02: /* fcom */
2329
                gen_op_fmov_FT0_STN(opreg);
2330
                gen_op_fcom_ST0_FT0();
2331
                break;
2332
            case 0x03: /* fcomp */
2333
                gen_op_fmov_FT0_STN(opreg);
2334
                gen_op_fcom_ST0_FT0();
2335
                gen_op_fpop();
2336
                break;
2337
            case 0x15: /* da/5 */
2338
                switch(rm) {
2339
                case 1: /* fucompp */
2340
                    gen_op_fmov_FT0_STN(1);
2341
                    gen_op_fucom_ST0_FT0();
2342
                    gen_op_fpop();
2343
                    gen_op_fpop();
2344
                    break;
2345
                default:
2346
                    goto illegal_op;
2347
                }
2348
                break;
2349
            case 0x1c:
2350
                switch(rm) {
2351
                case 2: /* fclex */
2352
                    gen_op_fclex();
2353
                    break;
2354
                case 3: /* fninit */
2355
                    gen_op_fninit();
2356
                    break;
2357
                default:
2358
                    goto illegal_op;
2359
                }
2360
                break;
2361
            case 0x2a: /* fst sti */
2362
                gen_op_fmov_STN_ST0(opreg);
2363
                break;
2364
            case 0x2b: /* fstp sti */
2365
                gen_op_fmov_STN_ST0(opreg);
2366
                gen_op_fpop();
2367
                break;
2368
            case 0x2c: /* fucom st(i) */
2369
                gen_op_fmov_FT0_STN(opreg);
2370
                gen_op_fucom_ST0_FT0();
2371
                break;
2372
            case 0x2d: /* fucomp st(i) */
2373
                gen_op_fmov_FT0_STN(opreg);
2374
                gen_op_fucom_ST0_FT0();
2375
                gen_op_fpop();
2376
                break;
2377
            case 0x33: /* de/3 */
2378
                switch(rm) {
2379
                case 1: /* fcompp */
2380
                    gen_op_fmov_FT0_STN(1);
2381
                    gen_op_fcom_ST0_FT0();
2382
                    gen_op_fpop();
2383
                    gen_op_fpop();
2384
                    break;
2385
                default:
2386
                    goto illegal_op;
2387
                }
2388
                break;
2389
            case 0x3c: /* df/4 */
2390
                switch(rm) {
2391
                case 0:
2392
                    gen_op_fnstsw_EAX();
2393
                    break;
2394
                default:
2395
                    goto illegal_op;
2396
                }
2397
                break;
2398
            default:
2399
                goto illegal_op;
2400
            }
2401
        }
2402
        break;
2403
        /************************/
2404
        /* string ops */
2405
    case 0xa4: /* movsS */
2406
    case 0xa5:
2407
        if ((b & 1) == 0)
2408
            ot = OT_BYTE;
2409
        else
2410
            ot = dflag ? OT_LONG : OT_WORD;
2411
        if (prefixes & PREFIX_REPZ) {
2412
            gen_op_movs[3 + ot]();
2413
        } else {
2414
            gen_op_movs[ot]();
2415
        }
2416
        break;
2417
        
2418
    case 0xaa: /* stosS */
2419
    case 0xab:
2420
        if ((b & 1) == 0)
2421
            ot = OT_BYTE;
2422
        else
2423
            ot = dflag ? OT_LONG : OT_WORD;
2424
        if (prefixes & PREFIX_REPZ) {
2425
            gen_op_stos[3 + ot]();
2426
        } else {
2427
            gen_op_stos[ot]();
2428
        }
2429
        break;
2430
    case 0xac: /* lodsS */
2431
    case 0xad:
2432
        if ((b & 1) == 0)
2433
            ot = OT_BYTE;
2434
        else
2435
            ot = dflag ? OT_LONG : OT_WORD;
2436
        if (prefixes & PREFIX_REPZ) {
2437
            gen_op_lods[3 + ot]();
2438
        } else {
2439
            gen_op_lods[ot]();
2440
        }
2441
        break;
2442
    case 0xae: /* scasS */
2443
    case 0xaf:
2444
        if ((b & 1) == 0)
2445
            ot = OT_BYTE;
2446
        else
2447
            ot = dflag ? OT_LONG : OT_WORD;
2448
        if (prefixes & PREFIX_REPNZ) {
2449
            if (s->cc_op != CC_OP_DYNAMIC)
2450
                gen_op_set_cc_op(s->cc_op);
2451
            gen_op_scas[6 + ot]();
2452
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2453
        } else if (prefixes & PREFIX_REPZ) {
2454
            if (s->cc_op != CC_OP_DYNAMIC)
2455
                gen_op_set_cc_op(s->cc_op);
2456
            gen_op_scas[3 + ot]();
2457
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2458
        } else {
2459
            gen_op_scas[ot]();
2460
            s->cc_op = CC_OP_SUBB + ot;
2461
        }
2462
        break;
2463

    
2464
    case 0xa6: /* cmpsS */
2465
    case 0xa7:
2466
        if ((b & 1) == 0)
2467
            ot = OT_BYTE;
2468
        else
2469
            ot = dflag ? OT_LONG : OT_WORD;
2470
        if (prefixes & PREFIX_REPNZ) {
2471
            if (s->cc_op != CC_OP_DYNAMIC)
2472
                gen_op_set_cc_op(s->cc_op);
2473
            gen_op_cmps[6 + ot]();
2474
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2475
        } else if (prefixes & PREFIX_REPZ) {
2476
            if (s->cc_op != CC_OP_DYNAMIC)
2477
                gen_op_set_cc_op(s->cc_op);
2478
            gen_op_cmps[3 + ot]();
2479
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2480
        } else {
2481
            gen_op_cmps[ot]();
2482
            s->cc_op = CC_OP_SUBB + ot;
2483
        }
2484
        break;
2485
        
2486
        /************************/
2487
        /* port I/O */
2488
    case 0x6c: /* insS */
2489
    case 0x6d:
2490
        if ((b & 1) == 0)
2491
            ot = OT_BYTE;
2492
        else
2493
            ot = dflag ? OT_LONG : OT_WORD;
2494
        if (prefixes & PREFIX_REPZ) {
2495
            gen_op_ins[3 + ot]();
2496
        } else {
2497
            gen_op_ins[ot]();
2498
        }
2499
        break;
2500
    case 0x6e: /* outsS */
2501
    case 0x6f:
2502
        if ((b & 1) == 0)
2503
            ot = OT_BYTE;
2504
        else
2505
            ot = dflag ? OT_LONG : OT_WORD;
2506
        if (prefixes & PREFIX_REPZ) {
2507
            gen_op_outs[3 + ot]();
2508
        } else {
2509
            gen_op_outs[ot]();
2510
        }
2511
        break;
2512
    case 0xe4:
2513
    case 0xe5:
2514
        if ((b & 1) == 0)
2515
            ot = OT_BYTE;
2516
        else
2517
            ot = dflag ? OT_LONG : OT_WORD;
2518
        val = ldub(s->pc++);
2519
        gen_op_movl_T0_im(val);
2520
        gen_op_in[ot]();
2521
        gen_op_mov_reg_T1[ot][R_EAX]();
2522
        break;
2523
    case 0xe6:
2524
    case 0xe7:
2525
        if ((b & 1) == 0)
2526
            ot = OT_BYTE;
2527
        else
2528
            ot = dflag ? OT_LONG : OT_WORD;
2529
        val = ldub(s->pc++);
2530
        gen_op_movl_T0_im(val);
2531
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2532
        gen_op_out[ot]();
2533
        break;
2534
    case 0xec:
2535
    case 0xed:
2536
        if ((b & 1) == 0)
2537
            ot = OT_BYTE;
2538
        else
2539
            ot = dflag ? OT_LONG : OT_WORD;
2540
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2541
        gen_op_in[ot]();
2542
        gen_op_mov_reg_T1[ot][R_EAX]();
2543
        break;
2544
    case 0xee:
2545
    case 0xef:
2546
        if ((b & 1) == 0)
2547
            ot = OT_BYTE;
2548
        else
2549
            ot = dflag ? OT_LONG : OT_WORD;
2550
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
2551
        gen_op_mov_TN_reg[ot][1][R_EAX]();
2552
        gen_op_out[ot]();
2553
        break;
2554

    
2555
        /************************/
2556
        /* control */
2557
    case 0xc2: /* ret im */
2558
        /* XXX: handle stack pop ? */
2559
        val = ldsw(s->pc);
2560
        s->pc += 2;
2561
        gen_op_popl_T0();
2562
        gen_op_addl_ESP_im(val);
2563
        gen_op_jmp_T0();
2564
        s->is_jmp = 1;
2565
        break;
2566
    case 0xc3: /* ret */
2567
        gen_op_popl_T0();
2568
        gen_op_jmp_T0();
2569
        s->is_jmp = 1;
2570
        break;
2571
    case 0xe8: /* call */
2572
        val = insn_get(s, OT_LONG);
2573
        val += (long)s->pc;
2574
        gen_op_movl_T1_im((long)s->pc);
2575
        gen_op_pushl_T1();
2576
        gen_op_jmp_im(val);
2577
        s->is_jmp = 1;
2578
        break;
2579
    case 0xe9: /* jmp */
2580
        val = insn_get(s, OT_LONG);
2581
        val += (long)s->pc;
2582
        gen_op_jmp_im(val);
2583
        s->is_jmp = 1;
2584
        break;
2585
    case 0xeb: /* jmp Jb */
2586
        val = (int8_t)insn_get(s, OT_BYTE);
2587
        val += (long)s->pc;
2588
        gen_op_jmp_im(val);
2589
        s->is_jmp = 1;
2590
        break;
2591
    case 0x70 ... 0x7f: /* jcc Jb */
2592
        val = (int8_t)insn_get(s, OT_BYTE);
2593
        val += (long)s->pc;
2594
        goto do_jcc;
2595
    case 0x180 ... 0x18f: /* jcc Jv */
2596
        if (dflag) {
2597
            val = insn_get(s, OT_LONG);
2598
        } else {
2599
            val = (int16_t)insn_get(s, OT_WORD); 
2600
        }
2601
        val += (long)s->pc; /* XXX: fix 16 bit wrap */
2602
    do_jcc:
2603
        gen_jcc(s, b, val);
2604
        s->is_jmp = 1;
2605
        break;
2606

    
2607
    case 0x190 ... 0x19f: /* setcc Gv */
2608
        modrm = ldub(s->pc++);
2609
        gen_setcc(s, b);
2610
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
2611
        break;
2612
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
2613
        ot = dflag ? OT_LONG : OT_WORD;
2614
        modrm = ldub(s->pc++);
2615
        reg = (modrm >> 3) & 7;
2616
        mod = (modrm >> 6) & 3;
2617
        gen_setcc(s, b);
2618
        if (mod != 3) {
2619
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2620
            gen_op_ld_T1_A0[ot]();
2621
        } else {
2622
            rm = modrm & 7;
2623
            gen_op_mov_TN_reg[ot][1][rm]();
2624
        }
2625
        gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
2626
        break;
2627
        
2628
        /************************/
2629
        /* flags */
2630
    case 0x9c: /* pushf */
2631
        if (s->cc_op != CC_OP_DYNAMIC)
2632
            gen_op_set_cc_op(s->cc_op);
2633
        gen_op_movl_T0_eflags();
2634
        gen_op_pushl_T0();
2635
        break;
2636
    case 0x9d: /* popf */
2637
        gen_op_popl_T0();
2638
        gen_op_movl_eflags_T0();
2639
        s->cc_op = CC_OP_EFLAGS;
2640
        break;
2641
    case 0x9e: /* sahf */
2642
        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
2643
        if (s->cc_op != CC_OP_DYNAMIC)
2644
            gen_op_set_cc_op(s->cc_op);
2645
        gen_op_movb_eflags_T0();
2646
        s->cc_op = CC_OP_EFLAGS;
2647
        break;
2648
    case 0x9f: /* lahf */
2649
        if (s->cc_op != CC_OP_DYNAMIC)
2650
            gen_op_set_cc_op(s->cc_op);
2651
        gen_op_movl_T0_eflags();
2652
        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
2653
        break;
2654
    case 0xf5: /* cmc */
2655
        if (s->cc_op != CC_OP_DYNAMIC)
2656
            gen_op_set_cc_op(s->cc_op);
2657
        gen_op_cmc();
2658
        s->cc_op = CC_OP_EFLAGS;
2659
        break;
2660
    case 0xf8: /* clc */
2661
        if (s->cc_op != CC_OP_DYNAMIC)
2662
            gen_op_set_cc_op(s->cc_op);
2663
        gen_op_clc();
2664
        s->cc_op = CC_OP_EFLAGS;
2665
        break;
2666
    case 0xf9: /* stc */
2667
        if (s->cc_op != CC_OP_DYNAMIC)
2668
            gen_op_set_cc_op(s->cc_op);
2669
        gen_op_stc();
2670
        s->cc_op = CC_OP_EFLAGS;
2671
        break;
2672
    case 0xfc: /* cld */
2673
        gen_op_cld();
2674
        break;
2675
    case 0xfd: /* std */
2676
        gen_op_std();
2677
        break;
2678

    
2679
        /************************/
2680
        /* bit operations */
2681
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
2682
        ot = dflag ? OT_LONG : OT_WORD;
2683
        modrm = ldub(s->pc++);
2684
        op = (modrm >> 3) & 7;
2685
        mod = (modrm >> 6) & 3;
2686
        rm = modrm & 7;
2687
        if (mod != 3) {
2688
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2689
            gen_op_ld_T0_A0[ot]();
2690
        } else {
2691
            gen_op_mov_TN_reg[ot][0][rm]();
2692
        }
2693
        /* load shift */
2694
        val = ldub(s->pc++);
2695
        gen_op_movl_T1_im(val);
2696
        if (op < 4)
2697
            goto illegal_op;
2698
        op -= 4;
2699
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2700
        s->cc_op = CC_OP_SARB + ot;
2701
        if (op != 0) {
2702
            if (mod != 3)
2703
                gen_op_st_T0_A0[ot]();
2704
            else
2705
                gen_op_mov_reg_T0[ot][rm]();
2706
        }
2707
        break;
2708
    case 0x1a3: /* bt Gv, Ev */
2709
        op = 0;
2710
        goto do_btx;
2711
    case 0x1ab: /* bts */
2712
        op = 1;
2713
        goto do_btx;
2714
    case 0x1b3: /* btr */
2715
        op = 2;
2716
        goto do_btx;
2717
    case 0x1bb: /* btc */
2718
        op = 3;
2719
    do_btx:
2720
        ot = dflag ? OT_LONG : OT_WORD;
2721
        modrm = ldub(s->pc++);
2722
        reg = (modrm >> 3) & 7;
2723
        mod = (modrm >> 6) & 3;
2724
        rm = modrm & 7;
2725
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
2726
        if (mod != 3) {
2727
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2728
            /* specific case: we need to add a displacement */
2729
            if (ot == OT_WORD)
2730
                gen_op_add_bitw_A0_T1();
2731
            else
2732
                gen_op_add_bitl_A0_T1();
2733
            gen_op_ld_T0_A0[ot]();
2734
        } else {
2735
            gen_op_mov_TN_reg[ot][0][rm]();
2736
        }
2737
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2738
        s->cc_op = CC_OP_SARB + ot;
2739
        if (op != 0) {
2740
            if (mod != 3)
2741
                gen_op_st_T0_A0[ot]();
2742
            else
2743
                gen_op_mov_reg_T0[ot][rm]();
2744
        }
2745
        break;
2746
    case 0x1bc: /* bsf */
2747
    case 0x1bd: /* bsr */
2748
        ot = dflag ? OT_LONG : OT_WORD;
2749
        modrm = ldub(s->pc++);
2750
        reg = (modrm >> 3) & 7;
2751
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2752
        gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
2753
        /* NOTE: we always write back the result. Intel doc says it is
2754
           undefined if T0 == 0 */
2755
        gen_op_mov_reg_T0[ot][reg]();
2756
        s->cc_op = CC_OP_LOGICB + ot;
2757
        break;
2758
        /************************/
2759
        /* bcd */
2760
    case 0x27: /* daa */
2761
        if (s->cc_op != CC_OP_DYNAMIC)
2762
            gen_op_set_cc_op(s->cc_op);
2763
        gen_op_daa();
2764
        s->cc_op = CC_OP_EFLAGS;
2765
        break;
2766
    case 0x2f: /* das */
2767
        if (s->cc_op != CC_OP_DYNAMIC)
2768
            gen_op_set_cc_op(s->cc_op);
2769
        gen_op_das();
2770
        s->cc_op = CC_OP_EFLAGS;
2771
        break;
2772
    case 0x37: /* aaa */
2773
        if (s->cc_op != CC_OP_DYNAMIC)
2774
            gen_op_set_cc_op(s->cc_op);
2775
        gen_op_aaa();
2776
        s->cc_op = CC_OP_EFLAGS;
2777
        break;
2778
    case 0x3f: /* aas */
2779
        if (s->cc_op != CC_OP_DYNAMIC)
2780
            gen_op_set_cc_op(s->cc_op);
2781
        gen_op_aas();
2782
        s->cc_op = CC_OP_EFLAGS;
2783
        break;
2784
    case 0xd4: /* aam */
2785
        val = ldub(s->pc++);
2786
        gen_op_aam(val);
2787
        s->cc_op = CC_OP_LOGICB;
2788
        break;
2789
    case 0xd5: /* aad */
2790
        val = ldub(s->pc++);
2791
        gen_op_aad(val);
2792
        s->cc_op = CC_OP_LOGICB;
2793
        break;
2794
        /************************/
2795
        /* misc */
2796
    case 0x90: /* nop */
2797
        break;
2798
    case 0xcc: /* int3 */
2799
        gen_op_int3((long)pc_start);
2800
        s->is_jmp = 1;
2801
        break;
2802
    case 0xcd: /* int N */
2803
        val = ldub(s->pc++);
2804
        /* XXX: currently we ignore the interrupt number */
2805
        gen_op_int_im((long)pc_start);
2806
        s->is_jmp = 1;
2807
        break;
2808
    case 0xce: /* into */
2809
        if (s->cc_op != CC_OP_DYNAMIC)
2810
            gen_op_set_cc_op(s->cc_op);
2811
        gen_op_into((long)pc_start, (long)s->pc);
2812
        s->is_jmp = 1;
2813
        break;
2814
    case 0x1c8 ... 0x1cf: /* bswap reg */
2815
        reg = b & 7;
2816
        gen_op_mov_TN_reg[OT_LONG][0][reg]();
2817
        gen_op_bswapl_T0();
2818
        gen_op_mov_reg_T0[OT_LONG][reg]();
2819
        break;
2820
    case 0xd6: /* salc */
2821
        if (s->cc_op != CC_OP_DYNAMIC)
2822
            gen_op_set_cc_op(s->cc_op);
2823
        gen_op_salc();
2824
        break;
2825
    case 0xe0: /* loopnz */
2826
    case 0xe1: /* loopz */
2827
        if (s->cc_op != CC_OP_DYNAMIC)
2828
            gen_op_set_cc_op(s->cc_op);
2829
        /* FALL THRU */
2830
    case 0xe2: /* loop */
2831
    case 0xe3: /* jecxz */
2832
        val = (int8_t)insn_get(s, OT_BYTE);
2833
        val += (long)s->pc;
2834
        gen_op_loop[s->aflag][b & 3](val, (long)s->pc);
2835
        s->is_jmp = 1;
2836
        break;
2837
    case 0x131: /* rdtsc */
2838
        gen_op_rdtsc();
2839
        break;
2840
#if 0
2841
    case 0x1a2: /* cpuid */
2842
        gen_insn0(OP_ASM);
2843
        break;
2844
#endif
2845
    default:
2846
        goto illegal_op;
2847
    }
2848
    return (long)s->pc;
2849
 illegal_op:
2850
    return -1;
2851
}
2852

    
2853
#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
2854
#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
2855

    
2856
/* flags read by an operation */
2857
static uint16_t opc_read_flags[NB_OPS] = { 
2858
    [INDEX_op_aas] = CC_A,
2859
    [INDEX_op_aaa] = CC_A,
2860
    [INDEX_op_das] = CC_A | CC_C,
2861
    [INDEX_op_daa] = CC_A | CC_C,
2862

    
2863
    [INDEX_op_adcb_T0_T1_cc] = CC_C,
2864
    [INDEX_op_adcw_T0_T1_cc] = CC_C,
2865
    [INDEX_op_adcl_T0_T1_cc] = CC_C,
2866
    [INDEX_op_sbbb_T0_T1_cc] = CC_C,
2867
    [INDEX_op_sbbw_T0_T1_cc] = CC_C,
2868
    [INDEX_op_sbbl_T0_T1_cc] = CC_C,
2869

    
2870
    [INDEX_op_into] = CC_O,
2871

    
2872
    [INDEX_op_jo_cc] = CC_O,
2873
    [INDEX_op_jb_cc] = CC_C,
2874
    [INDEX_op_jz_cc] = CC_Z,
2875
    [INDEX_op_jbe_cc] = CC_Z | CC_C,
2876
    [INDEX_op_js_cc] = CC_S,
2877
    [INDEX_op_jp_cc] = CC_P,
2878
    [INDEX_op_jl_cc] = CC_O | CC_S,
2879
    [INDEX_op_jle_cc] = CC_O | CC_S | CC_Z,
2880

    
2881
    [INDEX_op_jb_subb] = CC_C,
2882
    [INDEX_op_jb_subw] = CC_C,
2883
    [INDEX_op_jb_subl] = CC_C,
2884

    
2885
    [INDEX_op_jz_subb] = CC_Z,
2886
    [INDEX_op_jz_subw] = CC_Z,
2887
    [INDEX_op_jz_subl] = CC_Z,
2888

    
2889
    [INDEX_op_jbe_subb] = CC_Z | CC_C,
2890
    [INDEX_op_jbe_subw] = CC_Z | CC_C,
2891
    [INDEX_op_jbe_subl] = CC_Z | CC_C,
2892

    
2893
    [INDEX_op_js_subb] = CC_S,
2894
    [INDEX_op_js_subw] = CC_S,
2895
    [INDEX_op_js_subl] = CC_S,
2896

    
2897
    [INDEX_op_jl_subb] = CC_O | CC_S,
2898
    [INDEX_op_jl_subw] = CC_O | CC_S,
2899
    [INDEX_op_jl_subl] = CC_O | CC_S,
2900

    
2901
    [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
2902
    [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
2903
    [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
2904

    
2905
    [INDEX_op_loopnzw] = CC_Z,
2906
    [INDEX_op_loopnzl] = CC_Z,
2907
    [INDEX_op_loopzw] = CC_Z,
2908
    [INDEX_op_loopzl] = CC_Z,
2909

    
2910
    [INDEX_op_seto_T0_cc] = CC_O,
2911
    [INDEX_op_setb_T0_cc] = CC_C,
2912
    [INDEX_op_setz_T0_cc] = CC_Z,
2913
    [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
2914
    [INDEX_op_sets_T0_cc] = CC_S,
2915
    [INDEX_op_setp_T0_cc] = CC_P,
2916
    [INDEX_op_setl_T0_cc] = CC_O | CC_S,
2917
    [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
2918

    
2919
    [INDEX_op_setb_T0_subb] = CC_C,
2920
    [INDEX_op_setb_T0_subw] = CC_C,
2921
    [INDEX_op_setb_T0_subl] = CC_C,
2922

    
2923
    [INDEX_op_setz_T0_subb] = CC_Z,
2924
    [INDEX_op_setz_T0_subw] = CC_Z,
2925
    [INDEX_op_setz_T0_subl] = CC_Z,
2926

    
2927
    [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
2928
    [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
2929
    [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
2930

    
2931
    [INDEX_op_sets_T0_subb] = CC_S,
2932
    [INDEX_op_sets_T0_subw] = CC_S,
2933
    [INDEX_op_sets_T0_subl] = CC_S,
2934

    
2935
    [INDEX_op_setl_T0_subb] = CC_O | CC_S,
2936
    [INDEX_op_setl_T0_subw] = CC_O | CC_S,
2937
    [INDEX_op_setl_T0_subl] = CC_O | CC_S,
2938

    
2939
    [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
2940
    [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
2941
    [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
2942

    
2943
    [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
2944
    [INDEX_op_cmc] = CC_C,
2945
    [INDEX_op_salc] = CC_C,
2946

    
2947
    [INDEX_op_rclb_T0_T1_cc] = CC_C,
2948
    [INDEX_op_rclw_T0_T1_cc] = CC_C,
2949
    [INDEX_op_rcll_T0_T1_cc] = CC_C,
2950
    [INDEX_op_rcrb_T0_T1_cc] = CC_C,
2951
    [INDEX_op_rcrw_T0_T1_cc] = CC_C,
2952
    [INDEX_op_rcrl_T0_T1_cc] = CC_C,
2953
};
2954

    
2955
/* flags written by an operation */
2956
static uint16_t opc_write_flags[NB_OPS] = { 
2957
    [INDEX_op_addl_T0_T1_cc] = CC_OSZAPC,
2958
    [INDEX_op_orl_T0_T1_cc] = CC_OSZAPC,
2959
    [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
2960
    [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
2961
    [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
2962
    [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
2963
    [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
2964
    [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
2965
    [INDEX_op_andl_T0_T1_cc] = CC_OSZAPC,
2966
    [INDEX_op_subl_T0_T1_cc] = CC_OSZAPC,
2967
    [INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,
2968
    [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
2969
    [INDEX_op_negl_T0_cc] = CC_OSZAPC,
2970
    [INDEX_op_incl_T0_cc] = CC_OSZAP,
2971
    [INDEX_op_decl_T0_cc] = CC_OSZAP,
2972
    [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
2973

    
2974
    [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
2975
    [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
2976
    [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
2977
    [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
2978
    [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
2979
    [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
2980
    [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
2981
    [INDEX_op_imull_T0_T1] = CC_OSZAPC,
2982
    
2983
    /* bcd */
2984
    [INDEX_op_aam] = CC_OSZAPC,
2985
    [INDEX_op_aad] = CC_OSZAPC,
2986
    [INDEX_op_aas] = CC_OSZAPC,
2987
    [INDEX_op_aaa] = CC_OSZAPC,
2988
    [INDEX_op_das] = CC_OSZAPC,
2989
    [INDEX_op_daa] = CC_OSZAPC,
2990

    
2991
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
2992
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
2993
    [INDEX_op_clc] = CC_C,
2994
    [INDEX_op_stc] = CC_C,
2995
    [INDEX_op_cmc] = CC_C,
2996

    
2997
    [INDEX_op_rolb_T0_T1_cc] = CC_O | CC_C,
2998
    [INDEX_op_rolw_T0_T1_cc] = CC_O | CC_C,
2999
    [INDEX_op_roll_T0_T1_cc] = CC_O | CC_C,
3000
    [INDEX_op_rorb_T0_T1_cc] = CC_O | CC_C,
3001
    [INDEX_op_rorw_T0_T1_cc] = CC_O | CC_C,
3002
    [INDEX_op_rorl_T0_T1_cc] = CC_O | CC_C,
3003

    
3004
    [INDEX_op_rclb_T0_T1_cc] = CC_O | CC_C,
3005
    [INDEX_op_rclw_T0_T1_cc] = CC_O | CC_C,
3006
    [INDEX_op_rcll_T0_T1_cc] = CC_O | CC_C,
3007
    [INDEX_op_rcrb_T0_T1_cc] = CC_O | CC_C,
3008
    [INDEX_op_rcrw_T0_T1_cc] = CC_O | CC_C,
3009
    [INDEX_op_rcrl_T0_T1_cc] = CC_O | CC_C,
3010

    
3011
    [INDEX_op_shlb_T0_T1_cc] = CC_OSZAPC,
3012
    [INDEX_op_shlw_T0_T1_cc] = CC_OSZAPC,
3013
    [INDEX_op_shll_T0_T1_cc] = CC_OSZAPC,
3014

    
3015
    [INDEX_op_shrb_T0_T1_cc] = CC_OSZAPC,
3016
    [INDEX_op_shrw_T0_T1_cc] = CC_OSZAPC,
3017
    [INDEX_op_shrl_T0_T1_cc] = CC_OSZAPC,
3018

    
3019
    [INDEX_op_sarb_T0_T1_cc] = CC_OSZAPC,
3020
    [INDEX_op_sarw_T0_T1_cc] = CC_OSZAPC,
3021
    [INDEX_op_sarl_T0_T1_cc] = CC_OSZAPC,
3022

    
3023
    [INDEX_op_shldw_T0_T1_ECX_cc] = CC_OSZAPC,
3024
    [INDEX_op_shldl_T0_T1_ECX_cc] = CC_OSZAPC,
3025
    [INDEX_op_shldw_T0_T1_im_cc] = CC_OSZAPC,
3026
    [INDEX_op_shldl_T0_T1_im_cc] = CC_OSZAPC,
3027

    
3028
    [INDEX_op_shrdw_T0_T1_ECX_cc] = CC_OSZAPC,
3029
    [INDEX_op_shrdl_T0_T1_ECX_cc] = CC_OSZAPC,
3030
    [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
3031
    [INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC,
3032

    
3033
    [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
3034
    [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
3035
    [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
3036
    [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
3037
    [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
3038
    [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
3039
    [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
3040
    [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
3041

    
3042
    [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
3043
    [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
3044
    [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
3045
    [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
3046

    
3047
    [INDEX_op_scasb] = CC_OSZAPC,
3048
    [INDEX_op_scasw] = CC_OSZAPC,
3049
    [INDEX_op_scasl] = CC_OSZAPC,
3050
    [INDEX_op_repz_scasb] = CC_OSZAPC,
3051
    [INDEX_op_repz_scasw] = CC_OSZAPC,
3052
    [INDEX_op_repz_scasl] = CC_OSZAPC,
3053
    [INDEX_op_repnz_scasb] = CC_OSZAPC,
3054
    [INDEX_op_repnz_scasw] = CC_OSZAPC,
3055
    [INDEX_op_repnz_scasl] = CC_OSZAPC,
3056

    
3057
    [INDEX_op_cmpsb] = CC_OSZAPC,
3058
    [INDEX_op_cmpsw] = CC_OSZAPC,
3059
    [INDEX_op_cmpsl] = CC_OSZAPC,
3060
    [INDEX_op_repz_cmpsb] = CC_OSZAPC,
3061
    [INDEX_op_repz_cmpsw] = CC_OSZAPC,
3062
    [INDEX_op_repz_cmpsl] = CC_OSZAPC,
3063
    [INDEX_op_repnz_cmpsb] = CC_OSZAPC,
3064
    [INDEX_op_repnz_cmpsw] = CC_OSZAPC,
3065
    [INDEX_op_repnz_cmpsl] = CC_OSZAPC,
3066

    
3067
    [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
3068
    [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
3069
};
3070

    
3071
/* simpler form of an operation if no flags need to be generated */
3072
static uint16_t opc_simpler[NB_OPS] = { 
3073
    [INDEX_op_addl_T0_T1_cc] = INDEX_op_addl_T0_T1,
3074
    [INDEX_op_orl_T0_T1_cc] = INDEX_op_orl_T0_T1,
3075
    [INDEX_op_andl_T0_T1_cc] = INDEX_op_andl_T0_T1,
3076
    [INDEX_op_subl_T0_T1_cc] = INDEX_op_subl_T0_T1,
3077
    [INDEX_op_xorl_T0_T1_cc] = INDEX_op_xorl_T0_T1,
3078
    [INDEX_op_negl_T0_cc] = INDEX_op_negl_T0,
3079
    [INDEX_op_incl_T0_cc] = INDEX_op_incl_T0,
3080
    [INDEX_op_decl_T0_cc] = INDEX_op_decl_T0,
3081

    
3082
    [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
3083
    [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
3084
    [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
3085

    
3086
    [INDEX_op_rorb_T0_T1_cc] = INDEX_op_rorb_T0_T1,
3087
    [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
3088
    [INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1,
3089

    
3090
    [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
3091
    [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
3092
    [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
3093

    
3094
    [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
3095
    [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
3096
    [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
3097

    
3098
    [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
3099
    [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
3100
    [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
3101
};
3102

    
3103
static void optimize_flags_init(void)
3104
{
3105
    int i;
3106
    /* put default values in arrays */
3107
    for(i = 0; i < NB_OPS; i++) {
3108
        if (opc_simpler[i] == 0)
3109
            opc_simpler[i] = i;
3110
    }
3111
}
3112

    
3113
/* CPU flags computation optimization: we move backward thru the
3114
   generated code to see which flags are needed. The operation is
3115
   modified if suitable */
3116
static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
3117
{
3118
    uint16_t *opc_ptr;
3119
    int live_flags, write_flags, op;
3120

    
3121
    opc_ptr = opc_buf + opc_buf_len;
3122
    /* live_flags contains the flags needed by the next instructions
3123
       in the code. At the end of the bloc, we consider that all the
3124
       flags are live. */
3125
    live_flags = CC_OSZAPC;
3126
    while (opc_ptr > opc_buf) {
3127
        op = *--opc_ptr;
3128
        /* if none of the flags written by the instruction is used,
3129
           then we can try to find a simpler instruction */
3130
        write_flags = opc_write_flags[op];
3131
        if ((live_flags & write_flags) == 0) {
3132
            *opc_ptr = opc_simpler[op];
3133
        }
3134
        /* compute the live flags before the instruction */
3135
        live_flags &= ~write_flags;
3136
        live_flags |= opc_read_flags[op];
3137
    }
3138
}
3139

    
3140

    
3141
#ifdef DEBUG_DISAS
3142
static const char *op_str[] = {
3143
#define DEF(s) #s,
3144
#include "opc-i386.h"
3145
#undef DEF
3146
};
3147

    
3148
static void dump_ops(const uint16_t *opc_buf)
3149
{
3150
    const uint16_t *opc_ptr;
3151
    int c;
3152
    opc_ptr = opc_buf;
3153
    for(;;) {
3154
        c = *opc_ptr++;
3155
        fprintf(logfile, "0x%04x: %s\n", opc_ptr - opc_buf - 1, op_str[c]);
3156
        if (c == INDEX_op_end)
3157
            break;
3158
    }
3159
}
3160

    
3161
#endif
3162

    
3163
/* XXX: make this buffer thread safe */
3164
/* XXX: make safe guess about sizes */
3165
#define MAX_OP_PER_INSTR 32
3166
#define OPC_BUF_SIZE 512
3167
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
3168

    
3169
#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
3170

    
3171
static uint16_t gen_opc_buf[OPC_BUF_SIZE];
3172
static uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
3173

    
3174
/* return the next pc */
3175
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 
3176
                     int *gen_code_size_ptr, uint8_t *pc_start, 
3177
                     int flags)
3178
{
3179
    DisasContext dc1, *dc = &dc1;
3180
    uint8_t *pc_ptr;
3181
    uint16_t *gen_opc_end;
3182
    long ret;
3183
#ifdef DEBUG_DISAS
3184
    struct disassemble_info disasm_info;
3185
#endif
3186
    
3187
    /* generate intermediate code */
3188

    
3189
    dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;
3190
    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
3191
    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
3192
    dc->cc_op = CC_OP_DYNAMIC;
3193

    
3194
    gen_opc_ptr = gen_opc_buf;
3195
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3196
    gen_opparam_ptr = gen_opparam_buf;
3197

    
3198
    dc->is_jmp = 0;
3199
    pc_ptr = pc_start;
3200
    do {
3201
        ret = disas_insn(dc, pc_ptr);
3202
        if (ret == -1) {
3203
            fprintf(stderr, "unknown instruction at PC=0x%08lx B=%02x %02x %02x", 
3204
                    (long)pc_ptr, pc_ptr[0], pc_ptr[1], pc_ptr[2]);
3205
            abort();
3206
        }
3207
        pc_ptr = (void *)ret;
3208
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);
3209
    /* we must store the eflags state if it is not already done */
3210
    if (dc->cc_op != CC_OP_DYNAMIC)
3211
        gen_op_set_cc_op(dc->cc_op);
3212
    if (dc->is_jmp != 1) {
3213
        /* we add an additionnal jmp to update the simulated PC */
3214
        gen_op_jmp_im(ret);
3215
    }
3216
    *gen_opc_ptr = INDEX_op_end;
3217

    
3218
    /* optimize flag computations */
3219
#ifdef DEBUG_DISAS
3220
    if (loglevel) {
3221
        uint8_t *pc;
3222
        int count;
3223

    
3224
        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
3225
#if 0        
3226
        disasm_info.flavour = bfd_get_flavour (abfd);
3227
        disasm_info.arch = bfd_get_arch (abfd);
3228
        disasm_info.mach = bfd_get_mach (abfd);
3229
#endif
3230
#ifdef WORDS_BIGENDIAN
3231
        disasm_info.endian = BFD_ENDIAN_BIG;
3232
#else
3233
        disasm_info.endian = BFD_ENDIAN_LITTLE;
3234
#endif        
3235
        fprintf(logfile, "----------------\n");
3236
        fprintf(logfile, "IN:\n");
3237
        disasm_info.buffer = pc_start;
3238
        disasm_info.buffer_vma = (unsigned long)pc_start;
3239
        disasm_info.buffer_length = pc_ptr - pc_start;
3240
        pc = pc_start;
3241
        while (pc < pc_ptr) {
3242
            fprintf(logfile, "0x%08lx:  ", (long)pc);
3243
            count = print_insn_i386((unsigned long)pc, &disasm_info);
3244
            fprintf(logfile, "\n");
3245
            pc += count;
3246
        }
3247
        fprintf(logfile, "\n");
3248
        
3249
        fprintf(logfile, "OP:\n");
3250
        dump_ops(gen_opc_buf);
3251
        fprintf(logfile, "\n");
3252
    }
3253
#endif
3254

    
3255
    /* optimize flag computations */
3256
    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
3257

    
3258
#ifdef DEBUG_DISAS
3259
    if (loglevel) {
3260
        fprintf(logfile, "AFTER FLAGS OPT:\n");
3261
        dump_ops(gen_opc_buf);
3262
        fprintf(logfile, "\n");
3263
    }
3264
#endif
3265

    
3266
    /* generate machine code */
3267
    *gen_code_size_ptr = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf);
3268

    
3269
#ifdef DEBUG_DISAS
3270
    if (loglevel) {
3271
        uint8_t *pc;
3272
        int count;
3273

    
3274
        pc = gen_code_buf;
3275
        disasm_info.buffer = pc;
3276
        disasm_info.buffer_vma = (unsigned long)pc;
3277
        disasm_info.buffer_length = *gen_code_size_ptr;
3278
        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
3279
        while (pc < gen_code_buf + *gen_code_size_ptr) {
3280
            fprintf(logfile, "0x%08lx:  ", (long)pc);
3281
            count = print_insn_i386((unsigned long)pc, &disasm_info);
3282
            fprintf(logfile, "\n");
3283
            pc += count;
3284
        }
3285
        fprintf(logfile, "\n");
3286
    }
3287
#endif
3288
    return 0;
3289
}
3290

    
3291
CPUX86State *cpu_x86_init(void)
3292
{
3293
    CPUX86State *env;
3294
    int i;
3295
    static int inited;
3296

    
3297
    cpu_x86_tblocks_init();
3298

    
3299
    env = malloc(sizeof(CPUX86State));
3300
    if (!env)
3301
        return NULL;
3302
    memset(env, 0, sizeof(CPUX86State));
3303
    /* basic FPU init */
3304
    for(i = 0;i < 8; i++)
3305
        env->fptags[i] = 1;
3306
    env->fpuc = 0x37f;
3307
    /* flags setup */
3308
    env->cc_op = CC_OP_EFLAGS;
3309
    env->df = 1;
3310

    
3311
    /* init various static tables */
3312
    if (!inited) {
3313
        inited = 1;
3314
        optimize_flags_init();
3315
    }
3316
    return env;
3317
}
3318

    
3319
void cpu_x86_close(CPUX86State *env)
3320
{
3321
    free(env);
3322
}