Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 1d6e34fd

History | View | Annotate | Download (187.1 kB)

1
/*
2
 *  i386 translation
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library 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 GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <signal.h>
26
#include <assert.h>
27

    
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31

    
32
/* XXX: move that elsewhere */
33
static uint16_t *gen_opc_ptr;
34
static uint32_t *gen_opparam_ptr;
35

    
36
#define PREFIX_REPZ   0x01
37
#define PREFIX_REPNZ  0x02
38
#define PREFIX_LOCK   0x04
39
#define PREFIX_DATA   0x08
40
#define PREFIX_ADR    0x10
41

    
42
#ifdef TARGET_X86_64
43
#define X86_64_ONLY(x) x
44
#define X86_64_DEF(x...) x
45
#define CODE64(s) ((s)->code64)
46
#define REX_X(s) ((s)->rex_x)
47
#define REX_B(s) ((s)->rex_b)
48
/* XXX: gcc generates push/pop in some opcodes, so we cannot use them */
49
#if 1
50
#define BUGGY_64(x) NULL
51
#endif
52
#else
53
#define X86_64_ONLY(x) NULL
54
#define X86_64_DEF(x...)
55
#define CODE64(s) 0
56
#define REX_X(s) 0
57
#define REX_B(s) 0
58
#endif
59

    
60
#ifdef TARGET_X86_64
61
static int x86_64_hregs;
62
#endif
63

    
64
#ifdef USE_DIRECT_JUMP
65
#define TBPARAM(x)
66
#else
67
#define TBPARAM(x) (long)(x)
68
#endif
69

    
70
typedef struct DisasContext {
71
    /* current insn context */
72
    int override; /* -1 if no override */
73
    int prefix;
74
    int aflag, dflag;
75
    target_ulong pc; /* pc = eip + cs_base */
76
    int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
77
                   static state change (stop translation) */
78
    /* current block context */
79
    target_ulong cs_base; /* base of CS segment */
80
    int pe;     /* protected mode */
81
    int code32; /* 32 bit code segment */
82
#ifdef TARGET_X86_64
83
    int lma;    /* long mode active */
84
    int code64; /* 64 bit code segment */
85
    int rex_x, rex_b;
86
#endif
87
    int ss32;   /* 32 bit stack segment */
88
    int cc_op;  /* current CC operation */
89
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
90
    int f_st;   /* currently unused */
91
    int vm86;   /* vm86 mode */
92
    int cpl;
93
    int iopl;
94
    int tf;     /* TF cpu flag */
95
    int singlestep_enabled; /* "hardware" single step enabled */
96
    int jmp_opt; /* use direct block chaining for direct jumps */
97
    int mem_index; /* select memory access functions */
98
    int flags; /* all execution flags */
99
    struct TranslationBlock *tb;
100
    int popl_esp_hack; /* for correct popl with esp base handling */
101
    int rip_offset; /* only used in x86_64, but left for simplicity */
102
    int cpuid_features;
103
} DisasContext;
104

    
105
static void gen_eob(DisasContext *s);
106
static void gen_jmp(DisasContext *s, target_ulong eip);
107
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
108

    
109
/* i386 arith/logic operations */
110
enum {
111
    OP_ADDL, 
112
    OP_ORL, 
113
    OP_ADCL, 
114
    OP_SBBL,
115
    OP_ANDL, 
116
    OP_SUBL, 
117
    OP_XORL, 
118
    OP_CMPL,
119
};
120

    
121
/* i386 shift ops */
122
enum {
123
    OP_ROL, 
124
    OP_ROR, 
125
    OP_RCL, 
126
    OP_RCR, 
127
    OP_SHL, 
128
    OP_SHR, 
129
    OP_SHL1, /* undocumented */
130
    OP_SAR = 7,
131
};
132

    
133
enum {
134
#define DEF(s, n, copy_size) INDEX_op_ ## s,
135
#include "opc.h"
136
#undef DEF
137
    NB_OPS,
138
};
139

    
140
#include "gen-op.h"
141

    
142
/* operand size */
143
enum {
144
    OT_BYTE = 0,
145
    OT_WORD,
146
    OT_LONG, 
147
    OT_QUAD,
148
};
149

    
150
enum {
151
    /* I386 int registers */
152
    OR_EAX,   /* MUST be even numbered */
153
    OR_ECX,
154
    OR_EDX,
155
    OR_EBX,
156
    OR_ESP,
157
    OR_EBP,
158
    OR_ESI,
159
    OR_EDI,
160

    
161
    OR_TMP0 = 16,    /* temporary operand register */
162
    OR_TMP1,
163
    OR_A0, /* temporary register used when doing address evaluation */
164
};
165

    
166
#ifdef TARGET_X86_64
167

    
168
#define NB_OP_SIZES 4
169

    
170
#define DEF_REGS(prefix, suffix) \
171
  prefix ## EAX ## suffix,\
172
  prefix ## ECX ## suffix,\
173
  prefix ## EDX ## suffix,\
174
  prefix ## EBX ## suffix,\
175
  prefix ## ESP ## suffix,\
176
  prefix ## EBP ## suffix,\
177
  prefix ## ESI ## suffix,\
178
  prefix ## EDI ## suffix,\
179
  prefix ## R8 ## suffix,\
180
  prefix ## R9 ## suffix,\
181
  prefix ## R10 ## suffix,\
182
  prefix ## R11 ## suffix,\
183
  prefix ## R12 ## suffix,\
184
  prefix ## R13 ## suffix,\
185
  prefix ## R14 ## suffix,\
186
  prefix ## R15 ## suffix,
187

    
188
#define DEF_BREGS(prefixb, prefixh, suffix)             \
189
                                                        \
190
static void prefixb ## ESP ## suffix ## _wrapper(void)  \
191
{                                                       \
192
    if (x86_64_hregs)                                 \
193
        prefixb ## ESP ## suffix ();                    \
194
    else                                                \
195
        prefixh ## EAX ## suffix ();                    \
196
}                                                       \
197
                                                        \
198
static void prefixb ## EBP ## suffix ## _wrapper(void)  \
199
{                                                       \
200
    if (x86_64_hregs)                                 \
201
        prefixb ## EBP ## suffix ();                    \
202
    else                                                \
203
        prefixh ## ECX ## suffix ();                    \
204
}                                                       \
205
                                                        \
206
static void prefixb ## ESI ## suffix ## _wrapper(void)  \
207
{                                                       \
208
    if (x86_64_hregs)                                 \
209
        prefixb ## ESI ## suffix ();                    \
210
    else                                                \
211
        prefixh ## EDX ## suffix ();                    \
212
}                                                       \
213
                                                        \
214
static void prefixb ## EDI ## suffix ## _wrapper(void)  \
215
{                                                       \
216
    if (x86_64_hregs)                                 \
217
        prefixb ## EDI ## suffix ();                    \
218
    else                                                \
219
        prefixh ## EBX ## suffix ();                    \
220
}
221

    
222
DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)
223
DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)
224
DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )
225
DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
226

    
227
#else /* !TARGET_X86_64 */
228

    
229
#define NB_OP_SIZES 3
230

    
231
#define DEF_REGS(prefix, suffix) \
232
  prefix ## EAX ## suffix,\
233
  prefix ## ECX ## suffix,\
234
  prefix ## EDX ## suffix,\
235
  prefix ## EBX ## suffix,\
236
  prefix ## ESP ## suffix,\
237
  prefix ## EBP ## suffix,\
238
  prefix ## ESI ## suffix,\
239
  prefix ## EDI ## suffix,
240

    
241
#endif /* !TARGET_X86_64 */
242

    
243
static GenOpFunc *gen_op_mov_reg_T0[NB_OP_SIZES][CPU_NB_REGS] = {
244
    [OT_BYTE] = {
245
        gen_op_movb_EAX_T0,
246
        gen_op_movb_ECX_T0,
247
        gen_op_movb_EDX_T0,
248
        gen_op_movb_EBX_T0,
249
#ifdef TARGET_X86_64
250
        gen_op_movb_ESP_T0_wrapper,
251
        gen_op_movb_EBP_T0_wrapper,
252
        gen_op_movb_ESI_T0_wrapper,
253
        gen_op_movb_EDI_T0_wrapper,
254
        gen_op_movb_R8_T0,
255
        gen_op_movb_R9_T0,
256
        gen_op_movb_R10_T0,
257
        gen_op_movb_R11_T0,
258
        gen_op_movb_R12_T0,
259
        gen_op_movb_R13_T0,
260
        gen_op_movb_R14_T0,
261
        gen_op_movb_R15_T0,
262
#else
263
        gen_op_movh_EAX_T0,
264
        gen_op_movh_ECX_T0,
265
        gen_op_movh_EDX_T0,
266
        gen_op_movh_EBX_T0,
267
#endif
268
    },
269
    [OT_WORD] = {
270
        DEF_REGS(gen_op_movw_, _T0)
271
    },
272
    [OT_LONG] = {
273
        DEF_REGS(gen_op_movl_, _T0)
274
    },
275
#ifdef TARGET_X86_64
276
    [OT_QUAD] = {
277
        DEF_REGS(gen_op_movq_, _T0)
278
    },
279
#endif
280
};
281

    
282
static GenOpFunc *gen_op_mov_reg_T1[NB_OP_SIZES][CPU_NB_REGS] = {
283
    [OT_BYTE] = {
284
        gen_op_movb_EAX_T1,
285
        gen_op_movb_ECX_T1,
286
        gen_op_movb_EDX_T1,
287
        gen_op_movb_EBX_T1,
288
#ifdef TARGET_X86_64
289
        gen_op_movb_ESP_T1_wrapper,
290
        gen_op_movb_EBP_T1_wrapper,
291
        gen_op_movb_ESI_T1_wrapper,
292
        gen_op_movb_EDI_T1_wrapper,
293
        gen_op_movb_R8_T1,
294
        gen_op_movb_R9_T1,
295
        gen_op_movb_R10_T1,
296
        gen_op_movb_R11_T1,
297
        gen_op_movb_R12_T1,
298
        gen_op_movb_R13_T1,
299
        gen_op_movb_R14_T1,
300
        gen_op_movb_R15_T1,
301
#else
302
        gen_op_movh_EAX_T1,
303
        gen_op_movh_ECX_T1,
304
        gen_op_movh_EDX_T1,
305
        gen_op_movh_EBX_T1,
306
#endif
307
    },
308
    [OT_WORD] = {
309
        DEF_REGS(gen_op_movw_, _T1)
310
    },
311
    [OT_LONG] = {
312
        DEF_REGS(gen_op_movl_, _T1)
313
    },
314
#ifdef TARGET_X86_64
315
    [OT_QUAD] = {
316
        DEF_REGS(gen_op_movq_, _T1)
317
    },
318
#endif
319
};
320

    
321
static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
322
    [0] = {
323
        DEF_REGS(gen_op_movw_, _A0)
324
    },
325
    [1] = {
326
        DEF_REGS(gen_op_movl_, _A0)
327
    },
328
#ifdef TARGET_X86_64
329
    [2] = {
330
        DEF_REGS(gen_op_movq_, _A0)
331
    },
332
#endif
333
};
334

    
335
static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] = 
336
{
337
    [OT_BYTE] = {
338
        {
339
            gen_op_movl_T0_EAX,
340
            gen_op_movl_T0_ECX,
341
            gen_op_movl_T0_EDX,
342
            gen_op_movl_T0_EBX,
343
#ifdef TARGET_X86_64
344
            gen_op_movl_T0_ESP_wrapper,
345
            gen_op_movl_T0_EBP_wrapper,
346
            gen_op_movl_T0_ESI_wrapper,
347
            gen_op_movl_T0_EDI_wrapper,
348
            gen_op_movl_T0_R8,
349
            gen_op_movl_T0_R9,
350
            gen_op_movl_T0_R10,
351
            gen_op_movl_T0_R11,
352
            gen_op_movl_T0_R12,
353
            gen_op_movl_T0_R13,
354
            gen_op_movl_T0_R14,
355
            gen_op_movl_T0_R15,
356
#else
357
            gen_op_movh_T0_EAX,
358
            gen_op_movh_T0_ECX,
359
            gen_op_movh_T0_EDX,
360
            gen_op_movh_T0_EBX,
361
#endif
362
        },
363
        {
364
            gen_op_movl_T1_EAX,
365
            gen_op_movl_T1_ECX,
366
            gen_op_movl_T1_EDX,
367
            gen_op_movl_T1_EBX,
368
#ifdef TARGET_X86_64
369
            gen_op_movl_T1_ESP_wrapper,
370
            gen_op_movl_T1_EBP_wrapper,
371
            gen_op_movl_T1_ESI_wrapper,
372
            gen_op_movl_T1_EDI_wrapper,
373
            gen_op_movl_T1_R8,
374
            gen_op_movl_T1_R9,
375
            gen_op_movl_T1_R10,
376
            gen_op_movl_T1_R11,
377
            gen_op_movl_T1_R12,
378
            gen_op_movl_T1_R13,
379
            gen_op_movl_T1_R14,
380
            gen_op_movl_T1_R15,
381
#else
382
            gen_op_movh_T1_EAX,
383
            gen_op_movh_T1_ECX,
384
            gen_op_movh_T1_EDX,
385
            gen_op_movh_T1_EBX,
386
#endif
387
        },
388
    },
389
    [OT_WORD] = {
390
        {
391
            DEF_REGS(gen_op_movl_T0_, )
392
        },
393
        {
394
            DEF_REGS(gen_op_movl_T1_, )
395
        },
396
    },
397
    [OT_LONG] = {
398
        {
399
            DEF_REGS(gen_op_movl_T0_, )
400
        },
401
        {
402
            DEF_REGS(gen_op_movl_T1_, )
403
        },
404
    },
405
#ifdef TARGET_X86_64
406
    [OT_QUAD] = {
407
        {
408
            DEF_REGS(gen_op_movl_T0_, )
409
        },
410
        {
411
            DEF_REGS(gen_op_movl_T1_, )
412
        },
413
    },
414
#endif
415
};
416

    
417
static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = {
418
    DEF_REGS(gen_op_movl_A0_, )
419
};
420

    
421
static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = {
422
    [0] = {
423
        DEF_REGS(gen_op_addl_A0_, )
424
    },
425
    [1] = {
426
        DEF_REGS(gen_op_addl_A0_, _s1)
427
    },
428
    [2] = {
429
        DEF_REGS(gen_op_addl_A0_, _s2)
430
    },
431
    [3] = {
432
        DEF_REGS(gen_op_addl_A0_, _s3)
433
    },
434
};
435

    
436
#ifdef TARGET_X86_64
437
static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = {
438
    DEF_REGS(gen_op_movq_A0_, )
439
};
440

    
441
static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = {
442
    [0] = {
443
        DEF_REGS(gen_op_addq_A0_, )
444
    },
445
    [1] = {
446
        DEF_REGS(gen_op_addq_A0_, _s1)
447
    },
448
    [2] = {
449
        DEF_REGS(gen_op_addq_A0_, _s2)
450
    },
451
    [3] = {
452
        DEF_REGS(gen_op_addq_A0_, _s3)
453
    },
454
};
455
#endif
456

    
457
static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
458
    [0] = {
459
        DEF_REGS(gen_op_cmovw_, _T1_T0)
460
    },
461
    [1] = {
462
        DEF_REGS(gen_op_cmovl_, _T1_T0)
463
    },
464
#ifdef TARGET_X86_64
465
    [2] = {
466
        DEF_REGS(gen_op_cmovq_, _T1_T0)
467
    },
468
#endif
469
};
470

    
471
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
472
    NULL,
473
    gen_op_orl_T0_T1,
474
    NULL,
475
    NULL,
476
    gen_op_andl_T0_T1,
477
    NULL,
478
    gen_op_xorl_T0_T1,
479
    NULL,
480
};
481

    
482
#define DEF_ARITHC(SUFFIX)\
483
    {\
484
        gen_op_adcb ## SUFFIX ## _T0_T1_cc,\
485
        gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\
486
    },\
487
    {\
488
        gen_op_adcw ## SUFFIX ## _T0_T1_cc,\
489
        gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\
490
    },\
491
    {\
492
        gen_op_adcl ## SUFFIX ## _T0_T1_cc,\
493
        gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\
494
    },\
495
    {\
496
        X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\
497
        X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\
498
    },
499

    
500
static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = {
501
    DEF_ARITHC( )
502
};
503

    
504
static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = {
505
    DEF_ARITHC(_raw)
506
#ifndef CONFIG_USER_ONLY
507
    DEF_ARITHC(_kernel)
508
    DEF_ARITHC(_user)
509
#endif
510
};
511

    
512
static const int cc_op_arithb[8] = {
513
    CC_OP_ADDB,
514
    CC_OP_LOGICB,
515
    CC_OP_ADDB,
516
    CC_OP_SUBB,
517
    CC_OP_LOGICB,
518
    CC_OP_SUBB,
519
    CC_OP_LOGICB,
520
    CC_OP_SUBB,
521
};
522

    
523
#define DEF_CMPXCHG(SUFFIX)\
524
    gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\
525
    gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\
526
    gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\
527
    X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc),
528

    
529
static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = {
530
    DEF_CMPXCHG( )
531
};
532

    
533
static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = {
534
    DEF_CMPXCHG(_raw)
535
#ifndef CONFIG_USER_ONLY
536
    DEF_CMPXCHG(_kernel)
537
    DEF_CMPXCHG(_user)
538
#endif
539
};
540

    
541
#define DEF_SHIFT(SUFFIX)\
542
    {\
543
        gen_op_rolb ## SUFFIX ## _T0_T1_cc,\
544
        gen_op_rorb ## SUFFIX ## _T0_T1_cc,\
545
        gen_op_rclb ## SUFFIX ## _T0_T1_cc,\
546
        gen_op_rcrb ## SUFFIX ## _T0_T1_cc,\
547
        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
548
        gen_op_shrb ## SUFFIX ## _T0_T1_cc,\
549
        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\
550
        gen_op_sarb ## SUFFIX ## _T0_T1_cc,\
551
    },\
552
    {\
553
        gen_op_rolw ## SUFFIX ## _T0_T1_cc,\
554
        gen_op_rorw ## SUFFIX ## _T0_T1_cc,\
555
        gen_op_rclw ## SUFFIX ## _T0_T1_cc,\
556
        gen_op_rcrw ## SUFFIX ## _T0_T1_cc,\
557
        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
558
        gen_op_shrw ## SUFFIX ## _T0_T1_cc,\
559
        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\
560
        gen_op_sarw ## SUFFIX ## _T0_T1_cc,\
561
    },\
562
    {\
563
        gen_op_roll ## SUFFIX ## _T0_T1_cc,\
564
        gen_op_rorl ## SUFFIX ## _T0_T1_cc,\
565
        gen_op_rcll ## SUFFIX ## _T0_T1_cc,\
566
        gen_op_rcrl ## SUFFIX ## _T0_T1_cc,\
567
        gen_op_shll ## SUFFIX ## _T0_T1_cc,\
568
        gen_op_shrl ## SUFFIX ## _T0_T1_cc,\
569
        gen_op_shll ## SUFFIX ## _T0_T1_cc,\
570
        gen_op_sarl ## SUFFIX ## _T0_T1_cc,\
571
    },\
572
    {\
573
        X86_64_ONLY(gen_op_rolq ## SUFFIX ## _T0_T1_cc),\
574
        X86_64_ONLY(gen_op_rorq ## SUFFIX ## _T0_T1_cc),\
575
        X86_64_ONLY(gen_op_rclq ## SUFFIX ## _T0_T1_cc),\
576
        X86_64_ONLY(gen_op_rcrq ## SUFFIX ## _T0_T1_cc),\
577
        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
578
        X86_64_ONLY(gen_op_shrq ## SUFFIX ## _T0_T1_cc),\
579
        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\
580
        X86_64_ONLY(gen_op_sarq ## SUFFIX ## _T0_T1_cc),\
581
    },
582

    
583
static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {
584
    DEF_SHIFT( )
585
};
586

    
587
static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
588
    DEF_SHIFT(_raw)
589
#ifndef CONFIG_USER_ONLY
590
    DEF_SHIFT(_kernel)
591
    DEF_SHIFT(_user)
592
#endif
593
};
594

    
595
#define DEF_SHIFTD(SUFFIX, op)\
596
    {\
597
        NULL,\
598
        NULL,\
599
    },\
600
    {\
601
        gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
602
        gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
603
    },\
604
    {\
605
        gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
606
        gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
607
    },\
608
    {\
609
    },
610

    
611
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {
612
    DEF_SHIFTD(, im)
613
};
614

    
615
static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {
616
    DEF_SHIFTD(, ECX)
617
};
618

    
619
static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {
620
    DEF_SHIFTD(_raw, im)
621
#ifndef CONFIG_USER_ONLY
622
    DEF_SHIFTD(_kernel, im)
623
    DEF_SHIFTD(_user, im)
624
#endif
625
};
626

    
627
static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[3 * 4][2] = {
628
    DEF_SHIFTD(_raw, ECX)
629
#ifndef CONFIG_USER_ONLY
630
    DEF_SHIFTD(_kernel, ECX)
631
    DEF_SHIFTD(_user, ECX)
632
#endif
633
};
634

    
635
static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
636
    [0] = {
637
        gen_op_btw_T0_T1_cc,
638
        gen_op_btsw_T0_T1_cc,
639
        gen_op_btrw_T0_T1_cc,
640
        gen_op_btcw_T0_T1_cc,
641
    },
642
    [1] = {
643
        gen_op_btl_T0_T1_cc,
644
        gen_op_btsl_T0_T1_cc,
645
        gen_op_btrl_T0_T1_cc,
646
        gen_op_btcl_T0_T1_cc,
647
    },
648
#ifdef TARGET_X86_64
649
    [2] = {
650
        gen_op_btq_T0_T1_cc,
651
        gen_op_btsq_T0_T1_cc,
652
        gen_op_btrq_T0_T1_cc,
653
        gen_op_btcq_T0_T1_cc,
654
    },
655
#endif
656
};
657

    
658
static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
659
    gen_op_add_bitw_A0_T1,
660
    gen_op_add_bitl_A0_T1,
661
    X86_64_ONLY(gen_op_add_bitq_A0_T1),
662
};
663

    
664
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
665
    [0] = {
666
        gen_op_bsfw_T0_cc,
667
        gen_op_bsrw_T0_cc,
668
    },
669
    [1] = {
670
        gen_op_bsfl_T0_cc,
671
        gen_op_bsrl_T0_cc,
672
    },
673
#ifdef TARGET_X86_64
674
    [2] = {
675
        gen_op_bsfq_T0_cc,
676
        gen_op_bsrq_T0_cc,
677
    },
678
#endif
679
};
680

    
681
static GenOpFunc *gen_op_lds_T0_A0[3 * 4] = {
682
    gen_op_ldsb_raw_T0_A0,
683
    gen_op_ldsw_raw_T0_A0,
684
    X86_64_ONLY(gen_op_ldsl_raw_T0_A0),
685
    NULL,
686
#ifndef CONFIG_USER_ONLY
687
    gen_op_ldsb_kernel_T0_A0,
688
    gen_op_ldsw_kernel_T0_A0,
689
    X86_64_ONLY(gen_op_ldsl_kernel_T0_A0),
690
    NULL,
691

    
692
    gen_op_ldsb_user_T0_A0,
693
    gen_op_ldsw_user_T0_A0,
694
    X86_64_ONLY(gen_op_ldsl_user_T0_A0),
695
    NULL,
696
#endif
697
};
698

    
699
static GenOpFunc *gen_op_ldu_T0_A0[3 * 4] = {
700
    gen_op_ldub_raw_T0_A0,
701
    gen_op_lduw_raw_T0_A0,
702
    NULL,
703
    NULL,
704

    
705
#ifndef CONFIG_USER_ONLY
706
    gen_op_ldub_kernel_T0_A0,
707
    gen_op_lduw_kernel_T0_A0,
708
    NULL,
709
    NULL,
710

    
711
    gen_op_ldub_user_T0_A0,
712
    gen_op_lduw_user_T0_A0,
713
    NULL,
714
    NULL,
715
#endif
716
};
717

    
718
/* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
719
static GenOpFunc *gen_op_ld_T0_A0[3 * 4] = {
720
    gen_op_ldub_raw_T0_A0,
721
    gen_op_lduw_raw_T0_A0,
722
    gen_op_ldl_raw_T0_A0,
723
    X86_64_ONLY(gen_op_ldq_raw_T0_A0),
724

    
725
#ifndef CONFIG_USER_ONLY
726
    gen_op_ldub_kernel_T0_A0,
727
    gen_op_lduw_kernel_T0_A0,
728
    gen_op_ldl_kernel_T0_A0,
729
    X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
730

    
731
    gen_op_ldub_user_T0_A0,
732
    gen_op_lduw_user_T0_A0,
733
    gen_op_ldl_user_T0_A0,
734
    X86_64_ONLY(gen_op_ldq_user_T0_A0),
735
#endif
736
};
737

    
738
static GenOpFunc *gen_op_ld_T1_A0[3 * 4] = {
739
    gen_op_ldub_raw_T1_A0,
740
    gen_op_lduw_raw_T1_A0,
741
    gen_op_ldl_raw_T1_A0,
742
    X86_64_ONLY(gen_op_ldq_raw_T1_A0),
743

    
744
#ifndef CONFIG_USER_ONLY
745
    gen_op_ldub_kernel_T1_A0,
746
    gen_op_lduw_kernel_T1_A0,
747
    gen_op_ldl_kernel_T1_A0,
748
    X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
749

    
750
    gen_op_ldub_user_T1_A0,
751
    gen_op_lduw_user_T1_A0,
752
    gen_op_ldl_user_T1_A0,
753
    X86_64_ONLY(gen_op_ldq_user_T1_A0),
754
#endif
755
};
756

    
757
static GenOpFunc *gen_op_st_T0_A0[3 * 4] = {
758
    gen_op_stb_raw_T0_A0,
759
    gen_op_stw_raw_T0_A0,
760
    gen_op_stl_raw_T0_A0,
761
    X86_64_ONLY(gen_op_stq_raw_T0_A0),
762

    
763
#ifndef CONFIG_USER_ONLY
764
    gen_op_stb_kernel_T0_A0,
765
    gen_op_stw_kernel_T0_A0,
766
    gen_op_stl_kernel_T0_A0,
767
    X86_64_ONLY(gen_op_stq_kernel_T0_A0),
768

    
769
    gen_op_stb_user_T0_A0,
770
    gen_op_stw_user_T0_A0,
771
    gen_op_stl_user_T0_A0,
772
    X86_64_ONLY(gen_op_stq_user_T0_A0),
773
#endif
774
};
775

    
776
static GenOpFunc *gen_op_st_T1_A0[3 * 4] = {
777
    NULL,
778
    gen_op_stw_raw_T1_A0,
779
    gen_op_stl_raw_T1_A0,
780
    X86_64_ONLY(gen_op_stq_raw_T1_A0),
781

    
782
#ifndef CONFIG_USER_ONLY
783
    NULL,
784
    gen_op_stw_kernel_T1_A0,
785
    gen_op_stl_kernel_T1_A0,
786
    X86_64_ONLY(gen_op_stq_kernel_T1_A0),
787

    
788
    NULL,
789
    gen_op_stw_user_T1_A0,
790
    gen_op_stl_user_T1_A0,
791
    X86_64_ONLY(gen_op_stq_user_T1_A0),
792
#endif
793
};
794

    
795
static inline void gen_jmp_im(target_ulong pc)
796
{
797
#ifdef TARGET_X86_64
798
    if (pc == (uint32_t)pc) {
799
        gen_op_movl_eip_im(pc);
800
    } else if (pc == (int32_t)pc) {
801
        gen_op_movq_eip_im(pc);
802
    } else {
803
        gen_op_movq_eip_im64(pc >> 32, pc);
804
    }
805
#else
806
    gen_op_movl_eip_im(pc);
807
#endif
808
}
809

    
810
static inline void gen_string_movl_A0_ESI(DisasContext *s)
811
{
812
    int override;
813

    
814
    override = s->override;
815
#ifdef TARGET_X86_64
816
    if (s->aflag == 2) {
817
        if (override >= 0) {
818
            gen_op_movq_A0_seg(offsetof(CPUX86State,segs[override].base));
819
            gen_op_addq_A0_reg_sN[0][R_ESI]();
820
        } else {
821
            gen_op_movq_A0_reg[R_ESI]();
822
        }
823
    } else
824
#endif
825
    if (s->aflag) {
826
        /* 32 bit address */
827
        if (s->addseg && override < 0)
828
            override = R_DS;
829
        if (override >= 0) {
830
            gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));
831
            gen_op_addl_A0_reg_sN[0][R_ESI]();
832
        } else {
833
            gen_op_movl_A0_reg[R_ESI]();
834
        }
835
    } else {
836
        /* 16 address, always override */
837
        if (override < 0)
838
            override = R_DS;
839
        gen_op_movl_A0_reg[R_ESI]();
840
        gen_op_andl_A0_ffff();
841
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
842
    }
843
}
844

    
845
static inline void gen_string_movl_A0_EDI(DisasContext *s)
846
{
847
#ifdef TARGET_X86_64
848
    if (s->aflag == 2) {
849
        gen_op_movq_A0_reg[R_EDI]();
850
    } else
851
#endif
852
    if (s->aflag) {
853
        if (s->addseg) {
854
            gen_op_movl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
855
            gen_op_addl_A0_reg_sN[0][R_EDI]();
856
        } else {
857
            gen_op_movl_A0_reg[R_EDI]();
858
        }
859
    } else {
860
        gen_op_movl_A0_reg[R_EDI]();
861
        gen_op_andl_A0_ffff();
862
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
863
    }
864
}
865

    
866
static GenOpFunc *gen_op_movl_T0_Dshift[4] = {
867
    gen_op_movl_T0_Dshiftb,
868
    gen_op_movl_T0_Dshiftw,
869
    gen_op_movl_T0_Dshiftl,
870
    X86_64_ONLY(gen_op_movl_T0_Dshiftq),
871
};
872

    
873
static GenOpFunc1 *gen_op_jnz_ecx[3] = {
874
    gen_op_jnz_ecxw,
875
    gen_op_jnz_ecxl,
876
    X86_64_ONLY(gen_op_jnz_ecxq),
877
};
878
    
879
static GenOpFunc1 *gen_op_jz_ecx[3] = {
880
    gen_op_jz_ecxw,
881
    gen_op_jz_ecxl,
882
    X86_64_ONLY(gen_op_jz_ecxq),
883
};
884

    
885
static GenOpFunc *gen_op_dec_ECX[3] = {
886
    gen_op_decw_ECX,
887
    gen_op_decl_ECX,
888
    X86_64_ONLY(gen_op_decq_ECX),
889
};
890

    
891
static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
892
    {
893
        gen_op_jnz_subb,
894
        gen_op_jnz_subw,
895
        gen_op_jnz_subl,
896
        X86_64_ONLY(gen_op_jnz_subq),
897
    },
898
    {
899
        gen_op_jz_subb,
900
        gen_op_jz_subw,
901
        gen_op_jz_subl,
902
        X86_64_ONLY(gen_op_jz_subq),
903
    },
904
};
905

    
906
static GenOpFunc *gen_op_in_DX_T0[3] = {
907
    gen_op_inb_DX_T0,
908
    gen_op_inw_DX_T0,
909
    gen_op_inl_DX_T0,
910
};
911

    
912
static GenOpFunc *gen_op_out_DX_T0[3] = {
913
    gen_op_outb_DX_T0,
914
    gen_op_outw_DX_T0,
915
    gen_op_outl_DX_T0,
916
};
917

    
918
static GenOpFunc *gen_op_in[3] = {
919
    gen_op_inb_T0_T1,
920
    gen_op_inw_T0_T1,
921
    gen_op_inl_T0_T1,
922
};
923

    
924
static GenOpFunc *gen_op_out[3] = {
925
    gen_op_outb_T0_T1,
926
    gen_op_outw_T0_T1,
927
    gen_op_outl_T0_T1,
928
};
929

    
930
static GenOpFunc *gen_check_io_T0[3] = {
931
    gen_op_check_iob_T0,
932
    gen_op_check_iow_T0,
933
    gen_op_check_iol_T0,
934
};
935

    
936
static GenOpFunc *gen_check_io_DX[3] = {
937
    gen_op_check_iob_DX,
938
    gen_op_check_iow_DX,
939
    gen_op_check_iol_DX,
940
};
941

    
942
static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
943
{
944
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
945
        if (s->cc_op != CC_OP_DYNAMIC)
946
            gen_op_set_cc_op(s->cc_op);
947
        gen_jmp_im(cur_eip);
948
        if (use_dx)
949
            gen_check_io_DX[ot]();
950
        else
951
            gen_check_io_T0[ot]();
952
    }
953
}
954

    
955
static inline void gen_movs(DisasContext *s, int ot)
956
{
957
    gen_string_movl_A0_ESI(s);
958
    gen_op_ld_T0_A0[ot + s->mem_index]();
959
    gen_string_movl_A0_EDI(s);
960
    gen_op_st_T0_A0[ot + s->mem_index]();
961
    gen_op_movl_T0_Dshift[ot]();
962
#ifdef TARGET_X86_64
963
    if (s->aflag == 2) {
964
        gen_op_addq_ESI_T0();
965
        gen_op_addq_EDI_T0();
966
    } else 
967
#endif
968
    if (s->aflag) {
969
        gen_op_addl_ESI_T0();
970
        gen_op_addl_EDI_T0();
971
    } else {
972
        gen_op_addw_ESI_T0();
973
        gen_op_addw_EDI_T0();
974
    }
975
}
976

    
977
static inline void gen_update_cc_op(DisasContext *s)
978
{
979
    if (s->cc_op != CC_OP_DYNAMIC) {
980
        gen_op_set_cc_op(s->cc_op);
981
        s->cc_op = CC_OP_DYNAMIC;
982
    }
983
}
984

    
985
/* XXX: does not work with gdbstub "ice" single step - not a
986
   serious problem */
987
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
988
{
989
    int l1, l2;
990

    
991
    l1 = gen_new_label();
992
    l2 = gen_new_label();
993
    gen_op_jnz_ecx[s->aflag](l1);
994
    gen_set_label(l2);
995
    gen_jmp_tb(s, next_eip, 1);
996
    gen_set_label(l1);
997
    return l2;
998
}
999

    
1000
static inline void gen_stos(DisasContext *s, int ot)
1001
{
1002
    gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
1003
    gen_string_movl_A0_EDI(s);
1004
    gen_op_st_T0_A0[ot + s->mem_index]();
1005
    gen_op_movl_T0_Dshift[ot]();
1006
#ifdef TARGET_X86_64
1007
    if (s->aflag == 2) {
1008
        gen_op_addq_EDI_T0();
1009
    } else 
1010
#endif
1011
    if (s->aflag) {
1012
        gen_op_addl_EDI_T0();
1013
    } else {
1014
        gen_op_addw_EDI_T0();
1015
    }
1016
}
1017

    
1018
static inline void gen_lods(DisasContext *s, int ot)
1019
{
1020
    gen_string_movl_A0_ESI(s);
1021
    gen_op_ld_T0_A0[ot + s->mem_index]();
1022
    gen_op_mov_reg_T0[ot][R_EAX]();
1023
    gen_op_movl_T0_Dshift[ot]();
1024
#ifdef TARGET_X86_64
1025
    if (s->aflag == 2) {
1026
        gen_op_addq_ESI_T0();
1027
    } else 
1028
#endif
1029
    if (s->aflag) {
1030
        gen_op_addl_ESI_T0();
1031
    } else {
1032
        gen_op_addw_ESI_T0();
1033
    }
1034
}
1035

    
1036
static inline void gen_scas(DisasContext *s, int ot)
1037
{
1038
    gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
1039
    gen_string_movl_A0_EDI(s);
1040
    gen_op_ld_T1_A0[ot + s->mem_index]();
1041
    gen_op_cmpl_T0_T1_cc();
1042
    gen_op_movl_T0_Dshift[ot]();
1043
#ifdef TARGET_X86_64
1044
    if (s->aflag == 2) {
1045
        gen_op_addq_EDI_T0();
1046
    } else 
1047
#endif
1048
    if (s->aflag) {
1049
        gen_op_addl_EDI_T0();
1050
    } else {
1051
        gen_op_addw_EDI_T0();
1052
    }
1053
}
1054

    
1055
static inline void gen_cmps(DisasContext *s, int ot)
1056
{
1057
    gen_string_movl_A0_ESI(s);
1058
    gen_op_ld_T0_A0[ot + s->mem_index]();
1059
    gen_string_movl_A0_EDI(s);
1060
    gen_op_ld_T1_A0[ot + s->mem_index]();
1061
    gen_op_cmpl_T0_T1_cc();
1062
    gen_op_movl_T0_Dshift[ot]();
1063
#ifdef TARGET_X86_64
1064
    if (s->aflag == 2) {
1065
        gen_op_addq_ESI_T0();
1066
        gen_op_addq_EDI_T0();
1067
    } else 
1068
#endif
1069
    if (s->aflag) {
1070
        gen_op_addl_ESI_T0();
1071
        gen_op_addl_EDI_T0();
1072
    } else {
1073
        gen_op_addw_ESI_T0();
1074
        gen_op_addw_EDI_T0();
1075
    }
1076
}
1077

    
1078
static inline void gen_ins(DisasContext *s, int ot)
1079
{
1080
    gen_string_movl_A0_EDI(s);
1081
    gen_op_movl_T0_0();
1082
    gen_op_st_T0_A0[ot + s->mem_index]();
1083
    gen_op_in_DX_T0[ot]();
1084
    gen_op_st_T0_A0[ot + s->mem_index]();
1085
    gen_op_movl_T0_Dshift[ot]();
1086
#ifdef TARGET_X86_64
1087
    if (s->aflag == 2) {
1088
        gen_op_addq_EDI_T0();
1089
    } else 
1090
#endif
1091
    if (s->aflag) {
1092
        gen_op_addl_EDI_T0();
1093
    } else {
1094
        gen_op_addw_EDI_T0();
1095
    }
1096
}
1097

    
1098
static inline void gen_outs(DisasContext *s, int ot)
1099
{
1100
    gen_string_movl_A0_ESI(s);
1101
    gen_op_ld_T0_A0[ot + s->mem_index]();
1102
    gen_op_out_DX_T0[ot]();
1103
    gen_op_movl_T0_Dshift[ot]();
1104
#ifdef TARGET_X86_64
1105
    if (s->aflag == 2) {
1106
        gen_op_addq_ESI_T0();
1107
    } else 
1108
#endif
1109
    if (s->aflag) {
1110
        gen_op_addl_ESI_T0();
1111
    } else {
1112
        gen_op_addw_ESI_T0();
1113
    }
1114
}
1115

    
1116
/* same method as Valgrind : we generate jumps to current or next
1117
   instruction */
1118
#define GEN_REPZ(op)                                                          \
1119
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1120
                                 target_ulong cur_eip, target_ulong next_eip) \
1121
{                                                                             \
1122
    int l2;\
1123
    gen_update_cc_op(s);                                                      \
1124
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1125
    gen_ ## op(s, ot);                                                        \
1126
    gen_op_dec_ECX[s->aflag]();                                               \
1127
    /* a loop would cause two single step exceptions if ECX = 1               \
1128
       before rep string_insn */                                              \
1129
    if (!s->jmp_opt)                                                          \
1130
        gen_op_jz_ecx[s->aflag](l2);                                          \
1131
    gen_jmp(s, cur_eip);                                                      \
1132
}
1133

    
1134
#define GEN_REPZ2(op)                                                         \
1135
static inline void gen_repz_ ## op(DisasContext *s, int ot,                   \
1136
                                   target_ulong cur_eip,                      \
1137
                                   target_ulong next_eip,                     \
1138
                                   int nz)                                    \
1139
{                                                                             \
1140
    int l2;\
1141
    gen_update_cc_op(s);                                                      \
1142
    l2 = gen_jz_ecx_string(s, next_eip);                                      \
1143
    gen_ ## op(s, ot);                                                        \
1144
    gen_op_dec_ECX[s->aflag]();                                               \
1145
    gen_op_set_cc_op(CC_OP_SUBB + ot);                                        \
1146
    gen_op_string_jnz_sub[nz][ot](l2);\
1147
    if (!s->jmp_opt)                                                          \
1148
        gen_op_jz_ecx[s->aflag](l2);                                          \
1149
    gen_jmp(s, cur_eip);                                                      \
1150
}
1151

    
1152
GEN_REPZ(movs)
1153
GEN_REPZ(stos)
1154
GEN_REPZ(lods)
1155
GEN_REPZ(ins)
1156
GEN_REPZ(outs)
1157
GEN_REPZ2(scas)
1158
GEN_REPZ2(cmps)
1159

    
1160
enum {
1161
    JCC_O,
1162
    JCC_B,
1163
    JCC_Z,
1164
    JCC_BE,
1165
    JCC_S,
1166
    JCC_P,
1167
    JCC_L,
1168
    JCC_LE,
1169
};
1170

    
1171
static GenOpFunc1 *gen_jcc_sub[4][8] = {
1172
    [OT_BYTE] = {
1173
        NULL,
1174
        gen_op_jb_subb,
1175
        gen_op_jz_subb,
1176
        gen_op_jbe_subb,
1177
        gen_op_js_subb,
1178
        NULL,
1179
        gen_op_jl_subb,
1180
        gen_op_jle_subb,
1181
    },
1182
    [OT_WORD] = {
1183
        NULL,
1184
        gen_op_jb_subw,
1185
        gen_op_jz_subw,
1186
        gen_op_jbe_subw,
1187
        gen_op_js_subw,
1188
        NULL,
1189
        gen_op_jl_subw,
1190
        gen_op_jle_subw,
1191
    },
1192
    [OT_LONG] = {
1193
        NULL,
1194
        gen_op_jb_subl,
1195
        gen_op_jz_subl,
1196
        gen_op_jbe_subl,
1197
        gen_op_js_subl,
1198
        NULL,
1199
        gen_op_jl_subl,
1200
        gen_op_jle_subl,
1201
    },
1202
#ifdef TARGET_X86_64
1203
    [OT_QUAD] = {
1204
        NULL,
1205
        BUGGY_64(gen_op_jb_subq),
1206
        gen_op_jz_subq,
1207
        BUGGY_64(gen_op_jbe_subq),
1208
        gen_op_js_subq,
1209
        NULL,
1210
        BUGGY_64(gen_op_jl_subq),
1211
        BUGGY_64(gen_op_jle_subq),
1212
    },
1213
#endif
1214
};
1215
static GenOpFunc1 *gen_op_loop[3][4] = {
1216
    [0] = {
1217
        gen_op_loopnzw,
1218
        gen_op_loopzw,
1219
        gen_op_jnz_ecxw,
1220
    },
1221
    [1] = {
1222
        gen_op_loopnzl,
1223
        gen_op_loopzl,
1224
        gen_op_jnz_ecxl,
1225
    },
1226
#ifdef TARGET_X86_64
1227
    [2] = {
1228
        gen_op_loopnzq,
1229
        gen_op_loopzq,
1230
        gen_op_jnz_ecxq,
1231
    },
1232
#endif
1233
};
1234

    
1235
static GenOpFunc *gen_setcc_slow[8] = {
1236
    gen_op_seto_T0_cc,
1237
    gen_op_setb_T0_cc,
1238
    gen_op_setz_T0_cc,
1239
    gen_op_setbe_T0_cc,
1240
    gen_op_sets_T0_cc,
1241
    gen_op_setp_T0_cc,
1242
    gen_op_setl_T0_cc,
1243
    gen_op_setle_T0_cc,
1244
};
1245

    
1246
static GenOpFunc *gen_setcc_sub[4][8] = {
1247
    [OT_BYTE] = {
1248
        NULL,
1249
        gen_op_setb_T0_subb,
1250
        gen_op_setz_T0_subb,
1251
        gen_op_setbe_T0_subb,
1252
        gen_op_sets_T0_subb,
1253
        NULL,
1254
        gen_op_setl_T0_subb,
1255
        gen_op_setle_T0_subb,
1256
    },
1257
    [OT_WORD] = {
1258
        NULL,
1259
        gen_op_setb_T0_subw,
1260
        gen_op_setz_T0_subw,
1261
        gen_op_setbe_T0_subw,
1262
        gen_op_sets_T0_subw,
1263
        NULL,
1264
        gen_op_setl_T0_subw,
1265
        gen_op_setle_T0_subw,
1266
    },
1267
    [OT_LONG] = {
1268
        NULL,
1269
        gen_op_setb_T0_subl,
1270
        gen_op_setz_T0_subl,
1271
        gen_op_setbe_T0_subl,
1272
        gen_op_sets_T0_subl,
1273
        NULL,
1274
        gen_op_setl_T0_subl,
1275
        gen_op_setle_T0_subl,
1276
    },
1277
#ifdef TARGET_X86_64
1278
    [OT_QUAD] = {
1279
        NULL,
1280
        gen_op_setb_T0_subq,
1281
        gen_op_setz_T0_subq,
1282
        gen_op_setbe_T0_subq,
1283
        gen_op_sets_T0_subq,
1284
        NULL,
1285
        gen_op_setl_T0_subq,
1286
        gen_op_setle_T0_subq,
1287
    },
1288
#endif
1289
};
1290

    
1291
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
1292
    gen_op_fadd_ST0_FT0,
1293
    gen_op_fmul_ST0_FT0,
1294
    gen_op_fcom_ST0_FT0,
1295
    gen_op_fcom_ST0_FT0,
1296
    gen_op_fsub_ST0_FT0,
1297
    gen_op_fsubr_ST0_FT0,
1298
    gen_op_fdiv_ST0_FT0,
1299
    gen_op_fdivr_ST0_FT0,
1300
};
1301

    
1302
/* NOTE the exception in "r" op ordering */
1303
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
1304
    gen_op_fadd_STN_ST0,
1305
    gen_op_fmul_STN_ST0,
1306
    NULL,
1307
    NULL,
1308
    gen_op_fsubr_STN_ST0,
1309
    gen_op_fsub_STN_ST0,
1310
    gen_op_fdivr_STN_ST0,
1311
    gen_op_fdiv_STN_ST0,
1312
};
1313

    
1314
/* if d == OR_TMP0, it means memory operand (address in A0) */
1315
static void gen_op(DisasContext *s1, int op, int ot, int d)
1316
{
1317
    GenOpFunc *gen_update_cc;
1318
    
1319
    if (d != OR_TMP0) {
1320
        gen_op_mov_TN_reg[ot][0][d]();
1321
    } else {
1322
        gen_op_ld_T0_A0[ot + s1->mem_index]();
1323
    }
1324
    switch(op) {
1325
    case OP_ADCL:
1326
    case OP_SBBL:
1327
        if (s1->cc_op != CC_OP_DYNAMIC)
1328
            gen_op_set_cc_op(s1->cc_op);
1329
        if (d != OR_TMP0) {
1330
            gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
1331
            gen_op_mov_reg_T0[ot][d]();
1332
        } else {
1333
            gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL]();
1334
        }
1335
        s1->cc_op = CC_OP_DYNAMIC;
1336
        goto the_end;
1337
    case OP_ADDL:
1338
        gen_op_addl_T0_T1();
1339
        s1->cc_op = CC_OP_ADDB + ot;
1340
        gen_update_cc = gen_op_update2_cc;
1341
        break;
1342
    case OP_SUBL:
1343
        gen_op_subl_T0_T1();
1344
        s1->cc_op = CC_OP_SUBB + ot;
1345
        gen_update_cc = gen_op_update2_cc;
1346
        break;
1347
    default:
1348
    case OP_ANDL:
1349
    case OP_ORL:
1350
    case OP_XORL:
1351
        gen_op_arith_T0_T1_cc[op]();
1352
        s1->cc_op = CC_OP_LOGICB + ot;
1353
        gen_update_cc = gen_op_update1_cc;
1354
        break;
1355
    case OP_CMPL:
1356
        gen_op_cmpl_T0_T1_cc();
1357
        s1->cc_op = CC_OP_SUBB + ot;
1358
        gen_update_cc = NULL;
1359
        break;
1360
    }
1361
    if (op != OP_CMPL) {
1362
        if (d != OR_TMP0)
1363
            gen_op_mov_reg_T0[ot][d]();
1364
        else
1365
            gen_op_st_T0_A0[ot + s1->mem_index]();
1366
    }
1367
    /* the flags update must happen after the memory write (precise
1368
       exception support) */
1369
    if (gen_update_cc)
1370
        gen_update_cc();
1371
 the_end: ;
1372
}
1373

    
1374
/* if d == OR_TMP0, it means memory operand (address in A0) */
1375
static void gen_inc(DisasContext *s1, int ot, int d, int c)
1376
{
1377
    if (d != OR_TMP0)
1378
        gen_op_mov_TN_reg[ot][0][d]();
1379
    else
1380
        gen_op_ld_T0_A0[ot + s1->mem_index]();
1381
    if (s1->cc_op != CC_OP_DYNAMIC)
1382
        gen_op_set_cc_op(s1->cc_op);
1383
    if (c > 0) {
1384
        gen_op_incl_T0();
1385
        s1->cc_op = CC_OP_INCB + ot;
1386
    } else {
1387
        gen_op_decl_T0();
1388
        s1->cc_op = CC_OP_DECB + ot;
1389
    }
1390
    if (d != OR_TMP0)
1391
        gen_op_mov_reg_T0[ot][d]();
1392
    else
1393
        gen_op_st_T0_A0[ot + s1->mem_index]();
1394
    gen_op_update_inc_cc();
1395
}
1396

    
1397
static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
1398
{
1399
    if (d != OR_TMP0)
1400
        gen_op_mov_TN_reg[ot][0][d]();
1401
    else
1402
        gen_op_ld_T0_A0[ot + s1->mem_index]();
1403
    if (s != OR_TMP1)
1404
        gen_op_mov_TN_reg[ot][1][s]();
1405
    /* for zero counts, flags are not updated, so must do it dynamically */
1406
    if (s1->cc_op != CC_OP_DYNAMIC)
1407
        gen_op_set_cc_op(s1->cc_op);
1408
    
1409
    if (d != OR_TMP0)
1410
        gen_op_shift_T0_T1_cc[ot][op]();
1411
    else
1412
        gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op]();
1413
    if (d != OR_TMP0)
1414
        gen_op_mov_reg_T0[ot][d]();
1415
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1416
}
1417

    
1418
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1419
{
1420
    /* currently not optimized */
1421
    gen_op_movl_T1_im(c);
1422
    gen_shift(s1, op, ot, d, OR_TMP1);
1423
}
1424

    
1425
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1426
{
1427
    target_long disp;
1428
    int havesib;
1429
    int base;
1430
    int index;
1431
    int scale;
1432
    int opreg;
1433
    int mod, rm, code, override, must_add_seg;
1434

    
1435
    override = s->override;
1436
    must_add_seg = s->addseg;
1437
    if (override >= 0)
1438
        must_add_seg = 1;
1439
    mod = (modrm >> 6) & 3;
1440
    rm = modrm & 7;
1441

    
1442
    if (s->aflag) {
1443

    
1444
        havesib = 0;
1445
        base = rm;
1446
        index = 0;
1447
        scale = 0;
1448
        
1449
        if (base == 4) {
1450
            havesib = 1;
1451
            code = ldub_code(s->pc++);
1452
            scale = (code >> 6) & 3;
1453
            index = ((code >> 3) & 7) | REX_X(s);
1454
            base = (code & 7);
1455
        }
1456
        base |= REX_B(s);
1457

    
1458
        switch (mod) {
1459
        case 0:
1460
            if ((base & 7) == 5) {
1461
                base = -1;
1462
                disp = (int32_t)ldl_code(s->pc);
1463
                s->pc += 4;
1464
                if (CODE64(s) && !havesib) {
1465
                    disp += s->pc + s->rip_offset;
1466
                }
1467
            } else {
1468
                disp = 0;
1469
            }
1470
            break;
1471
        case 1:
1472
            disp = (int8_t)ldub_code(s->pc++);
1473
            break;
1474
        default:
1475
        case 2:
1476
            disp = ldl_code(s->pc);
1477
            s->pc += 4;
1478
            break;
1479
        }
1480
        
1481
        if (base >= 0) {
1482
            /* for correct popl handling with esp */
1483
            if (base == 4 && s->popl_esp_hack)
1484
                disp += s->popl_esp_hack;
1485
#ifdef TARGET_X86_64
1486
            if (s->aflag == 2) {
1487
                gen_op_movq_A0_reg[base]();
1488
                if (disp != 0) {
1489
                    if ((int32_t)disp == disp)
1490
                        gen_op_addq_A0_im(disp);
1491
                    else
1492
                        gen_op_addq_A0_im64(disp >> 32, disp);
1493
                }
1494
            } else 
1495
#endif
1496
            {
1497
                gen_op_movl_A0_reg[base]();
1498
                if (disp != 0)
1499
                    gen_op_addl_A0_im(disp);
1500
            }
1501
        } else {
1502
#ifdef TARGET_X86_64
1503
            if (s->aflag == 2) {
1504
                if ((int32_t)disp == disp)
1505
                    gen_op_movq_A0_im(disp);
1506
                else
1507
                    gen_op_movq_A0_im64(disp >> 32, disp);
1508
            } else 
1509
#endif
1510
            {
1511
                gen_op_movl_A0_im(disp);
1512
            }
1513
        }
1514
        /* XXX: index == 4 is always invalid */
1515
        if (havesib && (index != 4 || scale != 0)) {
1516
#ifdef TARGET_X86_64
1517
            if (s->aflag == 2) {
1518
                gen_op_addq_A0_reg_sN[scale][index]();
1519
            } else 
1520
#endif
1521
            {
1522
                gen_op_addl_A0_reg_sN[scale][index]();
1523
            }
1524
        }
1525
        if (must_add_seg) {
1526
            if (override < 0) {
1527
                if (base == R_EBP || base == R_ESP)
1528
                    override = R_SS;
1529
                else
1530
                    override = R_DS;
1531
            }
1532
#ifdef TARGET_X86_64
1533
            if (s->aflag == 2) {
1534
                gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
1535
            } else 
1536
#endif
1537
            {
1538
                gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1539
            }
1540
        }
1541
    } else {
1542
        switch (mod) {
1543
        case 0:
1544
            if (rm == 6) {
1545
                disp = lduw_code(s->pc);
1546
                s->pc += 2;
1547
                gen_op_movl_A0_im(disp);
1548
                rm = 0; /* avoid SS override */
1549
                goto no_rm;
1550
            } else {
1551
                disp = 0;
1552
            }
1553
            break;
1554
        case 1:
1555
            disp = (int8_t)ldub_code(s->pc++);
1556
            break;
1557
        default:
1558
        case 2:
1559
            disp = lduw_code(s->pc);
1560
            s->pc += 2;
1561
            break;
1562
        }
1563
        switch(rm) {
1564
        case 0:
1565
            gen_op_movl_A0_reg[R_EBX]();
1566
            gen_op_addl_A0_reg_sN[0][R_ESI]();
1567
            break;
1568
        case 1:
1569
            gen_op_movl_A0_reg[R_EBX]();
1570
            gen_op_addl_A0_reg_sN[0][R_EDI]();
1571
            break;
1572
        case 2:
1573
            gen_op_movl_A0_reg[R_EBP]();
1574
            gen_op_addl_A0_reg_sN[0][R_ESI]();
1575
            break;
1576
        case 3:
1577
            gen_op_movl_A0_reg[R_EBP]();
1578
            gen_op_addl_A0_reg_sN[0][R_EDI]();
1579
            break;
1580
        case 4:
1581
            gen_op_movl_A0_reg[R_ESI]();
1582
            break;
1583
        case 5:
1584
            gen_op_movl_A0_reg[R_EDI]();
1585
            break;
1586
        case 6:
1587
            gen_op_movl_A0_reg[R_EBP]();
1588
            break;
1589
        default:
1590
        case 7:
1591
            gen_op_movl_A0_reg[R_EBX]();
1592
            break;
1593
        }
1594
        if (disp != 0)
1595
            gen_op_addl_A0_im(disp);
1596
        gen_op_andl_A0_ffff();
1597
    no_rm:
1598
        if (must_add_seg) {
1599
            if (override < 0) {
1600
                if (rm == 2 || rm == 3 || rm == 6)
1601
                    override = R_SS;
1602
                else
1603
                    override = R_DS;
1604
            }
1605
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1606
        }
1607
    }
1608

    
1609
    opreg = OR_A0;
1610
    disp = 0;
1611
    *reg_ptr = opreg;
1612
    *offset_ptr = disp;
1613
}
1614

    
1615
/* used for LEA and MOV AX, mem */
1616
static void gen_add_A0_ds_seg(DisasContext *s)
1617
{
1618
    int override, must_add_seg;
1619
    must_add_seg = s->addseg;
1620
    override = R_DS;
1621
    if (s->override >= 0) {
1622
        override = s->override;
1623
        must_add_seg = 1;
1624
    } else {
1625
        override = R_DS;
1626
    }
1627
    if (must_add_seg) {
1628
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1629
    }
1630
}
1631

    
1632
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
1633
   OR_TMP0 */
1634
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
1635
{
1636
    int mod, rm, opreg, disp;
1637

    
1638
    mod = (modrm >> 6) & 3;
1639
    rm = (modrm & 7) | REX_B(s);
1640
    if (mod == 3) {
1641
        if (is_store) {
1642
            if (reg != OR_TMP0)
1643
                gen_op_mov_TN_reg[ot][0][reg]();
1644
            gen_op_mov_reg_T0[ot][rm]();
1645
        } else {
1646
            gen_op_mov_TN_reg[ot][0][rm]();
1647
            if (reg != OR_TMP0)
1648
                gen_op_mov_reg_T0[ot][reg]();
1649
        }
1650
    } else {
1651
        gen_lea_modrm(s, modrm, &opreg, &disp);
1652
        if (is_store) {
1653
            if (reg != OR_TMP0)
1654
                gen_op_mov_TN_reg[ot][0][reg]();
1655
            gen_op_st_T0_A0[ot + s->mem_index]();
1656
        } else {
1657
            gen_op_ld_T0_A0[ot + s->mem_index]();
1658
            if (reg != OR_TMP0)
1659
                gen_op_mov_reg_T0[ot][reg]();
1660
        }
1661
    }
1662
}
1663

    
1664
static inline uint32_t insn_get(DisasContext *s, int ot)
1665
{
1666
    uint32_t ret;
1667

    
1668
    switch(ot) {
1669
    case OT_BYTE:
1670
        ret = ldub_code(s->pc);
1671
        s->pc++;
1672
        break;
1673
    case OT_WORD:
1674
        ret = lduw_code(s->pc);
1675
        s->pc += 2;
1676
        break;
1677
    default:
1678
    case OT_LONG:
1679
        ret = ldl_code(s->pc);
1680
        s->pc += 4;
1681
        break;
1682
    }
1683
    return ret;
1684
}
1685

    
1686
static inline int insn_const_size(unsigned int ot)
1687
{
1688
    if (ot <= OT_LONG)
1689
        return 1 << ot;
1690
    else
1691
        return 4;
1692
}
1693

    
1694
static inline void gen_jcc(DisasContext *s, int b, 
1695
                           target_ulong val, target_ulong next_eip)
1696
{
1697
    TranslationBlock *tb;
1698
    int inv, jcc_op;
1699
    GenOpFunc1 *func;
1700
    target_ulong tmp;
1701
    int l1, l2;
1702

    
1703
    inv = b & 1;
1704
    jcc_op = (b >> 1) & 7;
1705
    
1706
    if (s->jmp_opt) {
1707
        switch(s->cc_op) {
1708
            /* we optimize the cmp/jcc case */
1709
        case CC_OP_SUBB:
1710
        case CC_OP_SUBW:
1711
        case CC_OP_SUBL:
1712
        case CC_OP_SUBQ:
1713
            func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1714
            break;
1715
            
1716
            /* some jumps are easy to compute */
1717
        case CC_OP_ADDB:
1718
        case CC_OP_ADDW:
1719
        case CC_OP_ADDL:
1720
        case CC_OP_ADDQ:
1721

    
1722
        case CC_OP_ADCB:
1723
        case CC_OP_ADCW:
1724
        case CC_OP_ADCL:
1725
        case CC_OP_ADCQ:
1726

    
1727
        case CC_OP_SBBB:
1728
        case CC_OP_SBBW:
1729
        case CC_OP_SBBL:
1730
        case CC_OP_SBBQ:
1731

    
1732
        case CC_OP_LOGICB:
1733
        case CC_OP_LOGICW:
1734
        case CC_OP_LOGICL:
1735
        case CC_OP_LOGICQ:
1736

    
1737
        case CC_OP_INCB:
1738
        case CC_OP_INCW:
1739
        case CC_OP_INCL:
1740
        case CC_OP_INCQ:
1741

    
1742
        case CC_OP_DECB:
1743
        case CC_OP_DECW:
1744
        case CC_OP_DECL:
1745
        case CC_OP_DECQ:
1746

    
1747
        case CC_OP_SHLB:
1748
        case CC_OP_SHLW:
1749
        case CC_OP_SHLL:
1750
        case CC_OP_SHLQ:
1751

    
1752
        case CC_OP_SARB:
1753
        case CC_OP_SARW:
1754
        case CC_OP_SARL:
1755
        case CC_OP_SARQ:
1756
            switch(jcc_op) {
1757
            case JCC_Z:
1758
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1759
                break;
1760
            case JCC_S:
1761
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1762
                break;
1763
            default:
1764
                func = NULL;
1765
                break;
1766
            }
1767
            break;
1768
        default:
1769
            func = NULL;
1770
            break;
1771
        }
1772

    
1773
        if (s->cc_op != CC_OP_DYNAMIC)
1774
            gen_op_set_cc_op(s->cc_op);
1775

    
1776
        if (!func) {
1777
            gen_setcc_slow[jcc_op]();
1778
            func = gen_op_jnz_T0_label;
1779
        }
1780
    
1781
        if (inv) {
1782
            tmp = val;
1783
            val = next_eip;
1784
            next_eip = tmp;
1785
        }
1786
        tb = s->tb;
1787

    
1788
        l1 = gen_new_label();
1789
        func(l1);
1790

    
1791
        gen_op_goto_tb0(TBPARAM(tb));
1792
        gen_jmp_im(next_eip);
1793
        gen_op_movl_T0_im((long)tb + 0);
1794
        gen_op_exit_tb();
1795

    
1796
        gen_set_label(l1);
1797
        gen_op_goto_tb1(TBPARAM(tb));
1798
        gen_jmp_im(val);
1799
        gen_op_movl_T0_im((long)tb + 1);
1800
        gen_op_exit_tb();
1801

    
1802
        s->is_jmp = 3;
1803
    } else {
1804

    
1805
        if (s->cc_op != CC_OP_DYNAMIC) {
1806
            gen_op_set_cc_op(s->cc_op);
1807
            s->cc_op = CC_OP_DYNAMIC;
1808
        }
1809
        gen_setcc_slow[jcc_op]();
1810
        if (inv) {
1811
            tmp = val;
1812
            val = next_eip;
1813
            next_eip = tmp;
1814
        }
1815
        l1 = gen_new_label();
1816
        l2 = gen_new_label();
1817
        gen_op_jnz_T0_label(l1);
1818
        gen_jmp_im(next_eip);
1819
        gen_op_jmp_label(l2);
1820
        gen_set_label(l1);
1821
        gen_jmp_im(val);
1822
        gen_set_label(l2);
1823
        gen_eob(s);
1824
    }
1825
}
1826

    
1827
static void gen_setcc(DisasContext *s, int b)
1828
{
1829
    int inv, jcc_op;
1830
    GenOpFunc *func;
1831

    
1832
    inv = b & 1;
1833
    jcc_op = (b >> 1) & 7;
1834
    switch(s->cc_op) {
1835
        /* we optimize the cmp/jcc case */
1836
    case CC_OP_SUBB:
1837
    case CC_OP_SUBW:
1838
    case CC_OP_SUBL:
1839
    case CC_OP_SUBQ:
1840
        func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1841
        if (!func)
1842
            goto slow_jcc;
1843
        break;
1844
        
1845
        /* some jumps are easy to compute */
1846
    case CC_OP_ADDB:
1847
    case CC_OP_ADDW:
1848
    case CC_OP_ADDL:
1849
    case CC_OP_ADDQ:
1850

    
1851
    case CC_OP_LOGICB:
1852
    case CC_OP_LOGICW:
1853
    case CC_OP_LOGICL:
1854
    case CC_OP_LOGICQ:
1855

    
1856
    case CC_OP_INCB:
1857
    case CC_OP_INCW:
1858
    case CC_OP_INCL:
1859
    case CC_OP_INCQ:
1860

    
1861
    case CC_OP_DECB:
1862
    case CC_OP_DECW:
1863
    case CC_OP_DECL:
1864
    case CC_OP_DECQ:
1865

    
1866
    case CC_OP_SHLB:
1867
    case CC_OP_SHLW:
1868
    case CC_OP_SHLL:
1869
    case CC_OP_SHLQ:
1870
        switch(jcc_op) {
1871
        case JCC_Z:
1872
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1873
            break;
1874
        case JCC_S:
1875
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1876
            break;
1877
        default:
1878
            goto slow_jcc;
1879
        }
1880
        break;
1881
    default:
1882
    slow_jcc:
1883
        if (s->cc_op != CC_OP_DYNAMIC)
1884
            gen_op_set_cc_op(s->cc_op);
1885
        func = gen_setcc_slow[jcc_op];
1886
        break;
1887
    }
1888
    func();
1889
    if (inv) {
1890
        gen_op_xor_T0_1();
1891
    }
1892
}
1893

    
1894
/* move T0 to seg_reg and compute if the CPU state may change. Never
1895
   call this function with seg_reg == R_CS */
1896
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1897
{
1898
    if (s->pe && !s->vm86) {
1899
        /* XXX: optimize by finding processor state dynamically */
1900
        if (s->cc_op != CC_OP_DYNAMIC)
1901
            gen_op_set_cc_op(s->cc_op);
1902
        gen_jmp_im(cur_eip);
1903
        gen_op_movl_seg_T0(seg_reg);
1904
        /* abort translation because the addseg value may change or
1905
           because ss32 may change. For R_SS, translation must always
1906
           stop as a special handling must be done to disable hardware
1907
           interrupts for the next instruction */
1908
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
1909
            s->is_jmp = 3;
1910
    } else {
1911
        gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
1912
        if (seg_reg == R_SS)
1913
            s->is_jmp = 3;
1914
    }
1915
}
1916

    
1917
static inline void gen_stack_update(DisasContext *s, int addend)
1918
{
1919
#ifdef TARGET_X86_64
1920
    if (CODE64(s)) {
1921
        if (addend == 8)
1922
            gen_op_addq_ESP_8();
1923
        else 
1924
            gen_op_addq_ESP_im(addend);
1925
    } else
1926
#endif
1927
    if (s->ss32) {
1928
        if (addend == 2)
1929
            gen_op_addl_ESP_2();
1930
        else if (addend == 4)
1931
            gen_op_addl_ESP_4();
1932
        else 
1933
            gen_op_addl_ESP_im(addend);
1934
    } else {
1935
        if (addend == 2)
1936
            gen_op_addw_ESP_2();
1937
        else if (addend == 4)
1938
            gen_op_addw_ESP_4();
1939
        else
1940
            gen_op_addw_ESP_im(addend);
1941
    }
1942
}
1943

    
1944
/* generate a push. It depends on ss32, addseg and dflag */
1945
static void gen_push_T0(DisasContext *s)
1946
{
1947
#ifdef TARGET_X86_64
1948
    if (CODE64(s)) {
1949
        /* XXX: check 16 bit behaviour */
1950
        gen_op_movq_A0_reg[R_ESP]();
1951
        gen_op_subq_A0_8();
1952
        gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1953
        gen_op_movq_ESP_A0();
1954
    } else 
1955
#endif
1956
    {
1957
        gen_op_movl_A0_reg[R_ESP]();
1958
        if (!s->dflag)
1959
            gen_op_subl_A0_2();
1960
        else
1961
            gen_op_subl_A0_4();
1962
        if (s->ss32) {
1963
            if (s->addseg) {
1964
                gen_op_movl_T1_A0();
1965
                gen_op_addl_A0_SS();
1966
            }
1967
        } else {
1968
            gen_op_andl_A0_ffff();
1969
            gen_op_movl_T1_A0();
1970
            gen_op_addl_A0_SS();
1971
        }
1972
        gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
1973
        if (s->ss32 && !s->addseg)
1974
            gen_op_movl_ESP_A0();
1975
        else
1976
            gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
1977
    }
1978
}
1979

    
1980
/* generate a push. It depends on ss32, addseg and dflag */
1981
/* slower version for T1, only used for call Ev */
1982
static void gen_push_T1(DisasContext *s)
1983
{
1984
#ifdef TARGET_X86_64
1985
    if (CODE64(s)) {
1986
        /* XXX: check 16 bit behaviour */
1987
        gen_op_movq_A0_reg[R_ESP]();
1988
        gen_op_subq_A0_8();
1989
        gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
1990
        gen_op_movq_ESP_A0();
1991
    } else 
1992
#endif
1993
    {
1994
        gen_op_movl_A0_reg[R_ESP]();
1995
        if (!s->dflag)
1996
            gen_op_subl_A0_2();
1997
        else
1998
            gen_op_subl_A0_4();
1999
        if (s->ss32) {
2000
            if (s->addseg) {
2001
                gen_op_addl_A0_SS();
2002
            }
2003
        } else {
2004
            gen_op_andl_A0_ffff();
2005
            gen_op_addl_A0_SS();
2006
        }
2007
        gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
2008
        
2009
        if (s->ss32 && !s->addseg)
2010
            gen_op_movl_ESP_A0();
2011
        else
2012
            gen_stack_update(s, (-2) << s->dflag);
2013
    }
2014
}
2015

    
2016
/* two step pop is necessary for precise exceptions */
2017
static void gen_pop_T0(DisasContext *s)
2018
{
2019
#ifdef TARGET_X86_64
2020
    if (CODE64(s)) {
2021
        /* XXX: check 16 bit behaviour */
2022
        gen_op_movq_A0_reg[R_ESP]();
2023
        gen_op_ld_T0_A0[OT_QUAD + s->mem_index]();
2024
    } else 
2025
#endif
2026
    {
2027
        gen_op_movl_A0_reg[R_ESP]();
2028
        if (s->ss32) {
2029
            if (s->addseg)
2030
                gen_op_addl_A0_SS();
2031
        } else {
2032
            gen_op_andl_A0_ffff();
2033
            gen_op_addl_A0_SS();
2034
        }
2035
        gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
2036
    }
2037
}
2038

    
2039
static void gen_pop_update(DisasContext *s)
2040
{
2041
#ifdef TARGET_X86_64
2042
    if (CODE64(s)) {
2043
        gen_stack_update(s, 8);
2044
    } else
2045
#endif
2046
    {
2047
        gen_stack_update(s, 2 << s->dflag);
2048
    }
2049
}
2050

    
2051
static void gen_stack_A0(DisasContext *s)
2052
{
2053
    gen_op_movl_A0_ESP();
2054
    if (!s->ss32)
2055
        gen_op_andl_A0_ffff();
2056
    gen_op_movl_T1_A0();
2057
    if (s->addseg)
2058
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2059
}
2060

    
2061
/* NOTE: wrap around in 16 bit not fully handled */
2062
static void gen_pusha(DisasContext *s)
2063
{
2064
    int i;
2065
    gen_op_movl_A0_ESP();
2066
    gen_op_addl_A0_im(-16 <<  s->dflag);
2067
    if (!s->ss32)
2068
        gen_op_andl_A0_ffff();
2069
    gen_op_movl_T1_A0();
2070
    if (s->addseg)
2071
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2072
    for(i = 0;i < 8; i++) {
2073
        gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
2074
        gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
2075
        gen_op_addl_A0_im(2 <<  s->dflag);
2076
    }
2077
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2078
}
2079

    
2080
/* NOTE: wrap around in 16 bit not fully handled */
2081
static void gen_popa(DisasContext *s)
2082
{
2083
    int i;
2084
    gen_op_movl_A0_ESP();
2085
    if (!s->ss32)
2086
        gen_op_andl_A0_ffff();
2087
    gen_op_movl_T1_A0();
2088
    gen_op_addl_T1_im(16 <<  s->dflag);
2089
    if (s->addseg)
2090
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2091
    for(i = 0;i < 8; i++) {
2092
        /* ESP is not reloaded */
2093
        if (i != 3) {
2094
            gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
2095
            gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
2096
        }
2097
        gen_op_addl_A0_im(2 <<  s->dflag);
2098
    }
2099
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2100
}
2101

    
2102
static void gen_enter(DisasContext *s, int esp_addend, int level)
2103
{
2104
    int ot, opsize;
2105

    
2106
    ot = s->dflag + OT_WORD;
2107
    level &= 0x1f;
2108
    opsize = 2 << s->dflag;
2109

    
2110
    gen_op_movl_A0_ESP();
2111
    gen_op_addl_A0_im(-opsize);
2112
    if (!s->ss32)
2113
        gen_op_andl_A0_ffff();
2114
    gen_op_movl_T1_A0();
2115
    if (s->addseg)
2116
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2117
    /* push bp */
2118
    gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2119
    gen_op_st_T0_A0[ot + s->mem_index]();
2120
    if (level) {
2121
        gen_op_enter_level(level, s->dflag);
2122
    }
2123
    gen_op_mov_reg_T1[ot][R_EBP]();
2124
    gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2125
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2126
}
2127

    
2128
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2129
{
2130
    if (s->cc_op != CC_OP_DYNAMIC)
2131
        gen_op_set_cc_op(s->cc_op);
2132
    gen_jmp_im(cur_eip);
2133
    gen_op_raise_exception(trapno);
2134
    s->is_jmp = 3;
2135
}
2136

    
2137
/* an interrupt is different from an exception because of the
2138
   priviledge checks */
2139
static void gen_interrupt(DisasContext *s, int intno, 
2140
                          target_ulong cur_eip, target_ulong next_eip)
2141
{
2142
    if (s->cc_op != CC_OP_DYNAMIC)
2143
        gen_op_set_cc_op(s->cc_op);
2144
    gen_jmp_im(cur_eip);
2145
    gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip));
2146
    s->is_jmp = 3;
2147
}
2148

    
2149
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2150
{
2151
    if (s->cc_op != CC_OP_DYNAMIC)
2152
        gen_op_set_cc_op(s->cc_op);
2153
    gen_jmp_im(cur_eip);
2154
    gen_op_debug();
2155
    s->is_jmp = 3;
2156
}
2157

    
2158
/* generate a generic end of block. Trace exception is also generated
2159
   if needed */
2160
static void gen_eob(DisasContext *s)
2161
{
2162
    if (s->cc_op != CC_OP_DYNAMIC)
2163
        gen_op_set_cc_op(s->cc_op);
2164
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2165
        gen_op_reset_inhibit_irq();
2166
    }
2167
    if (s->singlestep_enabled) {
2168
        gen_op_debug();
2169
    } else if (s->tf) {
2170
        gen_op_raise_exception(EXCP01_SSTP);
2171
    } else {
2172
        gen_op_movl_T0_0();
2173
        gen_op_exit_tb();
2174
    }
2175
    s->is_jmp = 3;
2176
}
2177

    
2178
/* generate a jump to eip. No segment change must happen before as a
2179
   direct call to the next block may occur */
2180
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2181
{
2182
    TranslationBlock *tb = s->tb;
2183

    
2184
    if (s->jmp_opt) {
2185
        if (s->cc_op != CC_OP_DYNAMIC)
2186
            gen_op_set_cc_op(s->cc_op);
2187
        if (tb_num)
2188
            gen_op_goto_tb1(TBPARAM(tb));
2189
        else
2190
            gen_op_goto_tb0(TBPARAM(tb));
2191
        gen_jmp_im(eip);
2192
        gen_op_movl_T0_im((long)tb + tb_num);
2193
        gen_op_exit_tb();
2194
        s->is_jmp = 3;
2195
    } else {
2196
        gen_jmp_im(eip);
2197
        gen_eob(s);
2198
    }
2199
}
2200

    
2201
static void gen_jmp(DisasContext *s, target_ulong eip)
2202
{
2203
    gen_jmp_tb(s, eip, 0);
2204
}
2205

    
2206
static void gen_movtl_T0_im(target_ulong val)
2207
{
2208
#ifdef TARGET_X86_64    
2209
    if ((int32_t)val == val) {
2210
        gen_op_movl_T0_im(val);
2211
    } else {
2212
        gen_op_movq_T0_im64(val >> 32, val);
2213
    }
2214
#else
2215
    gen_op_movl_T0_im(val);
2216
#endif
2217
}
2218

    
2219
static void gen_movtl_T1_im(target_ulong val)
2220
{
2221
#ifdef TARGET_X86_64    
2222
    if ((int32_t)val == val) {
2223
        gen_op_movl_T1_im(val);
2224
    } else {
2225
        gen_op_movq_T1_im64(val >> 32, val);
2226
    }
2227
#else
2228
    gen_op_movl_T1_im(val);
2229
#endif
2230
}
2231

    
2232
static GenOpFunc1 *gen_ldq_env_A0[3] = {
2233
    gen_op_ldq_raw_env_A0,
2234
#ifndef CONFIG_USER_ONLY
2235
    gen_op_ldq_kernel_env_A0,
2236
    gen_op_ldq_user_env_A0,
2237
#endif
2238
};
2239

    
2240
static GenOpFunc1 *gen_stq_env_A0[3] = {
2241
    gen_op_stq_raw_env_A0,
2242
#ifndef CONFIG_USER_ONLY
2243
    gen_op_stq_kernel_env_A0,
2244
    gen_op_stq_user_env_A0,
2245
#endif
2246
};
2247

    
2248
static GenOpFunc1 *gen_ldo_env_A0[3] = {
2249
    gen_op_ldo_raw_env_A0,
2250
#ifndef CONFIG_USER_ONLY
2251
    gen_op_ldo_kernel_env_A0,
2252
    gen_op_ldo_user_env_A0,
2253
#endif
2254
};
2255

    
2256
static GenOpFunc1 *gen_sto_env_A0[3] = {
2257
    gen_op_sto_raw_env_A0,
2258
#ifndef CONFIG_USER_ONLY
2259
    gen_op_sto_kernel_env_A0,
2260
    gen_op_sto_user_env_A0,
2261
#endif
2262
};
2263

    
2264
#define SSE_SPECIAL ((GenOpFunc2 *)1)
2265

    
2266
#define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
2267
#define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
2268
                     gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
2269

    
2270
static GenOpFunc2 *sse_op_table1[256][4] = {
2271
    /* pure SSE operations */
2272
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2273
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2274
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2275
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2276
    [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
2277
    [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
2278
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2279
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2280

    
2281
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2282
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2283
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2284
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2285
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2286
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2287
    [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
2288
    [0x2f] = { gen_op_comiss, gen_op_comisd },
2289
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2290
    [0x51] = SSE_FOP(sqrt),
2291
    [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
2292
    [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
2293
    [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
2294
    [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
2295
    [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
2296
    [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
2297
    [0x58] = SSE_FOP(add),
2298
    [0x59] = SSE_FOP(mul),
2299
    [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps, 
2300
               gen_op_cvtss2sd, gen_op_cvtsd2ss },
2301
    [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
2302
    [0x5c] = SSE_FOP(sub),
2303
    [0x5d] = SSE_FOP(min),
2304
    [0x5e] = SSE_FOP(div),
2305
    [0x5f] = SSE_FOP(max),
2306

    
2307
    [0xc2] = SSE_FOP(cmpeq),
2308
    [0xc6] = { (GenOpFunc2 *)gen_op_shufps, (GenOpFunc2 *)gen_op_shufpd },
2309

    
2310
    /* MMX ops and their SSE extensions */
2311
    [0x60] = MMX_OP2(punpcklbw),
2312
    [0x61] = MMX_OP2(punpcklwd),
2313
    [0x62] = MMX_OP2(punpckldq),
2314
    [0x63] = MMX_OP2(packsswb),
2315
    [0x64] = MMX_OP2(pcmpgtb),
2316
    [0x65] = MMX_OP2(pcmpgtw),
2317
    [0x66] = MMX_OP2(pcmpgtl),
2318
    [0x67] = MMX_OP2(packuswb),
2319
    [0x68] = MMX_OP2(punpckhbw),
2320
    [0x69] = MMX_OP2(punpckhwd),
2321
    [0x6a] = MMX_OP2(punpckhdq),
2322
    [0x6b] = MMX_OP2(packssdw),
2323
    [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
2324
    [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
2325
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2326
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2327
    [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx, 
2328
               (GenOpFunc2 *)gen_op_pshufd_xmm, 
2329
               (GenOpFunc2 *)gen_op_pshufhw_xmm, 
2330
               (GenOpFunc2 *)gen_op_pshuflw_xmm },
2331
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2332
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2333
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2334
    [0x74] = MMX_OP2(pcmpeqb),
2335
    [0x75] = MMX_OP2(pcmpeqw),
2336
    [0x76] = MMX_OP2(pcmpeql),
2337
    [0x77] = { SSE_SPECIAL }, /* emms */
2338
    [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
2339
    [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
2340
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2341
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2342
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2343
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2344
    [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
2345
    [0xd1] = MMX_OP2(psrlw),
2346
    [0xd2] = MMX_OP2(psrld),
2347
    [0xd3] = MMX_OP2(psrlq),
2348
    [0xd4] = MMX_OP2(paddq),
2349
    [0xd5] = MMX_OP2(pmullw),
2350
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2351
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2352
    [0xd8] = MMX_OP2(psubusb),
2353
    [0xd9] = MMX_OP2(psubusw),
2354
    [0xda] = MMX_OP2(pminub),
2355
    [0xdb] = MMX_OP2(pand),
2356
    [0xdc] = MMX_OP2(paddusb),
2357
    [0xdd] = MMX_OP2(paddusw),
2358
    [0xde] = MMX_OP2(pmaxub),
2359
    [0xdf] = MMX_OP2(pandn),
2360
    [0xe0] = MMX_OP2(pavgb),
2361
    [0xe1] = MMX_OP2(psraw),
2362
    [0xe2] = MMX_OP2(psrad),
2363
    [0xe3] = MMX_OP2(pavgw),
2364
    [0xe4] = MMX_OP2(pmulhuw),
2365
    [0xe5] = MMX_OP2(pmulhw),
2366
    [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
2367
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2368
    [0xe8] = MMX_OP2(psubsb),
2369
    [0xe9] = MMX_OP2(psubsw),
2370
    [0xea] = MMX_OP2(pminsw),
2371
    [0xeb] = MMX_OP2(por),
2372
    [0xec] = MMX_OP2(paddsb),
2373
    [0xed] = MMX_OP2(paddsw),
2374
    [0xee] = MMX_OP2(pmaxsw),
2375
    [0xef] = MMX_OP2(pxor),
2376
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu (PNI) */
2377
    [0xf1] = MMX_OP2(psllw),
2378
    [0xf2] = MMX_OP2(pslld),
2379
    [0xf3] = MMX_OP2(psllq),
2380
    [0xf4] = MMX_OP2(pmuludq),
2381
    [0xf5] = MMX_OP2(pmaddwd),
2382
    [0xf6] = MMX_OP2(psadbw),
2383
    [0xf7] = MMX_OP2(maskmov),
2384
    [0xf8] = MMX_OP2(psubb),
2385
    [0xf9] = MMX_OP2(psubw),
2386
    [0xfa] = MMX_OP2(psubl),
2387
    [0xfb] = MMX_OP2(psubq),
2388
    [0xfc] = MMX_OP2(paddb),
2389
    [0xfd] = MMX_OP2(paddw),
2390
    [0xfe] = MMX_OP2(paddl),
2391
};
2392

    
2393
static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
2394
    [0 + 2] = MMX_OP2(psrlw),
2395
    [0 + 4] = MMX_OP2(psraw),
2396
    [0 + 6] = MMX_OP2(psllw),
2397
    [8 + 2] = MMX_OP2(psrld),
2398
    [8 + 4] = MMX_OP2(psrad),
2399
    [8 + 6] = MMX_OP2(pslld),
2400
    [16 + 2] = MMX_OP2(psrlq),
2401
    [16 + 3] = { NULL, gen_op_psrldq_xmm },
2402
    [16 + 6] = MMX_OP2(psllq),
2403
    [16 + 7] = { NULL, gen_op_pslldq_xmm },
2404
};
2405

    
2406
static GenOpFunc1 *sse_op_table3[4 * 3] = {
2407
    gen_op_cvtsi2ss,
2408
    gen_op_cvtsi2sd,
2409
    X86_64_ONLY(gen_op_cvtsq2ss),
2410
    X86_64_ONLY(gen_op_cvtsq2sd),
2411
    
2412
    gen_op_cvttss2si,
2413
    gen_op_cvttsd2si,
2414
    X86_64_ONLY(gen_op_cvttss2sq),
2415
    X86_64_ONLY(gen_op_cvttsd2sq),
2416

    
2417
    gen_op_cvtss2si,
2418
    gen_op_cvtsd2si,
2419
    X86_64_ONLY(gen_op_cvtss2sq),
2420
    X86_64_ONLY(gen_op_cvtsd2sq),
2421
};
2422
    
2423
static GenOpFunc2 *sse_op_table4[8][4] = {
2424
    SSE_FOP(cmpeq),
2425
    SSE_FOP(cmplt),
2426
    SSE_FOP(cmple),
2427
    SSE_FOP(cmpunord),
2428
    SSE_FOP(cmpneq),
2429
    SSE_FOP(cmpnlt),
2430
    SSE_FOP(cmpnle),
2431
    SSE_FOP(cmpord),
2432
};
2433
    
2434
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2435
{
2436
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
2437
    int modrm, mod, rm, reg, reg_addr, offset_addr;
2438
    GenOpFunc2 *sse_op2;
2439
    GenOpFunc3 *sse_op3;
2440

    
2441
    b &= 0xff;
2442
    if (s->prefix & PREFIX_DATA) 
2443
        b1 = 1;
2444
    else if (s->prefix & PREFIX_REPZ) 
2445
        b1 = 2;
2446
    else if (s->prefix & PREFIX_REPNZ) 
2447
        b1 = 3;
2448
    else
2449
        b1 = 0;
2450
    sse_op2 = sse_op_table1[b][b1];
2451
    if (!sse_op2) 
2452
        goto illegal_op;
2453
    if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
2454
        is_xmm = 1;
2455
    } else {
2456
        if (b1 == 0) {
2457
            /* MMX case */
2458
            is_xmm = 0;
2459
        } else {
2460
            is_xmm = 1;
2461
        }
2462
    }
2463
    /* simple MMX/SSE operation */
2464
    if (s->flags & HF_TS_MASK) {
2465
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2466
        return;
2467
    }
2468
    if (s->flags & HF_EM_MASK) {
2469
    illegal_op:
2470
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2471
        return;
2472
    }
2473
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2474
        goto illegal_op;
2475
    if (b == 0x77) {
2476
        /* emms */
2477
        gen_op_emms();
2478
        return;
2479
    }
2480
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2481
       the static cpu state) */
2482
    if (!is_xmm) {
2483
        gen_op_enter_mmx();
2484
    }
2485

    
2486
    modrm = ldub_code(s->pc++);
2487
    reg = ((modrm >> 3) & 7);
2488
    if (is_xmm)
2489
        reg |= rex_r;
2490
    mod = (modrm >> 6) & 3;
2491
    if (sse_op2 == SSE_SPECIAL) {
2492
        b |= (b1 << 8);
2493
        switch(b) {
2494
        case 0x0e7: /* movntq */
2495
            if (mod == 3) 
2496
                goto illegal_op;
2497
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2498
            gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2499
            break;
2500
        case 0x1e7: /* movntdq */
2501
        case 0x02b: /* movntps */
2502
        case 0x12b: /* movntps */
2503
        case 0x2f0: /* lddqu */
2504
            if (mod == 3) 
2505
                goto illegal_op;
2506
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2507
            gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2508
            break;
2509
        case 0x6e: /* movd mm, ea */
2510
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2511
            gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2512
            break;
2513
        case 0x16e: /* movd xmm, ea */
2514
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2515
            gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2516
            break;
2517
        case 0x6f: /* movq mm, ea */
2518
            if (mod != 3) {
2519
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2520
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2521
            } else {
2522
                rm = (modrm & 7);
2523
                gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
2524
                            offsetof(CPUX86State,fpregs[rm].mmx));
2525
            }
2526
            break;
2527
        case 0x010: /* movups */
2528
        case 0x110: /* movupd */
2529
        case 0x028: /* movaps */
2530
        case 0x128: /* movapd */
2531
        case 0x16f: /* movdqa xmm, ea */
2532
        case 0x26f: /* movdqu xmm, ea */
2533
            if (mod != 3) {
2534
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2535
                gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2536
            } else {
2537
                rm = (modrm & 7) | REX_B(s);
2538
                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),
2539
                            offsetof(CPUX86State,xmm_regs[rm]));
2540
            }
2541
            break;
2542
        case 0x210: /* movss xmm, ea */
2543
            if (mod != 3) {
2544
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2545
                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2546
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2547
                gen_op_movl_T0_0();
2548
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2549
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2550
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2551
            } else {
2552
                rm = (modrm & 7) | REX_B(s);
2553
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2554
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2555
            }
2556
            break;
2557
        case 0x310: /* movsd xmm, ea */
2558
            if (mod != 3) {
2559
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2560
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2561
                gen_op_movl_T0_0();
2562
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2563
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2564
            } else {
2565
                rm = (modrm & 7) | REX_B(s);
2566
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2567
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2568
            }
2569
            break;
2570
        case 0x012: /* movlps */
2571
        case 0x112: /* movlpd */
2572
            if (mod != 3) {
2573
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2574
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2575
            } else {
2576
                /* movhlps */
2577
                rm = (modrm & 7) | REX_B(s);
2578
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2579
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2580
            }
2581
            break;
2582
        case 0x016: /* movhps */
2583
        case 0x116: /* movhpd */
2584
            if (mod != 3) {
2585
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2586
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2587
            } else {
2588
                /* movlhps */
2589
                rm = (modrm & 7) | REX_B(s);
2590
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2591
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2592
            }
2593
            break;
2594
        case 0x216: /* movshdup */
2595
            if (mod != 3) {
2596
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2597
                gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2598
            } else {
2599
                rm = (modrm & 7) | REX_B(s);
2600
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2601
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
2602
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2603
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
2604
            }
2605
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2606
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2607
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2608
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2609
            break;
2610
        case 0x7e: /* movd ea, mm */
2611
            gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2612
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2613
            break;
2614
        case 0x17e: /* movd ea, xmm */
2615
            gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2616
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2617
            break;
2618
        case 0x27e: /* movq xmm, ea */
2619
            if (mod != 3) {
2620
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2621
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2622
            } else {
2623
                rm = (modrm & 7) | REX_B(s);
2624
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2625
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2626
            }
2627
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2628
            break;
2629
        case 0x7f: /* movq ea, mm */
2630
            if (mod != 3) {
2631
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2632
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2633
            } else {
2634
                rm = (modrm & 7);
2635
                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2636
                            offsetof(CPUX86State,fpregs[reg].mmx));
2637
            }
2638
            break;
2639
        case 0x011: /* movups */
2640
        case 0x111: /* movupd */
2641
        case 0x029: /* movaps */
2642
        case 0x129: /* movapd */
2643
        case 0x17f: /* movdqa ea, xmm */
2644
        case 0x27f: /* movdqu ea, xmm */
2645
            if (mod != 3) {
2646
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2647
                gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2648
            } else {
2649
                rm = (modrm & 7) | REX_B(s);
2650
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
2651
                            offsetof(CPUX86State,xmm_regs[reg]));
2652
            }
2653
            break;
2654
        case 0x211: /* movss ea, xmm */
2655
            if (mod != 3) {
2656
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2657
                gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2658
                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
2659
            } else {
2660
                rm = (modrm & 7) | REX_B(s);
2661
                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
2662
                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2663
            }
2664
            break;
2665
        case 0x311: /* movsd ea, xmm */
2666
            if (mod != 3) {
2667
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2668
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2669
            } else {
2670
                rm = (modrm & 7) | REX_B(s);
2671
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2672
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2673
            }
2674
            break;
2675
        case 0x013: /* movlps */
2676
        case 0x113: /* movlpd */
2677
            if (mod != 3) {
2678
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2679
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2680
            } else {
2681
                goto illegal_op;
2682
            }
2683
            break;
2684
        case 0x017: /* movhps */
2685
        case 0x117: /* movhpd */
2686
            if (mod != 3) {
2687
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2688
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2689
            } else {
2690
                goto illegal_op;
2691
            }
2692
            break;
2693
        case 0x71: /* shift mm, im */
2694
        case 0x72:
2695
        case 0x73:
2696
        case 0x171: /* shift xmm, im */
2697
        case 0x172:
2698
        case 0x173:
2699
            val = ldub_code(s->pc++);
2700
            if (is_xmm) {
2701
                gen_op_movl_T0_im(val);
2702
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2703
                gen_op_movl_T0_0();
2704
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
2705
                op1_offset = offsetof(CPUX86State,xmm_t0);
2706
            } else {
2707
                gen_op_movl_T0_im(val);
2708
                gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
2709
                gen_op_movl_T0_0();
2710
                gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
2711
                op1_offset = offsetof(CPUX86State,mmx_t0);
2712
            }
2713
            sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
2714
            if (!sse_op2)
2715
                goto illegal_op;
2716
            if (is_xmm) {
2717
                rm = (modrm & 7) | REX_B(s);
2718
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2719
            } else {
2720
                rm = (modrm & 7);
2721
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2722
            }
2723
            sse_op2(op2_offset, op1_offset);
2724
            break;
2725
        case 0x050: /* movmskps */
2726
            gen_op_movmskps(offsetof(CPUX86State,xmm_regs[reg]));
2727
            rm = (modrm & 7) | REX_B(s);
2728
            gen_op_mov_reg_T0[OT_LONG][rm]();
2729
            break;
2730
        case 0x150: /* movmskpd */
2731
            gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[reg]));
2732
            rm = (modrm & 7) | REX_B(s);
2733
            gen_op_mov_reg_T0[OT_LONG][rm]();
2734
            break;
2735
        case 0x02a: /* cvtpi2ps */
2736
        case 0x12a: /* cvtpi2pd */
2737
            gen_op_enter_mmx();
2738
            if (mod != 3) {
2739
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2740
                op2_offset = offsetof(CPUX86State,mmx_t0);
2741
                gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
2742
            } else {
2743
                rm = (modrm & 7);
2744
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2745
            }
2746
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2747
            switch(b >> 8) {
2748
            case 0x0:
2749
                gen_op_cvtpi2ps(op1_offset, op2_offset);
2750
                break;
2751
            default:
2752
            case 0x1:
2753
                gen_op_cvtpi2pd(op1_offset, op2_offset);
2754
                break;
2755
            }
2756
            break;
2757
        case 0x22a: /* cvtsi2ss */
2758
        case 0x32a: /* cvtsi2sd */
2759
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2760
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2761
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2762
            sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
2763
            break;
2764
        case 0x02c: /* cvttps2pi */
2765
        case 0x12c: /* cvttpd2pi */
2766
        case 0x02d: /* cvtps2pi */
2767
        case 0x12d: /* cvtpd2pi */
2768
            gen_op_enter_mmx();
2769
            if (mod != 3) {
2770
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2771
                op2_offset = offsetof(CPUX86State,xmm_t0);
2772
                gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
2773
            } else {
2774
                rm = (modrm & 7) | REX_B(s);
2775
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2776
            }
2777
            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
2778
            switch(b) {
2779
            case 0x02c:
2780
                gen_op_cvttps2pi(op1_offset, op2_offset);
2781
                break;
2782
            case 0x12c:
2783
                gen_op_cvttpd2pi(op1_offset, op2_offset);
2784
                break;
2785
            case 0x02d:
2786
                gen_op_cvtps2pi(op1_offset, op2_offset);
2787
                break;
2788
            case 0x12d:
2789
                gen_op_cvtpd2pi(op1_offset, op2_offset);
2790
                break;
2791
            }
2792
            break;
2793
        case 0x22c: /* cvttss2si */
2794
        case 0x32c: /* cvttsd2si */
2795
        case 0x22d: /* cvtss2si */
2796
        case 0x32d: /* cvtsd2si */
2797
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2798
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2799
            sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 + 
2800
                          (b & 1) * 4](op1_offset);
2801
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2802
            break;
2803
        case 0xc4: /* pinsrw */
2804
        case 0x1c4: 
2805
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
2806
            val = ldub_code(s->pc++);
2807
            if (b1) {
2808
                val &= 7;
2809
                gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
2810
            } else {
2811
                val &= 3;
2812
                gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
2813
            }
2814
            break;
2815
        case 0xc5: /* pextrw */
2816
        case 0x1c5: 
2817
            if (mod != 3)
2818
                goto illegal_op;
2819
            val = ldub_code(s->pc++);
2820
            if (b1) {
2821
                val &= 7;
2822
                rm = (modrm & 7) | REX_B(s);
2823
                gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
2824
            } else {
2825
                val &= 3;
2826
                rm = (modrm & 7);
2827
                gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
2828
            }
2829
            reg = ((modrm >> 3) & 7) | rex_r;
2830
            gen_op_mov_reg_T0[OT_LONG][reg]();
2831
            break;
2832
        case 0x1d6: /* movq ea, xmm */
2833
            if (mod != 3) {
2834
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2835
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2836
            } else {
2837
                rm = (modrm & 7) | REX_B(s);
2838
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2839
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2840
                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2841
            }
2842
            break;
2843
        case 0x2d6: /* movq2dq */
2844
            gen_op_enter_mmx();
2845
            rm = (modrm & 7) | REX_B(s);
2846
            gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2847
                        offsetof(CPUX86State,fpregs[reg & 7].mmx));
2848
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2849
            break;
2850
        case 0x3d6: /* movdq2q */
2851
            gen_op_enter_mmx();
2852
            rm = (modrm & 7);
2853
            gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2854
                        offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2855
            break;
2856
        case 0xd7: /* pmovmskb */
2857
        case 0x1d7:
2858
            if (mod != 3)
2859
                goto illegal_op;
2860
            if (b1) {
2861
                rm = (modrm & 7) | REX_B(s);
2862
                gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
2863
            } else {
2864
                rm = (modrm & 7);
2865
                gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
2866
            }
2867
            reg = ((modrm >> 3) & 7) | rex_r;
2868
            gen_op_mov_reg_T0[OT_LONG][reg]();
2869
            break;
2870
        default:
2871
            goto illegal_op;
2872
        }
2873
    } else {
2874
        /* generic MMX or SSE operation */
2875
        if (b == 0xf7) {
2876
            /* maskmov : we must prepare A0 */
2877
            if (mod != 3) 
2878
                goto illegal_op;
2879
#ifdef TARGET_X86_64
2880
            if (CODE64(s)) {
2881
                gen_op_movq_A0_reg[R_EDI]();
2882
            } else 
2883
#endif
2884
            {
2885
                gen_op_movl_A0_reg[R_EDI]();
2886
                if (s->aflag == 0)
2887
                    gen_op_andl_A0_ffff();
2888
            }
2889
            gen_add_A0_ds_seg(s);
2890
        }
2891
        if (is_xmm) {
2892
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2893
            if (mod != 3) {
2894
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2895
                op2_offset = offsetof(CPUX86State,xmm_t0);
2896
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f) ||
2897
                                b == 0xc2)) {
2898
                    /* specific case for SSE single instructions */
2899
                    if (b1 == 2) {
2900
                        /* 32 bit access */
2901
                        gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2902
                        gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2903
                    } else {
2904
                        /* 64 bit access */
2905
                        gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
2906
                    }
2907
                } else {
2908
                    gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
2909
                }
2910
            } else {
2911
                rm = (modrm & 7) | REX_B(s);
2912
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2913
            }
2914
        } else {
2915
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
2916
            if (mod != 3) {
2917
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2918
                op2_offset = offsetof(CPUX86State,mmx_t0);
2919
                gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
2920
            } else {
2921
                rm = (modrm & 7);
2922
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2923
            }
2924
        }
2925
        switch(b) {
2926
        case 0x70: /* pshufx insn */
2927
        case 0xc6: /* pshufx insn */
2928
            val = ldub_code(s->pc++);
2929
            sse_op3 = (GenOpFunc3 *)sse_op2;
2930
            sse_op3(op1_offset, op2_offset, val);
2931
            break;
2932
        case 0xc2:
2933
            /* compare insns */
2934
            val = ldub_code(s->pc++);
2935
            if (val >= 8)
2936
                goto illegal_op;
2937
            sse_op2 = sse_op_table4[val][b1];
2938
            sse_op2(op1_offset, op2_offset);
2939
            break;
2940
        default:
2941
            sse_op2(op1_offset, op2_offset);
2942
            break;
2943
        }
2944
        if (b == 0x2e || b == 0x2f) {
2945
            s->cc_op = CC_OP_EFLAGS;
2946
        }
2947
    }
2948
}
2949

    
2950

    
2951
/* convert one instruction. s->is_jmp is set if the translation must
2952
   be stopped. Return the next pc value */
2953
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
2954
{
2955
    int b, prefixes, aflag, dflag;
2956
    int shift, ot;
2957
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
2958
    target_ulong next_eip, tval;
2959
    int rex_w, rex_r;
2960

    
2961
    s->pc = pc_start;
2962
    prefixes = 0;
2963
    aflag = s->code32;
2964
    dflag = s->code32;
2965
    s->override = -1;
2966
    rex_w = -1;
2967
    rex_r = 0;
2968
#ifdef TARGET_X86_64
2969
    s->rex_x = 0;
2970
    s->rex_b = 0;
2971
    x86_64_hregs = 0; 
2972
#endif
2973
    s->rip_offset = 0; /* for relative ip address */
2974
 next_byte:
2975
    b = ldub_code(s->pc);
2976
    s->pc++;
2977
    /* check prefixes */
2978
#ifdef TARGET_X86_64
2979
    if (CODE64(s)) {
2980
        switch (b) {
2981
        case 0xf3:
2982
            prefixes |= PREFIX_REPZ;
2983
            goto next_byte;
2984
        case 0xf2:
2985
            prefixes |= PREFIX_REPNZ;
2986
            goto next_byte;
2987
        case 0xf0:
2988
            prefixes |= PREFIX_LOCK;
2989
            goto next_byte;
2990
        case 0x2e:
2991
            s->override = R_CS;
2992
            goto next_byte;
2993
        case 0x36:
2994
            s->override = R_SS;
2995
            goto next_byte;
2996
        case 0x3e:
2997
            s->override = R_DS;
2998
            goto next_byte;
2999
        case 0x26:
3000
            s->override = R_ES;
3001
            goto next_byte;
3002
        case 0x64:
3003
            s->override = R_FS;
3004
            goto next_byte;
3005
        case 0x65:
3006
            s->override = R_GS;
3007
            goto next_byte;
3008
        case 0x66:
3009
            prefixes |= PREFIX_DATA;
3010
            goto next_byte;
3011
        case 0x67:
3012
            prefixes |= PREFIX_ADR;
3013
            goto next_byte;
3014
        case 0x40 ... 0x4f:
3015
            /* REX prefix */
3016
            rex_w = (b >> 3) & 1;
3017
            rex_r = (b & 0x4) << 1;
3018
            s->rex_x = (b & 0x2) << 2;
3019
            REX_B(s) = (b & 0x1) << 3;
3020
            x86_64_hregs = 1; /* select uniform byte register addressing */
3021
            goto next_byte;
3022
        }
3023
        if (rex_w == 1) {
3024
            /* 0x66 is ignored if rex.w is set */
3025
            dflag = 2;
3026
        } else {
3027
            if (prefixes & PREFIX_DATA)
3028
                dflag ^= 1;
3029
        }
3030
        if (!(prefixes & PREFIX_ADR))
3031
            aflag = 2;
3032
    } else 
3033
#endif
3034
    {
3035
        switch (b) {
3036
        case 0xf3:
3037
            prefixes |= PREFIX_REPZ;
3038
            goto next_byte;
3039
        case 0xf2:
3040
            prefixes |= PREFIX_REPNZ;
3041
            goto next_byte;
3042
        case 0xf0:
3043
            prefixes |= PREFIX_LOCK;
3044
            goto next_byte;
3045
        case 0x2e:
3046
            s->override = R_CS;
3047
            goto next_byte;
3048
        case 0x36:
3049
            s->override = R_SS;
3050
            goto next_byte;
3051
        case 0x3e:
3052
            s->override = R_DS;
3053
            goto next_byte;
3054
        case 0x26:
3055
            s->override = R_ES;
3056
            goto next_byte;
3057
        case 0x64:
3058
            s->override = R_FS;
3059
            goto next_byte;
3060
        case 0x65:
3061
            s->override = R_GS;
3062
            goto next_byte;
3063
        case 0x66:
3064
            prefixes |= PREFIX_DATA;
3065
            goto next_byte;
3066
        case 0x67:
3067
            prefixes |= PREFIX_ADR;
3068
            goto next_byte;
3069
        }
3070
        if (prefixes & PREFIX_DATA)
3071
            dflag ^= 1;
3072
        if (prefixes & PREFIX_ADR)
3073
            aflag ^= 1;
3074
    }
3075

    
3076
    s->prefix = prefixes;
3077
    s->aflag = aflag;
3078
    s->dflag = dflag;
3079

    
3080
    /* lock generation */
3081
    if (prefixes & PREFIX_LOCK)
3082
        gen_op_lock();
3083

    
3084
    /* now check op code */
3085
 reswitch:
3086
    switch(b) {
3087
    case 0x0f:
3088
        /**************************/
3089
        /* extended op code */
3090
        b = ldub_code(s->pc++) | 0x100;
3091
        goto reswitch;
3092
        
3093
        /**************************/
3094
        /* arith & logic */
3095
    case 0x00 ... 0x05:
3096
    case 0x08 ... 0x0d:
3097
    case 0x10 ... 0x15:
3098
    case 0x18 ... 0x1d:
3099
    case 0x20 ... 0x25:
3100
    case 0x28 ... 0x2d:
3101
    case 0x30 ... 0x35:
3102
    case 0x38 ... 0x3d:
3103
        {
3104
            int op, f, val;
3105
            op = (b >> 3) & 7;
3106
            f = (b >> 1) & 3;
3107

    
3108
            if ((b & 1) == 0)
3109
                ot = OT_BYTE;
3110
            else
3111
                ot = dflag + OT_WORD;
3112
            
3113
            switch(f) {
3114
            case 0: /* OP Ev, Gv */
3115
                modrm = ldub_code(s->pc++);
3116
                reg = ((modrm >> 3) & 7) | rex_r;
3117
                mod = (modrm >> 6) & 3;
3118
                rm = (modrm & 7) | REX_B(s);
3119
                if (mod != 3) {
3120
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3121
                    opreg = OR_TMP0;
3122
                } else if (op == OP_XORL && rm == reg) {
3123
                xor_zero:
3124
                    /* xor reg, reg optimisation */
3125
                    gen_op_movl_T0_0();
3126
                    s->cc_op = CC_OP_LOGICB + ot;
3127
                    gen_op_mov_reg_T0[ot][reg]();
3128
                    gen_op_update1_cc();
3129
                    break;
3130
                } else {
3131
                    opreg = rm;
3132
                }
3133
                gen_op_mov_TN_reg[ot][1][reg]();
3134
                gen_op(s, op, ot, opreg);
3135
                break;
3136
            case 1: /* OP Gv, Ev */
3137
                modrm = ldub_code(s->pc++);
3138
                mod = (modrm >> 6) & 3;
3139
                reg = ((modrm >> 3) & 7) | rex_r;
3140
                rm = (modrm & 7) | REX_B(s);
3141
                if (mod != 3) {
3142
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3143
                    gen_op_ld_T1_A0[ot + s->mem_index]();
3144
                } else if (op == OP_XORL && rm == reg) {
3145
                    goto xor_zero;
3146
                } else {
3147
                    gen_op_mov_TN_reg[ot][1][rm]();
3148
                }
3149
                gen_op(s, op, ot, reg);
3150
                break;
3151
            case 2: /* OP A, Iv */
3152
                val = insn_get(s, ot);
3153
                gen_op_movl_T1_im(val);
3154
                gen_op(s, op, ot, OR_EAX);
3155
                break;
3156
            }
3157
        }
3158
        break;
3159

    
3160
    case 0x80: /* GRP1 */
3161
    case 0x81:
3162
    case 0x82:
3163
    case 0x83:
3164
        {
3165
            int val;
3166

    
3167
            if ((b & 1) == 0)
3168
                ot = OT_BYTE;
3169
            else
3170
                ot = dflag + OT_WORD;
3171
            
3172
            modrm = ldub_code(s->pc++);
3173
            mod = (modrm >> 6) & 3;
3174
            rm = (modrm & 7) | REX_B(s);
3175
            op = (modrm >> 3) & 7;
3176
            
3177
            if (mod != 3) {
3178
                if (b == 0x83)
3179
                    s->rip_offset = 1;
3180
                else
3181
                    s->rip_offset = insn_const_size(ot);
3182
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3183
                opreg = OR_TMP0;
3184
            } else {
3185
                opreg = rm;
3186
            }
3187

    
3188
            switch(b) {
3189
            default:
3190
            case 0x80:
3191
            case 0x81:
3192
            case 0x82:
3193
                val = insn_get(s, ot);
3194
                break;
3195
            case 0x83:
3196
                val = (int8_t)insn_get(s, OT_BYTE);
3197
                break;
3198
            }
3199
            gen_op_movl_T1_im(val);
3200
            gen_op(s, op, ot, opreg);
3201
        }
3202
        break;
3203

    
3204
        /**************************/
3205
        /* inc, dec, and other misc arith */
3206
    case 0x40 ... 0x47: /* inc Gv */
3207
        ot = dflag ? OT_LONG : OT_WORD;
3208
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3209
        break;
3210
    case 0x48 ... 0x4f: /* dec Gv */
3211
        ot = dflag ? OT_LONG : OT_WORD;
3212
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3213
        break;
3214
    case 0xf6: /* GRP3 */
3215
    case 0xf7:
3216
        if ((b & 1) == 0)
3217
            ot = OT_BYTE;
3218
        else
3219
            ot = dflag + OT_WORD;
3220

    
3221
        modrm = ldub_code(s->pc++);
3222
        mod = (modrm >> 6) & 3;
3223
        rm = (modrm & 7) | REX_B(s);
3224
        op = (modrm >> 3) & 7;
3225
        if (mod != 3) {
3226
            if (op == 0)
3227
                s->rip_offset = insn_const_size(ot);
3228
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3229
            gen_op_ld_T0_A0[ot + s->mem_index]();
3230
        } else {
3231
            gen_op_mov_TN_reg[ot][0][rm]();
3232
        }
3233

    
3234
        switch(op) {
3235
        case 0: /* test */
3236
            val = insn_get(s, ot);
3237
            gen_op_movl_T1_im(val);
3238
            gen_op_testl_T0_T1_cc();
3239
            s->cc_op = CC_OP_LOGICB + ot;
3240
            break;
3241
        case 2: /* not */
3242
            gen_op_notl_T0();
3243
            if (mod != 3) {
3244
                gen_op_st_T0_A0[ot + s->mem_index]();
3245
            } else {
3246
                gen_op_mov_reg_T0[ot][rm]();
3247
            }
3248
            break;
3249
        case 3: /* neg */
3250
            gen_op_negl_T0();
3251
            if (mod != 3) {
3252
                gen_op_st_T0_A0[ot + s->mem_index]();
3253
            } else {
3254
                gen_op_mov_reg_T0[ot][rm]();
3255
            }
3256
            gen_op_update_neg_cc();
3257
            s->cc_op = CC_OP_SUBB + ot;
3258
            break;
3259
        case 4: /* mul */
3260
            switch(ot) {
3261
            case OT_BYTE:
3262
                gen_op_mulb_AL_T0();
3263
                s->cc_op = CC_OP_MULB;
3264
                break;
3265
            case OT_WORD:
3266
                gen_op_mulw_AX_T0();
3267
                s->cc_op = CC_OP_MULW;
3268
                break;
3269
            default:
3270
            case OT_LONG:
3271
                gen_op_mull_EAX_T0();
3272
                s->cc_op = CC_OP_MULL;
3273
                break;
3274
#ifdef TARGET_X86_64
3275
            case OT_QUAD:
3276
                gen_op_mulq_EAX_T0();
3277
                s->cc_op = CC_OP_MULQ;
3278
                break;
3279
#endif
3280
            }
3281
            break;
3282
        case 5: /* imul */
3283
            switch(ot) {
3284
            case OT_BYTE:
3285
                gen_op_imulb_AL_T0();
3286
                s->cc_op = CC_OP_MULB;
3287
                break;
3288
            case OT_WORD:
3289
                gen_op_imulw_AX_T0();
3290
                s->cc_op = CC_OP_MULW;
3291
                break;
3292
            default:
3293
            case OT_LONG:
3294
                gen_op_imull_EAX_T0();
3295
                s->cc_op = CC_OP_MULL;
3296
                break;
3297
#ifdef TARGET_X86_64
3298
            case OT_QUAD:
3299
                gen_op_imulq_EAX_T0();
3300
                s->cc_op = CC_OP_MULQ;
3301
                break;
3302
#endif
3303
            }
3304
            break;
3305
        case 6: /* div */
3306
            switch(ot) {
3307
            case OT_BYTE:
3308
                gen_jmp_im(pc_start - s->cs_base);
3309
                gen_op_divb_AL_T0();
3310
                break;
3311
            case OT_WORD:
3312
                gen_jmp_im(pc_start - s->cs_base);
3313
                gen_op_divw_AX_T0();
3314
                break;
3315
            default:
3316
            case OT_LONG:
3317
                gen_jmp_im(pc_start - s->cs_base);
3318
                gen_op_divl_EAX_T0();
3319
                break;
3320
#ifdef TARGET_X86_64
3321
            case OT_QUAD:
3322
                gen_jmp_im(pc_start - s->cs_base);
3323
                gen_op_divq_EAX_T0();
3324
                break;
3325
#endif
3326
            }
3327
            break;
3328
        case 7: /* idiv */
3329
            switch(ot) {
3330
            case OT_BYTE:
3331
                gen_jmp_im(pc_start - s->cs_base);
3332
                gen_op_idivb_AL_T0();
3333
                break;
3334
            case OT_WORD:
3335
                gen_jmp_im(pc_start - s->cs_base);
3336
                gen_op_idivw_AX_T0();
3337
                break;
3338
            default:
3339
            case OT_LONG:
3340
                gen_jmp_im(pc_start - s->cs_base);
3341
                gen_op_idivl_EAX_T0();
3342
                break;
3343
#ifdef TARGET_X86_64
3344
            case OT_QUAD:
3345
                gen_jmp_im(pc_start - s->cs_base);
3346
                gen_op_idivq_EAX_T0();
3347
                break;
3348
#endif
3349
            }
3350
            break;
3351
        default:
3352
            goto illegal_op;
3353
        }
3354
        break;
3355

    
3356
    case 0xfe: /* GRP4 */
3357
    case 0xff: /* GRP5 */
3358
        if ((b & 1) == 0)
3359
            ot = OT_BYTE;
3360
        else
3361
            ot = dflag + OT_WORD;
3362

    
3363
        modrm = ldub_code(s->pc++);
3364
        mod = (modrm >> 6) & 3;
3365
        rm = (modrm & 7) | REX_B(s);
3366
        op = (modrm >> 3) & 7;
3367
        if (op >= 2 && b == 0xfe) {
3368
            goto illegal_op;
3369
        }
3370
        if (CODE64(s)) {
3371
            if (op >= 2 && op <= 5) {
3372
                /* operand size for jumps is 64 bit */
3373
                ot = OT_QUAD;
3374
            } else if (op == 6) {
3375
                /* default push size is 64 bit */
3376
                ot = dflag ? OT_QUAD : OT_WORD;
3377
            }
3378
        }
3379
        if (mod != 3) {
3380
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3381
            if (op >= 2 && op != 3 && op != 5)
3382
                gen_op_ld_T0_A0[ot + s->mem_index]();
3383
        } else {
3384
            gen_op_mov_TN_reg[ot][0][rm]();
3385
        }
3386

    
3387
        switch(op) {
3388
        case 0: /* inc Ev */
3389
            if (mod != 3)
3390
                opreg = OR_TMP0;
3391
            else
3392
                opreg = rm;
3393
            gen_inc(s, ot, opreg, 1);
3394
            break;
3395
        case 1: /* dec Ev */
3396
            if (mod != 3)
3397
                opreg = OR_TMP0;
3398
            else
3399
                opreg = rm;
3400
            gen_inc(s, ot, opreg, -1);
3401
            break;
3402
        case 2: /* call Ev */
3403
            /* XXX: optimize if memory (no 'and' is necessary) */
3404
            if (s->dflag == 0)
3405
                gen_op_andl_T0_ffff();
3406
            next_eip = s->pc - s->cs_base;
3407
            gen_movtl_T1_im(next_eip);
3408
            gen_push_T1(s);
3409
            gen_op_jmp_T0();
3410
            gen_eob(s);
3411
            break;
3412
        case 3: /* lcall Ev */
3413
            gen_op_ld_T1_A0[ot + s->mem_index]();
3414
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
3415
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3416
        do_lcall:
3417
            if (s->pe && !s->vm86) {
3418
                if (s->cc_op != CC_OP_DYNAMIC)
3419
                    gen_op_set_cc_op(s->cc_op);
3420
                gen_jmp_im(pc_start - s->cs_base);
3421
                gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base);
3422
            } else {
3423
                gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
3424
            }
3425
            gen_eob(s);
3426
            break;
3427
        case 4: /* jmp Ev */
3428
            if (s->dflag == 0)
3429
                gen_op_andl_T0_ffff();
3430
            gen_op_jmp_T0();
3431
            gen_eob(s);
3432
            break;
3433
        case 5: /* ljmp Ev */
3434
            gen_op_ld_T1_A0[ot + s->mem_index]();
3435
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
3436
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3437
        do_ljmp:
3438
            if (s->pe && !s->vm86) {
3439
                if (s->cc_op != CC_OP_DYNAMIC)
3440
                    gen_op_set_cc_op(s->cc_op);
3441
                gen_jmp_im(pc_start - s->cs_base);
3442
                gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
3443
            } else {
3444
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3445
                gen_op_movl_T0_T1();
3446
                gen_op_jmp_T0();
3447
            }
3448
            gen_eob(s);
3449
            break;
3450
        case 6: /* push Ev */
3451
            gen_push_T0(s);
3452
            break;
3453
        default:
3454
            goto illegal_op;
3455
        }
3456
        break;
3457

    
3458
    case 0x84: /* test Ev, Gv */
3459
    case 0x85: 
3460
        if ((b & 1) == 0)
3461
            ot = OT_BYTE;
3462
        else
3463
            ot = dflag + OT_WORD;
3464

    
3465
        modrm = ldub_code(s->pc++);
3466
        mod = (modrm >> 6) & 3;
3467
        rm = (modrm & 7) | REX_B(s);
3468
        reg = ((modrm >> 3) & 7) | rex_r;
3469
        
3470
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3471
        gen_op_mov_TN_reg[ot][1][reg]();
3472
        gen_op_testl_T0_T1_cc();
3473
        s->cc_op = CC_OP_LOGICB + ot;
3474
        break;
3475
        
3476
    case 0xa8: /* test eAX, Iv */
3477
    case 0xa9:
3478
        if ((b & 1) == 0)
3479
            ot = OT_BYTE;
3480
        else
3481
            ot = dflag + OT_WORD;
3482
        val = insn_get(s, ot);
3483

    
3484
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
3485
        gen_op_movl_T1_im(val);
3486
        gen_op_testl_T0_T1_cc();
3487
        s->cc_op = CC_OP_LOGICB + ot;
3488
        break;
3489
        
3490
    case 0x98: /* CWDE/CBW */
3491
#ifdef TARGET_X86_64
3492
        if (dflag == 2) {
3493
            gen_op_movslq_RAX_EAX();
3494
        } else
3495
#endif
3496
        if (dflag == 1)
3497
            gen_op_movswl_EAX_AX();
3498
        else
3499
            gen_op_movsbw_AX_AL();
3500
        break;
3501
    case 0x99: /* CDQ/CWD */
3502
#ifdef TARGET_X86_64
3503
        if (dflag == 2) {
3504
            gen_op_movsqo_RDX_RAX();
3505
        } else
3506
#endif
3507
        if (dflag == 1)
3508
            gen_op_movslq_EDX_EAX();
3509
        else
3510
            gen_op_movswl_DX_AX();
3511
        break;
3512
    case 0x1af: /* imul Gv, Ev */
3513
    case 0x69: /* imul Gv, Ev, I */
3514
    case 0x6b:
3515
        ot = dflag + OT_WORD;
3516
        modrm = ldub_code(s->pc++);
3517
        reg = ((modrm >> 3) & 7) | rex_r;
3518
        if (b == 0x69)
3519
            s->rip_offset = insn_const_size(ot);
3520
        else if (b == 0x6b)
3521
            s->rip_offset = 1;
3522
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3523
        if (b == 0x69) {
3524
            val = insn_get(s, ot);
3525
            gen_op_movl_T1_im(val);
3526
        } else if (b == 0x6b) {
3527
            val = (int8_t)insn_get(s, OT_BYTE);
3528
            gen_op_movl_T1_im(val);
3529
        } else {
3530
            gen_op_mov_TN_reg[ot][1][reg]();
3531
        }
3532

    
3533
#ifdef TARGET_X86_64
3534
        if (ot == OT_QUAD) {
3535
            gen_op_imulq_T0_T1();
3536
        } else
3537
#endif
3538
        if (ot == OT_LONG) {
3539
            gen_op_imull_T0_T1();
3540
        } else {
3541
            gen_op_imulw_T0_T1();
3542
        }
3543
        gen_op_mov_reg_T0[ot][reg]();
3544
        s->cc_op = CC_OP_MULB + ot;
3545
        break;
3546
    case 0x1c0:
3547
    case 0x1c1: /* xadd Ev, Gv */
3548
        if ((b & 1) == 0)
3549
            ot = OT_BYTE;
3550
        else
3551
            ot = dflag + OT_WORD;
3552
        modrm = ldub_code(s->pc++);
3553
        reg = ((modrm >> 3) & 7) | rex_r;
3554
        mod = (modrm >> 6) & 3;
3555
        if (mod == 3) {
3556
            rm = (modrm & 7) | REX_B(s);
3557
            gen_op_mov_TN_reg[ot][0][reg]();
3558
            gen_op_mov_TN_reg[ot][1][rm]();
3559
            gen_op_addl_T0_T1();
3560
            gen_op_mov_reg_T1[ot][reg]();
3561
            gen_op_mov_reg_T0[ot][rm]();
3562
        } else {
3563
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3564
            gen_op_mov_TN_reg[ot][0][reg]();
3565
            gen_op_ld_T1_A0[ot + s->mem_index]();
3566
            gen_op_addl_T0_T1();
3567
            gen_op_st_T0_A0[ot + s->mem_index]();
3568
            gen_op_mov_reg_T1[ot][reg]();
3569
        }
3570
        gen_op_update2_cc();
3571
        s->cc_op = CC_OP_ADDB + ot;
3572
        break;
3573
    case 0x1b0:
3574
    case 0x1b1: /* cmpxchg Ev, Gv */
3575
        if ((b & 1) == 0)
3576
            ot = OT_BYTE;
3577
        else
3578
            ot = dflag + OT_WORD;
3579
        modrm = ldub_code(s->pc++);
3580
        reg = ((modrm >> 3) & 7) | rex_r;
3581
        mod = (modrm >> 6) & 3;
3582
        gen_op_mov_TN_reg[ot][1][reg]();
3583
        if (mod == 3) {
3584
            rm = (modrm & 7) | REX_B(s);
3585
            gen_op_mov_TN_reg[ot][0][rm]();
3586
            gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
3587
            gen_op_mov_reg_T0[ot][rm]();
3588
        } else {
3589
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3590
            gen_op_ld_T0_A0[ot + s->mem_index]();
3591
            gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
3592
        }
3593
        s->cc_op = CC_OP_SUBB + ot;
3594
        break;
3595
    case 0x1c7: /* cmpxchg8b */
3596
        modrm = ldub_code(s->pc++);
3597
        mod = (modrm >> 6) & 3;
3598
        if (mod == 3)
3599
            goto illegal_op;
3600
        if (s->cc_op != CC_OP_DYNAMIC)
3601
            gen_op_set_cc_op(s->cc_op);
3602
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3603
        gen_op_cmpxchg8b();
3604
        s->cc_op = CC_OP_EFLAGS;
3605
        break;
3606
        
3607
        /**************************/
3608
        /* push/pop */
3609
    case 0x50 ... 0x57: /* push */
3610
        gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
3611
        gen_push_T0(s);
3612
        break;
3613
    case 0x58 ... 0x5f: /* pop */
3614
        if (CODE64(s)) {
3615
            ot = dflag ? OT_QUAD : OT_WORD;
3616
        } else {
3617
            ot = dflag + OT_WORD;
3618
        }
3619
        gen_pop_T0(s);
3620
        /* NOTE: order is important for pop %sp */
3621
        gen_pop_update(s);
3622
        gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
3623
        break;
3624
    case 0x60: /* pusha */
3625
        if (CODE64(s))
3626
            goto illegal_op;
3627
        gen_pusha(s);
3628
        break;
3629
    case 0x61: /* popa */
3630
        if (CODE64(s))
3631
            goto illegal_op;
3632
        gen_popa(s);
3633
        break;
3634
    case 0x68: /* push Iv */
3635
    case 0x6a:
3636
        if (CODE64(s)) {
3637
            ot = dflag ? OT_QUAD : OT_WORD;
3638
        } else {
3639
            ot = dflag + OT_WORD;
3640
        }
3641
        if (b == 0x68)
3642
            val = insn_get(s, ot);
3643
        else
3644
            val = (int8_t)insn_get(s, OT_BYTE);
3645
        gen_op_movl_T0_im(val);
3646
        gen_push_T0(s);
3647
        break;
3648
    case 0x8f: /* pop Ev */
3649
        if (CODE64(s)) {
3650
            ot = dflag ? OT_QUAD : OT_WORD;
3651
        } else {
3652
            ot = dflag + OT_WORD;
3653
        }
3654
        modrm = ldub_code(s->pc++);
3655
        mod = (modrm >> 6) & 3;
3656
        gen_pop_T0(s);
3657
        if (mod == 3) {
3658
            /* NOTE: order is important for pop %sp */
3659
            gen_pop_update(s);
3660
            rm = (modrm & 7) | REX_B(s);
3661
            gen_op_mov_reg_T0[ot][rm]();
3662
        } else {
3663
            /* NOTE: order is important too for MMU exceptions */
3664
            s->popl_esp_hack = 1 << ot;
3665
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3666
            s->popl_esp_hack = 0;
3667
            gen_pop_update(s);
3668
        }
3669
        break;
3670
    case 0xc8: /* enter */
3671
        {
3672
            /* XXX: long mode support */
3673
            int level;
3674
            val = lduw_code(s->pc);
3675
            s->pc += 2;
3676
            level = ldub_code(s->pc++);
3677
            gen_enter(s, val, level);
3678
        }
3679
        break;
3680
    case 0xc9: /* leave */
3681
        /* XXX: exception not precise (ESP is updated before potential exception) */
3682
        /* XXX: may be invalid for 16 bit in long mode */
3683
        if (CODE64(s)) {
3684
            gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
3685
            gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
3686
        } else if (s->ss32) {
3687
            gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
3688
            gen_op_mov_reg_T0[OT_LONG][R_ESP]();
3689
        } else {
3690
            gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
3691
            gen_op_mov_reg_T0[OT_WORD][R_ESP]();
3692
        }
3693
        gen_pop_T0(s);
3694
        if (CODE64(s)) {
3695
            ot = dflag ? OT_QUAD : OT_WORD;
3696
        } else {
3697
            ot = dflag + OT_WORD;
3698
        }
3699
        gen_op_mov_reg_T0[ot][R_EBP]();
3700
        gen_pop_update(s);
3701
        break;
3702
    case 0x06: /* push es */
3703
    case 0x0e: /* push cs */
3704
    case 0x16: /* push ss */
3705
    case 0x1e: /* push ds */
3706
        if (CODE64(s))
3707
            goto illegal_op;
3708
        gen_op_movl_T0_seg(b >> 3);
3709
        gen_push_T0(s);
3710
        break;
3711
    case 0x1a0: /* push fs */
3712
    case 0x1a8: /* push gs */
3713
        gen_op_movl_T0_seg((b >> 3) & 7);
3714
        gen_push_T0(s);
3715
        break;
3716
    case 0x07: /* pop es */
3717
    case 0x17: /* pop ss */
3718
    case 0x1f: /* pop ds */
3719
        if (CODE64(s))
3720
            goto illegal_op;
3721
        reg = b >> 3;
3722
        gen_pop_T0(s);
3723
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
3724
        gen_pop_update(s);
3725
        if (reg == R_SS) {
3726
            /* if reg == SS, inhibit interrupts/trace. */
3727
            /* If several instructions disable interrupts, only the
3728
               _first_ does it */
3729
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3730
                gen_op_set_inhibit_irq();
3731
            s->tf = 0;
3732
        }
3733
        if (s->is_jmp) {
3734
            gen_jmp_im(s->pc - s->cs_base);
3735
            gen_eob(s);
3736
        }
3737
        break;
3738
    case 0x1a1: /* pop fs */
3739
    case 0x1a9: /* pop gs */
3740
        gen_pop_T0(s);
3741
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
3742
        gen_pop_update(s);
3743
        if (s->is_jmp) {
3744
            gen_jmp_im(s->pc - s->cs_base);
3745
            gen_eob(s);
3746
        }
3747
        break;
3748

    
3749
        /**************************/
3750
        /* mov */
3751
    case 0x88:
3752
    case 0x89: /* mov Gv, Ev */
3753
        if ((b & 1) == 0)
3754
            ot = OT_BYTE;
3755
        else
3756
            ot = dflag + OT_WORD;
3757
        modrm = ldub_code(s->pc++);
3758
        reg = ((modrm >> 3) & 7) | rex_r;
3759
        
3760
        /* generate a generic store */
3761
        gen_ldst_modrm(s, modrm, ot, reg, 1);
3762
        break;
3763
    case 0xc6:
3764
    case 0xc7: /* mov Ev, Iv */
3765
        if ((b & 1) == 0)
3766
            ot = OT_BYTE;
3767
        else
3768
            ot = dflag + OT_WORD;
3769
        modrm = ldub_code(s->pc++);
3770
        mod = (modrm >> 6) & 3;
3771
        if (mod != 3) {
3772
            s->rip_offset = insn_const_size(ot);
3773
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3774
        }
3775
        val = insn_get(s, ot);
3776
        gen_op_movl_T0_im(val);
3777
        if (mod != 3)
3778
            gen_op_st_T0_A0[ot + s->mem_index]();
3779
        else
3780
            gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
3781
        break;
3782
    case 0x8a:
3783
    case 0x8b: /* mov Ev, Gv */
3784
        if ((b & 1) == 0)
3785
            ot = OT_BYTE;
3786
        else
3787
            ot = OT_WORD + dflag;
3788
        modrm = ldub_code(s->pc++);
3789
        reg = ((modrm >> 3) & 7) | rex_r;
3790
        
3791
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3792
        gen_op_mov_reg_T0[ot][reg]();
3793
        break;
3794
    case 0x8e: /* mov seg, Gv */
3795
        modrm = ldub_code(s->pc++);
3796
        reg = (modrm >> 3) & 7;
3797
        if (reg >= 6 || reg == R_CS)
3798
            goto illegal_op;
3799
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3800
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
3801
        if (reg == R_SS) {
3802
            /* if reg == SS, inhibit interrupts/trace */
3803
            /* If several instructions disable interrupts, only the
3804
               _first_ does it */
3805
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3806
                gen_op_set_inhibit_irq();
3807
            s->tf = 0;
3808
        }
3809
        if (s->is_jmp) {
3810
            gen_jmp_im(s->pc - s->cs_base);
3811
            gen_eob(s);
3812
        }
3813
        break;
3814
    case 0x8c: /* mov Gv, seg */
3815
        modrm = ldub_code(s->pc++);
3816
        reg = (modrm >> 3) & 7;
3817
        mod = (modrm >> 6) & 3;
3818
        if (reg >= 6)
3819
            goto illegal_op;
3820
        gen_op_movl_T0_seg(reg);
3821
        if (mod == 3)
3822
            ot = OT_WORD + dflag;
3823
        else
3824
            ot = OT_WORD;
3825
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3826
        break;
3827

    
3828
    case 0x1b6: /* movzbS Gv, Eb */
3829
    case 0x1b7: /* movzwS Gv, Eb */
3830
    case 0x1be: /* movsbS Gv, Eb */
3831
    case 0x1bf: /* movswS Gv, Eb */
3832
        {
3833
            int d_ot;
3834
            /* d_ot is the size of destination */
3835
            d_ot = dflag + OT_WORD;
3836
            /* ot is the size of source */
3837
            ot = (b & 1) + OT_BYTE;
3838
            modrm = ldub_code(s->pc++);
3839
            reg = ((modrm >> 3) & 7) | rex_r;
3840
            mod = (modrm >> 6) & 3;
3841
            rm = (modrm & 7) | REX_B(s);
3842
            
3843
            if (mod == 3) {
3844
                gen_op_mov_TN_reg[ot][0][rm]();
3845
                switch(ot | (b & 8)) {
3846
                case OT_BYTE:
3847
                    gen_op_movzbl_T0_T0();
3848
                    break;
3849
                case OT_BYTE | 8:
3850
                    gen_op_movsbl_T0_T0();
3851
                    break;
3852
                case OT_WORD:
3853
                    gen_op_movzwl_T0_T0();
3854
                    break;
3855
                default:
3856
                case OT_WORD | 8:
3857
                    gen_op_movswl_T0_T0();
3858
                    break;
3859
                }
3860
                gen_op_mov_reg_T0[d_ot][reg]();
3861
            } else {
3862
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3863
                if (b & 8) {
3864
                    gen_op_lds_T0_A0[ot + s->mem_index]();
3865
                } else {
3866
                    gen_op_ldu_T0_A0[ot + s->mem_index]();
3867
                }
3868
                gen_op_mov_reg_T0[d_ot][reg]();
3869
            }
3870
        }
3871
        break;
3872

    
3873
    case 0x8d: /* lea */
3874
        ot = dflag + OT_WORD;
3875
        modrm = ldub_code(s->pc++);
3876
        mod = (modrm >> 6) & 3;
3877
        if (mod == 3)
3878
            goto illegal_op;
3879
        reg = ((modrm >> 3) & 7) | rex_r;
3880
        /* we must ensure that no segment is added */
3881
        s->override = -1;
3882
        val = s->addseg;
3883
        s->addseg = 0;
3884
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3885
        s->addseg = val;
3886
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
3887
        break;
3888
        
3889
    case 0xa0: /* mov EAX, Ov */
3890
    case 0xa1:
3891
    case 0xa2: /* mov Ov, EAX */
3892
    case 0xa3:
3893
        {
3894
            target_ulong offset_addr;
3895

    
3896
            if ((b & 1) == 0)
3897
                ot = OT_BYTE;
3898
            else
3899
                ot = dflag + OT_WORD;
3900
#ifdef TARGET_X86_64
3901
            if (CODE64(s)) {
3902
                offset_addr = ldq_code(s->pc);
3903
                s->pc += 8;
3904
                if (offset_addr == (int32_t)offset_addr)
3905
                    gen_op_movq_A0_im(offset_addr);
3906
                else
3907
                    gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
3908
            } else 
3909
#endif
3910
            {
3911
                if (s->aflag) {
3912
                    offset_addr = insn_get(s, OT_LONG);
3913
                } else {
3914
                    offset_addr = insn_get(s, OT_WORD);
3915
                }
3916
                gen_op_movl_A0_im(offset_addr);
3917
            }
3918
            gen_add_A0_ds_seg(s);
3919
            if ((b & 2) == 0) {
3920
                gen_op_ld_T0_A0[ot + s->mem_index]();
3921
                gen_op_mov_reg_T0[ot][R_EAX]();
3922
            } else {
3923
                gen_op_mov_TN_reg[ot][0][R_EAX]();
3924
                gen_op_st_T0_A0[ot + s->mem_index]();
3925
            }
3926
        }
3927
        break;
3928
    case 0xd7: /* xlat */
3929
#ifdef TARGET_X86_64
3930
        if (CODE64(s)) {
3931
            gen_op_movq_A0_reg[R_EBX]();
3932
            gen_op_addq_A0_AL();
3933
        } else 
3934
#endif
3935
        {
3936
            gen_op_movl_A0_reg[R_EBX]();
3937
            gen_op_addl_A0_AL();
3938
            if (s->aflag == 0)
3939
                gen_op_andl_A0_ffff();
3940
        }
3941
        gen_add_A0_ds_seg(s);
3942
        gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
3943
        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
3944
        break;
3945
    case 0xb0 ... 0xb7: /* mov R, Ib */
3946
        val = insn_get(s, OT_BYTE);
3947
        gen_op_movl_T0_im(val);
3948
        gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
3949
        break;
3950
    case 0xb8 ... 0xbf: /* mov R, Iv */
3951
#ifdef TARGET_X86_64
3952
        if (dflag == 2) {
3953
            uint64_t tmp;
3954
            /* 64 bit case */
3955
            tmp = ldq_code(s->pc);
3956
            s->pc += 8;
3957
            reg = (b & 7) | REX_B(s);
3958
            gen_movtl_T0_im(tmp);
3959
            gen_op_mov_reg_T0[OT_QUAD][reg]();
3960
        } else 
3961
#endif
3962
        {
3963
            ot = dflag ? OT_LONG : OT_WORD;
3964
            val = insn_get(s, ot);
3965
            reg = (b & 7) | REX_B(s);
3966
            gen_op_movl_T0_im(val);
3967
            gen_op_mov_reg_T0[ot][reg]();
3968
        }
3969
        break;
3970

    
3971
    case 0x91 ... 0x97: /* xchg R, EAX */
3972
        ot = dflag + OT_WORD;
3973
        reg = (b & 7) | REX_B(s);
3974
        rm = R_EAX;
3975
        goto do_xchg_reg;
3976
    case 0x86:
3977
    case 0x87: /* xchg Ev, Gv */
3978
        if ((b & 1) == 0)
3979
            ot = OT_BYTE;
3980
        else
3981
            ot = dflag + OT_WORD;
3982
        modrm = ldub_code(s->pc++);
3983
        reg = ((modrm >> 3) & 7) | rex_r;
3984
        mod = (modrm >> 6) & 3;
3985
        if (mod == 3) {
3986
            rm = (modrm & 7) | REX_B(s);
3987
        do_xchg_reg:
3988
            gen_op_mov_TN_reg[ot][0][reg]();
3989
            gen_op_mov_TN_reg[ot][1][rm]();
3990
            gen_op_mov_reg_T0[ot][rm]();
3991
            gen_op_mov_reg_T1[ot][reg]();
3992
        } else {
3993
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3994
            gen_op_mov_TN_reg[ot][0][reg]();
3995
            /* for xchg, lock is implicit */
3996
            if (!(prefixes & PREFIX_LOCK))
3997
                gen_op_lock();
3998
            gen_op_ld_T1_A0[ot + s->mem_index]();
3999
            gen_op_st_T0_A0[ot + s->mem_index]();
4000
            if (!(prefixes & PREFIX_LOCK))
4001
                gen_op_unlock();
4002
            gen_op_mov_reg_T1[ot][reg]();
4003
        }
4004
        break;
4005
    case 0xc4: /* les Gv */
4006
        if (CODE64(s))
4007
            goto illegal_op;
4008
        op = R_ES;
4009
        goto do_lxx;
4010
    case 0xc5: /* lds Gv */
4011
        if (CODE64(s))
4012
            goto illegal_op;
4013
        op = R_DS;
4014
        goto do_lxx;
4015
    case 0x1b2: /* lss Gv */
4016
        op = R_SS;
4017
        goto do_lxx;
4018
    case 0x1b4: /* lfs Gv */
4019
        op = R_FS;
4020
        goto do_lxx;
4021
    case 0x1b5: /* lgs Gv */
4022
        op = R_GS;
4023
    do_lxx:
4024
        ot = dflag ? OT_LONG : OT_WORD;
4025
        modrm = ldub_code(s->pc++);
4026
        reg = ((modrm >> 3) & 7) | rex_r;
4027
        mod = (modrm >> 6) & 3;
4028
        if (mod == 3)
4029
            goto illegal_op;
4030
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4031
        gen_op_ld_T1_A0[ot + s->mem_index]();
4032
        gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
4033
        /* load the segment first to handle exceptions properly */
4034
        gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
4035
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4036
        /* then put the data */
4037
        gen_op_mov_reg_T1[ot][reg]();
4038
        if (s->is_jmp) {
4039
            gen_jmp_im(s->pc - s->cs_base);
4040
            gen_eob(s);
4041
        }
4042
        break;
4043
        
4044
        /************************/
4045
        /* shifts */
4046
    case 0xc0:
4047
    case 0xc1:
4048
        /* shift Ev,Ib */
4049
        shift = 2;
4050
    grp2:
4051
        {
4052
            if ((b & 1) == 0)
4053
                ot = OT_BYTE;
4054
            else
4055
                ot = dflag + OT_WORD;
4056
            
4057
            modrm = ldub_code(s->pc++);
4058
            mod = (modrm >> 6) & 3;
4059
            op = (modrm >> 3) & 7;
4060
            
4061
            if (mod != 3) {
4062
                if (shift == 2) {
4063
                    s->rip_offset = 1;
4064
                }
4065
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4066
                opreg = OR_TMP0;
4067
            } else {
4068
                opreg = (modrm & 7) | REX_B(s);
4069
            }
4070

    
4071
            /* simpler op */
4072
            if (shift == 0) {
4073
                gen_shift(s, op, ot, opreg, OR_ECX);
4074
            } else {
4075
                if (shift == 2) {
4076
                    shift = ldub_code(s->pc++);
4077
                }
4078
                gen_shifti(s, op, ot, opreg, shift);
4079
            }
4080
        }
4081
        break;
4082
    case 0xd0:
4083
    case 0xd1:
4084
        /* shift Ev,1 */
4085
        shift = 1;
4086
        goto grp2;
4087
    case 0xd2:
4088
    case 0xd3:
4089
        /* shift Ev,cl */
4090
        shift = 0;
4091
        goto grp2;
4092

    
4093
    case 0x1a4: /* shld imm */
4094
        op = 0;
4095
        shift = 1;
4096
        goto do_shiftd;
4097
    case 0x1a5: /* shld cl */
4098
        op = 0;
4099
        shift = 0;
4100
        goto do_shiftd;
4101
    case 0x1ac: /* shrd imm */
4102
        op = 1;
4103
        shift = 1;
4104
        goto do_shiftd;
4105
    case 0x1ad: /* shrd cl */
4106
        op = 1;
4107
        shift = 0;
4108
    do_shiftd:
4109
        ot = dflag + OT_WORD;
4110
        modrm = ldub_code(s->pc++);
4111
        mod = (modrm >> 6) & 3;
4112
        rm = (modrm & 7) | REX_B(s);
4113
        reg = ((modrm >> 3) & 7) | rex_r;
4114
        
4115
        if (mod != 3) {
4116
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4117
            gen_op_ld_T0_A0[ot + s->mem_index]();
4118
        } else {
4119
            gen_op_mov_TN_reg[ot][0][rm]();
4120
        }
4121
        gen_op_mov_TN_reg[ot][1][reg]();
4122
        
4123
        if (shift) {
4124
            val = ldub_code(s->pc++);
4125
            if (ot == OT_QUAD)
4126
                val &= 0x3f;
4127
            else
4128
                val &= 0x1f;
4129
            if (val) {
4130
                if (mod == 3)
4131
                    gen_op_shiftd_T0_T1_im_cc[ot][op](val);
4132
                else
4133
                    gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
4134
                if (op == 0 && ot != OT_WORD)
4135
                    s->cc_op = CC_OP_SHLB + ot;
4136
                else
4137
                    s->cc_op = CC_OP_SARB + ot;
4138
            }
4139
        } else {
4140
            if (s->cc_op != CC_OP_DYNAMIC)
4141
                gen_op_set_cc_op(s->cc_op);
4142
            if (mod == 3)
4143
                gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
4144
            else
4145
                gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
4146
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
4147
        }
4148
        if (mod == 3) {
4149
            gen_op_mov_reg_T0[ot][rm]();
4150
        }
4151
        break;
4152

    
4153
        /************************/
4154
        /* floats */
4155
    case 0xd8 ... 0xdf: 
4156
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4157
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4158
            /* XXX: what to do if illegal op ? */
4159
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4160
            break;
4161
        }
4162
        modrm = ldub_code(s->pc++);
4163
        mod = (modrm >> 6) & 3;
4164
        rm = modrm & 7;
4165
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4166
        if (mod != 3) {
4167
            /* memory op */
4168
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4169
            switch(op) {
4170
            case 0x00 ... 0x07: /* fxxxs */
4171
            case 0x10 ... 0x17: /* fixxxl */
4172
            case 0x20 ... 0x27: /* fxxxl */
4173
            case 0x30 ... 0x37: /* fixxx */
4174
                {
4175
                    int op1;
4176
                    op1 = op & 7;
4177

    
4178
                    switch(op >> 4) {
4179
                    case 0:
4180
                        gen_op_flds_FT0_A0();
4181
                        break;
4182
                    case 1:
4183
                        gen_op_fildl_FT0_A0();
4184
                        break;
4185
                    case 2:
4186
                        gen_op_fldl_FT0_A0();
4187
                        break;
4188
                    case 3:
4189
                    default:
4190
                        gen_op_fild_FT0_A0();
4191
                        break;
4192
                    }
4193
                    
4194
                    gen_op_fp_arith_ST0_FT0[op1]();
4195
                    if (op1 == 3) {
4196
                        /* fcomp needs pop */
4197
                        gen_op_fpop();
4198
                    }
4199
                }
4200
                break;
4201
            case 0x08: /* flds */
4202
            case 0x0a: /* fsts */
4203
            case 0x0b: /* fstps */
4204
            case 0x18: /* fildl */
4205
            case 0x1a: /* fistl */
4206
            case 0x1b: /* fistpl */
4207
            case 0x28: /* fldl */
4208
            case 0x2a: /* fstl */
4209
            case 0x2b: /* fstpl */
4210
            case 0x38: /* filds */
4211
            case 0x3a: /* fists */
4212
            case 0x3b: /* fistps */
4213
                
4214
                switch(op & 7) {
4215
                case 0:
4216
                    switch(op >> 4) {
4217
                    case 0:
4218
                        gen_op_flds_ST0_A0();
4219
                        break;
4220
                    case 1:
4221
                        gen_op_fildl_ST0_A0();
4222
                        break;
4223
                    case 2:
4224
                        gen_op_fldl_ST0_A0();
4225
                        break;
4226
                    case 3:
4227
                    default:
4228
                        gen_op_fild_ST0_A0();
4229
                        break;
4230
                    }
4231
                    break;
4232
                default:
4233
                    switch(op >> 4) {
4234
                    case 0:
4235
                        gen_op_fsts_ST0_A0();
4236
                        break;
4237
                    case 1:
4238
                        gen_op_fistl_ST0_A0();
4239
                        break;
4240
                    case 2:
4241
                        gen_op_fstl_ST0_A0();
4242
                        break;
4243
                    case 3:
4244
                    default:
4245
                        gen_op_fist_ST0_A0();
4246
                        break;
4247
                    }
4248
                    if ((op & 7) == 3)
4249
                        gen_op_fpop();
4250
                    break;
4251
                }
4252
                break;
4253
            case 0x0c: /* fldenv mem */
4254
                gen_op_fldenv_A0(s->dflag);
4255
                break;
4256
            case 0x0d: /* fldcw mem */
4257
                gen_op_fldcw_A0();
4258
                break;
4259
            case 0x0e: /* fnstenv mem */
4260
                gen_op_fnstenv_A0(s->dflag);
4261
                break;
4262
            case 0x0f: /* fnstcw mem */
4263
                gen_op_fnstcw_A0();
4264
                break;
4265
            case 0x1d: /* fldt mem */
4266
                gen_op_fldt_ST0_A0();
4267
                break;
4268
            case 0x1f: /* fstpt mem */
4269
                gen_op_fstt_ST0_A0();
4270
                gen_op_fpop();
4271
                break;
4272
            case 0x2c: /* frstor mem */
4273
                gen_op_frstor_A0(s->dflag);
4274
                break;
4275
            case 0x2e: /* fnsave mem */
4276
                gen_op_fnsave_A0(s->dflag);
4277
                break;
4278
            case 0x2f: /* fnstsw mem */
4279
                gen_op_fnstsw_A0();
4280
                break;
4281
            case 0x3c: /* fbld */
4282
                gen_op_fbld_ST0_A0();
4283
                break;
4284
            case 0x3e: /* fbstp */
4285
                gen_op_fbst_ST0_A0();
4286
                gen_op_fpop();
4287
                break;
4288
            case 0x3d: /* fildll */
4289
                gen_op_fildll_ST0_A0();
4290
                break;
4291
            case 0x3f: /* fistpll */
4292
                gen_op_fistll_ST0_A0();
4293
                gen_op_fpop();
4294
                break;
4295
            default:
4296
                goto illegal_op;
4297
            }
4298
        } else {
4299
            /* register float ops */
4300
            opreg = rm;
4301

    
4302
            switch(op) {
4303
            case 0x08: /* fld sti */
4304
                gen_op_fpush();
4305
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
4306
                break;
4307
            case 0x09: /* fxchg sti */
4308
            case 0x29: /* fxchg4 sti, undocumented op */
4309
            case 0x39: /* fxchg7 sti, undocumented op */
4310
                gen_op_fxchg_ST0_STN(opreg);
4311
                break;
4312
            case 0x0a: /* grp d9/2 */
4313
                switch(rm) {
4314
                case 0: /* fnop */
4315
                    /* check exceptions (FreeBSD FPU probe) */
4316
                    if (s->cc_op != CC_OP_DYNAMIC)
4317
                        gen_op_set_cc_op(s->cc_op);
4318
                    gen_jmp_im(pc_start - s->cs_base);
4319
                    gen_op_fwait();
4320
                    break;
4321
                default:
4322
                    goto illegal_op;
4323
                }
4324
                break;
4325
            case 0x0c: /* grp d9/4 */
4326
                switch(rm) {
4327
                case 0: /* fchs */
4328
                    gen_op_fchs_ST0();
4329
                    break;
4330
                case 1: /* fabs */
4331
                    gen_op_fabs_ST0();
4332
                    break;
4333
                case 4: /* ftst */
4334
                    gen_op_fldz_FT0();
4335
                    gen_op_fcom_ST0_FT0();
4336
                    break;
4337
                case 5: /* fxam */
4338
                    gen_op_fxam_ST0();
4339
                    break;
4340
                default:
4341
                    goto illegal_op;
4342
                }
4343
                break;
4344
            case 0x0d: /* grp d9/5 */
4345
                {
4346
                    switch(rm) {
4347
                    case 0:
4348
                        gen_op_fpush();
4349
                        gen_op_fld1_ST0();
4350
                        break;
4351
                    case 1:
4352
                        gen_op_fpush();
4353
                        gen_op_fldl2t_ST0();
4354
                        break;
4355
                    case 2:
4356
                        gen_op_fpush();
4357
                        gen_op_fldl2e_ST0();
4358
                        break;
4359
                    case 3:
4360
                        gen_op_fpush();
4361
                        gen_op_fldpi_ST0();
4362
                        break;
4363
                    case 4:
4364
                        gen_op_fpush();
4365
                        gen_op_fldlg2_ST0();
4366
                        break;
4367
                    case 5:
4368
                        gen_op_fpush();
4369
                        gen_op_fldln2_ST0();
4370
                        break;
4371
                    case 6:
4372
                        gen_op_fpush();
4373
                        gen_op_fldz_ST0();
4374
                        break;
4375
                    default:
4376
                        goto illegal_op;
4377
                    }
4378
                }
4379
                break;
4380
            case 0x0e: /* grp d9/6 */
4381
                switch(rm) {
4382
                case 0: /* f2xm1 */
4383
                    gen_op_f2xm1();
4384
                    break;
4385
                case 1: /* fyl2x */
4386
                    gen_op_fyl2x();
4387
                    break;
4388
                case 2: /* fptan */
4389
                    gen_op_fptan();
4390
                    break;
4391
                case 3: /* fpatan */
4392
                    gen_op_fpatan();
4393
                    break;
4394
                case 4: /* fxtract */
4395
                    gen_op_fxtract();
4396
                    break;
4397
                case 5: /* fprem1 */
4398
                    gen_op_fprem1();
4399
                    break;
4400
                case 6: /* fdecstp */
4401
                    gen_op_fdecstp();
4402
                    break;
4403
                default:
4404
                case 7: /* fincstp */
4405
                    gen_op_fincstp();
4406
                    break;
4407
                }
4408
                break;
4409
            case 0x0f: /* grp d9/7 */
4410
                switch(rm) {
4411
                case 0: /* fprem */
4412
                    gen_op_fprem();
4413
                    break;
4414
                case 1: /* fyl2xp1 */
4415
                    gen_op_fyl2xp1();
4416
                    break;
4417
                case 2: /* fsqrt */
4418
                    gen_op_fsqrt();
4419
                    break;
4420
                case 3: /* fsincos */
4421
                    gen_op_fsincos();
4422
                    break;
4423
                case 5: /* fscale */
4424
                    gen_op_fscale();
4425
                    break;
4426
                case 4: /* frndint */
4427
                    gen_op_frndint();
4428
                    break;
4429
                case 6: /* fsin */
4430
                    gen_op_fsin();
4431
                    break;
4432
                default:
4433
                case 7: /* fcos */
4434
                    gen_op_fcos();
4435
                    break;
4436
                }
4437
                break;
4438
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4439
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4440
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4441
                {
4442
                    int op1;
4443
                    
4444
                    op1 = op & 7;
4445
                    if (op >= 0x20) {
4446
                        gen_op_fp_arith_STN_ST0[op1](opreg);
4447
                        if (op >= 0x30)
4448
                            gen_op_fpop();
4449
                    } else {
4450
                        gen_op_fmov_FT0_STN(opreg);
4451
                        gen_op_fp_arith_ST0_FT0[op1]();
4452
                    }
4453
                }
4454
                break;
4455
            case 0x02: /* fcom */
4456
            case 0x22: /* fcom2, undocumented op */
4457
                gen_op_fmov_FT0_STN(opreg);
4458
                gen_op_fcom_ST0_FT0();
4459
                break;
4460
            case 0x03: /* fcomp */
4461
            case 0x23: /* fcomp3, undocumented op */
4462
            case 0x32: /* fcomp5, undocumented op */
4463
                gen_op_fmov_FT0_STN(opreg);
4464
                gen_op_fcom_ST0_FT0();
4465
                gen_op_fpop();
4466
                break;
4467
            case 0x15: /* da/5 */
4468
                switch(rm) {
4469
                case 1: /* fucompp */
4470
                    gen_op_fmov_FT0_STN(1);
4471
                    gen_op_fucom_ST0_FT0();
4472
                    gen_op_fpop();
4473
                    gen_op_fpop();
4474
                    break;
4475
                default:
4476
                    goto illegal_op;
4477
                }
4478
                break;
4479
            case 0x1c:
4480
                switch(rm) {
4481
                case 0: /* feni (287 only, just do nop here) */
4482
                    break;
4483
                case 1: /* fdisi (287 only, just do nop here) */
4484
                    break;
4485
                case 2: /* fclex */
4486
                    gen_op_fclex();
4487
                    break;
4488
                case 3: /* fninit */
4489
                    gen_op_fninit();
4490
                    break;
4491
                case 4: /* fsetpm (287 only, just do nop here) */
4492
                    break;
4493
                default:
4494
                    goto illegal_op;
4495
                }
4496
                break;
4497
            case 0x1d: /* fucomi */
4498
                if (s->cc_op != CC_OP_DYNAMIC)
4499
                    gen_op_set_cc_op(s->cc_op);
4500
                gen_op_fmov_FT0_STN(opreg);
4501
                gen_op_fucomi_ST0_FT0();
4502
                s->cc_op = CC_OP_EFLAGS;
4503
                break;
4504
            case 0x1e: /* fcomi */
4505
                if (s->cc_op != CC_OP_DYNAMIC)
4506
                    gen_op_set_cc_op(s->cc_op);
4507
                gen_op_fmov_FT0_STN(opreg);
4508
                gen_op_fcomi_ST0_FT0();
4509
                s->cc_op = CC_OP_EFLAGS;
4510
                break;
4511
            case 0x28: /* ffree sti */
4512
                gen_op_ffree_STN(opreg);
4513
                break; 
4514
            case 0x2a: /* fst sti */
4515
                gen_op_fmov_STN_ST0(opreg);
4516
                break;
4517
            case 0x2b: /* fstp sti */
4518
            case 0x0b: /* fstp1 sti, undocumented op */
4519
            case 0x3a: /* fstp8 sti, undocumented op */
4520
            case 0x3b: /* fstp9 sti, undocumented op */
4521
                gen_op_fmov_STN_ST0(opreg);
4522
                gen_op_fpop();
4523
                break;
4524
            case 0x2c: /* fucom st(i) */
4525
                gen_op_fmov_FT0_STN(opreg);
4526
                gen_op_fucom_ST0_FT0();
4527
                break;
4528
            case 0x2d: /* fucomp st(i) */
4529
                gen_op_fmov_FT0_STN(opreg);
4530
                gen_op_fucom_ST0_FT0();
4531
                gen_op_fpop();
4532
                break;
4533
            case 0x33: /* de/3 */
4534
                switch(rm) {
4535
                case 1: /* fcompp */
4536
                    gen_op_fmov_FT0_STN(1);
4537
                    gen_op_fcom_ST0_FT0();
4538
                    gen_op_fpop();
4539
                    gen_op_fpop();
4540
                    break;
4541
                default:
4542
                    goto illegal_op;
4543
                }
4544
                break;
4545
            case 0x38: /* ffreep sti, undocumented op */
4546
                gen_op_ffree_STN(opreg);
4547
                gen_op_fpop();
4548
                break;
4549
            case 0x3c: /* df/4 */
4550
                switch(rm) {
4551
                case 0:
4552
                    gen_op_fnstsw_EAX();
4553
                    break;
4554
                default:
4555
                    goto illegal_op;
4556
                }
4557
                break;
4558
            case 0x3d: /* fucomip */
4559
                if (s->cc_op != CC_OP_DYNAMIC)
4560
                    gen_op_set_cc_op(s->cc_op);
4561
                gen_op_fmov_FT0_STN(opreg);
4562
                gen_op_fucomi_ST0_FT0();
4563
                gen_op_fpop();
4564
                s->cc_op = CC_OP_EFLAGS;
4565
                break;
4566
            case 0x3e: /* fcomip */
4567
                if (s->cc_op != CC_OP_DYNAMIC)
4568
                    gen_op_set_cc_op(s->cc_op);
4569
                gen_op_fmov_FT0_STN(opreg);
4570
                gen_op_fcomi_ST0_FT0();
4571
                gen_op_fpop();
4572
                s->cc_op = CC_OP_EFLAGS;
4573
                break;
4574
            case 0x10 ... 0x13: /* fcmovxx */
4575
            case 0x18 ... 0x1b:
4576
                {
4577
                    int op1;
4578
                    const static uint8_t fcmov_cc[8] = {
4579
                        (JCC_B << 1),
4580
                        (JCC_Z << 1),
4581
                        (JCC_BE << 1),
4582
                        (JCC_P << 1),
4583
                    };
4584
                    op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
4585
                    gen_setcc(s, op1);
4586
                    gen_op_fcmov_ST0_STN_T0(opreg);
4587
                }
4588
                break;
4589
            default:
4590
                goto illegal_op;
4591
            }
4592
        }
4593
#ifdef USE_CODE_COPY
4594
        s->tb->cflags |= CF_TB_FP_USED;
4595
#endif
4596
        break;
4597
        /************************/
4598
        /* string ops */
4599

    
4600
    case 0xa4: /* movsS */
4601
    case 0xa5:
4602
        if ((b & 1) == 0)
4603
            ot = OT_BYTE;
4604
        else
4605
            ot = dflag + OT_WORD;
4606

    
4607
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4608
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4609
        } else {
4610
            gen_movs(s, ot);
4611
        }
4612
        break;
4613
        
4614
    case 0xaa: /* stosS */
4615
    case 0xab:
4616
        if ((b & 1) == 0)
4617
            ot = OT_BYTE;
4618
        else
4619
            ot = dflag + OT_WORD;
4620

    
4621
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4622
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4623
        } else {
4624
            gen_stos(s, ot);
4625
        }
4626
        break;
4627
    case 0xac: /* lodsS */
4628
    case 0xad:
4629
        if ((b & 1) == 0)
4630
            ot = OT_BYTE;
4631
        else
4632
            ot = dflag + OT_WORD;
4633
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4634
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4635
        } else {
4636
            gen_lods(s, ot);
4637
        }
4638
        break;
4639
    case 0xae: /* scasS */
4640
    case 0xaf:
4641
        if ((b & 1) == 0)
4642
            ot = OT_BYTE;
4643
        else
4644
            ot = dflag + OT_WORD;
4645
        if (prefixes & PREFIX_REPNZ) {
4646
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4647
        } else if (prefixes & PREFIX_REPZ) {
4648
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4649
        } else {
4650
            gen_scas(s, ot);
4651
            s->cc_op = CC_OP_SUBB + ot;
4652
        }
4653
        break;
4654

    
4655
    case 0xa6: /* cmpsS */
4656
    case 0xa7:
4657
        if ((b & 1) == 0)
4658
            ot = OT_BYTE;
4659
        else
4660
            ot = dflag + OT_WORD;
4661
        if (prefixes & PREFIX_REPNZ) {
4662
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4663
        } else if (prefixes & PREFIX_REPZ) {
4664
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4665
        } else {
4666
            gen_cmps(s, ot);
4667
            s->cc_op = CC_OP_SUBB + ot;
4668
        }
4669
        break;
4670
    case 0x6c: /* insS */
4671
    case 0x6d:
4672
        if ((b & 1) == 0)
4673
            ot = OT_BYTE;
4674
        else
4675
            ot = dflag ? OT_LONG : OT_WORD;
4676
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4677
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4678
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4679
        } else {
4680
            gen_ins(s, ot);
4681
        }
4682
        break;
4683
    case 0x6e: /* outsS */
4684
    case 0x6f:
4685
        if ((b & 1) == 0)
4686
            ot = OT_BYTE;
4687
        else
4688
            ot = dflag ? OT_LONG : OT_WORD;
4689
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4690
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4691
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4692
        } else {
4693
            gen_outs(s, ot);
4694
        }
4695
        break;
4696

    
4697
        /************************/
4698
        /* port I/O */
4699
    case 0xe4:
4700
    case 0xe5:
4701
        if ((b & 1) == 0)
4702
            ot = OT_BYTE;
4703
        else
4704
            ot = dflag ? OT_LONG : OT_WORD;
4705
        val = ldub_code(s->pc++);
4706
        gen_op_movl_T0_im(val);
4707
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4708
        gen_op_in[ot]();
4709
        gen_op_mov_reg_T1[ot][R_EAX]();
4710
        break;
4711
    case 0xe6:
4712
    case 0xe7:
4713
        if ((b & 1) == 0)
4714
            ot = OT_BYTE;
4715
        else
4716
            ot = dflag ? OT_LONG : OT_WORD;
4717
        val = ldub_code(s->pc++);
4718
        gen_op_movl_T0_im(val);
4719
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4720
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4721
        gen_op_out[ot]();
4722
        break;
4723
    case 0xec:
4724
    case 0xed:
4725
        if ((b & 1) == 0)
4726
            ot = OT_BYTE;
4727
        else
4728
            ot = dflag ? OT_LONG : OT_WORD;
4729
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4730
        gen_op_andl_T0_ffff();
4731
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4732
        gen_op_in[ot]();
4733
        gen_op_mov_reg_T1[ot][R_EAX]();
4734
        break;
4735
    case 0xee:
4736
    case 0xef:
4737
        if ((b & 1) == 0)
4738
            ot = OT_BYTE;
4739
        else
4740
            ot = dflag ? OT_LONG : OT_WORD;
4741
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4742
        gen_op_andl_T0_ffff();
4743
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4744
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4745
        gen_op_out[ot]();
4746
        break;
4747

    
4748
        /************************/
4749
        /* control */
4750
    case 0xc2: /* ret im */
4751
        val = ldsw_code(s->pc);
4752
        s->pc += 2;
4753
        gen_pop_T0(s);
4754
        gen_stack_update(s, val + (2 << s->dflag));
4755
        if (s->dflag == 0)
4756
            gen_op_andl_T0_ffff();
4757
        gen_op_jmp_T0();
4758
        gen_eob(s);
4759
        break;
4760
    case 0xc3: /* ret */
4761
        gen_pop_T0(s);
4762
        gen_pop_update(s);
4763
        if (s->dflag == 0)
4764
            gen_op_andl_T0_ffff();
4765
        gen_op_jmp_T0();
4766
        gen_eob(s);
4767
        break;
4768
    case 0xca: /* lret im */
4769
        val = ldsw_code(s->pc);
4770
        s->pc += 2;
4771
    do_lret:
4772
        if (s->pe && !s->vm86) {
4773
            if (s->cc_op != CC_OP_DYNAMIC)
4774
                gen_op_set_cc_op(s->cc_op);
4775
            gen_jmp_im(pc_start - s->cs_base);
4776
            gen_op_lret_protected(s->dflag, val);
4777
        } else {
4778
            gen_stack_A0(s);
4779
            /* pop offset */
4780
            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
4781
            if (s->dflag == 0)
4782
                gen_op_andl_T0_ffff();
4783
            /* NOTE: keeping EIP updated is not a problem in case of
4784
               exception */
4785
            gen_op_jmp_T0();
4786
            /* pop selector */
4787
            gen_op_addl_A0_im(2 << s->dflag);
4788
            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
4789
            gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
4790
            /* add stack offset */
4791
            gen_stack_update(s, val + (4 << s->dflag));
4792
        }
4793
        gen_eob(s);
4794
        break;
4795
    case 0xcb: /* lret */
4796
        val = 0;
4797
        goto do_lret;
4798
    case 0xcf: /* iret */
4799
        if (!s->pe) {
4800
            /* real mode */
4801
            gen_op_iret_real(s->dflag);
4802
            s->cc_op = CC_OP_EFLAGS;
4803
        } else if (s->vm86) {
4804
            if (s->iopl != 3) {
4805
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4806
            } else {
4807
                gen_op_iret_real(s->dflag);
4808
                s->cc_op = CC_OP_EFLAGS;
4809
            }
4810
        } else {
4811
            if (s->cc_op != CC_OP_DYNAMIC)
4812
                gen_op_set_cc_op(s->cc_op);
4813
            gen_jmp_im(pc_start - s->cs_base);
4814
            gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
4815
            s->cc_op = CC_OP_EFLAGS;
4816
        }
4817
        gen_eob(s);
4818
        break;
4819
    case 0xe8: /* call im */
4820
        {
4821
            if (dflag)
4822
                tval = (int32_t)insn_get(s, OT_LONG);
4823
            else
4824
                tval = (int16_t)insn_get(s, OT_WORD);
4825
            next_eip = s->pc - s->cs_base;
4826
            tval += next_eip;
4827
            if (s->dflag == 0)
4828
                tval &= 0xffff;
4829
            gen_movtl_T0_im(next_eip);
4830
            gen_push_T0(s);
4831
            gen_jmp(s, tval);
4832
        }
4833
        break;
4834
    case 0x9a: /* lcall im */
4835
        {
4836
            unsigned int selector, offset;
4837
            
4838
            if (CODE64(s))
4839
                goto illegal_op;
4840
            ot = dflag ? OT_LONG : OT_WORD;
4841
            offset = insn_get(s, ot);
4842
            selector = insn_get(s, OT_WORD);
4843
            
4844
            gen_op_movl_T0_im(selector);
4845
            gen_op_movl_T1_imu(offset);
4846
        }
4847
        goto do_lcall;
4848
    case 0xe9: /* jmp */
4849
        if (dflag)
4850
            tval = (int32_t)insn_get(s, OT_LONG);
4851
        else
4852
            tval = (int16_t)insn_get(s, OT_WORD);
4853
        tval += s->pc - s->cs_base;
4854
        if (s->dflag == 0)
4855
            tval &= 0xffff;
4856
        gen_jmp(s, tval);
4857
        break;
4858
    case 0xea: /* ljmp im */
4859
        {
4860
            unsigned int selector, offset;
4861

    
4862
            if (CODE64(s))
4863
                goto illegal_op;
4864
            ot = dflag ? OT_LONG : OT_WORD;
4865
            offset = insn_get(s, ot);
4866
            selector = insn_get(s, OT_WORD);
4867
            
4868
            gen_op_movl_T0_im(selector);
4869
            gen_op_movl_T1_imu(offset);
4870
        }
4871
        goto do_ljmp;
4872
    case 0xeb: /* jmp Jb */
4873
        tval = (int8_t)insn_get(s, OT_BYTE);
4874
        tval += s->pc - s->cs_base;
4875
        if (s->dflag == 0)
4876
            tval &= 0xffff;
4877
        gen_jmp(s, tval);
4878
        break;
4879
    case 0x70 ... 0x7f: /* jcc Jb */
4880
        tval = (int8_t)insn_get(s, OT_BYTE);
4881
        goto do_jcc;
4882
    case 0x180 ... 0x18f: /* jcc Jv */
4883
        if (dflag) {
4884
            tval = (int32_t)insn_get(s, OT_LONG);
4885
        } else {
4886
            tval = (int16_t)insn_get(s, OT_WORD); 
4887
        }
4888
    do_jcc:
4889
        next_eip = s->pc - s->cs_base;
4890
        tval += next_eip;
4891
        if (s->dflag == 0)
4892
            tval &= 0xffff;
4893
        gen_jcc(s, b, tval, next_eip);
4894
        break;
4895

    
4896
    case 0x190 ... 0x19f: /* setcc Gv */
4897
        modrm = ldub_code(s->pc++);
4898
        gen_setcc(s, b);
4899
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
4900
        break;
4901
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
4902
        ot = dflag + OT_WORD;
4903
        modrm = ldub_code(s->pc++);
4904
        reg = ((modrm >> 3) & 7) | rex_r;
4905
        mod = (modrm >> 6) & 3;
4906
        gen_setcc(s, b);
4907
        if (mod != 3) {
4908
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4909
            gen_op_ld_T1_A0[ot + s->mem_index]();
4910
        } else {
4911
            rm = (modrm & 7) | REX_B(s);
4912
            gen_op_mov_TN_reg[ot][1][rm]();
4913
        }
4914
        gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
4915
        break;
4916
        
4917
        /************************/
4918
        /* flags */
4919
    case 0x9c: /* pushf */
4920
        if (s->vm86 && s->iopl != 3) {
4921
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4922
        } else {
4923
            if (s->cc_op != CC_OP_DYNAMIC)
4924
                gen_op_set_cc_op(s->cc_op);
4925
            gen_op_movl_T0_eflags();
4926
            gen_push_T0(s);
4927
        }
4928
        break;
4929
    case 0x9d: /* popf */
4930
        if (s->vm86 && s->iopl != 3) {
4931
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4932
        } else {
4933
            gen_pop_T0(s);
4934
            if (s->cpl == 0) {
4935
                if (s->dflag) {
4936
                    gen_op_movl_eflags_T0_cpl0();
4937
                } else {
4938
                    gen_op_movw_eflags_T0_cpl0();
4939
                }
4940
            } else {
4941
                if (s->cpl <= s->iopl) {
4942
                    if (s->dflag) {
4943
                        gen_op_movl_eflags_T0_io();
4944
                    } else {
4945
                        gen_op_movw_eflags_T0_io();
4946
                    }
4947
                } else {
4948
                    if (s->dflag) {
4949
                        gen_op_movl_eflags_T0();
4950
                    } else {
4951
                        gen_op_movw_eflags_T0();
4952
                    }
4953
                }
4954
            }
4955
            gen_pop_update(s);
4956
            s->cc_op = CC_OP_EFLAGS;
4957
            /* abort translation because TF flag may change */
4958
            gen_jmp_im(s->pc - s->cs_base);
4959
            gen_eob(s);
4960
        }
4961
        break;
4962
    case 0x9e: /* sahf */
4963
        if (CODE64(s))
4964
            goto illegal_op;
4965
        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
4966
        if (s->cc_op != CC_OP_DYNAMIC)
4967
            gen_op_set_cc_op(s->cc_op);
4968
        gen_op_movb_eflags_T0();
4969
        s->cc_op = CC_OP_EFLAGS;
4970
        break;
4971
    case 0x9f: /* lahf */
4972
        if (CODE64(s))
4973
            goto illegal_op;
4974
        if (s->cc_op != CC_OP_DYNAMIC)
4975
            gen_op_set_cc_op(s->cc_op);
4976
        gen_op_movl_T0_eflags();
4977
        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
4978
        break;
4979
    case 0xf5: /* cmc */
4980
        if (s->cc_op != CC_OP_DYNAMIC)
4981
            gen_op_set_cc_op(s->cc_op);
4982
        gen_op_cmc();
4983
        s->cc_op = CC_OP_EFLAGS;
4984
        break;
4985
    case 0xf8: /* clc */
4986
        if (s->cc_op != CC_OP_DYNAMIC)
4987
            gen_op_set_cc_op(s->cc_op);
4988
        gen_op_clc();
4989
        s->cc_op = CC_OP_EFLAGS;
4990
        break;
4991
    case 0xf9: /* stc */
4992
        if (s->cc_op != CC_OP_DYNAMIC)
4993
            gen_op_set_cc_op(s->cc_op);
4994
        gen_op_stc();
4995
        s->cc_op = CC_OP_EFLAGS;
4996
        break;
4997
    case 0xfc: /* cld */
4998
        gen_op_cld();
4999
        break;
5000
    case 0xfd: /* std */
5001
        gen_op_std();
5002
        break;
5003

    
5004
        /************************/
5005
        /* bit operations */
5006
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
5007
        ot = dflag + OT_WORD;
5008
        modrm = ldub_code(s->pc++);
5009
        op = ((modrm >> 3) & 7) | rex_r;
5010
        mod = (modrm >> 6) & 3;
5011
        rm = (modrm & 7) | REX_B(s);
5012
        if (mod != 3) {
5013
            s->rip_offset = 1;
5014
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5015
            gen_op_ld_T0_A0[ot + s->mem_index]();
5016
        } else {
5017
            gen_op_mov_TN_reg[ot][0][rm]();
5018
        }
5019
        /* load shift */
5020
        val = ldub_code(s->pc++);
5021
        gen_op_movl_T1_im(val);
5022
        if (op < 4)
5023
            goto illegal_op;
5024
        op -= 4;
5025
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5026
        s->cc_op = CC_OP_SARB + ot;
5027
        if (op != 0) {
5028
            if (mod != 3)
5029
                gen_op_st_T0_A0[ot + s->mem_index]();
5030
            else
5031
                gen_op_mov_reg_T0[ot][rm]();
5032
            gen_op_update_bt_cc();
5033
        }
5034
        break;
5035
    case 0x1a3: /* bt Gv, Ev */
5036
        op = 0;
5037
        goto do_btx;
5038
    case 0x1ab: /* bts */
5039
        op = 1;
5040
        goto do_btx;
5041
    case 0x1b3: /* btr */
5042
        op = 2;
5043
        goto do_btx;
5044
    case 0x1bb: /* btc */
5045
        op = 3;
5046
    do_btx:
5047
        ot = dflag + OT_WORD;
5048
        modrm = ldub_code(s->pc++);
5049
        reg = ((modrm >> 3) & 7) | rex_r;
5050
        mod = (modrm >> 6) & 3;
5051
        rm = (modrm & 7) | REX_B(s);
5052
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
5053
        if (mod != 3) {
5054
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5055
            /* specific case: we need to add a displacement */
5056
            gen_op_add_bit_A0_T1[ot - OT_WORD]();
5057
            gen_op_ld_T0_A0[ot + s->mem_index]();
5058
        } else {
5059
            gen_op_mov_TN_reg[ot][0][rm]();
5060
        }
5061
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5062
        s->cc_op = CC_OP_SARB + ot;
5063
        if (op != 0) {
5064
            if (mod != 3)
5065
                gen_op_st_T0_A0[ot + s->mem_index]();
5066
            else
5067
                gen_op_mov_reg_T0[ot][rm]();
5068
            gen_op_update_bt_cc();
5069
        }
5070
        break;
5071
    case 0x1bc: /* bsf */
5072
    case 0x1bd: /* bsr */
5073
        ot = dflag + OT_WORD;
5074
        modrm = ldub_code(s->pc++);
5075
        reg = ((modrm >> 3) & 7) | rex_r;
5076
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5077
        /* NOTE: in order to handle the 0 case, we must load the
5078
           result. It could be optimized with a generated jump */
5079
        gen_op_mov_TN_reg[ot][1][reg]();
5080
        gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
5081
        gen_op_mov_reg_T1[ot][reg]();
5082
        s->cc_op = CC_OP_LOGICB + ot;
5083
        break;
5084
        /************************/
5085
        /* bcd */
5086
    case 0x27: /* daa */
5087
        if (CODE64(s))
5088
            goto illegal_op;
5089
        if (s->cc_op != CC_OP_DYNAMIC)
5090
            gen_op_set_cc_op(s->cc_op);
5091
        gen_op_daa();
5092
        s->cc_op = CC_OP_EFLAGS;
5093
        break;
5094
    case 0x2f: /* das */
5095
        if (CODE64(s))
5096
            goto illegal_op;
5097
        if (s->cc_op != CC_OP_DYNAMIC)
5098
            gen_op_set_cc_op(s->cc_op);
5099
        gen_op_das();
5100
        s->cc_op = CC_OP_EFLAGS;
5101
        break;
5102
    case 0x37: /* aaa */
5103
        if (CODE64(s))
5104
            goto illegal_op;
5105
        if (s->cc_op != CC_OP_DYNAMIC)
5106
            gen_op_set_cc_op(s->cc_op);
5107
        gen_op_aaa();
5108
        s->cc_op = CC_OP_EFLAGS;
5109
        break;
5110
    case 0x3f: /* aas */
5111
        if (CODE64(s))
5112
            goto illegal_op;
5113
        if (s->cc_op != CC_OP_DYNAMIC)
5114
            gen_op_set_cc_op(s->cc_op);
5115
        gen_op_aas();
5116
        s->cc_op = CC_OP_EFLAGS;
5117
        break;
5118
    case 0xd4: /* aam */
5119
        if (CODE64(s))
5120
            goto illegal_op;
5121
        val = ldub_code(s->pc++);
5122
        gen_op_aam(val);
5123
        s->cc_op = CC_OP_LOGICB;
5124
        break;
5125
    case 0xd5: /* aad */
5126
        if (CODE64(s))
5127
            goto illegal_op;
5128
        val = ldub_code(s->pc++);
5129
        gen_op_aad(val);
5130
        s->cc_op = CC_OP_LOGICB;
5131
        break;
5132
        /************************/
5133
        /* misc */
5134
    case 0x90: /* nop */
5135
        /* XXX: xchg + rex handling */
5136
        /* XXX: correct lock test for all insn */
5137
        if (prefixes & PREFIX_LOCK)
5138
            goto illegal_op;
5139
        break;
5140
    case 0x9b: /* fwait */
5141
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 
5142
            (HF_MP_MASK | HF_TS_MASK)) {
5143
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5144
        } else {
5145
            if (s->cc_op != CC_OP_DYNAMIC)
5146
                gen_op_set_cc_op(s->cc_op);
5147
            gen_jmp_im(pc_start - s->cs_base);
5148
            gen_op_fwait();
5149
        }
5150
        break;
5151
    case 0xcc: /* int3 */
5152
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
5153
        break;
5154
    case 0xcd: /* int N */
5155
        val = ldub_code(s->pc++);
5156
        if (s->vm86 && s->iopl != 3) {
5157
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 
5158
        } else {
5159
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
5160
        }
5161
        break;
5162
    case 0xce: /* into */
5163
        if (CODE64(s))
5164
            goto illegal_op;
5165
        if (s->cc_op != CC_OP_DYNAMIC)
5166
            gen_op_set_cc_op(s->cc_op);
5167
        gen_jmp_im(pc_start - s->cs_base);
5168
        gen_op_into(s->pc - pc_start);
5169
        break;
5170
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
5171
        gen_debug(s, pc_start - s->cs_base);
5172
        break;
5173
    case 0xfa: /* cli */
5174
        if (!s->vm86) {
5175
            if (s->cpl <= s->iopl) {
5176
                gen_op_cli();
5177
            } else {
5178
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5179
            }
5180
        } else {
5181
            if (s->iopl == 3) {
5182
                gen_op_cli();
5183
            } else {
5184
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5185
            }
5186
        }
5187
        break;
5188
    case 0xfb: /* sti */
5189
        if (!s->vm86) {
5190
            if (s->cpl <= s->iopl) {
5191
            gen_sti:
5192
                gen_op_sti();
5193
                /* interruptions are enabled only the first insn after sti */
5194
                /* If several instructions disable interrupts, only the
5195
                   _first_ does it */
5196
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5197
                    gen_op_set_inhibit_irq();
5198
                /* give a chance to handle pending irqs */
5199
                gen_jmp_im(s->pc - s->cs_base);
5200
                gen_eob(s);
5201
            } else {
5202
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5203
            }
5204
        } else {
5205
            if (s->iopl == 3) {
5206
                goto gen_sti;
5207
            } else {
5208
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5209
            }
5210
        }
5211
        break;
5212
    case 0x62: /* bound */
5213
        if (CODE64(s))
5214
            goto illegal_op;
5215
        ot = dflag ? OT_LONG : OT_WORD;
5216
        modrm = ldub_code(s->pc++);
5217
        reg = (modrm >> 3) & 7;
5218
        mod = (modrm >> 6) & 3;
5219
        if (mod == 3)
5220
            goto illegal_op;
5221
        gen_op_mov_TN_reg[ot][0][reg]();
5222
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5223
        gen_jmp_im(pc_start - s->cs_base);
5224
        if (ot == OT_WORD)
5225
            gen_op_boundw();
5226
        else
5227
            gen_op_boundl();
5228
        break;
5229
    case 0x1c8 ... 0x1cf: /* bswap reg */
5230
        reg = (b & 7) | REX_B(s);
5231
#ifdef TARGET_X86_64
5232
        if (dflag == 2) {
5233
            gen_op_mov_TN_reg[OT_QUAD][0][reg]();
5234
            gen_op_bswapq_T0();
5235
            gen_op_mov_reg_T0[OT_QUAD][reg]();
5236
        } else 
5237
#endif
5238
        {
5239
            gen_op_mov_TN_reg[OT_LONG][0][reg]();
5240
            gen_op_bswapl_T0();
5241
            gen_op_mov_reg_T0[OT_LONG][reg]();
5242
        }
5243
        break;
5244
    case 0xd6: /* salc */
5245
        if (CODE64(s))
5246
            goto illegal_op;
5247
        if (s->cc_op != CC_OP_DYNAMIC)
5248
            gen_op_set_cc_op(s->cc_op);
5249
        gen_op_salc();
5250
        break;
5251
    case 0xe0: /* loopnz */
5252
    case 0xe1: /* loopz */
5253
        if (s->cc_op != CC_OP_DYNAMIC)
5254
            gen_op_set_cc_op(s->cc_op);
5255
        /* FALL THRU */
5256
    case 0xe2: /* loop */
5257
    case 0xe3: /* jecxz */
5258
        {
5259
            int l1, l2;
5260

    
5261
            tval = (int8_t)insn_get(s, OT_BYTE);
5262
            next_eip = s->pc - s->cs_base;
5263
            tval += next_eip;
5264
            if (s->dflag == 0)
5265
                tval &= 0xffff;
5266
            
5267
            l1 = gen_new_label();
5268
            l2 = gen_new_label();
5269
            b &= 3;
5270
            if (b == 3) {
5271
                gen_op_jz_ecx[s->aflag](l1);
5272
            } else {
5273
                gen_op_dec_ECX[s->aflag]();
5274
                gen_op_loop[s->aflag][b](l1);
5275
            }
5276

    
5277
            gen_jmp_im(next_eip);
5278
            gen_op_jmp_label(l2);
5279
            gen_set_label(l1);
5280
            gen_jmp_im(tval);
5281
            gen_set_label(l2);
5282
            gen_eob(s);
5283
        }
5284
        break;
5285
    case 0x130: /* wrmsr */
5286
    case 0x132: /* rdmsr */
5287
        if (s->cpl != 0) {
5288
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5289
        } else {
5290
            if (b & 2)
5291
                gen_op_rdmsr();
5292
            else
5293
                gen_op_wrmsr();
5294
        }
5295
        break;
5296
    case 0x131: /* rdtsc */
5297
        gen_op_rdtsc();
5298
        break;
5299
    case 0x134: /* sysenter */
5300
        if (CODE64(s))
5301
            goto illegal_op;
5302
        if (!s->pe) {
5303
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5304
        } else {
5305
            if (s->cc_op != CC_OP_DYNAMIC) {
5306
                gen_op_set_cc_op(s->cc_op);
5307
                s->cc_op = CC_OP_DYNAMIC;
5308
            }
5309
            gen_jmp_im(pc_start - s->cs_base);
5310
            gen_op_sysenter();
5311
            gen_eob(s);
5312
        }
5313
        break;
5314
    case 0x135: /* sysexit */
5315
        if (CODE64(s))
5316
            goto illegal_op;
5317
        if (!s->pe) {
5318
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5319
        } else {
5320
            if (s->cc_op != CC_OP_DYNAMIC) {
5321
                gen_op_set_cc_op(s->cc_op);
5322
                s->cc_op = CC_OP_DYNAMIC;
5323
            }
5324
            gen_jmp_im(pc_start - s->cs_base);
5325
            gen_op_sysexit();
5326
            gen_eob(s);
5327
        }
5328
        break;
5329
#ifdef TARGET_X86_64
5330
    case 0x105: /* syscall */
5331
        /* XXX: is it usable in real mode ? */
5332
        if (s->cc_op != CC_OP_DYNAMIC) {
5333
            gen_op_set_cc_op(s->cc_op);
5334
            s->cc_op = CC_OP_DYNAMIC;
5335
        }
5336
        gen_jmp_im(pc_start - s->cs_base);
5337
        gen_op_syscall(s->pc - pc_start);
5338
        gen_eob(s);
5339
        break;
5340
    case 0x107: /* sysret */
5341
        if (!s->pe) {
5342
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5343
        } else {
5344
            if (s->cc_op != CC_OP_DYNAMIC) {
5345
                gen_op_set_cc_op(s->cc_op);
5346
                s->cc_op = CC_OP_DYNAMIC;
5347
            }
5348
            gen_jmp_im(pc_start - s->cs_base);
5349
            gen_op_sysret(s->dflag);
5350
            gen_eob(s);
5351
        }
5352
        break;
5353
#endif
5354
    case 0x1a2: /* cpuid */
5355
        gen_op_cpuid();
5356
        break;
5357
    case 0xf4: /* hlt */
5358
        if (s->cpl != 0) {
5359
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5360
        } else {
5361
            if (s->cc_op != CC_OP_DYNAMIC)
5362
                gen_op_set_cc_op(s->cc_op);
5363
            gen_jmp_im(s->pc - s->cs_base);
5364
            gen_op_hlt();
5365
            s->is_jmp = 3;
5366
        }
5367
        break;
5368
    case 0x100:
5369
        modrm = ldub_code(s->pc++);
5370
        mod = (modrm >> 6) & 3;
5371
        op = (modrm >> 3) & 7;
5372
        switch(op) {
5373
        case 0: /* sldt */
5374
            if (!s->pe || s->vm86)
5375
                goto illegal_op;
5376
            gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
5377
            ot = OT_WORD;
5378
            if (mod == 3)
5379
                ot += s->dflag;
5380
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5381
            break;
5382
        case 2: /* lldt */
5383
            if (!s->pe || s->vm86)
5384
                goto illegal_op;
5385
            if (s->cpl != 0) {
5386
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5387
            } else {
5388
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5389
                gen_jmp_im(pc_start - s->cs_base);
5390
                gen_op_lldt_T0();
5391
            }
5392
            break;
5393
        case 1: /* str */
5394
            if (!s->pe || s->vm86)
5395
                goto illegal_op;
5396
            gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
5397
            ot = OT_WORD;
5398
            if (mod == 3)
5399
                ot += s->dflag;
5400
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5401
            break;
5402
        case 3: /* ltr */
5403
            if (!s->pe || s->vm86)
5404
                goto illegal_op;
5405
            if (s->cpl != 0) {
5406
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5407
            } else {
5408
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5409
                gen_jmp_im(pc_start - s->cs_base);
5410
                gen_op_ltr_T0();
5411
            }
5412
            break;
5413
        case 4: /* verr */
5414
        case 5: /* verw */
5415
            if (!s->pe || s->vm86)
5416
                goto illegal_op;
5417
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5418
            if (s->cc_op != CC_OP_DYNAMIC)
5419
                gen_op_set_cc_op(s->cc_op);
5420
            if (op == 4)
5421
                gen_op_verr();
5422
            else
5423
                gen_op_verw();
5424
            s->cc_op = CC_OP_EFLAGS;
5425
            break;
5426
        default:
5427
            goto illegal_op;
5428
        }
5429
        break;
5430
    case 0x101:
5431
        modrm = ldub_code(s->pc++);
5432
        mod = (modrm >> 6) & 3;
5433
        op = (modrm >> 3) & 7;
5434
        switch(op) {
5435
        case 0: /* sgdt */
5436
        case 1: /* sidt */
5437
            if (mod == 3)
5438
                goto illegal_op;
5439
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5440
            if (op == 0)
5441
                gen_op_movl_T0_env(offsetof(CPUX86State,gdt.limit));
5442
            else
5443
                gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit));
5444
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
5445
#ifdef TARGET_X86_64
5446
            if (CODE64(s)) 
5447
                gen_op_addq_A0_im(2);
5448
            else
5449
#endif
5450
                gen_op_addl_A0_im(2);
5451
            if (op == 0)
5452
                gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base));
5453
            else
5454
                gen_op_movtl_T0_env(offsetof(CPUX86State,idt.base));
5455
            if (!s->dflag)
5456
                gen_op_andl_T0_im(0xffffff);
5457
            gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5458
            break;
5459
        case 2: /* lgdt */
5460
        case 3: /* lidt */
5461
            if (mod == 3)
5462
                goto illegal_op;
5463
            if (s->cpl != 0) {
5464
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5465
            } else {
5466
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5467
                gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
5468
#ifdef TARGET_X86_64
5469
                if (CODE64(s))
5470
                    gen_op_addq_A0_im(2);
5471
                else
5472
#endif
5473
                    gen_op_addl_A0_im(2);
5474
                gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5475
                if (!s->dflag)
5476
                    gen_op_andl_T0_im(0xffffff);
5477
                if (op == 2) {
5478
                    gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
5479
                    gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
5480
                } else {
5481
                    gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
5482
                    gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
5483
                }
5484
            }
5485
            break;
5486
        case 4: /* smsw */
5487
            gen_op_movl_T0_env(offsetof(CPUX86State,cr[0]));
5488
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
5489
            break;
5490
        case 6: /* lmsw */
5491
            if (s->cpl != 0) {
5492
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5493
            } else {
5494
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5495
                gen_op_lmsw_T0();
5496
                gen_jmp_im(s->pc - s->cs_base);
5497
                gen_eob(s);
5498
            }
5499
            break;
5500
        case 7: /* invlpg */
5501
            if (s->cpl != 0) {
5502
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5503
            } else {
5504
                if (mod == 3) {
5505
#ifdef TARGET_X86_64
5506
                    if (CODE64(s) && (modrm & 7) == 0) {
5507
                        /* swapgs */
5508
                        gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
5509
                        gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
5510
                        gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
5511
                        gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
5512
                    } else 
5513
#endif
5514
                    {
5515
                        goto illegal_op;
5516
                    }
5517
                } else {
5518
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5519
                    gen_op_invlpg_A0();
5520
                    gen_jmp_im(s->pc - s->cs_base);
5521
                    gen_eob(s);
5522
                }
5523
            }
5524
            break;
5525
        default:
5526
            goto illegal_op;
5527
        }
5528
        break;
5529
    case 0x108: /* invd */
5530
    case 0x109: /* wbinvd */
5531
        if (s->cpl != 0) {
5532
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5533
        } else {
5534
            /* nothing to do */
5535
        }
5536
        break;
5537
    case 0x63: /* arpl or movslS (x86_64) */
5538
#ifdef TARGET_X86_64
5539
        if (CODE64(s)) {
5540
            int d_ot;
5541
            /* d_ot is the size of destination */
5542
            d_ot = dflag + OT_WORD;
5543

    
5544
            modrm = ldub_code(s->pc++);
5545
            reg = ((modrm >> 3) & 7) | rex_r;
5546
            mod = (modrm >> 6) & 3;
5547
            rm = (modrm & 7) | REX_B(s);
5548
            
5549
            if (mod == 3) {
5550
                gen_op_mov_TN_reg[OT_LONG][0][rm]();
5551
                /* sign extend */
5552
                if (d_ot == OT_QUAD)
5553
                    gen_op_movslq_T0_T0();
5554
                gen_op_mov_reg_T0[d_ot][reg]();
5555
            } else {
5556
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5557
                if (d_ot == OT_QUAD) {
5558
                    gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
5559
                } else {
5560
                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5561
                }
5562
                gen_op_mov_reg_T0[d_ot][reg]();
5563
            }
5564
        } else 
5565
#endif
5566
        {
5567
            if (!s->pe || s->vm86)
5568
                goto illegal_op;
5569
            ot = dflag ? OT_LONG : OT_WORD;
5570
            modrm = ldub_code(s->pc++);
5571
            reg = (modrm >> 3) & 7;
5572
            mod = (modrm >> 6) & 3;
5573
            rm = modrm & 7;
5574
            if (mod != 3) {
5575
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5576
                gen_op_ld_T0_A0[ot + s->mem_index]();
5577
            } else {
5578
                gen_op_mov_TN_reg[ot][0][rm]();
5579
            }
5580
            if (s->cc_op != CC_OP_DYNAMIC)
5581
                gen_op_set_cc_op(s->cc_op);
5582
            gen_op_arpl();
5583
            s->cc_op = CC_OP_EFLAGS;
5584
            if (mod != 3) {
5585
                gen_op_st_T0_A0[ot + s->mem_index]();
5586
            } else {
5587
                gen_op_mov_reg_T0[ot][rm]();
5588
            }
5589
            gen_op_arpl_update();
5590
        }
5591
        break;
5592
    case 0x102: /* lar */
5593
    case 0x103: /* lsl */
5594
        if (!s->pe || s->vm86)
5595
            goto illegal_op;
5596
        ot = dflag ? OT_LONG : OT_WORD;
5597
        modrm = ldub_code(s->pc++);
5598
        reg = ((modrm >> 3) & 7) | rex_r;
5599
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5600
        gen_op_mov_TN_reg[ot][1][reg]();
5601
        if (s->cc_op != CC_OP_DYNAMIC)
5602
            gen_op_set_cc_op(s->cc_op);
5603
        if (b == 0x102)
5604
            gen_op_lar();
5605
        else
5606
            gen_op_lsl();
5607
        s->cc_op = CC_OP_EFLAGS;
5608
        gen_op_mov_reg_T1[ot][reg]();
5609
        break;
5610
    case 0x118:
5611
        modrm = ldub_code(s->pc++);
5612
        mod = (modrm >> 6) & 3;
5613
        op = (modrm >> 3) & 7;
5614
        switch(op) {
5615
        case 0: /* prefetchnta */
5616
        case 1: /* prefetchnt0 */
5617
        case 2: /* prefetchnt0 */
5618
        case 3: /* prefetchnt0 */
5619
            if (mod == 3)
5620
                goto illegal_op;
5621
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5622
            /* nothing more to do */
5623
            break;
5624
        default:
5625
            goto illegal_op;
5626
        }
5627
        break;
5628
    case 0x120: /* mov reg, crN */
5629
    case 0x122: /* mov crN, reg */
5630
        if (s->cpl != 0) {
5631
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5632
        } else {
5633
            modrm = ldub_code(s->pc++);
5634
            if ((modrm & 0xc0) != 0xc0)
5635
                goto illegal_op;
5636
            rm = (modrm & 7) | REX_B(s);
5637
            reg = ((modrm >> 3) & 7) | rex_r;
5638
            if (CODE64(s))
5639
                ot = OT_QUAD;
5640
            else
5641
                ot = OT_LONG;
5642
            switch(reg) {
5643
            case 0:
5644
            case 2:
5645
            case 3:
5646
            case 4:
5647
            case 8:
5648
                if (b & 2) {
5649
                    gen_op_mov_TN_reg[ot][0][rm]();
5650
                    gen_op_movl_crN_T0(reg);
5651
                    gen_jmp_im(s->pc - s->cs_base);
5652
                    gen_eob(s);
5653
                } else {
5654
#if !defined(CONFIG_USER_ONLY) 
5655
                    if (reg == 8)
5656
                        gen_op_movtl_T0_cr8();
5657
                    else
5658
#endif
5659
                        gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
5660
                    gen_op_mov_reg_T0[ot][rm]();
5661
                }
5662
                break;
5663
            default:
5664
                goto illegal_op;
5665
            }
5666
        }
5667
        break;
5668
    case 0x121: /* mov reg, drN */
5669
    case 0x123: /* mov drN, reg */
5670
        if (s->cpl != 0) {
5671
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5672
        } else {
5673
            modrm = ldub_code(s->pc++);
5674
            if ((modrm & 0xc0) != 0xc0)
5675
                goto illegal_op;
5676
            rm = (modrm & 7) | REX_B(s);
5677
            reg = ((modrm >> 3) & 7) | rex_r;
5678
            if (CODE64(s))
5679
                ot = OT_QUAD;
5680
            else
5681
                ot = OT_LONG;
5682
            /* XXX: do it dynamically with CR4.DE bit */
5683
            if (reg == 4 || reg == 5 || reg >= 8)
5684
                goto illegal_op;
5685
            if (b & 2) {
5686
                gen_op_mov_TN_reg[ot][0][rm]();
5687
                gen_op_movl_drN_T0(reg);
5688
                gen_jmp_im(s->pc - s->cs_base);
5689
                gen_eob(s);
5690
            } else {
5691
                gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
5692
                gen_op_mov_reg_T0[ot][rm]();
5693
            }
5694
        }
5695
        break;
5696
    case 0x106: /* clts */
5697
        if (s->cpl != 0) {
5698
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5699
        } else {
5700
            gen_op_clts();
5701
            /* abort block because static cpu state changed */
5702
            gen_jmp_im(s->pc - s->cs_base);
5703
            gen_eob(s);
5704
        }
5705
        break;
5706
    /* MMX/SSE/SSE2/PNI support */
5707
    case 0x1c3: /* MOVNTI reg, mem */
5708
        if (!(s->cpuid_features & CPUID_SSE2))
5709
            goto illegal_op;
5710
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
5711
        modrm = ldub_code(s->pc++);
5712
        mod = (modrm >> 6) & 3;
5713
        if (mod == 3)
5714
            goto illegal_op;
5715
        reg = ((modrm >> 3) & 7) | rex_r;
5716
        /* generate a generic store */
5717
        gen_ldst_modrm(s, modrm, ot, reg, 1);
5718
        break;
5719
    case 0x1ae:
5720
        modrm = ldub_code(s->pc++);
5721
        mod = (modrm >> 6) & 3;
5722
        op = (modrm >> 3) & 7;
5723
        switch(op) {
5724
        case 0: /* fxsave */
5725
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
5726
                goto illegal_op;
5727
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5728
            gen_op_fxsave_A0((s->dflag == 2));
5729
            break;
5730
        case 1: /* fxrstor */
5731
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR))
5732
                goto illegal_op;
5733
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5734
            gen_op_fxrstor_A0((s->dflag == 2));
5735
            break;
5736
        case 2: /* ldmxcsr */
5737
        case 3: /* stmxcsr */
5738
            if (s->flags & HF_TS_MASK) {
5739
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5740
                break;
5741
            }
5742
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
5743
                mod == 3)
5744
                goto illegal_op;
5745
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5746
            if (op == 2) {
5747
                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5748
                gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
5749
            } else {
5750
                gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
5751
                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
5752
            }
5753
            break;
5754
        case 5: /* lfence */
5755
        case 6: /* mfence */
5756
        case 7: /* sfence */
5757
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
5758
                goto illegal_op;
5759
            break;
5760
        default:
5761
            goto illegal_op;
5762
        }
5763
        break;
5764
    case 0x110 ... 0x117:
5765
    case 0x128 ... 0x12f:
5766
    case 0x150 ... 0x177:
5767
    case 0x17c ... 0x17f:
5768
    case 0x1c2:
5769
    case 0x1c4 ... 0x1c6:
5770
    case 0x1d0 ... 0x1fe:
5771
        gen_sse(s, b, pc_start, rex_r);
5772
        break;
5773
    default:
5774
        goto illegal_op;
5775
    }
5776
    /* lock generation */
5777
    if (s->prefix & PREFIX_LOCK)
5778
        gen_op_unlock();
5779
    return s->pc;
5780
 illegal_op:
5781
    if (s->prefix & PREFIX_LOCK)
5782
        gen_op_unlock();
5783
    /* XXX: ensure that no lock was generated */
5784
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
5785
    return s->pc;
5786
}
5787

    
5788
#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
5789
#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
5790

    
5791
/* flags read by an operation */
5792
static uint16_t opc_read_flags[NB_OPS] = { 
5793
    [INDEX_op_aas] = CC_A,
5794
    [INDEX_op_aaa] = CC_A,
5795
    [INDEX_op_das] = CC_A | CC_C,
5796
    [INDEX_op_daa] = CC_A | CC_C,
5797

    
5798
    /* subtle: due to the incl/decl implementation, C is used */
5799
    [INDEX_op_update_inc_cc] = CC_C, 
5800

    
5801
    [INDEX_op_into] = CC_O,
5802

    
5803
    [INDEX_op_jb_subb] = CC_C,
5804
    [INDEX_op_jb_subw] = CC_C,
5805
    [INDEX_op_jb_subl] = CC_C,
5806

    
5807
    [INDEX_op_jz_subb] = CC_Z,
5808
    [INDEX_op_jz_subw] = CC_Z,
5809
    [INDEX_op_jz_subl] = CC_Z,
5810

    
5811
    [INDEX_op_jbe_subb] = CC_Z | CC_C,
5812
    [INDEX_op_jbe_subw] = CC_Z | CC_C,
5813
    [INDEX_op_jbe_subl] = CC_Z | CC_C,
5814

    
5815
    [INDEX_op_js_subb] = CC_S,
5816
    [INDEX_op_js_subw] = CC_S,
5817
    [INDEX_op_js_subl] = CC_S,
5818

    
5819
    [INDEX_op_jl_subb] = CC_O | CC_S,
5820
    [INDEX_op_jl_subw] = CC_O | CC_S,
5821
    [INDEX_op_jl_subl] = CC_O | CC_S,
5822

    
5823
    [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
5824
    [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
5825
    [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
5826

    
5827
    [INDEX_op_loopnzw] = CC_Z,
5828
    [INDEX_op_loopnzl] = CC_Z,
5829
    [INDEX_op_loopzw] = CC_Z,
5830
    [INDEX_op_loopzl] = CC_Z,
5831

    
5832
    [INDEX_op_seto_T0_cc] = CC_O,
5833
    [INDEX_op_setb_T0_cc] = CC_C,
5834
    [INDEX_op_setz_T0_cc] = CC_Z,
5835
    [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
5836
    [INDEX_op_sets_T0_cc] = CC_S,
5837
    [INDEX_op_setp_T0_cc] = CC_P,
5838
    [INDEX_op_setl_T0_cc] = CC_O | CC_S,
5839
    [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
5840

    
5841
    [INDEX_op_setb_T0_subb] = CC_C,
5842
    [INDEX_op_setb_T0_subw] = CC_C,
5843
    [INDEX_op_setb_T0_subl] = CC_C,
5844

    
5845
    [INDEX_op_setz_T0_subb] = CC_Z,
5846
    [INDEX_op_setz_T0_subw] = CC_Z,
5847
    [INDEX_op_setz_T0_subl] = CC_Z,
5848

    
5849
    [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
5850
    [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
5851
    [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
5852

    
5853
    [INDEX_op_sets_T0_subb] = CC_S,
5854
    [INDEX_op_sets_T0_subw] = CC_S,
5855
    [INDEX_op_sets_T0_subl] = CC_S,
5856

    
5857
    [INDEX_op_setl_T0_subb] = CC_O | CC_S,
5858
    [INDEX_op_setl_T0_subw] = CC_O | CC_S,
5859
    [INDEX_op_setl_T0_subl] = CC_O | CC_S,
5860

    
5861
    [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
5862
    [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
5863
    [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
5864

    
5865
    [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
5866
    [INDEX_op_cmc] = CC_C,
5867
    [INDEX_op_salc] = CC_C,
5868

    
5869
    /* needed for correct flag optimisation before string ops */
5870
    [INDEX_op_jnz_ecxw] = CC_OSZAPC,
5871
    [INDEX_op_jnz_ecxl] = CC_OSZAPC,
5872
    [INDEX_op_jz_ecxw] = CC_OSZAPC,
5873
    [INDEX_op_jz_ecxl] = CC_OSZAPC,
5874

    
5875
#ifdef TARGET_X86_64
5876
    [INDEX_op_jb_subq] = CC_C,
5877
    [INDEX_op_jz_subq] = CC_Z,
5878
    [INDEX_op_jbe_subq] = CC_Z | CC_C,
5879
    [INDEX_op_js_subq] = CC_S,
5880
    [INDEX_op_jl_subq] = CC_O | CC_S,
5881
    [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
5882

    
5883
    [INDEX_op_loopnzq] = CC_Z,
5884
    [INDEX_op_loopzq] = CC_Z,
5885

    
5886
    [INDEX_op_setb_T0_subq] = CC_C,
5887
    [INDEX_op_setz_T0_subq] = CC_Z,
5888
    [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
5889
    [INDEX_op_sets_T0_subq] = CC_S,
5890
    [INDEX_op_setl_T0_subq] = CC_O | CC_S,
5891
    [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
5892

    
5893
    [INDEX_op_jnz_ecxq] = CC_OSZAPC,
5894
    [INDEX_op_jz_ecxq] = CC_OSZAPC,
5895
#endif
5896

    
5897
#define DEF_READF(SUFFIX)\
5898
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5899
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5900
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5901
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5902
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5903
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5904
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5905
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5906
\
5907
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5908
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5909
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
5910
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5911
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5912
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5913
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5914
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
5915

    
5916
    DEF_READF( )
5917
    DEF_READF(_raw)
5918
#ifndef CONFIG_USER_ONLY
5919
    DEF_READF(_kernel)
5920
    DEF_READF(_user)
5921
#endif
5922
};
5923

    
5924
/* flags written by an operation */
5925
static uint16_t opc_write_flags[NB_OPS] = { 
5926
    [INDEX_op_update2_cc] = CC_OSZAPC,
5927
    [INDEX_op_update1_cc] = CC_OSZAPC,
5928
    [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
5929
    [INDEX_op_update_neg_cc] = CC_OSZAPC,
5930
    /* subtle: due to the incl/decl implementation, C is used */
5931
    [INDEX_op_update_inc_cc] = CC_OSZAPC, 
5932
    [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
5933

    
5934
    [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
5935
    [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
5936
    [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
5937
    X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
5938
    [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
5939
    [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
5940
    [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
5941
    X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
5942
    [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
5943
    [INDEX_op_imull_T0_T1] = CC_OSZAPC,
5944
    X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
5945

    
5946
    /* sse */
5947
    [INDEX_op_ucomiss] = CC_OSZAPC,
5948
    [INDEX_op_ucomisd] = CC_OSZAPC,
5949
    [INDEX_op_comiss] = CC_OSZAPC,
5950
    [INDEX_op_comisd] = CC_OSZAPC,
5951

    
5952
    /* bcd */
5953
    [INDEX_op_aam] = CC_OSZAPC,
5954
    [INDEX_op_aad] = CC_OSZAPC,
5955
    [INDEX_op_aas] = CC_OSZAPC,
5956
    [INDEX_op_aaa] = CC_OSZAPC,
5957
    [INDEX_op_das] = CC_OSZAPC,
5958
    [INDEX_op_daa] = CC_OSZAPC,
5959

    
5960
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
5961
    [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
5962
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
5963
    [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
5964
    [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
5965
    [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
5966
    [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
5967
    [INDEX_op_clc] = CC_C,
5968
    [INDEX_op_stc] = CC_C,
5969
    [INDEX_op_cmc] = CC_C,
5970

    
5971
    [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
5972
    [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
5973
    X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
5974
    [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
5975
    [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
5976
    X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
5977
    [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
5978
    [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
5979
    X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
5980
    [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
5981
    [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
5982
    X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
5983

    
5984
    [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
5985
    [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
5986
    X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
5987
    [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
5988
    [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
5989
    X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
5990

    
5991
    [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
5992
    [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
5993
    [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
5994
    X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
5995

    
5996
    [INDEX_op_cmpxchg8b] = CC_Z,
5997
    [INDEX_op_lar] = CC_Z,
5998
    [INDEX_op_lsl] = CC_Z,
5999
    [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6000
    [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6001

    
6002
#define DEF_WRITEF(SUFFIX)\
6003
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6004
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6005
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6006
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6007
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6008
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6009
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6010
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6011
\
6012
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6013
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6014
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6015
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6016
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6017
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6018
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6019
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6020
\
6021
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6022
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6023
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6024
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6025
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6026
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6027
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6028
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6029
\
6030
    [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6031
    [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6032
    [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6033
    X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6034
\
6035
    [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6036
    [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6037
    [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6038
    X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6039
\
6040
    [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6041
    [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6042
    [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6043
    X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6044
\
6045
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6046
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6047
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6048
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6049
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6050
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6051
\
6052
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6053
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6054
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6055
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6056
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6057
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6058
\
6059
    [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6060
    [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6061
    [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6062
    X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
6063

    
6064

    
6065
    DEF_WRITEF( )
6066
    DEF_WRITEF(_raw)
6067
#ifndef CONFIG_USER_ONLY
6068
    DEF_WRITEF(_kernel)
6069
    DEF_WRITEF(_user)
6070
#endif
6071
};
6072

    
6073
/* simpler form of an operation if no flags need to be generated */
6074
static uint16_t opc_simpler[NB_OPS] = { 
6075
    [INDEX_op_update2_cc] = INDEX_op_nop,
6076
    [INDEX_op_update1_cc] = INDEX_op_nop,
6077
    [INDEX_op_update_neg_cc] = INDEX_op_nop,
6078
#if 0
6079
    /* broken: CC_OP logic must be rewritten */
6080
    [INDEX_op_update_inc_cc] = INDEX_op_nop,
6081
#endif
6082

    
6083
    [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
6084
    [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
6085
    [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
6086
    X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
6087

    
6088
    [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
6089
    [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
6090
    [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
6091
    X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
6092

    
6093
    [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
6094
    [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
6095
    [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
6096
    X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
6097

    
6098
#define DEF_SIMPLER(SUFFIX)\
6099
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
6100
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
6101
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
6102
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
6103
\
6104
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
6105
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
6106
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
6107
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
6108

    
6109
    DEF_SIMPLER( )
6110
    DEF_SIMPLER(_raw)
6111
#ifndef CONFIG_USER_ONLY
6112
    DEF_SIMPLER(_kernel)
6113
    DEF_SIMPLER(_user)
6114
#endif
6115
};
6116

    
6117
void optimize_flags_init(void)
6118
{
6119
    int i;
6120
    /* put default values in arrays */
6121
    for(i = 0; i < NB_OPS; i++) {
6122
        if (opc_simpler[i] == 0)
6123
            opc_simpler[i] = i;
6124
    }
6125
}
6126

    
6127
/* CPU flags computation optimization: we move backward thru the
6128
   generated code to see which flags are needed. The operation is
6129
   modified if suitable */
6130
static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
6131
{
6132
    uint16_t *opc_ptr;
6133
    int live_flags, write_flags, op;
6134

    
6135
    opc_ptr = opc_buf + opc_buf_len;
6136
    /* live_flags contains the flags needed by the next instructions
6137
       in the code. At the end of the bloc, we consider that all the
6138
       flags are live. */
6139
    live_flags = CC_OSZAPC;
6140
    while (opc_ptr > opc_buf) {
6141
        op = *--opc_ptr;
6142
        /* if none of the flags written by the instruction is used,
6143
           then we can try to find a simpler instruction */
6144
        write_flags = opc_write_flags[op];
6145
        if ((live_flags & write_flags) == 0) {
6146
            *opc_ptr = opc_simpler[op];
6147
        }
6148
        /* compute the live flags before the instruction */
6149
        live_flags &= ~write_flags;
6150
        live_flags |= opc_read_flags[op];
6151
    }
6152
}
6153

    
6154
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
6155
   basic block 'tb'. If search_pc is TRUE, also generate PC
6156
   information for each intermediate instruction. */
6157
static inline int gen_intermediate_code_internal(CPUState *env,
6158
                                                 TranslationBlock *tb, 
6159
                                                 int search_pc)
6160
{
6161
    DisasContext dc1, *dc = &dc1;
6162
    target_ulong pc_ptr;
6163
    uint16_t *gen_opc_end;
6164
    int flags, j, lj, cflags;
6165
    target_ulong pc_start;
6166
    target_ulong cs_base;
6167
    
6168
    /* generate intermediate code */
6169
    pc_start = tb->pc;
6170
    cs_base = tb->cs_base;
6171
    flags = tb->flags;
6172
    cflags = tb->cflags;
6173

    
6174
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
6175
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
6176
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
6177
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
6178
    dc->f_st = 0;
6179
    dc->vm86 = (flags >> VM_SHIFT) & 1;
6180
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
6181
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
6182
    dc->tf = (flags >> TF_SHIFT) & 1;
6183
    dc->singlestep_enabled = env->singlestep_enabled;
6184
    dc->cc_op = CC_OP_DYNAMIC;
6185
    dc->cs_base = cs_base;
6186
    dc->tb = tb;
6187
    dc->popl_esp_hack = 0;
6188
    /* select memory access functions */
6189
    dc->mem_index = 0;
6190
    if (flags & HF_SOFTMMU_MASK) {
6191
        if (dc->cpl == 3)
6192
            dc->mem_index = 2 * 4;
6193
        else
6194
            dc->mem_index = 1 * 4;
6195
    }
6196
    dc->cpuid_features = env->cpuid_features;
6197
#ifdef TARGET_X86_64
6198
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
6199
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
6200
#endif
6201
    dc->flags = flags;
6202
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
6203
                    (flags & HF_INHIBIT_IRQ_MASK)
6204
#ifndef CONFIG_SOFTMMU
6205
                    || (flags & HF_SOFTMMU_MASK)
6206
#endif
6207
                    );
6208
#if 0
6209
    /* check addseg logic */
6210
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
6211
        printf("ERROR addseg\n");
6212
#endif
6213

    
6214
    gen_opc_ptr = gen_opc_buf;
6215
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6216
    gen_opparam_ptr = gen_opparam_buf;
6217
    nb_gen_labels = 0;
6218

    
6219
    dc->is_jmp = DISAS_NEXT;
6220
    pc_ptr = pc_start;
6221
    lj = -1;
6222

    
6223
    for(;;) {
6224
        if (env->nb_breakpoints > 0) {
6225
            for(j = 0; j < env->nb_breakpoints; j++) {
6226
                if (env->breakpoints[j] == pc_ptr) {
6227
                    gen_debug(dc, pc_ptr - dc->cs_base);
6228
                    break;
6229
                }
6230
            }
6231
        }
6232
        if (search_pc) {
6233
            j = gen_opc_ptr - gen_opc_buf;
6234
            if (lj < j) {
6235
                lj++;
6236
                while (lj < j)
6237
                    gen_opc_instr_start[lj++] = 0;
6238
            }
6239
            gen_opc_pc[lj] = pc_ptr;
6240
            gen_opc_cc_op[lj] = dc->cc_op;
6241
            gen_opc_instr_start[lj] = 1;
6242
        }
6243
        pc_ptr = disas_insn(dc, pc_ptr);
6244
        /* stop translation if indicated */
6245
        if (dc->is_jmp)
6246
            break;
6247
        /* if single step mode, we generate only one instruction and
6248
           generate an exception */
6249
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
6250
           the flag and abort the translation to give the irqs a
6251
           change to be happen */
6252
        if (dc->tf || dc->singlestep_enabled || 
6253
            (flags & HF_INHIBIT_IRQ_MASK) ||
6254
            (cflags & CF_SINGLE_INSN)) {
6255
            gen_jmp_im(pc_ptr - dc->cs_base);
6256
            gen_eob(dc);
6257
            break;
6258
        }
6259
        /* if too long translation, stop generation too */
6260
        if (gen_opc_ptr >= gen_opc_end ||
6261
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
6262
            gen_jmp_im(pc_ptr - dc->cs_base);
6263
            gen_eob(dc);
6264
            break;
6265
        }
6266
    }
6267
    *gen_opc_ptr = INDEX_op_end;
6268
    /* we don't forget to fill the last values */
6269
    if (search_pc) {
6270
        j = gen_opc_ptr - gen_opc_buf;
6271
        lj++;
6272
        while (lj <= j)
6273
            gen_opc_instr_start[lj++] = 0;
6274
    }
6275
        
6276
#ifdef DEBUG_DISAS
6277
    if (loglevel & CPU_LOG_TB_CPU) {
6278
        cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
6279
    }
6280
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6281
        int disas_flags;
6282
        fprintf(logfile, "----------------\n");
6283
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6284
#ifdef TARGET_X86_64
6285
        if (dc->code64)
6286
            disas_flags = 2;
6287
        else
6288
#endif
6289
            disas_flags = !dc->code32;
6290
        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
6291
        fprintf(logfile, "\n");
6292
        if (loglevel & CPU_LOG_TB_OP) {
6293
            fprintf(logfile, "OP:\n");
6294
            dump_ops(gen_opc_buf, gen_opparam_buf);
6295
            fprintf(logfile, "\n");
6296
        }
6297
    }
6298
#endif
6299

    
6300
    /* optimize flag computations */
6301
    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
6302

    
6303
#ifdef DEBUG_DISAS
6304
    if (loglevel & CPU_LOG_TB_OP_OPT) {
6305
        fprintf(logfile, "AFTER FLAGS OPT:\n");
6306
        dump_ops(gen_opc_buf, gen_opparam_buf);
6307
        fprintf(logfile, "\n");
6308
    }
6309
#endif
6310
    if (!search_pc)
6311
        tb->size = pc_ptr - pc_start;
6312
    return 0;
6313
}
6314

    
6315
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
6316
{
6317
    return gen_intermediate_code_internal(env, tb, 0);
6318
}
6319

    
6320
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
6321
{
6322
    return gen_intermediate_code_internal(env, tb, 1);
6323
}
6324