Statistics
| Branch: | Revision:

root / target-i386 / translate.c @ 664e0f19

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

    
99
static void gen_eob(DisasContext *s);
100
static void gen_jmp(DisasContext *s, target_ulong eip);
101
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
102

    
103
/* i386 arith/logic operations */
104
enum {
105
    OP_ADDL, 
106
    OP_ORL, 
107
    OP_ADCL, 
108
    OP_SBBL,
109
    OP_ANDL, 
110
    OP_SUBL, 
111
    OP_XORL, 
112
    OP_CMPL,
113
};
114

    
115
/* i386 shift ops */
116
enum {
117
    OP_ROL, 
118
    OP_ROR, 
119
    OP_RCL, 
120
    OP_RCR, 
121
    OP_SHL, 
122
    OP_SHR, 
123
    OP_SHL1, /* undocumented */
124
    OP_SAR = 7,
125
};
126

    
127
enum {
128
#define DEF(s, n, copy_size) INDEX_op_ ## s,
129
#include "opc.h"
130
#undef DEF
131
    NB_OPS,
132
};
133

    
134
#include "gen-op.h"
135

    
136
/* operand size */
137
enum {
138
    OT_BYTE = 0,
139
    OT_WORD,
140
    OT_LONG, 
141
    OT_QUAD,
142
};
143

    
144
enum {
145
    /* I386 int registers */
146
    OR_EAX,   /* MUST be even numbered */
147
    OR_ECX,
148
    OR_EDX,
149
    OR_EBX,
150
    OR_ESP,
151
    OR_EBP,
152
    OR_ESI,
153
    OR_EDI,
154

    
155
    OR_TMP0 = 16,    /* temporary operand register */
156
    OR_TMP1,
157
    OR_A0, /* temporary register used when doing address evaluation */
158
};
159

    
160
#ifdef TARGET_X86_64
161

    
162
#define NB_OP_SIZES 4
163

    
164
#define DEF_REGS(prefix, suffix) \
165
  prefix ## EAX ## suffix,\
166
  prefix ## ECX ## suffix,\
167
  prefix ## EDX ## suffix,\
168
  prefix ## EBX ## suffix,\
169
  prefix ## ESP ## suffix,\
170
  prefix ## EBP ## suffix,\
171
  prefix ## ESI ## suffix,\
172
  prefix ## EDI ## suffix,\
173
  prefix ## R8 ## suffix,\
174
  prefix ## R9 ## suffix,\
175
  prefix ## R10 ## suffix,\
176
  prefix ## R11 ## suffix,\
177
  prefix ## R12 ## suffix,\
178
  prefix ## R13 ## suffix,\
179
  prefix ## R14 ## suffix,\
180
  prefix ## R15 ## suffix,
181

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

    
216
DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)
217
DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)
218
DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )
219
DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
220

    
221
#else /* !TARGET_X86_64 */
222

    
223
#define NB_OP_SIZES 3
224

    
225
#define DEF_REGS(prefix, suffix) \
226
  prefix ## EAX ## suffix,\
227
  prefix ## ECX ## suffix,\
228
  prefix ## EDX ## suffix,\
229
  prefix ## EBX ## suffix,\
230
  prefix ## ESP ## suffix,\
231
  prefix ## EBP ## suffix,\
232
  prefix ## ESI ## suffix,\
233
  prefix ## EDI ## suffix,
234

    
235
#endif /* !TARGET_X86_64 */
236

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

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

    
315
static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
316
    [0] = {
317
        DEF_REGS(gen_op_movw_, _A0)
318
    },
319
    [1] = {
320
        DEF_REGS(gen_op_movl_, _A0)
321
    },
322
#ifdef TARGET_X86_64
323
    [2] = {
324
        DEF_REGS(gen_op_movq_, _A0)
325
    },
326
#endif
327
};
328

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

    
411
static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = {
412
    DEF_REGS(gen_op_movl_A0_, )
413
};
414

    
415
static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = {
416
    [0] = {
417
        DEF_REGS(gen_op_addl_A0_, )
418
    },
419
    [1] = {
420
        DEF_REGS(gen_op_addl_A0_, _s1)
421
    },
422
    [2] = {
423
        DEF_REGS(gen_op_addl_A0_, _s2)
424
    },
425
    [3] = {
426
        DEF_REGS(gen_op_addl_A0_, _s3)
427
    },
428
};
429

    
430
#ifdef TARGET_X86_64
431
static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = {
432
    DEF_REGS(gen_op_movq_A0_, )
433
};
434

    
435
static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = {
436
    [0] = {
437
        DEF_REGS(gen_op_addq_A0_, )
438
    },
439
    [1] = {
440
        DEF_REGS(gen_op_addq_A0_, _s1)
441
    },
442
    [2] = {
443
        DEF_REGS(gen_op_addq_A0_, _s2)
444
    },
445
    [3] = {
446
        DEF_REGS(gen_op_addq_A0_, _s3)
447
    },
448
};
449
#endif
450

    
451
static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
452
    [0] = {
453
        DEF_REGS(gen_op_cmovw_, _T1_T0)
454
    },
455
    [1] = {
456
        DEF_REGS(gen_op_cmovl_, _T1_T0)
457
    },
458
#ifdef TARGET_X86_64
459
    [2] = {
460
        DEF_REGS(gen_op_cmovq_, _T1_T0)
461
    },
462
#endif
463
};
464

    
465
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
466
    NULL,
467
    gen_op_orl_T0_T1,
468
    NULL,
469
    NULL,
470
    gen_op_andl_T0_T1,
471
    NULL,
472
    gen_op_xorl_T0_T1,
473
    NULL,
474
};
475

    
476
#define DEF_ARITHC(SUFFIX)\
477
    {\
478
        gen_op_adcb ## SUFFIX ## _T0_T1_cc,\
479
        gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\
480
    },\
481
    {\
482
        gen_op_adcw ## SUFFIX ## _T0_T1_cc,\
483
        gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\
484
    },\
485
    {\
486
        gen_op_adcl ## SUFFIX ## _T0_T1_cc,\
487
        gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\
488
    },\
489
    {\
490
        X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\
491
        X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\
492
    },
493

    
494
static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = {
495
    DEF_ARITHC( )
496
};
497

    
498
static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = {
499
    DEF_ARITHC(_raw)
500
#ifndef CONFIG_USER_ONLY
501
    DEF_ARITHC(_kernel)
502
    DEF_ARITHC(_user)
503
#endif
504
};
505

    
506
static const int cc_op_arithb[8] = {
507
    CC_OP_ADDB,
508
    CC_OP_LOGICB,
509
    CC_OP_ADDB,
510
    CC_OP_SUBB,
511
    CC_OP_LOGICB,
512
    CC_OP_SUBB,
513
    CC_OP_LOGICB,
514
    CC_OP_SUBB,
515
};
516

    
517
#define DEF_CMPXCHG(SUFFIX)\
518
    gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\
519
    gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\
520
    gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\
521
    X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc),
522

    
523
static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = {
524
    DEF_CMPXCHG( )
525
};
526

    
527
static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = {
528
    DEF_CMPXCHG(_raw)
529
#ifndef CONFIG_USER_ONLY
530
    DEF_CMPXCHG(_kernel)
531
    DEF_CMPXCHG(_user)
532
#endif
533
};
534

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

    
577
static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {
578
    DEF_SHIFT( )
579
};
580

    
581
static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {
582
    DEF_SHIFT(_raw)
583
#ifndef CONFIG_USER_ONLY
584
    DEF_SHIFT(_kernel)
585
    DEF_SHIFT(_user)
586
#endif
587
};
588

    
589
#define DEF_SHIFTD(SUFFIX, op)\
590
    {\
591
        NULL,\
592
        NULL,\
593
    },\
594
    {\
595
        gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
596
        gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\
597
    },\
598
    {\
599
        gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
600
        gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\
601
    },\
602
    {\
603
    },
604

    
605
static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {
606
    DEF_SHIFTD(, im)
607
};
608

    
609
static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {
610
    DEF_SHIFTD(, ECX)
611
};
612

    
613
static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {
614
    DEF_SHIFTD(_raw, im)
615
#ifndef CONFIG_USER_ONLY
616
    DEF_SHIFTD(_kernel, im)
617
    DEF_SHIFTD(_user, im)
618
#endif
619
};
620

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

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

    
652
static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
653
    gen_op_add_bitw_A0_T1,
654
    gen_op_add_bitl_A0_T1,
655
    X86_64_ONLY(gen_op_add_bitq_A0_T1),
656
};
657

    
658
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
659
    [0] = {
660
        gen_op_bsfw_T0_cc,
661
        gen_op_bsrw_T0_cc,
662
    },
663
    [1] = {
664
        gen_op_bsfl_T0_cc,
665
        gen_op_bsrl_T0_cc,
666
    },
667
#ifdef TARGET_X86_64
668
    [2] = {
669
        gen_op_bsfq_T0_cc,
670
        gen_op_bsrq_T0_cc,
671
    },
672
#endif
673
};
674

    
675
static GenOpFunc *gen_op_lds_T0_A0[3 * 4] = {
676
    gen_op_ldsb_raw_T0_A0,
677
    gen_op_ldsw_raw_T0_A0,
678
    X86_64_ONLY(gen_op_ldsl_raw_T0_A0),
679
    NULL,
680
#ifndef CONFIG_USER_ONLY
681
    gen_op_ldsb_kernel_T0_A0,
682
    gen_op_ldsw_kernel_T0_A0,
683
    X86_64_ONLY(gen_op_ldsl_kernel_T0_A0),
684
    NULL,
685

    
686
    gen_op_ldsb_user_T0_A0,
687
    gen_op_ldsw_user_T0_A0,
688
    X86_64_ONLY(gen_op_ldsl_user_T0_A0),
689
    NULL,
690
#endif
691
};
692

    
693
static GenOpFunc *gen_op_ldu_T0_A0[3 * 4] = {
694
    gen_op_ldub_raw_T0_A0,
695
    gen_op_lduw_raw_T0_A0,
696
    NULL,
697
    NULL,
698

    
699
#ifndef CONFIG_USER_ONLY
700
    gen_op_ldub_kernel_T0_A0,
701
    gen_op_lduw_kernel_T0_A0,
702
    NULL,
703
    NULL,
704

    
705
    gen_op_ldub_user_T0_A0,
706
    gen_op_lduw_user_T0_A0,
707
    NULL,
708
    NULL,
709
#endif
710
};
711

    
712
/* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
713
static GenOpFunc *gen_op_ld_T0_A0[3 * 4] = {
714
    gen_op_ldub_raw_T0_A0,
715
    gen_op_lduw_raw_T0_A0,
716
    gen_op_ldl_raw_T0_A0,
717
    X86_64_ONLY(gen_op_ldq_raw_T0_A0),
718

    
719
#ifndef CONFIG_USER_ONLY
720
    gen_op_ldub_kernel_T0_A0,
721
    gen_op_lduw_kernel_T0_A0,
722
    gen_op_ldl_kernel_T0_A0,
723
    X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
724

    
725
    gen_op_ldub_user_T0_A0,
726
    gen_op_lduw_user_T0_A0,
727
    gen_op_ldl_user_T0_A0,
728
    X86_64_ONLY(gen_op_ldq_user_T0_A0),
729
#endif
730
};
731

    
732
static GenOpFunc *gen_op_ld_T1_A0[3 * 4] = {
733
    gen_op_ldub_raw_T1_A0,
734
    gen_op_lduw_raw_T1_A0,
735
    gen_op_ldl_raw_T1_A0,
736
    X86_64_ONLY(gen_op_ldq_raw_T1_A0),
737

    
738
#ifndef CONFIG_USER_ONLY
739
    gen_op_ldub_kernel_T1_A0,
740
    gen_op_lduw_kernel_T1_A0,
741
    gen_op_ldl_kernel_T1_A0,
742
    X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
743

    
744
    gen_op_ldub_user_T1_A0,
745
    gen_op_lduw_user_T1_A0,
746
    gen_op_ldl_user_T1_A0,
747
    X86_64_ONLY(gen_op_ldq_user_T1_A0),
748
#endif
749
};
750

    
751
static GenOpFunc *gen_op_st_T0_A0[3 * 4] = {
752
    gen_op_stb_raw_T0_A0,
753
    gen_op_stw_raw_T0_A0,
754
    gen_op_stl_raw_T0_A0,
755
    X86_64_ONLY(gen_op_stq_raw_T0_A0),
756

    
757
#ifndef CONFIG_USER_ONLY
758
    gen_op_stb_kernel_T0_A0,
759
    gen_op_stw_kernel_T0_A0,
760
    gen_op_stl_kernel_T0_A0,
761
    X86_64_ONLY(gen_op_stq_kernel_T0_A0),
762

    
763
    gen_op_stb_user_T0_A0,
764
    gen_op_stw_user_T0_A0,
765
    gen_op_stl_user_T0_A0,
766
    X86_64_ONLY(gen_op_stq_user_T0_A0),
767
#endif
768
};
769

    
770
static GenOpFunc *gen_op_st_T1_A0[3 * 4] = {
771
    NULL,
772
    gen_op_stw_raw_T1_A0,
773
    gen_op_stl_raw_T1_A0,
774
    X86_64_ONLY(gen_op_stq_raw_T1_A0),
775

    
776
#ifndef CONFIG_USER_ONLY
777
    NULL,
778
    gen_op_stw_kernel_T1_A0,
779
    gen_op_stl_kernel_T1_A0,
780
    X86_64_ONLY(gen_op_stq_kernel_T1_A0),
781

    
782
    NULL,
783
    gen_op_stw_user_T1_A0,
784
    gen_op_stl_user_T1_A0,
785
    X86_64_ONLY(gen_op_stq_user_T1_A0),
786
#endif
787
};
788

    
789
static inline void gen_jmp_im(target_ulong pc)
790
{
791
#ifdef TARGET_X86_64
792
    if (pc == (uint32_t)pc) {
793
        gen_op_movl_eip_im(pc);
794
    } else if (pc == (int32_t)pc) {
795
        gen_op_movq_eip_im(pc);
796
    } else {
797
        gen_op_movq_eip_im64(pc >> 32, pc);
798
    }
799
#else
800
    gen_op_movl_eip_im(pc);
801
#endif
802
}
803

    
804
static inline void gen_string_movl_A0_ESI(DisasContext *s)
805
{
806
    int override;
807

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

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

    
860
static GenOpFunc *gen_op_movl_T0_Dshift[4] = {
861
    gen_op_movl_T0_Dshiftb,
862
    gen_op_movl_T0_Dshiftw,
863
    gen_op_movl_T0_Dshiftl,
864
    X86_64_ONLY(gen_op_movl_T0_Dshiftq),
865
};
866

    
867
static GenOpFunc1 *gen_op_jnz_ecx[3] = {
868
    gen_op_jnz_ecxw,
869
    gen_op_jnz_ecxl,
870
    X86_64_ONLY(gen_op_jnz_ecxq),
871
};
872
    
873
static GenOpFunc1 *gen_op_jz_ecx[3] = {
874
    gen_op_jz_ecxw,
875
    gen_op_jz_ecxl,
876
    X86_64_ONLY(gen_op_jz_ecxq),
877
};
878

    
879
static GenOpFunc *gen_op_dec_ECX[3] = {
880
    gen_op_decw_ECX,
881
    gen_op_decl_ECX,
882
    X86_64_ONLY(gen_op_decq_ECX),
883
};
884

    
885
static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {
886
    {
887
        gen_op_jnz_subb,
888
        gen_op_jnz_subw,
889
        gen_op_jnz_subl,
890
        X86_64_ONLY(gen_op_jnz_subq),
891
    },
892
    {
893
        gen_op_jz_subb,
894
        gen_op_jz_subw,
895
        gen_op_jz_subl,
896
        X86_64_ONLY(gen_op_jz_subq),
897
    },
898
};
899

    
900
static GenOpFunc *gen_op_in_DX_T0[3] = {
901
    gen_op_inb_DX_T0,
902
    gen_op_inw_DX_T0,
903
    gen_op_inl_DX_T0,
904
};
905

    
906
static GenOpFunc *gen_op_out_DX_T0[3] = {
907
    gen_op_outb_DX_T0,
908
    gen_op_outw_DX_T0,
909
    gen_op_outl_DX_T0,
910
};
911

    
912
static GenOpFunc *gen_op_in[3] = {
913
    gen_op_inb_T0_T1,
914
    gen_op_inw_T0_T1,
915
    gen_op_inl_T0_T1,
916
};
917

    
918
static GenOpFunc *gen_op_out[3] = {
919
    gen_op_outb_T0_T1,
920
    gen_op_outw_T0_T1,
921
    gen_op_outl_T0_T1,
922
};
923

    
924
static GenOpFunc *gen_check_io_T0[3] = {
925
    gen_op_check_iob_T0,
926
    gen_op_check_iow_T0,
927
    gen_op_check_iol_T0,
928
};
929

    
930
static GenOpFunc *gen_check_io_DX[3] = {
931
    gen_op_check_iob_DX,
932
    gen_op_check_iow_DX,
933
    gen_op_check_iol_DX,
934
};
935

    
936
static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip)
937
{
938
    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
939
        if (s->cc_op != CC_OP_DYNAMIC)
940
            gen_op_set_cc_op(s->cc_op);
941
        gen_jmp_im(cur_eip);
942
        if (use_dx)
943
            gen_check_io_DX[ot]();
944
        else
945
            gen_check_io_T0[ot]();
946
    }
947
}
948

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

    
971
static inline void gen_update_cc_op(DisasContext *s)
972
{
973
    if (s->cc_op != CC_OP_DYNAMIC) {
974
        gen_op_set_cc_op(s->cc_op);
975
        s->cc_op = CC_OP_DYNAMIC;
976
    }
977
}
978

    
979
/* XXX: does not work with gdbstub "ice" single step - not a
980
   serious problem */
981
static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
982
{
983
    int l1, l2;
984

    
985
    l1 = gen_new_label();
986
    l2 = gen_new_label();
987
    gen_op_jnz_ecx[s->aflag](l1);
988
    gen_set_label(l2);
989
    gen_jmp_tb(s, next_eip, 1);
990
    gen_set_label(l1);
991
    return l2;
992
}
993

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

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

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

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

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

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

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

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

    
1146
GEN_REPZ(movs)
1147
GEN_REPZ(stos)
1148
GEN_REPZ(lods)
1149
GEN_REPZ(ins)
1150
GEN_REPZ(outs)
1151
GEN_REPZ2(scas)
1152
GEN_REPZ2(cmps)
1153

    
1154
enum {
1155
    JCC_O,
1156
    JCC_B,
1157
    JCC_Z,
1158
    JCC_BE,
1159
    JCC_S,
1160
    JCC_P,
1161
    JCC_L,
1162
    JCC_LE,
1163
};
1164

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

    
1229
static GenOpFunc *gen_setcc_slow[8] = {
1230
    gen_op_seto_T0_cc,
1231
    gen_op_setb_T0_cc,
1232
    gen_op_setz_T0_cc,
1233
    gen_op_setbe_T0_cc,
1234
    gen_op_sets_T0_cc,
1235
    gen_op_setp_T0_cc,
1236
    gen_op_setl_T0_cc,
1237
    gen_op_setle_T0_cc,
1238
};
1239

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

    
1285
static GenOpFunc *gen_op_fp_arith_ST0_FT0[8] = {
1286
    gen_op_fadd_ST0_FT0,
1287
    gen_op_fmul_ST0_FT0,
1288
    gen_op_fcom_ST0_FT0,
1289
    gen_op_fcom_ST0_FT0,
1290
    gen_op_fsub_ST0_FT0,
1291
    gen_op_fsubr_ST0_FT0,
1292
    gen_op_fdiv_ST0_FT0,
1293
    gen_op_fdivr_ST0_FT0,
1294
};
1295

    
1296
/* NOTE the exception in "r" op ordering */
1297
static GenOpFunc1 *gen_op_fp_arith_STN_ST0[8] = {
1298
    gen_op_fadd_STN_ST0,
1299
    gen_op_fmul_STN_ST0,
1300
    NULL,
1301
    NULL,
1302
    gen_op_fsubr_STN_ST0,
1303
    gen_op_fsub_STN_ST0,
1304
    gen_op_fdivr_STN_ST0,
1305
    gen_op_fdiv_STN_ST0,
1306
};
1307

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

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

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

    
1412
static void gen_shifti(DisasContext *s1, int op, int ot, int d, int c)
1413
{
1414
    /* currently not optimized */
1415
    gen_op_movl_T1_im(c);
1416
    gen_shift(s1, op, ot, d, OR_TMP1);
1417
}
1418

    
1419
static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ptr)
1420
{
1421
    target_long disp;
1422
    int havesib;
1423
    int base;
1424
    int index;
1425
    int scale;
1426
    int opreg;
1427
    int mod, rm, code, override, must_add_seg;
1428

    
1429
    override = s->override;
1430
    must_add_seg = s->addseg;
1431
    if (override >= 0)
1432
        must_add_seg = 1;
1433
    mod = (modrm >> 6) & 3;
1434
    rm = modrm & 7;
1435

    
1436
    if (s->aflag) {
1437

    
1438
        havesib = 0;
1439
        base = rm;
1440
        index = 0;
1441
        scale = 0;
1442
        
1443
        if (base == 4) {
1444
            havesib = 1;
1445
            code = ldub_code(s->pc++);
1446
            scale = (code >> 6) & 3;
1447
            index = ((code >> 3) & 7) | REX_X(s);
1448
            base = (code & 7);
1449
        }
1450
        base |= REX_B(s);
1451

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

    
1603
    opreg = OR_A0;
1604
    disp = 0;
1605
    *reg_ptr = opreg;
1606
    *offset_ptr = disp;
1607
}
1608

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

    
1626
/* generate modrm memory load or store of 'reg'. TMP0 is used if reg !=
1627
   OR_TMP0 */
1628
static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_store)
1629
{
1630
    int mod, rm, opreg, disp;
1631

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

    
1658
static inline uint32_t insn_get(DisasContext *s, int ot)
1659
{
1660
    uint32_t ret;
1661

    
1662
    switch(ot) {
1663
    case OT_BYTE:
1664
        ret = ldub_code(s->pc);
1665
        s->pc++;
1666
        break;
1667
    case OT_WORD:
1668
        ret = lduw_code(s->pc);
1669
        s->pc += 2;
1670
        break;
1671
    default:
1672
    case OT_LONG:
1673
        ret = ldl_code(s->pc);
1674
        s->pc += 4;
1675
        break;
1676
    }
1677
    return ret;
1678
}
1679

    
1680
static inline int insn_const_size(unsigned int ot)
1681
{
1682
    if (ot <= OT_LONG)
1683
        return 1 << ot;
1684
    else
1685
        return 4;
1686
}
1687

    
1688
static inline void gen_jcc(DisasContext *s, int b, 
1689
                           target_ulong val, target_ulong next_eip)
1690
{
1691
    TranslationBlock *tb;
1692
    int inv, jcc_op;
1693
    GenOpFunc1 *func;
1694
    target_ulong tmp;
1695
    int l1, l2;
1696

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

    
1716
        case CC_OP_ADCB:
1717
        case CC_OP_ADCW:
1718
        case CC_OP_ADCL:
1719
        case CC_OP_ADCQ:
1720

    
1721
        case CC_OP_SBBB:
1722
        case CC_OP_SBBW:
1723
        case CC_OP_SBBL:
1724
        case CC_OP_SBBQ:
1725

    
1726
        case CC_OP_LOGICB:
1727
        case CC_OP_LOGICW:
1728
        case CC_OP_LOGICL:
1729
        case CC_OP_LOGICQ:
1730

    
1731
        case CC_OP_INCB:
1732
        case CC_OP_INCW:
1733
        case CC_OP_INCL:
1734
        case CC_OP_INCQ:
1735

    
1736
        case CC_OP_DECB:
1737
        case CC_OP_DECW:
1738
        case CC_OP_DECL:
1739
        case CC_OP_DECQ:
1740

    
1741
        case CC_OP_SHLB:
1742
        case CC_OP_SHLW:
1743
        case CC_OP_SHLL:
1744
        case CC_OP_SHLQ:
1745

    
1746
        case CC_OP_SARB:
1747
        case CC_OP_SARW:
1748
        case CC_OP_SARL:
1749
        case CC_OP_SARQ:
1750
            switch(jcc_op) {
1751
            case JCC_Z:
1752
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1753
                break;
1754
            case JCC_S:
1755
                func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 4][jcc_op];
1756
                break;
1757
            default:
1758
                func = NULL;
1759
                break;
1760
            }
1761
            break;
1762
        default:
1763
            func = NULL;
1764
            break;
1765
        }
1766

    
1767
        if (s->cc_op != CC_OP_DYNAMIC)
1768
            gen_op_set_cc_op(s->cc_op);
1769

    
1770
        if (!func) {
1771
            gen_setcc_slow[jcc_op]();
1772
            func = gen_op_jnz_T0_label;
1773
        }
1774
    
1775
        if (inv) {
1776
            tmp = val;
1777
            val = next_eip;
1778
            next_eip = tmp;
1779
        }
1780
        tb = s->tb;
1781

    
1782
        l1 = gen_new_label();
1783
        func(l1);
1784

    
1785
        gen_op_goto_tb0();
1786
        gen_jmp_im(next_eip);
1787
        gen_op_movl_T0_im((long)tb + 0);
1788
        gen_op_exit_tb();
1789

    
1790
        gen_set_label(l1);
1791
        gen_op_goto_tb1();
1792
        gen_jmp_im(val);
1793
        gen_op_movl_T0_im((long)tb + 1);
1794
        gen_op_exit_tb();
1795

    
1796
        s->is_jmp = 3;
1797
    } else {
1798

    
1799
        if (s->cc_op != CC_OP_DYNAMIC) {
1800
            gen_op_set_cc_op(s->cc_op);
1801
            s->cc_op = CC_OP_DYNAMIC;
1802
        }
1803
        gen_setcc_slow[jcc_op]();
1804
        if (inv) {
1805
            tmp = val;
1806
            val = next_eip;
1807
            next_eip = tmp;
1808
        }
1809
        l1 = gen_new_label();
1810
        l2 = gen_new_label();
1811
        gen_op_jnz_T0_label(l1);
1812
        gen_jmp_im(next_eip);
1813
        gen_op_jmp_label(l2);
1814
        gen_set_label(l1);
1815
        gen_jmp_im(val);
1816
        gen_set_label(l2);
1817
        gen_eob(s);
1818
    }
1819
}
1820

    
1821
static void gen_setcc(DisasContext *s, int b)
1822
{
1823
    int inv, jcc_op;
1824
    GenOpFunc *func;
1825

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

    
1845
    case CC_OP_LOGICB:
1846
    case CC_OP_LOGICW:
1847
    case CC_OP_LOGICL:
1848
    case CC_OP_LOGICQ:
1849

    
1850
    case CC_OP_INCB:
1851
    case CC_OP_INCW:
1852
    case CC_OP_INCL:
1853
    case CC_OP_INCQ:
1854

    
1855
    case CC_OP_DECB:
1856
    case CC_OP_DECW:
1857
    case CC_OP_DECL:
1858
    case CC_OP_DECQ:
1859

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

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

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

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

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

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

    
2033
static void gen_pop_update(DisasContext *s)
2034
{
2035
#ifdef TARGET_X86_64
2036
    if (CODE64(s)) {
2037
        gen_stack_update(s, 8);
2038
    } else
2039
#endif
2040
    {
2041
        gen_stack_update(s, 2 << s->dflag);
2042
    }
2043
}
2044

    
2045
static void gen_stack_A0(DisasContext *s)
2046
{
2047
    gen_op_movl_A0_ESP();
2048
    if (!s->ss32)
2049
        gen_op_andl_A0_ffff();
2050
    gen_op_movl_T1_A0();
2051
    if (s->addseg)
2052
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2053
}
2054

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

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

    
2096
static void gen_enter(DisasContext *s, int esp_addend, int level)
2097
{
2098
    int ot, opsize;
2099

    
2100
    ot = s->dflag + OT_WORD;
2101
    level &= 0x1f;
2102
    opsize = 2 << s->dflag;
2103

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

    
2122
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
2123
{
2124
    if (s->cc_op != CC_OP_DYNAMIC)
2125
        gen_op_set_cc_op(s->cc_op);
2126
    gen_jmp_im(cur_eip);
2127
    gen_op_raise_exception(trapno);
2128
    s->is_jmp = 3;
2129
}
2130

    
2131
/* an interrupt is different from an exception because of the
2132
   priviledge checks */
2133
static void gen_interrupt(DisasContext *s, int intno, 
2134
                          target_ulong cur_eip, target_ulong next_eip)
2135
{
2136
    if (s->cc_op != CC_OP_DYNAMIC)
2137
        gen_op_set_cc_op(s->cc_op);
2138
    gen_jmp_im(cur_eip);
2139
    gen_op_raise_interrupt(intno, (int)(next_eip - cur_eip));
2140
    s->is_jmp = 3;
2141
}
2142

    
2143
static void gen_debug(DisasContext *s, target_ulong cur_eip)
2144
{
2145
    if (s->cc_op != CC_OP_DYNAMIC)
2146
        gen_op_set_cc_op(s->cc_op);
2147
    gen_jmp_im(cur_eip);
2148
    gen_op_debug();
2149
    s->is_jmp = 3;
2150
}
2151

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

    
2172
/* generate a jump to eip. No segment change must happen before as a
2173
   direct call to the next block may occur */
2174
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2175
{
2176
    TranslationBlock *tb = s->tb;
2177

    
2178
    if (s->jmp_opt) {
2179
        if (s->cc_op != CC_OP_DYNAMIC)
2180
            gen_op_set_cc_op(s->cc_op);
2181
        if (tb_num)
2182
            gen_op_goto_tb1();
2183
        else
2184
            gen_op_goto_tb0();
2185
        gen_jmp_im(eip);
2186
        gen_op_movl_T0_im((long)tb + tb_num);
2187
        gen_op_exit_tb();
2188
        s->is_jmp = 3;
2189
    } else {
2190
        gen_jmp_im(eip);
2191
        gen_eob(s);
2192
    }
2193
}
2194

    
2195
static void gen_jmp(DisasContext *s, target_ulong eip)
2196
{
2197
    gen_jmp_tb(s, eip, 0);
2198
}
2199

    
2200
static void gen_movtl_T0_im(target_ulong val)
2201
{
2202
#ifdef TARGET_X86_64    
2203
    if ((int32_t)val == val) {
2204
        gen_op_movl_T0_im(val);
2205
    } else {
2206
        gen_op_movq_T0_im64(val >> 32, val);
2207
    }
2208
#else
2209
    gen_op_movl_T0_im(val);
2210
#endif
2211
}
2212

    
2213
static GenOpFunc1 *gen_ldq_env_A0[3] = {
2214
    gen_op_ldq_raw_env_A0,
2215
#ifndef CONFIG_USER_ONLY
2216
    gen_op_ldq_kernel_env_A0,
2217
    gen_op_ldq_user_env_A0,
2218
#endif
2219
};
2220

    
2221
static GenOpFunc1 *gen_stq_env_A0[3] = {
2222
    gen_op_stq_raw_env_A0,
2223
#ifndef CONFIG_USER_ONLY
2224
    gen_op_stq_kernel_env_A0,
2225
    gen_op_stq_user_env_A0,
2226
#endif
2227
};
2228

    
2229
static GenOpFunc1 *gen_ldo_env_A0[3] = {
2230
    gen_op_ldo_raw_env_A0,
2231
#ifndef CONFIG_USER_ONLY
2232
    gen_op_ldo_kernel_env_A0,
2233
    gen_op_ldo_user_env_A0,
2234
#endif
2235
};
2236

    
2237
static GenOpFunc1 *gen_sto_env_A0[3] = {
2238
    gen_op_sto_raw_env_A0,
2239
#ifndef CONFIG_USER_ONLY
2240
    gen_op_sto_kernel_env_A0,
2241
    gen_op_sto_user_env_A0,
2242
#endif
2243
};
2244

    
2245
#define SSE_SPECIAL ((GenOpFunc2 *)1)
2246

    
2247
#define MMX_OP2(x) { gen_op_ ## x ## _mmx, gen_op_ ## x ## _xmm }
2248
#define SSE_FOP(x) { gen_op_ ## x ## ps, gen_op_ ## x ## pd, \
2249
                     gen_op_ ## x ## ss, gen_op_ ## x ## sd, }
2250

    
2251
static GenOpFunc2 *sse_op_table1[256][4] = {
2252
    /* pure SSE operations */
2253
    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2254
    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */
2255
    [0x12] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2256
    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */
2257
    [0x14] = { gen_op_punpckldq_xmm, gen_op_punpcklqdq_xmm },
2258
    [0x15] = { gen_op_punpckhdq_xmm, gen_op_punpckhqdq_xmm },
2259
    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */
2260
    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */
2261

    
2262
    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2263
    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */
2264
    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */
2265
    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */
2266
    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */
2267
    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */
2268
    [0x2e] = { gen_op_ucomiss, gen_op_ucomisd },
2269
    [0x2f] = { gen_op_comiss, gen_op_comisd },
2270
    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */
2271
    [0x51] = SSE_FOP(sqrt),
2272
    [0x52] = { gen_op_rsqrtps, NULL, gen_op_rsqrtss, NULL },
2273
    [0x53] = { gen_op_rcpps, NULL, gen_op_rcpss, NULL },
2274
    [0x54] = { gen_op_pand_xmm, gen_op_pand_xmm }, /* andps, andpd */
2275
    [0x55] = { gen_op_pandn_xmm, gen_op_pandn_xmm }, /* andnps, andnpd */
2276
    [0x56] = { gen_op_por_xmm, gen_op_por_xmm }, /* orps, orpd */
2277
    [0x57] = { gen_op_pxor_xmm, gen_op_pxor_xmm }, /* xorps, xorpd */
2278
    [0x58] = SSE_FOP(add),
2279
    [0x59] = SSE_FOP(mul),
2280
    [0x5a] = { gen_op_cvtps2pd, gen_op_cvtpd2ps, 
2281
               gen_op_cvtss2sd, gen_op_cvtsd2ss },
2282
    [0x5b] = { gen_op_cvtdq2ps, gen_op_cvtps2dq, gen_op_cvttps2dq },
2283
    [0x5c] = SSE_FOP(sub),
2284
    [0x5d] = SSE_FOP(min),
2285
    [0x5e] = SSE_FOP(div),
2286
    [0x5f] = SSE_FOP(max),
2287

    
2288
    [0xc2] = SSE_FOP(cmpeq),
2289
    [0xc6] = { (GenOpFunc2 *)gen_op_pshufd_xmm, (GenOpFunc2 *)gen_op_shufpd },
2290

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

    
2374
static GenOpFunc2 *sse_op_table2[3 * 8][2] = {
2375
    [0 + 2] = MMX_OP2(psrlw),
2376
    [0 + 4] = MMX_OP2(psraw),
2377
    [0 + 6] = MMX_OP2(psllw),
2378
    [8 + 2] = MMX_OP2(psrld),
2379
    [8 + 4] = MMX_OP2(psrad),
2380
    [8 + 6] = MMX_OP2(pslld),
2381
    [16 + 2] = MMX_OP2(psrlq),
2382
    [16 + 3] = { NULL, gen_op_psrldq_xmm },
2383
    [16 + 6] = MMX_OP2(psllq),
2384
    [16 + 7] = { NULL, gen_op_pslldq_xmm },
2385
};
2386

    
2387
static GenOpFunc1 *sse_op_table3[4 * 3] = {
2388
    gen_op_cvtsi2ss,
2389
    gen_op_cvtsi2sd,
2390
    X86_64_ONLY(gen_op_cvtsq2ss),
2391
    X86_64_ONLY(gen_op_cvtsq2sd),
2392
    
2393
    gen_op_cvttss2si,
2394
    gen_op_cvttsd2si,
2395
    X86_64_ONLY(gen_op_cvttss2sq),
2396
    X86_64_ONLY(gen_op_cvttsd2sq),
2397

    
2398
    gen_op_cvtss2si,
2399
    gen_op_cvtsd2si,
2400
    X86_64_ONLY(gen_op_cvtss2sq),
2401
    X86_64_ONLY(gen_op_cvtsd2sq),
2402
};
2403
    
2404
static GenOpFunc2 *sse_op_table4[8][4] = {
2405
    SSE_FOP(cmpeq),
2406
    SSE_FOP(cmplt),
2407
    SSE_FOP(cmple),
2408
    SSE_FOP(cmpunord),
2409
    SSE_FOP(cmpneq),
2410
    SSE_FOP(cmpnlt),
2411
    SSE_FOP(cmpnle),
2412
    SSE_FOP(cmpord),
2413
};
2414
    
2415
static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
2416
{
2417
    int b1, op1_offset, op2_offset, is_xmm, val, ot;
2418
    int modrm, mod, rm, reg, reg_addr, offset_addr;
2419
    GenOpFunc2 *sse_op2;
2420
    GenOpFunc3 *sse_op3;
2421

    
2422
    b &= 0xff;
2423
    if (s->prefix & PREFIX_DATA) 
2424
        b1 = 1;
2425
    else if (s->prefix & PREFIX_REPZ) 
2426
        b1 = 2;
2427
    else if (s->prefix & PREFIX_REPNZ) 
2428
        b1 = 3;
2429
    else
2430
        b1 = 0;
2431
    sse_op2 = sse_op_table1[b][b1];
2432
    if (!sse_op2) 
2433
        goto illegal_op;
2434
    if (b <= 0x5f || b == 0xc6 || b == 0xc2) {
2435
        is_xmm = 1;
2436
    } else {
2437
        if (b1 == 0) {
2438
            /* MMX case */
2439
            is_xmm = 0;
2440
        } else {
2441
            is_xmm = 1;
2442
        }
2443
    }
2444
    /* simple MMX/SSE operation */
2445
    if (s->flags & HF_TS_MASK) {
2446
        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
2447
        return;
2448
    }
2449
    if (s->flags & HF_EM_MASK) {
2450
    illegal_op:
2451
        gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
2452
        return;
2453
    }
2454
    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))
2455
        goto illegal_op;
2456
    if (b == 0x77) {
2457
        /* emms */
2458
        gen_op_emms();
2459
        return;
2460
    }
2461
    /* prepare MMX state (XXX: optimize by storing fptt and fptags in
2462
       the static cpu state) */
2463
    if (!is_xmm) {
2464
        gen_op_enter_mmx();
2465
    }
2466

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

    
2931

    
2932
/* convert one instruction. s->is_jmp is set if the translation must
2933
   be stopped. Return the next pc value */
2934
static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
2935
{
2936
    int b, prefixes, aflag, dflag;
2937
    int shift, ot;
2938
    int modrm, reg, rm, mod, reg_addr, op, opreg, offset_addr, val;
2939
    target_ulong next_eip, tval;
2940
    int rex_w, rex_r;
2941

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

    
3057
    s->prefix = prefixes;
3058
    s->aflag = aflag;
3059
    s->dflag = dflag;
3060

    
3061
    /* lock generation */
3062
    if (prefixes & PREFIX_LOCK)
3063
        gen_op_lock();
3064

    
3065
    /* now check op code */
3066
 reswitch:
3067
    switch(b) {
3068
    case 0x0f:
3069
        /**************************/
3070
        /* extended op code */
3071
        b = ldub_code(s->pc++) | 0x100;
3072
        goto reswitch;
3073
        
3074
        /**************************/
3075
        /* arith & logic */
3076
    case 0x00 ... 0x05:
3077
    case 0x08 ... 0x0d:
3078
    case 0x10 ... 0x15:
3079
    case 0x18 ... 0x1d:
3080
    case 0x20 ... 0x25:
3081
    case 0x28 ... 0x2d:
3082
    case 0x30 ... 0x35:
3083
    case 0x38 ... 0x3d:
3084
        {
3085
            int op, f, val;
3086
            op = (b >> 3) & 7;
3087
            f = (b >> 1) & 3;
3088

    
3089
            if ((b & 1) == 0)
3090
                ot = OT_BYTE;
3091
            else
3092
                ot = dflag + OT_WORD;
3093
            
3094
            switch(f) {
3095
            case 0: /* OP Ev, Gv */
3096
                modrm = ldub_code(s->pc++);
3097
                reg = ((modrm >> 3) & 7) | rex_r;
3098
                mod = (modrm >> 6) & 3;
3099
                rm = (modrm & 7) | REX_B(s);
3100
                if (mod != 3) {
3101
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3102
                    opreg = OR_TMP0;
3103
                } else if (op == OP_XORL && rm == reg) {
3104
                xor_zero:
3105
                    /* xor reg, reg optimisation */
3106
                    gen_op_movl_T0_0();
3107
                    s->cc_op = CC_OP_LOGICB + ot;
3108
                    gen_op_mov_reg_T0[ot][reg]();
3109
                    gen_op_update1_cc();
3110
                    break;
3111
                } else {
3112
                    opreg = rm;
3113
                }
3114
                gen_op_mov_TN_reg[ot][1][reg]();
3115
                gen_op(s, op, ot, opreg);
3116
                break;
3117
            case 1: /* OP Gv, Ev */
3118
                modrm = ldub_code(s->pc++);
3119
                mod = (modrm >> 6) & 3;
3120
                reg = ((modrm >> 3) & 7) | rex_r;
3121
                rm = (modrm & 7) | REX_B(s);
3122
                if (mod != 3) {
3123
                    gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3124
                    gen_op_ld_T1_A0[ot + s->mem_index]();
3125
                } else if (op == OP_XORL && rm == reg) {
3126
                    goto xor_zero;
3127
                } else {
3128
                    gen_op_mov_TN_reg[ot][1][rm]();
3129
                }
3130
                gen_op(s, op, ot, reg);
3131
                break;
3132
            case 2: /* OP A, Iv */
3133
                val = insn_get(s, ot);
3134
                gen_op_movl_T1_im(val);
3135
                gen_op(s, op, ot, OR_EAX);
3136
                break;
3137
            }
3138
        }
3139
        break;
3140

    
3141
    case 0x80: /* GRP1 */
3142
    case 0x81:
3143
    case 0x82:
3144
    case 0x83:
3145
        {
3146
            int val;
3147

    
3148
            if ((b & 1) == 0)
3149
                ot = OT_BYTE;
3150
            else
3151
                ot = dflag + OT_WORD;
3152
            
3153
            modrm = ldub_code(s->pc++);
3154
            mod = (modrm >> 6) & 3;
3155
            rm = (modrm & 7) | REX_B(s);
3156
            op = (modrm >> 3) & 7;
3157
            
3158
            if (mod != 3) {
3159
                if (b == 0x83)
3160
                    s->rip_offset = 1;
3161
                else
3162
                    s->rip_offset = insn_const_size(ot);
3163
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3164
                opreg = OR_TMP0;
3165
            } else {
3166
                opreg = rm;
3167
            }
3168

    
3169
            switch(b) {
3170
            default:
3171
            case 0x80:
3172
            case 0x81:
3173
            case 0x82:
3174
                val = insn_get(s, ot);
3175
                break;
3176
            case 0x83:
3177
                val = (int8_t)insn_get(s, OT_BYTE);
3178
                break;
3179
            }
3180
            gen_op_movl_T1_im(val);
3181
            gen_op(s, op, ot, opreg);
3182
        }
3183
        break;
3184

    
3185
        /**************************/
3186
        /* inc, dec, and other misc arith */
3187
    case 0x40 ... 0x47: /* inc Gv */
3188
        ot = dflag ? OT_LONG : OT_WORD;
3189
        gen_inc(s, ot, OR_EAX + (b & 7), 1);
3190
        break;
3191
    case 0x48 ... 0x4f: /* dec Gv */
3192
        ot = dflag ? OT_LONG : OT_WORD;
3193
        gen_inc(s, ot, OR_EAX + (b & 7), -1);
3194
        break;
3195
    case 0xf6: /* GRP3 */
3196
    case 0xf7:
3197
        if ((b & 1) == 0)
3198
            ot = OT_BYTE;
3199
        else
3200
            ot = dflag + OT_WORD;
3201

    
3202
        modrm = ldub_code(s->pc++);
3203
        mod = (modrm >> 6) & 3;
3204
        rm = (modrm & 7) | REX_B(s);
3205
        op = (modrm >> 3) & 7;
3206
        if (mod != 3) {
3207
            if (op == 0)
3208
                s->rip_offset = insn_const_size(ot);
3209
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3210
            gen_op_ld_T0_A0[ot + s->mem_index]();
3211
        } else {
3212
            gen_op_mov_TN_reg[ot][0][rm]();
3213
        }
3214

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

    
3337
    case 0xfe: /* GRP4 */
3338
    case 0xff: /* GRP5 */
3339
        if ((b & 1) == 0)
3340
            ot = OT_BYTE;
3341
        else
3342
            ot = dflag + OT_WORD;
3343

    
3344
        modrm = ldub_code(s->pc++);
3345
        mod = (modrm >> 6) & 3;
3346
        rm = (modrm & 7) | REX_B(s);
3347
        op = (modrm >> 3) & 7;
3348
        if (op >= 2 && b == 0xfe) {
3349
            goto illegal_op;
3350
        }
3351
        if (CODE64(s)) {
3352
            if (op >= 2 && op <= 5) {
3353
                /* operand size for jumps is 64 bit */
3354
                ot = OT_QUAD;
3355
            } else if (op == 6) {
3356
                /* default push size is 64 bit */
3357
                ot = dflag ? OT_QUAD : OT_WORD;
3358
            }
3359
        }
3360
        if (mod != 3) {
3361
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3362
            if (op >= 2 && op != 3 && op != 5)
3363
                gen_op_ld_T0_A0[ot + s->mem_index]();
3364
        } else {
3365
            gen_op_mov_TN_reg[ot][0][rm]();
3366
        }
3367

    
3368
        switch(op) {
3369
        case 0: /* inc Ev */
3370
            if (mod != 3)
3371
                opreg = OR_TMP0;
3372
            else
3373
                opreg = rm;
3374
            gen_inc(s, ot, opreg, 1);
3375
            break;
3376
        case 1: /* dec Ev */
3377
            if (mod != 3)
3378
                opreg = OR_TMP0;
3379
            else
3380
                opreg = rm;
3381
            gen_inc(s, ot, opreg, -1);
3382
            break;
3383
        case 2: /* call Ev */
3384
            /* XXX: optimize if memory (no 'and' is necessary) */
3385
            if (s->dflag == 0)
3386
                gen_op_andl_T0_ffff();
3387
            next_eip = s->pc - s->cs_base;
3388
            gen_op_movl_T1_im(next_eip);
3389
            gen_push_T1(s);
3390
            gen_op_jmp_T0();
3391
            gen_eob(s);
3392
            break;
3393
        case 3: /* lcall Ev */
3394
            gen_op_ld_T1_A0[ot + s->mem_index]();
3395
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
3396
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3397
        do_lcall:
3398
            if (s->pe && !s->vm86) {
3399
                if (s->cc_op != CC_OP_DYNAMIC)
3400
                    gen_op_set_cc_op(s->cc_op);
3401
                gen_jmp_im(pc_start - s->cs_base);
3402
                gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base);
3403
            } else {
3404
                gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
3405
            }
3406
            gen_eob(s);
3407
            break;
3408
        case 4: /* jmp Ev */
3409
            if (s->dflag == 0)
3410
                gen_op_andl_T0_ffff();
3411
            gen_op_jmp_T0();
3412
            gen_eob(s);
3413
            break;
3414
        case 5: /* ljmp Ev */
3415
            gen_op_ld_T1_A0[ot + s->mem_index]();
3416
            gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
3417
            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3418
        do_ljmp:
3419
            if (s->pe && !s->vm86) {
3420
                if (s->cc_op != CC_OP_DYNAMIC)
3421
                    gen_op_set_cc_op(s->cc_op);
3422
                gen_jmp_im(pc_start - s->cs_base);
3423
                gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
3424
            } else {
3425
                gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3426
                gen_op_movl_T0_T1();
3427
                gen_op_jmp_T0();
3428
            }
3429
            gen_eob(s);
3430
            break;
3431
        case 6: /* push Ev */
3432
            gen_push_T0(s);
3433
            break;
3434
        default:
3435
            goto illegal_op;
3436
        }
3437
        break;
3438

    
3439
    case 0x84: /* test Ev, Gv */
3440
    case 0x85: 
3441
        if ((b & 1) == 0)
3442
            ot = OT_BYTE;
3443
        else
3444
            ot = dflag + OT_WORD;
3445

    
3446
        modrm = ldub_code(s->pc++);
3447
        mod = (modrm >> 6) & 3;
3448
        rm = (modrm & 7) | REX_B(s);
3449
        reg = ((modrm >> 3) & 7) | rex_r;
3450
        
3451
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3452
        gen_op_mov_TN_reg[ot][1][reg]();
3453
        gen_op_testl_T0_T1_cc();
3454
        s->cc_op = CC_OP_LOGICB + ot;
3455
        break;
3456
        
3457
    case 0xa8: /* test eAX, Iv */
3458
    case 0xa9:
3459
        if ((b & 1) == 0)
3460
            ot = OT_BYTE;
3461
        else
3462
            ot = dflag + OT_WORD;
3463
        val = insn_get(s, ot);
3464

    
3465
        gen_op_mov_TN_reg[ot][0][OR_EAX]();
3466
        gen_op_movl_T1_im(val);
3467
        gen_op_testl_T0_T1_cc();
3468
        s->cc_op = CC_OP_LOGICB + ot;
3469
        break;
3470
        
3471
    case 0x98: /* CWDE/CBW */
3472
#ifdef TARGET_X86_64
3473
        if (dflag == 2) {
3474
            gen_op_movslq_RAX_EAX();
3475
        } else
3476
#endif
3477
        if (dflag == 1)
3478
            gen_op_movswl_EAX_AX();
3479
        else
3480
            gen_op_movsbw_AX_AL();
3481
        break;
3482
    case 0x99: /* CDQ/CWD */
3483
#ifdef TARGET_X86_64
3484
        if (dflag == 2) {
3485
            gen_op_movsqo_RDX_RAX();
3486
        } else
3487
#endif
3488
        if (dflag == 1)
3489
            gen_op_movslq_EDX_EAX();
3490
        else
3491
            gen_op_movswl_DX_AX();
3492
        break;
3493
    case 0x1af: /* imul Gv, Ev */
3494
    case 0x69: /* imul Gv, Ev, I */
3495
    case 0x6b:
3496
        ot = dflag + OT_WORD;
3497
        modrm = ldub_code(s->pc++);
3498
        reg = ((modrm >> 3) & 7) | rex_r;
3499
        if (b == 0x69)
3500
            s->rip_offset = insn_const_size(ot);
3501
        else if (b == 0x6b)
3502
            s->rip_offset = 1;
3503
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
3504
        if (b == 0x69) {
3505
            val = insn_get(s, ot);
3506
            gen_op_movl_T1_im(val);
3507
        } else if (b == 0x6b) {
3508
            val = (int8_t)insn_get(s, OT_BYTE);
3509
            gen_op_movl_T1_im(val);
3510
        } else {
3511
            gen_op_mov_TN_reg[ot][1][reg]();
3512
        }
3513

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

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

    
3809
    case 0x1b6: /* movzbS Gv, Eb */
3810
    case 0x1b7: /* movzwS Gv, Eb */
3811
    case 0x1be: /* movsbS Gv, Eb */
3812
    case 0x1bf: /* movswS Gv, Eb */
3813
        {
3814
            int d_ot;
3815
            /* d_ot is the size of destination */
3816
            d_ot = dflag + OT_WORD;
3817
            /* ot is the size of source */
3818
            ot = (b & 1) + OT_BYTE;
3819
            modrm = ldub_code(s->pc++);
3820
            reg = ((modrm >> 3) & 7) | rex_r;
3821
            mod = (modrm >> 6) & 3;
3822
            rm = (modrm & 7) | REX_B(s);
3823
            
3824
            if (mod == 3) {
3825
                gen_op_mov_TN_reg[ot][0][rm]();
3826
                switch(ot | (b & 8)) {
3827
                case OT_BYTE:
3828
                    gen_op_movzbl_T0_T0();
3829
                    break;
3830
                case OT_BYTE | 8:
3831
                    gen_op_movsbl_T0_T0();
3832
                    break;
3833
                case OT_WORD:
3834
                    gen_op_movzwl_T0_T0();
3835
                    break;
3836
                default:
3837
                case OT_WORD | 8:
3838
                    gen_op_movswl_T0_T0();
3839
                    break;
3840
                }
3841
                gen_op_mov_reg_T0[d_ot][reg]();
3842
            } else {
3843
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3844
                if (b & 8) {
3845
                    gen_op_lds_T0_A0[ot + s->mem_index]();
3846
                } else {
3847
                    gen_op_ldu_T0_A0[ot + s->mem_index]();
3848
                }
3849
                gen_op_mov_reg_T0[d_ot][reg]();
3850
            }
3851
        }
3852
        break;
3853

    
3854
    case 0x8d: /* lea */
3855
        ot = dflag + OT_WORD;
3856
        modrm = ldub_code(s->pc++);
3857
        mod = (modrm >> 6) & 3;
3858
        if (mod == 3)
3859
            goto illegal_op;
3860
        reg = ((modrm >> 3) & 7) | rex_r;
3861
        /* we must ensure that no segment is added */
3862
        s->override = -1;
3863
        val = s->addseg;
3864
        s->addseg = 0;
3865
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3866
        s->addseg = val;
3867
        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
3868
        break;
3869
        
3870
    case 0xa0: /* mov EAX, Ov */
3871
    case 0xa1:
3872
    case 0xa2: /* mov Ov, EAX */
3873
    case 0xa3:
3874
        {
3875
            target_ulong offset_addr;
3876

    
3877
            if ((b & 1) == 0)
3878
                ot = OT_BYTE;
3879
            else
3880
                ot = dflag + OT_WORD;
3881
#ifdef TARGET_X86_64
3882
            if (CODE64(s)) {
3883
                offset_addr = ldq_code(s->pc);
3884
                s->pc += 8;
3885
                if (offset_addr == (int32_t)offset_addr)
3886
                    gen_op_movq_A0_im(offset_addr);
3887
                else
3888
                    gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
3889
            } else 
3890
#endif
3891
            {
3892
                if (s->aflag) {
3893
                    offset_addr = insn_get(s, OT_LONG);
3894
                } else {
3895
                    offset_addr = insn_get(s, OT_WORD);
3896
                }
3897
                gen_op_movl_A0_im(offset_addr);
3898
            }
3899
            gen_add_A0_ds_seg(s);
3900
            if ((b & 2) == 0) {
3901
                gen_op_ld_T0_A0[ot + s->mem_index]();
3902
                gen_op_mov_reg_T0[ot][R_EAX]();
3903
            } else {
3904
                gen_op_mov_TN_reg[ot][0][R_EAX]();
3905
                gen_op_st_T0_A0[ot + s->mem_index]();
3906
            }
3907
        }
3908
        break;
3909
    case 0xd7: /* xlat */
3910
#ifdef TARGET_X86_64
3911
        if (CODE64(s)) {
3912
            gen_op_movq_A0_reg[R_EBX]();
3913
            gen_op_addq_A0_AL();
3914
        } else 
3915
#endif
3916
        {
3917
            gen_op_movl_A0_reg[R_EBX]();
3918
            gen_op_addl_A0_AL();
3919
            if (s->aflag == 0)
3920
                gen_op_andl_A0_ffff();
3921
        }
3922
        gen_add_A0_ds_seg(s);
3923
        gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
3924
        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
3925
        break;
3926
    case 0xb0 ... 0xb7: /* mov R, Ib */
3927
        val = insn_get(s, OT_BYTE);
3928
        gen_op_movl_T0_im(val);
3929
        gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
3930
        break;
3931
    case 0xb8 ... 0xbf: /* mov R, Iv */
3932
#ifdef TARGET_X86_64
3933
        if (dflag == 2) {
3934
            uint64_t tmp;
3935
            /* 64 bit case */
3936
            tmp = ldq_code(s->pc);
3937
            s->pc += 8;
3938
            reg = (b & 7) | REX_B(s);
3939
            gen_movtl_T0_im(tmp);
3940
            gen_op_mov_reg_T0[OT_QUAD][reg]();
3941
        } else 
3942
#endif
3943
        {
3944
            ot = dflag ? OT_LONG : OT_WORD;
3945
            val = insn_get(s, ot);
3946
            reg = (b & 7) | REX_B(s);
3947
            gen_op_movl_T0_im(val);
3948
            gen_op_mov_reg_T0[ot][reg]();
3949
        }
3950
        break;
3951

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

    
4052
            /* simpler op */
4053
            if (shift == 0) {
4054
                gen_shift(s, op, ot, opreg, OR_ECX);
4055
            } else {
4056
                if (shift == 2) {
4057
                    shift = ldub_code(s->pc++);
4058
                }
4059
                gen_shifti(s, op, ot, opreg, shift);
4060
            }
4061
        }
4062
        break;
4063
    case 0xd0:
4064
    case 0xd1:
4065
        /* shift Ev,1 */
4066
        shift = 1;
4067
        goto grp2;
4068
    case 0xd2:
4069
    case 0xd3:
4070
        /* shift Ev,cl */
4071
        shift = 0;
4072
        goto grp2;
4073

    
4074
    case 0x1a4: /* shld imm */
4075
        op = 0;
4076
        shift = 1;
4077
        goto do_shiftd;
4078
    case 0x1a5: /* shld cl */
4079
        op = 0;
4080
        shift = 0;
4081
        goto do_shiftd;
4082
    case 0x1ac: /* shrd imm */
4083
        op = 1;
4084
        shift = 1;
4085
        goto do_shiftd;
4086
    case 0x1ad: /* shrd cl */
4087
        op = 1;
4088
        shift = 0;
4089
    do_shiftd:
4090
        ot = dflag + OT_WORD;
4091
        modrm = ldub_code(s->pc++);
4092
        mod = (modrm >> 6) & 3;
4093
        rm = (modrm & 7) | REX_B(s);
4094
        reg = ((modrm >> 3) & 7) | rex_r;
4095
        
4096
        if (mod != 3) {
4097
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4098
            gen_op_ld_T0_A0[ot + s->mem_index]();
4099
        } else {
4100
            gen_op_mov_TN_reg[ot][0][rm]();
4101
        }
4102
        gen_op_mov_TN_reg[ot][1][reg]();
4103
        
4104
        if (shift) {
4105
            val = ldub_code(s->pc++);
4106
            if (ot == OT_QUAD)
4107
                val &= 0x3f;
4108
            else
4109
                val &= 0x1f;
4110
            if (val) {
4111
                if (mod == 3)
4112
                    gen_op_shiftd_T0_T1_im_cc[ot][op](val);
4113
                else
4114
                    gen_op_shiftd_mem_T0_T1_im_cc[ot + s->mem_index][op](val);
4115
                if (op == 0 && ot != OT_WORD)
4116
                    s->cc_op = CC_OP_SHLB + ot;
4117
                else
4118
                    s->cc_op = CC_OP_SARB + ot;
4119
            }
4120
        } else {
4121
            if (s->cc_op != CC_OP_DYNAMIC)
4122
                gen_op_set_cc_op(s->cc_op);
4123
            if (mod == 3)
4124
                gen_op_shiftd_T0_T1_ECX_cc[ot][op]();
4125
            else
4126
                gen_op_shiftd_mem_T0_T1_ECX_cc[ot + s->mem_index][op]();
4127
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
4128
        }
4129
        if (mod == 3) {
4130
            gen_op_mov_reg_T0[ot][rm]();
4131
        }
4132
        break;
4133

    
4134
        /************************/
4135
        /* floats */
4136
    case 0xd8 ... 0xdf: 
4137
        if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
4138
            /* if CR0.EM or CR0.TS are set, generate an FPU exception */
4139
            /* XXX: what to do if illegal op ? */
4140
            gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
4141
            break;
4142
        }
4143
        modrm = ldub_code(s->pc++);
4144
        mod = (modrm >> 6) & 3;
4145
        rm = modrm & 7;
4146
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
4147
        if (mod != 3) {
4148
            /* memory op */
4149
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4150
            switch(op) {
4151
            case 0x00 ... 0x07: /* fxxxs */
4152
            case 0x10 ... 0x17: /* fixxxl */
4153
            case 0x20 ... 0x27: /* fxxxl */
4154
            case 0x30 ... 0x37: /* fixxx */
4155
                {
4156
                    int op1;
4157
                    op1 = op & 7;
4158

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

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

    
4581
    case 0xa4: /* movsS */
4582
    case 0xa5:
4583
        if ((b & 1) == 0)
4584
            ot = OT_BYTE;
4585
        else
4586
            ot = dflag + OT_WORD;
4587

    
4588
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4589
            gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4590
        } else {
4591
            gen_movs(s, ot);
4592
        }
4593
        break;
4594
        
4595
    case 0xaa: /* stosS */
4596
    case 0xab:
4597
        if ((b & 1) == 0)
4598
            ot = OT_BYTE;
4599
        else
4600
            ot = dflag + OT_WORD;
4601

    
4602
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4603
            gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4604
        } else {
4605
            gen_stos(s, ot);
4606
        }
4607
        break;
4608
    case 0xac: /* lodsS */
4609
    case 0xad:
4610
        if ((b & 1) == 0)
4611
            ot = OT_BYTE;
4612
        else
4613
            ot = dflag + OT_WORD;
4614
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4615
            gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4616
        } else {
4617
            gen_lods(s, ot);
4618
        }
4619
        break;
4620
    case 0xae: /* scasS */
4621
    case 0xaf:
4622
        if ((b & 1) == 0)
4623
            ot = OT_BYTE;
4624
        else
4625
            ot = dflag + OT_WORD;
4626
        if (prefixes & PREFIX_REPNZ) {
4627
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4628
        } else if (prefixes & PREFIX_REPZ) {
4629
            gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4630
        } else {
4631
            gen_scas(s, ot);
4632
            s->cc_op = CC_OP_SUBB + ot;
4633
        }
4634
        break;
4635

    
4636
    case 0xa6: /* cmpsS */
4637
    case 0xa7:
4638
        if ((b & 1) == 0)
4639
            ot = OT_BYTE;
4640
        else
4641
            ot = dflag + OT_WORD;
4642
        if (prefixes & PREFIX_REPNZ) {
4643
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
4644
        } else if (prefixes & PREFIX_REPZ) {
4645
            gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
4646
        } else {
4647
            gen_cmps(s, ot);
4648
            s->cc_op = CC_OP_SUBB + ot;
4649
        }
4650
        break;
4651
    case 0x6c: /* insS */
4652
    case 0x6d:
4653
        if ((b & 1) == 0)
4654
            ot = OT_BYTE;
4655
        else
4656
            ot = dflag ? OT_LONG : OT_WORD;
4657
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4658
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4659
            gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4660
        } else {
4661
            gen_ins(s, ot);
4662
        }
4663
        break;
4664
    case 0x6e: /* outsS */
4665
    case 0x6f:
4666
        if ((b & 1) == 0)
4667
            ot = OT_BYTE;
4668
        else
4669
            ot = dflag ? OT_LONG : OT_WORD;
4670
        gen_check_io(s, ot, 1, pc_start - s->cs_base);
4671
        if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
4672
            gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
4673
        } else {
4674
            gen_outs(s, ot);
4675
        }
4676
        break;
4677

    
4678
        /************************/
4679
        /* port I/O */
4680
    case 0xe4:
4681
    case 0xe5:
4682
        if ((b & 1) == 0)
4683
            ot = OT_BYTE;
4684
        else
4685
            ot = dflag ? OT_LONG : OT_WORD;
4686
        val = ldub_code(s->pc++);
4687
        gen_op_movl_T0_im(val);
4688
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4689
        gen_op_in[ot]();
4690
        gen_op_mov_reg_T1[ot][R_EAX]();
4691
        break;
4692
    case 0xe6:
4693
    case 0xe7:
4694
        if ((b & 1) == 0)
4695
            ot = OT_BYTE;
4696
        else
4697
            ot = dflag ? OT_LONG : OT_WORD;
4698
        val = ldub_code(s->pc++);
4699
        gen_op_movl_T0_im(val);
4700
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4701
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4702
        gen_op_out[ot]();
4703
        break;
4704
    case 0xec:
4705
    case 0xed:
4706
        if ((b & 1) == 0)
4707
            ot = OT_BYTE;
4708
        else
4709
            ot = dflag ? OT_LONG : OT_WORD;
4710
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4711
        gen_op_andl_T0_ffff();
4712
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4713
        gen_op_in[ot]();
4714
        gen_op_mov_reg_T1[ot][R_EAX]();
4715
        break;
4716
    case 0xee:
4717
    case 0xef:
4718
        if ((b & 1) == 0)
4719
            ot = OT_BYTE;
4720
        else
4721
            ot = dflag ? OT_LONG : OT_WORD;
4722
        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
4723
        gen_op_andl_T0_ffff();
4724
        gen_check_io(s, ot, 0, pc_start - s->cs_base);
4725
        gen_op_mov_TN_reg[ot][1][R_EAX]();
4726
        gen_op_out[ot]();
4727
        break;
4728

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

    
4843
            if (CODE64(s))
4844
                goto illegal_op;
4845
            ot = dflag ? OT_LONG : OT_WORD;
4846
            offset = insn_get(s, ot);
4847
            selector = insn_get(s, OT_WORD);
4848
            
4849
            gen_op_movl_T0_im(selector);
4850
            gen_op_movl_T1_imu(offset);
4851
        }
4852
        goto do_ljmp;
4853
    case 0xeb: /* jmp Jb */
4854
        tval = (int8_t)insn_get(s, OT_BYTE);
4855
        tval += s->pc - s->cs_base;
4856
        if (s->dflag == 0)
4857
            tval &= 0xffff;
4858
        gen_jmp(s, tval);
4859
        break;
4860
    case 0x70 ... 0x7f: /* jcc Jb */
4861
        tval = (int8_t)insn_get(s, OT_BYTE);
4862
        goto do_jcc;
4863
    case 0x180 ... 0x18f: /* jcc Jv */
4864
        if (dflag) {
4865
            tval = (int32_t)insn_get(s, OT_LONG);
4866
        } else {
4867
            tval = (int16_t)insn_get(s, OT_WORD); 
4868
        }
4869
    do_jcc:
4870
        next_eip = s->pc - s->cs_base;
4871
        tval += next_eip;
4872
        if (s->dflag == 0)
4873
            tval &= 0xffff;
4874
        gen_jcc(s, b, tval, next_eip);
4875
        break;
4876

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

    
4985
        /************************/
4986
        /* bit operations */
4987
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
4988
        ot = dflag + OT_WORD;
4989
        modrm = ldub_code(s->pc++);
4990
        op = ((modrm >> 3) & 7) | rex_r;
4991
        mod = (modrm >> 6) & 3;
4992
        rm = (modrm & 7) | REX_B(s);
4993
        if (mod != 3) {
4994
            s->rip_offset = 1;
4995
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4996
            gen_op_ld_T0_A0[ot + s->mem_index]();
4997
        } else {
4998
            gen_op_mov_TN_reg[ot][0][rm]();
4999
        }
5000
        /* load shift */
5001
        val = ldub_code(s->pc++);
5002
        gen_op_movl_T1_im(val);
5003
        if (op < 4