Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ b7e2c11d

History | View | Annotate | Download (187.8 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
X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\
610
           gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\
611
    },
612

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

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

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

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

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

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

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

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

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

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

    
707
#ifndef CONFIG_USER_ONLY
708
    gen_op_ldub_kernel_T0_A0,
709
    gen_op_lduw_kernel_T0_A0,
710
    NULL,
711
    NULL,
712

    
713
    gen_op_ldub_user_T0_A0,
714
    gen_op_lduw_user_T0_A0,
715
    NULL,
716
    NULL,
717
#endif
718
};
719

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

    
727
#ifndef CONFIG_USER_ONLY
728
    gen_op_ldub_kernel_T0_A0,
729
    gen_op_lduw_kernel_T0_A0,
730
    gen_op_ldl_kernel_T0_A0,
731
    X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
732

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

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

    
746
#ifndef CONFIG_USER_ONLY
747
    gen_op_ldub_kernel_T1_A0,
748
    gen_op_lduw_kernel_T1_A0,
749
    gen_op_ldl_kernel_T1_A0,
750
    X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
751

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

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

    
765
#ifndef CONFIG_USER_ONLY
766
    gen_op_stb_kernel_T0_A0,
767
    gen_op_stw_kernel_T0_A0,
768
    gen_op_stl_kernel_T0_A0,
769
    X86_64_ONLY(gen_op_stq_kernel_T0_A0),
770

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

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

    
784
#ifndef CONFIG_USER_ONLY
785
    NULL,
786
    gen_op_stw_kernel_T1_A0,
787
    gen_op_stl_kernel_T1_A0,
788
    X86_64_ONLY(gen_op_stq_kernel_T1_A0),
789

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

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

    
812
static inline void gen_string_movl_A0_ESI(DisasContext *s)
813
{
814
    int override;
815

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1444
    if (s->aflag) {
1445

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

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

    
1611
    opreg = OR_A0;
1612
    disp = 0;
1613
    *reg_ptr = opreg;
1614
    *offset_ptr = disp;
1615
}
1616

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

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

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

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

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

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

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

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

    
1724
        case CC_OP_ADCB:
1725
        case CC_OP_ADCW:
1726
        case CC_OP_ADCL:
1727
        case CC_OP_ADCQ:
1728

    
1729
        case CC_OP_SBBB:
1730
        case CC_OP_SBBW:
1731
        case CC_OP_SBBL:
1732
        case CC_OP_SBBQ:
1733

    
1734
        case CC_OP_LOGICB:
1735
        case CC_OP_LOGICW:
1736
        case CC_OP_LOGICL:
1737
        case CC_OP_LOGICQ:
1738

    
1739
        case CC_OP_INCB:
1740
        case CC_OP_INCW:
1741
        case CC_OP_INCL:
1742
        case CC_OP_INCQ:
1743

    
1744
        case CC_OP_DECB:
1745
        case CC_OP_DECW:
1746
        case CC_OP_DECL:
1747
        case CC_OP_DECQ:
1748

    
1749
        case CC_OP_SHLB:
1750
        case CC_OP_SHLW:
1751
        case CC_OP_SHLL:
1752
        case CC_OP_SHLQ:
1753

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

    
1775
        if (s->cc_op != CC_OP_DYNAMIC)
1776
            gen_op_set_cc_op(s->cc_op);
1777

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

    
1790
        l1 = gen_new_label();
1791
        func(l1);
1792

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

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

    
1804
        s->is_jmp = 3;
1805
    } else {
1806

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

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

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

    
1853
    case CC_OP_LOGICB:
1854
    case CC_OP_LOGICW:
1855
    case CC_OP_LOGICL:
1856
    case CC_OP_LOGICQ:
1857

    
1858
    case CC_OP_INCB:
1859
    case CC_OP_INCW:
1860
    case CC_OP_INCL:
1861
    case CC_OP_INCQ:
1862

    
1863
    case CC_OP_DECB:
1864
    case CC_OP_DECW:
1865
    case CC_OP_DECL:
1866
    case CC_OP_DECQ:
1867

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2266
#define SSE_SPECIAL ((GenOpFunc2 *)1)
2267

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

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

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

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

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

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

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

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

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

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

    
2964

    
2965
/* convert one instruction. s->is_jmp is set if the translation must
2966
   be stopped. Return the next pc value */
2967
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
2968
{
2969
    int b, prefixes, aflag, dflag;
2970
    int shift, ot;
2971
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
2972
    target_ulong next_eip, tval;
2973
    int rex_w, rex_r;
2974

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

    
3090
    s->prefix = prefixes;
3091
    s->aflag = aflag;
3092
    s->dflag = dflag;
3093

    
3094
    /* lock generation */
3095
    if (prefixes & PREFIX_LOCK)
3096
        gen_op_lock();
3097

    
3098
    /* now check op code */
3099
 reswitch:
3100
    switch(b) {
3101
    case 0x0f:
3102
        /**************************/
3103
        /* extended op code */
3104
        b = ldub_code(s->pc++) | 0x100;
3105
        goto reswitch;
3106
        
3107
        /**************************/
3108
        /* arith & logic */
3109
    case 0x00 ... 0x05:
3110
    case 0x08 ... 0x0d:
3111
    case 0x10 ... 0x15:
3112
    case 0x18 ... 0x1d:
3113
    case 0x20 ... 0x25:
3114
    case 0x28 ... 0x2d:
3115
    case 0x30 ... 0x35:
3116
    case 0x38 ... 0x3d:
3117
        {
3118
            int op, f, val;
3119
            op = (b >> 3) & 7;
3120
            f = (b >> 1) & 3;
3121

    
3122
            if ((b & 1) == 0)
3123
                ot = OT_BYTE;
3124
            else
3125
                ot = dflag + OT_WORD;
3126
            
3127
            switch(f) {
3128
            case 0: /* OP Ev, Gv */
3129
                modrm = ldub_code(s->pc++);
3130
                reg = ((modrm >> 3) & 7) | rex_r;
3131
                mod = (modrm >> 6) & 3;
3132
                rm = (modrm & 7) | REX_B(s);
3133
                if (mod != 3) {
3134
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3135
                    opreg = OR_TMP0;
3136
                } else if (op == OP_XORL && rm == reg) {
3137
                xor_zero:
3138
                    /* xor reg, reg optimisation */
3139
                    gen_op_movl_T0_0();
3140
                    s->cc_op = CC_OP_LOGICB + ot;
3141
                    gen_op_mov_reg_T0[ot][reg]();
3142
                    gen_op_update1_cc();
3143
                    break;
3144
                } else {
3145
                    opreg = rm;
3146
                }
3147
                gen_op_mov_TN_reg[ot][1][reg]();
3148
                gen_op(s, op, ot, opreg);
3149
                break;
3150
            case 1: /* OP Gv, Ev */
3151
                modrm = ldub_code(s->pc++);
3152
                mod = (modrm >> 6) & 3;
3153
                reg = ((modrm >> 3) & 7) | rex_r;
3154
                rm = (modrm & 7) | REX_B(s);
3155
                if (mod != 3) {
3156
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3157
                    gen_op_ld_T1_A0[ot + s->mem_index]();
3158
                } else if (op == OP_XORL && rm == reg) {
3159
                    goto xor_zero;
3160
                } else {
3161
                    gen_op_mov_TN_reg[ot][1][rm]();
3162
                }
3163
                gen_op(s, op, ot, reg);
3164
                break;
3165
            case 2: /* OP A, Iv */
3166
                val = insn_get(s, ot);
3167
                gen_op_movl_T1_im(val);
3168
                gen_op(s, op, ot, OR_EAX);
3169
                break;
3170
            }
3171
        }
3172
        break;
3173

    
3174
    case 0x80: /* GRP1 */
3175
    case 0x81:
3176
    case 0x82:
3177
    case 0x83:
3178
        {
3179
            int val;
3180

    
3181
            if ((b & 1) == 0)
3182
                ot = OT_BYTE;
3183
            else
3184
                ot = dflag + OT_WORD;
3185
            
3186
            modrm = ldub_code(s->pc++);
3187
            mod = (modrm >> 6) & 3;
3188
            rm = (modrm & 7) | REX_B(s);
3189
            op = (modrm >> 3) & 7;
3190
            
3191
            if (mod != 3) {
3192
                if (b == 0x83)
3193
                    s->rip_offset = 1;
3194
                else
3195
                    s->rip_offset = insn_const_size(ot);
3196
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3197
                opreg = OR_TMP0;
3198
            } else {
3199
                opreg = rm;
3200
            }
3201

    
3202
            switch(b) {
3203
            default:
3204
            case 0x80:
3205
            case 0x81:
3206
            case 0x82:
3207
                val = insn_get(s, ot);
3208
                break;
3209
            case 0x83:
3210
                val = (int8_t)insn_get(s, OT_BYTE);
3211
                break;
3212
            }
3213
            gen_op_movl_T1_im(val);
3214
            gen_op(s, op, ot, opreg);
3215
        }
3216
        break;
3217

    
3218
        /**************************/
3219
        /* inc, dec, and other misc arith */
3220
    case 0x40 ... 0x47: /* inc Gv */
3221
        ot = dflag ? OT_LONG : OT_WORD;
3222
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3223
        break;
3224
    case 0x48 ... 0x4f: /* dec Gv */
3225
        ot = dflag ? OT_LONG : OT_WORD;
3226
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3227
        break;
3228
    case 0xf6: /* GRP3 */
3229
    case 0xf7:
3230
        if ((b & 1) == 0)
3231
            ot = OT_BYTE;
3232
        else
3233
            ot = dflag + OT_WORD;
3234

    
3235
        modrm = ldub_code(s->pc++);
3236
        mod = (modrm >> 6) & 3;
3237
        rm = (modrm & 7) | REX_B(s);
3238
        op = (modrm >> 3) & 7;
3239
        if (mod != 3) {
3240
            if (op == 0)
3241
                s->rip_offset = insn_const_size(ot);
3242
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3243
            gen_op_ld_T0_A0[ot + s->mem_index]();
3244
        } else {
3245
            gen_op_mov_TN_reg[ot][0][rm]();
3246
        }
3247

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

    
3370
    case 0xfe: /* GRP4 */
3371
    case 0xff: /* GRP5 */
3372
        if ((b & 1) == 0)
3373
            ot = OT_BYTE;
3374
        else
3375
            ot = dflag + OT_WORD;
3376

    
3377
        modrm = ldub_code(s->pc++);
3378
        mod = (modrm >> 6) & 3;
3379
        rm = (modrm & 7) | REX_B(s);
3380
        op = (modrm >> 3) & 7;
3381
        if (op >= 2 && b == 0xfe) {
3382
            goto illegal_op;
3383
        }
3384
        if (CODE64(s)) {
3385
            if (op >= 2 && op <= 5) {
3386
                /* operand size for jumps is 64 bit */
3387
                ot = OT_QUAD;
3388
            } else if (op == 6) {
3389
                /* default push size is 64 bit */
3390
                ot = dflag ? OT_QUAD : OT_WORD;
3391
            }
3392
        }
3393
        if (mod != 3) {
3394
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3395
            if (op >= 2 && op != 3 && op != 5)
3396
                gen_op_ld_T0_A0[ot + s->mem_index]();
3397
        } else {
3398
            gen_op_mov_TN_reg[ot][0][rm]();
3399
        }
3400

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

    
3472
    case 0x84: /* test Ev, Gv */
3473
    case 0x85: 
3474
        if ((b & 1) == 0)
3475
            ot = OT_BYTE;
3476
        else
3477
            ot = dflag + OT_WORD;
3478

    
3479
        modrm = ldub_code(s->pc++);
3480
        mod = (modrm >> 6) & 3;
3481
        rm = (modrm & 7) | REX_B(s);
3482
        reg = ((modrm >> 3) & 7) | rex_r;
3483
        
3484
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3485
        gen_op_mov_TN_reg[ot][1][reg]();
3486
        gen_op_testl_T0_T1_cc();
3487
        s->cc_op = CC_OP_LOGICB + ot;
3488
        break;
3489
        
3490
    case 0xa8: /* test eAX, Iv */
3491
    case 0xa9:
3492
        if ((b & 1) == 0)
3493
            ot = OT_BYTE;
3494
        else
3495
            ot = dflag + OT_WORD;
3496
        val = insn_get(s, ot);
3497

    
3498
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
3499
        gen_op_movl_T1_im(val);
3500
        gen_op_testl_T0_T1_cc();
3501
        s->cc_op = CC_OP_LOGICB + ot;
3502
        break;
3503
        
3504
    case 0x98: /* CWDE/CBW */
3505
#ifdef TARGET_X86_64
3506
        if (dflag == 2) {
3507
            gen_op_movslq_RAX_EAX();
3508
        } else
3509
#endif
3510
        if (dflag == 1)
3511
            gen_op_movswl_EAX_AX();
3512
        else
3513
            gen_op_movsbw_AX_AL();
3514
        break;
3515
    case 0x99: /* CDQ/CWD */
3516
#ifdef TARGET_X86_64
3517
        if (dflag == 2) {
3518
            gen_op_movsqo_RDX_RAX();
3519
        } else
3520
#endif
3521
        if (dflag == 1)
3522
            gen_op_movslq_EDX_EAX();
3523
        else
3524
            gen_op_movswl_DX_AX();
3525
        break;
3526
    case 0x1af: /* imul Gv, Ev */
3527
    case 0x69: /* imul Gv, Ev, I */
3528
    case 0x6b:
3529
        ot = dflag + OT_WORD;
3530
        modrm = ldub_code(s->pc++);
3531
        reg = ((modrm >> 3) & 7) | rex_r;
3532
        if (b == 0x69)
3533
            s->rip_offset = insn_const_size(ot);
3534
        else if (b == 0x6b)
3535
            s->rip_offset = 1;
3536
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3537
        if (b == 0x69) {
3538
            val = insn_get(s, ot);
3539
            gen_op_movl_T1_im(val);
3540
        } else if (b == 0x6b) {
3541
            val = (int8_t)insn_get(s, OT_BYTE);
3542
            gen_op_movl_T1_im(val);
3543
        } else {
3544
            gen_op_mov_TN_reg[ot][1][reg]();
3545
        }
3546

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

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

    
3842
    case 0x1b6: /* movzbS Gv, Eb */
3843
    case 0x1b7: /* movzwS Gv, Eb */
3844
    case 0x1be: /* movsbS Gv, Eb */
3845
    case 0x1bf: /* movswS Gv, Eb */
3846
        {
3847
            int d_ot;
3848
            /* d_ot is the size of destination */
3849
            d_ot = dflag + OT_WORD;
3850
            /* ot is the size of source */
3851
            ot = (b & 1) + OT_BYTE;
3852
            modrm = ldub_code(s->pc++);
3853
            reg = ((modrm >> 3) & 7) | rex_r;
3854
            mod = (modrm >> 6) & 3;
3855
            rm = (modrm & 7) | REX_B(s);
3856
            
3857
            if (mod == 3) {
3858
                gen_op_mov_TN_reg[ot][0][rm]();
3859
                switch(ot | (b & 8)) {
3860
                case OT_BYTE:
3861
                    gen_op_movzbl_T0_T0();
3862
                    break;
3863
                case OT_BYTE | 8:
3864
                    gen_op_movsbl_T0_T0();
3865
                    break;
3866
                case OT_WORD:
3867
                    gen_op_movzwl_T0_T0();
3868
                    break;
3869
                default:
3870
                case OT_WORD | 8:
3871
                    gen_op_movswl_T0_T0();
3872
                    break;
3873
                }
3874
                gen_op_mov_reg_T0[d_ot][reg]();
3875
            } else {
3876
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3877
                if (b & 8) {
3878
                    gen_op_lds_T0_A0[ot + s->mem_index]();
3879
                } else {
3880
                    gen_op_ldu_T0_A0[ot + s->mem_index]();
3881
                }
3882
                gen_op_mov_reg_T0[d_ot][reg]();
3883
            }
3884
        }
3885
        break;
3886

    
3887
    case 0x8d: /* lea */
3888
        ot = dflag + OT_WORD;
3889
        modrm = ldub_code(s->pc++);
3890
        mod = (modrm >> 6) & 3;
3891
        if (mod == 3)
3892
            goto illegal_op;
3893
        reg = ((modrm >> 3) & 7) | rex_r;
3894
        /* we must ensure that no segment is added */
3895
        s->override = -1;
3896
        val = s->addseg;
3897
        s->addseg = 0;
3898
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3899
        s->addseg = val;
3900
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
3901
        break;
3902
        
3903
    case 0xa0: /* mov EAX, Ov */
3904
    case 0xa1:
3905
    case 0xa2: /* mov Ov, EAX */
3906
    case 0xa3:
3907
        {
3908
            target_ulong offset_addr;
3909

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

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

    
4085
            /* simpler op */
4086
            if (shift == 0) {
4087
                gen_shift(s, op, ot, opreg, OR_ECX);
4088
            } else {
4089
                if (shift == 2) {
4090
                    shift = ldub_code(s->pc++);
4091
                }
4092
                gen_shifti(s, op, ot, opreg, shift);
4093
            }
4094
        }
4095
        break;
4096
    case 0xd0:
4097
    case 0xd1:
4098
        /* shift Ev,1 */
4099
        shift = 1;
4100
        goto grp2;
4101
    case 0xd2:
4102
    case 0xd3:
4103
        /* shift Ev,cl */
4104
        shift = 0;
4105
        goto grp2;
4106

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

    
4167
        /************************/
4168
        /* floats */
4169
    case 0xd8 ... 0xdf: 
4170
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4171
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4172
            /* XXX: what to do if illegal op ? */
4173
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4174
            break;
4175
        }
4176
        modrm = ldub_code(s->pc++);
4177
        mod = (modrm >> 6) & 3;
4178
        rm = modrm & 7;
4179
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4180
        if (mod != 3) {
4181
            /* memory op */
4182
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4183
            switch(op) {
4184
            case 0x00 ... 0x07: /* fxxxs */
4185
            case 0x10 ... 0x17: /* fixxxl */
4186
            case 0x20 ... 0x27: /* fxxxl */
4187
            case 0x30 ... 0x37: /* fixxx */
4188
                {
4189
                    int op1;
4190
                    op1 = op & 7;
4191

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

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

    
4614
    case 0xa4: /* movsS */
4615
    case 0xa5:
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_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4623
        } else {
4624
            gen_movs(s, ot);
4625
        }
4626
        break;
4627
        
4628
    case 0xaa: /* stosS */
4629
    case 0xab:
4630
        if ((b & 1) == 0)
4631
            ot = OT_BYTE;
4632
        else
4633
            ot = dflag + OT_WORD;
4634

    
4635
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4636
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4637
        } else {
4638
            gen_stos(s, ot);
4639
        }
4640
        break;
4641
    case 0xac: /* lodsS */
4642
    case 0xad:
4643
        if ((b & 1) == 0)
4644
            ot = OT_BYTE;
4645
        else
4646
            ot = dflag + OT_WORD;
4647
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4648
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4649
        } else {
4650
            gen_lods(s, ot);
4651
        }
4652
        break;
4653
    case 0xae: /* scasS */
4654
    case 0xaf:
4655
        if ((b & 1) == 0)
4656
            ot = OT_BYTE;
4657
        else
4658
            ot = dflag + OT_WORD;
4659
        if (prefixes & PREFIX_REPNZ) {
4660
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4661
        } else if (prefixes & PREFIX_REPZ) {
4662
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4663
        } else {
4664
            gen_scas(s, ot);
4665
            s->cc_op = CC_OP_SUBB + ot;
4666
        }
4667
        break;
4668

    
4669
    case 0xa6: /* cmpsS */
4670
    case 0xa7:
4671
        if ((b & 1) == 0)
4672
            ot = OT_BYTE;
4673
        else
4674
            ot = dflag + OT_WORD;
4675
        if (prefixes & PREFIX_REPNZ) {
4676
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4677
        } else if (prefixes & PREFIX_REPZ) {
4678
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4679
        } else {
4680
            gen_cmps(s, ot);
4681
            s->cc_op = CC_OP_SUBB + ot;
4682
        }
4683
        break;
4684
    case 0x6c: /* insS */
4685
    case 0x6d:
4686
        if ((b & 1) == 0)
4687
            ot = OT_BYTE;
4688
        else
4689
            ot = dflag ? OT_LONG : OT_WORD;
4690
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4691
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4692
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4693
        } else {
4694
            gen_ins(s, ot);
4695
        }
4696
        break;
4697
    case 0x6e: /* outsS */
4698
    case 0x6f:
4699
        if ((b & 1) == 0)
4700
            ot = OT_BYTE;
4701
        else
4702
            ot = dflag ? OT_LONG : OT_WORD;
4703
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4704
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4705
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4706
        } else {
4707
            gen_outs(s, ot);
4708
        }
4709
        break;
4710

    
4711
        /************************/
4712
        /* port I/O */
4713
    case 0xe4:
4714
    case 0xe5:
4715
        if ((b & 1) == 0)
4716
            ot = OT_BYTE;
4717
        else
4718
            ot = dflag ? OT_LONG : OT_WORD;
4719
        val = ldub_code(s->pc++);
4720
        gen_op_movl_T0_im(val);
4721
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4722
        gen_op_in[ot]();
4723
        gen_op_mov_reg_T1[ot][R_EAX]();
4724
        break;
4725
    case 0xe6:
4726
    case 0xe7:
4727
        if ((b & 1) == 0)
4728
            ot = OT_BYTE;
4729
        else
4730
            ot = dflag ? OT_LONG : OT_WORD;
4731
        val = ldub_code(s->pc++);
4732
        gen_op_movl_T0_im(val);
4733
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4734
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4735
        gen_op_out[ot]();
4736
        break;
4737
    case 0xec:
4738
    case 0xed:
4739
        if ((b & 1) == 0)
4740
            ot = OT_BYTE;
4741
        else
4742
            ot = dflag ? OT_LONG : OT_WORD;
4743
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4744
        gen_op_andl_T0_ffff();
4745
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4746
        gen_op_in[ot]();
4747
        gen_op_mov_reg_T1[ot][R_EAX]();
4748
        break;
4749
    case 0xee:
4750
    case 0xef:
4751
        if ((b & 1) == 0)
4752
            ot = OT_BYTE;
4753
        else
4754
            ot = dflag ? OT_LONG : OT_WORD;
4755
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4756
        gen_op_andl_T0_ffff();
4757
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4758
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4759
        gen_op_out[ot]();
4760
        break;
4761

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

    
4876
            if (CODE64(s))
4877
                goto illegal_op;
4878
            ot = dflag ? OT_LONG : OT_WORD;
4879
            offset = insn_get(s, ot);
4880
            selector = insn_get(s, OT_WORD);
4881
            
4882
            gen_op_movl_T0_im(selector);
4883
            gen_op_movl_T1_imu(offset);
4884
        }
4885
        goto do_ljmp;
4886
    case 0xeb: /* jmp Jb */
4887
        tval = (int8_t)insn_get(s, OT_BYTE);
4888
        tval += s->pc - s->cs_base;
4889
        if (s->dflag == 0)
4890
            tval &= 0xffff;
4891
        gen_jmp(s, tval);
4892
        break;
4893
    case 0x70 ... 0x7f: /* jcc Jb */
4894
        tval = (int8_t)insn_get(s, OT_BYTE);
4895
        goto do_jcc;
4896
    case 0x180 ... 0x18f: /* jcc Jv */
4897
        if (dflag) {
4898
            tval = (int32_t)insn_get(s, OT_LONG);
4899
        } else {
4900
            tval = (int16_t)insn_get(s, OT_WORD); 
4901
        }
4902
    do_jcc:
4903
        next_eip = s->pc - s->cs_base;
4904
        tval += next_eip;
4905
        if (s->dflag == 0)
4906
            tval &= 0xffff;
4907
        gen_jcc(s, b, tval, next_eip);
4908
        break;
4909

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

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

    
5275
            tval = (int8_t)insn_get(s, OT_BYTE);
5276
            next_eip = s->pc - s->cs_base;
5277
            tval += next_eip;
5278
            if (s->dflag == 0)
5279
                tval &= 0xffff;
5280
            
5281
            l1 = gen_new_label();
5282
            l2 = gen_new_label();
5283
            b &= 3;
5284
            if (b == 3) {
5285
                gen_op_jz_ecx[s->aflag](l1);
5286
            } else {
5287
                gen_op_dec_ECX[s->aflag]();
5288
                if (b <= 1)
5289
                    gen_op_mov_T0_cc();
5290
                gen_op_loop[s->aflag][b](l1);
5291
            }
5292

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

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

    
5804
#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
5805
#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
5806

    
5807
/* flags read by an operation */
5808
static uint16_t opc_read_flags[NB_OPS] = { 
5809
    [INDEX_op_aas] = CC_A,
5810
    [INDEX_op_aaa] = CC_A,
5811
    [INDEX_op_das] = CC_A | CC_C,
5812
    [INDEX_op_daa] = CC_A | CC_C,
5813

    
5814
    /* subtle: due to the incl/decl implementation, C is used */
5815
    [INDEX_op_update_inc_cc] = CC_C, 
5816

    
5817
    [INDEX_op_into] = CC_O,
5818

    
5819
    [INDEX_op_jb_subb] = CC_C,
5820
    [INDEX_op_jb_subw] = CC_C,
5821
    [INDEX_op_jb_subl] = CC_C,
5822

    
5823
    [INDEX_op_jz_subb] = CC_Z,
5824
    [INDEX_op_jz_subw] = CC_Z,
5825
    [INDEX_op_jz_subl] = CC_Z,
5826

    
5827
    [INDEX_op_jbe_subb] = CC_Z | CC_C,
5828
    [INDEX_op_jbe_subw] = CC_Z | CC_C,
5829
    [INDEX_op_jbe_subl] = CC_Z | CC_C,
5830

    
5831
    [INDEX_op_js_subb] = CC_S,
5832
    [INDEX_op_js_subw] = CC_S,
5833
    [INDEX_op_js_subl] = CC_S,
5834

    
5835
    [INDEX_op_jl_subb] = CC_O | CC_S,
5836
    [INDEX_op_jl_subw] = CC_O | CC_S,
5837
    [INDEX_op_jl_subl] = CC_O | CC_S,
5838

    
5839
    [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
5840
    [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
5841
    [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
5842

    
5843
    [INDEX_op_loopnzw] = CC_Z,
5844
    [INDEX_op_loopnzl] = CC_Z,
5845
    [INDEX_op_loopzw] = CC_Z,
5846
    [INDEX_op_loopzl] = CC_Z,
5847

    
5848
    [INDEX_op_seto_T0_cc] = CC_O,
5849
    [INDEX_op_setb_T0_cc] = CC_C,
5850
    [INDEX_op_setz_T0_cc] = CC_Z,
5851
    [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
5852
    [INDEX_op_sets_T0_cc] = CC_S,
5853
    [INDEX_op_setp_T0_cc] = CC_P,
5854
    [INDEX_op_setl_T0_cc] = CC_O | CC_S,
5855
    [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
5856

    
5857
    [INDEX_op_setb_T0_subb] = CC_C,
5858
    [INDEX_op_setb_T0_subw] = CC_C,
5859
    [INDEX_op_setb_T0_subl] = CC_C,
5860

    
5861
    [INDEX_op_setz_T0_subb] = CC_Z,
5862
    [INDEX_op_setz_T0_subw] = CC_Z,
5863
    [INDEX_op_setz_T0_subl] = CC_Z,
5864

    
5865
    [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
5866
    [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
5867
    [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
5868

    
5869
    [INDEX_op_sets_T0_subb] = CC_S,
5870
    [INDEX_op_sets_T0_subw] = CC_S,
5871
    [INDEX_op_sets_T0_subl] = CC_S,
5872

    
5873
    [INDEX_op_setl_T0_subb] = CC_O | CC_S,
5874
    [INDEX_op_setl_T0_subw] = CC_O | CC_S,
5875
    [INDEX_op_setl_T0_subl] = CC_O | CC_S,
5876

    
5877
    [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
5878
    [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
5879
    [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
5880

    
5881
    [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
5882
    [INDEX_op_cmc] = CC_C,
5883
    [INDEX_op_salc] = CC_C,
5884

    
5885
    /* needed for correct flag optimisation before string ops */
5886
    [INDEX_op_jnz_ecxw] = CC_OSZAPC,
5887
    [INDEX_op_jnz_ecxl] = CC_OSZAPC,
5888
    [INDEX_op_jz_ecxw] = CC_OSZAPC,
5889
    [INDEX_op_jz_ecxl] = CC_OSZAPC,
5890

    
5891
#ifdef TARGET_X86_64
5892
    [INDEX_op_jb_subq] = CC_C,
5893
    [INDEX_op_jz_subq] = CC_Z,
5894
    [INDEX_op_jbe_subq] = CC_Z | CC_C,
5895
    [INDEX_op_js_subq] = CC_S,
5896
    [INDEX_op_jl_subq] = CC_O | CC_S,
5897
    [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
5898

    
5899
    [INDEX_op_loopnzq] = CC_Z,
5900
    [INDEX_op_loopzq] = CC_Z,
5901

    
5902
    [INDEX_op_setb_T0_subq] = CC_C,
5903
    [INDEX_op_setz_T0_subq] = CC_Z,
5904
    [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
5905
    [INDEX_op_sets_T0_subq] = CC_S,
5906
    [INDEX_op_setl_T0_subq] = CC_O | CC_S,
5907
    [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
5908

    
5909
    [INDEX_op_jnz_ecxq] = CC_OSZAPC,
5910
    [INDEX_op_jz_ecxq] = CC_OSZAPC,
5911
#endif
5912

    
5913
#define DEF_READF(SUFFIX)\
5914
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5915
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5916
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5917
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5918
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5919
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5920
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5921
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5922
\
5923
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5924
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5925
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
5926
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
5927
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
5928
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
5929
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
5930
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
5931

    
5932
    DEF_READF( )
5933
    DEF_READF(_raw)
5934
#ifndef CONFIG_USER_ONLY
5935
    DEF_READF(_kernel)
5936
    DEF_READF(_user)
5937
#endif
5938
};
5939

    
5940
/* flags written by an operation */
5941
static uint16_t opc_write_flags[NB_OPS] = { 
5942
    [INDEX_op_update2_cc] = CC_OSZAPC,
5943
    [INDEX_op_update1_cc] = CC_OSZAPC,
5944
    [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
5945
    [INDEX_op_update_neg_cc] = CC_OSZAPC,
5946
    /* subtle: due to the incl/decl implementation, C is used */
5947
    [INDEX_op_update_inc_cc] = CC_OSZAPC, 
5948
    [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
5949

    
5950
    [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
5951
    [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
5952
    [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
5953
    X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
5954
    [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
5955
    [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
5956
    [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
5957
    X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
5958
    [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
5959
    [INDEX_op_imull_T0_T1] = CC_OSZAPC,
5960
    X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
5961

    
5962
    /* sse */
5963
    [INDEX_op_ucomiss] = CC_OSZAPC,
5964
    [INDEX_op_ucomisd] = CC_OSZAPC,
5965
    [INDEX_op_comiss] = CC_OSZAPC,
5966
    [INDEX_op_comisd] = CC_OSZAPC,
5967

    
5968
    /* bcd */
5969
    [INDEX_op_aam] = CC_OSZAPC,
5970
    [INDEX_op_aad] = CC_OSZAPC,
5971
    [INDEX_op_aas] = CC_OSZAPC,
5972
    [INDEX_op_aaa] = CC_OSZAPC,
5973
    [INDEX_op_das] = CC_OSZAPC,
5974
    [INDEX_op_daa] = CC_OSZAPC,
5975

    
5976
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
5977
    [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
5978
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
5979
    [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
5980
    [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
5981
    [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
5982
    [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
5983
    [INDEX_op_clc] = CC_C,
5984
    [INDEX_op_stc] = CC_C,
5985
    [INDEX_op_cmc] = CC_C,
5986

    
5987
    [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
5988
    [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
5989
    X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
5990
    [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
5991
    [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
5992
    X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
5993
    [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
5994
    [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
5995
    X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
5996
    [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
5997
    [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
5998
    X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
5999

    
6000
    [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
6001
    [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
6002
    X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
6003
    [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
6004
    [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
6005
    X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
6006

    
6007
    [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
6008
    [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
6009
    [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
6010
    X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
6011

    
6012
    [INDEX_op_cmpxchg8b] = CC_Z,
6013
    [INDEX_op_lar] = CC_Z,
6014
    [INDEX_op_lsl] = CC_Z,
6015
    [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6016
    [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6017

    
6018
#define DEF_WRITEF(SUFFIX)\
6019
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6020
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6021
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6022
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6023
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6024
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6025
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6026
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6027
\
6028
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6029
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6030
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6031
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6032
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6033
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6034
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6035
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6036
\
6037
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6038
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6039
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6040
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6041
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6042
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6043
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6044
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6045
\
6046
    [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6047
    [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6048
    [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6049
    X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6050
\
6051
    [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6052
    [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6053
    [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6054
    X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6055
\
6056
    [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6057
    [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6058
    [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6059
    X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6060
\
6061
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6062
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6063
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6064
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6065
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6066
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6067
\
6068
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6069
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6070
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6071
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6072
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6073
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6074
\
6075
    [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6076
    [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6077
    [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6078
    X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
6079

    
6080

    
6081
    DEF_WRITEF( )
6082
    DEF_WRITEF(_raw)
6083
#ifndef CONFIG_USER_ONLY
6084
    DEF_WRITEF(_kernel)
6085
    DEF_WRITEF(_user)
6086
#endif
6087
};
6088

    
6089
/* simpler form of an operation if no flags need to be generated */
6090
static uint16_t opc_simpler[NB_OPS] = { 
6091
    [INDEX_op_update2_cc] = INDEX_op_nop,
6092
    [INDEX_op_update1_cc] = INDEX_op_nop,
6093
    [INDEX_op_update_neg_cc] = INDEX_op_nop,
6094
#if 0
6095
    /* broken: CC_OP logic must be rewritten */
6096
    [INDEX_op_update_inc_cc] = INDEX_op_nop,
6097
#endif
6098

    
6099
    [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
6100
    [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
6101
    [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
6102
    X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
6103

    
6104
    [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
6105
    [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
6106
    [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
6107
    X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
6108

    
6109
    [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
6110
    [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
6111
    [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
6112
    X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
6113

    
6114
#define DEF_SIMPLER(SUFFIX)\
6115
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
6116
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
6117
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
6118
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
6119
\
6120
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
6121
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
6122
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
6123
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
6124

    
6125
    DEF_SIMPLER( )
6126
    DEF_SIMPLER(_raw)
6127
#ifndef CONFIG_USER_ONLY
6128
    DEF_SIMPLER(_kernel)
6129
    DEF_SIMPLER(_user)
6130
#endif
6131
};
6132

    
6133
void optimize_flags_init(void)
6134
{
6135
    int i;
6136
    /* put default values in arrays */
6137
    for(i = 0; i < NB_OPS; i++) {
6138
        if (opc_simpler[i] == 0)
6139
            opc_simpler[i] = i;
6140
    }
6141
}
6142

    
6143
/* CPU flags computation optimization: we move backward thru the
6144
   generated code to see which flags are needed. The operation is
6145
   modified if suitable */
6146
static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
6147
{
6148
    uint16_t *opc_ptr;
6149
    int live_flags, write_flags, op;
6150

    
6151
    opc_ptr = opc_buf + opc_buf_len;
6152
    /* live_flags contains the flags needed by the next instructions
6153
       in the code. At the end of the bloc, we consider that all the
6154
       flags are live. */
6155
    live_flags = CC_OSZAPC;
6156
    while (opc_ptr > opc_buf) {
6157
        op = *--opc_ptr;
6158
        /* if none of the flags written by the instruction is used,
6159
           then we can try to find a simpler instruction */
6160
        write_flags = opc_write_flags[op];
6161
        if ((live_flags & write_flags) == 0) {
6162
            *opc_ptr = opc_simpler[op];
6163
        }
6164
        /* compute the live flags before the instruction */
6165
        live_flags &= ~write_flags;
6166
        live_flags |= opc_read_flags[op];
6167
    }
6168
}
6169

    
6170
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
6171
   basic block 'tb'. If search_pc is TRUE, also generate PC
6172
   information for each intermediate instruction. */
6173
static inline int gen_intermediate_code_internal(CPUState *env,
6174
                                                 TranslationBlock *tb, 
6175
                                                 int search_pc)
6176
{
6177
    DisasContext dc1, *dc = &dc1;
6178
    target_ulong pc_ptr;
6179
    uint16_t *gen_opc_end;
6180
    int flags, j, lj, cflags;
6181
    target_ulong pc_start;
6182
    target_ulong cs_base;
6183
    
6184
    /* generate intermediate code */
6185
    pc_start = tb->pc;
6186
    cs_base = tb->cs_base;
6187
    flags = tb->flags;
6188
    cflags = tb->cflags;
6189

    
6190
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
6191
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
6192
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
6193
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
6194
    dc->f_st = 0;
6195
    dc->vm86 = (flags >> VM_SHIFT) & 1;
6196
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
6197
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
6198
    dc->tf = (flags >> TF_SHIFT) & 1;
6199
    dc->singlestep_enabled = env->singlestep_enabled;
6200
    dc->cc_op = CC_OP_DYNAMIC;
6201
    dc->cs_base = cs_base;
6202
    dc->tb = tb;
6203
    dc->popl_esp_hack = 0;
6204
    /* select memory access functions */
6205
    dc->mem_index = 0;
6206
    if (flags & HF_SOFTMMU_MASK) {
6207
        if (dc->cpl == 3)
6208
            dc->mem_index = 2 * 4;
6209
        else
6210
            dc->mem_index = 1 * 4;
6211
    }
6212
    dc->cpuid_features = env->cpuid_features;
6213
#ifdef TARGET_X86_64
6214
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
6215
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
6216
#endif
6217
    dc->flags = flags;
6218
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
6219
                    (flags & HF_INHIBIT_IRQ_MASK)
6220
#ifndef CONFIG_SOFTMMU
6221
                    || (flags & HF_SOFTMMU_MASK)
6222
#endif
6223
                    );
6224
#if 0
6225
    /* check addseg logic */
6226
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
6227
        printf("ERROR addseg\n");
6228
#endif
6229

    
6230
    gen_opc_ptr = gen_opc_buf;
6231
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6232
    gen_opparam_ptr = gen_opparam_buf;
6233
    nb_gen_labels = 0;
6234

    
6235
    dc->is_jmp = DISAS_NEXT;
6236
    pc_ptr = pc_start;
6237
    lj = -1;
6238

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

    
6316
    /* optimize flag computations */
6317
    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
6318

    
6319
#ifdef DEBUG_DISAS
6320
    if (loglevel & CPU_LOG_TB_OP_OPT) {
6321
        fprintf(logfile, "AFTER FLAGS OPT:\n");
6322
        dump_ops(gen_opc_buf, gen_opparam_buf);
6323
        fprintf(logfile, "\n");
6324
    }
6325
#endif
6326
    if (!search_pc)
6327
        tb->size = pc_ptr - pc_start;
6328
    return 0;
6329
}
6330

    
6331
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
6332
{
6333
    return gen_intermediate_code_internal(env, tb, 0);
6334
}
6335

    
6336
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
6337
{
6338
    return gen_intermediate_code_internal(env, tb, 1);
6339
}
6340