Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 3d7374c5

History | View | Annotate | Download (194.6 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
    int cpuid_ext_features;
104
} DisasContext;
105

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

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

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

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

    
141
#include "gen-op.h"
142

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

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

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

    
167
#ifdef TARGET_X86_64
168

    
169
#define NB_OP_SIZES 4
170

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

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

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

    
228
#else /* !TARGET_X86_64 */
229

    
230
#define NB_OP_SIZES 3
231

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

    
242
#endif /* !TARGET_X86_64 */
243

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1445
    if (s->aflag) {
1446

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

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

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

    
1618
/* used for LEA and MOV AX, mem */
1619
static void gen_add_A0_ds_seg(DisasContext *s)
1620
{
1621
    int override, must_add_seg;
1622
    must_add_seg = s->addseg;
1623
    override = R_DS;
1624
    if (s->override >= 0) {
1625
        override = s->override;
1626
        must_add_seg = 1;
1627
    } else {
1628
        override = R_DS;
1629
    }
1630
    if (must_add_seg) {
1631
#ifdef TARGET_X86_64
1632
        if (CODE64(s)) {
1633
            gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
1634
        } else 
1635
#endif
1636
        {
1637
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1638
        }
1639
    }
1640
}
1641

    
1642
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
1643
   OR_TMP0 */
1644
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
1645
{
1646
    int mod, rm, opreg, disp;
1647

    
1648
    mod = (modrm >> 6) & 3;
1649
    rm = (modrm & 7) | REX_B(s);
1650
    if (mod == 3) {
1651
        if (is_store) {
1652
            if (reg != OR_TMP0)
1653
                gen_op_mov_TN_reg[ot][0][reg]();
1654
            gen_op_mov_reg_T0[ot][rm]();
1655
        } else {
1656
            gen_op_mov_TN_reg[ot][0][rm]();
1657
            if (reg != OR_TMP0)
1658
                gen_op_mov_reg_T0[ot][reg]();
1659
        }
1660
    } else {
1661
        gen_lea_modrm(s, modrm, &opreg, &disp);
1662
        if (is_store) {
1663
            if (reg != OR_TMP0)
1664
                gen_op_mov_TN_reg[ot][0][reg]();
1665
            gen_op_st_T0_A0[ot + s->mem_index]();
1666
        } else {
1667
            gen_op_ld_T0_A0[ot + s->mem_index]();
1668
            if (reg != OR_TMP0)
1669
                gen_op_mov_reg_T0[ot][reg]();
1670
        }
1671
    }
1672
}
1673

    
1674
static inline uint32_t insn_get(DisasContext *s, int ot)
1675
{
1676
    uint32_t ret;
1677

    
1678
    switch(ot) {
1679
    case OT_BYTE:
1680
        ret = ldub_code(s->pc);
1681
        s->pc++;
1682
        break;
1683
    case OT_WORD:
1684
        ret = lduw_code(s->pc);
1685
        s->pc += 2;
1686
        break;
1687
    default:
1688
    case OT_LONG:
1689
        ret = ldl_code(s->pc);
1690
        s->pc += 4;
1691
        break;
1692
    }
1693
    return ret;
1694
}
1695

    
1696
static inline int insn_const_size(unsigned int ot)
1697
{
1698
    if (ot <= OT_LONG)
1699
        return 1 << ot;
1700
    else
1701
        return 4;
1702
}
1703

    
1704
static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
1705
{
1706
    TranslationBlock *tb;
1707
    target_ulong pc;
1708

    
1709
    pc = s->cs_base + eip;
1710
    tb = s->tb;
1711
    /* NOTE: we handle the case where the TB spans two pages here */
1712
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
1713
        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
1714
        /* jump to same page: we can use a direct jump */
1715
        if (tb_num == 0)
1716
            gen_op_goto_tb0(TBPARAM(tb));
1717
        else
1718
            gen_op_goto_tb1(TBPARAM(tb));
1719
        gen_jmp_im(eip);
1720
        gen_op_movl_T0_im((long)tb + tb_num);
1721
        gen_op_exit_tb();
1722
    } else {
1723
        /* jump to another page: currently not optimized */
1724
        gen_jmp_im(eip);
1725
        gen_eob(s);
1726
    }
1727
}
1728

    
1729
static inline void gen_jcc(DisasContext *s, int b, 
1730
                           target_ulong val, target_ulong next_eip)
1731
{
1732
    TranslationBlock *tb;
1733
    int inv, jcc_op;
1734
    GenOpFunc1 *func;
1735
    target_ulong tmp;
1736
    int l1, l2;
1737

    
1738
    inv = b & 1;
1739
    jcc_op = (b >> 1) & 7;
1740
    
1741
    if (s->jmp_opt) {
1742
        switch(s->cc_op) {
1743
            /* we optimize the cmp/jcc case */
1744
        case CC_OP_SUBB:
1745
        case CC_OP_SUBW:
1746
        case CC_OP_SUBL:
1747
        case CC_OP_SUBQ:
1748
            func = gen_jcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1749
            break;
1750
            
1751
            /* some jumps are easy to compute */
1752
        case CC_OP_ADDB:
1753
        case CC_OP_ADDW:
1754
        case CC_OP_ADDL:
1755
        case CC_OP_ADDQ:
1756

    
1757
        case CC_OP_ADCB:
1758
        case CC_OP_ADCW:
1759
        case CC_OP_ADCL:
1760
        case CC_OP_ADCQ:
1761

    
1762
        case CC_OP_SBBB:
1763
        case CC_OP_SBBW:
1764
        case CC_OP_SBBL:
1765
        case CC_OP_SBBQ:
1766

    
1767
        case CC_OP_LOGICB:
1768
        case CC_OP_LOGICW:
1769
        case CC_OP_LOGICL:
1770
        case CC_OP_LOGICQ:
1771

    
1772
        case CC_OP_INCB:
1773
        case CC_OP_INCW:
1774
        case CC_OP_INCL:
1775
        case CC_OP_INCQ:
1776

    
1777
        case CC_OP_DECB:
1778
        case CC_OP_DECW:
1779
        case CC_OP_DECL:
1780
        case CC_OP_DECQ:
1781

    
1782
        case CC_OP_SHLB:
1783
        case CC_OP_SHLW:
1784
        case CC_OP_SHLL:
1785
        case CC_OP_SHLQ:
1786

    
1787
        case CC_OP_SARB:
1788
        case CC_OP_SARW:
1789
        case CC_OP_SARL:
1790
        case CC_OP_SARQ:
1791
            switch(jcc_op) {
1792
            case JCC_Z:
1793
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1794
                break;
1795
            case JCC_S:
1796
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1797
                break;
1798
            default:
1799
                func = NULL;
1800
                break;
1801
            }
1802
            break;
1803
        default:
1804
            func = NULL;
1805
            break;
1806
        }
1807

    
1808
        if (s->cc_op != CC_OP_DYNAMIC) {
1809
            gen_op_set_cc_op(s->cc_op);
1810
            s->cc_op = CC_OP_DYNAMIC;
1811
        }
1812

    
1813
        if (!func) {
1814
            gen_setcc_slow[jcc_op]();
1815
            func = gen_op_jnz_T0_label;
1816
        }
1817
    
1818
        if (inv) {
1819
            tmp = val;
1820
            val = next_eip;
1821
            next_eip = tmp;
1822
        }
1823
        tb = s->tb;
1824

    
1825
        l1 = gen_new_label();
1826
        func(l1);
1827

    
1828
        gen_goto_tb(s, 0, next_eip);
1829

    
1830
        gen_set_label(l1);
1831
        gen_goto_tb(s, 1, val);
1832

    
1833
        s->is_jmp = 3;
1834
    } else {
1835

    
1836
        if (s->cc_op != CC_OP_DYNAMIC) {
1837
            gen_op_set_cc_op(s->cc_op);
1838
            s->cc_op = CC_OP_DYNAMIC;
1839
        }
1840
        gen_setcc_slow[jcc_op]();
1841
        if (inv) {
1842
            tmp = val;
1843
            val = next_eip;
1844
            next_eip = tmp;
1845
        }
1846
        l1 = gen_new_label();
1847
        l2 = gen_new_label();
1848
        gen_op_jnz_T0_label(l1);
1849
        gen_jmp_im(next_eip);
1850
        gen_op_jmp_label(l2);
1851
        gen_set_label(l1);
1852
        gen_jmp_im(val);
1853
        gen_set_label(l2);
1854
        gen_eob(s);
1855
    }
1856
}
1857

    
1858
static void gen_setcc(DisasContext *s, int b)
1859
{
1860
    int inv, jcc_op;
1861
    GenOpFunc *func;
1862

    
1863
    inv = b & 1;
1864
    jcc_op = (b >> 1) & 7;
1865
    switch(s->cc_op) {
1866
        /* we optimize the cmp/jcc case */
1867
    case CC_OP_SUBB:
1868
    case CC_OP_SUBW:
1869
    case CC_OP_SUBL:
1870
    case CC_OP_SUBQ:
1871
        func = gen_setcc_sub[s->cc_op - CC_OP_SUBB][jcc_op];
1872
        if (!func)
1873
            goto slow_jcc;
1874
        break;
1875
        
1876
        /* some jumps are easy to compute */
1877
    case CC_OP_ADDB:
1878
    case CC_OP_ADDW:
1879
    case CC_OP_ADDL:
1880
    case CC_OP_ADDQ:
1881

    
1882
    case CC_OP_LOGICB:
1883
    case CC_OP_LOGICW:
1884
    case CC_OP_LOGICL:
1885
    case CC_OP_LOGICQ:
1886

    
1887
    case CC_OP_INCB:
1888
    case CC_OP_INCW:
1889
    case CC_OP_INCL:
1890
    case CC_OP_INCQ:
1891

    
1892
    case CC_OP_DECB:
1893
    case CC_OP_DECW:
1894
    case CC_OP_DECL:
1895
    case CC_OP_DECQ:
1896

    
1897
    case CC_OP_SHLB:
1898
    case CC_OP_SHLW:
1899
    case CC_OP_SHLL:
1900
    case CC_OP_SHLQ:
1901
        switch(jcc_op) {
1902
        case JCC_Z:
1903
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1904
            break;
1905
        case JCC_S:
1906
            func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1907
            break;
1908
        default:
1909
            goto slow_jcc;
1910
        }
1911
        break;
1912
    default:
1913
    slow_jcc:
1914
        if (s->cc_op != CC_OP_DYNAMIC)
1915
            gen_op_set_cc_op(s->cc_op);
1916
        func = gen_setcc_slow[jcc_op];
1917
        break;
1918
    }
1919
    func();
1920
    if (inv) {
1921
        gen_op_xor_T0_1();
1922
    }
1923
}
1924

    
1925
/* move T0 to seg_reg and compute if the CPU state may change. Never
1926
   call this function with seg_reg == R_CS */
1927
static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
1928
{
1929
    if (s->pe && !s->vm86) {
1930
        /* XXX: optimize by finding processor state dynamically */
1931
        if (s->cc_op != CC_OP_DYNAMIC)
1932
            gen_op_set_cc_op(s->cc_op);
1933
        gen_jmp_im(cur_eip);
1934
        gen_op_movl_seg_T0(seg_reg);
1935
        /* abort translation because the addseg value may change or
1936
           because ss32 may change. For R_SS, translation must always
1937
           stop as a special handling must be done to disable hardware
1938
           interrupts for the next instruction */
1939
        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
1940
            s->is_jmp = 3;
1941
    } else {
1942
        gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
1943
        if (seg_reg == R_SS)
1944
            s->is_jmp = 3;
1945
    }
1946
}
1947

    
1948
static inline void gen_stack_update(DisasContext *s, int addend)
1949
{
1950
#ifdef TARGET_X86_64
1951
    if (CODE64(s)) {
1952
        if (addend == 8)
1953
            gen_op_addq_ESP_8();
1954
        else 
1955
            gen_op_addq_ESP_im(addend);
1956
    } else
1957
#endif
1958
    if (s->ss32) {
1959
        if (addend == 2)
1960
            gen_op_addl_ESP_2();
1961
        else if (addend == 4)
1962
            gen_op_addl_ESP_4();
1963
        else 
1964
            gen_op_addl_ESP_im(addend);
1965
    } else {
1966
        if (addend == 2)
1967
            gen_op_addw_ESP_2();
1968
        else if (addend == 4)
1969
            gen_op_addw_ESP_4();
1970
        else
1971
            gen_op_addw_ESP_im(addend);
1972
    }
1973
}
1974

    
1975
/* generate a push. It depends on ss32, addseg and dflag */
1976
static void gen_push_T0(DisasContext *s)
1977
{
1978
#ifdef TARGET_X86_64
1979
    if (CODE64(s)) {
1980
        gen_op_movq_A0_reg[R_ESP]();
1981
        if (s->dflag) {
1982
            gen_op_subq_A0_8();
1983
            gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1984
        } else {
1985
            gen_op_subq_A0_2();
1986
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
1987
        }
1988
        gen_op_movq_ESP_A0();
1989
    } else 
1990
#endif
1991
    {
1992
        gen_op_movl_A0_reg[R_ESP]();
1993
        if (!s->dflag)
1994
            gen_op_subl_A0_2();
1995
        else
1996
            gen_op_subl_A0_4();
1997
        if (s->ss32) {
1998
            if (s->addseg) {
1999
                gen_op_movl_T1_A0();
2000
                gen_op_addl_A0_SS();
2001
            }
2002
        } else {
2003
            gen_op_andl_A0_ffff();
2004
            gen_op_movl_T1_A0();
2005
            gen_op_addl_A0_SS();
2006
        }
2007
        gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
2008
        if (s->ss32 && !s->addseg)
2009
            gen_op_movl_ESP_A0();
2010
        else
2011
            gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
2012
    }
2013
}
2014

    
2015
/* generate a push. It depends on ss32, addseg and dflag */
2016
/* slower version for T1, only used for call Ev */
2017
static void gen_push_T1(DisasContext *s)
2018
{
2019
#ifdef TARGET_X86_64
2020
    if (CODE64(s)) {
2021
        gen_op_movq_A0_reg[R_ESP]();
2022
        if (s->dflag) {
2023
            gen_op_subq_A0_8();
2024
            gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
2025
        } else {
2026
            gen_op_subq_A0_2();
2027
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
2028
        }
2029
        gen_op_movq_ESP_A0();
2030
    } else 
2031
#endif
2032
    {
2033
        gen_op_movl_A0_reg[R_ESP]();
2034
        if (!s->dflag)
2035
            gen_op_subl_A0_2();
2036
        else
2037
            gen_op_subl_A0_4();
2038
        if (s->ss32) {
2039
            if (s->addseg) {
2040
                gen_op_addl_A0_SS();
2041
            }
2042
        } else {
2043
            gen_op_andl_A0_ffff();
2044
            gen_op_addl_A0_SS();
2045
        }
2046
        gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
2047
        
2048
        if (s->ss32 && !s->addseg)
2049
            gen_op_movl_ESP_A0();
2050
        else
2051
            gen_stack_update(s, (-2) << s->dflag);
2052
    }
2053
}
2054

    
2055
/* two step pop is necessary for precise exceptions */
2056
static void gen_pop_T0(DisasContext *s)
2057
{
2058
#ifdef TARGET_X86_64
2059
    if (CODE64(s)) {
2060
        gen_op_movq_A0_reg[R_ESP]();
2061
        gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
2062
    } else 
2063
#endif
2064
    {
2065
        gen_op_movl_A0_reg[R_ESP]();
2066
        if (s->ss32) {
2067
            if (s->addseg)
2068
                gen_op_addl_A0_SS();
2069
        } else {
2070
            gen_op_andl_A0_ffff();
2071
            gen_op_addl_A0_SS();
2072
        }
2073
        gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
2074
    }
2075
}
2076

    
2077
static void gen_pop_update(DisasContext *s)
2078
{
2079
#ifdef TARGET_X86_64
2080
    if (CODE64(s) && s->dflag) {
2081
        gen_stack_update(s, 8);
2082
    } else
2083
#endif
2084
    {
2085
        gen_stack_update(s, 2 << s->dflag);
2086
    }
2087
}
2088

    
2089
static void gen_stack_A0(DisasContext *s)
2090
{
2091
    gen_op_movl_A0_ESP();
2092
    if (!s->ss32)
2093
        gen_op_andl_A0_ffff();
2094
    gen_op_movl_T1_A0();
2095
    if (s->addseg)
2096
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2097
}
2098

    
2099
/* NOTE: wrap around in 16 bit not fully handled */
2100
static void gen_pusha(DisasContext *s)
2101
{
2102
    int i;
2103
    gen_op_movl_A0_ESP();
2104
    gen_op_addl_A0_im(-16 <<  s->dflag);
2105
    if (!s->ss32)
2106
        gen_op_andl_A0_ffff();
2107
    gen_op_movl_T1_A0();
2108
    if (s->addseg)
2109
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2110
    for(i = 0;i < 8; i++) {
2111
        gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
2112
        gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
2113
        gen_op_addl_A0_im(2 <<  s->dflag);
2114
    }
2115
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2116
}
2117

    
2118
/* NOTE: wrap around in 16 bit not fully handled */
2119
static void gen_popa(DisasContext *s)
2120
{
2121
    int i;
2122
    gen_op_movl_A0_ESP();
2123
    if (!s->ss32)
2124
        gen_op_andl_A0_ffff();
2125
    gen_op_movl_T1_A0();
2126
    gen_op_addl_T1_im(16 <<  s->dflag);
2127
    if (s->addseg)
2128
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2129
    for(i = 0;i < 8; i++) {
2130
        /* ESP is not reloaded */
2131
        if (i != 3) {
2132
            gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
2133
            gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
2134
        }
2135
        gen_op_addl_A0_im(2 <<  s->dflag);
2136
    }
2137
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2138
}
2139

    
2140
static void gen_enter(DisasContext *s, int esp_addend, int level)
2141
{
2142
    int ot, opsize;
2143

    
2144
    level &= 0x1f;
2145
#ifdef TARGET_X86_64
2146
    if (CODE64(s)) {
2147
        ot = s->dflag ? OT_QUAD : OT_WORD;
2148
        opsize = 1 << ot;
2149
        
2150
        gen_op_movl_A0_ESP();
2151
        gen_op_addq_A0_im(-opsize);
2152
        gen_op_movl_T1_A0();
2153

    
2154
        /* push bp */
2155
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2156
        gen_op_st_T0_A0[ot + s->mem_index]();
2157
        if (level) {
2158
            gen_op_enter64_level(level, (ot == OT_QUAD));
2159
        }
2160
        gen_op_mov_reg_T1[ot][R_EBP]();
2161
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2162
        gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
2163
    } else 
2164
#endif
2165
    {
2166
        ot = s->dflag + OT_WORD;
2167
        opsize = 2 << s->dflag;
2168
        
2169
        gen_op_movl_A0_ESP();
2170
        gen_op_addl_A0_im(-opsize);
2171
        if (!s->ss32)
2172
            gen_op_andl_A0_ffff();
2173
        gen_op_movl_T1_A0();
2174
        if (s->addseg)
2175
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2176
        /* push bp */
2177
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2178
        gen_op_st_T0_A0[ot + s->mem_index]();
2179
        if (level) {
2180
            gen_op_enter_level(level, s->dflag);
2181
        }
2182
        gen_op_mov_reg_T1[ot][R_EBP]();
2183
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2184
        gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2185
    }
2186
}
2187

    
2188
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2189
{
2190
    if (s->cc_op != CC_OP_DYNAMIC)
2191
        gen_op_set_cc_op(s->cc_op);
2192
    gen_jmp_im(cur_eip);
2193
    gen_op_raise_exception(trapno);
2194
    s->is_jmp = 3;
2195
}
2196

    
2197
/* an interrupt is different from an exception because of the
2198
   priviledge checks */
2199
static void gen_interrupt(DisasContext *s, int intno, 
2200
                          target_ulong cur_eip, target_ulong next_eip)
2201
{
2202
    if (s->cc_op != CC_OP_DYNAMIC)
2203
        gen_op_set_cc_op(s->cc_op);
2204
    gen_jmp_im(cur_eip);
2205
    gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip));
2206
    s->is_jmp = 3;
2207
}
2208

    
2209
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2210
{
2211
    if (s->cc_op != CC_OP_DYNAMIC)
2212
        gen_op_set_cc_op(s->cc_op);
2213
    gen_jmp_im(cur_eip);
2214
    gen_op_debug();
2215
    s->is_jmp = 3;
2216
}
2217

    
2218
/* generate a generic end of block. Trace exception is also generated
2219
   if needed */
2220
static void gen_eob(DisasContext *s)
2221
{
2222
    if (s->cc_op != CC_OP_DYNAMIC)
2223
        gen_op_set_cc_op(s->cc_op);
2224
    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
2225
        gen_op_reset_inhibit_irq();
2226
    }
2227
    if (s->singlestep_enabled) {
2228
        gen_op_debug();
2229
    } else if (s->tf) {
2230
        gen_op_raise_exception(EXCP01_SSTP);
2231
    } else {
2232
        gen_op_movl_T0_0();
2233
        gen_op_exit_tb();
2234
    }
2235
    s->is_jmp = 3;
2236
}
2237

    
2238
/* generate a jump to eip. No segment change must happen before as a
2239
   direct call to the next block may occur */
2240
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2241
{
2242
    if (s->jmp_opt) {
2243
        if (s->cc_op != CC_OP_DYNAMIC) {
2244
            gen_op_set_cc_op(s->cc_op);
2245
            s->cc_op = CC_OP_DYNAMIC;
2246
        }
2247
        gen_goto_tb(s, tb_num, eip);
2248
        s->is_jmp = 3;
2249
    } else {
2250
        gen_jmp_im(eip);
2251
        gen_eob(s);
2252
    }
2253
}
2254

    
2255
static void gen_jmp(DisasContext *s, target_ulong eip)
2256
{
2257
    gen_jmp_tb(s, eip, 0);
2258
}
2259

    
2260
static void gen_movtl_T0_im(target_ulong val)
2261
{
2262
#ifdef TARGET_X86_64    
2263
    if ((int32_t)val == val) {
2264
        gen_op_movl_T0_im(val);
2265
    } else {
2266
        gen_op_movq_T0_im64(val >> 32, val);
2267
    }
2268
#else
2269
    gen_op_movl_T0_im(val);
2270
#endif
2271
}
2272

    
2273
static void gen_movtl_T1_im(target_ulong val)
2274
{
2275
#ifdef TARGET_X86_64    
2276
    if ((int32_t)val == val) {
2277
        gen_op_movl_T1_im(val);
2278
    } else {
2279
        gen_op_movq_T1_im64(val >> 32, val);
2280
    }
2281
#else
2282
    gen_op_movl_T1_im(val);
2283
#endif
2284
}
2285

    
2286
static void gen_add_A0_im(DisasContext *s, int val)
2287
{
2288
#ifdef TARGET_X86_64
2289
    if (CODE64(s))
2290
        gen_op_addq_A0_im(val);
2291
    else
2292
#endif
2293
        gen_op_addl_A0_im(val);
2294
}
2295

    
2296
static GenOpFunc1 *gen_ldq_env_A0[3] = {
2297
    gen_op_ldq_raw_env_A0,
2298
#ifndef CONFIG_USER_ONLY
2299
    gen_op_ldq_kernel_env_A0,
2300
    gen_op_ldq_user_env_A0,
2301
#endif
2302
};
2303

    
2304
static GenOpFunc1 *gen_stq_env_A0[3] = {
2305
    gen_op_stq_raw_env_A0,
2306
#ifndef CONFIG_USER_ONLY
2307
    gen_op_stq_kernel_env_A0,
2308
    gen_op_stq_user_env_A0,
2309
#endif
2310
};
2311

    
2312
static GenOpFunc1 *gen_ldo_env_A0[3] = {
2313
    gen_op_ldo_raw_env_A0,
2314
#ifndef CONFIG_USER_ONLY
2315
    gen_op_ldo_kernel_env_A0,
2316
    gen_op_ldo_user_env_A0,
2317
#endif
2318
};
2319

    
2320
static GenOpFunc1 *gen_sto_env_A0[3] = {
2321
    gen_op_sto_raw_env_A0,
2322
#ifndef CONFIG_USER_ONLY
2323
    gen_op_sto_kernel_env_A0,
2324
    gen_op_sto_user_env_A0,
2325
#endif
2326
};
2327

    
2328
#define SSE_SPECIAL ((GenOpFunc2 *)1)
2329

    
2330
#define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
2331
#define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
2332
                     gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
2333

    
2334
static GenOpFunc2 *sse_op_table1[256][4] = {
2335
    /* pure SSE operations */
2336
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2337
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2338
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */
2339
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2340
    [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
2341
    [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
2342
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2343
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2344

    
2345
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2346
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2347
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2348
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2349
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2350
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2351
    [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
2352
    [0x2f] = { gen_op_comiss, gen_op_comisd },
2353
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2354
    [0x51] = SSE_FOP(sqrt),
2355
    [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
2356
    [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
2357
    [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
2358
    [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
2359
    [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
2360
    [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
2361
    [0x58] = SSE_FOP(add),
2362
    [0x59] = SSE_FOP(mul),
2363
    [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps, 
2364
               gen_op_cvtss2sd, gen_op_cvtsd2ss },
2365
    [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
2366
    [0x5c] = SSE_FOP(sub),
2367
    [0x5d] = SSE_FOP(min),
2368
    [0x5e] = SSE_FOP(div),
2369
    [0x5f] = SSE_FOP(max),
2370

    
2371
    [0xc2] = SSE_FOP(cmpeq),
2372
    [0xc6] = { (GenOpFunc2 *)gen_op_shufps, (GenOpFunc2 *)gen_op_shufpd },
2373

    
2374
    /* MMX ops and their SSE extensions */
2375
    [0x60] = MMX_OP2(punpcklbw),
2376
    [0x61] = MMX_OP2(punpcklwd),
2377
    [0x62] = MMX_OP2(punpckldq),
2378
    [0x63] = MMX_OP2(packsswb),
2379
    [0x64] = MMX_OP2(pcmpgtb),
2380
    [0x65] = MMX_OP2(pcmpgtw),
2381
    [0x66] = MMX_OP2(pcmpgtl),
2382
    [0x67] = MMX_OP2(packuswb),
2383
    [0x68] = MMX_OP2(punpckhbw),
2384
    [0x69] = MMX_OP2(punpckhwd),
2385
    [0x6a] = MMX_OP2(punpckhdq),
2386
    [0x6b] = MMX_OP2(packssdw),
2387
    [0x6c] = { NULL, gen_op_punpcklqdq_xmm },
2388
    [0x6d] = { NULL, gen_op_punpckhqdq_xmm },
2389
    [0x6e] = { SSE_SPECIAL, SSE_SPECIAL }, /* movd mm, ea */
2390
    [0x6f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, , movqdu */
2391
    [0x70] = { (GenOpFunc2 *)gen_op_pshufw_mmx, 
2392
               (GenOpFunc2 *)gen_op_pshufd_xmm, 
2393
               (GenOpFunc2 *)gen_op_pshufhw_xmm, 
2394
               (GenOpFunc2 *)gen_op_pshuflw_xmm },
2395
    [0x71] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftw */
2396
    [0x72] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftd */
2397
    [0x73] = { SSE_SPECIAL, SSE_SPECIAL }, /* shiftq */
2398
    [0x74] = MMX_OP2(pcmpeqb),
2399
    [0x75] = MMX_OP2(pcmpeqw),
2400
    [0x76] = MMX_OP2(pcmpeql),
2401
    [0x77] = { SSE_SPECIAL }, /* emms */
2402
    [0x7c] = { NULL, gen_op_haddpd, NULL, gen_op_haddps },
2403
    [0x7d] = { NULL, gen_op_hsubpd, NULL, gen_op_hsubps },
2404
    [0x7e] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movd, movd, , movq */
2405
    [0x7f] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movq, movdqa, movdqu */
2406
    [0xc4] = { SSE_SPECIAL, SSE_SPECIAL }, /* pinsrw */
2407
    [0xc5] = { SSE_SPECIAL, SSE_SPECIAL }, /* pextrw */
2408
    [0xd0] = { NULL, gen_op_addsubpd, NULL, gen_op_addsubps },
2409
    [0xd1] = MMX_OP2(psrlw),
2410
    [0xd2] = MMX_OP2(psrld),
2411
    [0xd3] = MMX_OP2(psrlq),
2412
    [0xd4] = MMX_OP2(paddq),
2413
    [0xd5] = MMX_OP2(pmullw),
2414
    [0xd6] = { NULL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },
2415
    [0xd7] = { SSE_SPECIAL, SSE_SPECIAL }, /* pmovmskb */
2416
    [0xd8] = MMX_OP2(psubusb),
2417
    [0xd9] = MMX_OP2(psubusw),
2418
    [0xda] = MMX_OP2(pminub),
2419
    [0xdb] = MMX_OP2(pand),
2420
    [0xdc] = MMX_OP2(paddusb),
2421
    [0xdd] = MMX_OP2(paddusw),
2422
    [0xde] = MMX_OP2(pmaxub),
2423
    [0xdf] = MMX_OP2(pandn),
2424
    [0xe0] = MMX_OP2(pavgb),
2425
    [0xe1] = MMX_OP2(psraw),
2426
    [0xe2] = MMX_OP2(psrad),
2427
    [0xe3] = MMX_OP2(pavgw),
2428
    [0xe4] = MMX_OP2(pmulhuw),
2429
    [0xe5] = MMX_OP2(pmulhw),
2430
    [0xe6] = { NULL, gen_op_cvttpd2dq, gen_op_cvtdq2pd, gen_op_cvtpd2dq },
2431
    [0xe7] = { SSE_SPECIAL , SSE_SPECIAL },  /* movntq, movntq */
2432
    [0xe8] = MMX_OP2(psubsb),
2433
    [0xe9] = MMX_OP2(psubsw),
2434
    [0xea] = MMX_OP2(pminsw),
2435
    [0xeb] = MMX_OP2(por),
2436
    [0xec] = MMX_OP2(paddsb),
2437
    [0xed] = MMX_OP2(paddsw),
2438
    [0xee] = MMX_OP2(pmaxsw),
2439
    [0xef] = MMX_OP2(pxor),
2440
    [0xf0] = { NULL, NULL, NULL, SSE_SPECIAL }, /* lddqu */
2441
    [0xf1] = MMX_OP2(psllw),
2442
    [0xf2] = MMX_OP2(pslld),
2443
    [0xf3] = MMX_OP2(psllq),
2444
    [0xf4] = MMX_OP2(pmuludq),
2445
    [0xf5] = MMX_OP2(pmaddwd),
2446
    [0xf6] = MMX_OP2(psadbw),
2447
    [0xf7] = MMX_OP2(maskmov),
2448
    [0xf8] = MMX_OP2(psubb),
2449
    [0xf9] = MMX_OP2(psubw),
2450
    [0xfa] = MMX_OP2(psubl),
2451
    [0xfb] = MMX_OP2(psubq),
2452
    [0xfc] = MMX_OP2(paddb),
2453
    [0xfd] = MMX_OP2(paddw),
2454
    [0xfe] = MMX_OP2(paddl),
2455
};
2456

    
2457
static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
2458
    [0 + 2] = MMX_OP2(psrlw),
2459
    [0 + 4] = MMX_OP2(psraw),
2460
    [0 + 6] = MMX_OP2(psllw),
2461
    [8 + 2] = MMX_OP2(psrld),
2462
    [8 + 4] = MMX_OP2(psrad),
2463
    [8 + 6] = MMX_OP2(pslld),
2464
    [16 + 2] = MMX_OP2(psrlq),
2465
    [16 + 3] = { NULL, gen_op_psrldq_xmm },
2466
    [16 + 6] = MMX_OP2(psllq),
2467
    [16 + 7] = { NULL, gen_op_pslldq_xmm },
2468
};
2469

    
2470
static GenOpFunc1 *sse_op_table3[4 * 3] = {
2471
    gen_op_cvtsi2ss,
2472
    gen_op_cvtsi2sd,
2473
    X86_64_ONLY(gen_op_cvtsq2ss),
2474
    X86_64_ONLY(gen_op_cvtsq2sd),
2475
    
2476
    gen_op_cvttss2si,
2477
    gen_op_cvttsd2si,
2478
    X86_64_ONLY(gen_op_cvttss2sq),
2479
    X86_64_ONLY(gen_op_cvttsd2sq),
2480

    
2481
    gen_op_cvtss2si,
2482
    gen_op_cvtsd2si,
2483
    X86_64_ONLY(gen_op_cvtss2sq),
2484
    X86_64_ONLY(gen_op_cvtsd2sq),
2485
};
2486
    
2487
static GenOpFunc2 *sse_op_table4[8][4] = {
2488
    SSE_FOP(cmpeq),
2489
    SSE_FOP(cmplt),
2490
    SSE_FOP(cmple),
2491
    SSE_FOP(cmpunord),
2492
    SSE_FOP(cmpneq),
2493
    SSE_FOP(cmpnlt),
2494
    SSE_FOP(cmpnle),
2495
    SSE_FOP(cmpord),
2496
};
2497
    
2498
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2499
{
2500
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
2501
    int modrm, mod, rm, reg, reg_addr, offset_addr;
2502
    GenOpFunc2 *sse_op2;
2503
    GenOpFunc3 *sse_op3;
2504

    
2505
    b &= 0xff;
2506
    if (s->prefix & PREFIX_DATA) 
2507
        b1 = 1;
2508
    else if (s->prefix & PREFIX_REPZ) 
2509
        b1 = 2;
2510
    else if (s->prefix & PREFIX_REPNZ) 
2511
        b1 = 3;
2512
    else
2513
        b1 = 0;
2514
    sse_op2 = sse_op_table1[b][b1];
2515
    if (!sse_op2) 
2516
        goto illegal_op;
2517
    if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
2518
        is_xmm = 1;
2519
    } else {
2520
        if (b1 == 0) {
2521
            /* MMX case */
2522
            is_xmm = 0;
2523
        } else {
2524
            is_xmm = 1;
2525
        }
2526
    }
2527
    /* simple MMX/SSE operation */
2528
    if (s->flags & HF_TS_MASK) {
2529
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2530
        return;
2531
    }
2532
    if (s->flags & HF_EM_MASK) {
2533
    illegal_op:
2534
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2535
        return;
2536
    }
2537
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2538
        goto illegal_op;
2539
    if (b == 0x77) {
2540
        /* emms */
2541
        gen_op_emms();
2542
        return;
2543
    }
2544
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2545
       the static cpu state) */
2546
    if (!is_xmm) {
2547
        gen_op_enter_mmx();
2548
    }
2549

    
2550
    modrm = ldub_code(s->pc++);
2551
    reg = ((modrm >> 3) & 7);
2552
    if (is_xmm)
2553
        reg |= rex_r;
2554
    mod = (modrm >> 6) & 3;
2555
    if (sse_op2 == SSE_SPECIAL) {
2556
        b |= (b1 << 8);
2557
        switch(b) {
2558
        case 0x0e7: /* movntq */
2559
            if (mod == 3) 
2560
                goto illegal_op;
2561
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2562
            gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2563
            break;
2564
        case 0x1e7: /* movntdq */
2565
        case 0x02b: /* movntps */
2566
        case 0x12b: /* movntps */
2567
        case 0x3f0: /* lddqu */
2568
            if (mod == 3)
2569
                goto illegal_op;
2570
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2571
            gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2572
            break;
2573
        case 0x6e: /* movd mm, ea */
2574
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2575
            gen_op_movl_mm_T0_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2576
            break;
2577
        case 0x16e: /* movd xmm, ea */
2578
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 0);
2579
            gen_op_movl_mm_T0_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2580
            break;
2581
        case 0x6f: /* movq mm, ea */
2582
            if (mod != 3) {
2583
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2584
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2585
            } else {
2586
                rm = (modrm & 7);
2587
                gen_op_movq(offsetof(CPUX86State,fpregs[reg].mmx),
2588
                            offsetof(CPUX86State,fpregs[rm].mmx));
2589
            }
2590
            break;
2591
        case 0x010: /* movups */
2592
        case 0x110: /* movupd */
2593
        case 0x028: /* movaps */
2594
        case 0x128: /* movapd */
2595
        case 0x16f: /* movdqa xmm, ea */
2596
        case 0x26f: /* movdqu xmm, ea */
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_movo(offsetof(CPUX86State,xmm_regs[reg]),
2603
                            offsetof(CPUX86State,xmm_regs[rm]));
2604
            }
2605
            break;
2606
        case 0x210: /* movss xmm, ea */
2607
            if (mod != 3) {
2608
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2609
                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2610
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2611
                gen_op_movl_T0_0();
2612
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2613
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2614
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2615
            } else {
2616
                rm = (modrm & 7) | REX_B(s);
2617
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2618
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2619
            }
2620
            break;
2621
        case 0x310: /* movsd xmm, ea */
2622
            if (mod != 3) {
2623
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2624
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2625
                gen_op_movl_T0_0();
2626
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2627
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2628
            } else {
2629
                rm = (modrm & 7) | REX_B(s);
2630
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2631
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2632
            }
2633
            break;
2634
        case 0x012: /* movlps */
2635
        case 0x112: /* movlpd */
2636
            if (mod != 3) {
2637
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2638
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2639
            } else {
2640
                /* movhlps */
2641
                rm = (modrm & 7) | REX_B(s);
2642
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2643
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2644
            }
2645
            break;
2646
        case 0x212: /* movsldup */
2647
            if (mod != 3) {
2648
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2649
                gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2650
            } else {
2651
                rm = (modrm & 7) | REX_B(s);
2652
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2653
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)));
2654
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2655
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(2)));
2656
            }
2657
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2658
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2659
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2660
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));
2661
            break;
2662
        case 0x312: /* movddup */
2663
            if (mod != 3) {
2664
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2665
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2666
            } else {
2667
                rm = (modrm & 7) | REX_B(s);
2668
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2669
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2670
            }
2671
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2672
                        offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2673
            break;
2674
        case 0x016: /* movhps */
2675
        case 0x116: /* movhpd */
2676
            if (mod != 3) {
2677
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2678
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2679
            } else {
2680
                /* movlhps */
2681
                rm = (modrm & 7) | REX_B(s);
2682
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)),
2683
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2684
            }
2685
            break;
2686
        case 0x216: /* movshdup */
2687
            if (mod != 3) {
2688
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2689
                gen_ldo_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2690
            } else {
2691
                rm = (modrm & 7) | REX_B(s);
2692
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)),
2693
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(1)));
2694
                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)),
2695
                            offsetof(CPUX86State,xmm_regs[rm].XMM_L(3)));
2696
            }
2697
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)),
2698
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
2699
            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)),
2700
                        offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));
2701
            break;
2702
        case 0x7e: /* movd ea, mm */
2703
            gen_op_movl_T0_mm_mmx(offsetof(CPUX86State,fpregs[reg].mmx));
2704
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2705
            break;
2706
        case 0x17e: /* movd ea, xmm */
2707
            gen_op_movl_T0_mm_xmm(offsetof(CPUX86State,xmm_regs[reg]));
2708
            gen_ldst_modrm(s, modrm, OT_LONG, OR_TMP0, 1);
2709
            break;
2710
        case 0x27e: /* movq xmm, ea */
2711
            if (mod != 3) {
2712
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2713
                gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2714
            } else {
2715
                rm = (modrm & 7) | REX_B(s);
2716
                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2717
                            offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2718
            }
2719
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2720
            break;
2721
        case 0x7f: /* movq ea, mm */
2722
            if (mod != 3) {
2723
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2724
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,fpregs[reg].mmx));
2725
            } else {
2726
                rm = (modrm & 7);
2727
                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),
2728
                            offsetof(CPUX86State,fpregs[reg].mmx));
2729
            }
2730
            break;
2731
        case 0x011: /* movups */
2732
        case 0x111: /* movupd */
2733
        case 0x029: /* movaps */
2734
        case 0x129: /* movapd */
2735
        case 0x17f: /* movdqa ea, xmm */
2736
        case 0x27f: /* movdqu ea, xmm */
2737
            if (mod != 3) {
2738
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2739
                gen_sto_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg]));
2740
            } else {
2741
                rm = (modrm & 7) | REX_B(s);
2742
                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),
2743
                            offsetof(CPUX86State,xmm_regs[reg]));
2744
            }
2745
            break;
2746
        case 0x211: /* movss ea, xmm */
2747
            if (mod != 3) {
2748
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2749
                gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2750
                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
2751
            } else {
2752
                rm = (modrm & 7) | REX_B(s);
2753
                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
2754
                            offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
2755
            }
2756
            break;
2757
        case 0x311: /* movsd ea, xmm */
2758
            if (mod != 3) {
2759
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2760
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2761
            } else {
2762
                rm = (modrm & 7) | REX_B(s);
2763
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2764
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2765
            }
2766
            break;
2767
        case 0x013: /* movlps */
2768
        case 0x113: /* movlpd */
2769
            if (mod != 3) {
2770
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2771
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2772
            } else {
2773
                goto illegal_op;
2774
            }
2775
            break;
2776
        case 0x017: /* movhps */
2777
        case 0x117: /* movhpd */
2778
            if (mod != 3) {
2779
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2780
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2781
            } else {
2782
                goto illegal_op;
2783
            }
2784
            break;
2785
        case 0x71: /* shift mm, im */
2786
        case 0x72:
2787
        case 0x73:
2788
        case 0x171: /* shift xmm, im */
2789
        case 0x172:
2790
        case 0x173:
2791
            val = ldub_code(s->pc++);
2792
            if (is_xmm) {
2793
                gen_op_movl_T0_im(val);
2794
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2795
                gen_op_movl_T0_0();
2796
                gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(1)));
2797
                op1_offset = offsetof(CPUX86State,xmm_t0);
2798
            } else {
2799
                gen_op_movl_T0_im(val);
2800
                gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(0)));
2801
                gen_op_movl_T0_0();
2802
                gen_op_movl_env_T0(offsetof(CPUX86State,mmx_t0.MMX_L(1)));
2803
                op1_offset = offsetof(CPUX86State,mmx_t0);
2804
            }
2805
            sse_op2 = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1];
2806
            if (!sse_op2)
2807
                goto illegal_op;
2808
            if (is_xmm) {
2809
                rm = (modrm & 7) | REX_B(s);
2810
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2811
            } else {
2812
                rm = (modrm & 7);
2813
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2814
            }
2815
            sse_op2(op2_offset, op1_offset);
2816
            break;
2817
        case 0x050: /* movmskps */
2818
            rm = (modrm & 7) | REX_B(s);
2819
            gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
2820
            gen_op_mov_reg_T0[OT_LONG][reg]();
2821
            break;
2822
        case 0x150: /* movmskpd */
2823
            rm = (modrm & 7) | REX_B(s);
2824
            gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
2825
            gen_op_mov_reg_T0[OT_LONG][reg]();
2826
            break;
2827
        case 0x02a: /* cvtpi2ps */
2828
        case 0x12a: /* cvtpi2pd */
2829
            gen_op_enter_mmx();
2830
            if (mod != 3) {
2831
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2832
                op2_offset = offsetof(CPUX86State,mmx_t0);
2833
                gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
2834
            } else {
2835
                rm = (modrm & 7);
2836
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
2837
            }
2838
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2839
            switch(b >> 8) {
2840
            case 0x0:
2841
                gen_op_cvtpi2ps(op1_offset, op2_offset);
2842
                break;
2843
            default:
2844
            case 0x1:
2845
                gen_op_cvtpi2pd(op1_offset, op2_offset);
2846
                break;
2847
            }
2848
            break;
2849
        case 0x22a: /* cvtsi2ss */
2850
        case 0x32a: /* cvtsi2sd */
2851
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2852
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
2853
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
2854
            sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2)](op1_offset);
2855
            break;
2856
        case 0x02c: /* cvttps2pi */
2857
        case 0x12c: /* cvttpd2pi */
2858
        case 0x02d: /* cvtps2pi */
2859
        case 0x12d: /* cvtpd2pi */
2860
            gen_op_enter_mmx();
2861
            if (mod != 3) {
2862
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2863
                op2_offset = offsetof(CPUX86State,xmm_t0);
2864
                gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
2865
            } else {
2866
                rm = (modrm & 7) | REX_B(s);
2867
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2868
            }
2869
            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);
2870
            switch(b) {
2871
            case 0x02c:
2872
                gen_op_cvttps2pi(op1_offset, op2_offset);
2873
                break;
2874
            case 0x12c:
2875
                gen_op_cvttpd2pi(op1_offset, op2_offset);
2876
                break;
2877
            case 0x02d:
2878
                gen_op_cvtps2pi(op1_offset, op2_offset);
2879
                break;
2880
            case 0x12d:
2881
                gen_op_cvtpd2pi(op1_offset, op2_offset);
2882
                break;
2883
            }
2884
            break;
2885
        case 0x22c: /* cvttss2si */
2886
        case 0x32c: /* cvttsd2si */
2887
        case 0x22d: /* cvtss2si */
2888
        case 0x32d: /* cvtsd2si */
2889
            ot = (s->dflag == 2) ? OT_QUAD : OT_LONG;
2890
            if (mod != 3) {
2891
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2892
                if ((b >> 8) & 1) {
2893
                    gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
2894
                } else {
2895
                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
2896
                    gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
2897
                }
2898
                op2_offset = offsetof(CPUX86State,xmm_t0);
2899
            } else {
2900
                rm = (modrm & 7) | REX_B(s);
2901
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
2902
            }
2903
            sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 + 
2904
                          (b & 1) * 4](op2_offset);
2905
            gen_op_mov_reg_T0[ot][reg]();
2906
            break;
2907
        case 0xc4: /* pinsrw */
2908
        case 0x1c4: 
2909
            s->rip_offset = 1;
2910
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
2911
            val = ldub_code(s->pc++);
2912
            if (b1) {
2913
                val &= 7;
2914
                gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val);
2915
            } else {
2916
                val &= 3;
2917
                gen_op_pinsrw_mmx(offsetof(CPUX86State,fpregs[reg].mmx), val);
2918
            }
2919
            break;
2920
        case 0xc5: /* pextrw */
2921
        case 0x1c5: 
2922
            if (mod != 3)
2923
                goto illegal_op;
2924
            val = ldub_code(s->pc++);
2925
            if (b1) {
2926
                val &= 7;
2927
                rm = (modrm & 7) | REX_B(s);
2928
                gen_op_pextrw_xmm(offsetof(CPUX86State,xmm_regs[rm]), val);
2929
            } else {
2930
                val &= 3;
2931
                rm = (modrm & 7);
2932
                gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
2933
            }
2934
            reg = ((modrm >> 3) & 7) | rex_r;
2935
            gen_op_mov_reg_T0[OT_LONG][reg]();
2936
            break;
2937
        case 0x1d6: /* movq ea, xmm */
2938
            if (mod != 3) {
2939
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2940
                gen_stq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2941
            } else {
2942
                rm = (modrm & 7) | REX_B(s);
2943
                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)),
2944
                            offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)));
2945
                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].XMM_Q(1)));
2946
            }
2947
            break;
2948
        case 0x2d6: /* movq2dq */
2949
            gen_op_enter_mmx();
2950
            rm = (modrm & 7);
2951
            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(0)),
2952
                        offsetof(CPUX86State,fpregs[rm].mmx));
2953
            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_Q(1)));
2954
            break;
2955
        case 0x3d6: /* movdq2q */
2956
            gen_op_enter_mmx();
2957
            rm = (modrm & 7) | REX_B(s);
2958
            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),
2959
                        offsetof(CPUX86State,xmm_regs[rm].XMM_Q(0)));
2960
            break;
2961
        case 0xd7: /* pmovmskb */
2962
        case 0x1d7:
2963
            if (mod != 3)
2964
                goto illegal_op;
2965
            if (b1) {
2966
                rm = (modrm & 7) | REX_B(s);
2967
                gen_op_pmovmskb_xmm(offsetof(CPUX86State,xmm_regs[rm]));
2968
            } else {
2969
                rm = (modrm & 7);
2970
                gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
2971
            }
2972
            reg = ((modrm >> 3) & 7) | rex_r;
2973
            gen_op_mov_reg_T0[OT_LONG][reg]();
2974
            break;
2975
        default:
2976
            goto illegal_op;
2977
        }
2978
    } else {
2979
        /* generic MMX or SSE operation */
2980
        switch(b) {
2981
        case 0xf7:
2982
            /* maskmov : we must prepare A0 */
2983
            if (mod != 3) 
2984
                goto illegal_op;
2985
#ifdef TARGET_X86_64
2986
            if (s->aflag == 2) {
2987
                gen_op_movq_A0_reg[R_EDI]();
2988
            } else 
2989
#endif
2990
            {
2991
                gen_op_movl_A0_reg[R_EDI]();
2992
                if (s->aflag == 0)
2993
                    gen_op_andl_A0_ffff();
2994
            }
2995
            gen_add_A0_ds_seg(s);
2996
            break;
2997
        case 0x70: /* pshufx insn */
2998
        case 0xc6: /* pshufx insn */
2999
        case 0xc2: /* compare insns */
3000
            s->rip_offset = 1;
3001
            break;
3002
        default:
3003
            break;
3004
        }
3005
        if (is_xmm) {
3006
            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);
3007
            if (mod != 3) {
3008
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3009
                op2_offset = offsetof(CPUX86State,xmm_t0);
3010
                if (b1 >= 2 && ((b >= 0x50 && b <= 0x5f && b != 0x5b) ||
3011
                                b == 0xc2)) {
3012
                    /* specific case for SSE single instructions */
3013
                    if (b1 == 2) {
3014
                        /* 32 bit access */
3015
                        gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
3016
                        gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
3017
                    } else {
3018
                        /* 64 bit access */
3019
                        gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_D(0)));
3020
                    }
3021
                } else {
3022
                    gen_ldo_env_A0[s->mem_index >> 2](op2_offset);
3023
                }
3024
            } else {
3025
                rm = (modrm & 7) | REX_B(s);
3026
                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);
3027
            }
3028
        } else {
3029
            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
3030
            if (mod != 3) {
3031
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3032
                op2_offset = offsetof(CPUX86State,mmx_t0);
3033
                gen_ldq_env_A0[s->mem_index >> 2](op2_offset);
3034
            } else {
3035
                rm = (modrm & 7);
3036
                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
3037
            }
3038
        }
3039
        switch(b) {
3040
        case 0x70: /* pshufx insn */
3041
        case 0xc6: /* pshufx insn */
3042
            val = ldub_code(s->pc++);
3043
            sse_op3 = (GenOpFunc3 *)sse_op2;
3044
            sse_op3(op1_offset, op2_offset, val);
3045
            break;
3046
        case 0xc2:
3047
            /* compare insns */
3048
            val = ldub_code(s->pc++);
3049
            if (val >= 8)
3050
                goto illegal_op;
3051
            sse_op2 = sse_op_table4[val][b1];
3052
            sse_op2(op1_offset, op2_offset);
3053
            break;
3054
        default:
3055
            sse_op2(op1_offset, op2_offset);
3056
            break;
3057
        }
3058
        if (b == 0x2e || b == 0x2f) {
3059
            s->cc_op = CC_OP_EFLAGS;
3060
        }
3061
    }
3062
}
3063

    
3064

    
3065
/* convert one instruction. s->is_jmp is set if the translation must
3066
   be stopped. Return the next pc value */
3067
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3068
{
3069
    int b, prefixes, aflag, dflag;
3070
    int shift, ot;
3071
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
3072
    target_ulong next_eip, tval;
3073
    int rex_w, rex_r;
3074

    
3075
    s->pc = pc_start;
3076
    prefixes = 0;
3077
    aflag = s->code32;
3078
    dflag = s->code32;
3079
    s->override = -1;
3080
    rex_w = -1;
3081
    rex_r = 0;
3082
#ifdef TARGET_X86_64
3083
    s->rex_x = 0;
3084
    s->rex_b = 0;
3085
    x86_64_hregs = 0; 
3086
#endif
3087
    s->rip_offset = 0; /* for relative ip address */
3088
 next_byte:
3089
    b = ldub_code(s->pc);
3090
    s->pc++;
3091
    /* check prefixes */
3092
#ifdef TARGET_X86_64
3093
    if (CODE64(s)) {
3094
        switch (b) {
3095
        case 0xf3:
3096
            prefixes |= PREFIX_REPZ;
3097
            goto next_byte;
3098
        case 0xf2:
3099
            prefixes |= PREFIX_REPNZ;
3100
            goto next_byte;
3101
        case 0xf0:
3102
            prefixes |= PREFIX_LOCK;
3103
            goto next_byte;
3104
        case 0x2e:
3105
            s->override = R_CS;
3106
            goto next_byte;
3107
        case 0x36:
3108
            s->override = R_SS;
3109
            goto next_byte;
3110
        case 0x3e:
3111
            s->override = R_DS;
3112
            goto next_byte;
3113
        case 0x26:
3114
            s->override = R_ES;
3115
            goto next_byte;
3116
        case 0x64:
3117
            s->override = R_FS;
3118
            goto next_byte;
3119
        case 0x65:
3120
            s->override = R_GS;
3121
            goto next_byte;
3122
        case 0x66:
3123
            prefixes |= PREFIX_DATA;
3124
            goto next_byte;
3125
        case 0x67:
3126
            prefixes |= PREFIX_ADR;
3127
            goto next_byte;
3128
        case 0x40 ... 0x4f:
3129
            /* REX prefix */
3130
            rex_w = (b >> 3) & 1;
3131
            rex_r = (b & 0x4) << 1;
3132
            s->rex_x = (b & 0x2) << 2;
3133
            REX_B(s) = (b & 0x1) << 3;
3134
            x86_64_hregs = 1; /* select uniform byte register addressing */
3135
            goto next_byte;
3136
        }
3137
        if (rex_w == 1) {
3138
            /* 0x66 is ignored if rex.w is set */
3139
            dflag = 2;
3140
        } else {
3141
            if (prefixes & PREFIX_DATA)
3142
                dflag ^= 1;
3143
        }
3144
        if (!(prefixes & PREFIX_ADR))
3145
            aflag = 2;
3146
    } else 
3147
#endif
3148
    {
3149
        switch (b) {
3150
        case 0xf3:
3151
            prefixes |= PREFIX_REPZ;
3152
            goto next_byte;
3153
        case 0xf2:
3154
            prefixes |= PREFIX_REPNZ;
3155
            goto next_byte;
3156
        case 0xf0:
3157
            prefixes |= PREFIX_LOCK;
3158
            goto next_byte;
3159
        case 0x2e:
3160
            s->override = R_CS;
3161
            goto next_byte;
3162
        case 0x36:
3163
            s->override = R_SS;
3164
            goto next_byte;
3165
        case 0x3e:
3166
            s->override = R_DS;
3167
            goto next_byte;
3168
        case 0x26:
3169
            s->override = R_ES;
3170
            goto next_byte;
3171
        case 0x64:
3172
            s->override = R_FS;
3173
            goto next_byte;
3174
        case 0x65:
3175
            s->override = R_GS;
3176
            goto next_byte;
3177
        case 0x66:
3178
            prefixes |= PREFIX_DATA;
3179
            goto next_byte;
3180
        case 0x67:
3181
            prefixes |= PREFIX_ADR;
3182
            goto next_byte;
3183
        }
3184
        if (prefixes & PREFIX_DATA)
3185
            dflag ^= 1;
3186
        if (prefixes & PREFIX_ADR)
3187
            aflag ^= 1;
3188
    }
3189

    
3190
    s->prefix = prefixes;
3191
    s->aflag = aflag;
3192
    s->dflag = dflag;
3193

    
3194
    /* lock generation */
3195
    if (prefixes & PREFIX_LOCK)
3196
        gen_op_lock();
3197

    
3198
    /* now check op code */
3199
 reswitch:
3200
    switch(b) {
3201
    case 0x0f:
3202
        /**************************/
3203
        /* extended op code */
3204
        b = ldub_code(s->pc++) | 0x100;
3205
        goto reswitch;
3206
        
3207
        /**************************/
3208
        /* arith & logic */
3209
    case 0x00 ... 0x05:
3210
    case 0x08 ... 0x0d:
3211
    case 0x10 ... 0x15:
3212
    case 0x18 ... 0x1d:
3213
    case 0x20 ... 0x25:
3214
    case 0x28 ... 0x2d:
3215
    case 0x30 ... 0x35:
3216
    case 0x38 ... 0x3d:
3217
        {
3218
            int op, f, val;
3219
            op = (b >> 3) & 7;
3220
            f = (b >> 1) & 3;
3221

    
3222
            if ((b & 1) == 0)
3223
                ot = OT_BYTE;
3224
            else
3225
                ot = dflag + OT_WORD;
3226
            
3227
            switch(f) {
3228
            case 0: /* OP Ev, Gv */
3229
                modrm = ldub_code(s->pc++);
3230
                reg = ((modrm >> 3) & 7) | rex_r;
3231
                mod = (modrm >> 6) & 3;
3232
                rm = (modrm & 7) | REX_B(s);
3233
                if (mod != 3) {
3234
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3235
                    opreg = OR_TMP0;
3236
                } else if (op == OP_XORL && rm == reg) {
3237
                xor_zero:
3238
                    /* xor reg, reg optimisation */
3239
                    gen_op_movl_T0_0();
3240
                    s->cc_op = CC_OP_LOGICB + ot;
3241
                    gen_op_mov_reg_T0[ot][reg]();
3242
                    gen_op_update1_cc();
3243
                    break;
3244
                } else {
3245
                    opreg = rm;
3246
                }
3247
                gen_op_mov_TN_reg[ot][1][reg]();
3248
                gen_op(s, op, ot, opreg);
3249
                break;
3250
            case 1: /* OP Gv, Ev */
3251
                modrm = ldub_code(s->pc++);
3252
                mod = (modrm >> 6) & 3;
3253
                reg = ((modrm >> 3) & 7) | rex_r;
3254
                rm = (modrm & 7) | REX_B(s);
3255
                if (mod != 3) {
3256
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3257
                    gen_op_ld_T1_A0[ot + s->mem_index]();
3258
                } else if (op == OP_XORL && rm == reg) {
3259
                    goto xor_zero;
3260
                } else {
3261
                    gen_op_mov_TN_reg[ot][1][rm]();
3262
                }
3263
                gen_op(s, op, ot, reg);
3264
                break;
3265
            case 2: /* OP A, Iv */
3266
                val = insn_get(s, ot);
3267
                gen_op_movl_T1_im(val);
3268
                gen_op(s, op, ot, OR_EAX);
3269
                break;
3270
            }
3271
        }
3272
        break;
3273

    
3274
    case 0x80: /* GRP1 */
3275
    case 0x81:
3276
    case 0x82:
3277
    case 0x83:
3278
        {
3279
            int val;
3280

    
3281
            if ((b & 1) == 0)
3282
                ot = OT_BYTE;
3283
            else
3284
                ot = dflag + OT_WORD;
3285
            
3286
            modrm = ldub_code(s->pc++);
3287
            mod = (modrm >> 6) & 3;
3288
            rm = (modrm & 7) | REX_B(s);
3289
            op = (modrm >> 3) & 7;
3290
            
3291
            if (mod != 3) {
3292
                if (b == 0x83)
3293
                    s->rip_offset = 1;
3294
                else
3295
                    s->rip_offset = insn_const_size(ot);
3296
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3297
                opreg = OR_TMP0;
3298
            } else {
3299
                opreg = rm;
3300
            }
3301

    
3302
            switch(b) {
3303
            default:
3304
            case 0x80:
3305
            case 0x81:
3306
            case 0x82:
3307
                val = insn_get(s, ot);
3308
                break;
3309
            case 0x83:
3310
                val = (int8_t)insn_get(s, OT_BYTE);
3311
                break;
3312
            }
3313
            gen_op_movl_T1_im(val);
3314
            gen_op(s, op, ot, opreg);
3315
        }
3316
        break;
3317

    
3318
        /**************************/
3319
        /* inc, dec, and other misc arith */
3320
    case 0x40 ... 0x47: /* inc Gv */
3321
        ot = dflag ? OT_LONG : OT_WORD;
3322
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3323
        break;
3324
    case 0x48 ... 0x4f: /* dec Gv */
3325
        ot = dflag ? OT_LONG : OT_WORD;
3326
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3327
        break;
3328
    case 0xf6: /* GRP3 */
3329
    case 0xf7:
3330
        if ((b & 1) == 0)
3331
            ot = OT_BYTE;
3332
        else
3333
            ot = dflag + OT_WORD;
3334

    
3335
        modrm = ldub_code(s->pc++);
3336
        mod = (modrm >> 6) & 3;
3337
        rm = (modrm & 7) | REX_B(s);
3338
        op = (modrm >> 3) & 7;
3339
        if (mod != 3) {
3340
            if (op == 0)
3341
                s->rip_offset = insn_const_size(ot);
3342
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3343
            gen_op_ld_T0_A0[ot + s->mem_index]();
3344
        } else {
3345
            gen_op_mov_TN_reg[ot][0][rm]();
3346
        }
3347

    
3348
        switch(op) {
3349
        case 0: /* test */
3350
            val = insn_get(s, ot);
3351
            gen_op_movl_T1_im(val);
3352
            gen_op_testl_T0_T1_cc();
3353
            s->cc_op = CC_OP_LOGICB + ot;
3354
            break;
3355
        case 2: /* not */
3356
            gen_op_notl_T0();
3357
            if (mod != 3) {
3358
                gen_op_st_T0_A0[ot + s->mem_index]();
3359
            } else {
3360
                gen_op_mov_reg_T0[ot][rm]();
3361
            }
3362
            break;
3363
        case 3: /* neg */
3364
            gen_op_negl_T0();
3365
            if (mod != 3) {
3366
                gen_op_st_T0_A0[ot + s->mem_index]();
3367
            } else {
3368
                gen_op_mov_reg_T0[ot][rm]();
3369
            }
3370
            gen_op_update_neg_cc();
3371
            s->cc_op = CC_OP_SUBB + ot;
3372
            break;
3373
        case 4: /* mul */
3374
            switch(ot) {
3375
            case OT_BYTE:
3376
                gen_op_mulb_AL_T0();
3377
                s->cc_op = CC_OP_MULB;
3378
                break;
3379
            case OT_WORD:
3380
                gen_op_mulw_AX_T0();
3381
                s->cc_op = CC_OP_MULW;
3382
                break;
3383
            default:
3384
            case OT_LONG:
3385
                gen_op_mull_EAX_T0();
3386
                s->cc_op = CC_OP_MULL;
3387
                break;
3388
#ifdef TARGET_X86_64
3389
            case OT_QUAD:
3390
                gen_op_mulq_EAX_T0();
3391
                s->cc_op = CC_OP_MULQ;
3392
                break;
3393
#endif
3394
            }
3395
            break;
3396
        case 5: /* imul */
3397
            switch(ot) {
3398
            case OT_BYTE:
3399
                gen_op_imulb_AL_T0();
3400
                s->cc_op = CC_OP_MULB;
3401
                break;
3402
            case OT_WORD:
3403
                gen_op_imulw_AX_T0();
3404
                s->cc_op = CC_OP_MULW;
3405
                break;
3406
            default:
3407
            case OT_LONG:
3408
                gen_op_imull_EAX_T0();
3409
                s->cc_op = CC_OP_MULL;
3410
                break;
3411
#ifdef TARGET_X86_64
3412
            case OT_QUAD:
3413
                gen_op_imulq_EAX_T0();
3414
                s->cc_op = CC_OP_MULQ;
3415
                break;
3416
#endif
3417
            }
3418
            break;
3419
        case 6: /* div */
3420
            switch(ot) {
3421
            case OT_BYTE:
3422
                gen_jmp_im(pc_start - s->cs_base);
3423
                gen_op_divb_AL_T0();
3424
                break;
3425
            case OT_WORD:
3426
                gen_jmp_im(pc_start - s->cs_base);
3427
                gen_op_divw_AX_T0();
3428
                break;
3429
            default:
3430
            case OT_LONG:
3431
                gen_jmp_im(pc_start - s->cs_base);
3432
                gen_op_divl_EAX_T0();
3433
                break;
3434
#ifdef TARGET_X86_64
3435
            case OT_QUAD:
3436
                gen_jmp_im(pc_start - s->cs_base);
3437
                gen_op_divq_EAX_T0();
3438
                break;
3439
#endif
3440
            }
3441
            break;
3442
        case 7: /* idiv */
3443
            switch(ot) {
3444
            case OT_BYTE:
3445
                gen_jmp_im(pc_start - s->cs_base);
3446
                gen_op_idivb_AL_T0();
3447
                break;
3448
            case OT_WORD:
3449
                gen_jmp_im(pc_start - s->cs_base);
3450
                gen_op_idivw_AX_T0();
3451
                break;
3452
            default:
3453
            case OT_LONG:
3454
                gen_jmp_im(pc_start - s->cs_base);
3455
                gen_op_idivl_EAX_T0();
3456
                break;
3457
#ifdef TARGET_X86_64
3458
            case OT_QUAD:
3459
                gen_jmp_im(pc_start - s->cs_base);
3460
                gen_op_idivq_EAX_T0();
3461
                break;
3462
#endif
3463
            }
3464
            break;
3465
        default:
3466
            goto illegal_op;
3467
        }
3468
        break;
3469

    
3470
    case 0xfe: /* GRP4 */
3471
    case 0xff: /* GRP5 */
3472
        if ((b & 1) == 0)
3473
            ot = OT_BYTE;
3474
        else
3475
            ot = dflag + OT_WORD;
3476

    
3477
        modrm = ldub_code(s->pc++);
3478
        mod = (modrm >> 6) & 3;
3479
        rm = (modrm & 7) | REX_B(s);
3480
        op = (modrm >> 3) & 7;
3481
        if (op >= 2 && b == 0xfe) {
3482
            goto illegal_op;
3483
        }
3484
        if (CODE64(s)) {
3485
            if (op == 2 || op == 4) {
3486
                /* operand size for jumps is 64 bit */
3487
                ot = OT_QUAD;
3488
            } else if (op == 3 || op == 5) {
3489
                /* for call calls, the operand is 16 or 32 bit, even
3490
                   in long mode */
3491
                ot = dflag ? OT_LONG : OT_WORD;
3492
            } else if (op == 6) {
3493
                /* default push size is 64 bit */
3494
                ot = dflag ? OT_QUAD : OT_WORD;
3495
            }
3496
        }
3497
        if (mod != 3) {
3498
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3499
            if (op >= 2 && op != 3 && op != 5)
3500
                gen_op_ld_T0_A0[ot + s->mem_index]();
3501
        } else {
3502
            gen_op_mov_TN_reg[ot][0][rm]();
3503
        }
3504

    
3505
        switch(op) {
3506
        case 0: /* inc Ev */
3507
            if (mod != 3)
3508
                opreg = OR_TMP0;
3509
            else
3510
                opreg = rm;
3511
            gen_inc(s, ot, opreg, 1);
3512
            break;
3513
        case 1: /* dec Ev */
3514
            if (mod != 3)
3515
                opreg = OR_TMP0;
3516
            else
3517
                opreg = rm;
3518
            gen_inc(s, ot, opreg, -1);
3519
            break;
3520
        case 2: /* call Ev */
3521
            /* XXX: optimize if memory (no 'and' is necessary) */
3522
            if (s->dflag == 0)
3523
                gen_op_andl_T0_ffff();
3524
            next_eip = s->pc - s->cs_base;
3525
            gen_movtl_T1_im(next_eip);
3526
            gen_push_T1(s);
3527
            gen_op_jmp_T0();
3528
            gen_eob(s);
3529
            break;
3530
        case 3: /* lcall Ev */
3531
            gen_op_ld_T1_A0[ot + s->mem_index]();
3532
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3533
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3534
        do_lcall:
3535
            if (s->pe && !s->vm86) {
3536
                if (s->cc_op != CC_OP_DYNAMIC)
3537
                    gen_op_set_cc_op(s->cc_op);
3538
                gen_jmp_im(pc_start - s->cs_base);
3539
                gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
3540
            } else {
3541
                gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
3542
            }
3543
            gen_eob(s);
3544
            break;
3545
        case 4: /* jmp Ev */
3546
            if (s->dflag == 0)
3547
                gen_op_andl_T0_ffff();
3548
            gen_op_jmp_T0();
3549
            gen_eob(s);
3550
            break;
3551
        case 5: /* ljmp Ev */
3552
            gen_op_ld_T1_A0[ot + s->mem_index]();
3553
            gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3554
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3555
        do_ljmp:
3556
            if (s->pe && !s->vm86) {
3557
                if (s->cc_op != CC_OP_DYNAMIC)
3558
                    gen_op_set_cc_op(s->cc_op);
3559
                gen_jmp_im(pc_start - s->cs_base);
3560
                gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
3561
            } else {
3562
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3563
                gen_op_movl_T0_T1();
3564
                gen_op_jmp_T0();
3565
            }
3566
            gen_eob(s);
3567
            break;
3568
        case 6: /* push Ev */
3569
            gen_push_T0(s);
3570
            break;
3571
        default:
3572
            goto illegal_op;
3573
        }
3574
        break;
3575

    
3576
    case 0x84: /* test Ev, Gv */
3577
    case 0x85: 
3578
        if ((b & 1) == 0)
3579
            ot = OT_BYTE;
3580
        else
3581
            ot = dflag + OT_WORD;
3582

    
3583
        modrm = ldub_code(s->pc++);
3584
        mod = (modrm >> 6) & 3;
3585
        rm = (modrm & 7) | REX_B(s);
3586
        reg = ((modrm >> 3) & 7) | rex_r;
3587
        
3588
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3589
        gen_op_mov_TN_reg[ot][1][reg]();
3590
        gen_op_testl_T0_T1_cc();
3591
        s->cc_op = CC_OP_LOGICB + ot;
3592
        break;
3593
        
3594
    case 0xa8: /* test eAX, Iv */
3595
    case 0xa9:
3596
        if ((b & 1) == 0)
3597
            ot = OT_BYTE;
3598
        else
3599
            ot = dflag + OT_WORD;
3600
        val = insn_get(s, ot);
3601

    
3602
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
3603
        gen_op_movl_T1_im(val);
3604
        gen_op_testl_T0_T1_cc();
3605
        s->cc_op = CC_OP_LOGICB + ot;
3606
        break;
3607
        
3608
    case 0x98: /* CWDE/CBW */
3609
#ifdef TARGET_X86_64
3610
        if (dflag == 2) {
3611
            gen_op_movslq_RAX_EAX();
3612
        } else
3613
#endif
3614
        if (dflag == 1)
3615
            gen_op_movswl_EAX_AX();
3616
        else
3617
            gen_op_movsbw_AX_AL();
3618
        break;
3619
    case 0x99: /* CDQ/CWD */
3620
#ifdef TARGET_X86_64
3621
        if (dflag == 2) {
3622
            gen_op_movsqo_RDX_RAX();
3623
        } else
3624
#endif
3625
        if (dflag == 1)
3626
            gen_op_movslq_EDX_EAX();
3627
        else
3628
            gen_op_movswl_DX_AX();
3629
        break;
3630
    case 0x1af: /* imul Gv, Ev */
3631
    case 0x69: /* imul Gv, Ev, I */
3632
    case 0x6b:
3633
        ot = dflag + OT_WORD;
3634
        modrm = ldub_code(s->pc++);
3635
        reg = ((modrm >> 3) & 7) | rex_r;
3636
        if (b == 0x69)
3637
            s->rip_offset = insn_const_size(ot);
3638
        else if (b == 0x6b)
3639
            s->rip_offset = 1;
3640
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3641
        if (b == 0x69) {
3642
            val = insn_get(s, ot);
3643
            gen_op_movl_T1_im(val);
3644
        } else if (b == 0x6b) {
3645
            val = (int8_t)insn_get(s, OT_BYTE);
3646
            gen_op_movl_T1_im(val);
3647
        } else {
3648
            gen_op_mov_TN_reg[ot][1][reg]();
3649
        }
3650

    
3651
#ifdef TARGET_X86_64
3652
        if (ot == OT_QUAD) {
3653
            gen_op_imulq_T0_T1();
3654
        } else
3655
#endif
3656
        if (ot == OT_LONG) {
3657
            gen_op_imull_T0_T1();
3658
        } else {
3659
            gen_op_imulw_T0_T1();
3660
        }
3661
        gen_op_mov_reg_T0[ot][reg]();
3662
        s->cc_op = CC_OP_MULB + ot;
3663
        break;
3664
    case 0x1c0:
3665
    case 0x1c1: /* xadd Ev, Gv */
3666
        if ((b & 1) == 0)
3667
            ot = OT_BYTE;
3668
        else
3669
            ot = dflag + OT_WORD;
3670
        modrm = ldub_code(s->pc++);
3671
        reg = ((modrm >> 3) & 7) | rex_r;
3672
        mod = (modrm >> 6) & 3;
3673
        if (mod == 3) {
3674
            rm = (modrm & 7) | REX_B(s);
3675
            gen_op_mov_TN_reg[ot][0][reg]();
3676
            gen_op_mov_TN_reg[ot][1][rm]();
3677
            gen_op_addl_T0_T1();
3678
            gen_op_mov_reg_T1[ot][reg]();
3679
            gen_op_mov_reg_T0[ot][rm]();
3680
        } else {
3681
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3682
            gen_op_mov_TN_reg[ot][0][reg]();
3683
            gen_op_ld_T1_A0[ot + s->mem_index]();
3684
            gen_op_addl_T0_T1();
3685
            gen_op_st_T0_A0[ot + s->mem_index]();
3686
            gen_op_mov_reg_T1[ot][reg]();
3687
        }
3688
        gen_op_update2_cc();
3689
        s->cc_op = CC_OP_ADDB + ot;
3690
        break;
3691
    case 0x1b0:
3692
    case 0x1b1: /* cmpxchg Ev, Gv */
3693
        if ((b & 1) == 0)
3694
            ot = OT_BYTE;
3695
        else
3696
            ot = dflag + OT_WORD;
3697
        modrm = ldub_code(s->pc++);
3698
        reg = ((modrm >> 3) & 7) | rex_r;
3699
        mod = (modrm >> 6) & 3;
3700
        gen_op_mov_TN_reg[ot][1][reg]();
3701
        if (mod == 3) {
3702
            rm = (modrm & 7) | REX_B(s);
3703
            gen_op_mov_TN_reg[ot][0][rm]();
3704
            gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
3705
            gen_op_mov_reg_T0[ot][rm]();
3706
        } else {
3707
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3708
            gen_op_ld_T0_A0[ot + s->mem_index]();
3709
            gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
3710
        }
3711
        s->cc_op = CC_OP_SUBB + ot;
3712
        break;
3713
    case 0x1c7: /* cmpxchg8b */
3714
        modrm = ldub_code(s->pc++);
3715
        mod = (modrm >> 6) & 3;
3716
        if (mod == 3)
3717
            goto illegal_op;
3718
        if (s->cc_op != CC_OP_DYNAMIC)
3719
            gen_op_set_cc_op(s->cc_op);
3720
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3721
        gen_op_cmpxchg8b();
3722
        s->cc_op = CC_OP_EFLAGS;
3723
        break;
3724
        
3725
        /**************************/
3726
        /* push/pop */
3727
    case 0x50 ... 0x57: /* push */
3728
        gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
3729
        gen_push_T0(s);
3730
        break;
3731
    case 0x58 ... 0x5f: /* pop */
3732
        if (CODE64(s)) {
3733
            ot = dflag ? OT_QUAD : OT_WORD;
3734
        } else {
3735
            ot = dflag + OT_WORD;
3736
        }
3737
        gen_pop_T0(s);
3738
        /* NOTE: order is important for pop %sp */
3739
        gen_pop_update(s);
3740
        gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
3741
        break;
3742
    case 0x60: /* pusha */
3743
        if (CODE64(s))
3744
            goto illegal_op;
3745
        gen_pusha(s);
3746
        break;
3747
    case 0x61: /* popa */
3748
        if (CODE64(s))
3749
            goto illegal_op;
3750
        gen_popa(s);
3751
        break;
3752
    case 0x68: /* push Iv */
3753
    case 0x6a:
3754
        if (CODE64(s)) {
3755
            ot = dflag ? OT_QUAD : OT_WORD;
3756
        } else {
3757
            ot = dflag + OT_WORD;
3758
        }
3759
        if (b == 0x68)
3760
            val = insn_get(s, ot);
3761
        else
3762
            val = (int8_t)insn_get(s, OT_BYTE);
3763
        gen_op_movl_T0_im(val);
3764
        gen_push_T0(s);
3765
        break;
3766
    case 0x8f: /* pop Ev */
3767
        if (CODE64(s)) {
3768
            ot = dflag ? OT_QUAD : OT_WORD;
3769
        } else {
3770
            ot = dflag + OT_WORD;
3771
        }
3772
        modrm = ldub_code(s->pc++);
3773
        mod = (modrm >> 6) & 3;
3774
        gen_pop_T0(s);
3775
        if (mod == 3) {
3776
            /* NOTE: order is important for pop %sp */
3777
            gen_pop_update(s);
3778
            rm = (modrm & 7) | REX_B(s);
3779
            gen_op_mov_reg_T0[ot][rm]();
3780
        } else {
3781
            /* NOTE: order is important too for MMU exceptions */
3782
            s->popl_esp_hack = 1 << ot;
3783
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3784
            s->popl_esp_hack = 0;
3785
            gen_pop_update(s);
3786
        }
3787
        break;
3788
    case 0xc8: /* enter */
3789
        {
3790
            int level;
3791
            val = lduw_code(s->pc);
3792
            s->pc += 2;
3793
            level = ldub_code(s->pc++);
3794
            gen_enter(s, val, level);
3795
        }
3796
        break;
3797
    case 0xc9: /* leave */
3798
        /* XXX: exception not precise (ESP is updated before potential exception) */
3799
        if (CODE64(s)) {
3800
            gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
3801
            gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
3802
        } else if (s->ss32) {
3803
            gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
3804
            gen_op_mov_reg_T0[OT_LONG][R_ESP]();
3805
        } else {
3806
            gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
3807
            gen_op_mov_reg_T0[OT_WORD][R_ESP]();
3808
        }
3809
        gen_pop_T0(s);
3810
        if (CODE64(s)) {
3811
            ot = dflag ? OT_QUAD : OT_WORD;
3812
        } else {
3813
            ot = dflag + OT_WORD;
3814
        }
3815
        gen_op_mov_reg_T0[ot][R_EBP]();
3816
        gen_pop_update(s);
3817
        break;
3818
    case 0x06: /* push es */
3819
    case 0x0e: /* push cs */
3820
    case 0x16: /* push ss */
3821
    case 0x1e: /* push ds */
3822
        if (CODE64(s))
3823
            goto illegal_op;
3824
        gen_op_movl_T0_seg(b >> 3);
3825
        gen_push_T0(s);
3826
        break;
3827
    case 0x1a0: /* push fs */
3828
    case 0x1a8: /* push gs */
3829
        gen_op_movl_T0_seg((b >> 3) & 7);
3830
        gen_push_T0(s);
3831
        break;
3832
    case 0x07: /* pop es */
3833
    case 0x17: /* pop ss */
3834
    case 0x1f: /* pop ds */
3835
        if (CODE64(s))
3836
            goto illegal_op;
3837
        reg = b >> 3;
3838
        gen_pop_T0(s);
3839
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
3840
        gen_pop_update(s);
3841
        if (reg == R_SS) {
3842
            /* if reg == SS, inhibit interrupts/trace. */
3843
            /* If several instructions disable interrupts, only the
3844
               _first_ does it */
3845
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3846
                gen_op_set_inhibit_irq();
3847
            s->tf = 0;
3848
        }
3849
        if (s->is_jmp) {
3850
            gen_jmp_im(s->pc - s->cs_base);
3851
            gen_eob(s);
3852
        }
3853
        break;
3854
    case 0x1a1: /* pop fs */
3855
    case 0x1a9: /* pop gs */
3856
        gen_pop_T0(s);
3857
        gen_movl_seg_T0(s, (b >> 3) & 7, pc_start - s->cs_base);
3858
        gen_pop_update(s);
3859
        if (s->is_jmp) {
3860
            gen_jmp_im(s->pc - s->cs_base);
3861
            gen_eob(s);
3862
        }
3863
        break;
3864

    
3865
        /**************************/
3866
        /* mov */
3867
    case 0x88:
3868
    case 0x89: /* mov Gv, Ev */
3869
        if ((b & 1) == 0)
3870
            ot = OT_BYTE;
3871
        else
3872
            ot = dflag + OT_WORD;
3873
        modrm = ldub_code(s->pc++);
3874
        reg = ((modrm >> 3) & 7) | rex_r;
3875
        
3876
        /* generate a generic store */
3877
        gen_ldst_modrm(s, modrm, ot, reg, 1);
3878
        break;
3879
    case 0xc6:
3880
    case 0xc7: /* mov Ev, Iv */
3881
        if ((b & 1) == 0)
3882
            ot = OT_BYTE;
3883
        else
3884
            ot = dflag + OT_WORD;
3885
        modrm = ldub_code(s->pc++);
3886
        mod = (modrm >> 6) & 3;
3887
        if (mod != 3) {
3888
            s->rip_offset = insn_const_size(ot);
3889
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3890
        }
3891
        val = insn_get(s, ot);
3892
        gen_op_movl_T0_im(val);
3893
        if (mod != 3)
3894
            gen_op_st_T0_A0[ot + s->mem_index]();
3895
        else
3896
            gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
3897
        break;
3898
    case 0x8a:
3899
    case 0x8b: /* mov Ev, Gv */
3900
        if ((b & 1) == 0)
3901
            ot = OT_BYTE;
3902
        else
3903
            ot = OT_WORD + dflag;
3904
        modrm = ldub_code(s->pc++);
3905
        reg = ((modrm >> 3) & 7) | rex_r;
3906
        
3907
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3908
        gen_op_mov_reg_T0[ot][reg]();
3909
        break;
3910
    case 0x8e: /* mov seg, Gv */
3911
        modrm = ldub_code(s->pc++);
3912
        reg = (modrm >> 3) & 7;
3913
        if (reg >= 6 || reg == R_CS)
3914
            goto illegal_op;
3915
        gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3916
        gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
3917
        if (reg == R_SS) {
3918
            /* if reg == SS, inhibit interrupts/trace */
3919
            /* If several instructions disable interrupts, only the
3920
               _first_ does it */
3921
            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
3922
                gen_op_set_inhibit_irq();
3923
            s->tf = 0;
3924
        }
3925
        if (s->is_jmp) {
3926
            gen_jmp_im(s->pc - s->cs_base);
3927
            gen_eob(s);
3928
        }
3929
        break;
3930
    case 0x8c: /* mov Gv, seg */
3931
        modrm = ldub_code(s->pc++);
3932
        reg = (modrm >> 3) & 7;
3933
        mod = (modrm >> 6) & 3;
3934
        if (reg >= 6)
3935
            goto illegal_op;
3936
        gen_op_movl_T0_seg(reg);
3937
        if (mod == 3)
3938
            ot = OT_WORD + dflag;
3939
        else
3940
            ot = OT_WORD;
3941
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3942
        break;
3943

    
3944
    case 0x1b6: /* movzbS Gv, Eb */
3945
    case 0x1b7: /* movzwS Gv, Eb */
3946
    case 0x1be: /* movsbS Gv, Eb */
3947
    case 0x1bf: /* movswS Gv, Eb */
3948
        {
3949
            int d_ot;
3950
            /* d_ot is the size of destination */
3951
            d_ot = dflag + OT_WORD;
3952
            /* ot is the size of source */
3953
            ot = (b & 1) + OT_BYTE;
3954
            modrm = ldub_code(s->pc++);
3955
            reg = ((modrm >> 3) & 7) | rex_r;
3956
            mod = (modrm >> 6) & 3;
3957
            rm = (modrm & 7) | REX_B(s);
3958
            
3959
            if (mod == 3) {
3960
                gen_op_mov_TN_reg[ot][0][rm]();
3961
                switch(ot | (b & 8)) {
3962
                case OT_BYTE:
3963
                    gen_op_movzbl_T0_T0();
3964
                    break;
3965
                case OT_BYTE | 8:
3966
                    gen_op_movsbl_T0_T0();
3967
                    break;
3968
                case OT_WORD:
3969
                    gen_op_movzwl_T0_T0();
3970
                    break;
3971
                default:
3972
                case OT_WORD | 8:
3973
                    gen_op_movswl_T0_T0();
3974
                    break;
3975
                }
3976
                gen_op_mov_reg_T0[d_ot][reg]();
3977
            } else {
3978
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3979
                if (b & 8) {
3980
                    gen_op_lds_T0_A0[ot + s->mem_index]();
3981
                } else {
3982
                    gen_op_ldu_T0_A0[ot + s->mem_index]();
3983
                }
3984
                gen_op_mov_reg_T0[d_ot][reg]();
3985
            }
3986
        }
3987
        break;
3988

    
3989
    case 0x8d: /* lea */
3990
        ot = dflag + OT_WORD;
3991
        modrm = ldub_code(s->pc++);
3992
        mod = (modrm >> 6) & 3;
3993
        if (mod == 3)
3994
            goto illegal_op;
3995
        reg = ((modrm >> 3) & 7) | rex_r;
3996
        /* we must ensure that no segment is added */
3997
        s->override = -1;
3998
        val = s->addseg;
3999
        s->addseg = 0;
4000
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4001
        s->addseg = val;
4002
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
4003
        break;
4004
        
4005
    case 0xa0: /* mov EAX, Ov */
4006
    case 0xa1:
4007
    case 0xa2: /* mov Ov, EAX */
4008
    case 0xa3:
4009
        {
4010
            target_ulong offset_addr;
4011

    
4012
            if ((b & 1) == 0)
4013
                ot = OT_BYTE;
4014
            else
4015
                ot = dflag + OT_WORD;
4016
#ifdef TARGET_X86_64
4017
            if (s->aflag == 2) {
4018
                offset_addr = ldq_code(s->pc);
4019
                s->pc += 8;
4020
                if (offset_addr == (int32_t)offset_addr)
4021
                    gen_op_movq_A0_im(offset_addr);
4022
                else
4023
                    gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
4024
            } else 
4025
#endif
4026
            {
4027
                if (s->aflag) {
4028
                    offset_addr = insn_get(s, OT_LONG);
4029
                } else {
4030
                    offset_addr = insn_get(s, OT_WORD);
4031
                }
4032
                gen_op_movl_A0_im(offset_addr);
4033
            }
4034
            gen_add_A0_ds_seg(s);
4035
            if ((b & 2) == 0) {
4036
                gen_op_ld_T0_A0[ot + s->mem_index]();
4037
                gen_op_mov_reg_T0[ot][R_EAX]();
4038
            } else {
4039
                gen_op_mov_TN_reg[ot][0][R_EAX]();
4040
                gen_op_st_T0_A0[ot + s->mem_index]();
4041
            }
4042
        }
4043
        break;
4044
    case 0xd7: /* xlat */
4045
#ifdef TARGET_X86_64
4046
        if (s->aflag == 2) {
4047
            gen_op_movq_A0_reg[R_EBX]();
4048
            gen_op_addq_A0_AL();
4049
        } else 
4050
#endif
4051
        {
4052
            gen_op_movl_A0_reg[R_EBX]();
4053
            gen_op_addl_A0_AL();
4054
            if (s->aflag == 0)
4055
                gen_op_andl_A0_ffff();
4056
        }
4057
        gen_add_A0_ds_seg(s);
4058
        gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
4059
        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
4060
        break;
4061
    case 0xb0 ... 0xb7: /* mov R, Ib */
4062
        val = insn_get(s, OT_BYTE);
4063
        gen_op_movl_T0_im(val);
4064
        gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
4065
        break;
4066
    case 0xb8 ... 0xbf: /* mov R, Iv */
4067
#ifdef TARGET_X86_64
4068
        if (dflag == 2) {
4069
            uint64_t tmp;
4070
            /* 64 bit case */
4071
            tmp = ldq_code(s->pc);
4072
            s->pc += 8;
4073
            reg = (b & 7) | REX_B(s);
4074
            gen_movtl_T0_im(tmp);
4075
            gen_op_mov_reg_T0[OT_QUAD][reg]();
4076
        } else 
4077
#endif
4078
        {
4079
            ot = dflag ? OT_LONG : OT_WORD;
4080
            val = insn_get(s, ot);
4081
            reg = (b & 7) | REX_B(s);
4082
            gen_op_movl_T0_im(val);
4083
            gen_op_mov_reg_T0[ot][reg]();
4084
        }
4085
        break;
4086

    
4087
    case 0x91 ... 0x97: /* xchg R, EAX */
4088
        ot = dflag + OT_WORD;
4089
        reg = (b & 7) | REX_B(s);
4090
        rm = R_EAX;
4091
        goto do_xchg_reg;
4092
    case 0x86:
4093
    case 0x87: /* xchg Ev, Gv */
4094
        if ((b & 1) == 0)
4095
            ot = OT_BYTE;
4096
        else
4097
            ot = dflag + OT_WORD;
4098
        modrm = ldub_code(s->pc++);
4099
        reg = ((modrm >> 3) & 7) | rex_r;
4100
        mod = (modrm >> 6) & 3;
4101
        if (mod == 3) {
4102
            rm = (modrm & 7) | REX_B(s);
4103
        do_xchg_reg:
4104
            gen_op_mov_TN_reg[ot][0][reg]();
4105
            gen_op_mov_TN_reg[ot][1][rm]();
4106
            gen_op_mov_reg_T0[ot][rm]();
4107
            gen_op_mov_reg_T1[ot][reg]();
4108
        } else {
4109
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4110
            gen_op_mov_TN_reg[ot][0][reg]();
4111
            /* for xchg, lock is implicit */
4112
            if (!(prefixes & PREFIX_LOCK))
4113
                gen_op_lock();
4114
            gen_op_ld_T1_A0[ot + s->mem_index]();
4115
            gen_op_st_T0_A0[ot + s->mem_index]();
4116
            if (!(prefixes & PREFIX_LOCK))
4117
                gen_op_unlock();
4118
            gen_op_mov_reg_T1[ot][reg]();
4119
        }
4120
        break;
4121
    case 0xc4: /* les Gv */
4122
        if (CODE64(s))
4123
            goto illegal_op;
4124
        op = R_ES;
4125
        goto do_lxx;
4126
    case 0xc5: /* lds Gv */
4127
        if (CODE64(s))
4128
            goto illegal_op;
4129
        op = R_DS;
4130
        goto do_lxx;
4131
    case 0x1b2: /* lss Gv */
4132
        op = R_SS;
4133
        goto do_lxx;
4134
    case 0x1b4: /* lfs Gv */
4135
        op = R_FS;
4136
        goto do_lxx;
4137
    case 0x1b5: /* lgs Gv */
4138
        op = R_GS;
4139
    do_lxx:
4140
        ot = dflag ? OT_LONG : OT_WORD;
4141
        modrm = ldub_code(s->pc++);
4142
        reg = ((modrm >> 3) & 7) | rex_r;
4143
        mod = (modrm >> 6) & 3;
4144
        if (mod == 3)
4145
            goto illegal_op;
4146
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4147
        gen_op_ld_T1_A0[ot + s->mem_index]();
4148
        gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4149
        /* load the segment first to handle exceptions properly */
4150
        gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
4151
        gen_movl_seg_T0(s, op, pc_start - s->cs_base);
4152
        /* then put the data */
4153
        gen_op_mov_reg_T1[ot][reg]();
4154
        if (s->is_jmp) {
4155
            gen_jmp_im(s->pc - s->cs_base);
4156
            gen_eob(s);
4157
        }
4158
        break;
4159
        
4160
        /************************/
4161
        /* shifts */
4162
    case 0xc0:
4163
    case 0xc1:
4164
        /* shift Ev,Ib */
4165
        shift = 2;
4166
    grp2:
4167
        {
4168
            if ((b & 1) == 0)
4169
                ot = OT_BYTE;
4170
            else
4171
                ot = dflag + OT_WORD;
4172
            
4173
            modrm = ldub_code(s->pc++);
4174
            mod = (modrm >> 6) & 3;
4175
            op = (modrm >> 3) & 7;
4176
            
4177
            if (mod != 3) {
4178
                if (shift == 2) {
4179
                    s->rip_offset = 1;
4180
                }
4181
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4182
                opreg = OR_TMP0;
4183
            } else {
4184
                opreg = (modrm & 7) | REX_B(s);
4185
            }
4186

    
4187
            /* simpler op */
4188
            if (shift == 0) {
4189
                gen_shift(s, op, ot, opreg, OR_ECX);
4190
            } else {
4191
                if (shift == 2) {
4192
                    shift = ldub_code(s->pc++);
4193
                }
4194
                gen_shifti(s, op, ot, opreg, shift);
4195
            }
4196
        }
4197
        break;
4198
    case 0xd0:
4199
    case 0xd1:
4200
        /* shift Ev,1 */
4201
        shift = 1;
4202
        goto grp2;
4203
    case 0xd2:
4204
    case 0xd3:
4205
        /* shift Ev,cl */
4206
        shift = 0;
4207
        goto grp2;
4208

    
4209
    case 0x1a4: /* shld imm */
4210
        op = 0;
4211
        shift = 1;
4212
        goto do_shiftd;
4213
    case 0x1a5: /* shld cl */
4214
        op = 0;
4215
        shift = 0;
4216
        goto do_shiftd;
4217
    case 0x1ac: /* shrd imm */
4218
        op = 1;
4219
        shift = 1;
4220
        goto do_shiftd;
4221
    case 0x1ad: /* shrd cl */
4222
        op = 1;
4223
        shift = 0;
4224
    do_shiftd:
4225
        ot = dflag + OT_WORD;
4226
        modrm = ldub_code(s->pc++);
4227
        mod = (modrm >> 6) & 3;
4228
        rm = (modrm & 7) | REX_B(s);
4229
        reg = ((modrm >> 3) & 7) | rex_r;
4230
        
4231
        if (mod != 3) {
4232
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4233
            gen_op_ld_T0_A0[ot + s->mem_index]();
4234
        } else {
4235
            gen_op_mov_TN_reg[ot][0][rm]();
4236
        }
4237
        gen_op_mov_TN_reg[ot][1][reg]();
4238
        
4239
        if (shift) {
4240
            val = ldub_code(s->pc++);
4241
            if (ot == OT_QUAD)
4242
                val &= 0x3f;
4243
            else
4244
                val &= 0x1f;
4245
            if (val) {
4246
                if (mod == 3)
4247
                    gen_op_shiftd_T0_T1_im_cc[ot][op](val);
4248
                else
4249
                    gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
4250
                if (op == 0 && ot != OT_WORD)
4251
                    s->cc_op = CC_OP_SHLB + ot;
4252
                else
4253
                    s->cc_op = CC_OP_SARB + ot;
4254
            }
4255
        } else {
4256
            if (s->cc_op != CC_OP_DYNAMIC)
4257
                gen_op_set_cc_op(s->cc_op);
4258
            if (mod == 3)
4259
                gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
4260
            else
4261
                gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
4262
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
4263
        }
4264
        if (mod == 3) {
4265
            gen_op_mov_reg_T0[ot][rm]();
4266
        }
4267
        break;
4268

    
4269
        /************************/
4270
        /* floats */
4271
    case 0xd8 ... 0xdf: 
4272
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4273
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4274
            /* XXX: what to do if illegal op ? */
4275
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4276
            break;
4277
        }
4278
        modrm = ldub_code(s->pc++);
4279
        mod = (modrm >> 6) & 3;
4280
        rm = modrm & 7;
4281
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4282
        if (mod != 3) {
4283
            /* memory op */
4284
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4285
            switch(op) {
4286
            case 0x00 ... 0x07: /* fxxxs */
4287
            case 0x10 ... 0x17: /* fixxxl */
4288
            case 0x20 ... 0x27: /* fxxxl */
4289
            case 0x30 ... 0x37: /* fixxx */
4290
                {
4291
                    int op1;
4292
                    op1 = op & 7;
4293

    
4294
                    switch(op >> 4) {
4295
                    case 0:
4296
                        gen_op_flds_FT0_A0();
4297
                        break;
4298
                    case 1:
4299
                        gen_op_fildl_FT0_A0();
4300
                        break;
4301
                    case 2:
4302
                        gen_op_fldl_FT0_A0();
4303
                        break;
4304
                    case 3:
4305
                    default:
4306
                        gen_op_fild_FT0_A0();
4307
                        break;
4308
                    }
4309
                    
4310
                    gen_op_fp_arith_ST0_FT0[op1]();
4311
                    if (op1 == 3) {
4312
                        /* fcomp needs pop */
4313
                        gen_op_fpop();
4314
                    }
4315
                }
4316
                break;
4317
            case 0x08: /* flds */
4318
            case 0x0a: /* fsts */
4319
            case 0x0b: /* fstps */
4320
            case 0x18 ... 0x1b: /* fildl, fisttpl, fistl, fistpl */
4321
            case 0x28 ... 0x2b: /* fldl, fisttpll, fstl, fstpl */
4322
            case 0x38 ... 0x3b: /* filds, fisttps, fists, fistps */
4323
                switch(op & 7) {
4324
                case 0:
4325
                    switch(op >> 4) {
4326
                    case 0:
4327
                        gen_op_flds_ST0_A0();
4328
                        break;
4329
                    case 1:
4330
                        gen_op_fildl_ST0_A0();
4331
                        break;
4332
                    case 2:
4333
                        gen_op_fldl_ST0_A0();
4334
                        break;
4335
                    case 3:
4336
                    default:
4337
                        gen_op_fild_ST0_A0();
4338
                        break;
4339
                    }
4340
                    break;
4341
                case 1:
4342
                    switch(op >> 4) {
4343
                    case 1:
4344
                        gen_op_fisttl_ST0_A0();
4345
                        break;
4346
                    case 2:
4347
                        gen_op_fisttll_ST0_A0();
4348
                        break;
4349
                    case 3:
4350
                    default:
4351
                        gen_op_fistt_ST0_A0();
4352
                    }
4353
                    gen_op_fpop();
4354
                    break;
4355
                default:
4356
                    switch(op >> 4) {
4357
                    case 0:
4358
                        gen_op_fsts_ST0_A0();
4359
                        break;
4360
                    case 1:
4361
                        gen_op_fistl_ST0_A0();
4362
                        break;
4363
                    case 2:
4364
                        gen_op_fstl_ST0_A0();
4365
                        break;
4366
                    case 3:
4367
                    default:
4368
                        gen_op_fist_ST0_A0();
4369
                        break;
4370
                    }
4371
                    if ((op & 7) == 3)
4372
                        gen_op_fpop();
4373
                    break;
4374
                }
4375
                break;
4376
            case 0x0c: /* fldenv mem */
4377
                gen_op_fldenv_A0(s->dflag);
4378
                break;
4379
            case 0x0d: /* fldcw mem */
4380
                gen_op_fldcw_A0();
4381
                break;
4382
            case 0x0e: /* fnstenv mem */
4383
                gen_op_fnstenv_A0(s->dflag);
4384
                break;
4385
            case 0x0f: /* fnstcw mem */
4386
                gen_op_fnstcw_A0();
4387
                break;
4388
            case 0x1d: /* fldt mem */
4389
                gen_op_fldt_ST0_A0();
4390
                break;
4391
            case 0x1f: /* fstpt mem */
4392
                gen_op_fstt_ST0_A0();
4393
                gen_op_fpop();
4394
                break;
4395
            case 0x2c: /* frstor mem */
4396
                gen_op_frstor_A0(s->dflag);
4397
                break;
4398
            case 0x2e: /* fnsave mem */
4399
                gen_op_fnsave_A0(s->dflag);
4400
                break;
4401
            case 0x2f: /* fnstsw mem */
4402
                gen_op_fnstsw_A0();
4403
                break;
4404
            case 0x3c: /* fbld */
4405
                gen_op_fbld_ST0_A0();
4406
                break;
4407
            case 0x3e: /* fbstp */
4408
                gen_op_fbst_ST0_A0();
4409
                gen_op_fpop();
4410
                break;
4411
            case 0x3d: /* fildll */
4412
                gen_op_fildll_ST0_A0();
4413
                break;
4414
            case 0x3f: /* fistpll */
4415
                gen_op_fistll_ST0_A0();
4416
                gen_op_fpop();
4417
                break;
4418
            default:
4419
                goto illegal_op;
4420
            }
4421
        } else {
4422
            /* register float ops */
4423
            opreg = rm;
4424

    
4425
            switch(op) {
4426
            case 0x08: /* fld sti */
4427
                gen_op_fpush();
4428
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
4429
                break;
4430
            case 0x09: /* fxchg sti */
4431
            case 0x29: /* fxchg4 sti, undocumented op */
4432
            case 0x39: /* fxchg7 sti, undocumented op */
4433
                gen_op_fxchg_ST0_STN(opreg);
4434
                break;
4435
            case 0x0a: /* grp d9/2 */
4436
                switch(rm) {
4437
                case 0: /* fnop */
4438
                    /* check exceptions (FreeBSD FPU probe) */
4439
                    if (s->cc_op != CC_OP_DYNAMIC)
4440
                        gen_op_set_cc_op(s->cc_op);
4441
                    gen_jmp_im(pc_start - s->cs_base);
4442
                    gen_op_fwait();
4443
                    break;
4444
                default:
4445
                    goto illegal_op;
4446
                }
4447
                break;
4448
            case 0x0c: /* grp d9/4 */
4449
                switch(rm) {
4450
                case 0: /* fchs */
4451
                    gen_op_fchs_ST0();
4452
                    break;
4453
                case 1: /* fabs */
4454
                    gen_op_fabs_ST0();
4455
                    break;
4456
                case 4: /* ftst */
4457
                    gen_op_fldz_FT0();
4458
                    gen_op_fcom_ST0_FT0();
4459
                    break;
4460
                case 5: /* fxam */
4461
                    gen_op_fxam_ST0();
4462
                    break;
4463
                default:
4464
                    goto illegal_op;
4465
                }
4466
                break;
4467
            case 0x0d: /* grp d9/5 */
4468
                {
4469
                    switch(rm) {
4470
                    case 0:
4471
                        gen_op_fpush();
4472
                        gen_op_fld1_ST0();
4473
                        break;
4474
                    case 1:
4475
                        gen_op_fpush();
4476
                        gen_op_fldl2t_ST0();
4477
                        break;
4478
                    case 2:
4479
                        gen_op_fpush();
4480
                        gen_op_fldl2e_ST0();
4481
                        break;
4482
                    case 3:
4483
                        gen_op_fpush();
4484
                        gen_op_fldpi_ST0();
4485
                        break;
4486
                    case 4:
4487
                        gen_op_fpush();
4488
                        gen_op_fldlg2_ST0();
4489
                        break;
4490
                    case 5:
4491
                        gen_op_fpush();
4492
                        gen_op_fldln2_ST0();
4493
                        break;
4494
                    case 6:
4495
                        gen_op_fpush();
4496
                        gen_op_fldz_ST0();
4497
                        break;
4498
                    default:
4499
                        goto illegal_op;
4500
                    }
4501
                }
4502
                break;
4503
            case 0x0e: /* grp d9/6 */
4504
                switch(rm) {
4505
                case 0: /* f2xm1 */
4506
                    gen_op_f2xm1();
4507
                    break;
4508
                case 1: /* fyl2x */
4509
                    gen_op_fyl2x();
4510
                    break;
4511
                case 2: /* fptan */
4512
                    gen_op_fptan();
4513
                    break;
4514
                case 3: /* fpatan */
4515
                    gen_op_fpatan();
4516
                    break;
4517
                case 4: /* fxtract */
4518
                    gen_op_fxtract();
4519
                    break;
4520
                case 5: /* fprem1 */
4521
                    gen_op_fprem1();
4522
                    break;
4523
                case 6: /* fdecstp */
4524
                    gen_op_fdecstp();
4525
                    break;
4526
                default:
4527
                case 7: /* fincstp */
4528
                    gen_op_fincstp();
4529
                    break;
4530
                }
4531
                break;
4532
            case 0x0f: /* grp d9/7 */
4533
                switch(rm) {
4534
                case 0: /* fprem */
4535
                    gen_op_fprem();
4536
                    break;
4537
                case 1: /* fyl2xp1 */
4538
                    gen_op_fyl2xp1();
4539
                    break;
4540
                case 2: /* fsqrt */
4541
                    gen_op_fsqrt();
4542
                    break;
4543
                case 3: /* fsincos */
4544
                    gen_op_fsincos();
4545
                    break;
4546
                case 5: /* fscale */
4547
                    gen_op_fscale();
4548
                    break;
4549
                case 4: /* frndint */
4550
                    gen_op_frndint();
4551
                    break;
4552
                case 6: /* fsin */
4553
                    gen_op_fsin();
4554
                    break;
4555
                default:
4556
                case 7: /* fcos */
4557
                    gen_op_fcos();
4558
                    break;
4559
                }
4560
                break;
4561
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
4562
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
4563
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
4564
                {
4565
                    int op1;
4566
                    
4567
                    op1 = op & 7;
4568
                    if (op >= 0x20) {
4569
                        gen_op_fp_arith_STN_ST0[op1](opreg);
4570
                        if (op >= 0x30)
4571
                            gen_op_fpop();
4572
                    } else {
4573
                        gen_op_fmov_FT0_STN(opreg);
4574
                        gen_op_fp_arith_ST0_FT0[op1]();
4575
                    }
4576
                }
4577
                break;
4578
            case 0x02: /* fcom */
4579
            case 0x22: /* fcom2, undocumented op */
4580
                gen_op_fmov_FT0_STN(opreg);
4581
                gen_op_fcom_ST0_FT0();
4582
                break;
4583
            case 0x03: /* fcomp */
4584
            case 0x23: /* fcomp3, undocumented op */
4585
            case 0x32: /* fcomp5, undocumented op */
4586
                gen_op_fmov_FT0_STN(opreg);
4587
                gen_op_fcom_ST0_FT0();
4588
                gen_op_fpop();
4589
                break;
4590
            case 0x15: /* da/5 */
4591
                switch(rm) {
4592
                case 1: /* fucompp */
4593
                    gen_op_fmov_FT0_STN(1);
4594
                    gen_op_fucom_ST0_FT0();
4595
                    gen_op_fpop();
4596
                    gen_op_fpop();
4597
                    break;
4598
                default:
4599
                    goto illegal_op;
4600
                }
4601
                break;
4602
            case 0x1c:
4603
                switch(rm) {
4604
                case 0: /* feni (287 only, just do nop here) */
4605
                    break;
4606
                case 1: /* fdisi (287 only, just do nop here) */
4607
                    break;
4608
                case 2: /* fclex */
4609
                    gen_op_fclex();
4610
                    break;
4611
                case 3: /* fninit */
4612
                    gen_op_fninit();
4613
                    break;
4614
                case 4: /* fsetpm (287 only, just do nop here) */
4615
                    break;
4616
                default:
4617
                    goto illegal_op;
4618
                }
4619
                break;
4620
            case 0x1d: /* fucomi */
4621
                if (s->cc_op != CC_OP_DYNAMIC)
4622
                    gen_op_set_cc_op(s->cc_op);
4623
                gen_op_fmov_FT0_STN(opreg);
4624
                gen_op_fucomi_ST0_FT0();
4625
                s->cc_op = CC_OP_EFLAGS;
4626
                break;
4627
            case 0x1e: /* fcomi */
4628
                if (s->cc_op != CC_OP_DYNAMIC)
4629
                    gen_op_set_cc_op(s->cc_op);
4630
                gen_op_fmov_FT0_STN(opreg);
4631
                gen_op_fcomi_ST0_FT0();
4632
                s->cc_op = CC_OP_EFLAGS;
4633
                break;
4634
            case 0x28: /* ffree sti */
4635
                gen_op_ffree_STN(opreg);
4636
                break; 
4637
            case 0x2a: /* fst sti */
4638
                gen_op_fmov_STN_ST0(opreg);
4639
                break;
4640
            case 0x2b: /* fstp sti */
4641
            case 0x0b: /* fstp1 sti, undocumented op */
4642
            case 0x3a: /* fstp8 sti, undocumented op */
4643
            case 0x3b: /* fstp9 sti, undocumented op */
4644
                gen_op_fmov_STN_ST0(opreg);
4645
                gen_op_fpop();
4646
                break;
4647
            case 0x2c: /* fucom st(i) */
4648
                gen_op_fmov_FT0_STN(opreg);
4649
                gen_op_fucom_ST0_FT0();
4650
                break;
4651
            case 0x2d: /* fucomp st(i) */
4652
                gen_op_fmov_FT0_STN(opreg);
4653
                gen_op_fucom_ST0_FT0();
4654
                gen_op_fpop();
4655
                break;
4656
            case 0x33: /* de/3 */
4657
                switch(rm) {
4658
                case 1: /* fcompp */
4659
                    gen_op_fmov_FT0_STN(1);
4660
                    gen_op_fcom_ST0_FT0();
4661
                    gen_op_fpop();
4662
                    gen_op_fpop();
4663
                    break;
4664
                default:
4665
                    goto illegal_op;
4666
                }
4667
                break;
4668
            case 0x38: /* ffreep sti, undocumented op */
4669
                gen_op_ffree_STN(opreg);
4670
                gen_op_fpop();
4671
                break;
4672
            case 0x3c: /* df/4 */
4673
                switch(rm) {
4674
                case 0:
4675
                    gen_op_fnstsw_EAX();
4676
                    break;
4677
                default:
4678
                    goto illegal_op;
4679
                }
4680
                break;
4681
            case 0x3d: /* fucomip */
4682
                if (s->cc_op != CC_OP_DYNAMIC)
4683
                    gen_op_set_cc_op(s->cc_op);
4684
                gen_op_fmov_FT0_STN(opreg);
4685
                gen_op_fucomi_ST0_FT0();
4686
                gen_op_fpop();
4687
                s->cc_op = CC_OP_EFLAGS;
4688
                break;
4689
            case 0x3e: /* fcomip */
4690
                if (s->cc_op != CC_OP_DYNAMIC)
4691
                    gen_op_set_cc_op(s->cc_op);
4692
                gen_op_fmov_FT0_STN(opreg);
4693
                gen_op_fcomi_ST0_FT0();
4694
                gen_op_fpop();
4695
                s->cc_op = CC_OP_EFLAGS;
4696
                break;
4697
            case 0x10 ... 0x13: /* fcmovxx */
4698
            case 0x18 ... 0x1b:
4699
                {
4700
                    int op1;
4701
                    const static uint8_t fcmov_cc[8] = {
4702
                        (JCC_B << 1),
4703
                        (JCC_Z << 1),
4704
                        (JCC_BE << 1),
4705
                        (JCC_P << 1),
4706
                    };
4707
                    op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
4708
                    gen_setcc(s, op1);
4709
                    gen_op_fcmov_ST0_STN_T0(opreg);
4710
                }
4711
                break;
4712
            default:
4713
                goto illegal_op;
4714
            }
4715
        }
4716
#ifdef USE_CODE_COPY
4717
        s->tb->cflags |= CF_TB_FP_USED;
4718
#endif
4719
        break;
4720
        /************************/
4721
        /* string ops */
4722

    
4723
    case 0xa4: /* movsS */
4724
    case 0xa5:
4725
        if ((b & 1) == 0)
4726
            ot = OT_BYTE;
4727
        else
4728
            ot = dflag + OT_WORD;
4729

    
4730
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4731
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4732
        } else {
4733
            gen_movs(s, ot);
4734
        }
4735
        break;
4736
        
4737
    case 0xaa: /* stosS */
4738
    case 0xab:
4739
        if ((b & 1) == 0)
4740
            ot = OT_BYTE;
4741
        else
4742
            ot = dflag + OT_WORD;
4743

    
4744
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4745
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4746
        } else {
4747
            gen_stos(s, ot);
4748
        }
4749
        break;
4750
    case 0xac: /* lodsS */
4751
    case 0xad:
4752
        if ((b & 1) == 0)
4753
            ot = OT_BYTE;
4754
        else
4755
            ot = dflag + OT_WORD;
4756
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4757
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4758
        } else {
4759
            gen_lods(s, ot);
4760
        }
4761
        break;
4762
    case 0xae: /* scasS */
4763
    case 0xaf:
4764
        if ((b & 1) == 0)
4765
            ot = OT_BYTE;
4766
        else
4767
            ot = dflag + OT_WORD;
4768
        if (prefixes & PREFIX_REPNZ) {
4769
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4770
        } else if (prefixes & PREFIX_REPZ) {
4771
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4772
        } else {
4773
            gen_scas(s, ot);
4774
            s->cc_op = CC_OP_SUBB + ot;
4775
        }
4776
        break;
4777

    
4778
    case 0xa6: /* cmpsS */
4779
    case 0xa7:
4780
        if ((b & 1) == 0)
4781
            ot = OT_BYTE;
4782
        else
4783
            ot = dflag + OT_WORD;
4784
        if (prefixes & PREFIX_REPNZ) {
4785
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4786
        } else if (prefixes & PREFIX_REPZ) {
4787
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4788
        } else {
4789
            gen_cmps(s, ot);
4790
            s->cc_op = CC_OP_SUBB + ot;
4791
        }
4792
        break;
4793
    case 0x6c: /* insS */
4794
    case 0x6d:
4795
        if ((b & 1) == 0)
4796
            ot = OT_BYTE;
4797
        else
4798
            ot = dflag ? OT_LONG : OT_WORD;
4799
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4800
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4801
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4802
        } else {
4803
            gen_ins(s, ot);
4804
        }
4805
        break;
4806
    case 0x6e: /* outsS */
4807
    case 0x6f:
4808
        if ((b & 1) == 0)
4809
            ot = OT_BYTE;
4810
        else
4811
            ot = dflag ? OT_LONG : OT_WORD;
4812
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4813
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4814
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4815
        } else {
4816
            gen_outs(s, ot);
4817
        }
4818
        break;
4819

    
4820
        /************************/
4821
        /* port I/O */
4822
    case 0xe4:
4823
    case 0xe5:
4824
        if ((b & 1) == 0)
4825
            ot = OT_BYTE;
4826
        else
4827
            ot = dflag ? OT_LONG : OT_WORD;
4828
        val = ldub_code(s->pc++);
4829
        gen_op_movl_T0_im(val);
4830
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4831
        gen_op_in[ot]();
4832
        gen_op_mov_reg_T1[ot][R_EAX]();
4833
        break;
4834
    case 0xe6:
4835
    case 0xe7:
4836
        if ((b & 1) == 0)
4837
            ot = OT_BYTE;
4838
        else
4839
            ot = dflag ? OT_LONG : OT_WORD;
4840
        val = ldub_code(s->pc++);
4841
        gen_op_movl_T0_im(val);
4842
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4843
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4844
        gen_op_out[ot]();
4845
        break;
4846
    case 0xec:
4847
    case 0xed:
4848
        if ((b & 1) == 0)
4849
            ot = OT_BYTE;
4850
        else
4851
            ot = dflag ? OT_LONG : OT_WORD;
4852
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4853
        gen_op_andl_T0_ffff();
4854
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4855
        gen_op_in[ot]();
4856
        gen_op_mov_reg_T1[ot][R_EAX]();
4857
        break;
4858
    case 0xee:
4859
    case 0xef:
4860
        if ((b & 1) == 0)
4861
            ot = OT_BYTE;
4862
        else
4863
            ot = dflag ? OT_LONG : OT_WORD;
4864
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4865
        gen_op_andl_T0_ffff();
4866
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4867
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4868
        gen_op_out[ot]();
4869
        break;
4870

    
4871
        /************************/
4872
        /* control */
4873
    case 0xc2: /* ret im */
4874
        val = ldsw_code(s->pc);
4875
        s->pc += 2;
4876
        gen_pop_T0(s);
4877
        if (CODE64(s) && s->dflag)
4878
            s->dflag = 2;
4879
        gen_stack_update(s, val + (2 << s->dflag));
4880
        if (s->dflag == 0)
4881
            gen_op_andl_T0_ffff();
4882
        gen_op_jmp_T0();
4883
        gen_eob(s);
4884
        break;
4885
    case 0xc3: /* ret */
4886
        gen_pop_T0(s);
4887
        gen_pop_update(s);
4888
        if (s->dflag == 0)
4889
            gen_op_andl_T0_ffff();
4890
        gen_op_jmp_T0();
4891
        gen_eob(s);
4892
        break;
4893
    case 0xca: /* lret im */
4894
        val = ldsw_code(s->pc);
4895
        s->pc += 2;
4896
    do_lret:
4897
        if (s->pe && !s->vm86) {
4898
            if (s->cc_op != CC_OP_DYNAMIC)
4899
                gen_op_set_cc_op(s->cc_op);
4900
            gen_jmp_im(pc_start - s->cs_base);
4901
            gen_op_lret_protected(s->dflag, val);
4902
        } else {
4903
            gen_stack_A0(s);
4904
            /* pop offset */
4905
            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
4906
            if (s->dflag == 0)
4907
                gen_op_andl_T0_ffff();
4908
            /* NOTE: keeping EIP updated is not a problem in case of
4909
               exception */
4910
            gen_op_jmp_T0();
4911
            /* pop selector */
4912
            gen_op_addl_A0_im(2 << s->dflag);
4913
            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
4914
            gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
4915
            /* add stack offset */
4916
            gen_stack_update(s, val + (4 << s->dflag));
4917
        }
4918
        gen_eob(s);
4919
        break;
4920
    case 0xcb: /* lret */
4921
        val = 0;
4922
        goto do_lret;
4923
    case 0xcf: /* iret */
4924
        if (!s->pe) {
4925
            /* real mode */
4926
            gen_op_iret_real(s->dflag);
4927
            s->cc_op = CC_OP_EFLAGS;
4928
        } else if (s->vm86) {
4929
            if (s->iopl != 3) {
4930
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4931
            } else {
4932
                gen_op_iret_real(s->dflag);
4933
                s->cc_op = CC_OP_EFLAGS;
4934
            }
4935
        } else {
4936
            if (s->cc_op != CC_OP_DYNAMIC)
4937
                gen_op_set_cc_op(s->cc_op);
4938
            gen_jmp_im(pc_start - s->cs_base);
4939
            gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
4940
            s->cc_op = CC_OP_EFLAGS;
4941
        }
4942
        gen_eob(s);
4943
        break;
4944
    case 0xe8: /* call im */
4945
        {
4946
            if (dflag)
4947
                tval = (int32_t)insn_get(s, OT_LONG);
4948
            else
4949
                tval = (int16_t)insn_get(s, OT_WORD);
4950
            next_eip = s->pc - s->cs_base;
4951
            tval += next_eip;
4952
            if (s->dflag == 0)
4953
                tval &= 0xffff;
4954
            gen_movtl_T0_im(next_eip);
4955
            gen_push_T0(s);
4956
            gen_jmp(s, tval);
4957
        }
4958
        break;
4959
    case 0x9a: /* lcall im */
4960
        {
4961
            unsigned int selector, offset;
4962
            
4963
            if (CODE64(s))
4964
                goto illegal_op;
4965
            ot = dflag ? OT_LONG : OT_WORD;
4966
            offset = insn_get(s, ot);
4967
            selector = insn_get(s, OT_WORD);
4968
            
4969
            gen_op_movl_T0_im(selector);
4970
            gen_op_movl_T1_imu(offset);
4971
        }
4972
        goto do_lcall;
4973
    case 0xe9: /* jmp im */
4974
        if (dflag)
4975
            tval = (int32_t)insn_get(s, OT_LONG);
4976
        else
4977
            tval = (int16_t)insn_get(s, OT_WORD);
4978
        tval += s->pc - s->cs_base;
4979
        if (s->dflag == 0)
4980
            tval &= 0xffff;
4981
        gen_jmp(s, tval);
4982
        break;
4983
    case 0xea: /* ljmp im */
4984
        {
4985
            unsigned int selector, offset;
4986

    
4987
            if (CODE64(s))
4988
                goto illegal_op;
4989
            ot = dflag ? OT_LONG : OT_WORD;
4990
            offset = insn_get(s, ot);
4991
            selector = insn_get(s, OT_WORD);
4992
            
4993
            gen_op_movl_T0_im(selector);
4994
            gen_op_movl_T1_imu(offset);
4995
        }
4996
        goto do_ljmp;
4997
    case 0xeb: /* jmp Jb */
4998
        tval = (int8_t)insn_get(s, OT_BYTE);
4999
        tval += s->pc - s->cs_base;
5000
        if (s->dflag == 0)
5001
            tval &= 0xffff;
5002
        gen_jmp(s, tval);
5003
        break;
5004
    case 0x70 ... 0x7f: /* jcc Jb */
5005
        tval = (int8_t)insn_get(s, OT_BYTE);
5006
        goto do_jcc;
5007
    case 0x180 ... 0x18f: /* jcc Jv */
5008
        if (dflag) {
5009
            tval = (int32_t)insn_get(s, OT_LONG);
5010
        } else {
5011
            tval = (int16_t)insn_get(s, OT_WORD); 
5012
        }
5013
    do_jcc:
5014
        next_eip = s->pc - s->cs_base;
5015
        tval += next_eip;
5016
        if (s->dflag == 0)
5017
            tval &= 0xffff;
5018
        gen_jcc(s, b, tval, next_eip);
5019
        break;
5020

    
5021
    case 0x190 ... 0x19f: /* setcc Gv */
5022
        modrm = ldub_code(s->pc++);
5023
        gen_setcc(s, b);
5024
        gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1);
5025
        break;
5026
    case 0x140 ... 0x14f: /* cmov Gv, Ev */
5027
        ot = dflag + OT_WORD;
5028
        modrm = ldub_code(s->pc++);
5029
        reg = ((modrm >> 3) & 7) | rex_r;
5030
        mod = (modrm >> 6) & 3;
5031
        gen_setcc(s, b);
5032
        if (mod != 3) {
5033
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5034
            gen_op_ld_T1_A0[ot + s->mem_index]();
5035
        } else {
5036
            rm = (modrm & 7) | REX_B(s);
5037
            gen_op_mov_TN_reg[ot][1][rm]();
5038
        }
5039
        gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
5040
        break;
5041
        
5042
        /************************/
5043
        /* flags */
5044
    case 0x9c: /* pushf */
5045
        if (s->vm86 && s->iopl != 3) {
5046
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5047
        } else {
5048
            if (s->cc_op != CC_OP_DYNAMIC)
5049
                gen_op_set_cc_op(s->cc_op);
5050
            gen_op_movl_T0_eflags();
5051
            gen_push_T0(s);
5052
        }
5053
        break;
5054
    case 0x9d: /* popf */
5055
        if (s->vm86 && s->iopl != 3) {
5056
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5057
        } else {
5058
            gen_pop_T0(s);
5059
            if (s->cpl == 0) {
5060
                if (s->dflag) {
5061
                    gen_op_movl_eflags_T0_cpl0();
5062
                } else {
5063
                    gen_op_movw_eflags_T0_cpl0();
5064
                }
5065
            } else {
5066
                if (s->cpl <= s->iopl) {
5067
                    if (s->dflag) {
5068
                        gen_op_movl_eflags_T0_io();
5069
                    } else {
5070
                        gen_op_movw_eflags_T0_io();
5071
                    }
5072
                } else {
5073
                    if (s->dflag) {
5074
                        gen_op_movl_eflags_T0();
5075
                    } else {
5076
                        gen_op_movw_eflags_T0();
5077
                    }
5078
                }
5079
            }
5080
            gen_pop_update(s);
5081
            s->cc_op = CC_OP_EFLAGS;
5082
            /* abort translation because TF flag may change */
5083
            gen_jmp_im(s->pc - s->cs_base);
5084
            gen_eob(s);
5085
        }
5086
        break;
5087
    case 0x9e: /* sahf */
5088
        if (CODE64(s))
5089
            goto illegal_op;
5090
        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
5091
        if (s->cc_op != CC_OP_DYNAMIC)
5092
            gen_op_set_cc_op(s->cc_op);
5093
        gen_op_movb_eflags_T0();
5094
        s->cc_op = CC_OP_EFLAGS;
5095
        break;
5096
    case 0x9f: /* lahf */
5097
        if (CODE64(s))
5098
            goto illegal_op;
5099
        if (s->cc_op != CC_OP_DYNAMIC)
5100
            gen_op_set_cc_op(s->cc_op);
5101
        gen_op_movl_T0_eflags();
5102
        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
5103
        break;
5104
    case 0xf5: /* cmc */
5105
        if (s->cc_op != CC_OP_DYNAMIC)
5106
            gen_op_set_cc_op(s->cc_op);
5107
        gen_op_cmc();
5108
        s->cc_op = CC_OP_EFLAGS;
5109
        break;
5110
    case 0xf8: /* clc */
5111
        if (s->cc_op != CC_OP_DYNAMIC)
5112
            gen_op_set_cc_op(s->cc_op);
5113
        gen_op_clc();
5114
        s->cc_op = CC_OP_EFLAGS;
5115
        break;
5116
    case 0xf9: /* stc */
5117
        if (s->cc_op != CC_OP_DYNAMIC)
5118
            gen_op_set_cc_op(s->cc_op);
5119
        gen_op_stc();
5120
        s->cc_op = CC_OP_EFLAGS;
5121
        break;
5122
    case 0xfc: /* cld */
5123
        gen_op_cld();
5124
        break;
5125
    case 0xfd: /* std */
5126
        gen_op_std();
5127
        break;
5128

    
5129
        /************************/
5130
        /* bit operations */
5131
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
5132
        ot = dflag + OT_WORD;
5133
        modrm = ldub_code(s->pc++);
5134
        op = (modrm >> 3) & 7;
5135
        mod = (modrm >> 6) & 3;
5136
        rm = (modrm & 7) | REX_B(s);
5137
        if (mod != 3) {
5138
            s->rip_offset = 1;
5139
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5140
            gen_op_ld_T0_A0[ot + s->mem_index]();
5141
        } else {
5142
            gen_op_mov_TN_reg[ot][0][rm]();
5143
        }
5144
        /* load shift */
5145
        val = ldub_code(s->pc++);
5146
        gen_op_movl_T1_im(val);
5147
        if (op < 4)
5148
            goto illegal_op;
5149
        op -= 4;
5150
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5151
        s->cc_op = CC_OP_SARB + ot;
5152
        if (op != 0) {
5153
            if (mod != 3)
5154
                gen_op_st_T0_A0[ot + s->mem_index]();
5155
            else
5156
                gen_op_mov_reg_T0[ot][rm]();
5157
            gen_op_update_bt_cc();
5158
        }
5159
        break;
5160
    case 0x1a3: /* bt Gv, Ev */
5161
        op = 0;
5162
        goto do_btx;
5163
    case 0x1ab: /* bts */
5164
        op = 1;
5165
        goto do_btx;
5166
    case 0x1b3: /* btr */
5167
        op = 2;
5168
        goto do_btx;
5169
    case 0x1bb: /* btc */
5170
        op = 3;
5171
    do_btx:
5172
        ot = dflag + OT_WORD;
5173
        modrm = ldub_code(s->pc++);
5174
        reg = ((modrm >> 3) & 7) | rex_r;
5175
        mod = (modrm >> 6) & 3;
5176
        rm = (modrm & 7) | REX_B(s);
5177
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
5178
        if (mod != 3) {
5179
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5180
            /* specific case: we need to add a displacement */
5181
            gen_op_add_bit_A0_T1[ot - OT_WORD]();
5182
            gen_op_ld_T0_A0[ot + s->mem_index]();
5183
        } else {
5184
            gen_op_mov_TN_reg[ot][0][rm]();
5185
        }
5186
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5187
        s->cc_op = CC_OP_SARB + ot;
5188
        if (op != 0) {
5189
            if (mod != 3)
5190
                gen_op_st_T0_A0[ot + s->mem_index]();
5191
            else
5192
                gen_op_mov_reg_T0[ot][rm]();
5193
            gen_op_update_bt_cc();
5194
        }
5195
        break;
5196
    case 0x1bc: /* bsf */
5197
    case 0x1bd: /* bsr */
5198
        ot = dflag + OT_WORD;
5199
        modrm = ldub_code(s->pc++);
5200
        reg = ((modrm >> 3) & 7) | rex_r;
5201
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5202
        /* NOTE: in order to handle the 0 case, we must load the
5203
           result. It could be optimized with a generated jump */
5204
        gen_op_mov_TN_reg[ot][1][reg]();
5205
        gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
5206
        gen_op_mov_reg_T1[ot][reg]();
5207
        s->cc_op = CC_OP_LOGICB + ot;
5208
        break;
5209
        /************************/
5210
        /* bcd */
5211
    case 0x27: /* daa */
5212
        if (CODE64(s))
5213
            goto illegal_op;
5214
        if (s->cc_op != CC_OP_DYNAMIC)
5215
            gen_op_set_cc_op(s->cc_op);
5216
        gen_op_daa();
5217
        s->cc_op = CC_OP_EFLAGS;
5218
        break;
5219
    case 0x2f: /* das */
5220
        if (CODE64(s))
5221
            goto illegal_op;
5222
        if (s->cc_op != CC_OP_DYNAMIC)
5223
            gen_op_set_cc_op(s->cc_op);
5224
        gen_op_das();
5225
        s->cc_op = CC_OP_EFLAGS;
5226
        break;
5227
    case 0x37: /* aaa */
5228
        if (CODE64(s))
5229
            goto illegal_op;
5230
        if (s->cc_op != CC_OP_DYNAMIC)
5231
            gen_op_set_cc_op(s->cc_op);
5232
        gen_op_aaa();
5233
        s->cc_op = CC_OP_EFLAGS;
5234
        break;
5235
    case 0x3f: /* aas */
5236
        if (CODE64(s))
5237
            goto illegal_op;
5238
        if (s->cc_op != CC_OP_DYNAMIC)
5239
            gen_op_set_cc_op(s->cc_op);
5240
        gen_op_aas();
5241
        s->cc_op = CC_OP_EFLAGS;
5242
        break;
5243
    case 0xd4: /* aam */
5244
        if (CODE64(s))
5245
            goto illegal_op;
5246
        val = ldub_code(s->pc++);
5247
        gen_op_aam(val);
5248
        s->cc_op = CC_OP_LOGICB;
5249
        break;
5250
    case 0xd5: /* aad */
5251
        if (CODE64(s))
5252
            goto illegal_op;
5253
        val = ldub_code(s->pc++);
5254
        gen_op_aad(val);
5255
        s->cc_op = CC_OP_LOGICB;
5256
        break;
5257
        /************************/
5258
        /* misc */
5259
    case 0x90: /* nop */
5260
        /* XXX: xchg + rex handling */
5261
        /* XXX: correct lock test for all insn */
5262
        if (prefixes & PREFIX_LOCK)
5263
            goto illegal_op;
5264
        break;
5265
    case 0x9b: /* fwait */
5266
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 
5267
            (HF_MP_MASK | HF_TS_MASK)) {
5268
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5269
        } else {
5270
            if (s->cc_op != CC_OP_DYNAMIC)
5271
                gen_op_set_cc_op(s->cc_op);
5272
            gen_jmp_im(pc_start - s->cs_base);
5273
            gen_op_fwait();
5274
        }
5275
        break;
5276
    case 0xcc: /* int3 */
5277
        gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
5278
        break;
5279
    case 0xcd: /* int N */
5280
        val = ldub_code(s->pc++);
5281
        if (s->vm86 && s->iopl != 3) {
5282
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 
5283
        } else {
5284
            gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
5285
        }
5286
        break;
5287
    case 0xce: /* into */
5288
        if (CODE64(s))
5289
            goto illegal_op;
5290
        if (s->cc_op != CC_OP_DYNAMIC)
5291
            gen_op_set_cc_op(s->cc_op);
5292
        gen_jmp_im(pc_start - s->cs_base);
5293
        gen_op_into(s->pc - pc_start);
5294
        break;
5295
    case 0xf1: /* icebp (undocumented, exits to external debugger) */
5296
#if 1
5297
        gen_debug(s, pc_start - s->cs_base);
5298
#else
5299
        /* start debug */
5300
        tb_flush(cpu_single_env);
5301
        cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM);
5302
#endif
5303
        break;
5304
    case 0xfa: /* cli */
5305
        if (!s->vm86) {
5306
            if (s->cpl <= s->iopl) {
5307
                gen_op_cli();
5308
            } else {
5309
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5310
            }
5311
        } else {
5312
            if (s->iopl == 3) {
5313
                gen_op_cli();
5314
            } else {
5315
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5316
            }
5317
        }
5318
        break;
5319
    case 0xfb: /* sti */
5320
        if (!s->vm86) {
5321
            if (s->cpl <= s->iopl) {
5322
            gen_sti:
5323
                gen_op_sti();
5324
                /* interruptions are enabled only the first insn after sti */
5325
                /* If several instructions disable interrupts, only the
5326
                   _first_ does it */
5327
                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
5328
                    gen_op_set_inhibit_irq();
5329
                /* give a chance to handle pending irqs */
5330
                gen_jmp_im(s->pc - s->cs_base);
5331
                gen_eob(s);
5332
            } else {
5333
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5334
            }
5335
        } else {
5336
            if (s->iopl == 3) {
5337
                goto gen_sti;
5338
            } else {
5339
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5340
            }
5341
        }
5342
        break;
5343
    case 0x62: /* bound */
5344
        if (CODE64(s))
5345
            goto illegal_op;
5346
        ot = dflag ? OT_LONG : OT_WORD;
5347
        modrm = ldub_code(s->pc++);
5348
        reg = (modrm >> 3) & 7;
5349
        mod = (modrm >> 6) & 3;
5350
        if (mod == 3)
5351
            goto illegal_op;
5352
        gen_op_mov_TN_reg[ot][0][reg]();
5353
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5354
        gen_jmp_im(pc_start - s->cs_base);
5355
        if (ot == OT_WORD)
5356
            gen_op_boundw();
5357
        else
5358
            gen_op_boundl();
5359
        break;
5360
    case 0x1c8 ... 0x1cf: /* bswap reg */
5361
        reg = (b & 7) | REX_B(s);
5362
#ifdef TARGET_X86_64
5363
        if (dflag == 2) {
5364
            gen_op_mov_TN_reg[OT_QUAD][0][reg]();
5365
            gen_op_bswapq_T0();
5366
            gen_op_mov_reg_T0[OT_QUAD][reg]();
5367
        } else 
5368
#endif
5369
        {
5370
            gen_op_mov_TN_reg[OT_LONG][0][reg]();
5371
            gen_op_bswapl_T0();
5372
            gen_op_mov_reg_T0[OT_LONG][reg]();
5373
        }
5374
        break;
5375
    case 0xd6: /* salc */
5376
        if (CODE64(s))
5377
            goto illegal_op;
5378
        if (s->cc_op != CC_OP_DYNAMIC)
5379
            gen_op_set_cc_op(s->cc_op);
5380
        gen_op_salc();
5381
        break;
5382
    case 0xe0: /* loopnz */
5383
    case 0xe1: /* loopz */
5384
        if (s->cc_op != CC_OP_DYNAMIC)
5385
            gen_op_set_cc_op(s->cc_op);
5386
        /* FALL THRU */
5387
    case 0xe2: /* loop */
5388
    case 0xe3: /* jecxz */
5389
        {
5390
            int l1, l2;
5391

    
5392
            tval = (int8_t)insn_get(s, OT_BYTE);
5393
            next_eip = s->pc - s->cs_base;
5394
            tval += next_eip;
5395
            if (s->dflag == 0)
5396
                tval &= 0xffff;
5397
            
5398
            l1 = gen_new_label();
5399
            l2 = gen_new_label();
5400
            b &= 3;
5401
            if (b == 3) {
5402
                gen_op_jz_ecx[s->aflag](l1);
5403
            } else {
5404
                gen_op_dec_ECX[s->aflag]();
5405
                if (b <= 1)
5406
                    gen_op_mov_T0_cc();
5407
                gen_op_loop[s->aflag][b](l1);
5408
            }
5409

    
5410
            gen_jmp_im(next_eip);
5411
            gen_op_jmp_label(l2);
5412
            gen_set_label(l1);
5413
            gen_jmp_im(tval);
5414
            gen_set_label(l2);
5415
            gen_eob(s);
5416
        }
5417
        break;
5418
    case 0x130: /* wrmsr */
5419
    case 0x132: /* rdmsr */
5420
        if (s->cpl != 0) {
5421
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5422
        } else {
5423
            if (b & 2)
5424
                gen_op_rdmsr();
5425
            else
5426
                gen_op_wrmsr();
5427
        }
5428
        break;
5429
    case 0x131: /* rdtsc */
5430
        gen_jmp_im(pc_start - s->cs_base);
5431
        gen_op_rdtsc();
5432
        break;
5433
    case 0x134: /* sysenter */
5434
        if (CODE64(s))
5435
            goto illegal_op;
5436
        if (!s->pe) {
5437
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5438
        } else {
5439
            if (s->cc_op != CC_OP_DYNAMIC) {
5440
                gen_op_set_cc_op(s->cc_op);
5441
                s->cc_op = CC_OP_DYNAMIC;
5442
            }
5443
            gen_jmp_im(pc_start - s->cs_base);
5444
            gen_op_sysenter();
5445
            gen_eob(s);
5446
        }
5447
        break;
5448
    case 0x135: /* sysexit */
5449
        if (CODE64(s))
5450
            goto illegal_op;
5451
        if (!s->pe) {
5452
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5453
        } else {
5454
            if (s->cc_op != CC_OP_DYNAMIC) {
5455
                gen_op_set_cc_op(s->cc_op);
5456
                s->cc_op = CC_OP_DYNAMIC;
5457
            }
5458
            gen_jmp_im(pc_start - s->cs_base);
5459
            gen_op_sysexit();
5460
            gen_eob(s);
5461
        }
5462
        break;
5463
#ifdef TARGET_X86_64
5464
    case 0x105: /* syscall */
5465
        /* XXX: is it usable in real mode ? */
5466
        if (s->cc_op != CC_OP_DYNAMIC) {
5467
            gen_op_set_cc_op(s->cc_op);
5468
            s->cc_op = CC_OP_DYNAMIC;
5469
        }
5470
        gen_jmp_im(pc_start - s->cs_base);
5471
        gen_op_syscall(s->pc - pc_start);
5472
        gen_eob(s);
5473
        break;
5474
    case 0x107: /* sysret */
5475
        if (!s->pe) {
5476
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5477
        } else {
5478
            if (s->cc_op != CC_OP_DYNAMIC) {
5479
                gen_op_set_cc_op(s->cc_op);
5480
                s->cc_op = CC_OP_DYNAMIC;
5481
            }
5482
            gen_jmp_im(pc_start - s->cs_base);
5483
            gen_op_sysret(s->dflag);
5484
            /* condition codes are modified only in long mode */
5485
            if (s->lma)
5486
                s->cc_op = CC_OP_EFLAGS;
5487
            gen_eob(s);
5488
        }
5489
        break;
5490
#endif
5491
    case 0x1a2: /* cpuid */
5492
        gen_op_cpuid();
5493
        break;
5494
    case 0xf4: /* hlt */
5495
        if (s->cpl != 0) {
5496
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5497
        } else {
5498
            if (s->cc_op != CC_OP_DYNAMIC)
5499
                gen_op_set_cc_op(s->cc_op);
5500
            gen_jmp_im(s->pc - s->cs_base);
5501
            gen_op_hlt();
5502
            s->is_jmp = 3;
5503
        }
5504
        break;
5505
    case 0x100:
5506
        modrm = ldub_code(s->pc++);
5507
        mod = (modrm >> 6) & 3;
5508
        op = (modrm >> 3) & 7;
5509
        switch(op) {
5510
        case 0: /* sldt */
5511
            if (!s->pe || s->vm86)
5512
                goto illegal_op;
5513
            gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
5514
            ot = OT_WORD;
5515
            if (mod == 3)
5516
                ot += s->dflag;
5517
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5518
            break;
5519
        case 2: /* lldt */
5520
            if (!s->pe || s->vm86)
5521
                goto illegal_op;
5522
            if (s->cpl != 0) {
5523
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5524
            } else {
5525
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5526
                gen_jmp_im(pc_start - s->cs_base);
5527
                gen_op_lldt_T0();
5528
            }
5529
            break;
5530
        case 1: /* str */
5531
            if (!s->pe || s->vm86)
5532
                goto illegal_op;
5533
            gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
5534
            ot = OT_WORD;
5535
            if (mod == 3)
5536
                ot += s->dflag;
5537
            gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
5538
            break;
5539
        case 3: /* ltr */
5540
            if (!s->pe || s->vm86)
5541
                goto illegal_op;
5542
            if (s->cpl != 0) {
5543
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5544
            } else {
5545
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5546
                gen_jmp_im(pc_start - s->cs_base);
5547
                gen_op_ltr_T0();
5548
            }
5549
            break;
5550
        case 4: /* verr */
5551
        case 5: /* verw */
5552
            if (!s->pe || s->vm86)
5553
                goto illegal_op;
5554
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5555
            if (s->cc_op != CC_OP_DYNAMIC)
5556
                gen_op_set_cc_op(s->cc_op);
5557
            if (op == 4)
5558
                gen_op_verr();
5559
            else
5560
                gen_op_verw();
5561
            s->cc_op = CC_OP_EFLAGS;
5562
            break;
5563
        default:
5564
            goto illegal_op;
5565
        }
5566
        break;
5567
    case 0x101:
5568
        modrm = ldub_code(s->pc++);
5569
        mod = (modrm >> 6) & 3;
5570
        op = (modrm >> 3) & 7;
5571
        rm = modrm & 7;
5572
        switch(op) {
5573
        case 0: /* sgdt */
5574
            if (mod == 3)
5575
                goto illegal_op;
5576
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5577
            gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit));
5578
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
5579
            gen_add_A0_im(s, 2);
5580
            gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base));
5581
            if (!s->dflag)
5582
                gen_op_andl_T0_im(0xffffff);
5583
            gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5584
            break;
5585
        case 1:
5586
            if (mod == 3) {
5587
                switch (rm) {
5588
                case 0: /* monitor */
5589
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
5590
                        s->cpl != 0)
5591
                        goto illegal_op;
5592
                    gen_jmp_im(pc_start - s->cs_base);
5593
#ifdef TARGET_X86_64
5594
                    if (s->aflag == 2) {
5595
                        gen_op_movq_A0_reg[R_EBX]();
5596
                        gen_op_addq_A0_AL();
5597
                    } else 
5598
#endif
5599
                    {
5600
                        gen_op_movl_A0_reg[R_EBX]();
5601
                        gen_op_addl_A0_AL();
5602
                        if (s->aflag == 0)
5603
                            gen_op_andl_A0_ffff();
5604
                    }
5605
                    gen_add_A0_ds_seg(s);
5606
                    gen_op_monitor();
5607
                    break;
5608
                case 1: /* mwait */
5609
                    if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) ||
5610
                        s->cpl != 0)
5611
                        goto illegal_op;
5612
                    if (s->cc_op != CC_OP_DYNAMIC) {
5613
                        gen_op_set_cc_op(s->cc_op);
5614
                        s->cc_op = CC_OP_DYNAMIC;
5615
                    }
5616
                    gen_jmp_im(s->pc - s->cs_base);
5617
                    gen_op_mwait();
5618
                    gen_eob(s);
5619
                    break;
5620
                default:
5621
                    goto illegal_op;
5622
                }
5623
            } else { /* sidt */
5624
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5625
                gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit));
5626
                gen_op_st_T0_A0[OT_WORD + s->mem_index]();
5627
                gen_add_A0_im(s, 2);
5628
                gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base));
5629
                if (!s->dflag)
5630
                    gen_op_andl_T0_im(0xffffff);
5631
                gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5632
            }
5633
            break;
5634
        case 2: /* lgdt */
5635
        case 3: /* lidt */
5636
            if (mod == 3)
5637
                goto illegal_op;
5638
            if (s->cpl != 0) {
5639
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5640
            } else {
5641
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5642
                gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
5643
                gen_add_A0_im(s, 2);
5644
                gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5645
                if (!s->dflag)
5646
                    gen_op_andl_T0_im(0xffffff);
5647
                if (op == 2) {
5648
                    gen_op_movtl_env_T0(offsetof(CPUX86State,gdt.base));
5649
                    gen_op_movl_env_T1(offsetof(CPUX86State,gdt.limit));
5650
                } else {
5651
                    gen_op_movtl_env_T0(offsetof(CPUX86State,idt.base));
5652
                    gen_op_movl_env_T1(offsetof(CPUX86State,idt.limit));
5653
                }
5654
            }
5655
            break;
5656
        case 4: /* smsw */
5657
            gen_op_movl_T0_env(offsetof(CPUX86State,cr[0]));
5658
            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 1);
5659
            break;
5660
        case 6: /* lmsw */
5661
            if (s->cpl != 0) {
5662
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5663
            } else {
5664
                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
5665
                gen_op_lmsw_T0();
5666
                gen_jmp_im(s->pc - s->cs_base);
5667
                gen_eob(s);
5668
            }
5669
            break;
5670
        case 7: /* invlpg */
5671
            if (s->cpl != 0) {
5672
                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5673
            } else {
5674
                if (mod == 3) {
5675
#ifdef TARGET_X86_64
5676
                    if (CODE64(s) && rm == 0) {
5677
                        /* swapgs */
5678
                        gen_op_movtl_T0_env(offsetof(CPUX86State,segs[R_GS].base));
5679
                        gen_op_movtl_T1_env(offsetof(CPUX86State,kernelgsbase));
5680
                        gen_op_movtl_env_T1(offsetof(CPUX86State,segs[R_GS].base));
5681
                        gen_op_movtl_env_T0(offsetof(CPUX86State,kernelgsbase));
5682
                    } else 
5683
#endif
5684
                    {
5685
                        goto illegal_op;
5686
                    }
5687
                } else {
5688
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5689
                    gen_op_invlpg_A0();
5690
                    gen_jmp_im(s->pc - s->cs_base);
5691
                    gen_eob(s);
5692
                }
5693
            }
5694
            break;
5695
        default:
5696
            goto illegal_op;
5697
        }
5698
        break;
5699
    case 0x108: /* invd */
5700
    case 0x109: /* wbinvd */
5701
        if (s->cpl != 0) {
5702
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5703
        } else {
5704
            /* nothing to do */
5705
        }
5706
        break;
5707
    case 0x63: /* arpl or movslS (x86_64) */
5708
#ifdef TARGET_X86_64
5709
        if (CODE64(s)) {
5710
            int d_ot;
5711
            /* d_ot is the size of destination */
5712
            d_ot = dflag + OT_WORD;
5713

    
5714
            modrm = ldub_code(s->pc++);
5715
            reg = ((modrm >> 3) & 7) | rex_r;
5716
            mod = (modrm >> 6) & 3;
5717
            rm = (modrm & 7) | REX_B(s);
5718
            
5719
            if (mod == 3) {
5720
                gen_op_mov_TN_reg[OT_LONG][0][rm]();
5721
                /* sign extend */
5722
                if (d_ot == OT_QUAD)
5723
                    gen_op_movslq_T0_T0();
5724
                gen_op_mov_reg_T0[d_ot][reg]();
5725
            } else {
5726
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5727
                if (d_ot == OT_QUAD) {
5728
                    gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
5729
                } else {
5730
                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5731
                }
5732
                gen_op_mov_reg_T0[d_ot][reg]();
5733
            }
5734
        } else 
5735
#endif
5736
        {
5737
            if (!s->pe || s->vm86)
5738
                goto illegal_op;
5739
            ot = dflag ? OT_LONG : OT_WORD;
5740
            modrm = ldub_code(s->pc++);
5741
            reg = (modrm >> 3) & 7;
5742
            mod = (modrm >> 6) & 3;
5743
            rm = modrm & 7;
5744
            if (mod != 3) {
5745
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5746
                gen_op_ld_T0_A0[ot + s->mem_index]();
5747
            } else {
5748
                gen_op_mov_TN_reg[ot][0][rm]();
5749
            }
5750
            if (s->cc_op != CC_OP_DYNAMIC)
5751
                gen_op_set_cc_op(s->cc_op);
5752
            gen_op_arpl();
5753
            s->cc_op = CC_OP_EFLAGS;
5754
            if (mod != 3) {
5755
                gen_op_st_T0_A0[ot + s->mem_index]();
5756
            } else {
5757
                gen_op_mov_reg_T0[ot][rm]();
5758
            }
5759
            gen_op_arpl_update();
5760
        }
5761
        break;
5762
    case 0x102: /* lar */
5763
    case 0x103: /* lsl */
5764
        if (!s->pe || s->vm86)
5765
            goto illegal_op;
5766
        ot = dflag ? OT_LONG : OT_WORD;
5767
        modrm = ldub_code(s->pc++);
5768
        reg = ((modrm >> 3) & 7) | rex_r;
5769
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
5770
        gen_op_mov_TN_reg[ot][1][reg]();
5771
        if (s->cc_op != CC_OP_DYNAMIC)
5772
            gen_op_set_cc_op(s->cc_op);
5773
        if (b == 0x102)
5774
            gen_op_lar();
5775
        else
5776
            gen_op_lsl();
5777
        s->cc_op = CC_OP_EFLAGS;
5778
        gen_op_mov_reg_T1[ot][reg]();
5779
        break;
5780
    case 0x118:
5781
        modrm = ldub_code(s->pc++);
5782
        mod = (modrm >> 6) & 3;
5783
        op = (modrm >> 3) & 7;
5784
        switch(op) {
5785
        case 0: /* prefetchnta */
5786
        case 1: /* prefetchnt0 */
5787
        case 2: /* prefetchnt0 */
5788
        case 3: /* prefetchnt0 */
5789
            if (mod == 3)
5790
                goto illegal_op;
5791
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5792
            /* nothing more to do */
5793
            break;
5794
        default:
5795
            goto illegal_op;
5796
        }
5797
        break;
5798
    case 0x120: /* mov reg, crN */
5799
    case 0x122: /* mov crN, reg */
5800
        if (s->cpl != 0) {
5801
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5802
        } else {
5803
            modrm = ldub_code(s->pc++);
5804
            if ((modrm & 0xc0) != 0xc0)
5805
                goto illegal_op;
5806
            rm = (modrm & 7) | REX_B(s);
5807
            reg = ((modrm >> 3) & 7) | rex_r;
5808
            if (CODE64(s))
5809
                ot = OT_QUAD;
5810
            else
5811
                ot = OT_LONG;
5812
            switch(reg) {
5813
            case 0:
5814
            case 2:
5815
            case 3:
5816
            case 4:
5817
            case 8:
5818
                if (b & 2) {
5819
                    gen_op_mov_TN_reg[ot][0][rm]();
5820
                    gen_op_movl_crN_T0(reg);
5821
                    gen_jmp_im(s->pc - s->cs_base);
5822
                    gen_eob(s);
5823
                } else {
5824
#if !defined(CONFIG_USER_ONLY) 
5825
                    if (reg == 8)
5826
                        gen_op_movtl_T0_cr8();
5827
                    else
5828
#endif
5829
                        gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
5830
                    gen_op_mov_reg_T0[ot][rm]();
5831
                }
5832
                break;
5833
            default:
5834
                goto illegal_op;
5835
            }
5836
        }
5837
        break;
5838
    case 0x121: /* mov reg, drN */
5839
    case 0x123: /* mov drN, reg */
5840
        if (s->cpl != 0) {
5841
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5842
        } else {
5843
            modrm = ldub_code(s->pc++);
5844
            if ((modrm & 0xc0) != 0xc0)
5845
                goto illegal_op;
5846
            rm = (modrm & 7) | REX_B(s);
5847
            reg = ((modrm >> 3) & 7) | rex_r;
5848
            if (CODE64(s))
5849
                ot = OT_QUAD;
5850
            else
5851
                ot = OT_LONG;
5852
            /* XXX: do it dynamically with CR4.DE bit */
5853
            if (reg == 4 || reg == 5 || reg >= 8)
5854
                goto illegal_op;
5855
            if (b & 2) {
5856
                gen_op_mov_TN_reg[ot][0][rm]();
5857
                gen_op_movl_drN_T0(reg);
5858
                gen_jmp_im(s->pc - s->cs_base);
5859
                gen_eob(s);
5860
            } else {
5861
                gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
5862
                gen_op_mov_reg_T0[ot][rm]();
5863
            }
5864
        }
5865
        break;
5866
    case 0x106: /* clts */
5867
        if (s->cpl != 0) {
5868
            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
5869
        } else {
5870
            gen_op_clts();
5871
            /* abort block because static cpu state changed */
5872
            gen_jmp_im(s->pc - s->cs_base);
5873
            gen_eob(s);
5874
        }
5875
        break;
5876
    /* MMX/SSE/SSE2/PNI support */
5877
    case 0x1c3: /* MOVNTI reg, mem */
5878
        if (!(s->cpuid_features & CPUID_SSE2))
5879
            goto illegal_op;
5880
        ot = s->dflag == 2 ? OT_QUAD : OT_LONG;
5881
        modrm = ldub_code(s->pc++);
5882
        mod = (modrm >> 6) & 3;
5883
        if (mod == 3)
5884
            goto illegal_op;
5885
        reg = ((modrm >> 3) & 7) | rex_r;
5886
        /* generate a generic store */
5887
        gen_ldst_modrm(s, modrm, ot, reg, 1);
5888
        break;
5889
    case 0x1ae:
5890
        modrm = ldub_code(s->pc++);
5891
        mod = (modrm >> 6) & 3;
5892
        op = (modrm >> 3) & 7;
5893
        switch(op) {
5894
        case 0: /* fxsave */
5895
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 
5896
                (s->flags & HF_EM_MASK))
5897
                goto illegal_op;
5898
            if (s->flags & HF_TS_MASK) {
5899
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5900
                break;
5901
            }
5902
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5903
            gen_op_fxsave_A0((s->dflag == 2));
5904
            break;
5905
        case 1: /* fxrstor */
5906
            if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || 
5907
                (s->flags & HF_EM_MASK))
5908
                goto illegal_op;
5909
            if (s->flags & HF_TS_MASK) {
5910
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5911
                break;
5912
            }
5913
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5914
            gen_op_fxrstor_A0((s->dflag == 2));
5915
            break;
5916
        case 2: /* ldmxcsr */
5917
        case 3: /* stmxcsr */
5918
            if (s->flags & HF_TS_MASK) {
5919
                gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
5920
                break;
5921
            }
5922
            if ((s->flags & HF_EM_MASK) || !(s->flags & HF_OSFXSR_MASK) ||
5923
                mod == 3)
5924
                goto illegal_op;
5925
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5926
            if (op == 2) {
5927
                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
5928
                gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
5929
            } else {
5930
                gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
5931
                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
5932
            }
5933
            break;
5934
        case 5: /* lfence */
5935
        case 6: /* mfence */
5936
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
5937
                goto illegal_op;
5938
            break;
5939
        case 7: /* sfence / clflush */
5940
            if ((modrm & 0xc7) == 0xc0) {
5941
                /* sfence */
5942
                if (!(s->cpuid_features & CPUID_SSE))
5943
                    goto illegal_op;
5944
            } else {
5945
                /* clflush */
5946
                if (!(s->cpuid_features & CPUID_CLFLUSH))
5947
                    goto illegal_op;
5948
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5949
            }
5950
            break;
5951
        default:
5952
            goto illegal_op;
5953
        }
5954
        break;
5955
    case 0x10d: /* prefetch */
5956
        modrm = ldub_code(s->pc++);
5957
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5958
        /* ignore for now */
5959
        break;
5960
    case 0x110 ... 0x117:
5961
    case 0x128 ... 0x12f:
5962
    case 0x150 ... 0x177:
5963
    case 0x17c ... 0x17f:
5964
    case 0x1c2:
5965
    case 0x1c4 ... 0x1c6:
5966
    case 0x1d0 ... 0x1fe:
5967
        gen_sse(s, b, pc_start, rex_r);
5968
        break;
5969
    default:
5970
        goto illegal_op;
5971
    }
5972
    /* lock generation */
5973
    if (s->prefix & PREFIX_LOCK)
5974
        gen_op_unlock();
5975
    return s->pc;
5976
 illegal_op:
5977
    if (s->prefix & PREFIX_LOCK)
5978
        gen_op_unlock();
5979
    /* XXX: ensure that no lock was generated */
5980
    gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
5981
    return s->pc;
5982
}
5983

    
5984
#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
5985
#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
5986

    
5987
/* flags read by an operation */
5988
static uint16_t opc_read_flags[NB_OPS] = { 
5989
    [INDEX_op_aas] = CC_A,
5990
    [INDEX_op_aaa] = CC_A,
5991
    [INDEX_op_das] = CC_A | CC_C,
5992
    [INDEX_op_daa] = CC_A | CC_C,
5993

    
5994
    /* subtle: due to the incl/decl implementation, C is used */
5995
    [INDEX_op_update_inc_cc] = CC_C, 
5996

    
5997
    [INDEX_op_into] = CC_O,
5998

    
5999
    [INDEX_op_jb_subb] = CC_C,
6000
    [INDEX_op_jb_subw] = CC_C,
6001
    [INDEX_op_jb_subl] = CC_C,
6002

    
6003
    [INDEX_op_jz_subb] = CC_Z,
6004
    [INDEX_op_jz_subw] = CC_Z,
6005
    [INDEX_op_jz_subl] = CC_Z,
6006

    
6007
    [INDEX_op_jbe_subb] = CC_Z | CC_C,
6008
    [INDEX_op_jbe_subw] = CC_Z | CC_C,
6009
    [INDEX_op_jbe_subl] = CC_Z | CC_C,
6010

    
6011
    [INDEX_op_js_subb] = CC_S,
6012
    [INDEX_op_js_subw] = CC_S,
6013
    [INDEX_op_js_subl] = CC_S,
6014

    
6015
    [INDEX_op_jl_subb] = CC_O | CC_S,
6016
    [INDEX_op_jl_subw] = CC_O | CC_S,
6017
    [INDEX_op_jl_subl] = CC_O | CC_S,
6018

    
6019
    [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
6020
    [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
6021
    [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
6022

    
6023
    [INDEX_op_loopnzw] = CC_Z,
6024
    [INDEX_op_loopnzl] = CC_Z,
6025
    [INDEX_op_loopzw] = CC_Z,
6026
    [INDEX_op_loopzl] = CC_Z,
6027

    
6028
    [INDEX_op_seto_T0_cc] = CC_O,
6029
    [INDEX_op_setb_T0_cc] = CC_C,
6030
    [INDEX_op_setz_T0_cc] = CC_Z,
6031
    [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
6032
    [INDEX_op_sets_T0_cc] = CC_S,
6033
    [INDEX_op_setp_T0_cc] = CC_P,
6034
    [INDEX_op_setl_T0_cc] = CC_O | CC_S,
6035
    [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
6036

    
6037
    [INDEX_op_setb_T0_subb] = CC_C,
6038
    [INDEX_op_setb_T0_subw] = CC_C,
6039
    [INDEX_op_setb_T0_subl] = CC_C,
6040

    
6041
    [INDEX_op_setz_T0_subb] = CC_Z,
6042
    [INDEX_op_setz_T0_subw] = CC_Z,
6043
    [INDEX_op_setz_T0_subl] = CC_Z,
6044

    
6045
    [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
6046
    [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
6047
    [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
6048

    
6049
    [INDEX_op_sets_T0_subb] = CC_S,
6050
    [INDEX_op_sets_T0_subw] = CC_S,
6051
    [INDEX_op_sets_T0_subl] = CC_S,
6052

    
6053
    [INDEX_op_setl_T0_subb] = CC_O | CC_S,
6054
    [INDEX_op_setl_T0_subw] = CC_O | CC_S,
6055
    [INDEX_op_setl_T0_subl] = CC_O | CC_S,
6056

    
6057
    [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
6058
    [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
6059
    [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
6060

    
6061
    [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
6062
    [INDEX_op_cmc] = CC_C,
6063
    [INDEX_op_salc] = CC_C,
6064

    
6065
    /* needed for correct flag optimisation before string ops */
6066
    [INDEX_op_jnz_ecxw] = CC_OSZAPC,
6067
    [INDEX_op_jnz_ecxl] = CC_OSZAPC,
6068
    [INDEX_op_jz_ecxw] = CC_OSZAPC,
6069
    [INDEX_op_jz_ecxl] = CC_OSZAPC,
6070

    
6071
#ifdef TARGET_X86_64
6072
    [INDEX_op_jb_subq] = CC_C,
6073
    [INDEX_op_jz_subq] = CC_Z,
6074
    [INDEX_op_jbe_subq] = CC_Z | CC_C,
6075
    [INDEX_op_js_subq] = CC_S,
6076
    [INDEX_op_jl_subq] = CC_O | CC_S,
6077
    [INDEX_op_jle_subq] = CC_O | CC_S | CC_Z,
6078

    
6079
    [INDEX_op_loopnzq] = CC_Z,
6080
    [INDEX_op_loopzq] = CC_Z,
6081

    
6082
    [INDEX_op_setb_T0_subq] = CC_C,
6083
    [INDEX_op_setz_T0_subq] = CC_Z,
6084
    [INDEX_op_setbe_T0_subq] = CC_Z | CC_C,
6085
    [INDEX_op_sets_T0_subq] = CC_S,
6086
    [INDEX_op_setl_T0_subq] = CC_O | CC_S,
6087
    [INDEX_op_setle_T0_subq] = CC_O | CC_S | CC_Z,
6088

    
6089
    [INDEX_op_jnz_ecxq] = CC_OSZAPC,
6090
    [INDEX_op_jz_ecxq] = CC_OSZAPC,
6091
#endif
6092

    
6093
#define DEF_READF(SUFFIX)\
6094
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6095
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6096
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6097
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6098
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6099
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6100
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6101
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6102
\
6103
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6104
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6105
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_C,\
6106
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_C,)\
6107
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_C,\
6108
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_C,\
6109
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_C,\
6110
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_C,)
6111

    
6112
    DEF_READF( )
6113
    DEF_READF(_raw)
6114
#ifndef CONFIG_USER_ONLY
6115
    DEF_READF(_kernel)
6116
    DEF_READF(_user)
6117
#endif
6118
};
6119

    
6120
/* flags written by an operation */
6121
static uint16_t opc_write_flags[NB_OPS] = { 
6122
    [INDEX_op_update2_cc] = CC_OSZAPC,
6123
    [INDEX_op_update1_cc] = CC_OSZAPC,
6124
    [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
6125
    [INDEX_op_update_neg_cc] = CC_OSZAPC,
6126
    /* subtle: due to the incl/decl implementation, C is used */
6127
    [INDEX_op_update_inc_cc] = CC_OSZAPC, 
6128
    [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
6129

    
6130
    [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
6131
    [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
6132
    [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
6133
    X86_64_DEF([INDEX_op_mulq_EAX_T0] = CC_OSZAPC,)
6134
    [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
6135
    [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
6136
    [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
6137
    X86_64_DEF([INDEX_op_imulq_EAX_T0] = CC_OSZAPC,)
6138
    [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
6139
    [INDEX_op_imull_T0_T1] = CC_OSZAPC,
6140
    X86_64_DEF([INDEX_op_imulq_T0_T1] = CC_OSZAPC,)
6141

    
6142
    /* sse */
6143
    [INDEX_op_ucomiss] = CC_OSZAPC,
6144
    [INDEX_op_ucomisd] = CC_OSZAPC,
6145
    [INDEX_op_comiss] = CC_OSZAPC,
6146
    [INDEX_op_comisd] = CC_OSZAPC,
6147

    
6148
    /* bcd */
6149
    [INDEX_op_aam] = CC_OSZAPC,
6150
    [INDEX_op_aad] = CC_OSZAPC,
6151
    [INDEX_op_aas] = CC_OSZAPC,
6152
    [INDEX_op_aaa] = CC_OSZAPC,
6153
    [INDEX_op_das] = CC_OSZAPC,
6154
    [INDEX_op_daa] = CC_OSZAPC,
6155

    
6156
    [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
6157
    [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
6158
    [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
6159
    [INDEX_op_movw_eflags_T0_io] = CC_OSZAPC,
6160
    [INDEX_op_movl_eflags_T0_io] = CC_OSZAPC,
6161
    [INDEX_op_movw_eflags_T0_cpl0] = CC_OSZAPC,
6162
    [INDEX_op_movl_eflags_T0_cpl0] = CC_OSZAPC,
6163
    [INDEX_op_clc] = CC_C,
6164
    [INDEX_op_stc] = CC_C,
6165
    [INDEX_op_cmc] = CC_C,
6166

    
6167
    [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
6168
    [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
6169
    X86_64_DEF([INDEX_op_btq_T0_T1_cc] = CC_OSZAPC,)
6170
    [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
6171
    [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
6172
    X86_64_DEF([INDEX_op_btsq_T0_T1_cc] = CC_OSZAPC,)
6173
    [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
6174
    [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
6175
    X86_64_DEF([INDEX_op_btrq_T0_T1_cc] = CC_OSZAPC,)
6176
    [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
6177
    [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
6178
    X86_64_DEF([INDEX_op_btcq_T0_T1_cc] = CC_OSZAPC,)
6179

    
6180
    [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
6181
    [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
6182
    X86_64_DEF([INDEX_op_bsfq_T0_cc] = CC_OSZAPC,)
6183
    [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
6184
    [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
6185
    X86_64_DEF([INDEX_op_bsrq_T0_cc] = CC_OSZAPC,)
6186

    
6187
    [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
6188
    [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
6189
    [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
6190
    X86_64_DEF([INDEX_op_cmpxchgq_T0_T1_EAX_cc] = CC_OSZAPC,)
6191

    
6192
    [INDEX_op_cmpxchg8b] = CC_Z,
6193
    [INDEX_op_lar] = CC_Z,
6194
    [INDEX_op_lsl] = CC_Z,
6195
    [INDEX_op_verr] = CC_Z,
6196
    [INDEX_op_verw] = CC_Z,
6197
    [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6198
    [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
6199

    
6200
#define DEF_WRITEF(SUFFIX)\
6201
    [INDEX_op_adcb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6202
    [INDEX_op_adcw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6203
    [INDEX_op_adcl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6204
    X86_64_DEF([INDEX_op_adcq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6205
    [INDEX_op_sbbb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6206
    [INDEX_op_sbbw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6207
    [INDEX_op_sbbl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6208
    X86_64_DEF([INDEX_op_sbbq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6209
\
6210
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6211
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6212
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6213
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6214
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6215
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6216
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6217
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6218
\
6219
    [INDEX_op_rclb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6220
    [INDEX_op_rclw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6221
    [INDEX_op_rcll ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6222
    X86_64_DEF([INDEX_op_rclq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6223
    [INDEX_op_rcrb ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6224
    [INDEX_op_rcrw ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6225
    [INDEX_op_rcrl ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,\
6226
    X86_64_DEF([INDEX_op_rcrq ## SUFFIX ## _T0_T1_cc] = CC_O | CC_C,)\
6227
\
6228
    [INDEX_op_shlb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6229
    [INDEX_op_shlw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6230
    [INDEX_op_shll ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6231
    X86_64_DEF([INDEX_op_shlq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6232
\
6233
    [INDEX_op_shrb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6234
    [INDEX_op_shrw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6235
    [INDEX_op_shrl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6236
    X86_64_DEF([INDEX_op_shrq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6237
\
6238
    [INDEX_op_sarb ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6239
    [INDEX_op_sarw ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6240
    [INDEX_op_sarl ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,\
6241
    X86_64_DEF([INDEX_op_sarq ## SUFFIX ## _T0_T1_cc] = CC_OSZAPC,)\
6242
\
6243
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6244
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6245
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6246
    [INDEX_op_shldw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6247
    [INDEX_op_shldl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6248
    X86_64_DEF([INDEX_op_shldq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6249
\
6250
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6251
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,\
6252
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_ECX_cc] = CC_OSZAPC,)\
6253
    [INDEX_op_shrdw ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6254
    [INDEX_op_shrdl ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,\
6255
    X86_64_DEF([INDEX_op_shrdq ## SUFFIX ## _T0_T1_im_cc] = CC_OSZAPC,)\
6256
\
6257
    [INDEX_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6258
    [INDEX_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6259
    [INDEX_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,\
6260
    X86_64_DEF([INDEX_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc] = CC_OSZAPC,)
6261

    
6262

    
6263
    DEF_WRITEF( )
6264
    DEF_WRITEF(_raw)
6265
#ifndef CONFIG_USER_ONLY
6266
    DEF_WRITEF(_kernel)
6267
    DEF_WRITEF(_user)
6268
#endif
6269
};
6270

    
6271
/* simpler form of an operation if no flags need to be generated */
6272
static uint16_t opc_simpler[NB_OPS] = { 
6273
    [INDEX_op_update2_cc] = INDEX_op_nop,
6274
    [INDEX_op_update1_cc] = INDEX_op_nop,
6275
    [INDEX_op_update_neg_cc] = INDEX_op_nop,
6276
#if 0
6277
    /* broken: CC_OP logic must be rewritten */
6278
    [INDEX_op_update_inc_cc] = INDEX_op_nop,
6279
#endif
6280

    
6281
    [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
6282
    [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
6283
    [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
6284
    X86_64_DEF([INDEX_op_shlq_T0_T1_cc] = INDEX_op_shlq_T0_T1,)
6285

    
6286
    [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
6287
    [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
6288
    [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
6289
    X86_64_DEF([INDEX_op_shrq_T0_T1_cc] = INDEX_op_shrq_T0_T1,)
6290

    
6291
    [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
6292
    [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
6293
    [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
6294
    X86_64_DEF([INDEX_op_sarq_T0_T1_cc] = INDEX_op_sarq_T0_T1,)
6295

    
6296
#define DEF_SIMPLER(SUFFIX)\
6297
    [INDEX_op_rolb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolb ## SUFFIX ## _T0_T1,\
6298
    [INDEX_op_rolw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolw ## SUFFIX ## _T0_T1,\
6299
    [INDEX_op_roll ## SUFFIX ## _T0_T1_cc] = INDEX_op_roll ## SUFFIX ## _T0_T1,\
6300
    X86_64_DEF([INDEX_op_rolq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rolq ## SUFFIX ## _T0_T1,)\
6301
\
6302
    [INDEX_op_rorb ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorb ## SUFFIX ## _T0_T1,\
6303
    [INDEX_op_rorw ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorw ## SUFFIX ## _T0_T1,\
6304
    [INDEX_op_rorl ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorl ## SUFFIX ## _T0_T1,\
6305
    X86_64_DEF([INDEX_op_rorq ## SUFFIX ## _T0_T1_cc] = INDEX_op_rorq ## SUFFIX ## _T0_T1,)
6306

    
6307
    DEF_SIMPLER( )
6308
    DEF_SIMPLER(_raw)
6309
#ifndef CONFIG_USER_ONLY
6310
    DEF_SIMPLER(_kernel)
6311
    DEF_SIMPLER(_user)
6312
#endif
6313
};
6314

    
6315
void optimize_flags_init(void)
6316
{
6317
    int i;
6318
    /* put default values in arrays */
6319
    for(i = 0; i < NB_OPS; i++) {
6320
        if (opc_simpler[i] == 0)
6321
            opc_simpler[i] = i;
6322
    }
6323
}
6324

    
6325
/* CPU flags computation optimization: we move backward thru the
6326
   generated code to see which flags are needed. The operation is
6327
   modified if suitable */
6328
static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
6329
{
6330
    uint16_t *opc_ptr;
6331
    int live_flags, write_flags, op;
6332

    
6333
    opc_ptr = opc_buf + opc_buf_len;
6334
    /* live_flags contains the flags needed by the next instructions
6335
       in the code. At the end of the bloc, we consider that all the
6336
       flags are live. */
6337
    live_flags = CC_OSZAPC;
6338
    while (opc_ptr > opc_buf) {
6339
        op = *--opc_ptr;
6340
        /* if none of the flags written by the instruction is used,
6341
           then we can try to find a simpler instruction */
6342
        write_flags = opc_write_flags[op];
6343
        if ((live_flags & write_flags) == 0) {
6344
            *opc_ptr = opc_simpler[op];
6345
        }
6346
        /* compute the live flags before the instruction */
6347
        live_flags &= ~write_flags;
6348
        live_flags |= opc_read_flags[op];
6349
    }
6350
}
6351

    
6352
/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
6353
   basic block 'tb'. If search_pc is TRUE, also generate PC
6354
   information for each intermediate instruction. */
6355
static inline int gen_intermediate_code_internal(CPUState *env,
6356
                                                 TranslationBlock *tb, 
6357
                                                 int search_pc)
6358
{
6359
    DisasContext dc1, *dc = &dc1;
6360
    target_ulong pc_ptr;
6361
    uint16_t *gen_opc_end;
6362
    int flags, j, lj, cflags;
6363
    target_ulong pc_start;
6364
    target_ulong cs_base;
6365
    
6366
    /* generate intermediate code */
6367
    pc_start = tb->pc;
6368
    cs_base = tb->cs_base;
6369
    flags = tb->flags;
6370
    cflags = tb->cflags;
6371

    
6372
    dc->pe = (flags >> HF_PE_SHIFT) & 1;
6373
    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
6374
    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
6375
    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
6376
    dc->f_st = 0;
6377
    dc->vm86 = (flags >> VM_SHIFT) & 1;
6378
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
6379
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
6380
    dc->tf = (flags >> TF_SHIFT) & 1;
6381
    dc->singlestep_enabled = env->singlestep_enabled;
6382
    dc->cc_op = CC_OP_DYNAMIC;
6383
    dc->cs_base = cs_base;
6384
    dc->tb = tb;
6385
    dc->popl_esp_hack = 0;
6386
    /* select memory access functions */
6387
    dc->mem_index = 0;
6388
    if (flags & HF_SOFTMMU_MASK) {
6389
        if (dc->cpl == 3)
6390
            dc->mem_index = 2 * 4;
6391
        else
6392
            dc->mem_index = 1 * 4;
6393
    }
6394
    dc->cpuid_features = env->cpuid_features;
6395
    dc->cpuid_ext_features = env->cpuid_ext_features;
6396
#ifdef TARGET_X86_64
6397
    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
6398
    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
6399
#endif
6400
    dc->flags = flags;
6401
    dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
6402
                    (flags & HF_INHIBIT_IRQ_MASK)
6403
#ifndef CONFIG_SOFTMMU
6404
                    || (flags & HF_SOFTMMU_MASK)
6405
#endif
6406
                    );
6407
#if 0
6408
    /* check addseg logic */
6409
    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
6410
        printf("ERROR addseg\n");
6411
#endif
6412

    
6413
    gen_opc_ptr = gen_opc_buf;
6414
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6415
    gen_opparam_ptr = gen_opparam_buf;
6416
    nb_gen_labels = 0;
6417

    
6418
    dc->is_jmp = DISAS_NEXT;
6419
    pc_ptr = pc_start;
6420
    lj = -1;
6421

    
6422
    for(;;) {
6423
        if (env->nb_breakpoints > 0) {
6424
            for(j = 0; j < env->nb_breakpoints; j++) {
6425
                if (env->breakpoints[j] == pc_ptr) {
6426
                    gen_debug(dc, pc_ptr - dc->cs_base);
6427
                    break;
6428
                }
6429
            }
6430
        }
6431
        if (search_pc) {
6432
            j = gen_opc_ptr - gen_opc_buf;
6433
            if (lj < j) {
6434
                lj++;
6435
                while (lj < j)
6436
                    gen_opc_instr_start[lj++] = 0;
6437
            }
6438
            gen_opc_pc[lj] = pc_ptr;
6439
            gen_opc_cc_op[lj] = dc->cc_op;
6440
            gen_opc_instr_start[lj] = 1;
6441
        }
6442
        pc_ptr = disas_insn(dc, pc_ptr);
6443
        /* stop translation if indicated */
6444
        if (dc->is_jmp)
6445
            break;
6446
        /* if single step mode, we generate only one instruction and
6447
           generate an exception */
6448
        /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
6449
           the flag and abort the translation to give the irqs a
6450
           change to be happen */
6451
        if (dc->tf || dc->singlestep_enabled || 
6452
            (flags & HF_INHIBIT_IRQ_MASK) ||
6453
            (cflags & CF_SINGLE_INSN)) {
6454
            gen_jmp_im(pc_ptr - dc->cs_base);
6455
            gen_eob(dc);
6456
            break;
6457
        }
6458
        /* if too long translation, stop generation too */
6459
        if (gen_opc_ptr >= gen_opc_end ||
6460
            (pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
6461
            gen_jmp_im(pc_ptr - dc->cs_base);
6462
            gen_eob(dc);
6463
            break;
6464
        }
6465
    }
6466
    *gen_opc_ptr = INDEX_op_end;
6467
    /* we don't forget to fill the last values */
6468
    if (search_pc) {
6469
        j = gen_opc_ptr - gen_opc_buf;
6470
        lj++;
6471
        while (lj <= j)
6472
            gen_opc_instr_start[lj++] = 0;
6473
    }
6474
        
6475
#ifdef DEBUG_DISAS
6476
    if (loglevel & CPU_LOG_TB_CPU) {
6477
        cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
6478
    }
6479
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6480
        int disas_flags;
6481
        fprintf(logfile, "----------------\n");
6482
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6483
#ifdef TARGET_X86_64
6484
        if (dc->code64)
6485
            disas_flags = 2;
6486
        else
6487
#endif
6488
            disas_flags = !dc->code32;
6489
        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
6490
        fprintf(logfile, "\n");
6491
        if (loglevel & CPU_LOG_TB_OP) {
6492
            fprintf(logfile, "OP:\n");
6493
            dump_ops(gen_opc_buf, gen_opparam_buf);
6494
            fprintf(logfile, "\n");
6495
        }
6496
    }
6497
#endif
6498

    
6499
    /* optimize flag computations */
6500
    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
6501

    
6502
#ifdef DEBUG_DISAS
6503
    if (loglevel & CPU_LOG_TB_OP_OPT) {
6504
        fprintf(logfile, "AFTER FLAGS OPT:\n");
6505
        dump_ops(gen_opc_buf, gen_opparam_buf);
6506
        fprintf(logfile, "\n");
6507
    }
6508
#endif
6509
    if (!search_pc)
6510
        tb->size = pc_ptr - pc_start;
6511
    return 0;
6512
}
6513

    
6514
int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
6515
{
6516
    return gen_intermediate_code_internal(env, tb, 0);
6517
}
6518

    
6519
int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
6520
{
6521
    return gen_intermediate_code_internal(env, tb, 1);
6522
}
6523